mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
switch the EclWriter to the new tasklet infrastructure
This commit is contained in:
parent
7b56e9e9df
commit
8f61fe03fa
@ -206,9 +206,14 @@ SET_BOOL_PROP(EclBaseProblem, EnableVtkOutput, false);
|
|||||||
// ... but enable the ECL output by default
|
// ... but enable the ECL output by default
|
||||||
SET_BOOL_PROP(EclBaseProblem, EnableEclOutput, true);
|
SET_BOOL_PROP(EclBaseProblem, EnableEclOutput, true);
|
||||||
|
|
||||||
// Output single precision is default
|
// If available, write the ECL output in a non-blocking manner
|
||||||
|
SET_BOOL_PROP(EclBaseProblem, EnableAsyncEclOutput, true);
|
||||||
|
|
||||||
|
// By default, use single precision for the ECL formated results
|
||||||
SET_BOOL_PROP(EclBaseProblem, EclOutputDoublePrecision, false);
|
SET_BOOL_PROP(EclBaseProblem, EclOutputDoublePrecision, false);
|
||||||
|
|
||||||
|
// The default location for the ECL output files
|
||||||
|
SET_STRING_PROP(EclBaseProblem, EclOutputDir, ".");
|
||||||
|
|
||||||
// the cache for intensive quantities can be used for ECL problems and also yields a
|
// the cache for intensive quantities can be used for ECL problems and also yields a
|
||||||
// decent speedup...
|
// decent speedup...
|
||||||
@ -223,9 +228,6 @@ SET_TYPE_PROP(EclBaseProblem, FluxModule, Ewoms::EclTransFluxModule<TypeTag>);
|
|||||||
// Use the dummy gradient calculator in order not to do unnecessary work.
|
// Use the dummy gradient calculator in order not to do unnecessary work.
|
||||||
SET_TYPE_PROP(EclBaseProblem, GradientCalculator, Ewoms::EclDummyGradientCalculator<TypeTag>);
|
SET_TYPE_PROP(EclBaseProblem, GradientCalculator, Ewoms::EclDummyGradientCalculator<TypeTag>);
|
||||||
|
|
||||||
// The default location for the ECL output files
|
|
||||||
SET_STRING_PROP(EclBaseProblem, EclOutputDir, ".");
|
|
||||||
|
|
||||||
// The frequency of writing restart (*.ers) files. This is the number of time steps
|
// The frequency of writing restart (*.ers) files. This is the number of time steps
|
||||||
// between writing restart files
|
// between writing restart files
|
||||||
SET_INT_PROP(EclBaseProblem, RestartWritingInterval, 0xffffff); // disable
|
SET_INT_PROP(EclBaseProblem, RestartWritingInterval, 0xffffff); // disable
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include <ewoms/disc/ecfv/ecfvdiscretization.hh>
|
#include <ewoms/disc/ecfv/ecfvdiscretization.hh>
|
||||||
#include <ewoms/io/baseoutputwriter.hh>
|
#include <ewoms/io/baseoutputwriter.hh>
|
||||||
#include <ebos/threadhandle.hh>
|
#include <ewoms/parallel/tasklets.hh>
|
||||||
|
|
||||||
#if HAVE_ECL_OUTPUT
|
#if HAVE_ECL_OUTPUT
|
||||||
#include <opm/output/eclipse/EclipseIO.hpp>
|
#include <opm/output/eclipse/EclipseIO.hpp>
|
||||||
@ -51,6 +51,7 @@
|
|||||||
namespace Ewoms {
|
namespace Ewoms {
|
||||||
namespace Properties {
|
namespace Properties {
|
||||||
NEW_PROP_TAG(EnableEclOutput);
|
NEW_PROP_TAG(EnableEclOutput);
|
||||||
|
NEW_PROP_TAG(EnableAsyncEclOutput);
|
||||||
NEW_PROP_TAG(EclOutputDoublePrecision);
|
NEW_PROP_TAG(EclOutputDoublePrecision);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,11 +94,16 @@ class EclWriter
|
|||||||
typedef std::vector<Scalar> ScalarBuffer;
|
typedef std::vector<Scalar> ScalarBuffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static void registerParameters()
|
||||||
|
{
|
||||||
|
EWOMS_REGISTER_PARAM(TypeTag, bool, EnableAsyncEclOutput,
|
||||||
|
"Write the ECL-formated results in a non-blocking way (i.e., using a separate thread).");
|
||||||
|
}
|
||||||
|
|
||||||
EclWriter(const Simulator& simulator)
|
EclWriter(const Simulator& simulator)
|
||||||
: simulator_(simulator)
|
: simulator_(simulator)
|
||||||
, collectToIORank_(simulator_.vanguard())
|
, collectToIORank_(simulator_.vanguard())
|
||||||
, eclOutputModule_(simulator, collectToIORank_)
|
, eclOutputModule_(simulator, collectToIORank_)
|
||||||
, asyncOutput_()
|
|
||||||
{
|
{
|
||||||
globalGrid_ = simulator_.vanguard().grid();
|
globalGrid_ = simulator_.vanguard().grid();
|
||||||
globalGrid_.switchToGlobalView();
|
globalGrid_.switchToGlobalView();
|
||||||
@ -108,22 +114,9 @@ public:
|
|||||||
|
|
||||||
// create output thread if enabled and rank is I/O rank
|
// create output thread if enabled and rank is I/O rank
|
||||||
// async output is enabled by default if pthread are enabled
|
// async output is enabled by default if pthread are enabled
|
||||||
#if HAVE_PTHREAD
|
bool enableAsyncOutput = EWOMS_GET_PARAM(TypeTag, bool, EnableAsyncEclOutput);
|
||||||
const bool asyncOutputDefault = true;
|
bool createOutputThread = enableAsyncOutput && collectToIORank_.isIORank();
|
||||||
#else
|
taskletRunner_.reset(new TaskletRunner(createOutputThread));
|
||||||
const bool asyncOutputDefault = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO Add param
|
|
||||||
const bool isIORank = collectToIORank_.isParallel() && collectToIORank_.isIORank();
|
|
||||||
if( asyncOutputDefault && isIORank )
|
|
||||||
{
|
|
||||||
#if HAVE_PTHREAD
|
|
||||||
asyncOutput_.reset( new Opm::ThreadHandle( isIORank ) );
|
|
||||||
#else
|
|
||||||
throw std::runtime_error("Pthreads were not found, cannot enable async_output");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~EclWriter()
|
~EclWriter()
|
||||||
@ -190,7 +183,6 @@ public:
|
|||||||
|
|
||||||
// write output on I/O rank
|
// write output on I/O rank
|
||||||
if (collectToIORank_.isIORank()) {
|
if (collectToIORank_.isIORank()) {
|
||||||
|
|
||||||
std::map<std::string, std::vector<double>> extraRestartData;
|
std::map<std::string, std::vector<double>> extraRestartData;
|
||||||
|
|
||||||
// Add suggested next timestep to extra data.
|
// Add suggested next timestep to extra data.
|
||||||
@ -198,40 +190,37 @@ public:
|
|||||||
extraRestartData["OPMEXTRA"] = std::vector<double>(1, nextstep);
|
extraRestartData["OPMEXTRA"] = std::vector<double>(1, nextstep);
|
||||||
|
|
||||||
// Add TCPU
|
// Add TCPU
|
||||||
if (totalSolverTime != 0.0) {
|
if (totalSolverTime != 0.0)
|
||||||
miscSummaryData["TCPU"] = totalSolverTime;
|
miscSummaryData["TCPU"] = totalSolverTime;
|
||||||
}
|
|
||||||
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;
|
||||||
|
|
||||||
const std::map<std::pair<std::string, int>, double>& blockData = collectToIORank_.isParallel() ? collectToIORank_.globalBlockData() : eclOutputModule_.getBlockData();
|
const std::map<std::pair<std::string, int>, double>& blockData
|
||||||
|
= collectToIORank_.isParallel()
|
||||||
|
? collectToIORank_.globalBlockData()
|
||||||
|
: eclOutputModule_.getBlockData();
|
||||||
|
|
||||||
if( asyncOutput_ ) {
|
// first, create a tasklet to write the data for the current time step to disk
|
||||||
// dispatch the write call to the extra thread
|
auto eclWriteTasklet = std::make_shared<EclWriteTasklet>(*eclIO_,
|
||||||
asyncOutput_->dispatch( WriterCall(*eclIO_,
|
episodeIdx,
|
||||||
episodeIdx,
|
substep,
|
||||||
substep,
|
t,
|
||||||
t,
|
cellData,
|
||||||
cellData,
|
wellData,
|
||||||
wellData,
|
miscSummaryData,
|
||||||
miscSummaryData,
|
regionData,
|
||||||
regionData,
|
blockData,
|
||||||
blockData,
|
extraRestartData,
|
||||||
extraRestartData,
|
enableDoublePrecisionOutput);
|
||||||
enableDoublePrecisionOutput ) );
|
|
||||||
} else {
|
// then, make sure that the previous I/O request has been completed and the
|
||||||
eclIO_->writeTimeStep(episodeIdx,
|
// number of incomplete tasklets does not increase between time steps
|
||||||
substep,
|
taskletRunner_->barrier();
|
||||||
t,
|
|
||||||
cellData,
|
// finally, start a new output writing job
|
||||||
wellData,
|
taskletRunner_->dispatch(eclWriteTasklet);
|
||||||
miscSummaryData,
|
|
||||||
regionData,
|
|
||||||
blockData,
|
|
||||||
extraRestartData,
|
|
||||||
enableDoublePrecisionOutput);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -429,12 +418,12 @@ private:
|
|||||||
return nnc;
|
return nnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EclWriteTasklet
|
||||||
struct WriterCall : public Opm::ThreadHandle :: ObjectInterface
|
: public TaskletInterface
|
||||||
{
|
{
|
||||||
Opm::EclipseIO& eclIO_;
|
Opm::EclipseIO& eclIO_;
|
||||||
int episodeIdx_;
|
int episodeIdx_;
|
||||||
bool isSubstep_;
|
bool isSubStep_;
|
||||||
double secondsElapsed_;
|
double secondsElapsed_;
|
||||||
Opm::data::Solution cellData_;
|
Opm::data::Solution cellData_;
|
||||||
Opm::data::Wells wellData_;
|
Opm::data::Wells wellData_;
|
||||||
@ -444,38 +433,36 @@ private:
|
|||||||
std::map<std::string, std::vector<double>> extraRestartData_;
|
std::map<std::string, std::vector<double>> extraRestartData_;
|
||||||
bool writeDoublePrecision_;
|
bool writeDoublePrecision_;
|
||||||
|
|
||||||
explicit WriterCall(
|
explicit EclWriteTasklet(Opm::EclipseIO& eclIO,
|
||||||
Opm::EclipseIO& eclIO,
|
int episodeIdx,
|
||||||
int episodeIdx,
|
bool isSubStep,
|
||||||
bool isSubstep,
|
double secondsElapsed,
|
||||||
double secondsElapsed,
|
Opm::data::Solution cellData,
|
||||||
Opm::data::Solution cellData,
|
Opm::data::Wells wellData,
|
||||||
Opm::data::Wells wellData,
|
const std::map<std::string, double>& singleSummaryValues,
|
||||||
const std::map<std::string, double>& singleSummaryValues,
|
const std::map<std::string, std::vector<double>>& regionSummaryValues,
|
||||||
const std::map<std::string, std::vector<double>>& regionSummaryValues,
|
const std::map<std::pair<std::string, int>, double>& blockSummaryValues,
|
||||||
const std::map<std::pair<std::string, int>, double>& blockSummaryValues,
|
const std::map<std::string, std::vector<double>>& extraRestartData,
|
||||||
const std::map<std::string, std::vector<double>>& extraRestartData,
|
bool writeDoublePrecision)
|
||||||
bool writeDoublePrecision)
|
: eclIO_(eclIO)
|
||||||
: eclIO_(eclIO),
|
, episodeIdx_(episodeIdx)
|
||||||
episodeIdx_(episodeIdx),
|
, isSubStep_(isSubStep)
|
||||||
isSubstep_(isSubstep),
|
, secondsElapsed_(secondsElapsed)
|
||||||
secondsElapsed_(secondsElapsed),
|
, cellData_(cellData)
|
||||||
cellData_(cellData),
|
, wellData_(wellData)
|
||||||
wellData_(wellData),
|
, singleSummaryValues_(singleSummaryValues)
|
||||||
singleSummaryValues_(singleSummaryValues),
|
, regionSummaryValues_(regionSummaryValues)
|
||||||
regionSummaryValues_(regionSummaryValues),
|
, blockSummaryValues_(blockSummaryValues)
|
||||||
blockSummaryValues_(blockSummaryValues),
|
, extraRestartData_(extraRestartData)
|
||||||
extraRestartData_(extraRestartData),
|
, writeDoublePrecision_(writeDoublePrecision)
|
||||||
writeDoublePrecision_(writeDoublePrecision)
|
{ }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// callback to eclIO serial writeTimeStep method
|
// callback to eclIO serial writeTimeStep method
|
||||||
void run ()
|
void run ()
|
||||||
{
|
{
|
||||||
// write data
|
// write data
|
||||||
eclIO_.writeTimeStep(episodeIdx_,
|
eclIO_.writeTimeStep(episodeIdx_,
|
||||||
isSubstep_,
|
isSubStep_,
|
||||||
secondsElapsed_,
|
secondsElapsed_,
|
||||||
cellData_,
|
cellData_,
|
||||||
wellData_,
|
wellData_,
|
||||||
@ -495,7 +482,7 @@ private:
|
|||||||
EclOutputBlackOilModule<TypeTag> eclOutputModule_;
|
EclOutputBlackOilModule<TypeTag> eclOutputModule_;
|
||||||
std::unique_ptr<Opm::EclipseIO> eclIO_;
|
std::unique_ptr<Opm::EclipseIO> eclIO_;
|
||||||
Grid globalGrid_;
|
Grid globalGrid_;
|
||||||
std::unique_ptr< Opm::ThreadHandle > asyncOutput_;
|
std::unique_ptr<TaskletRunner> taskletRunner_;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user