mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
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:
@@ -98,6 +98,7 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
opm/simulators/flow/FlowUtils.cpp
|
||||
opm/simulators/flow/GenericCpGridVanguard.cpp
|
||||
opm/simulators/flow/GenericOutputBlackoilModule.cpp
|
||||
opm/simulators/flow/GenericOutputCompositionalModule.cpp
|
||||
opm/simulators/flow/GenericThresholdPressure.cpp
|
||||
opm/simulators/flow/GenericTracerModel.cpp
|
||||
opm/simulators/flow/InterRegFlows.cpp
|
||||
@@ -817,6 +818,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/simulators/flow/FlowThresholdPressure.hpp
|
||||
opm/simulators/flow/GenericCpGridVanguard.hpp
|
||||
opm/simulators/flow/GenericOutputBlackoilModule.hpp
|
||||
opm/simulators/flow/GenericOutputCompositionalModule.hpp
|
||||
opm/simulators/flow/GenericThresholdPressure.hpp
|
||||
opm/simulators/flow/GenericThresholdPressure_impl.hpp
|
||||
opm/simulators/flow/GenericTracerModel.hpp
|
||||
@@ -829,6 +831,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/simulators/flow/NewTranFluxModule.hpp
|
||||
opm/simulators/flow/NonlinearSolver.hpp
|
||||
opm/simulators/flow/OutputBlackoilModule.hpp
|
||||
opm/simulators/flow/OutputCompositionalModule.hpp
|
||||
opm/simulators/flow/partitionCells.hpp
|
||||
opm/simulators/flow/PolyhedralGridVanguard.hpp
|
||||
opm/simulators/flow/priVarsPacking.hpp
|
||||
|
||||
@@ -669,7 +669,7 @@ public:
|
||||
|
||||
// write initial condition
|
||||
if (problem_->shouldWriteOutput())
|
||||
EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput());
|
||||
EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput(true));
|
||||
|
||||
timeStepSize_ = oldTimeStepSize;
|
||||
timeStepIdx_ = oldTimeStepIdx;
|
||||
@@ -748,7 +748,7 @@ public:
|
||||
// write the result to disk
|
||||
writeTimer_.start();
|
||||
if (problem_->shouldWriteOutput())
|
||||
EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput());
|
||||
EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(problem_->writeOutput(true));
|
||||
writeTimer_.stop();
|
||||
|
||||
// do the next time integration
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <opm/simulators/flow/DamarisParameters.hpp>
|
||||
#include <opm/simulators/flow/EclGenericWriter.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/DamarisKeywords.hpp>
|
||||
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
|
||||
|
||||
@@ -134,6 +134,13 @@ protected:
|
||||
bool isFloresn,
|
||||
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,
|
||||
Scalar curTime,
|
||||
const data::Wells& localWellData,
|
||||
|
||||
@@ -136,10 +136,6 @@ 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<int> timeStepNum_;
|
||||
@@ -147,45 +143,48 @@ struct EclWriteTasklet : public Opm::TaskletInterface
|
||||
double secondsElapsed_;
|
||||
Opm::RestartValue restartValue_;
|
||||
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,
|
||||
const Opm::WellTestState& wtestState,
|
||||
const Opm::SummaryState& summaryState,
|
||||
const Opm::UDQState& udqState,
|
||||
Opm::EclipseIO& eclIO,
|
||||
explicit EclWriteTasklet(Opm::EclipseIO& eclIO,
|
||||
int reportStepNum,
|
||||
std::optional<int> timeStepNum,
|
||||
bool isSubStep,
|
||||
double secondsElapsed,
|
||||
Opm::RestartValue restartValue,
|
||||
bool writeDoublePrecision)
|
||||
: actionState_(actionState)
|
||||
, wtestState_(wtestState)
|
||||
, summaryState_(summaryState)
|
||||
, udqState_(udqState)
|
||||
, eclIO_(eclIO)
|
||||
bool writeDoublePrecision,
|
||||
std::optional<Opm::Action::State> actionState = std::nullopt,
|
||||
std::optional<Opm::WellTestState> wtestState = std::nullopt,
|
||||
std::optional<Opm::SummaryState> summaryState = std::nullopt,
|
||||
std::optional<Opm::UDQState> udqState = std::nullopt)
|
||||
: 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->actionState_,
|
||||
this->wtestState_,
|
||||
this->summaryState_,
|
||||
this->udqState_,
|
||||
this->reportStepNum_,
|
||||
this->eclIO_.writeTimeStep(this->reportStepNum_,
|
||||
this->isSubStep_,
|
||||
this->secondsElapsed_,
|
||||
std::move(this->restartValue_),
|
||||
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
|
||||
auto eclWriteTasklet = std::make_shared<EclWriteTasklet>(
|
||||
auto eclWriteTasklet = std::make_shared<EclWriteTasklet>(/*
|
||||
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<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>
|
||||
void EclGenericWriter<Grid,EquilGrid,GridView,ElementMapper,Scalar>::
|
||||
evalSummary(const int reportStepNum,
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <opm/simulators/flow/countGlobalCells.hpp>
|
||||
#include <opm/simulators/flow/EclGenericWriter.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/utils/DeferredLoggingErrorHelpers.hpp>
|
||||
#include <opm/simulators/utils/ParallelRestart.hpp>
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
|
||||
static void registerParameters()
|
||||
{
|
||||
OutputBlackOilModule<TypeTag>::registerParameters();
|
||||
OutputCompositionalModule<TypeTag>::registerParameters();
|
||||
|
||||
Parameters::Register<Parameters::EnableAsyncEclOutput>
|
||||
("Write the ECL-formated results in a non-blocking way "
|
||||
@@ -169,13 +169,13 @@ public:
|
||||
|
||||
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_);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
this->outputModule_ = std::make_unique<OutputBlackOilModule<TypeTag>>
|
||||
this->outputModule_ = std::make_unique<OutputCompositionalModule<TypeTag>>
|
||||
(simulator, this->eclIO_->finalSummaryConfig(), this->collectOnIORank_);
|
||||
}
|
||||
|
||||
@@ -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<std::string, double> miscSummaryData;
|
||||
@@ -323,6 +323,11 @@ public:
|
||||
? this->collectOnIORank_.globalInterRegFlows()
|
||||
: 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,
|
||||
curTime,
|
||||
localWellData,
|
||||
@@ -415,19 +420,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 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 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();
|
||||
//
|
||||
// data::Solution localCellData = {};
|
||||
if (! isSubStep || Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
|
||||
|
||||
@@ -438,7 +443,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() ||
|
||||
@@ -449,19 +454,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);
|
||||
}
|
||||
@@ -473,20 +478,24 @@ public:
|
||||
if (Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
|
||||
timeStepIdx = simulator_.timeStepIndex();
|
||||
}
|
||||
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<Parameters::EclOutputDoublePrecision>(),
|
||||
isFlowsn, std::move(flowsn),
|
||||
isFloresn, std::move(floresn));
|
||||
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<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.
|
||||
// Nevertheless, this is how Flow has "always" done it.
|
||||
//
|
||||
// See GenericOutputBlackoilModule::accumulateRegionSums() for
|
||||
// See GenericOutputCompositionalModule::accumulateRegionSums() for
|
||||
// additional comments.
|
||||
auto inplace = this->outputModule_
|
||||
->calc_inplace(miscSummaryData, regionData,
|
||||
@@ -661,10 +670,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
const OutputBlackOilModule<TypeTag>& outputModule() const
|
||||
const OutputCompositionalModule<TypeTag>& outputModule() const
|
||||
{ return *outputModule_; }
|
||||
|
||||
OutputBlackOilModule<TypeTag>& mutableOutputModule() const
|
||||
OutputCompositionalModule<TypeTag>& mutableOutputModule() const
|
||||
{ return *outputModule_; }
|
||||
|
||||
Scalar restartTimeStepSize() const
|
||||
@@ -736,26 +745,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);
|
||||
@@ -826,7 +835,8 @@ private:
|
||||
}
|
||||
|
||||
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_;
|
||||
int rank_ ;
|
||||
Inplace inplace_;
|
||||
|
||||
@@ -493,7 +493,7 @@ public:
|
||||
* \brief Write the requested quantities of the current solution into the output
|
||||
* files.
|
||||
*/
|
||||
void writeOutput(bool verbose = true)
|
||||
virtual void writeOutput(bool verbose)
|
||||
{
|
||||
OPM_TIMEBLOCK(problemWriteOutput);
|
||||
// use the generic code to prepare the output fields and to
|
||||
|
||||
@@ -432,7 +432,7 @@ public:
|
||||
/*!
|
||||
* \brief Called by the simulator after each time integration.
|
||||
*/
|
||||
void endTimeStep () override
|
||||
void endTimeStep() override
|
||||
{
|
||||
FlowProblemType::endTimeStep();
|
||||
|
||||
@@ -517,7 +517,7 @@ public:
|
||||
* \brief Write the requested quantities of the current solution into the output
|
||||
* files.
|
||||
*/
|
||||
void writeOutput(bool verbose = true)
|
||||
void writeOutput(bool verbose) override
|
||||
{
|
||||
FlowProblemType::writeOutput(verbose);
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ class FlowProblemComp : public FlowProblem<TypeTag>
|
||||
using typename FlowProblemType::RateVector;
|
||||
|
||||
using InitialFluidState = CompositionalFluidState<Scalar, FluidSystem>;
|
||||
using EclWriterType = EclWriter<TypeTag>;
|
||||
|
||||
public:
|
||||
using FlowProblemType::porosity;
|
||||
@@ -94,6 +95,8 @@ public:
|
||||
{
|
||||
FlowProblemType::registerParameters();
|
||||
|
||||
EclWriterType::registerParameters();
|
||||
|
||||
// tighter tolerance is needed for compositional modeling here
|
||||
Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(1e-7);
|
||||
}
|
||||
@@ -105,6 +108,8 @@ public:
|
||||
explicit FlowProblemComp(Simulator& 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); });
|
||||
updated = true;
|
||||
};
|
||||
// TODO: we might need to do the same with FlowProblemBlackoil for parallel
|
||||
|
||||
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& schedule = simulator.vanguard().schedule();
|
||||
|
||||
@@ -179,6 +193,11 @@ public:
|
||||
FlowProblemType::readMaterialParameters_();
|
||||
FlowProblemType::readThermalParameters_();
|
||||
|
||||
// write the static output files (EGRID, INIT)
|
||||
if (enableEclOutput_) {
|
||||
eclWriter_->writeInit();
|
||||
}
|
||||
|
||||
const auto& initconfig = eclState.getInitConfig();
|
||||
if (initconfig.restartRequested())
|
||||
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
|
||||
*
|
||||
@@ -494,6 +567,9 @@ private:
|
||||
|
||||
std::vector<InitialFluidState> initialFluidStates_;
|
||||
|
||||
bool enableEclOutput_;
|
||||
std::unique_ptr<EclWriterType> eclWriter_;
|
||||
|
||||
bool enableVtkOutput_;
|
||||
};
|
||||
|
||||
|
||||
1741
opm/simulators/flow/GenericOutputCompositionalModule.cpp
Normal file
1741
opm/simulators/flow/GenericOutputCompositionalModule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
566
opm/simulators/flow/GenericOutputCompositionalModule.hpp
Normal file
566
opm/simulators/flow/GenericOutputCompositionalModule.hpp
Normal 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
|
||||
@@ -65,13 +65,13 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm::Parameters {
|
||||
|
||||
struct ForceDisableFluidInPlaceOutput { static constexpr bool value = false; };
|
||||
struct ForceDisableResvFluidInPlaceOutput { static constexpr bool value = false; };
|
||||
|
||||
} // namespace Opm::Parameters
|
||||
|
||||
//namespace Opm::Parameters {
|
||||
//
|
||||
//struct ForceDisableFluidInPlaceOutput { static constexpr bool value = false; };
|
||||
//struct ForceDisableResvFluidInPlaceOutput { static constexpr bool value = false; };
|
||||
//
|
||||
//} // namespace Opm::Parameters
|
||||
//
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
|
||||
1854
opm/simulators/flow/OutputCompositionalModule.hpp
Normal file
1854
opm/simulators/flow/OutputCompositionalModule.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -283,7 +283,7 @@ public:
|
||||
simulator_.setEpisodeLength(0.0);
|
||||
simulator_.setTimeStepSize(0.0);
|
||||
wellModel_().beginReportStep(timer.currentStepNum());
|
||||
simulator_.problem().writeOutput();
|
||||
simulator_.problem().writeOutput(true);
|
||||
|
||||
report_.success.output_write_time += perfTimer.stop();
|
||||
}
|
||||
@@ -370,7 +370,7 @@ public:
|
||||
perfTimer.start();
|
||||
const double nextstep = adaptiveTimeStepping_ ? adaptiveTimeStepping_->suggestedNextStep() : -1.0;
|
||||
simulator_.problem().setNextTimeStepSize(nextstep);
|
||||
simulator_.problem().writeOutput();
|
||||
simulator_.problem().writeOutput(true);
|
||||
report_.success.output_write_time += perfTimer.stop();
|
||||
|
||||
solver_->model().endReportStep();
|
||||
|
||||
@@ -353,7 +353,7 @@ void registerAdaptiveParameters();
|
||||
time::StopWatch perfTimer;
|
||||
perfTimer.start();
|
||||
|
||||
problem.writeOutput();
|
||||
problem.writeOutput(true);
|
||||
|
||||
report.success.output_write_time += perfTimer.secsSinceStart();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user