Make SummaryState Objects Aware of Undefined UDQ Value

This PR switches to calling the SummaryState constructor which is
aware of the value of undefined UDQs (OPM/opm-common#4052) directly.

While here, also sort headers, split some long lines, and prefer
initialisation lists to constructor body assignments.
This commit is contained in:
Bård Skaflestad 2024-05-06 14:02:39 +02:00
parent 091f758b5a
commit a3a2b7a978
5 changed files with 130 additions and 92 deletions

View File

@ -19,59 +19,65 @@
#include <config.h> #include <config.h>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Units/Units.hpp>
#include <opm/simulators/wells/VFPProperties.hpp>
#include <opm/simulators/wells/VFPInjProperties.hpp>
#include <opm/simulators/wells/VFPProdProperties.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/common/utility/TimeService.hpp> #include <opm/common/utility/TimeService.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/simulators/wells/VFPHelpers.hpp> #include <opm/simulators/wells/VFPHelpers.hpp>
#include <opm/simulators/wells/VFPInjProperties.hpp>
#include <opm/simulators/wells/VFPProdProperties.hpp>
#include <opm/simulators/wells/VFPProperties.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/input/eclipse/Units/Units.hpp>
#include <opm/core/props/phaseUsageFromDeck.hpp> #include <opm/core/props/phaseUsageFromDeck.hpp>
#include <iostream> #include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <cassert>
#include <cstdlib>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace Opm; using namespace Opm;
namespace {
struct Setup struct Setup
{ {
std::unique_ptr<const EclipseState> ecl_state; explicit Setup(const std::string& file)
std::shared_ptr<Python> python; : Setup { Parser{}.parseFile(file) }
std::unique_ptr<const Schedule> schedule; {}
std::unique_ptr<SummaryState> summary_state;
std::unique_ptr<VFPProperties<double>> vfp_properties;
Setup(const std::string& file) explicit Setup(const Deck& deck)
: ecl_state { std::make_unique<EclipseState>(deck) }
, schedule { std::make_unique<Schedule>(deck, *ecl_state, std::make_shared<Python>()) }
, well_state { std::make_unique<WellState<double>>(phaseUsage(ecl_state->runspec().phases())) }
{ {
Parser parser;
auto deck = parser.parseFile(file);
ecl_state.reset(new EclipseState(deck) );
const TableManager table( deck );
const Runspec runspec(deck);
python = std::make_shared<Python>();
schedule.reset( new Schedule(deck, *ecl_state, python));
summary_state.reset( new SummaryState(TimeService::from_time_t(schedule->getStartTime())));
const int step = 0; const int step = 0;
const auto& sched_state = schedule->operator[](step); const auto& sched_state = (*this->schedule)[step];
WellState<double> well_state(phaseUsage(runspec.phases()));
vfp_properties = std::make_unique<VFPProperties<double>>(sched_state.vfpinj(), this->vfp_properties = std::make_unique<VFPProperties<double>>
sched_state.vfpprod(), (sched_state.vfpinj(), sched_state.vfpprod(), *well_state);
well_state); }
};
std::unique_ptr<EclipseState> ecl_state;
std::unique_ptr<Schedule> schedule;
std::unique_ptr<WellState<double>> well_state;
std::unique_ptr<VFPProperties<double>> vfp_properties;
}; };
double computeBhp(const VFPProdTable& table, double computeBhp(const VFPProdTable& table,
const double flo, const double flo,
const double thp, const double thp,
@ -83,24 +89,25 @@ double computeBhp(const VFPProdTable& table,
// First, find the values to interpolate between. // First, find the values to interpolate between.
// Assuming positive flo here! // Assuming positive flo here!
assert(flo > 0.0); assert(flo > 0.0);
auto flo_i = VFPHelpers<double>::findInterpData(flo, table.getFloAxis());
auto thp_i = VFPHelpers<double>::findInterpData(thp, table.getTHPAxis()); // assume constant const auto flo_i = VFPHelpers<double>::findInterpData(flo, table.getFloAxis());
auto wfr_i = VFPHelpers<double>::findInterpData(wfr, table.getWFRAxis()); const auto thp_i = VFPHelpers<double>::findInterpData(thp, table.getTHPAxis()); // assume constant
auto gfr_i = VFPHelpers<double>::findInterpData(gfr, table.getGFRAxis()); const auto wfr_i = VFPHelpers<double>::findInterpData(wfr, table.getWFRAxis());
auto alq_i = VFPHelpers<double>::findInterpData(alq, table.getALQAxis()); //assume constant const auto gfr_i = VFPHelpers<double>::findInterpData(gfr, table.getGFRAxis());
const auto alq_i = VFPHelpers<double>::findInterpData(alq, table.getALQAxis()); // assume constant
return VFPHelpers<double>::interpolate(table, flo_i, thp_i, wfr_i, gfr_i, alq_i).value; return VFPHelpers<double>::interpolate(table, flo_i, thp_i, wfr_i, gfr_i, alq_i).value;
} }
} // Anonymous namespace
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if (argc < 2) { if (argc < 2) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
Setup setup(argv[1]);
const Setup setup(argv[1]);
// const int table_id = 1; // const int table_id = 1;
const int table_id = 4; const int table_id = 4;

View File

@ -22,16 +22,22 @@
*/ */
#include <config.h> #include <config.h>
#include <opm/simulators/flow//FlowGenericVanguard.hpp> #include <opm/simulators/flow/FlowGenericVanguard.hpp>
#include <opm/common/utility/MemPacker.hpp> #include <opm/common/utility/MemPacker.hpp>
#include <opm/common/utility/Serializer.hpp> #include <opm/common/utility/Serializer.hpp>
#include <opm/common/ErrorMacros.hpp> #include <opm/common/ErrorMacros.hpp>
#include <opm/common/utility/TimeService.hpp> #include <opm/common/utility/TimeService.hpp>
#include <opm/input/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferCell.hpp> #include <opm/input/eclipse/EclipseState/Aquifer/NumericalAquifer/NumericalAquiferCell.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp> #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Parser/InputErrorAction.hpp> #include <opm/input/eclipse/EclipseState/Runspec.hpp>
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Schedule/Action/Actions.hpp> #include <opm/input/eclipse/Schedule/Action/Actions.hpp>
#include <opm/input/eclipse/Schedule/Action/ASTNode.hpp> #include <opm/input/eclipse/Schedule/Action/ASTNode.hpp>
#include <opm/input/eclipse/Schedule/Action/State.hpp> #include <opm/input/eclipse/Schedule/Action/State.hpp>
@ -51,6 +57,7 @@
#include <opm/input/eclipse/Schedule/UDQ/UDQActive.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQActive.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQASTNode.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQASTNode.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQParams.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
#include <opm/input/eclipse/Schedule/Well/NameOrder.hpp> #include <opm/input/eclipse/Schedule/Well/NameOrder.hpp>
#include <opm/input/eclipse/Schedule/Well/WDFAC.hpp> #include <opm/input/eclipse/Schedule/Well/WDFAC.hpp>
@ -67,8 +74,9 @@
#include <opm/input/eclipse/Schedule/Well/WListManager.hpp> #include <opm/input/eclipse/Schedule/Well/WListManager.hpp>
#include <opm/input/eclipse/Schedule/Well/WVFPDP.hpp> #include <opm/input/eclipse/Schedule/Well/WVFPDP.hpp>
#include <opm/input/eclipse/Schedule/Well/WVFPEXP.hpp> #include <opm/input/eclipse/Schedule/Well/WVFPEXP.hpp>
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/input/eclipse/Python/Python.hpp> #include <opm/input/eclipse/Parser/InputErrorAction.hpp>
#include <opm/simulators/utils/readDeck.hpp> #include <opm/simulators/utils/readDeck.hpp>
#include <dune/common/version.hh> #include <dune/common/version.hh>
@ -239,8 +247,11 @@ void FlowGenericVanguard::init()
} }
if (!this->summaryState_) if (!this->summaryState_) {
this->summaryState_ = std::make_unique<SummaryState>( TimeService::from_time_t(this->eclSchedule_->getStartTime() )); this->summaryState_ = std::make_unique<SummaryState>
(TimeService::from_time_t(this->eclSchedule_->getStartTime()),
this->eclState_->runspec().udqParams().undefinedValue());
}
// Initialize parallelWells with all local wells // Initialize parallelWells with all local wells
const auto& schedule_wells = schedule().getWellsatEnd(); const auto& schedule_wells = schedule().getWellsatEnd();

View File

@ -55,7 +55,6 @@
#include <opm/input/eclipse/Schedule/Action/State.hpp> #include <opm/input/eclipse/Schedule/Action/State.hpp>
#include <opm/input/eclipse/Schedule/ArrayDimChecker.hpp> #include <opm/input/eclipse/Schedule/ArrayDimChecker.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp> #include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp> #include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>

View File

@ -27,15 +27,19 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h> #include <opm/common/utility/platform_dependent/reenable_warnings.h>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp> #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp> #include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/input/eclipse/Python/Python.hpp> #include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQParams.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
#include <opm/grid/GridManager.hpp> #include <opm/grid/GridManager.hpp>
#include <opm/input/eclipse/Units/Units.hpp> #include <opm/input/eclipse/Units/Units.hpp>
#include <opm/common/utility/TimeService.hpp> #include <opm/common/utility/TimeService.hpp>
@ -50,13 +54,18 @@
#include <opm/simulators/wells/StandardWell.hpp> #include <opm/simulators/wells/StandardWell.hpp>
#include <opm/simulators/wells/BlackoilWellModel.hpp> #include <opm/simulators/wells/BlackoilWellModel.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#if HAVE_DUNE_FEM #if HAVE_DUNE_FEM
#include <dune/fem/misc/mpimanager.hh> #include <dune/fem/misc/mpimanager.hh>
#else #else
#include <dune/common/parallel/mpihelper.hh> #include <dune/common/parallel/mpihelper.hh>
#endif #endif
#include <memory>
#include <stdexcept>
#include <vector>
using StandardWell = Opm::StandardWell<Opm::Properties::TTag::FlowProblem>; using StandardWell = Opm::StandardWell<Opm::Properties::TTag::FlowProblem>;
@ -64,18 +73,21 @@ struct SetupTest {
using Grid = UnstructuredGrid; using Grid = UnstructuredGrid;
SetupTest () SetupTest()
{ {
Opm::Parser parser; const auto deck = Opm::Parser{}.parseFile("TESTWELLMODEL.DATA");
auto deck = parser.parseFile("TESTWELLMODEL.DATA"); this->ecl_state = std::make_unique<const Opm::EclipseState>(deck);
ecl_state.reset(new Opm::EclipseState(deck) );
{ const Opm::TableManager table(deck);
const Opm::TableManager table ( deck ); const Opm::Runspec runspec(deck);
const Opm::Runspec runspec (deck);
python = std::make_shared<Opm::Python>(); this->schedule = std::make_unique<const Opm::Schedule>
schedule.reset( new Opm::Schedule(deck, *ecl_state, python)); (deck, *this->ecl_state, std::make_shared<Opm::Python>());
summaryState.reset( new Opm::SummaryState(Opm::TimeService::from_time_t(schedule->getStartTime())));
} this->summaryState = std::make_unique<Opm::SummaryState>
(Opm::TimeService::from_time_t(schedule->getStartTime()),
this->ecl_state->runspec().udqParams().undefinedValue());
current_timestep = 0; current_timestep = 0;
}; };
@ -136,7 +148,6 @@ BOOST_AUTO_TEST_CASE(TestStandardWellInput) {
BOOST_CHECK_THROW( StandardWell( well, pinfo, -1, param, *rateConverter, 0, 3, 3, 0, pdata), std::invalid_argument); BOOST_CHECK_THROW( StandardWell( well, pinfo, -1, param, *rateConverter, 0, 3, 3, 0, pdata), std::invalid_argument);
} }
BOOST_AUTO_TEST_CASE(TestBehavoir) { BOOST_AUTO_TEST_CASE(TestBehavoir) {
const SetupTest setup_test; const SetupTest setup_test;
const auto& wells_ecl = setup_test.schedule->getWells(setup_test.current_timestep); const auto& wells_ecl = setup_test.schedule->getWells(setup_test.current_timestep);

View File

@ -17,49 +17,59 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <algorithm>
#include <config.h> #include <config.h>
#include <functional>
#include <vector>
#define BOOST_TEST_MODULE WellStateFIBOTest #define BOOST_TEST_MODULE WellStateFIBOTest
#include "MpiFixture.hpp"
#include <opm/common/ErrorMacros.hpp>
#include <opm/simulators/wells/GlobalWellInfo.hpp>
#include <opm/simulators/wells/ParallelWellInfo.hpp>
#include <opm/simulators/wells/PerforationData.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/SingleWellState.hpp>
#include <opm/simulators/wells/SegmentState.hpp>
#include <opm/simulators/wells/WellContainer.hpp>
#include <opm/simulators/wells/PerfData.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp> #include "MpiFixture.hpp"
#include <opm/common/ErrorMacros.hpp>
#include <opm/common/utility/TimeService.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp> #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Parser/ParseContext.hpp> #include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Schedule/MSW/WellSegments.hpp> #include <opm/input/eclipse/Schedule/MSW/WellSegments.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp> #include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp> #include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQParams.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp> #include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp> #include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
#include <opm/simulators/wells/GlobalWellInfo.hpp>
#include <opm/simulators/wells/ParallelWellInfo.hpp>
#include <opm/simulators/wells/PerfData.hpp>
#include <opm/simulators/wells/PerforationData.hpp>
#include <opm/simulators/wells/SegmentState.hpp>
#include <opm/simulators/wells/SingleWellState.hpp>
#include <opm/simulators/wells/WellContainer.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/input/eclipse/Units/Units.hpp> #include <opm/input/eclipse/Units/Units.hpp>
#include <opm/common/utility/TimeService.hpp>
#include <opm/grid/GridHelpers.hpp> #include <opm/grid/GridHelpers.hpp>
#include <opm/grid/GridManager.hpp>
#include <opm/core/props/BlackoilPhases.hpp> #include <opm/core/props/BlackoilPhases.hpp>
#include <opm/core/props/phaseUsageFromDeck.hpp> #include <opm/core/props/phaseUsageFromDeck.hpp>
#include <opm/grid/GridManager.hpp> #include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Parser/ParseContext.hpp>
#include <algorithm>
#include <chrono> #include <chrono>
#include <cstddef> #include <cstddef>
#include <ctime>
#include <functional>
#include <memory>
#include <stdexcept>
#include <string> #include <string>
#include <vector>
BOOST_GLOBAL_FIXTURE(MPIFixture); BOOST_GLOBAL_FIXTURE(MPIFixture);
@ -73,9 +83,9 @@ struct Setup
: es (deck) : es (deck)
, pu (Opm::phaseUsageFromDeck(es)) , pu (Opm::phaseUsageFromDeck(es))
, grid (es.getInputGrid()) , grid (es.getInputGrid())
, python( std::make_shared<Opm::Python>() ) , sched(deck, es, std::make_shared<Opm::Python>())
, sched(deck, es, python) , st { Opm::TimeService::from_time_t(sched.getStartTime()),
, st(Opm::TimeService::from_time_t(sched.getStartTime())) es.runspec().udqParams().undefinedValue() }
{ {
initWellPerfData(); initWellPerfData();
} }