From 197282ccfcf0b98d15c9f808e704185652f46098 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Thu, 17 Oct 2024 13:05:39 +0200 Subject: [PATCH] cleaing up EclWriter related and DamarisWriter.hpp --- flowexperimental/comp/EmptyModel.hpp | 97 +++++++++ flowexperimental/comp/flowexp_comp.hpp | 51 +---- opm/simulators/flow/DamarisWriter.hpp | 2 +- opm/simulators/flow/EclGenericWriter.hpp | 7 - opm/simulators/flow/EclGenericWriter_impl.hpp | 133 +++--------- opm/simulators/flow/EclWriter.hpp | 202 +++++++++--------- 6 files changed, 220 insertions(+), 272 deletions(-) create mode 100644 flowexperimental/comp/EmptyModel.hpp diff --git a/flowexperimental/comp/EmptyModel.hpp b/flowexperimental/comp/EmptyModel.hpp new file mode 100644 index 000000000..9b772320c --- /dev/null +++ b/flowexperimental/comp/EmptyModel.hpp @@ -0,0 +1,97 @@ +/* + Copyright 2024, SINTEF Digital + + 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 . +*/ + + +// this is an empty model that having a lot of empty interfaces. +// it is use for the development when some facility class are not ready + +#include +#include + +#include +#include + +namespace Opm { + +template +class EmptyModel : public BaseAuxiliaryModule +{ + using Scalar = GetPropType; + using GridView = GetPropType; + using GlobalEqVector = GetPropType; + using SparseMatrixAdapter = GetPropType; + +public: + using Simulator = GetPropType; + EmptyModel(Simulator& /*simulator*/) + { + } + + void init(){} + template + void init(Something /*A*/){} + void prepareTracerBatches(){}; + using NeighborSet = std::set; + void linearize(SparseMatrixAdapter& /*matrix*/, GlobalEqVector& /*residual*/){}; + unsigned numDofs() const{return 0;}; + void addNeighbors(std::vector& /*neighbors*/) const{}; + //void applyInitial(){}; + void initialSolutionApplied(){}; + //void initFromRestart(const data::Aquifers& aquiferSoln); + template + void serialize(Restarter& /*res*/){}; + + template + void deserialize(Restarter& /*res*/){}; + + void beginEpisode(){}; + void beginTimeStep(){}; + void beginIteration(){}; + // add the water rate due to aquifers to the source term. + template + void addToSource(RateVector& /*rates*/, const Context& /*context*/, + unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const {} + template + void addToSource(RateVector& /*rates*/, unsigned /*globalSpaceIdx*/, + unsigned /*timeIdx*/) const {} + void endIteration()const{}; + void endTimeStep(){}; + void endEpisode(){}; + void applyInitial(){}; + template + void computeTotalRatesForDof(RateType& /*rate*/, unsigned /*globalIdx*/) const{}; + + auto wellData() const { + return data::Wells{}; + } + auto wellBlockAveragePressures() const { + return data::WellBlockAveragePressures{}; + } + auto groupAndNetworkData(const int&) const { + return data::GroupAndNetworkValues{}; + } + auto wellTestState() const { + return WellTestState{}; + } + auto aquiferData() const { + return data::Aquifers{}; + } +}; + +} // end of namespace Opm diff --git a/flowexperimental/comp/flowexp_comp.hpp b/flowexperimental/comp/flowexp_comp.hpp index 10884ab55..213d63c07 100644 --- a/flowexperimental/comp/flowexp_comp.hpp +++ b/flowexperimental/comp/flowexp_comp.hpp @@ -30,6 +30,8 @@ #include +#include + // // the current code use eclnewtonmethod adding other conditions to proceed_ should do the trick for KA // // adding linearshe sould be chaning the update_ function in the same class with condition that the error is reduced. // the trick is to be able to recalculate the residual from here. @@ -37,55 +39,6 @@ // suggestTimeStep is taken from newton solver in problem.limitTimestep namespace Opm { -template -class EmptyModel : public BaseAuxiliaryModule -{ - using Scalar = GetPropType; - using GridView = GetPropType; - using GlobalEqVector = GetPropType; - using SparseMatrixAdapter = GetPropType; - -public: - using Simulator = GetPropType; - EmptyModel(Simulator& /*simulator*/) - { - } - - void init(){} - template - void init(Something /*A*/){} - void prepareTracerBatches(){}; - using NeighborSet = std::set; - void linearize(SparseMatrixAdapter& /*matrix*/, GlobalEqVector& /*residual*/){}; - unsigned numDofs() const{return 0;}; - void addNeighbors(std::vector& /*neighbors*/) const{}; - //void applyInitial(){}; - void initialSolutionApplied(){}; - //void initFromRestart(const data::Aquifers& aquiferSoln); - template - void serialize(Restarter& /*res*/){}; - - template - void deserialize(Restarter& /*res*/){}; - - void beginEpisode(){}; - void beginTimeStep(){}; - void beginIteration(){}; - // add the water rate due to aquifers to the source term. - template - void addToSource(RateVector& /*rates*/, const Context& /*context*/, - unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const {} - template - void addToSource(RateVector& /*rates*/, unsigned /*globalSpaceIdx*/, - unsigned /*timeIdx*/) const {} - void endIteration()const{}; - void endTimeStep(){}; - void endEpisode(){}; - void applyInitial(){}; - template - void computeTotalRatesForDof(RateType& /*rate*/, unsigned /*globalIdx*/) const{}; -}; - template int dispatchFlowExpComp(int argc, char** argv); diff --git a/opm/simulators/flow/DamarisWriter.hpp b/opm/simulators/flow/DamarisWriter.hpp index 058e8570c..22a7af7be 100644 --- a/opm/simulators/flow/DamarisWriter.hpp +++ b/opm/simulators/flow/DamarisWriter.hpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/opm/simulators/flow/EclGenericWriter.hpp b/opm/simulators/flow/EclGenericWriter.hpp index f28912e9b..fee0f0c65 100644 --- a/opm/simulators/flow/EclGenericWriter.hpp +++ b/opm/simulators/flow/EclGenericWriter.hpp @@ -134,13 +134,6 @@ protected: bool isFloresn, std::array, 3>&& floresn); - void doWriteOutput(const int reportStepNum, - const std::optional timeStepNum, - const bool isSubStep, - Scalar curTime, - Scalar nextStepSize, - data::Solution&& localCellData); - void evalSummary(int reportStepNum, Scalar curTime, const data::Wells& localWellData, diff --git a/opm/simulators/flow/EclGenericWriter_impl.hpp b/opm/simulators/flow/EclGenericWriter_impl.hpp index 05f943590..b033333aa 100644 --- a/opm/simulators/flow/EclGenericWriter_impl.hpp +++ b/opm/simulators/flow/EclGenericWriter_impl.hpp @@ -136,6 +136,10 @@ getInterRegFlowsAsMap(const Opm::InterRegFlowMap& map) struct EclWriteTasklet : public Opm::TaskletInterface { + Opm::Action::State actionState_; + Opm::WellTestState wtestState_; + Opm::SummaryState summaryState_; + Opm::UDQState udqState_; Opm::EclipseIO& eclIO_; int reportStepNum_; std::optional timeStepNum_; @@ -143,48 +147,45 @@ struct EclWriteTasklet : public Opm::TaskletInterface double secondsElapsed_; Opm::RestartValue restartValue_; bool writeDoublePrecision_; - std::optional actionState_; - std::optional wtestState_; - std::optional summaryState_; - std::optional udqState_; - explicit EclWriteTasklet(Opm::EclipseIO& eclIO, + explicit EclWriteTasklet(const Opm::Action::State& actionState, + const Opm::WellTestState& wtestState, + const Opm::SummaryState& summaryState, + const Opm::UDQState& udqState, + Opm::EclipseIO& eclIO, int reportStepNum, std::optional timeStepNum, bool isSubStep, double secondsElapsed, Opm::RestartValue restartValue, - bool writeDoublePrecision, - std::optional actionState = std::nullopt, - std::optional wtestState = std::nullopt, - std::optional summaryState = std::nullopt, - std::optional udqState = std::nullopt) - : eclIO_(eclIO) + bool writeDoublePrecision) + : actionState_(actionState) + , wtestState_(wtestState) + , summaryState_(summaryState) + , udqState_(udqState) + , eclIO_(eclIO) , reportStepNum_(reportStepNum) , timeStepNum_(timeStepNum) , isSubStep_(isSubStep) , secondsElapsed_(secondsElapsed) , restartValue_(std::move(restartValue)) , writeDoublePrecision_(writeDoublePrecision) - , actionState_(std::move(actionState)) - , wtestState_(std::move(wtestState)) - , summaryState_(std::move(summaryState)) - , udqState_(std::move(udqState)) {} // callback to eclIO serial writeTimeStep method void run() { - this->eclIO_.writeTimeStep(this->reportStepNum_, + this->eclIO_.writeTimeStep(this->actionState_, + this->wtestState_, + this->summaryState_, + this->udqState_, + this->reportStepNum_, this->isSubStep_, this->secondsElapsed_, std::move(this->restartValue_), this->writeDoublePrecision_, - this->timeStepNum_, - std::move(this->actionState_), - std::move(this->wtestState_), - std::move(this->summaryState_), - std::move(this->udqState_)); + this->timeStepNum_ +); } }; @@ -608,102 +609,16 @@ doWriteOutput(const int reportStepNum, } // create a tasklet to write the data for the current time step to disk - auto eclWriteTasklet = std::make_shared(/* + auto eclWriteTasklet = std::make_shared( actionState, isParallel ? this->collectOnIORank_.globalWellTestState() : std::move(localWTestState), - summaryState, udqState, */*this->eclIO_, + summaryState, udqState, *this->eclIO_, reportStepNum, timeStepNum, isSubStep, curTime, std::move(restartValue), doublePrecision); // finally, start a new output writing job this->taskletRunner_->dispatch(std::move(eclWriteTasklet)); } -template -void EclGenericWriter:: -doWriteOutput(const int reportStepNum, - const std::optional timeStepNum, - const bool isSubStep, - Scalar curTime, - Scalar nextStepSize, - data::Solution&& localCellData) -{ - - const auto isParallel = this->collectOnIORank_.isParallel(); - const bool needsReordering = this->collectOnIORank_.doesNeedReordering(); - - data::Wells localWellData {}; - data::WellBlockAveragePressures localWBP{}; - data::GroupAndNetworkValues localGroupAndNetworkData{}; - std::map localAquiferData {}; - - RestartValue restartValue { - (isParallel || needsReordering) - ? this->collectOnIORank_.globalCellData() - : std::move(localCellData), - - isParallel ? this->collectOnIORank_.globalWellData() - : std::move(localWellData), - - isParallel ? this->collectOnIORank_.globalGroupAndNetworkData() - : std::move(localGroupAndNetworkData), - - isParallel ? this->collectOnIORank_.globalAquiferData() - : std::move(localAquiferData) - }; - -// if (eclState_.getSimulationConfig().useThresholdPressure()) { -// restartValue.addExtra("THRESHPR", UnitSystem::measure::pressure, -// thresholdPressure); -// } - - // Add suggested next timestep to extra data. - if (! isSubStep) { - restartValue.addExtra("OPMEXTRA", std::vector(1, nextStepSize)); - } - - // Add nnc flows and flores. -// if (false/*isFlowsn*/) { -// const auto flowsn_global = isParallel ? this->collectOnIORank_.globalFlowsn() : std::move(flowsn); -// for (const auto& flows : flowsn_global) { -// if (flows.name.empty()) -// continue; -// if (flows.name == "FLOGASN+") { -// restartValue.addExtra(flows.name, UnitSystem::measure::gas_surface_rate, flows.values); -// } else { -// restartValue.addExtra(flows.name, UnitSystem::measure::liquid_surface_rate, flows.values); -// } -// } -// } -// if (/*isFloresn*/) { -// const auto floresn_global = isParallel ? this->collectOnIORank_.globalFloresn() : std::move(floresn); -// for (const auto& flores : floresn_global) { -// if (flores.name.empty()) { -// continue; -// } -// restartValue.addExtra(flores.name, UnitSystem::measure::rate, flores.values); -// } -// } - // make sure that the previous I/O request has been completed - // and the number of incomplete tasklets does not increase between - // time steps - this->taskletRunner_->barrier(); - - // check if there might have been a failure in the TaskletRunner - if (this->taskletRunner_->failure()) { - throw std::runtime_error("Failure in the TaskletRunner while writing output."); - } - - // create a tasklet to write the data for the current time step to disk - auto eclWriteTasklet = std::make_shared( - /* actionState, - isParallel ? this->collectOnIORank_.globalWellTestState() : std::move(localWTestState), - summaryState, udqState, */ *this->eclIO_, - reportStepNum, timeStepNum, isSubStep, curTime, std::move(restartValue), /* doublePrecision*/ false); - - // finally, start a new output writing job - this->taskletRunner_->dispatch(std::move(eclWriteTasklet)); -} - template void EclGenericWriter:: evalSummary(const int reportStepNum, diff --git a/opm/simulators/flow/EclWriter.hpp b/opm/simulators/flow/EclWriter.hpp index b16454869..775f63de0 100644 --- a/opm/simulators/flow/EclWriter.hpp +++ b/opm/simulators/flow/EclWriter.hpp @@ -227,49 +227,49 @@ public: simulator_.setupTimer().realTimeElapsed() + simulator_.vanguard().setupTime(); - // const auto localWellData = simulator_.problem().wellModel().wellData(); - // const auto localWBP = simulator_.problem().wellModel().wellBlockAveragePressures(); - // const auto localGroupAndNetworkData = simulator_.problem().wellModel() - // .groupAndNetworkData(reportStepNum); - // - // const auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); - // const auto localWellTestState = simulator_.problem().wellModel().wellTestState(); + const auto localWellData = simulator_.problem().wellModel().wellData(); + const auto localWBP = simulator_.problem().wellModel().wellBlockAveragePressures(); + const auto localGroupAndNetworkData = simulator_.problem().wellModel() + .groupAndNetworkData(reportStepNum); + + const auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); + const auto localWellTestState = simulator_.problem().wellModel().wellTestState(); this->prepareLocalCellData(isSubStep, reportStepNum); if (this->outputModule_->needInterfaceFluxes(isSubStep)) { this->captureLocalFluxData(); } - // if (this->collectOnIORank_.isParallel()) { - // OPM_BEGIN_PARALLEL_TRY_CATCH() - // - // this->collectOnIORank_.collect({}, - // outputModule_->getBlockData(), - // localWellData, - // localWBP, - // localGroupAndNetworkData, - // localAquiferData, - // localWellTestState, - // this->outputModule_->getInterRegFlows(), - // {}, - // {}); - // - // if (this->collectOnIORank_.isIORank()) { - // auto& iregFlows = this->collectOnIORank_.globalInterRegFlows(); - // - // if (! iregFlows.readIsConsistent()) { - // throw std::runtime_error { - // "Inconsistent inter-region flow " - // "region set names in parallel" - // }; - // } - // - // iregFlows.compress(); - // } - // - // OPM_END_PARALLEL_TRY_CATCH("Collect to I/O rank: ", - // this->simulator_.vanguard().grid().comm()); - // } + if (this->collectOnIORank_.isParallel()) { + OPM_BEGIN_PARALLEL_TRY_CATCH() + + this->collectOnIORank_.collect({}, + outputModule_->getBlockData(), + localWellData, + localWBP, + localGroupAndNetworkData, + localAquiferData, + localWellTestState, + this->outputModule_->getInterRegFlows(), + {}, + {}); + + if (this->collectOnIORank_.isIORank()) { + auto& iregFlows = this->collectOnIORank_.globalInterRegFlows(); + + if (! iregFlows.readIsConsistent()) { + throw std::runtime_error { + "Inconsistent inter-region flow " + "region set names in parallel" + }; + } + + iregFlows.compress(); + } + + OPM_END_PARALLEL_TRY_CATCH("Collect to I/O rank: ", + this->simulator_.vanguard().grid().comm()); + } std::map miscSummaryData; @@ -323,11 +323,6 @@ public: ? this->collectOnIORank_.globalInterRegFlows() : this->outputModule_->getInterRegFlows(); - const data::Wells& localWellData {}; - const data::WellBlockAveragePressures& localWBP{}; - const data::GroupAndNetworkValues& localGroupAndNetworkData{}; - const std::map& localAquiferData {}; - this->evalSummary(reportStepNum, curTime, localWellData, @@ -420,20 +415,19 @@ public: this->outputModule_->outputErrorLog(simulator_.gridView().comm()); // output using eclWriter if enabled - // auto localWellData = simulator_.problem().wellModel().wellData(); - // auto localGroupAndNetworkData = simulator_.problem().wellModel() - // .groupAndNetworkData(reportStepNum); + auto localWellData = simulator_.problem().wellModel().wellData(); + auto localGroupAndNetworkData = simulator_.problem().wellModel() + .groupAndNetworkData(reportStepNum); + + auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); + auto localWellTestState = simulator_.problem().wellModel().wellTestState(); + + const bool isFlowsn = this->outputModule_->hasFlowsn(); + auto flowsn = this->outputModule_->getFlowsn(); + + const bool isFloresn = this->outputModule_->hasFloresn(); + auto floresn = this->outputModule_->getFloresn(); - // auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); - // auto localWellTestState = simulator_.problem().wellModel().wellTestState(); - // - // const bool isFlowsn = this->outputModule_->hasFlowsn(); - // auto flowsn = this->outputModule_->getFlowsn(); - // - // const bool isFloresn = this->outputModule_->hasFloresn(); - // auto floresn = this->outputModule_->getFloresn(); - // - // data::Solution localCellData = {}; if (! isSubStep || Parameters::Get()) { if (localCellData.empty()) { @@ -443,7 +437,7 @@ public: // Collect RFT data on rank 0 this->outputModule_->accumulateRftDataParallel(simulator_.gridView().comm()); // Add cell data to perforations for RFT output - // this->outputModule_->addRftDataToWells(localWellData, reportStepNum); + this->outputModule_->addRftDataToWells(localWellData, reportStepNum); } if (this->collectOnIORank_.isParallel() || @@ -454,19 +448,19 @@ public: // output. There's consequently no need to collect those // properties on the I/O rank. - // this->collectOnIORank_.collect(localCellData, - // this->outputModule_->getBlockData(), - // localWellData, - // /* wbpData = */ {}, - // localGroupAndNetworkData, - // localAquiferData, - // localWellTestState, - // /* interRegFlows = */ {}, - // flowsn, - // floresn); - // if (this->collectOnIORank_.isIORank()) { - // this->outputModule_->assignGlobalFieldsToSolution(this->collectOnIORank_.globalCellData()); - // } + this->collectOnIORank_.collect(localCellData, + this->outputModule_->getBlockData(), + localWellData, + /* wbpData = */ {}, + localGroupAndNetworkData, + localAquiferData, + localWellTestState, + /* interRegFlows = */ {}, + flowsn, + floresn); + if (this->collectOnIORank_.isIORank()) { + this->outputModule_->assignGlobalFieldsToSolution(this->collectOnIORank_.globalCellData()); + } } else { this->outputModule_->assignGlobalFieldsToSolution(localCellData); } @@ -478,24 +472,20 @@ public: if (Parameters::Get()) { timeStepIdx = simulator_.timeStepIndex(); } - this->doWriteOutput(reportStepNum, - timeStepIdx, - isSubStep, - curTime, - nextStepSize, - std::move(localCellData) ); - // std::move(localWellData), - // std::move(localGroupAndNetworkData), - // std::move(localAquiferData), - // std::move(localWellTestState), - // this->actionState(), - // this->udqState(), - // this->summaryState(), - // this->simulator_.problem().thresholdPressure().getRestartVector(), - // curTime, nextStepSize, - // Parameters::Get(), - // isFlowsn, std::move(flowsn), - // isFloresn, std::move(floresn)); + this->doWriteOutput(reportStepNum, timeStepIdx, isSubStep, + std::move(localCellData), + std::move(localWellData), + std::move(localGroupAndNetworkData), + std::move(localAquiferData), + std::move(localWellTestState), + this->actionState(), + this->udqState(), + this->summaryState(), + {}, // this->simulator_.problem().thresholdPressure().getRestartVector(), + curTime, nextStepSize, + Parameters::Get(), + isFlowsn, std::move(flowsn), + isFloresn, std::move(floresn)); } } @@ -745,26 +735,26 @@ private: this->outputModule_->accumulateDensityParallel(); } -// if constexpr (enableMech) { -// if (simulator_.vanguard().eclState().runspec().mech()) { -// OPM_TIMEBLOCK(prepareMechData); -// for (const auto& elem : elements(gridView, Dune::Partitions::interior)) { -// elemCtx.updatePrimaryStencil(elem); -// elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); -// outputModule_->processElementMech(elemCtx); -// } -// } -// } + if constexpr (enableMech) { + if (simulator_.vanguard().eclState().runspec().mech()) { + OPM_TIMEBLOCK(prepareMechData); + for (const auto& elem : elements(gridView, Dune::Partitions::interior)) { + elemCtx.updatePrimaryStencil(elem); + elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); + outputModule_->processElementMech(elemCtx); + } + } + } -// if (! this->simulator_.model().linearizer().getFlowsInfo().empty()) { -// OPM_TIMEBLOCK(prepareFlowsData); -// for (const auto& elem : elements(gridView, Dune::Partitions::interior)) { -// elemCtx.updatePrimaryStencil(elem); -// elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); -// -// this->outputModule_->processElementFlows(elemCtx); -// } -// } + if (! this->simulator_.model().linearizer().getFlowsInfo().empty()) { + OPM_TIMEBLOCK(prepareFlowsData); + for (const auto& elem : elements(gridView, Dune::Partitions::interior)) { + elemCtx.updatePrimaryStencil(elem); + elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); + + this->outputModule_->processElementFlows(elemCtx); + } + } { OPM_TIMEBLOCK(prepareBlockData);