mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-08-13 08:54:50 -05:00
Extract the Summary::eval() call from the output call
This commit is contained in:
@@ -438,9 +438,11 @@ public:
|
|||||||
* computed, ready to use summary values. The values will typically be used by
|
* computed, ready to use summary values. The values will typically be used by
|
||||||
* the UDQ, WTEST and ACTIONX calculations.
|
* the UDQ, WTEST and ACTIONX calculations.
|
||||||
*/
|
*/
|
||||||
Opm::SummaryState& summaryState()
|
Opm::SummaryState& summaryState()
|
||||||
{ return summaryState_; }
|
{ return summaryState_; }
|
||||||
|
|
||||||
|
const Opm::SummaryState& summaryState() const
|
||||||
|
{ return summaryState_; }
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the name of the case.
|
* \brief Returns the name of the case.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1009,6 +1009,7 @@ public:
|
|||||||
|
|
||||||
bool isSubStep = !EWOMS_GET_PARAM(TypeTag, bool, EnableWriteAllSolutions) && !this->simulator().episodeWillBeOver();
|
bool isSubStep = !EWOMS_GET_PARAM(TypeTag, bool, EnableWriteAllSolutions) && !this->simulator().episodeWillBeOver();
|
||||||
|
|
||||||
|
eclWriter_->evalSummaryState(isSubStep);
|
||||||
if (enableEclOutput_)
|
if (enableEclOutput_)
|
||||||
eclWriter_->writeOutput(isSubStep);
|
eclWriter_->writeOutput(isSubStep);
|
||||||
}
|
}
|
||||||
|
|||||||
+107
-70
@@ -54,6 +54,10 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef HAVE_MPI
|
||||||
|
#include <mpi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
BEGIN_PROPERTIES
|
BEGIN_PROPERTIES
|
||||||
|
|
||||||
NEW_PROP_TAG(EnableEclOutput);
|
NEW_PROP_TAG(EnableEclOutput);
|
||||||
@@ -207,13 +211,109 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief collect and pass data and pass it to eclIO writer
|
* \brief collect and pass data and pass it to eclIO writer
|
||||||
*/
|
*/
|
||||||
void writeOutput(bool isSubStep)
|
|
||||||
|
void evalSummaryState(bool isSubStep)
|
||||||
{
|
{
|
||||||
|
int reportStepNum = simulator_.episodeIndex() + 1;
|
||||||
|
/*
|
||||||
|
The summary data is not evaluated for timestep 0, that is
|
||||||
|
implemented with a:
|
||||||
|
|
||||||
|
if (time_step == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
check somewhere in the summary code. When the summary code was
|
||||||
|
split in separate methods Summary::eval() and
|
||||||
|
Summary::add_timestep() it was necessary to pull this test out
|
||||||
|
here to ensure that the well and group related keywords in the
|
||||||
|
restart file, like XWEL and XGRP were "correct" also in the
|
||||||
|
initial report step.
|
||||||
|
|
||||||
|
"Correct" in this context means unchanged behavior, might very
|
||||||
|
well be more correct to actually remove this if test.
|
||||||
|
*/
|
||||||
|
if (reportStepNum == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& summary = eclIO_->summary();
|
||||||
Scalar curTime = simulator_.time() + simulator_.timeStepSize();
|
Scalar curTime = simulator_.time() + simulator_.timeStepSize();
|
||||||
Scalar totalCpuTime =
|
Scalar totalCpuTime =
|
||||||
simulator_.executionTimer().realTimeElapsed() +
|
simulator_.executionTimer().realTimeElapsed() +
|
||||||
simulator_.setupTimer().realTimeElapsed() +
|
simulator_.setupTimer().realTimeElapsed() +
|
||||||
simulator_.vanguard().externalSetupTime();
|
simulator_.vanguard().externalSetupTime();
|
||||||
|
|
||||||
|
Opm::data::Wells localWellData = simulator_.problem().wellModel().wellData();
|
||||||
|
|
||||||
|
const auto& gridView = simulator_.vanguard().gridView();
|
||||||
|
int numElements = gridView.size(/*codim=*/0);
|
||||||
|
bool log = collectToIORank_.isIORank();
|
||||||
|
eclOutputModule_.allocBuffers(numElements, reportStepNum, isSubStep, log);
|
||||||
|
|
||||||
|
ElementContext elemCtx(simulator_);
|
||||||
|
ElementIterator elemIt = gridView.template begin</*codim=*/0>();
|
||||||
|
const ElementIterator& elemEndIt = gridView.template end</*codim=*/0>();
|
||||||
|
for (; elemIt != elemEndIt; ++elemIt) {
|
||||||
|
const Element& elem = *elemIt;
|
||||||
|
elemCtx.updatePrimaryStencil(elem);
|
||||||
|
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
|
||||||
|
eclOutputModule_.processElement(elemCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collectToIORank_.isParallel())
|
||||||
|
collectToIORank_.collect({}, eclOutputModule_.getBlockData(), localWellData);
|
||||||
|
|
||||||
|
std::map<std::string, double> miscSummaryData;
|
||||||
|
std::map<std::string, std::vector<double>> regionData;
|
||||||
|
eclOutputModule_.outputFipLog(miscSummaryData, regionData, isSubStep);
|
||||||
|
|
||||||
|
std::vector<char> buffer;
|
||||||
|
if (collectToIORank_.isIORank()) {
|
||||||
|
const auto& eclState = simulator_.vanguard().eclState();
|
||||||
|
|
||||||
|
// Add TCPU
|
||||||
|
if (totalCpuTime != 0.0)
|
||||||
|
miscSummaryData["TCPU"] = totalCpuTime;
|
||||||
|
|
||||||
|
const Opm::data::Wells& wellData = collectToIORank_.isParallel() ? collectToIORank_.globalWellData() : localWellData;
|
||||||
|
|
||||||
|
const std::map<std::pair<std::string, int>, double>& blockData
|
||||||
|
= collectToIORank_.isParallel()
|
||||||
|
? collectToIORank_.globalBlockData()
|
||||||
|
: eclOutputModule_.getBlockData();
|
||||||
|
|
||||||
|
summary.eval(summaryState(),
|
||||||
|
reportStepNum,
|
||||||
|
curTime,
|
||||||
|
eclState,
|
||||||
|
schedule(),
|
||||||
|
wellData,
|
||||||
|
miscSummaryData,
|
||||||
|
regionData,
|
||||||
|
blockData);
|
||||||
|
buffer = summaryState().serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collectToIORank_.isParallel()) {
|
||||||
|
unsigned long buffer_size = buffer.size();
|
||||||
|
|
||||||
|
#ifdef HAVE_MPI
|
||||||
|
MPI_Bcast(&buffer_size, 1, MPI_UNSIGNED_LONG, collectToIORank_.ioRank, MPI_COMM_WORLD);
|
||||||
|
if (!collectToIORank_.isIORank())
|
||||||
|
buffer.resize( buffer_size );
|
||||||
|
|
||||||
|
MPI_Bcast(buffer.data(), buffer_size, MPI_CHAR, collectToIORank_.ioRank, MPI_COMM_WORLD);
|
||||||
|
if (!collectToIORank_.isIORank()) {
|
||||||
|
Opm::SummaryState& st = summaryState();
|
||||||
|
st.deserialize(buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeOutput(bool isSubStep)
|
||||||
|
{
|
||||||
|
Scalar curTime = simulator_.time() + simulator_.timeStepSize();
|
||||||
Scalar nextStepSize = simulator_.problem().nextTimeStepSize();
|
Scalar nextStepSize = simulator_.problem().nextTimeStepSize();
|
||||||
|
|
||||||
// output using eclWriter if enabled
|
// output using eclWriter if enabled
|
||||||
@@ -248,48 +348,30 @@ public:
|
|||||||
if (collectToIORank_.isParallel())
|
if (collectToIORank_.isParallel())
|
||||||
collectToIORank_.collect(localCellData, eclOutputModule_.getBlockData(), localWellData);
|
collectToIORank_.collect(localCellData, eclOutputModule_.getBlockData(), localWellData);
|
||||||
|
|
||||||
std::map<std::string, double> miscSummaryData;
|
|
||||||
std::map<std::string, std::vector<double>> regionData;
|
|
||||||
eclOutputModule_.outputFipLog(miscSummaryData, regionData, isSubStep);
|
|
||||||
|
|
||||||
// write output on I/O rank
|
|
||||||
if (collectToIORank_.isIORank()) {
|
if (collectToIORank_.isIORank()) {
|
||||||
const auto& eclState = simulator_.vanguard().eclState();
|
const auto& eclState = simulator_.vanguard().eclState();
|
||||||
const auto& simConfig = eclState.getSimulationConfig();
|
const auto& simConfig = eclState.getSimulationConfig();
|
||||||
|
|
||||||
// Add TCPU
|
|
||||||
if (totalCpuTime != 0.0)
|
|
||||||
miscSummaryData["TCPU"] = totalCpuTime;
|
|
||||||
|
|
||||||
bool enableDoublePrecisionOutput = EWOMS_GET_PARAM(TypeTag, bool, EclOutputDoublePrecision);
|
bool enableDoublePrecisionOutput = EWOMS_GET_PARAM(TypeTag, bool, EclOutputDoublePrecision);
|
||||||
const Opm::data::Solution& cellData = collectToIORank_.isParallel() ? collectToIORank_.globalCellData() : localCellData;
|
const Opm::data::Solution& cellData = collectToIORank_.isParallel() ? collectToIORank_.globalCellData() : localCellData;
|
||||||
const Opm::data::Wells& wellData = collectToIORank_.isParallel() ? collectToIORank_.globalWellData() : localWellData;
|
const Opm::data::Wells& wellData = collectToIORank_.isParallel() ? collectToIORank_.globalWellData() : localWellData;
|
||||||
Opm::RestartValue restartValue(cellData, wellData);
|
Opm::RestartValue restartValue(cellData, wellData);
|
||||||
|
|
||||||
const std::map<std::pair<std::string, int>, double>& blockData
|
if (simConfig.useThresholdPressure())
|
||||||
= collectToIORank_.isParallel()
|
restartValue.addExtra("THRESHPR", Opm::UnitSystem::measure::pressure, simulator_.problem().thresholdPressure().data());
|
||||||
? collectToIORank_.globalBlockData()
|
|
||||||
: eclOutputModule_.getBlockData();
|
|
||||||
|
|
||||||
// Add suggested next timestep to extra data.
|
// Add suggested next timestep to extra data.
|
||||||
if (!isSubStep)
|
if (!isSubStep)
|
||||||
restartValue.addExtra("OPMEXTRA", std::vector<double>(1, nextStepSize));
|
restartValue.addExtra("OPMEXTRA", std::vector<double>(1, nextStepSize));
|
||||||
|
|
||||||
if (simConfig.useThresholdPressure())
|
|
||||||
restartValue.addExtra("THRESHPR", Opm::UnitSystem::measure::pressure, simulator_.problem().thresholdPressure().data());
|
|
||||||
|
|
||||||
// first, create a tasklet to write the data for the current time step to disk
|
// first, create a tasklet to write the data for the current time step to disk
|
||||||
auto eclWriteTasklet = std::make_shared<EclWriteTasklet>(summaryState(),
|
auto eclWriteTasklet = std::make_shared<EclWriteTasklet>(summaryState(),
|
||||||
eclState,
|
|
||||||
schedule(),
|
|
||||||
*eclIO_,
|
*eclIO_,
|
||||||
reportStepNum,
|
reportStepNum,
|
||||||
isSubStep,
|
isSubStep,
|
||||||
curTime,
|
curTime,
|
||||||
restartValue,
|
restartValue,
|
||||||
miscSummaryData,
|
|
||||||
regionData,
|
|
||||||
blockData,
|
|
||||||
enableDoublePrecisionOutput);
|
enableDoublePrecisionOutput);
|
||||||
|
|
||||||
// then, make sure that the previous I/O request has been completed and the
|
// then, make sure that the previous I/O request has been completed and the
|
||||||
@@ -575,79 +657,34 @@ private:
|
|||||||
struct EclWriteTasklet
|
struct EclWriteTasklet
|
||||||
: public TaskletInterface
|
: public TaskletInterface
|
||||||
{
|
{
|
||||||
Opm::SummaryState& summaryState;
|
Opm::SummaryState summaryState_;
|
||||||
const Opm::EclipseState& eclState;
|
|
||||||
const Opm::Schedule& schedule;
|
|
||||||
Opm::EclipseIO& eclIO_;
|
Opm::EclipseIO& eclIO_;
|
||||||
int reportStepNum_;
|
int reportStepNum_;
|
||||||
bool isSubStep_;
|
bool isSubStep_;
|
||||||
double secondsElapsed_;
|
double secondsElapsed_;
|
||||||
Opm::RestartValue restartValue_;
|
Opm::RestartValue restartValue_;
|
||||||
std::map<std::string, double> singleSummaryValues_;
|
|
||||||
std::map<std::string, std::vector<double>> regionSummaryValues_;
|
|
||||||
std::map<std::pair<std::string, int>, double> blockSummaryValues_;
|
|
||||||
bool writeDoublePrecision_;
|
bool writeDoublePrecision_;
|
||||||
|
|
||||||
explicit EclWriteTasklet(Opm::SummaryState& summaryState,
|
explicit EclWriteTasklet(const Opm::SummaryState& summaryState,
|
||||||
const Opm::EclipseState& eclState,
|
|
||||||
const Opm::Schedule& schedule,
|
|
||||||
Opm::EclipseIO& eclIO,
|
Opm::EclipseIO& eclIO,
|
||||||
int reportStepNum,
|
int reportStepNum,
|
||||||
bool isSubStep,
|
bool isSubStep,
|
||||||
double secondsElapsed,
|
double secondsElapsed,
|
||||||
Opm::RestartValue restartValue,
|
Opm::RestartValue restartValue,
|
||||||
const std::map<std::string, double>& singleSummaryValues,
|
|
||||||
const std::map<std::string, std::vector<double>>& regionSummaryValues,
|
|
||||||
const std::map<std::pair<std::string, int>, double>& blockSummaryValues,
|
|
||||||
bool writeDoublePrecision)
|
bool writeDoublePrecision)
|
||||||
: summaryState(summaryState)
|
: summaryState_(summaryState)
|
||||||
, eclState(eclState)
|
|
||||||
, schedule(schedule)
|
|
||||||
, eclIO_(eclIO)
|
, eclIO_(eclIO)
|
||||||
, reportStepNum_(reportStepNum)
|
, reportStepNum_(reportStepNum)
|
||||||
, isSubStep_(isSubStep)
|
, isSubStep_(isSubStep)
|
||||||
, secondsElapsed_(secondsElapsed)
|
, secondsElapsed_(secondsElapsed)
|
||||||
, restartValue_(restartValue)
|
, restartValue_(restartValue)
|
||||||
, singleSummaryValues_(singleSummaryValues)
|
|
||||||
, regionSummaryValues_(regionSummaryValues)
|
|
||||||
, blockSummaryValues_(blockSummaryValues)
|
|
||||||
, writeDoublePrecision_(writeDoublePrecision)
|
, writeDoublePrecision_(writeDoublePrecision)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// callback to eclIO serial writeTimeStep method
|
// callback to eclIO serial writeTimeStep method
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
const auto& summary = eclIO_.summary();
|
eclIO_.writeTimeStep(summaryState_,
|
||||||
|
|
||||||
/*
|
|
||||||
The summary data is not evaluated for timestep 0, that is
|
|
||||||
implemented with a:
|
|
||||||
|
|
||||||
if (time_step == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
check somewhere in the summary code. When the summary code was
|
|
||||||
split in separate methods Summary::eval() and
|
|
||||||
Summary::add_timestep() it was necessary to pull this test out
|
|
||||||
here to ensure that the well and group related keywords in the
|
|
||||||
restart file, like XWEL and XGRP were "correct" also in the
|
|
||||||
initial report step.
|
|
||||||
|
|
||||||
"Correct" in this context means unchanged behavior, might very
|
|
||||||
well be more correct to actually remove this if test.
|
|
||||||
*/
|
|
||||||
if (reportStepNum_ > 0)
|
|
||||||
summary.eval(summaryState,
|
|
||||||
reportStepNum_,
|
|
||||||
secondsElapsed_,
|
|
||||||
eclState,
|
|
||||||
schedule,
|
|
||||||
restartValue_.wells,
|
|
||||||
singleSummaryValues_,
|
|
||||||
regionSummaryValues_,
|
|
||||||
blockSummaryValues_);
|
|
||||||
|
|
||||||
eclIO_.writeTimeStep(summaryState,
|
|
||||||
reportStepNum_,
|
reportStepNum_,
|
||||||
isSubStep_,
|
isSubStep_,
|
||||||
secondsElapsed_,
|
secondsElapsed_,
|
||||||
|
|||||||
@@ -132,11 +132,17 @@ void test_summary()
|
|||||||
Opm::data::Wells dw;
|
Opm::data::Wells dw;
|
||||||
bool substep = false;
|
bool substep = false;
|
||||||
simulator->startNextEpisode(0.0, 1e30);
|
simulator->startNextEpisode(0.0, 1e30);
|
||||||
|
|
||||||
simulator->setEpisodeIndex(0);
|
simulator->setEpisodeIndex(0);
|
||||||
|
eclWriter->evalSummaryState(substep);
|
||||||
eclWriter->writeOutput(substep);
|
eclWriter->writeOutput(substep);
|
||||||
|
|
||||||
simulator->setEpisodeIndex(1);
|
simulator->setEpisodeIndex(1);
|
||||||
|
eclWriter->evalSummaryState(substep);
|
||||||
eclWriter->writeOutput(substep);
|
eclWriter->writeOutput(substep);
|
||||||
|
|
||||||
simulator->setEpisodeIndex(2);
|
simulator->setEpisodeIndex(2);
|
||||||
|
eclWriter->evalSummaryState(substep);
|
||||||
eclWriter->writeOutput(substep);
|
eclWriter->writeOutput(substep);
|
||||||
|
|
||||||
auto res = readsum( casename );
|
auto res = readsum( casename );
|
||||||
|
|||||||
Reference in New Issue
Block a user