add EclWriter to FlowProblemComp

so the FlowProblemComp can output ecl style output.
it duplicates the OutputBlackoilModule and GenericOutputBlackoilModule
for compositional related output for now.
This commit is contained in:
Kai Bao
2024-10-01 23:31:24 +02:00
parent 0a128e8a17
commit 4ba1cd53d7
15 changed files with 4486 additions and 144 deletions

View File

@@ -98,6 +98,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/flow/FlowUtils.cpp opm/simulators/flow/FlowUtils.cpp
opm/simulators/flow/GenericCpGridVanguard.cpp opm/simulators/flow/GenericCpGridVanguard.cpp
opm/simulators/flow/GenericOutputBlackoilModule.cpp opm/simulators/flow/GenericOutputBlackoilModule.cpp
opm/simulators/flow/GenericOutputCompositionalModule.cpp
opm/simulators/flow/GenericThresholdPressure.cpp opm/simulators/flow/GenericThresholdPressure.cpp
opm/simulators/flow/GenericTracerModel.cpp opm/simulators/flow/GenericTracerModel.cpp
opm/simulators/flow/InterRegFlows.cpp opm/simulators/flow/InterRegFlows.cpp
@@ -817,6 +818,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/flow/FlowThresholdPressure.hpp opm/simulators/flow/FlowThresholdPressure.hpp
opm/simulators/flow/GenericCpGridVanguard.hpp opm/simulators/flow/GenericCpGridVanguard.hpp
opm/simulators/flow/GenericOutputBlackoilModule.hpp opm/simulators/flow/GenericOutputBlackoilModule.hpp
opm/simulators/flow/GenericOutputCompositionalModule.hpp
opm/simulators/flow/GenericThresholdPressure.hpp opm/simulators/flow/GenericThresholdPressure.hpp
opm/simulators/flow/GenericThresholdPressure_impl.hpp opm/simulators/flow/GenericThresholdPressure_impl.hpp
opm/simulators/flow/GenericTracerModel.hpp opm/simulators/flow/GenericTracerModel.hpp
@@ -829,6 +831,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/flow/NewTranFluxModule.hpp opm/simulators/flow/NewTranFluxModule.hpp
opm/simulators/flow/NonlinearSolver.hpp opm/simulators/flow/NonlinearSolver.hpp
opm/simulators/flow/OutputBlackoilModule.hpp opm/simulators/flow/OutputBlackoilModule.hpp
opm/simulators/flow/OutputCompositionalModule.hpp
opm/simulators/flow/partitionCells.hpp opm/simulators/flow/partitionCells.hpp
opm/simulators/flow/PolyhedralGridVanguard.hpp opm/simulators/flow/PolyhedralGridVanguard.hpp
opm/simulators/flow/priVarsPacking.hpp opm/simulators/flow/priVarsPacking.hpp

View File

@@ -669,7 +669,7 @@ public:
// write initial condition // write initial condition
if (problem_->shouldWriteOutput()) if (problem_->shouldWriteOutput())
EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput()); EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput(true));
timeStepSize_ = oldTimeStepSize; timeStepSize_ = oldTimeStepSize;
timeStepIdx_ = oldTimeStepIdx; timeStepIdx_ = oldTimeStepIdx;
@@ -748,7 +748,7 @@ public:
// write the result to disk // write the result to disk
writeTimer_.start(); writeTimer_.start();
if (problem_->shouldWriteOutput()) if (problem_->shouldWriteOutput())
EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput()); EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput(true));
writeTimer_.stop(); writeTimer_.stop();
// do the next time integration // do the next time integration

View File

@@ -39,7 +39,7 @@
#include <opm/simulators/flow/DamarisParameters.hpp> #include <opm/simulators/flow/DamarisParameters.hpp>
#include <opm/simulators/flow/EclGenericWriter.hpp> #include <opm/simulators/flow/EclGenericWriter.hpp>
#include <opm/simulators/flow/FlowBaseVanguard.hpp> #include <opm/simulators/flow/FlowBaseVanguard.hpp>
#include <opm/simulators/flow/OutputBlackoilModule.hpp> #include <opm/simulators/flow/OutputCompositionalModule.hpp>
#include <opm/simulators/utils/DamarisVar.hpp> #include <opm/simulators/utils/DamarisVar.hpp>
#include <opm/simulators/utils/DamarisKeywords.hpp> #include <opm/simulators/utils/DamarisKeywords.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp> #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>

View File

@@ -134,6 +134,13 @@ protected:
bool isFloresn, bool isFloresn,
std::array<FlowsData<double>, 3>&& floresn); std::array<FlowsData<double>, 3>&& floresn);
void doWriteOutput(const int reportStepNum,
const std::optional<int> timeStepNum,
const bool isSubStep,
Scalar curTime,
Scalar nextStepSize,
data::Solution&& localCellData);
void evalSummary(int reportStepNum, void evalSummary(int reportStepNum,
Scalar curTime, Scalar curTime,
const data::Wells& localWellData, const data::Wells& localWellData,

View File

@@ -136,10 +136,6 @@ getInterRegFlowsAsMap(const Opm::InterRegFlowMap& map)
struct EclWriteTasklet : public Opm::TaskletInterface struct EclWriteTasklet : public Opm::TaskletInterface
{ {
Opm::Action::State actionState_;
Opm::WellTestState wtestState_;
Opm::SummaryState summaryState_;
Opm::UDQState udqState_;
Opm::EclipseIO& eclIO_; Opm::EclipseIO& eclIO_;
int reportStepNum_; int reportStepNum_;
std::optional<int> timeStepNum_; std::optional<int> timeStepNum_;
@@ -147,45 +143,48 @@ struct EclWriteTasklet : public Opm::TaskletInterface
double secondsElapsed_; double secondsElapsed_;
Opm::RestartValue restartValue_; Opm::RestartValue restartValue_;
bool writeDoublePrecision_; bool writeDoublePrecision_;
std::optional<Opm::Action::State> actionState_;
std::optional<Opm::WellTestState> wtestState_;
std::optional<Opm::SummaryState> summaryState_;
std::optional<Opm::UDQState> udqState_;
explicit EclWriteTasklet(const Opm::Action::State& actionState, explicit EclWriteTasklet(Opm::EclipseIO& eclIO,
const Opm::WellTestState& wtestState,
const Opm::SummaryState& summaryState,
const Opm::UDQState& udqState,
Opm::EclipseIO& eclIO,
int reportStepNum, int reportStepNum,
std::optional<int> timeStepNum, std::optional<int> timeStepNum,
bool isSubStep, bool isSubStep,
double secondsElapsed, double secondsElapsed,
Opm::RestartValue restartValue, Opm::RestartValue restartValue,
bool writeDoublePrecision) bool writeDoublePrecision,
: actionState_(actionState) std::optional<Opm::Action::State> actionState = std::nullopt,
, wtestState_(wtestState) std::optional<Opm::WellTestState> wtestState = std::nullopt,
, summaryState_(summaryState) std::optional<Opm::SummaryState> summaryState = std::nullopt,
, udqState_(udqState) std::optional<Opm::UDQState> udqState = std::nullopt)
, eclIO_(eclIO) : eclIO_(eclIO)
, reportStepNum_(reportStepNum) , reportStepNum_(reportStepNum)
, timeStepNum_(timeStepNum) , timeStepNum_(timeStepNum)
, isSubStep_(isSubStep) , isSubStep_(isSubStep)
, secondsElapsed_(secondsElapsed) , secondsElapsed_(secondsElapsed)
, restartValue_(std::move(restartValue)) , restartValue_(std::move(restartValue))
, writeDoublePrecision_(writeDoublePrecision) , writeDoublePrecision_(writeDoublePrecision)
, actionState_(std::move(actionState))
, wtestState_(std::move(wtestState))
, summaryState_(std::move(summaryState))
, udqState_(std::move(udqState))
{} {}
// callback to eclIO serial writeTimeStep method // callback to eclIO serial writeTimeStep method
void run() void run()
{ {
this->eclIO_.writeTimeStep(this->actionState_, this->eclIO_.writeTimeStep(this->reportStepNum_,
this->wtestState_,
this->summaryState_,
this->udqState_,
this->reportStepNum_,
this->isSubStep_, this->isSubStep_,
this->secondsElapsed_, this->secondsElapsed_,
std::move(this->restartValue_), std::move(this->restartValue_),
this->writeDoublePrecision_, this->writeDoublePrecision_,
this->timeStepNum_ this->timeStepNum_,
); std::move(this->actionState_),
std::move(this->wtestState_),
std::move(this->summaryState_),
std::move(this->udqState_));
} }
}; };
@@ -609,16 +608,102 @@ doWriteOutput(const int reportStepNum,
} }
// create a tasklet to write the data for the current time step to disk // create a tasklet to write the data for the current time step to disk
auto eclWriteTasklet = std::make_shared<EclWriteTasklet>( auto eclWriteTasklet = std::make_shared<EclWriteTasklet>(/*
actionState, actionState,
isParallel ? this->collectOnIORank_.globalWellTestState() : std::move(localWTestState), isParallel ? this->collectOnIORank_.globalWellTestState() : std::move(localWTestState),
summaryState, udqState, *this->eclIO_, summaryState, udqState, */*this->eclIO_,
reportStepNum, timeStepNum, isSubStep, curTime, std::move(restartValue), doublePrecision); reportStepNum, timeStepNum, isSubStep, curTime, std::move(restartValue), doublePrecision);
// finally, start a new output writing job // finally, start a new output writing job
this->taskletRunner_->dispatch(std::move(eclWriteTasklet)); this->taskletRunner_->dispatch(std::move(eclWriteTasklet));
} }
template<class Grid, class EquilGrid, class GridView, class ElementMapper, class Scalar>
void EclGenericWriter<Grid,EquilGrid,GridView,ElementMapper,Scalar>::
doWriteOutput(const int reportStepNum,
const std::optional<int> 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<int,data::AquiferData> 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<double>(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<EclWriteTasklet>(
/* 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<class Grid, class EquilGrid, class GridView, class ElementMapper, class Scalar> template<class Grid, class EquilGrid, class GridView, class ElementMapper, class Scalar>
void EclGenericWriter<Grid,EquilGrid,GridView,ElementMapper,Scalar>:: void EclGenericWriter<Grid,EquilGrid,GridView,ElementMapper,Scalar>::
evalSummary(const int reportStepNum, evalSummary(const int reportStepNum,

View File

@@ -41,7 +41,7 @@
#include <opm/simulators/flow/countGlobalCells.hpp> #include <opm/simulators/flow/countGlobalCells.hpp>
#include <opm/simulators/flow/EclGenericWriter.hpp> #include <opm/simulators/flow/EclGenericWriter.hpp>
#include <opm/simulators/flow/FlowBaseVanguard.hpp> #include <opm/simulators/flow/FlowBaseVanguard.hpp>
#include <opm/simulators/flow/OutputBlackoilModule.hpp> #include <opm/simulators/flow/OutputCompositionalModule.hpp>
#include <opm/simulators/timestepping/SimulatorTimer.hpp> #include <opm/simulators/timestepping/SimulatorTimer.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp> #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/simulators/utils/ParallelRestart.hpp> #include <opm/simulators/utils/ParallelRestart.hpp>
@@ -132,7 +132,7 @@ public:
static void registerParameters() static void registerParameters()
{ {
OutputBlackOilModule<TypeTag>::registerParameters(); OutputCompositionalModule<TypeTag>::registerParameters();
Parameters::Register<Parameters::EnableAsyncEclOutput> Parameters::Register<Parameters::EnableAsyncEclOutput>
("Write the ECL-formated results in a non-blocking way " ("Write the ECL-formated results in a non-blocking way "
@@ -169,13 +169,13 @@ public:
eclBroadcast(this->simulator_.vanguard().grid().comm(), smryCfg); eclBroadcast(this->simulator_.vanguard().grid().comm(), smryCfg);
this->outputModule_ = std::make_unique<OutputBlackOilModule<TypeTag>> this->outputModule_ = std::make_unique<OutputCompositionalModule<TypeTag>>
(simulator, smryCfg, this->collectOnIORank_); (simulator, smryCfg, this->collectOnIORank_);
} }
else else
#endif #endif
{ {
this->outputModule_ = std::make_unique<OutputBlackOilModule<TypeTag>> this->outputModule_ = std::make_unique<OutputCompositionalModule<TypeTag>>
(simulator, this->eclIO_->finalSummaryConfig(), this->collectOnIORank_); (simulator, this->eclIO_->finalSummaryConfig(), this->collectOnIORank_);
} }
@@ -227,49 +227,49 @@ public:
simulator_.setupTimer().realTimeElapsed() + simulator_.setupTimer().realTimeElapsed() +
simulator_.vanguard().setupTime(); simulator_.vanguard().setupTime();
const auto localWellData = simulator_.problem().wellModel().wellData(); // const auto localWellData = simulator_.problem().wellModel().wellData();
const auto localWBP = simulator_.problem().wellModel().wellBlockAveragePressures(); // const auto localWBP = simulator_.problem().wellModel().wellBlockAveragePressures();
const auto localGroupAndNetworkData = simulator_.problem().wellModel() // const auto localGroupAndNetworkData = simulator_.problem().wellModel()
.groupAndNetworkData(reportStepNum); // .groupAndNetworkData(reportStepNum);
//
const auto localAquiferData = simulator_.problem().aquiferModel().aquiferData(); // const auto localAquiferData = simulator_.problem().aquiferModel().aquiferData();
const auto localWellTestState = simulator_.problem().wellModel().wellTestState(); // const auto localWellTestState = simulator_.problem().wellModel().wellTestState();
this->prepareLocalCellData(isSubStep, reportStepNum); this->prepareLocalCellData(isSubStep, reportStepNum);
if (this->outputModule_->needInterfaceFluxes(isSubStep)) { if (this->outputModule_->needInterfaceFluxes(isSubStep)) {
this->captureLocalFluxData(); this->captureLocalFluxData();
} }
if (this->collectOnIORank_.isParallel()) { // if (this->collectOnIORank_.isParallel()) {
OPM_BEGIN_PARALLEL_TRY_CATCH() // OPM_BEGIN_PARALLEL_TRY_CATCH()
//
this->collectOnIORank_.collect({}, // this->collectOnIORank_.collect({},
outputModule_->getBlockData(), // outputModule_->getBlockData(),
localWellData, // localWellData,
localWBP, // localWBP,
localGroupAndNetworkData, // localGroupAndNetworkData,
localAquiferData, // localAquiferData,
localWellTestState, // localWellTestState,
this->outputModule_->getInterRegFlows(), // this->outputModule_->getInterRegFlows(),
{}, // {},
{}); // {});
//
if (this->collectOnIORank_.isIORank()) { // if (this->collectOnIORank_.isIORank()) {
auto& iregFlows = this->collectOnIORank_.globalInterRegFlows(); // auto& iregFlows = this->collectOnIORank_.globalInterRegFlows();
//
if (! iregFlows.readIsConsistent()) { // if (! iregFlows.readIsConsistent()) {
throw std::runtime_error { // throw std::runtime_error {
"Inconsistent inter-region flow " // "Inconsistent inter-region flow "
"region set names in parallel" // "region set names in parallel"
}; // };
} // }
//
iregFlows.compress(); // iregFlows.compress();
} // }
//
OPM_END_PARALLEL_TRY_CATCH("Collect to I/O rank: ", // OPM_END_PARALLEL_TRY_CATCH("Collect to I/O rank: ",
this->simulator_.vanguard().grid().comm()); // this->simulator_.vanguard().grid().comm());
} // }
std::map<std::string, double> miscSummaryData; std::map<std::string, double> miscSummaryData;
@@ -323,6 +323,11 @@ public:
? this->collectOnIORank_.globalInterRegFlows() ? this->collectOnIORank_.globalInterRegFlows()
: this->outputModule_->getInterRegFlows(); : this->outputModule_->getInterRegFlows();
const data::Wells& localWellData {};
const data::WellBlockAveragePressures& localWBP{};
const data::GroupAndNetworkValues& localGroupAndNetworkData{};
const std::map<int,data::AquiferData>& localAquiferData {};
this->evalSummary(reportStepNum, this->evalSummary(reportStepNum,
curTime, curTime,
localWellData, localWellData,
@@ -415,19 +420,19 @@ public:
this->outputModule_->outputErrorLog(simulator_.gridView().comm()); this->outputModule_->outputErrorLog(simulator_.gridView().comm());
// output using eclWriter if enabled // output using eclWriter if enabled
auto localWellData = simulator_.problem().wellModel().wellData(); // auto localWellData = simulator_.problem().wellModel().wellData();
auto localGroupAndNetworkData = simulator_.problem().wellModel() // auto localGroupAndNetworkData = simulator_.problem().wellModel()
.groupAndNetworkData(reportStepNum); // .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 = {}; // data::Solution localCellData = {};
if (! isSubStep || Parameters::Get<Parameters::EnableWriteAllSolutions>()) { if (! isSubStep || Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
@@ -438,7 +443,7 @@ public:
// Collect RFT data on rank 0 // Collect RFT data on rank 0
this->outputModule_->accumulateRftDataParallel(simulator_.gridView().comm()); this->outputModule_->accumulateRftDataParallel(simulator_.gridView().comm());
// Add cell data to perforations for RFT output // Add cell data to perforations for RFT output
this->outputModule_->addRftDataToWells(localWellData, reportStepNum); // this->outputModule_->addRftDataToWells(localWellData, reportStepNum);
} }
if (this->collectOnIORank_.isParallel() || if (this->collectOnIORank_.isParallel() ||
@@ -449,19 +454,19 @@ public:
// output. There's consequently no need to collect those // output. There's consequently no need to collect those
// properties on the I/O rank. // properties on the I/O rank.
this->collectOnIORank_.collect(localCellData, // this->collectOnIORank_.collect(localCellData,
this->outputModule_->getBlockData(), // this->outputModule_->getBlockData(),
localWellData, // localWellData,
/* wbpData = */ {}, // /* wbpData = */ {},
localGroupAndNetworkData, // localGroupAndNetworkData,
localAquiferData, // localAquiferData,
localWellTestState, // localWellTestState,
/* interRegFlows = */ {}, // /* interRegFlows = */ {},
flowsn, // flowsn,
floresn); // floresn);
if (this->collectOnIORank_.isIORank()) { // if (this->collectOnIORank_.isIORank()) {
this->outputModule_->assignGlobalFieldsToSolution(this->collectOnIORank_.globalCellData()); // this->outputModule_->assignGlobalFieldsToSolution(this->collectOnIORank_.globalCellData());
} // }
} else { } else {
this->outputModule_->assignGlobalFieldsToSolution(localCellData); this->outputModule_->assignGlobalFieldsToSolution(localCellData);
} }
@@ -473,20 +478,24 @@ public:
if (Parameters::Get<Parameters::EnableWriteAllSolutions>()) { if (Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
timeStepIdx = simulator_.timeStepIndex(); timeStepIdx = simulator_.timeStepIndex();
} }
this->doWriteOutput(reportStepNum, timeStepIdx, isSubStep, this->doWriteOutput(reportStepNum,
std::move(localCellData), timeStepIdx,
std::move(localWellData), isSubStep,
std::move(localGroupAndNetworkData), curTime,
std::move(localAquiferData), nextStepSize,
std::move(localWellTestState), std::move(localCellData) );
this->actionState(), // std::move(localWellData),
this->udqState(), // std::move(localGroupAndNetworkData),
this->summaryState(), // std::move(localAquiferData),
this->simulator_.problem().thresholdPressure().getRestartVector(), // std::move(localWellTestState),
curTime, nextStepSize, // this->actionState(),
Parameters::Get<Parameters::EclOutputDoublePrecision>(), // this->udqState(),
isFlowsn, std::move(flowsn), // this->summaryState(),
isFloresn, std::move(floresn)); // this->simulator_.problem().thresholdPressure().getRestartVector(),
// curTime, nextStepSize,
// Parameters::Get<Parameters::EclOutputDoublePrecision>(),
// isFlowsn, std::move(flowsn),
// isFloresn, std::move(floresn));
} }
} }
@@ -650,7 +659,7 @@ public:
// volumes at the restart time instead of the start of the base run. // volumes at the restart time instead of the start of the base run.
// Nevertheless, this is how Flow has "always" done it. // Nevertheless, this is how Flow has "always" done it.
// //
// See GenericOutputBlackoilModule::accumulateRegionSums() for // See GenericOutputCompositionalModule::accumulateRegionSums() for
// additional comments. // additional comments.
auto inplace = this->outputModule_ auto inplace = this->outputModule_
->calc_inplace(miscSummaryData, regionData, ->calc_inplace(miscSummaryData, regionData,
@@ -661,10 +670,10 @@ public:
} }
} }
const OutputBlackOilModule<TypeTag>& outputModule() const const OutputCompositionalModule<TypeTag>& outputModule() const
{ return *outputModule_; } { return *outputModule_; }
OutputBlackOilModule<TypeTag>& mutableOutputModule() const OutputCompositionalModule<TypeTag>& mutableOutputModule() const
{ return *outputModule_; } { return *outputModule_; }
Scalar restartTimeStepSize() const Scalar restartTimeStepSize() const
@@ -736,26 +745,26 @@ private:
this->outputModule_->accumulateDensityParallel(); this->outputModule_->accumulateDensityParallel();
} }
if constexpr (enableMech) { // if constexpr (enableMech) {
if (simulator_.vanguard().eclState().runspec().mech()) { // if (simulator_.vanguard().eclState().runspec().mech()) {
OPM_TIMEBLOCK(prepareMechData); // OPM_TIMEBLOCK(prepareMechData);
for (const auto& elem : elements(gridView, Dune::Partitions::interior)) { // for (const auto& elem : elements(gridView, Dune::Partitions::interior)) {
elemCtx.updatePrimaryStencil(elem); // elemCtx.updatePrimaryStencil(elem);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); // elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
outputModule_->processElementMech(elemCtx); // outputModule_->processElementMech(elemCtx);
} // }
} // }
} // }
if (! this->simulator_.model().linearizer().getFlowsInfo().empty()) { // if (! this->simulator_.model().linearizer().getFlowsInfo().empty()) {
OPM_TIMEBLOCK(prepareFlowsData); // OPM_TIMEBLOCK(prepareFlowsData);
for (const auto& elem : elements(gridView, Dune::Partitions::interior)) { // for (const auto& elem : elements(gridView, Dune::Partitions::interior)) {
elemCtx.updatePrimaryStencil(elem); // elemCtx.updatePrimaryStencil(elem);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); // elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
//
this->outputModule_->processElementFlows(elemCtx); // this->outputModule_->processElementFlows(elemCtx);
} // }
} // }
{ {
OPM_TIMEBLOCK(prepareBlockData); OPM_TIMEBLOCK(prepareBlockData);
@@ -826,7 +835,8 @@ private:
} }
Simulator& simulator_; Simulator& simulator_;
std::unique_ptr<OutputBlackOilModule<TypeTag> > outputModule_; // TODO: OutputCompositionalModule needs to be part of the TypeTag
std::unique_ptr<OutputCompositionalModule<TypeTag> > outputModule_;
Scalar restartTimeStepSize_; Scalar restartTimeStepSize_;
int rank_ ; int rank_ ;
Inplace inplace_; Inplace inplace_;

View File

@@ -493,7 +493,7 @@ public:
* \brief Write the requested quantities of the current solution into the output * \brief Write the requested quantities of the current solution into the output
* files. * files.
*/ */
void writeOutput(bool verbose = true) virtual void writeOutput(bool verbose)
{ {
OPM_TIMEBLOCK(problemWriteOutput); OPM_TIMEBLOCK(problemWriteOutput);
// use the generic code to prepare the output fields and to // use the generic code to prepare the output fields and to

View File

@@ -432,7 +432,7 @@ public:
/*! /*!
* \brief Called by the simulator after each time integration. * \brief Called by the simulator after each time integration.
*/ */
void endTimeStep () override void endTimeStep() override
{ {
FlowProblemType::endTimeStep(); FlowProblemType::endTimeStep();
@@ -517,7 +517,7 @@ public:
* \brief Write the requested quantities of the current solution into the output * \brief Write the requested quantities of the current solution into the output
* files. * files.
*/ */
void writeOutput(bool verbose = true) void writeOutput(bool verbose) override
{ {
FlowProblemType::writeOutput(verbose); FlowProblemType::writeOutput(verbose);

View File

@@ -82,6 +82,7 @@ class FlowProblemComp : public FlowProblem<TypeTag>
using typename FlowProblemType::RateVector; using typename FlowProblemType::RateVector;
using InitialFluidState = CompositionalFluidState<Scalar, FluidSystem>; using InitialFluidState = CompositionalFluidState<Scalar, FluidSystem>;
using EclWriterType = EclWriter<TypeTag>;
public: public:
using FlowProblemType::porosity; using FlowProblemType::porosity;
@@ -94,6 +95,8 @@ public:
{ {
FlowProblemType::registerParameters(); FlowProblemType::registerParameters();
EclWriterType::registerParameters();
// tighter tolerance is needed for compositional modeling here // tighter tolerance is needed for compositional modeling here
Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(1e-7); Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(1e-7);
} }
@@ -105,6 +108,8 @@ public:
explicit FlowProblemComp(Simulator& simulator) explicit FlowProblemComp(Simulator& simulator)
: FlowProblemType(simulator) : FlowProblemType(simulator)
{ {
eclWriter_ = std::make_unique<EclWriterType>(simulator);
enableEclOutput_ = Parameters::Get<Parameters::EnableEclOutput>();
} }
/*! /*!
@@ -127,9 +132,18 @@ public:
[&vg = this->simulator().vanguard()](const unsigned int it) { return vg.gridIdxToEquilGridIdx(it); }); [&vg = this->simulator().vanguard()](const unsigned int it) { return vg.gridIdxToEquilGridIdx(it); });
updated = true; updated = true;
}; };
// TODO: we might need to do the same with FlowProblemBlackoil for parallel
finishTransmissibilities(); finishTransmissibilities();
if (enableEclOutput_) {
eclWriter_->setTransmissibilities(&simulator.problem().eclTransmissibilities());
std::function<unsigned int(unsigned int)> equilGridToGrid = [&simulator](unsigned int i) {
return simulator.vanguard().gridEquilIdxToGridIdx(i);
};
eclWriter_->extractOutputTransAndNNC(equilGridToGrid);
}
const auto& eclState = simulator.vanguard().eclState(); const auto& eclState = simulator.vanguard().eclState();
const auto& schedule = simulator.vanguard().schedule(); const auto& schedule = simulator.vanguard().schedule();
@@ -179,6 +193,11 @@ public:
FlowProblemType::readMaterialParameters_(); FlowProblemType::readMaterialParameters_();
FlowProblemType::readThermalParameters_(); FlowProblemType::readThermalParameters_();
// write the static output files (EGRID, INIT)
if (enableEclOutput_) {
eclWriter_->writeInit();
}
const auto& initconfig = eclState.getInitConfig(); const auto& initconfig = eclState.getInitConfig();
if (initconfig.restartRequested()) if (initconfig.restartRequested())
readEclRestartSolution_(); readEclRestartSolution_();
@@ -220,6 +239,60 @@ public:
} }
} }
/*!
* \brief Called by the simulator after each time integration.
*/
void endTimeStep() override
{
FlowProblemType::endTimeStep();
const bool isSubStep = !this->simulator().episodeWillBeOver();
// after the solution is updated, the values in output module needs also updated
this->eclWriter_->mutableOutputModule().invalidateLocalData();
// For CpGrid with LGRs, ecl/vtk output is not supported yet.
const auto& grid = this->simulator().vanguard().gridView().grid();
using GridType = std::remove_cv_t<std::remove_reference_t<decltype(grid)>>;
constexpr bool isCpGrid = std::is_same_v<GridType, Dune::CpGrid>;
if (!isCpGrid || (grid.maxLevel() == 0)) {
this->eclWriter_->evalSummaryState(isSubStep);
}
}
void writeReports(const SimulatorTimer& timer) {
if (enableEclOutput_){
eclWriter_->writeReports(timer);
}
}
/*!
* \brief Write the requested quantities of the current solution into the output
* files.
*/
void writeOutput(bool verbose) override
{
FlowProblemType::writeOutput(verbose);
const bool isSubStep = !this->simulator().episodeWillBeOver();
data::Solution localCellData = {};
#if HAVE_DAMARIS
// N.B. the Damaris output has to be done before the ECL output as the ECL one
// does all kinds of std::move() relocation of data
if (enableDamarisOutput_) {
damarisWriter_->writeOutput(localCellData, isSubStep) ;
}
#endif
if (enableEclOutput_) {
if (Parameters::Get<Parameters::EnableWriteAllSolutions>() || !isSubStep) {
eclWriter_->writeOutput(std::move(localCellData), isSubStep);
}
}
}
/*! /*!
* \copydoc FvBaseProblem::boundary * \copydoc FvBaseProblem::boundary
* *
@@ -494,6 +567,9 @@ private:
std::vector<InitialFluidState> initialFluidStates_; std::vector<InitialFluidState> initialFluidStates_;
bool enableEclOutput_;
std::unique_ptr<EclWriterType> eclWriter_;
bool enableVtkOutput_; bool enableVtkOutput_;
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,566 @@
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*
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 2 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/>.
Consult the COPYING file in the top-level source directory of this
module for the precise wording of the license and the list of
copyright holders.
*/
/*!
* \file
* \copydoc Opm::OutputCompositionalModule
*/
#ifndef OPM_GENERIC_OUTPUT_COMPOSITIONAL_MODULE_HPP
#define OPM_GENERIC_OUTPUT_COMPOSITIONAL_MODULE_HPP
#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/Inplace.hpp>
#include <opm/simulators/flow/FlowsData.hpp>
#include <opm/simulators/flow/InterRegFlows.hpp>
#include <opm/simulators/flow/LogOutputHelper.hpp>
#include <opm/simulators/flow/RegionPhasePVAverage.hpp>
#include <opm/simulators/utils/ParallelCommunication.hpp>
#include <array>
#include <cstddef>
#include <functional>
#include <map>
#include <optional>
#include <unordered_map>
#include <utility>
#include <vector>
namespace Opm {
namespace data { class Solution; }
class EclipseState;
class Schedule;
class SummaryConfig;
class SummaryConfigNode;
class SummaryState;
template<class FluidSystem>
class GenericOutputCompositionalModule {
public:
using Scalar = typename FluidSystem::Scalar;
// Virtual destructor for safer inheritance.
virtual ~GenericOutputCompositionalModule();
Scalar* getPRESSURE_ptr(void) {
return (this->fluidPressure_.data()) ;
};
int getPRESSURE_size( void ) {
return (this->fluidPressure_.size()) ;
};
void outputTimeStamp(const std::string& lbl,
double elapsed,
int rstep,
boost::posix_time::ptime currentDate);
/// Clear internal arrays for parallel accumulation of per-region phase
/// density averages.
void prepareDensityAccumulation();
/// Run cross-rank parallel accumulation of per-region phase density
/// running sums (average values).
void accumulateDensityParallel();
// write cumulative production and injection reports to output
void outputCumLog(std::size_t reportStepNum);
// write production report to output
void outputProdLog(std::size_t reportStepNum);
// write injection report to output
void outputInjLog(std::size_t reportStepNum);
// calculate Fluid In Place
Inplace calc_inplace(std::map<std::string, double>& miscSummaryData,
std::map<std::string, std::vector<double>>& regionData,
const Parallel::Communication& comm);
void outputFipAndResvLog(const Inplace& inplace,
const std::size_t reportStepNum,
double elapsed,
boost::posix_time::ptime currentDate,
const bool substep,
const Parallel::Communication& comm);
void outputErrorLog(const Parallel::Communication& comm) const;
void addRftDataToWells(data::Wells& wellDatas,
std::size_t reportStepNum);
/*!
* \brief Move all buffers to data::Solution.
*/
void assignToSolution(data::Solution& sol);
void setRestart(const data::Solution& sol,
unsigned elemIdx,
unsigned globalDofIndex);
Scalar getSolventSaturation(unsigned elemIdx) const
{
if (sSol_.size() > elemIdx)
return sSol_[elemIdx];
return 0;
}
Scalar getSolventRsw(unsigned elemIdx) const
{
if (rswSol_.size() > elemIdx)
return rswSol_[elemIdx];
return 0;
}
Scalar getPolymerConcentration(unsigned elemIdx) const
{
if (cPolymer_.size() > elemIdx)
return cPolymer_[elemIdx];
return 0;
}
Scalar getFoamConcentration(unsigned elemIdx) const
{
if (cFoam_.size() > elemIdx)
return cFoam_[elemIdx];
return 0;
}
Scalar getSaltConcentration(unsigned elemIdx) const
{
if (cSalt_.size() > elemIdx)
return cSalt_[elemIdx];
return 0;
}
Scalar getSaltSaturation(unsigned elemIdx) const
{
if (pSalt_.size() > elemIdx)
return pSalt_[elemIdx];
return 0;
}
Scalar getPermFactor(unsigned elemIdx) const
{
if (permFact_.size() > elemIdx)
return permFact_[elemIdx];
return 0;
}
Scalar getMicrobialConcentration(unsigned elemIdx) const
{
if (cMicrobes_.size() > elemIdx)
return cMicrobes_[elemIdx];
return 0;
}
Scalar getOxygenConcentration(unsigned elemIdx) const
{
if (cOxygen_.size() > elemIdx)
return cOxygen_[elemIdx];
return 0;
}
Scalar getUreaConcentration(unsigned elemIdx) const
{
if (cUrea_.size() > elemIdx)
return cUrea_[elemIdx];
return 0;
}
Scalar getBiofilmConcentration(unsigned elemIdx) const
{
if (cBiofilm_.size() > elemIdx)
return cBiofilm_[elemIdx];
return 0;
}
Scalar getCalciteConcentration(unsigned elemIdx) const
{
if (cCalcite_.size() > elemIdx)
return cCalcite_[elemIdx];
return 0;
}
const std::array<FlowsData<double>, 3>& getFlowsn() const
{
return this->flowsn_;
}
bool hasFlowsn() const
{
return enableFlowsn_;
}
bool hasFlows() const
{
return enableFlows_;
}
bool hasBlockFlows() const
{
return blockFlows_;
}
bool anyFlows() const
{
return anyFlows_;
}
const std::array<FlowsData<double>, 3>& getFloresn() const
{
return this->floresn_;
}
bool hasFloresn() const
{
return enableFloresn_;
}
bool hasFlores() const
{
return enableFlores_;
}
bool anyFlores() const
{
return anyFlores_;
}
bool needInterfaceFluxes([[maybe_unused]] const bool isSubStep) const
{
return this->interRegionFlows_.wantInterRegflowSummary();
}
const std::map<std::pair<std::string, int>, double>& getBlockData()
{
return blockData_;
}
const Inplace& initialInplace() const
{
return this->initialInplace_.value();
}
bool localDataValid() const{
return local_data_valid_;
}
void invalidateLocalData(){
local_data_valid_ = false;
}
void validateLocalData(){
local_data_valid_ = true;
}
void setCnvData(const std::vector<std::vector<int>>& data)
{
cnvData_ = data;
}
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(initialInplace_);
}
//! \brief Assign fields that are in global numbering to the solution.
//! \detail This is used to add fields that for some reason cannot be collected
//! using the regular collect mechanism to the solution. In particular this
//! is used with RPTRST CONV output.
void assignGlobalFieldsToSolution(data::Solution& sol);
protected:
using ScalarBuffer = std::vector<Scalar>;
using StringBuffer = std::vector<std::string>;
enum { numPhases = FluidSystem::numPhases };
enum { numComponents = FluidSystem::numComponents };
enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
enum { gasCompIdx = FluidSystem::gasCompIdx };
enum { oilCompIdx = FluidSystem::oilCompIdx };
enum { waterCompIdx = FluidSystem::waterCompIdx };
using Dir = FaceDir::DirEnum;
GenericOutputCompositionalModule(const EclipseState& eclState,
const Schedule& schedule,
const SummaryConfig& summaryConfig,
const SummaryState& summaryState,
const std::string& moduleVersionName,
bool enableEnergy,
bool enableTemperature,
bool enableMech,
bool enableSolvent,
bool enablePolymer,
bool enableFoam,
bool enableBrine,
bool enableSaltPrecipitation,
bool enableExtbo,
bool enableMICP);
void doAllocBuffers(unsigned bufferSize,
unsigned reportStepNum,
const bool substep,
const bool log,
const bool isRestart,
const bool vapparsActive = false,
const bool enablePCHysteresis = false,
const bool enableNonWettingHysteresis =false,
const bool enableWettingHysteresis = false,
unsigned numTracers = 0,
const std::vector<bool>& enableSolTracers = {},
unsigned numOutputNnc = 0);
void makeRegionSum(Inplace& inplace,
const std::string& region_name,
const Parallel::Communication& comm) const;
Inplace accumulateRegionSums(const Parallel::Communication& comm);
void updateSummaryRegionValues(const Inplace& inplace,
std::map<std::string, double>& miscSummaryData,
std::map<std::string, std::vector<double>>& regionData) const;
static bool isOutputCreationDirective_(const std::string& keyword);
// Sum Fip values over regions.
static ScalarBuffer regionSum(const ScalarBuffer& property,
const std::vector<int>& regionId,
const std::size_t maxNumberOfRegions,
const Parallel::Communication& comm);
static int regionMax(const std::vector<int>& region,
const Parallel::Communication& comm);
static void update(Inplace& inplace,
const std::string& region_name,
const Inplace::Phase phase,
const std::size_t ntFip,
const ScalarBuffer& values);
static Scalar sum(const ScalarBuffer& v);
void setupBlockData(std::function<bool(int)> isCartIdxOnThisRank);
virtual bool isDefunctParallelWell(std::string wname) const = 0;
const EclipseState& eclState_;
const Schedule& schedule_;
const SummaryState& summaryState_;
SummaryConfig summaryConfig_;
InterRegFlowMap interRegionFlows_;
LogOutputHelper<Scalar> logOutput_;
bool enableEnergy_{false};
bool enableTemperature_{false};
bool enableMech_{false};
bool enableSolvent_{false};
bool enablePolymer_{false};
bool enableFoam_{false};
bool enableBrine_{false};
bool enableSaltPrecipitation_{false};
bool enableExtbo_{false};
bool enableMICP_{false};
bool forceDisableFipOutput_{false};
bool forceDisableFipresvOutput_{false};
bool computeFip_{false};
struct OutputFIPRestart {
/// Whether or not run requests (surface condition) fluid-in-place
/// restart file output using the 'FIP' mnemonic.
bool noPrefix {false};
/// Whether or not run requests surface condition fluid-in-place
/// restart file output using the 'SFIP' mnemonic.
bool surface {false};
/// Whether or not run requests reservoir condition fluid-in-place
/// restart file output using the 'RFIP' mnemonic.
bool reservoir {false};
void clearBits()
{
this->noPrefix = this->surface = this->reservoir = false;
}
explicit operator bool() const
{
return this->noPrefix || this->surface || this->reservoir;
}
} outputFipRestart_{};
bool anyFlows_{false};
bool anyFlores_{false};
bool blockFlows_{false};
bool enableFlows_{false};
bool enableFlores_{false};
bool enableFlowsn_{false};
bool enableFloresn_{false};
std::unordered_map<Inplace::Phase, ScalarBuffer> fip_;
std::unordered_map<std::string, std::vector<int>> regions_;
std::unordered_map<Inplace::Phase, std::vector<SummaryConfigNode>> regionNodes_;
std::vector<SummaryConfigNode> RPRNodes_;
std::vector<SummaryConfigNode> RPRPNodes_;
std::vector<int> failedCellsPb_;
std::vector<int> failedCellsPd_;
ScalarBuffer gasFormationVolumeFactor_;
ScalarBuffer hydrocarbonPoreVolume_;
ScalarBuffer pressureTimesPoreVolume_;
ScalarBuffer pressureTimesHydrocarbonVolume_;
ScalarBuffer dynamicPoreVolume_;
ScalarBuffer rPorV_;
ScalarBuffer fluidPressure_;
ScalarBuffer temperature_;
ScalarBuffer rs_;
ScalarBuffer rsw_;
ScalarBuffer rv_;
ScalarBuffer rvw_;
ScalarBuffer overburdenPressure_;
ScalarBuffer oilSaturationPressure_;
ScalarBuffer drsdtcon_;
ScalarBuffer sSol_;
ScalarBuffer rswSol_;
ScalarBuffer cPolymer_;
ScalarBuffer cFoam_;
ScalarBuffer cSalt_;
ScalarBuffer pSalt_;
ScalarBuffer permFact_;
ScalarBuffer extboX_;
ScalarBuffer extboY_;
ScalarBuffer extboZ_;
ScalarBuffer mFracOil_;
ScalarBuffer mFracGas_;
ScalarBuffer mFracCo2_;
ScalarBuffer soMax_;
ScalarBuffer swMax_;
ScalarBuffer sgmax_;
ScalarBuffer shmax_;
ScalarBuffer somin_;
ScalarBuffer swmin_;
ScalarBuffer ppcw_;
ScalarBuffer gasDissolutionFactor_;
ScalarBuffer oilVaporizationFactor_;
ScalarBuffer gasDissolutionFactorInWater_;
ScalarBuffer waterVaporizationFactor_;
ScalarBuffer bubblePointPressure_;
ScalarBuffer dewPointPressure_;
ScalarBuffer rockCompPorvMultiplier_;
ScalarBuffer minimumOilPressure_;
ScalarBuffer saturatedOilFormationVolumeFactor_;
ScalarBuffer rockCompTransMultiplier_;
ScalarBuffer cMicrobes_;
ScalarBuffer cOxygen_;
ScalarBuffer cUrea_;
ScalarBuffer cBiofilm_;
ScalarBuffer cCalcite_;
ScalarBuffer pcgw_;
ScalarBuffer pcow_;
ScalarBuffer pcog_;
// buffers for mechanical output
ScalarBuffer mechPotentialForce_;
ScalarBuffer mechPotentialPressForce_;
ScalarBuffer mechPotentialTempForce_;
ScalarBuffer dispX_;
ScalarBuffer dispY_;
ScalarBuffer dispZ_;
ScalarBuffer stressXX_;
ScalarBuffer stressYY_;
ScalarBuffer stressZZ_;
ScalarBuffer stressXY_;
ScalarBuffer stressXZ_;
ScalarBuffer stressYZ_;
ScalarBuffer delstressXX_;
ScalarBuffer delstressYY_;
ScalarBuffer delstressZZ_;
ScalarBuffer delstressXY_;
ScalarBuffer delstressXZ_;
ScalarBuffer delstressYZ_;
ScalarBuffer strainXX_;
ScalarBuffer strainYY_;
ScalarBuffer strainZZ_;
ScalarBuffer strainXY_;
ScalarBuffer strainXZ_;
ScalarBuffer strainYZ_;
std::array<ScalarBuffer, numPhases> saturation_;
std::array<ScalarBuffer, numPhases> invB_;
std::array<ScalarBuffer, numPhases> density_;
std::array<ScalarBuffer, numPhases> viscosity_;
std::array<ScalarBuffer, numPhases> relativePermeability_;
std::array<ScalarBuffer, numComponents> moleFractions_;
std::vector<ScalarBuffer> freeTracerConcentrations_;
std::vector<ScalarBuffer> solTracerConcentrations_;
std::array<ScalarBuffer, numPhases> residual_;
std::array<std::array<ScalarBuffer, numPhases>, 6> flows_;
std::array<std::array<ScalarBuffer, numPhases>, 6> flores_;
std::array<FlowsData<double>, 3> floresn_;
std::array<FlowsData<double>, 3> flowsn_;
std::map<std::size_t, Scalar> oilConnectionPressures_;
std::map<std::size_t, Scalar> waterConnectionSaturations_;
std::map<std::size_t, Scalar> gasConnectionSaturations_;
std::map<std::pair<std::string, int>, double> blockData_;
std::vector<std::vector<int>> cnvData_; //!< Data for CNV_xxx arrays
std::optional<Inplace> initialInplace_;
bool local_data_valid_{false};
std::optional<RegionPhasePoreVolAverage> regionAvgDensity_;
};
} // namespace Opm
#endif // OPM_GENERIC_OUTPUT_BLACK_OIL_MODULE_HPP

View File

@@ -65,13 +65,13 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace Opm::Parameters { //namespace Opm::Parameters {
//
struct ForceDisableFluidInPlaceOutput { static constexpr bool value = false; }; //struct ForceDisableFluidInPlaceOutput { static constexpr bool value = false; };
struct ForceDisableResvFluidInPlaceOutput { static constexpr bool value = false; }; //struct ForceDisableResvFluidInPlaceOutput { static constexpr bool value = false; };
//
} // namespace Opm::Parameters //} // namespace Opm::Parameters
//
namespace Opm namespace Opm
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -283,7 +283,7 @@ public:
simulator_.setEpisodeLength(0.0); simulator_.setEpisodeLength(0.0);
simulator_.setTimeStepSize(0.0); simulator_.setTimeStepSize(0.0);
wellModel_().beginReportStep(timer.currentStepNum()); wellModel_().beginReportStep(timer.currentStepNum());
simulator_.problem().writeOutput(); simulator_.problem().writeOutput(true);
report_.success.output_write_time += perfTimer.stop(); report_.success.output_write_time += perfTimer.stop();
} }
@@ -370,7 +370,7 @@ public:
perfTimer.start(); perfTimer.start();
const double nextstep = adaptiveTimeStepping_ ? adaptiveTimeStepping_->suggestedNextStep() : -1.0; const double nextstep = adaptiveTimeStepping_ ? adaptiveTimeStepping_->suggestedNextStep() : -1.0;
simulator_.problem().setNextTimeStepSize(nextstep); simulator_.problem().setNextTimeStepSize(nextstep);
simulator_.problem().writeOutput(); simulator_.problem().writeOutput(true);
report_.success.output_write_time += perfTimer.stop(); report_.success.output_write_time += perfTimer.stop();
solver_->model().endReportStep(); solver_->model().endReportStep();

View File

@@ -353,7 +353,7 @@ void registerAdaptiveParameters();
time::StopWatch perfTimer; time::StopWatch perfTimer;
perfTimer.start(); perfTimer.start();
problem.writeOutput(); problem.writeOutput(true);
report.success.output_write_time += perfTimer.secsSinceStart(); report.success.output_write_time += perfTimer.secsSinceStart();
} }