diff --git a/ebos/eclbaseaquifermodel.hh b/ebos/eclbaseaquifermodel.hh index 248387597..c140b7422 100644 --- a/ebos/eclbaseaquifermodel.hh +++ b/ebos/eclbaseaquifermodel.hh @@ -72,7 +72,7 @@ public: * aquifer pressure and the base run's total produced liquid * volume from the model's aquifers. */ - void initFromRestart(const std::vector& aquiferSoln OPM_UNUSED) + void initFromRestart(const data::Aquifers& aquiferSoln OPM_UNUSED) { throw std::logic_error { "Initialization from restart data not supported " diff --git a/ebos/eclgenericwriter.cc b/ebos/eclgenericwriter.cc index 99c404635..ed9114695 100644 --- a/ebos/eclgenericwriter.cc +++ b/ebos/eclgenericwriter.cc @@ -392,6 +392,7 @@ doWriteOutput(const int reportStepNum, data::Solution&& localCellData, data::Wells&& localWellData, data::GroupAndNetworkValues&& localGroupAndNetworkData, + data::Aquifers&& localAquiferData, const Action::State& actionState, const UDQState& udqState, const SummaryState& summaryState, @@ -410,7 +411,10 @@ doWriteOutput(const int reportStepNum, : std::move(localWellData), isParallel ? this->collectToIORank_.globalGroupAndNetworkData() - : std::move(localGroupAndNetworkData) + : std::move(localGroupAndNetworkData), + + isParallel ? this->collectToIORank_.globalAquiferData() + : std::move(localAquiferData) }; if (eclState_.getSimulationConfig().useThresholdPressure()) { diff --git a/ebos/eclgenericwriter.hh b/ebos/eclgenericwriter.hh index 3b6739ece..0126acc2a 100644 --- a/ebos/eclgenericwriter.hh +++ b/ebos/eclgenericwriter.hh @@ -82,6 +82,7 @@ protected: data::Solution&& localCellData, data::Wells&& localWellData, data::GroupAndNetworkValues&& localGroupAndNetworkData, + data::Aquifers&& localAquiferData, const Action::State& actionState, const UDQState& udqState, const SummaryState& summaryState, diff --git a/ebos/eclproblem.hh b/ebos/eclproblem.hh index 2d65ff74a..f61778c38 100644 --- a/ebos/eclproblem.hh +++ b/ebos/eclproblem.hh @@ -1885,6 +1885,9 @@ public: EclWellModel& wellModel() { return wellModel_; } + const EclAquiferModel& aquiferModel() const + { return aquiferModel_; } + EclAquiferModel& mutableAquiferModel() { return aquiferModel_; } diff --git a/ebos/eclwriter.hh b/ebos/eclwriter.hh index bb70726b7..bcde644bc 100644 --- a/ebos/eclwriter.hh +++ b/ebos/eclwriter.hh @@ -141,7 +141,6 @@ public: /*! * \brief collect and pass data and pass it to eclIO writer */ - void evalSummaryState(bool isSubStep) { const int reportStepNum = simulator_.episodeIndex() + 1; @@ -176,7 +175,7 @@ public: .groupAndNetworkData(reportStepNum, simulator_.vanguard().schedule()); - const auto localAquiferData = simulator_.problem().mutableAquiferModel().aquiferData(); + const auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); this->prepareLocalCellData(isSubStep, reportStepNum); @@ -221,7 +220,6 @@ public: eclOutputModule_->initialInplace()); } - void writeOutput(bool isSubStep) { const int reportStepNum = simulator_.episodeIndex() + 1; @@ -234,6 +232,8 @@ public: auto localGroupAndNetworkData = simulator_.problem().wellModel() .groupAndNetworkData(reportStepNum, simulator_.vanguard().schedule()); + auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); + data::Solution localCellData = {}; if (! isSubStep) { this->eclOutputModule_->assignToSolution(localCellData); @@ -248,7 +248,7 @@ public: eclOutputModule_->getWBPData(), localWellData, localGroupAndNetworkData, - {}); + localAquiferData); } if (this->collectToIORank_.isIORank()) { @@ -258,6 +258,7 @@ public: std::move(localCellData), std::move(localWellData), std::move(localGroupAndNetworkData), + std::move(localAquiferData), this->actionState(), this->udqState(), this->summaryState(), diff --git a/opm/simulators/aquifers/AquiferFetkovich.hpp b/opm/simulators/aquifers/AquiferFetkovich.hpp index 844d3aa6f..0b5faf21b 100644 --- a/opm/simulators/aquifers/AquiferFetkovich.hpp +++ b/opm/simulators/aquifers/AquiferFetkovich.hpp @@ -83,8 +83,9 @@ public: data.volume = this->W_flux_.value(); data.initPressure = this->pa0_; data.type = data::AquiferType::Fetkovich; - // Not handling std::shared_ptr aquFet for now, - // because we do not need it yet + + data.aquFet = std::make_shared(); + return data; } diff --git a/opm/simulators/aquifers/AquiferInterface.hpp b/opm/simulators/aquifers/AquiferInterface.hpp index a26431079..88e739a77 100644 --- a/opm/simulators/aquifers/AquiferInterface.hpp +++ b/opm/simulators/aquifers/AquiferInterface.hpp @@ -88,19 +88,16 @@ public: { } - void initFromRestart(const std::vector& aquiferSoln) + void initFromRestart(const data::Aquifers& aquiferSoln) { - auto xaqPos - = std::find_if(aquiferSoln.begin(), aquiferSoln.end(), [this](const data::AquiferData& xaq) -> bool { - return xaq.aquiferID == this->aquiferID(); - }); - + auto xaqPos = aquiferSoln.find(this->aquiferID()); if (xaqPos == aquiferSoln.end()) return; - this->assignRestartData(*xaqPos); - this->W_flux_ = xaqPos->volume; - this->pa0_ = xaqPos->initPressure; + this->assignRestartData(xaqPos->second); + + this->W_flux_ = xaqPos->second.volume; + this->pa0_ = xaqPos->second.initPressure; this->solution_set_from_restart_ = true; } diff --git a/opm/simulators/aquifers/AquiferNumerical.hpp b/opm/simulators/aquifers/AquiferNumerical.hpp index e52f11130..5f5dbf9fd 100644 --- a/opm/simulators/aquifers/AquiferNumerical.hpp +++ b/opm/simulators/aquifers/AquiferNumerical.hpp @@ -72,7 +72,7 @@ public: } } - void initFromRestart([[maybe_unused]]const std::vector& aquiferSoln) + void initFromRestart([[maybe_unused]]const data::Aquifers& aquiferSoln) { // NOT handling Restart for now } diff --git a/opm/simulators/aquifers/BlackoilAquiferModel.hpp b/opm/simulators/aquifers/BlackoilAquiferModel.hpp index 2d064ab31..124810d00 100644 --- a/opm/simulators/aquifers/BlackoilAquiferModel.hpp +++ b/opm/simulators/aquifers/BlackoilAquiferModel.hpp @@ -87,7 +87,7 @@ public: explicit BlackoilAquiferModel(Simulator& simulator); void initialSolutionApplied(); - void initFromRestart(const std::vector& aquiferSoln); + void initFromRestart(const data::Aquifers& aquiferSoln); void beginEpisode(); void beginTimeStep(); diff --git a/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp b/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp index 0aea20558..bf09ec5c3 100644 --- a/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp +++ b/opm/simulators/aquifers/BlackoilAquiferModel_impl.hpp @@ -59,19 +59,21 @@ BlackoilAquiferModel::initialSolutionApplied() template void -BlackoilAquiferModel::initFromRestart(const std::vector& aquiferSoln) +BlackoilAquiferModel::initFromRestart(const data::Aquifers& aquiferSoln) { - if (aquiferCarterTracyActive()) { - for (auto& aquifer : aquifers_CarterTracy) { + if (this->aquiferCarterTracyActive()) { + for (auto& aquifer : this->aquifers_CarterTracy) { aquifer.initFromRestart(aquiferSoln); } } - if (aquiferFetkovichActive()) { - for (auto& aquifer : aquifers_Fetkovich) { + + if (this->aquiferFetkovichActive()) { + for (auto& aquifer : this->aquifers_Fetkovich) { aquifer.initFromRestart(aquiferSoln); } } - if (aquiferNumericalActive()) { + + if (this->aquiferNumericalActive()) { for (auto& aquifer : this->aquifers_numerical) { aquifer.initFromRestart(aquiferSoln); } diff --git a/opm/simulators/utils/ParallelRestart.cpp b/opm/simulators/utils/ParallelRestart.cpp index b57a06590..c796060a7 100644 --- a/opm/simulators/utils/ParallelRestart.cpp +++ b/opm/simulators/utils/ParallelRestart.cpp @@ -22,9 +22,12 @@ #endif #include "ParallelRestart.hpp" -#include +#include #include +#include +#include #include +#include #include #include #include @@ -214,13 +217,37 @@ std::size_t packSize(const std::array& data, Dune::MPIHelper::MPICommunicat return N*packSize(data[0], comm); } +HANDLE_AS_POD(data::CarterTracyData) HANDLE_AS_POD(data::Connection) HANDLE_AS_POD(data::CurrentControl) +HANDLE_AS_POD(data::FetkovichData) HANDLE_AS_POD(data::GroupConstraints) HANDLE_AS_POD(data::NodeData) HANDLE_AS_POD(data::Rates) HANDLE_AS_POD(data::Segment) +std::size_t packSize(const data::AquiferData& data, Dune::MPIHelper::MPICommunicator comm) +{ + const auto type = 0ull; + + const auto base = packSize(data.aquiferID, comm) + + packSize(data.pressure, comm) + + packSize(data.fluxRate, comm) + + packSize(data.volume, comm) + + packSize(data.initPressure, comm) + + packSize(data.datumDepth, comm) + + packSize(type, comm); + + if (data.aquFet != nullptr) { + return base + packSize(*data.aquFet, comm); + } + else if (data.aquCT != nullptr) { + return base + packSize(*data.aquCT, comm); + } + + return base; +} + std::size_t packSize(const data::GuideRateValue&, Dune::MPIHelper::MPICommunicator comm) { const auto nItem = static_cast(data::GuideRateValue::Item::NumItems); @@ -289,6 +316,7 @@ std::size_t packSize(const RestartValue& data, Dune::MPIHelper::MPICommunicator return packSize(data.solution, comm) + packSize(data.wells, comm) + packSize(data.grp_nwrk, comm) + + packSize(data.aquifer, comm) + packSize(data.extra, comm); } @@ -485,6 +513,29 @@ void pack(const std::unordered_map& data, std::vector& buffer } } +void pack(const data::AquiferData& data, std::vector& buffer, int& position, + Dune::MPIHelper::MPICommunicator comm) +{ + const auto type = + (data.aquFet != nullptr)*(1ull << 0) + + (data.aquCT != nullptr)*(1ull << 1); + + pack(data.aquiferID, buffer, position, comm); + pack(data.pressure, buffer, position, comm); + pack(data.fluxRate, buffer, position, comm); + pack(data.volume, buffer, position, comm); + pack(data.initPressure, buffer, position, comm); + pack(data.datumDepth, buffer, position, comm); + pack(type, buffer, position, comm); + + if (data.aquFet != nullptr) { + pack(*data.aquFet, buffer, position, comm); + } + else if (data.aquCT != nullptr) { + pack(*data.aquCT, buffer, position, comm); + } +} + void pack(const data::GuideRateValue& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { @@ -582,6 +633,7 @@ void pack(const RestartValue& data, std::vector& buffer, int& position, pack(data.solution, buffer, position, comm); pack(data.wells, buffer, position, comm); pack(data.grp_nwrk, buffer, position, comm); + pack(data.aquifer, buffer, position, comm); pack(data.extra, buffer, position, comm); } @@ -813,6 +865,31 @@ void unpack(data::Well& data, std::vector& buffer, int& position, unpack(data.guide_rates, buffer, position, comm); } +void unpack(data::AquiferData& data, std::vector& buffer, int& position, + Dune::MPIHelper::MPICommunicator comm) +{ + auto type = 0ull; + + unpack(data.aquiferID, buffer, position, comm); + unpack(data.pressure, buffer, position, comm); + unpack(data.fluxRate, buffer, position, comm); + unpack(data.volume, buffer, position, comm); + unpack(data.initPressure, buffer, position, comm); + unpack(data.datumDepth, buffer, position, comm); + unpack(type, buffer, position, comm); + + if (type == 1ull) { + data.type = data::AquiferType::Fetkovich; + data.aquFet = std::make_shared(); + unpack(*data.aquFet, buffer, position, comm); + } + else if (type == 2ull) { + data.type = data::AquiferType::CarterTracy; + data.aquCT = std::make_shared(); + unpack(*data.aquCT, buffer, position, comm); + } +} + void unpack(data::GuideRateValue& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { @@ -893,6 +970,7 @@ void unpack(RestartValue& data, std::vector& buffer, int& position, unpack(data.solution, buffer, position, comm); unpack(data.wells, buffer, position, comm); unpack(data.grp_nwrk, buffer, position, comm); + unpack(data.aquifer, buffer, position, comm); unpack(data.extra, buffer, position, comm); } @@ -964,6 +1042,7 @@ INSTANTIATE_PACK(std::map,int>>) INSTANTIATE_PACK(std::map) INSTANTIATE_PACK(std::map) INSTANTIATE_PACK(std::map) +INSTANTIATE_PACK(std::map) INSTANTIATE_PACK(std::unordered_map) INSTANTIATE_PACK(std::unordered_map) INSTANTIATE_PACK(std::unordered_set) @@ -979,10 +1058,7 @@ RestartValue loadParallelRestart(const EclipseIO* eclIO, Action::State& actionSt Dune::CollectiveCommunication comm) { #if HAVE_MPI - data::Solution sol; - data::Wells wells; - data::GroupAndNetworkValues grp_nwrk; - RestartValue restartValues(sol, wells, grp_nwrk); + RestartValue restartValues{}; if (eclIO) { diff --git a/opm/simulators/utils/ParallelRestart.hpp b/opm/simulators/utils/ParallelRestart.hpp index e0a6fca37..0013be121 100644 --- a/opm/simulators/utils/ParallelRestart.hpp +++ b/opm/simulators/utils/ParallelRestart.hpp @@ -49,9 +49,12 @@ class RestartValue; namespace data { +struct AquiferData; +struct CarterTracyData; struct CellData; struct Connection; struct CurrentControl; +struct FetkovichData; class GroupAndNetworkValues; struct GroupConstraints; struct GroupData; @@ -331,9 +334,12 @@ void unpack(char* str, std::size_t length, std::vector& buffer, int& posit void unpack(T& data, std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); +ADD_PACK_PROTOTYPES(data::AquiferData) +ADD_PACK_PROTOTYPES(data::CarterTracyData) ADD_PACK_PROTOTYPES(data::CellData) ADD_PACK_PROTOTYPES(data::Connection) ADD_PACK_PROTOTYPES(data::CurrentControl) +ADD_PACK_PROTOTYPES(data::FetkovichData) ADD_PACK_PROTOTYPES(data::Rates) ADD_PACK_PROTOTYPES(data::Segment) ADD_PACK_PROTOTYPES(data::Solution) diff --git a/tests/test_ParallelRestart.cpp b/tests/test_ParallelRestart.cpp index 2a36f7db0..34bf7e5ba 100644 --- a/tests/test_ParallelRestart.cpp +++ b/tests/test_ParallelRestart.cpp @@ -24,6 +24,7 @@ #include +#include #include #include @@ -116,6 +117,7 @@ #include #include #include +#include #include #include #include @@ -260,6 +262,39 @@ Opm::data::NodeData getNodeData() 123.457 }; } + +Opm::data::AquiferData getFetkovichAquifer(const int aquiferID = 1) +{ + auto aquifer = Opm::data::AquiferData { + aquiferID, 123.456, 56.78, 9.0e10, 290.0, 2515.5, Opm::data::AquiferType::Fetkovich + }; + + aquifer.aquFet = std::make_shared(); + + aquifer.aquFet->initVolume = 1.23; + aquifer.aquFet->prodIndex = 45.67; + aquifer.aquFet->timeConstant = 890.123; + + return aquifer; +} + +Opm::data::AquiferData getCarterTracyAquifer(const int aquiferID = 5) +{ + auto aquifer = Opm::data::AquiferData { + aquiferID, 123.456, 56.78, 9.0e10, 290.0, 2515.5, Opm::data::AquiferType::CarterTracy + }; + + aquifer.aquCT = std::make_shared(); + + aquifer.aquCT->timeConstant = 987.65; + aquifer.aquCT->influxConstant = 43.21; + aquifer.aquCT->waterDensity = 1014.5; + aquifer.aquCT->waterViscosity = 0.00318; + aquifer.aquCT->dimensionless_time = 42.0; + aquifer.aquCT->dimensionless_pressure = 2.34; + + return aquifer; +} } @@ -313,6 +348,35 @@ BOOST_AUTO_TEST_CASE(Rates) DO_CHECKS(data::Rates) } +BOOST_AUTO_TEST_CASE(dataFetkovichData) +{ + const auto val1 = getFetkovichAquifer(); + const auto val2 = PackUnpack(val1); + + DO_CHECKS(data::FetkovichData) +} + +BOOST_AUTO_TEST_CASE(dataCarterTracyData) +{ + const auto val1 = getCarterTracyAquifer(); + const auto val2 = PackUnpack(val1); + + DO_CHECKS(data::CarterTracyData) +} + +BOOST_AUTO_TEST_CASE(dataAquifers) +{ + const auto val1 = Opm::data::Aquifers { + { 1, getFetkovichAquifer(1) }, + { 4, getFetkovichAquifer(4) }, + { 5, getCarterTracyAquifer(5) }, + }; + + const auto val2 = PackUnpack(val1); + + DO_CHECKS(data::Aquifers) +} + BOOST_AUTO_TEST_CASE(dataGuideRateValue) { using Item = Opm::data::GuideRateValue::Item; @@ -436,8 +500,13 @@ BOOST_AUTO_TEST_CASE(RestartValue) } }; + auto aquifers = Opm::data::Aquifers { + { 2, getCarterTracyAquifer(2) }, + {11, getFetkovichAquifer(11) }, + }; + const auto val1 = Opm::RestartValue { - getSolution(), std::move(wells1), std::move(grp_nwrk_1) + getSolution(), std::move(wells1), std::move(grp_nwrk_1), std::move(aquifers) }; const auto val2 = PackUnpack(val1);