Merge pull request #2118 from joakim-hove/wbp

Wbp
This commit is contained in:
Joakim Hove 2020-11-30 13:17:18 +01:00 committed by GitHub
commit e52e0914fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 885 additions and 65 deletions

View File

@ -132,6 +132,8 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Schedule/Well/Connection.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/injection.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.cpp
@ -712,6 +714,8 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/EclipseState/Schedule/Well/ProductionControls.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/InjectionControls.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp

View File

@ -120,6 +120,7 @@ void msim::run_step(const Schedule& schedule, Action::State& action_state, Summa
group_nwrk_data,
{},
{},
{},
{});
schedule.getUDQConfig( report_step ).eval(report_step, schedule.wellMatcher(report_step), st, udq_state);

View File

@ -20,12 +20,14 @@
#ifndef OPM_OUTPUT_SUMMARY_HPP
#define OPM_OUTPUT_SUMMARY_HPP
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>
#include <opm/output/data/Aquifer.hpp>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
@ -69,12 +71,14 @@ public:
GlobalProcessParameters single_values,
const Inplace& initial_inplace,
const Inplace& inplace,
const PAvgCalculatorCollection& ,
const RegionParameters& region_values = {},
const BlockValues& block_values = {},
const data::Aquifers& aquifers_values = {}) const;
void write() const;
PAvgCalculatorCollection wbp_calculators(std::size_t report_step) const;
private:
class SummaryImplementation;

View File

@ -22,6 +22,7 @@
#include <map>
#include <memory>
#include <optional>
#include <unordered_set>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.hpp>
@ -44,6 +45,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
@ -191,6 +193,7 @@ namespace Opm
const TimeMap& getTimeMap() const;
PAvgCalculatorCollection pavg_calculators(const EclipseGrid& grid, const std::unordered_set<std::string>& wells, std::size_t report_step) const;
std::size_t numWells() const;
std::size_t numWells(std::size_t timestep) const;
bool hasWell(const std::string& wellName) const;

View File

@ -0,0 +1,108 @@
/*
Copyright 2020 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PAVE_CALC_HPP
#define PAVE_CALC_HPP
#include <functional>
#include <map>
#include <optional>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
namespace Opm {
class WellConnections;
class EclipseGrid;
class Serializer;
class PAvgCalculator {
public:
PAvgCalculator(const std::string& well, const EclipseGrid& grid, const WellConnections& connections, const PAvg& pavg);
enum class WBPMode {
WBP,
WBP4,
WBP5,
WBP9
};
struct Neighbour {
Neighbour(double porv_arg, std::size_t index_arg) :
porv(porv_arg),
global_index(index_arg)
{}
double porv;
std::size_t global_index;
};
struct Connection {
Connection(double porv_arg, double cf, ::Opm::Connection::Direction dir_arg, std::size_t index_arg) :
porv(porv_arg),
cfactor(cf),
dir(dir_arg),
global_index(index_arg)
{
}
double porv;
double cfactor;
::Opm::Connection::Direction dir;
std::size_t global_index;
std::vector<Neighbour> rect_neighbours;
std::vector<Neighbour> diag_neighbours;
};
const std::string& wname() const;
double wbp() const;
double wbp4() const;
double wbp5() const;
double wbp9() const;
bool add_pressure(std::size_t global_index, double pressure);
void update(Serializer& serializer);
const std::vector< std::size_t >& index_list() const;
std::pair< std::reference_wrapper<const std::vector<double>>, std::reference_wrapper<const std::vector<bool>> > data() const;
void serialize(Serializer& serializer) const;
private:
void update(const std::vector<double>& p, const std::vector<char>& m);
void add_connection(const PAvgCalculator::Connection& conn);
void add_neighbour(std::size_t global_index, std::optional<PAvgCalculator::Neighbour> neighbour, bool rect_neighbour);
double get_pressure(std::size_t global_index) const;
double connection_pressure(const std::vector<std::optional<double>>& block_pressure) const;
double wbp(WBPMode mode) const;
std::string well_name;
PAvg m_pavg;
std::vector<Connection> m_connections;
std::map<std::size_t, std::size_t> m_index_map;
std::vector<std::size_t> m_index_list;
std::vector<double> pressure;
std::vector<char> valid_pressure;
};
}
#endif

View File

@ -0,0 +1,49 @@
/*
Copyright 2020 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PAVE_CALC_COLLECTIONHPP
#define PAVE_CALC_COLLECTIONHPP
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.hpp>
namespace Opm {
class PAvgCalculatorCollection {
public:
bool empty() const;
void add(const PAvgCalculator& calculator);
bool has(const std::string& wname) const;
const PAvgCalculator& get(const std::string& wname) const;
const std::vector<std::size_t>& index_list() const;
void add_pressure(std::size_t index, double pressure);
private:
std::unordered_map<std::string, PAvgCalculator> calculators;
mutable std::optional<std::vector<std::size_t>> indexlist;
};
}
#endif

View File

@ -38,6 +38,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/MSW/WellSegments.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleTypes.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/ProductionControls.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/InjectionControls.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellFoamProperties.hpp>
@ -589,6 +590,7 @@ public:
void applyWellProdIndexScaling(const double scalingFactor,
std::vector<bool>& scalingApplicable);
const PAvg& pavg() const;
PAvgCalculator pavg_calculator(const EclipseGrid& grid) const;
template<class Serializer>
void serializeOp(Serializer& serializer)

View File

@ -25,6 +25,7 @@
#include <optional>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>
@ -197,6 +198,7 @@ namespace Opm {
*/
bool require3DField( const std::string& keyword) const;
std::set<std::string> fip_regions() const;
std::unordered_set<std::string> wbp_wells() const;
bool operator==(const SummaryConfig& data) const;

View File

@ -2802,6 +2802,7 @@ public:
void internal_store(const SummaryState& st, const int report_step);
void write();
PAvgCalculatorCollection wbp_calculators(std::size_t report_step) const;
private:
struct MiniStep
@ -2817,6 +2818,7 @@ private:
std::reference_wrapper<const Opm::EclipseState> es_;
std::reference_wrapper<const Opm::Schedule> sched_;
Opm::out::RegionCache regCache_;
std::unordered_set<std::string> wbp_wells;
std::unique_ptr<SMSpecStreamDeferredCreation> deferredSMSpec_;
@ -2877,6 +2879,9 @@ SummaryImplementation(const EclipseState& es,
this->configureSummaryInput(es, sumcfg, grid, sched);
this->configureRequiredRestartParameters(sumcfg, sched);
this->configureUDQ(sumcfg, sched);
for (const auto& config_node : sumcfg.keywords("WBP*"))
this->wbp_wells.insert( config_node.namedEntity() );
}
void Opm::out::Summary::SummaryImplementation::
@ -2896,6 +2901,17 @@ internal_store(const SummaryState& st, const int report_step)
}
}
Opm::PAvgCalculatorCollection Opm::out::Summary::SummaryImplementation::wbp_calculators(std::size_t report_step) const {
Opm::PAvgCalculatorCollection calculators;
for (const auto& wname : this->wbp_wells) {
const auto& well = this->sched_.get().getWell(wname, report_step);
if (well.getStatus() == Opm::Well::Status::OPEN)
calculators.add(well.pavg_calculator(this->grid_));
}
return calculators;
}
void
Opm::out::Summary::SummaryImplementation::
eval(const int sim_step,
@ -3304,6 +3320,7 @@ void Summary::eval(SummaryState& st,
GlobalProcessParameters single_values,
const Inplace& initial_inplace,
const Inplace& inplace,
const PAvgCalculatorCollection& ,
const RegionParameters& region_values,
const BlockValues& block_values,
const Opm::data::Aquifers& aquifer_values) const
@ -3326,6 +3343,11 @@ void Summary::eval(SummaryState& st,
region_values, block_values, aquifer_values, st);
}
PAvgCalculatorCollection Summary::wbp_calculators(std::size_t report_step) const {
return this->pImpl_->wbp_calculators(report_step);
}
void Summary::add_timestep(const SummaryState& st, const int report_step)
{
this->pImpl_->internal_store(st, report_step);

View File

@ -2024,4 +2024,15 @@ bool Schedule::cmp(const Schedule& sched1, const Schedule& sched2, std::size_t r
}
return (count == 0);
}
PAvgCalculatorCollection Schedule::pavg_calculators(const EclipseGrid& grid, const std::unordered_set<std::string>& wells, std::size_t report_step) const
{
PAvgCalculatorCollection calculators;
for (const auto& wname : wells) {
const auto& well = this->getWell(wname, report_step);
calculators.add(well.pavg_calculator(grid));
}
return calculators;
}
}

View File

@ -116,9 +116,16 @@ bool PAvg::open_connections() const {
}
bool PAvg::use_porv() const {
return this->m_conn_weight != 1.0;
if (this->m_conn_weight != 1)
return true;
if (this->m_inner_weight < 0)
return true;
return false;
}
bool PAvg::operator==(const PAvg& other) const {
return this->m_inner_weight == other.m_inner_weight &&
this->m_conn_weight == other.m_conn_weight &&

View File

@ -0,0 +1,271 @@
/*
Copyright 2020 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <fmt/format.h>
#include <numeric>
#include <opm/common/utility/Serializer.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculator.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
namespace Opm {
namespace {
std::optional<PAvgCalculator::Neighbour> make_neighbour(const EclipseGrid& grid, std::size_t i, std::size_t j, std::size_t k) {
if (i >= grid.getNX())
return {};
if (j >= grid.getNY())
return {};
if (k >= grid.getNZ())
return {};
if (!grid.cellActive(i,j,k))
return {};
double porv = -1;
return PAvgCalculator::Neighbour(porv, grid.getGlobalIndex(i,j,k));
}
}
const std::string& PAvgCalculator::wname() const {
return this->well_name;
}
PAvgCalculator::PAvgCalculator(const std::string& well, const EclipseGrid& grid, const WellConnections& connections, const PAvg& pavg) :
well_name(well),
m_pavg(pavg)
{
if (pavg.use_porv())
throw std::logic_error("The current implementation does not yet support PORV based averaging");
for (const auto& conn : connections) {
if (conn.state() == ::Opm::Connection::State::OPEN || !this->m_pavg.open_connections()) {
double porv = -1;
Connection wp_conn(porv, conn.CF(), conn.dir(), conn.global_index());
this->add_connection(wp_conn);
}
}
auto size = this->m_connections.size();
for (std::size_t index = 0; index < size; index++) {
auto& conn = this->m_connections[index];
auto [i,j,k] = grid.getIJK(conn.global_index);
if (conn.dir == ::Opm::Connection::Direction::X) {
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j ,k+1), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j ,k-1), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j+1,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j-1,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j+1,k+1), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j+1,k-1), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j-1,k+1), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i,j-1,k-1), false);
}
if (conn.dir == ::Opm::Connection::Direction::Y) {
this->add_neighbour(conn.global_index, make_neighbour(grid, i+1,j,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i-1,j,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i ,j,k+1), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i ,j,k-1), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i+1,j,k+1), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i-1,j,k+1), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i+1,j,k-1), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i-1,j,k-1), false);
}
if (conn.dir == ::Opm::Connection::Direction::Z) {
this->add_neighbour(conn.global_index, make_neighbour(grid, i+1,j ,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i-1,j ,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i ,j+1,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i ,j-1,k), true);
this->add_neighbour(conn.global_index, make_neighbour(grid, i+1,j+1,k), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i-1,j+1,k), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i+1,j-1,k), false);
this->add_neighbour(conn.global_index, make_neighbour(grid, i-1,j-1,k), false);
}
}
for (const auto& [ijk, _] : this->m_index_map)
this->m_index_list.push_back(ijk);
this->pressure.resize( this->m_index_list.size() );
this->valid_pressure.resize( this->m_index_list.size(), 0 );
}
void PAvgCalculator::add_connection(const PAvgCalculator::Connection& conn) {
this->m_index_map.insert(std::make_pair( conn.global_index, this->m_index_map.size()));
this->m_connections.push_back(conn);
}
void PAvgCalculator::add_neighbour(std::size_t global_index, std::optional<PAvgCalculator::Neighbour> neighbour, bool rect_neighbour) {
if (neighbour) {
this->m_index_map.insert(std::make_pair( neighbour->global_index, this->m_index_map.size()));
auto& conn = this->m_connections[ this->m_index_map[global_index] ];
if (rect_neighbour)
conn.rect_neighbours.push_back(neighbour.value());
else
conn.diag_neighbours.push_back(neighbour.value());
}
}
const std::vector< std::size_t >& PAvgCalculator::index_list() const {
return this->m_index_list;
}
bool PAvgCalculator::add_pressure(std::size_t global_index, double block_pressure) {
auto index_iter = this->m_index_map.find(global_index);
if (index_iter == this->m_index_map.end())
return false;
auto storage_index = index_iter->second;
this->pressure[storage_index] = block_pressure;
this->valid_pressure[storage_index] = 1;
return true;
}
double PAvgCalculator::get_pressure(std::size_t global_index) const {
auto storage_index = this->m_index_map.at(global_index);
if (this->valid_pressure[storage_index])
return this->pressure[storage_index];
auto msg = fmt::format("Tried to access pressure in invalid cell: {}", global_index);
throw std::runtime_error(msg);
}
double PAvgCalculator::connection_pressure(const std::vector<std::optional<double>>& block_pressure) const {
double pressure_sum = 0;
double cf_sum = 0;
for (std::size_t index = 0; index < block_pressure.size(); index++) {
if (block_pressure[index]) {
const auto& conn = this->m_connections[index];
pressure_sum += block_pressure[index].value() * conn.cfactor;
cf_sum += conn.cfactor;
}
}
if (cf_sum == 0)
return 0;
return pressure_sum / cf_sum;
}
double PAvgCalculator::wbp() const {
return this->wbp(PAvgCalculator::WBPMode::WBP);
}
double PAvgCalculator::wbp4() const {
return this->wbp(PAvgCalculator::WBPMode::WBP4);
}
double PAvgCalculator::wbp5() const {
return this->wbp(PAvgCalculator::WBPMode::WBP5);
}
double PAvgCalculator::wbp9() const {
return this->wbp(PAvgCalculator::WBPMode::WBP9);
}
double PAvgCalculator::wbp(PAvgCalculator::WBPMode mode) const {
double conn_pressure = 0;
if (this->m_pavg.conn_weight() > 0) {
std::vector<std::optional<double>> block_pressure;
for (const auto& conn : this->m_connections) {
if (this->m_pavg.inner_weight() >= 0) {
double neighbour_pressure = 0;
std::size_t neighbour_count = 0;
if (mode != PAvgCalculator::WBPMode::WBP) {
for (const auto& neighbour : conn.rect_neighbours) {
neighbour_pressure += this->get_pressure(neighbour.global_index);
neighbour_count += 1;
}
if (mode == PAvgCalculator::WBPMode::WBP9) {
for (const auto& neighbour : conn.diag_neighbours) {
neighbour_pressure += this->get_pressure(neighbour.global_index);
neighbour_count += 1;
}
}
}
if (mode == PAvgCalculator::WBPMode::WBP)
block_pressure.push_back(this->get_pressure(conn.global_index));
else if (mode == PAvgCalculator::WBPMode::WBP4) {
if (neighbour_count == 0)
block_pressure.push_back({});
else
block_pressure.push_back(neighbour_pressure / neighbour_count);
}
else {
if (neighbour_count == 0)
block_pressure.push_back(this->get_pressure(conn.global_index));
else {
const auto F1 = this->m_pavg.inner_weight();
block_pressure.push_back(F1 * this->get_pressure(conn.global_index) + (1 - F1) * neighbour_pressure / neighbour_count);
}
}
}
}
conn_pressure = this->connection_pressure(block_pressure);
}
return conn_pressure;
}
void PAvgCalculator::update(const std::vector<double>& p, const std::vector<char>& m) {
if (p.size() != this->pressure.size())
std::logic_error("Wrong size in update");
for (std::size_t index=0; index < p.size(); index++) {
if (m[index]) {
if (this->valid_pressure[index])
std::logic_error("Internal error - trying to update already valid pressure element");
this->pressure[index] = p[index];
this->valid_pressure[index] = 1;
}
}
}
void PAvgCalculator::serialize(Serializer& serializer) const {
serializer.put_vector( this->pressure );
serializer.put_vector( this->valid_pressure );
}
void PAvgCalculator::update(Serializer& serializer) {
std::vector<double> p = serializer.get_vector<double>();
std::vector<char> v = serializer.get_vector<char>();
this->update(p,v);
}
}

View File

@ -0,0 +1,71 @@
/*
Copyright 2020 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unordered_set>
#include <fmt/format.h>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp>
namespace Opm {
bool PAvgCalculatorCollection::empty() const {
return true;
}
bool PAvgCalculatorCollection::has(const std::string& wname) const {
return this->calculators.count(wname) > 0;
}
const PAvgCalculator& PAvgCalculatorCollection::get(const std::string& wname) const {
return this->calculators.at(wname);
}
void PAvgCalculatorCollection::add(const PAvgCalculator& calculator) {
this->calculators.emplace( calculator.wname(), calculator );
this->indexlist.reset();
}
const std::vector<std::size_t>& PAvgCalculatorCollection::index_list() const {
if (!this->indexlist.has_value()) {
std::unordered_set<std::size_t> il;
for ( const auto&[_, calculator] : this->calculators) {
(void)_;
const auto& calc_il = calculator.index_list();
il.insert(calc_il.begin(), calc_il.end());
}
this->indexlist = std::vector<std::size_t>{ il.begin(), il.end() };
}
return this->indexlist.value();
}
void PAvgCalculatorCollection::add_pressure(std::size_t index, double pressure) {
std::size_t count = 0;
for (auto& [_, calculator] : this->calculators) {
(void)_;
if (calculator.add_pressure(index, pressure))
count += 1;
}
if (count == 0) {
auto msg = fmt::format("Tried to update pressure in invalid cell: {}" , index);
throw std::logic_error(msg);
}
}
}

View File

@ -1633,6 +1633,12 @@ bool Well::operator==(const Well& data) const {
this->getInjectionProperties() == data.getInjectionProperties();
}
PAvgCalculator Well::pavg_calculator(const EclipseGrid& grid) const {
return PAvgCalculator(this->name(), grid, this->getConnections(), this->m_pavg);
}
}
int Opm::eclipseControlMode(const Opm::Well::InjectorCMode imode,

View File

@ -1533,6 +1533,13 @@ bool SummaryConfig::require3DField( const std::string& keyword ) const {
}
std::unordered_set<std::string> SummaryConfig::wbp_wells() const {
std::unordered_set<std::string> wells;
for (const auto& node : this->keywords("WBP*"))
wells.insert( node.namedEntity() );
return wells;
}
std::set<std::string> SummaryConfig::fip_regions() const {
std::set<std::string> reg_set;

View File

@ -22,7 +22,12 @@
#include <exception>
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvgCalculatorCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/common/utility/Serializer.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
@ -94,3 +99,248 @@ WWPAVE
BOOST_CHECK_EQUAL( pavg.conn_weight(), 0.5);
BOOST_CHECK( pavg.use_porv() );
}
bool contains(const std::vector<std::size_t>& index_list, std::size_t global_index) {
auto find_iter = std::find(index_list.begin(), index_list.end(), global_index);
return (find_iter != index_list.end());
}
BOOST_AUTO_TEST_CASE(WPAVE_CALCULATOR) {
const std::string deck_string = R"(
START
7 OCT 2020 /
DIMENS
10 10 3 /
GRID
DXV
10*100.0 /
DYV
10*100.0 /
DZV
3*10.0 /
DEPTHZ
121*2000.0 /
PERMX
300*100.0 /
PERMY
300*100.0 /
PERMZ
300*10.0 /
PORO
300*0.3 /
SCHEDULE
WELSPECS -- 0
'P1' 'G' 5 5 2005 'LIQ' /
'P2' 'G' 2 5 2005 'LIQ' /
'P3' 'G' 3 5 2005 'LIQ' /
'P4' 'G' 4 5 2005 'LIQ' /
'P5' 'G' 1 1 2005 'LIQ' / -- P5 is in the corner and will only have three neighbours
/
COMPDAT
'P1' 0 0 1 3 OPEN 1 100 /
'P5' 0 0 1 3 OPEN 1 100 /
/
TSTEP -- 1
10
/
WPAVE -- PAVG1
0.75 0.25 NONE /
TSTEP -- 2
10
/
WWPAVE
P1 0.30 0.60 NONE / -- PAVG2
P3 0.40 0.70 NONE / -- PAVG3
/
TSTEP -- 3
10
/
WPAVE -- PAVG4
0.10 0.10 NONE /
TSTEP -- 4
10
/
TSTEP -- 5
10
/
END
)";
const auto deck = Parser{}.parseString(deck_string);
const auto es = EclipseState{ deck };
const auto grid = es.getInputGrid();
auto sched = Schedule{ deck, es };
auto summary_config = SummaryConfig{deck, sched, es.getTableManager(), es.aquifer()};
const auto& w1 = sched.getWell("P1", 0);
auto calc = w1.pavg_calculator(grid);
{
const auto& index_list = calc.index_list();
for (std::size_t k = 0; k < 3; k++) {
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(4, 4, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(5, 4, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(3, 4, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(4, 3, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(4, 5, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(5, 5, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(3, 3, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(5, 3, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(3, 5, k)));
}
}
BOOST_CHECK( !calc.add_pressure(grid.getGlobalIndex(6, 7, 8), 100));
BOOST_CHECK_THROW(calc.wbp(), std::exception);
for (std::size_t k = 0; k < 3; k++) {
calc.add_pressure(grid.getGlobalIndex(4,4,k), 1);
}
BOOST_CHECK_EQUAL(calc.wbp(), 1);
BOOST_CHECK_THROW(calc.wbp4(), std::exception);
for (std::size_t k=0; k < 3; k++) {
calc.add_pressure(grid.getGlobalIndex(5,4,k), 1);
calc.add_pressure(grid.getGlobalIndex(3,4,k), 1);
calc.add_pressure(grid.getGlobalIndex(4,5,k), 1);
calc.add_pressure(grid.getGlobalIndex(4,3,k), 1);
}
BOOST_CHECK_EQUAL(calc.wbp4(), 1);
BOOST_CHECK_EQUAL(calc.wbp5(), 1);
//----------------------------------------------------
const auto& w5 = sched.getWell("P5", 0);
auto calc5 = w5.pavg_calculator(grid);
{
const auto& index_list = calc5.index_list();
BOOST_CHECK_EQUAL(index_list.size(), 12);
for (std::size_t k = 0; k < 3; k++) {
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(0, 0, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(1,0, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(0,1, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(1,1, k)));
calc5.add_pressure(grid.getGlobalIndex(0,0,k), 1);
calc5.add_pressure(grid.getGlobalIndex(1,0,k), 2.0);
calc5.add_pressure(grid.getGlobalIndex(0,1,k), 2.0);
calc5.add_pressure(grid.getGlobalIndex(1,1,k), 4.0);
}
BOOST_CHECK_EQUAL( calc5.wbp(), 1.0 );
BOOST_CHECK_EQUAL( calc5.wbp4(), 2.0 );
double inner_weight = 0.50;
BOOST_CHECK_EQUAL( calc5.wbp5(), inner_weight * 1 + (1 - inner_weight) * 2 );
BOOST_CHECK_EQUAL( calc5.wbp9(), inner_weight * 1 + (1 - inner_weight) * (2 * 2 + 4) / 3);
}
// We emulate MPI and calc1 and calc2 are on two different processors
{
auto calc1 = w5.pavg_calculator(grid);
auto calc2 = w5.pavg_calculator(grid);
for (std::size_t k = 0; k < 3; k++) {
calc1.add_pressure(grid.getGlobalIndex(0,0,k), 1);
calc2.add_pressure(grid.getGlobalIndex(1,0,k), 2.0);
calc2.add_pressure(grid.getGlobalIndex(0,1,k), 2.0);
calc2.add_pressure(grid.getGlobalIndex(1,1,k), 4.0);
}
BOOST_CHECK_THROW(calc1.wbp9(), std::exception);
Serializer ser1;
calc2.serialize(ser1);
Serializer ser2(ser1.buffer);
calc1.update(ser2);
double inner_weight = 0.50;
BOOST_CHECK_EQUAL( calc1.wbp5(), inner_weight * 1 + (1 - inner_weight) * 2 );
BOOST_CHECK_EQUAL( calc1.wbp9(), inner_weight * 1 + (1 - inner_weight) * (2 * 2 + 4) / 3);
}
auto calculators = sched.pavg_calculators(grid, summary_config.wbp_wells(), 0);
calculators.add(w1.pavg_calculator(grid));
calculators.add(w5.pavg_calculator(grid));
BOOST_CHECK( calculators.has("P1"));
BOOST_CHECK( calculators.has("P5"));
BOOST_CHECK( !calculators.has("P100"));
{
const auto& index_list = calculators.index_list();
for (std::size_t k = 0; k < 3; k++) {
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(4, 4, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(5, 4, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(3, 4, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(4, 3, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(4, 5, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(5, 5, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(3, 3, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(5, 3, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(3, 5, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(0, 0, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(1,0, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(0,1, k)));
BOOST_CHECK(contains(index_list, grid.getGlobalIndex(1,1, k)));
}
}
BOOST_CHECK_THROW( calculators.add_pressure(100000000, 1), std::exception );
for (std::size_t k = 0; k < 3; k++) {
calculators.add_pressure(grid.getGlobalIndex(0,0,k), 1);
calculators.add_pressure(grid.getGlobalIndex(1,0,k), 2.0);
calculators.add_pressure(grid.getGlobalIndex(0,1,k), 2.0);
calculators.add_pressure(grid.getGlobalIndex(1,1,k), 4.0);
calculators.add_pressure(grid.getGlobalIndex(4,4,k), 1);
calculators.add_pressure(grid.getGlobalIndex(5,4,k), 1);
calculators.add_pressure(grid.getGlobalIndex(3,4,k), 1);
calculators.add_pressure(grid.getGlobalIndex(4,5,k), 1);
calculators.add_pressure(grid.getGlobalIndex(4,3,k), 1);
}
{
const auto& c5 = calculators.get("P5");
double inner_weight = 0.50;
BOOST_CHECK_EQUAL( c5.wbp5(), inner_weight * 1 + (1 - inner_weight) * 2 );
BOOST_CHECK_EQUAL( c5.wbp9(), inner_weight * 1 + (1 - inner_weight) * (2 * 2 + 4) / 3);
}
}
BOOST_AUTO_TEST_CASE(CalcultorCollection) {
PAvgCalculatorCollection calc_list;
BOOST_CHECK(calc_list.empty());
}

View File

@ -4351,3 +4351,5 @@ END
BOOST_CHECK(w4.pavg() == pavg4);
}
}

View File

@ -480,13 +480,13 @@ BOOST_AUTO_TEST_CASE(well_keywords) {
SummaryState st(std::chrono::system_clock::now());
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
writer.eval(st, 0, 0*day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval(st, 0, 0*day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval(st, 1, 1*day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval(st, 1, 1*day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval(st, 2, 2*day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval(st, 2, 2*day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -727,11 +727,11 @@ BOOST_AUTO_TEST_CASE(udq_keywords) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -752,13 +752,13 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -909,11 +909,11 @@ BOOST_AUTO_TEST_CASE(group_group) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -965,11 +965,11 @@ BOOST_AUTO_TEST_CASE(connection_kewords) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1039,13 +1039,13 @@ BOOST_AUTO_TEST_CASE(DATE) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.eval( st, 3, 18 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 3, 18 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 3);
writer.eval( st, 4, 22 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 4, 22 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 4);
writer.write();
@ -1076,11 +1076,11 @@ BOOST_AUTO_TEST_CASE(field_keywords) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1213,11 +1213,11 @@ BOOST_AUTO_TEST_CASE(report_steps_time) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 1, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 1, 5 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 5 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 10 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 10 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1240,11 +1240,11 @@ BOOST_AUTO_TEST_CASE(skip_unknown_var) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 1, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 1, 5 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 5 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 10 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 10 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1350,11 +1350,11 @@ BOOST_AUTO_TEST_CASE(region_vars) {
{
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 1, 2 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, region_values);
writer.eval( st, 1, 2 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {}, region_values);
writer.add_timestep( st, 1);
writer.eval( st, 1, 5 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, region_values);
writer.eval( st, 1, 5 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {}, region_values);
writer.add_timestep( st, 1);
writer.eval( st, 2, 10 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, region_values);
writer.eval( st, 2, 10 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {}, region_values);
writer.add_timestep( st, 2);
writer.write();
}
@ -1401,11 +1401,11 @@ BOOST_AUTO_TEST_CASE(region_production) {
{
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
}
@ -1433,11 +1433,11 @@ BOOST_AUTO_TEST_CASE(region_injection) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1491,15 +1491,15 @@ BOOST_AUTO_TEST_CASE(BLOCK_VARIABLES) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, block_values);
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, {}, block_values);
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, block_values);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, {}, block_values);
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, block_values);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, {}, block_values);
writer.add_timestep( st, 2);
writer.eval( st, 3, 2 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, block_values);
writer.eval( st, 3, 2 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, {}, block_values);
writer.add_timestep( st, 3);
writer.eval( st, 4, 2 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, block_values);
writer.eval( st, 4, 2 * day, cfg.wells , cfg.grp_nwrk, {},{}, {}, {}, {}, block_values);
writer.add_timestep( st, 4);
writer.write();
@ -1552,13 +1552,13 @@ BOOST_AUTO_TEST_CASE(NODE_VARIABLES) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1610,11 +1610,11 @@ BOOST_AUTO_TEST_CASE(MISC) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
@ -1630,19 +1630,19 @@ BOOST_AUTO_TEST_CASE(EXTRA) {
{
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, { {"TCPU" , 0 }}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells , cfg.grp_nwrk, { {"TCPU" , 0 }}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, { {"TCPU" , 1 }}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells , cfg.grp_nwrk, { {"TCPU" , 1 }}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, { {"TCPU" , 2}}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells , cfg.grp_nwrk, { {"TCPU" , 2}}, {}, {}, {});
writer.add_timestep( st, 2);
/* Add a not-recognized key; that is OK */
BOOST_CHECK_NO_THROW( writer.eval( st, 3, 3 * day, cfg.wells , cfg.grp_nwrk, { {"MISSING" , 2 }}, {}, {}));
BOOST_CHECK_NO_THROW( writer.eval( st, 3, 3 * day, cfg.wells , cfg.grp_nwrk, { {"MISSING" , 2 }}, {}, {}, {}));
BOOST_CHECK_NO_THROW( writer.add_timestep( st, 3));
/* Override a NOT MISC variable - ignored. */
writer.eval( st, 4, 4 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 4, 4 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 4);
writer.write();
}
@ -1761,11 +1761,11 @@ BOOST_AUTO_TEST_CASE(efficiency_factor) {
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule, cfg.name );
SummaryState st(std::chrono::system_clock::now());
writer.eval( st, 0, 0 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 0, 0 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval( st, 1, 1 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 1, 1 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.eval( st, 2, 2 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval( st, 2, 2 * day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 2);
writer.write();
auto res = readsum( cfg.name );
@ -2008,11 +2008,11 @@ namespace {
};
SummaryState st(std::chrono::system_clock::now());
smry.eval(st, 0, 0*day, config.wells, config.grp_nwrk, {}, {}, {});
smry.eval(st, 0, 0*day, config.wells, config.grp_nwrk, {}, {}, {}, {});
smry.add_timestep(st, 0);
smry.eval(st, 1, 1*day, config.wells, config.grp_nwrk, {}, {}, {});
smry.eval(st, 1, 1*day, config.wells, config.grp_nwrk, {}, {}, {}, {});
smry.add_timestep(st, 1);
smry.eval(st, 2, 2*day, config.wells, config.grp_nwrk, {}, {}, {});
smry.eval(st, 2, 2*day, config.wells, config.grp_nwrk, {}, {}, {}, {});
smry.add_timestep(st, 2);
return st;
@ -3008,11 +3008,11 @@ BOOST_AUTO_TEST_CASE(Write_Read)
};
SummaryState st(std::chrono::system_clock::now());
writer.eval(st, 0, 0*day, config.wells, config.grp_nwrk, {}, {}, {});
writer.eval(st, 0, 0*day, config.wells, config.grp_nwrk, {}, {}, {}, {});
writer.add_timestep(st, 0);
writer.eval(st, 1, 1*day, config.wells, config.grp_nwrk, {}, {}, {});
writer.eval(st, 1, 1*day, config.wells, config.grp_nwrk, {}, {}, {}, {});
writer.add_timestep(st, 1);
writer.eval(st, 2, 2*day, config.wells, config.grp_nwrk, {}, {}, {});
writer.eval(st, 2, 2*day, config.wells, config.grp_nwrk, {}, {}, {}, {});
writer.add_timestep(st, 2);
writer.write();

View File

@ -259,10 +259,10 @@ BOOST_AUTO_TEST_CASE(group_keywords) {
SummaryState st(std::chrono::system_clock::now());
out::Summary writer( cfg.es, cfg.config, cfg.grid, cfg.schedule , cfg.name );
writer.eval(st, 0, 0*day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval(st, 0, 0*day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 0);
writer.eval(st, 1, 1*day, cfg.wells, cfg.grp_nwrk, {}, {}, {});
writer.eval(st, 1, 1*day, cfg.wells, cfg.grp_nwrk, {}, {}, {}, {});
writer.add_timestep( st, 1);
writer.write();