Prepare for Revised Implementation of WBPn

This initial commit changes the API of the CollectDataToIORank
class' handling of WBPn values from collecting a set cell pressures
into communicating pre-computed WBPn values through the new
WellBlockAveragePressures container class.  This is in preparation
of moving the WBPn calculation to the simulator side for greater
parallelism.  For now we do not compute any of the actual WBPn
values.  That will be the subject of follow-up commits.

While here, also split a number of very long lines for readability.
This commit is contained in:
Bård Skaflestad
2023-06-06 16:51:47 +02:00
parent b1ffc68853
commit 9d75915e4b
8 changed files with 307 additions and 257 deletions

View File

@@ -531,55 +531,48 @@ public:
class PackUnPackWBPData : public P2PCommunicatorType::DataHandleInterface class PackUnPackWBPData : public P2PCommunicatorType::DataHandleInterface
{ {
const std::map<std::size_t, double>& localWBPData_; const data::WellBlockAveragePressures& localWBPData_;
std::map<std::size_t, double>& globalWBPValues_; data::WellBlockAveragePressures& globalWBPValues_;
public: public:
PackUnPackWBPData(const std::map<std::size_t, double>& localWBPData, PackUnPackWBPData(const data::WellBlockAveragePressures& localWBPData,
std::map<std::size_t, double>& globalWBPValues, data::WellBlockAveragePressures& globalWBPValues,
bool isIORank) const bool isIORank)
: localWBPData_(localWBPData) : localWBPData_ (localWBPData)
, globalWBPValues_(globalWBPValues) , globalWBPValues_(globalWBPValues)
{ {
if (isIORank) { if (! isIORank) {
MessageBufferType buffer; return;
pack(0, buffer);
// pass a dummyLink to satisfy virtual class
int dummyLink = -1;
unpack(dummyLink, buffer);
} }
MessageBufferType buffer;
pack(0, buffer);
// Pass a dummy link to satisfy base class API requirement
const int dummyLink = -1;
unpack(dummyLink, buffer);
} }
// pack all data associated with link // Pack all data associated with link
void pack(int link, MessageBufferType& buffer) void pack(int link, MessageBufferType& buffer)
{ {
// we should only get one link // We should only get one link
if (link != 0) if (link != 0) {
throw std::logic_error("link in method pack is not 0 as expected"); throw std::logic_error {
"link (" + std::to_string(link) +
// write all block data ") in method pack() is not 0 as expected"
unsigned int size = localWBPData_.size(); };
buffer.write(size);
for (const auto& [global_index, wbp_value] : localWBPData_) {
buffer.write(global_index);
buffer.write(wbp_value);
} }
// Write all local, per-well, WBP data
this->localWBPData_.write(buffer);
} }
// unpack all data associated with link // Unpack all data associated with link
void unpack(int /*link*/, MessageBufferType& buffer) void unpack([[maybe_unused]] const int link,
MessageBufferType& buffer)
{ {
// read all block data this->globalWBPValues_.read(buffer);
unsigned int size = 0;
buffer.read(size);
for (size_t i = 0; i < size; ++i) {
std::size_t idx;
double data;
buffer.read(idx);
buffer.read(data);
globalWBPValues_[idx] = data;
}
} }
}; };
@@ -984,21 +977,21 @@ CollectDataToIORank(const Grid& grid, const EquilGrid* equilGrid,
template <class Grid, class EquilGrid, class GridView> template <class Grid, class EquilGrid, class GridView>
void CollectDataToIORank<Grid,EquilGrid,GridView>:: void CollectDataToIORank<Grid,EquilGrid,GridView>::
collect(const data::Solution& localCellData, collect(const data::Solution& localCellData,
const std::map<std::pair<std::string, int>, double>& localBlockData, const std::map<std::pair<std::string, int>, double>& localBlockData,
const std::map<std::size_t, double>& localWBPData, const data::Wells& localWellData,
const data::Wells& localWellData, const data::WellBlockAveragePressures& localWBPData,
const data::GroupAndNetworkValues& localGroupAndNetworkData, const data::GroupAndNetworkValues& localGroupAndNetworkData,
const data::Aquifers& localAquiferData, const data::Aquifers& localAquiferData,
const WellTestState& localWellTestState, const WellTestState& localWellTestState,
const EclInterRegFlowMap& localInterRegFlows, const EclInterRegFlowMap& localInterRegFlows,
const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFlowsn, const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFlowsn,
const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFloresn) const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFloresn)
{ {
globalCellData_ = {}; globalCellData_ = {};
globalBlockData_.clear(); globalBlockData_.clear();
globalWBPData_.clear();
globalWellData_.clear(); globalWellData_.clear();
globalWBPData_.values.clear();
globalGroupAndNetworkData_.clear(); globalGroupAndNetworkData_.clear();
globalAquiferData_.clear(); globalAquiferData_.clear();
globalWellTestState_.clear(); globalWellTestState_.clear();
@@ -1055,8 +1048,8 @@ collect(const data::Solution& localCellData,
PackUnPackWBPData packUnpackWBPData { PackUnPackWBPData packUnpackWBPData {
localWBPData, localWBPData,
this->globalWBPData_, this->globalWBPData_,
this->isIORank() this->isIORank()
}; };
PackUnPackAquiferData packUnpackAquiferData { PackUnPackAquiferData packUnpackAquiferData {
@@ -1110,28 +1103,37 @@ template <class Grid, class EquilGrid, class GridView>
int CollectDataToIORank<Grid,EquilGrid,GridView>:: int CollectDataToIORank<Grid,EquilGrid,GridView>::
localIdxToGlobalIdx(unsigned localIdx) const localIdxToGlobalIdx(unsigned localIdx) const
{ {
if (!isParallel()) if (!isParallel()) {
return localIdx; return localIdx;
}
if (localIdxToGlobalIdx_.empty()) if (this->localIdxToGlobalIdx_.empty()) {
throw std::logic_error("index map is not created on this rank"); throw std::logic_error("index map is not created on this rank");
}
if (localIdx > localIdxToGlobalIdx_.size()) if (localIdx > this->localIdxToGlobalIdx_.size()) {
throw std::logic_error("local index is outside map range"); throw std::logic_error("local index is outside map range");
}
return localIdxToGlobalIdx_[localIdx]; return this->localIdxToGlobalIdx_[localIdx];
} }
template <class Grid, class EquilGrid, class GridView> template <class Grid, class EquilGrid, class GridView>
bool CollectDataToIORank<Grid,EquilGrid,GridView>:: bool CollectDataToIORank<Grid,EquilGrid,GridView>::
isCartIdxOnThisRank(int cartIdx) const isCartIdxOnThisRank(int cartIdx) const
{ {
if (!isParallel()) if (! this->isParallel()) {
return true; return true;
}
assert(!needsReordering); assert (! needsReordering);
auto candidate = std::lower_bound(sortedCartesianIdx_.begin(), sortedCartesianIdx_.end(), cartIdx);
return (candidate != sortedCartesianIdx_.end() && *candidate == cartIdx); auto candidate = std::lower_bound(this->sortedCartesianIdx_.begin(),
this->sortedCartesianIdx_.end(),
cartIdx);
return (candidate != sortedCartesianIdx_.end())
&& (*candidate == cartIdx);
} }

View File

@@ -25,15 +25,21 @@
#include <opm/output/data/Aquifer.hpp> #include <opm/output/data/Aquifer.hpp>
#include <opm/output/data/Cells.hpp> #include <opm/output/data/Cells.hpp>
#include <opm/output/data/Groups.hpp>
#include <opm/output/data/Solution.hpp> #include <opm/output/data/Solution.hpp>
#include <opm/output/data/Wells.hpp> #include <opm/output/data/Wells.hpp>
#include <opm/output/data/Groups.hpp>
#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp> #include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
#include <opm/grid/common/p2pcommunicator.hh> #include <opm/grid/common/p2pcommunicator.hh>
#include <ebos/eclinterregflows.hh> #include <ebos/eclinterregflows.hh>
#include <array>
#include <map> #include <map>
#include <set>
#include <string>
#include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -67,20 +73,17 @@ public:
const std::set<std::string>& fipRegionsInterregFlow = {}); const std::set<std::string>& fipRegionsInterregFlow = {});
// gather solution to rank 0 for EclipseWriter // gather solution to rank 0 for EclipseWriter
void collect(const data::Solution& localCellData, void collect(const data::Solution& localCellData,
const std::map<std::pair<std::string, int>, double>& localBlockData, const std::map<std::pair<std::string, int>, double>& localBlockData,
const std::map<std::size_t, double>& localWBPData, const data::Wells& localWellData,
const data::Wells& localWellData, const data::WellBlockAveragePressures& localWBPData,
const data::GroupAndNetworkValues& localGroupAndNetworkData, const data::GroupAndNetworkValues& localGroupAndNetworkData,
const data::Aquifers& localAquiferData, const data::Aquifers& localAquiferData,
const WellTestState& localWellTestState, const WellTestState& localWellTestState,
const EclInterRegFlowMap& interRegFlows, const EclInterRegFlowMap& interRegFlows,
const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFlowsn, const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFlowsn,
const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFloresn); const std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>& localFloresn);
const std::map<std::size_t, double>& globalWBPData() const
{ return this->globalWBPData_; }
const std::map<std::pair<std::string, int>, double>& globalBlockData() const const std::map<std::pair<std::string, int>, double>& globalBlockData() const
{ return globalBlockData_; } { return globalBlockData_; }
@@ -90,8 +93,8 @@ public:
const data::Wells& globalWellData() const const data::Wells& globalWellData() const
{ return globalWellData_; } { return globalWellData_; }
const WellTestState& globalWellTestState() const const data::WellBlockAveragePressures& globalWBPData() const
{ return this->globalWellTestState_; } { return this->globalWBPData_; }
const data::GroupAndNetworkValues& globalGroupAndNetworkData() const const data::GroupAndNetworkValues& globalGroupAndNetworkData() const
{ return globalGroupAndNetworkData_; } { return globalGroupAndNetworkData_; }
@@ -99,6 +102,9 @@ public:
const data::Aquifers& globalAquiferData() const const data::Aquifers& globalAquiferData() const
{ return globalAquiferData_; } { return globalAquiferData_; }
const WellTestState& globalWellTestState() const
{ return this->globalWellTestState_; }
EclInterRegFlowMap& globalInterRegFlows() EclInterRegFlowMap& globalInterRegFlows()
{ return this->globalInterRegFlows_; } { return this->globalInterRegFlows_; }
@@ -144,8 +150,8 @@ protected:
std::vector<int> globalRanks_; std::vector<int> globalRanks_;
data::Solution globalCellData_; data::Solution globalCellData_;
std::map<std::pair<std::string, int>, double> globalBlockData_; std::map<std::pair<std::string, int>, double> globalBlockData_;
std::map<std::size_t, double> globalWBPData_;
data::Wells globalWellData_; data::Wells globalWellData_;
data::WellBlockAveragePressures globalWBPData_;
data::GroupAndNetworkValues globalGroupAndNetworkData_; data::GroupAndNetworkValues globalGroupAndNetworkData_;
data::Aquifers globalAquiferData_; data::Aquifers globalAquiferData_;
WellTestState globalWellTestState_; WellTestState globalWellTestState_;

View File

@@ -234,11 +234,6 @@ public:
return this->interRegionFlows_.wantInterRegflowSummary(); return this->interRegionFlows_.wantInterRegflowSummary();
} }
const std::map<std::size_t, double>& getWBPData() const
{
return this->wbpData_;
}
const std::map<std::pair<std::string, int>, double>& getBlockData() const std::map<std::pair<std::string, int>, double>& getBlockData()
{ {
return blockData_; return blockData_;
@@ -552,7 +547,6 @@ protected:
std::map<size_t, Scalar> waterConnectionSaturations_; std::map<size_t, Scalar> waterConnectionSaturations_;
std::map<size_t, Scalar> gasConnectionSaturations_; std::map<size_t, Scalar> gasConnectionSaturations_;
std::map<std::pair<std::string, int>, double> blockData_; std::map<std::pair<std::string, int>, double> blockData_;
std::map<std::size_t , double> wbpData_;
std::optional<Inplace> initialInplace_; std::optional<Inplace> initialInplace_;
bool local_data_valid_; bool local_data_valid_;

View File

@@ -22,12 +22,14 @@
*/ */
#include <config.h> #include <config.h>
#include <ebos/eclgenericwriter.hh> #include <ebos/eclgenericwriter.hh>
#include <opm/grid/CpGrid.hpp> #include <opm/grid/CpGrid.hpp>
#include <opm/grid/cpgrid/GridHelpers.hpp> #include <opm/grid/cpgrid/GridHelpers.hpp>
#include <opm/grid/polyhedralgrid.hh> #include <opm/grid/polyhedralgrid.hh>
#include <opm/grid/utility/cartesianToCompressed.hpp> #include <opm/grid/utility/cartesianToCompressed.hpp>
#if HAVE_DUNE_ALUGRID #if HAVE_DUNE_ALUGRID
#include "eclalugridvanguard.hh" #include "eclalugridvanguard.hh"
#include <dune/alugrid/grid.hh> #include <dune/alugrid/grid.hh>
@@ -40,13 +42,14 @@
#include <opm/input/eclipse/EclipseState/EclipseState.hpp> #include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp> #include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <opm/input/eclipse/Schedule/Action/State.hpp> #include <opm/input/eclipse/Schedule/Action/State.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp> #include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp> #include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
#include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp> #include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
#include <opm/input/eclipse/Schedule/Well/PAvgCalculatorCollection.hpp>
#include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp> #include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp>
#include <opm/input/eclipse/Units/UnitSystem.hpp> #include <opm/input/eclipse/Units/UnitSystem.hpp>
#include <dune/grid/common/mcmgmapper.hh> #include <dune/grid/common/mcmgmapper.hh>
@@ -65,7 +68,12 @@
#include <mpi.h> #include <mpi.h>
#endif #endif
#include <algorithm>
#include <array> #include <array>
#include <cassert>
#include <functional>
#include <map>
#include <memory>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
@@ -169,22 +177,22 @@ struct EclWriteTasklet : public Opm::TaskletInterface
, reportStepNum_(reportStepNum) , reportStepNum_(reportStepNum)
, isSubStep_(isSubStep) , isSubStep_(isSubStep)
, secondsElapsed_(secondsElapsed) , secondsElapsed_(secondsElapsed)
, restartValue_(restartValue) , restartValue_(std::move(restartValue))
, writeDoublePrecision_(writeDoublePrecision) , writeDoublePrecision_(writeDoublePrecision)
{ } {}
// callback to eclIO serial writeTimeStep method // callback to eclIO serial writeTimeStep method
void run() void run()
{ {
eclIO_.writeTimeStep(actionState_, this->eclIO_.writeTimeStep(this->actionState_,
wtestState_, this->wtestState_,
summaryState_, this->summaryState_,
udqState_, this->udqState_,
reportStepNum_, this->reportStepNum_,
isSubStep_, this->isSubStep_,
secondsElapsed_, this->secondsElapsed_,
restartValue_, std::move(this->restartValue_),
writeDoublePrecision_); this->writeDoublePrecision_);
} }
}; };
@@ -210,38 +218,30 @@ EclGenericWriter(const Schedule& schedule,
cartMapper, cartMapper,
equilCartMapper, equilCartMapper,
summaryConfig.fip_regions_interreg_flow()) summaryConfig.fip_regions_interreg_flow())
, grid_(grid) , grid_ (grid)
, gridView_(gridView) , gridView_ (gridView)
, schedule_(schedule) , schedule_ (schedule)
, eclState_(eclState) , eclState_ (eclState)
, summaryConfig_(summaryConfig) , summaryConfig_ (summaryConfig)
, cartMapper_(cartMapper) , cartMapper_ (cartMapper)
, equilCartMapper_(equilCartMapper) , equilCartMapper_(equilCartMapper)
, equilGrid_(equilGrid) , equilGrid_ (equilGrid)
{ {
if (collectToIORank_.isIORank()) { if (this->collectToIORank_.isIORank()) {
eclIO_.reset(new EclipseIO(eclState_, this->eclIO_ = std::make_unique<EclipseIO>
UgGridHelpers::createEclipseGrid(*equilGrid, eclState_.getInputGrid()), (this->eclState_,
schedule_, UgGridHelpers::createEclipseGrid(*equilGrid, eclState_.getInputGrid()),
summaryConfig_, "", enableEsmry)); this->schedule_, this->summaryConfig_, "", enableEsmry);
}
const auto& wbp_calculators = eclIO_->summary().wbp_calculators( schedule.size() - 1 );
wbp_index_list_ = wbp_calculators.index_list();
}
if (collectToIORank_.isParallel()) {
const auto& comm = grid_.comm();
unsigned long size = wbp_index_list_.size();
comm.broadcast(&size, 1, collectToIORank_.ioRank);
if (!collectToIORank_.isIORank())
wbp_index_list_.resize( size );
comm.broadcast(wbp_index_list_.data(), size, collectToIORank_.ioRank);
}
// 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
int numWorkerThreads = 0; int numWorkerThreads = 0;
if (enableAsyncOutput && collectToIORank_.isIORank()) if (enableAsyncOutput && collectToIORank_.isIORank()) {
numWorkerThreads = 1; numWorkerThreads = 1;
taskletRunner_.reset(new TaskletRunner(numWorkerThreads)); }
this->taskletRunner_.reset(new TaskletRunner(numWorkerThreads));
} }
template<class Grid, class EquilGrid, class GridView, class ElementMapper, class Scalar> template<class Grid, class EquilGrid, class GridView, class ElementMapper, class Scalar>
@@ -257,12 +257,18 @@ void EclGenericWriter<Grid,EquilGrid,GridView,ElementMapper,Scalar>::
writeInit(const std::function<unsigned int(unsigned int)>& map) writeInit(const std::function<unsigned int(unsigned int)>& map)
{ {
if (collectToIORank_.isIORank()) { if (collectToIORank_.isIORank()) {
std::map<std::string, std::vector<int> > integerVectors; std::map<std::string, std::vector<int>> integerVectors;
if (collectToIORank_.isParallel()) if (collectToIORank_.isParallel()) {
integerVectors.emplace("MPI_RANK", collectToIORank_.globalRanks()); integerVectors.emplace("MPI_RANK", collectToIORank_.globalRanks());
}
auto cartMap = cartesianToCompressed(equilGrid_->size(0), UgGridHelpers::globalCell(*equilGrid_)); auto cartMap = cartesianToCompressed(equilGrid_->size(0), UgGridHelpers::globalCell(*equilGrid_));
eclIO_->writeInitial(computeTrans_(cartMap, map), integerVectors, exportNncStructure_(cartMap, map));
eclIO_->writeInitial(computeTrans_(cartMap, map),
integerVectors,
exportNncStructure_(cartMap, map));
} }
#if HAVE_MPI #if HAVE_MPI
if (collectToIORank_.isParallel()) { if (collectToIORank_.isParallel()) {
const auto& comm = grid_.comm(); const auto& comm = grid_.comm();
@@ -450,8 +456,9 @@ doWriteOutput(const int reportStepNum,
const bool needsReordering = this->collectToIORank_.doesNeedReordering(); const bool needsReordering = this->collectToIORank_.doesNeedReordering();
RestartValue restartValue { RestartValue restartValue {
(isParallel || needsReordering) ? this->collectToIORank_.globalCellData() (isParallel || needsReordering)
: std::move(localCellData), ? this->collectToIORank_.globalCellData()
: std::move(localCellData),
isParallel ? this->collectToIORank_.globalWellData() isParallel ? this->collectToIORank_.globalWellData()
: std::move(localWellData), : std::move(localWellData),
@@ -515,32 +522,32 @@ doWriteOutput(const int reportStepNum,
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,
const Scalar curTime, const Scalar curTime,
const std::map<std::size_t, double>& wbpData, const data::Wells& localWellData,
const data::Wells& localWellData, const data::WellBlockAveragePressures& localWBPData,
const data::GroupAndNetworkValues& localGroupAndNetworkData, const data::GroupAndNetworkValues& localGroupAndNetworkData,
const std::map<int,data::AquiferData>& localAquiferData, const std::map<int,data::AquiferData>& localAquiferData,
const std::map<std::pair<std::string, int>, double>& blockData, const std::map<std::pair<std::string, int>, double>& blockData,
const std::map<std::string, double>& miscSummaryData, const std::map<std::string, double>& miscSummaryData,
const std::map<std::string, std::vector<double>>& regionData, const std::map<std::string, std::vector<double>>& regionData,
const Inplace& inplace, const Inplace& inplace,
const Inplace& initialInPlace, const Inplace& initialInPlace,
const EclInterRegFlowMap& interRegionFlowMap, const EclInterRegFlowMap& interRegFlows,
SummaryState& summaryState, SummaryState& summaryState,
UDQState& udqState) UDQState& udqState)
{ {
if (collectToIORank_.isIORank()) { if (collectToIORank_.isIORank()) {
const auto& summary = eclIO_->summary(); const auto& summary = eclIO_->summary();
auto wbp_calculators = summary.wbp_calculators(reportStepNum);
for (const auto& [global_index, pressure] : wbpData)
wbp_calculators.add_pressure( global_index, pressure );
const auto& wellData = this->collectToIORank_.isParallel() const auto& wellData = this->collectToIORank_.isParallel()
? this->collectToIORank_.globalWellData() ? this->collectToIORank_.globalWellData()
: localWellData; : localWellData;
const auto& wbpData = this->collectToIORank_.isParallel()
? this->collectToIORank_.globalWBPData()
: localWBPData;
const auto& groupAndNetworkData = this->collectToIORank_.isParallel() const auto& groupAndNetworkData = this->collectToIORank_.isParallel()
? this->collectToIORank_.globalGroupAndNetworkData() ? this->collectToIORank_.globalGroupAndNetworkData()
: localGroupAndNetworkData; : localGroupAndNetworkData;
@@ -553,24 +560,29 @@ evalSummary(const int reportStepNum,
reportStepNum, reportStepNum,
curTime, curTime,
wellData, wellData,
wbpData,
groupAndNetworkData, groupAndNetworkData,
miscSummaryData, miscSummaryData,
initialInPlace, initialInPlace,
inplace, inplace,
wbp_calculators,
regionData, regionData,
blockData, blockData,
aquiferData, aquiferData,
getInterRegFlowsAsMap(interRegionFlowMap)); getInterRegFlowsAsMap(interRegFlows));
// Off-by-one-fun: The reportStepNum argument corresponds to the // Off-by-one-fun: The reportStepNum argument corresponds to the
// report step these results will be written to, whereas the // report step these results will be written to, whereas the
// argument to UDQ function evaluation corresponds to the report // argument to UDQ function evaluation corresponds to the report
// step we are currently on. // step we are currently on.
auto udq_step = reportStepNum - 1; const auto udq_step = reportStepNum - 1;
const auto& udq_config = schedule_.getUDQConfig(udq_step);
udq_config.eval( udq_step, schedule_.wellMatcher(udq_step), summaryState, udqState); this->schedule_.getUDQConfig(udq_step)
.eval(udq_step,
this->schedule_.wellMatcher(udq_step),
summaryState,
udqState);
} }
#if HAVE_MPI #if HAVE_MPI
if (collectToIORank_.isParallel()) { if (collectToIORank_.isParallel()) {
EclMpiSerializer ser(grid_.comm()); EclMpiSerializer ser(grid_.comm());

View File

@@ -116,10 +116,10 @@ protected:
data::GroupAndNetworkValues&& localGroupAndNetworkData, data::GroupAndNetworkValues&& localGroupAndNetworkData,
data::Aquifers&& localAquiferData, data::Aquifers&& localAquiferData,
WellTestState&& localWTestState, WellTestState&& localWTestState,
const Action::State& actionState, const Action::State& actionState,
const UDQState& udqState, const UDQState& udqState,
const SummaryState& summaryState, const SummaryState& summaryState,
const std::vector<Scalar>& thresholdPressure, const std::vector<Scalar>& thresholdPressure,
Scalar curTime, Scalar curTime,
Scalar nextStepSize, Scalar nextStepSize,
bool doublePrecision, bool doublePrecision,
@@ -128,20 +128,20 @@ protected:
bool isFloresn, bool isFloresn,
std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>&& floresn); std::array<std::pair<std::string, std::pair<std::vector<int>, std::vector<double>>>, 3>&& floresn);
void evalSummary(int reportStepNum, void evalSummary(int reportStepNum,
Scalar curTime, Scalar curTime,
const std::map<std::size_t, double>& wbpData, const data::Wells& localWellData,
const data::Wells& localWellData, const data::WellBlockAveragePressures& localWBPData,
const data::GroupAndNetworkValues& localGroupAndNetworkData, const data::GroupAndNetworkValues& localGroupAndNetworkData,
const std::map<int,data::AquiferData>& localAquiferData, const std::map<int,data::AquiferData>& localAquiferData,
const std::map<std::pair<std::string, int>, double>& blockData, const std::map<std::pair<std::string, int>, double>& blockData,
const std::map<std::string, double>& miscSummaryData, const std::map<std::string, double>& miscSummaryData,
const std::map<std::string, std::vector<double>>& regionData, const std::map<std::string, std::vector<double>>& regionData,
const Inplace& inplace, const Inplace& inplace,
const Inplace& initialInPlace, const Inplace& initialInPlace,
const EclInterRegFlowMap& interRegionFlowMap, const EclInterRegFlowMap& interRegFlows,
SummaryState& summaryState, SummaryState& summaryState,
UDQState& udqState); UDQState& udqState);
CollectDataToIORankType collectToIORank_; CollectDataToIORankType collectToIORank_;
const Grid& grid_; const Grid& grid_;
@@ -156,7 +156,6 @@ protected:
const Dune::CartesianIndexMapper<Grid>& cartMapper_; const Dune::CartesianIndexMapper<Grid>& cartMapper_;
const Dune::CartesianIndexMapper<EquilGrid>* equilCartMapper_; const Dune::CartesianIndexMapper<EquilGrid>* equilCartMapper_;
const EquilGrid* equilGrid_; const EquilGrid* equilGrid_;
std::vector<std::size_t> wbp_index_list_;
SimulatorReportSingle sub_step_report_; SimulatorReportSingle sub_step_report_;
SimulatorReport simulation_report_; SimulatorReport simulation_report_;
mutable std::vector<NNCdata> outputNnc_; mutable std::vector<NNCdata> outputNnc_;

View File

@@ -138,7 +138,6 @@ class EclOutputBlackOilModule : public EclGenericOutputBlackoilModule<GetPropTyp
public: public:
template <class CollectDataToIORankType> template <class CollectDataToIORankType>
EclOutputBlackOilModule(const Simulator& simulator, EclOutputBlackOilModule(const Simulator& simulator,
const std::vector<std::size_t>& wbp_index_list,
const CollectDataToIORankType& collectToIORank) const CollectDataToIORankType& collectToIORank)
: BaseType(simulator.vanguard().eclState(), : BaseType(simulator.vanguard().eclState(),
simulator.vanguard().schedule(), simulator.vanguard().schedule(),
@@ -159,22 +158,17 @@ public:
this->createLocalRegion_(region_pair.second); this->createLocalRegion_(region_pair.second);
} }
auto isCartIdxOnThisRank = [&collectToIORank](int idx) auto isCartIdxOnThisRank = [&collectToIORank](const int idx) {
{ return collectToIORank.isCartIdxOnThisRank(idx);
return collectToIORank.isCartIdxOnThisRank(idx); };
};
this->setupBlockData(isCartIdxOnThisRank); this->setupBlockData(isCartIdxOnThisRank);
for (const auto& global_index : wbp_index_list) { this->forceDisableFipOutput_ =
if (collectToIORank.isCartIdxOnThisRank(global_index - 1)) { EWOMS_GET_PARAM(TypeTag, bool, ForceDisableFluidInPlaceOutput);
this->wbpData_.emplace(global_index, 0.0);
}
}
this->forceDisableFipOutput_ = EWOMS_GET_PARAM(TypeTag, bool, ForceDisableFluidInPlaceOutput); this->forceDisableFipresvOutput_ =
EWOMS_GET_PARAM(TypeTag, bool, ForceDisableResvFluidInPlaceOutput);
this->forceDisableFipresvOutput_ = EWOMS_GET_PARAM(TypeTag, bool, ForceDisableResvFluidInPlaceOutput);
} }
/*! /*!
@@ -199,25 +193,32 @@ public:
* write to ECL output files * write to ECL output files
*/ */
void void
allocBuffers(unsigned bufferSize, unsigned reportStepNum, const bool substep, const bool log, const bool isRestart) allocBuffers(const unsigned bufferSize,
const unsigned reportStepNum,
const bool substep,
const bool log,
const bool isRestart)
{ {
if (!std::is_same<Discretization, EcfvDiscretization<TypeTag>>::value) if (! std::is_same<Discretization, EcfvDiscretization<TypeTag>>::value) {
return; return;
}
const auto& problem = this->simulator_.problem();
this->doAllocBuffers(bufferSize, this->doAllocBuffers(bufferSize,
reportStepNum, reportStepNum,
substep, substep,
log, log,
isRestart, isRestart,
simulator_.problem().vapparsActive(std::max(simulator_.episodeIndex(), 0)), problem.vapparsActive(std::max(simulator_.episodeIndex(), 0)),
simulator_.problem().materialLawManager()->enableHysteresis(), problem.materialLawManager()->enableHysteresis(),
simulator_.problem().tracerModel().numTracers(), problem.tracerModel().numTracers(),
simulator_.problem().eclWriter()->getOutputNnc().size()); problem.eclWriter()->getOutputNnc().size());
} }
/*! /*!
* \brief Modify the internal buffers according to the intensive quanties relevant * \brief Modify the internal buffers according to the intensive
* for an element * quanties relevant for an element
*/ */
void processElement(const ElementContext& elemCtx) void processElement(const ElementContext& elemCtx)
{ {
@@ -550,7 +551,6 @@ public:
= FluidSystem::viscosity(fsInitial, gasPhaseIdx, intQuants.pvtRegionIndex()); = FluidSystem::viscosity(fsInitial, gasPhaseIdx, intQuants.pvtRegionIndex());
} }
// Adding Well RFT data // Adding Well RFT data
const auto cartesianIdx = elemCtx.simulator().vanguard().cartesianIndex(globalDofIdx); const auto cartesianIdx = elemCtx.simulator().vanguard().cartesianIndex(globalDofIdx);
if (this->oilConnectionPressures_.count(cartesianIdx) > 0) { if (this->oilConnectionPressures_.count(cartesianIdx) > 0) {
@@ -562,25 +562,17 @@ public:
if (this->gasConnectionSaturations_.count(cartesianIdx) > 0) { if (this->gasConnectionSaturations_.count(cartesianIdx) > 0) {
this->gasConnectionSaturations_[cartesianIdx] = getValue(fs.saturation(gasPhaseIdx)); this->gasConnectionSaturations_[cartesianIdx] = getValue(fs.saturation(gasPhaseIdx));
} }
if (this->wbpData_.count(cartesianIdx) > 0) {
if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
this->wbpData_[cartesianIdx] = getValue(fs.pressure(oilPhaseIdx));
} else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
this->wbpData_[cartesianIdx] = getValue(fs.pressure(gasPhaseIdx));
} else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
this->wbpData_[cartesianIdx] = getValue(fs.pressure(waterPhaseIdx));
}
}
// tracers // tracers
const auto& tracerModel = simulator_.problem().tracerModel(); const auto& tracerModel = simulator_.problem().tracerModel();
if (!this->tracerConcentrations_.empty()) { if (! this->tracerConcentrations_.empty()) {
for (int tracerIdx = 0; tracerIdx < tracerModel.numTracers(); tracerIdx++) { for (int tracerIdx = 0; tracerIdx < tracerModel.numTracers(); ++tracerIdx) {
if (this->tracerConcentrations_[tracerIdx].empty()) if (this->tracerConcentrations_[tracerIdx].empty()) {
continue; continue;
}
this->tracerConcentrations_[tracerIdx][globalDofIdx] this->tracerConcentrations_[tracerIdx][globalDofIdx] =
= tracerModel.tracerConcentration(tracerIdx, globalDofIdx); tracerModel.tracerConcentration(tracerIdx, globalDofIdx);
} }
} }
} }

View File

@@ -148,22 +148,28 @@ public:
simulator.vanguard().eclState(), simulator.vanguard().eclState(),
simulator.vanguard().summaryConfig(), simulator.vanguard().summaryConfig(),
simulator.vanguard().grid(), simulator.vanguard().grid(),
simulator.vanguard().grid().comm().rank() == 0 ? &simulator.vanguard().equilGrid() : nullptr, ((simulator.vanguard().grid().comm().rank() == 0)
? &simulator.vanguard().equilGrid()
: nullptr),
simulator.vanguard().gridView(), simulator.vanguard().gridView(),
simulator.vanguard().cartesianIndexMapper(), simulator.vanguard().cartesianIndexMapper(),
simulator.vanguard().grid().comm().rank() == 0 ? &simulator.vanguard().equilCartesianIndexMapper() : nullptr, ((simulator.vanguard().grid().comm().rank() == 0)
EWOMS_GET_PARAM(TypeTag, bool, EnableAsyncEclOutput), EWOMS_GET_PARAM(TypeTag, bool, EnableEsmry)) ? &simulator.vanguard().equilCartesianIndexMapper()
: nullptr),
EWOMS_GET_PARAM(TypeTag, bool, EnableAsyncEclOutput),
EWOMS_GET_PARAM(TypeTag, bool, EnableEsmry))
, simulator_(simulator) , simulator_(simulator)
{ {
#ifdef HAVE_DAMARIS #ifdef HAVE_DAMARIS
this->damarisUpdate_ = enableDamarisOutput_(); this->damarisUpdate_ = enableDamarisOutput_();
#endif #endif
this->eclOutputModule_ = std::make_unique<EclOutputBlackOilModule<TypeTag>>(simulator, this->wbp_index_list_, this->collectToIORank_);
this->wbp_index_list_.clear(); this->eclOutputModule_ = std::make_unique<EclOutputBlackOilModule<TypeTag>>
(simulator, this->collectToIORank_);
} }
~EclWriter() ~EclWriter()
{ } {}
const EquilGrid& globalGrid() const const EquilGrid& globalGrid() const
{ {
@@ -204,6 +210,7 @@ public:
simulator_.vanguard().setupTime(); simulator_.vanguard().setupTime();
const auto localWellData = simulator_.problem().wellModel().wellData(); const auto localWellData = simulator_.problem().wellModel().wellData();
const auto localWBP = data::WellBlockAveragePressures{};
const auto localGroupAndNetworkData = simulator_.problem().wellModel() const auto localGroupAndNetworkData = simulator_.problem().wellModel()
.groupAndNetworkData(reportStepNum); .groupAndNetworkData(reportStepNum);
@@ -220,8 +227,8 @@ public:
this->collectToIORank_.collect({}, this->collectToIORank_.collect({},
eclOutputModule_->getBlockData(), eclOutputModule_->getBlockData(),
eclOutputModule_->getWBPData(),
localWellData, localWellData,
localWBP,
localGroupAndNetworkData, localGroupAndNetworkData,
localAquiferData, localAquiferData,
localWellTestState, localWellTestState,
@@ -283,26 +290,34 @@ public:
if (this->simulation_report_.success.total_newton_iterations != 0) { if (this->simulation_report_.success.total_newton_iterations != 0) {
miscSummaryData["MSUMNEWT"] = this->simulation_report_.success.total_newton_iterations; miscSummaryData["MSUMNEWT"] = this->simulation_report_.success.total_newton_iterations;
} }
{ {
OPM_TIMEBLOCK(evalSummary); OPM_TIMEBLOCK(evalSummary);
this->evalSummary(reportStepNum, curTime,
this->collectToIORank_.isParallel() ? const auto& blockData = this->collectToIORank_.isParallel()
this->collectToIORank_.globalWBPData() : ? this->collectToIORank_.globalBlockData()
this->eclOutputModule_->getWBPData(), : this->eclOutputModule_->getBlockData();
localWellData,
localGroupAndNetworkData, const auto& interRegFlows = this->collectToIORank_.isParallel()
localAquiferData, ? this->collectToIORank_.globalInterRegFlows()
this->collectToIORank_.isParallel() ? : this->eclOutputModule_->getInterRegFlows();
this->collectToIORank_.globalBlockData() :
this->eclOutputModule_->getBlockData(), this->evalSummary(reportStepNum,
miscSummaryData, regionData, curTime,
inplace, localWellData,
eclOutputModule_->initialInplace(), localWBP,
this->collectToIORank_.isParallel() localGroupAndNetworkData,
? this->collectToIORank_.globalInterRegFlows() localAquiferData,
: this->eclOutputModule_->getInterRegFlows(), blockData,
summaryState(), udqState()); miscSummaryData,
regionData,
inplace,
this->eclOutputModule_->initialInplace(),
interRegFlows,
this->summaryState(),
this->udqState());
} }
{ {
OPM_TIMEBLOCK(outputXXX); OPM_TIMEBLOCK(outputXXX);
eclOutputModule_->outputProdLog(reportStepNum, isSubStep, forceDisableProdOutput); eclOutputModule_->outputProdLog(reportStepNum, isSubStep, forceDisableProdOutput);
@@ -314,9 +329,11 @@ public:
void writeOutput(bool isSubStep) void writeOutput(bool isSubStep)
{ {
OPM_TIMEBLOCK(writeOutput); OPM_TIMEBLOCK(writeOutput);
const int reportStepNum = simulator_.episodeIndex() + 1; const int reportStepNum = simulator_.episodeIndex() + 1;
this->prepareLocalCellData(isSubStep, reportStepNum); this->prepareLocalCellData(isSubStep, reportStepNum);
this->eclOutputModule_->outputErrorLog(simulator_.gridView().comm()); this->eclOutputModule_->outputErrorLog(simulator_.gridView().comm());
#ifdef HAVE_DAMARIS #ifdef HAVE_DAMARIS
if (EWOMS_GET_PARAM(TypeTag, bool, EnableDamarisOutput)) { if (EWOMS_GET_PARAM(TypeTag, bool, EnableDamarisOutput)) {
// N.B. damarisUpdate_ should be set to true if at any time the model geometry changes // N.B. damarisUpdate_ should be set to true if at any time the model geometry changes
@@ -340,35 +357,44 @@ public:
} }
} }
#endif #endif
// 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 localAquiferData = simulator_.problem().aquiferModel().aquiferData();
auto localWellTestState = simulator_.problem().wellModel().wellTestState(); auto localWellTestState = simulator_.problem().wellModel().wellTestState();
auto flowsn = this->eclOutputModule_->getFlowsn();
const bool isFlowsn = this->eclOutputModule_->hasFlowsn(); const bool isFlowsn = this->eclOutputModule_->hasFlowsn();
auto floresn = this->eclOutputModule_->getFloresn(); auto flowsn = this->eclOutputModule_->getFlowsn();
const bool isFloresn = this->eclOutputModule_->hasFloresn(); const bool isFloresn = this->eclOutputModule_->hasFloresn();
auto floresn = this->eclOutputModule_->getFloresn();
data::Solution localCellData = {}; data::Solution localCellData = {};
if (! isSubStep) { if (! isSubStep) {
this->eclOutputModule_->assignToSolution(localCellData); this->eclOutputModule_->assignToSolution(localCellData);
// add cell data to perforations for Rft output // Add cell data to perforations for RFT output
this->eclOutputModule_->addRftDataToWells(localWellData, reportStepNum); this->eclOutputModule_->addRftDataToWells(localWellData, reportStepNum);
} }
if (this->collectToIORank_.isParallel()|| this->collectToIORank_.doesNeedReordering()) { if (this->collectToIORank_.isParallel() ||
this->collectToIORank_.doesNeedReordering())
{
// Note: We don't need WBP (well-block averaged pressures) or
// inter-region flow rate values in order to create restart file
// output. There's consequently no need to collect those
// properties on the I/O rank.
this->collectToIORank_.collect(localCellData, this->collectToIORank_.collect(localCellData,
eclOutputModule_->getBlockData(), this->eclOutputModule_->getBlockData(),
eclOutputModule_->getWBPData(),
localWellData, localWellData,
/* wbpData = */ {},
localGroupAndNetworkData, localGroupAndNetworkData,
localAquiferData, localAquiferData,
localWellTestState, localWellTestState,
{}, /* interRegFlows = */ {},
flowsn, flowsn,
floresn); floresn);
} }
@@ -376,6 +402,7 @@ public:
if (this->collectToIORank_.isIORank()) { if (this->collectToIORank_.isIORank()) {
const Scalar curTime = simulator_.time() + simulator_.timeStepSize(); const Scalar curTime = simulator_.time() + simulator_.timeStepSize();
const Scalar nextStepSize = simulator_.problem().nextTimeStepSize(); const Scalar nextStepSize = simulator_.problem().nextTimeStepSize();
this->doWriteOutput(reportStepNum, isSubStep, this->doWriteOutput(reportStepNum, isSubStep,
std::move(localCellData), std::move(localCellData),
std::move(localWellData), std::move(localWellData),
@@ -385,13 +412,11 @@ public:
this->actionState(), this->actionState(),
this->udqState(), this->udqState(),
this->summaryState(), this->summaryState(),
simulator_.problem().thresholdPressure().getRestartVector(), this->simulator_.problem().thresholdPressure().getRestartVector(),
curTime, nextStepSize, curTime, nextStepSize,
EWOMS_GET_PARAM(TypeTag, bool, EclOutputDoublePrecision), EWOMS_GET_PARAM(TypeTag, bool, EclOutputDoublePrecision),
isFlowsn, isFlowsn, std::move(flowsn),
std::move(flowsn), isFloresn, std::move(floresn));
isFloresn,
std::move(floresn));
} }
} }
@@ -487,7 +512,7 @@ public:
Scalar restartTimeStepSize() const Scalar restartTimeStepSize() const
{ return restartTimeStepSize_; } { return restartTimeStepSize_; }
template<class Serializer> template <class Serializer>
void serializeOp(Serializer& serializer) void serializeOp(Serializer& serializer)
{ {
serializer(*eclOutputModule_); serializer(*eclOutputModule_);
@@ -496,10 +521,12 @@ public:
private: private:
static bool enableEclOutput_() static bool enableEclOutput_()
{ return EWOMS_GET_PARAM(TypeTag, bool, EnableEclOutput); } { return EWOMS_GET_PARAM(TypeTag, bool, EnableEclOutput); }
#ifdef HAVE_DAMARIS #ifdef HAVE_DAMARIS
static bool enableDamarisOutput_() static bool enableDamarisOutput_()
{ return EWOMS_GET_PARAM(TypeTag, bool, EnableDamarisOutput); } { return EWOMS_GET_PARAM(TypeTag, bool, EnableDamarisOutput); }
#endif #endif
const EclipseState& eclState() const const EclipseState& eclState() const
{ return simulator_.vanguard().eclState(); } { return simulator_.vanguard().eclState(); }
@@ -519,7 +546,8 @@ private:
const int reportStepNum) const int reportStepNum)
{ {
OPM_TIMEBLOCK(prepareLocalCellData); OPM_TIMEBLOCK(prepareLocalCellData);
if (eclOutputModule_->localDataValid()) {
if (this->eclOutputModule_->localDataValid()) {
return; return;
} }
@@ -527,54 +555,68 @@ private:
const int numElements = gridView.size(/*codim=*/0); const int numElements = gridView.size(/*codim=*/0);
const bool log = this->collectToIORank_.isIORank(); const bool log = this->collectToIORank_.isIORank();
eclOutputModule_->allocBuffers(numElements, reportStepNum, this->eclOutputModule_->
isSubStep, log, /*isRestart*/ false); allocBuffers(numElements, reportStepNum,
isSubStep, log, /*isRestart*/ false);
ElementContext elemCtx(simulator_); ElementContext elemCtx(simulator_);
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
OPM_TIMEBLOCK(prepareCellBasedData);
for (const auto& elem : elements(gridView)) {
elemCtx.updatePrimaryStencil(elem);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
eclOutputModule_->processElement(elemCtx); OPM_BEGIN_PARALLEL_TRY_CATCH();
{
OPM_TIMEBLOCK(prepareCellBasedData);
for (const auto& elem : elements(gridView)) {
elemCtx.updatePrimaryStencil(elem);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
this->eclOutputModule_->processElement(elemCtx);
}
} }
}
if(!simulator_.model().linearizer().getFlowsInfo().empty()){ if (! this->simulator_.model().linearizer().getFlowsInfo().empty()) {
OPM_TIMEBLOCK(prepareFlowsData); OPM_TIMEBLOCK(prepareFlowsData);
for (const auto& elem : elements(gridView)) { for (const auto& elem : elements(gridView)) {
elemCtx.updatePrimaryStencil(elem); elemCtx.updatePrimaryStencil(elem);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
eclOutputModule_->processElementFlows(elemCtx);
this->eclOutputModule_->processElementFlows(elemCtx);
} }
} }
{ {
OPM_TIMEBLOCK(prepareBlockData); OPM_TIMEBLOCK(prepareBlockData);
for (const auto& elem : elements(gridView)) { for (const auto& elem : elements(gridView)) {
elemCtx.updatePrimaryStencil(elem); elemCtx.updatePrimaryStencil(elem);
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
eclOutputModule_->processElementBlockData(elemCtx);
} this->eclOutputModule_->processElementBlockData(elemCtx);
}
} }
{ {
OPM_TIMEBLOCK(prepareFluidInPlace); OPM_TIMEBLOCK(prepareFluidInPlace);
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
for (int dofIdx=0; dofIdx < numElements; ++dofIdx){ for (int dofIdx = 0; dofIdx < numElements; ++dofIdx) {
const auto& intQuants = *(simulator_.model().cachedIntensiveQuantities(dofIdx, /*timeIdx=*/0)); const auto& intQuants = *simulator_.model().cachedIntensiveQuantities(dofIdx, /*timeIdx=*/0);
const auto totVolume = simulator_.model().dofTotalVolume(dofIdx); const auto totVolume = simulator_.model().dofTotalVolume(dofIdx);
eclOutputModule_->updateFluidInPlace(dofIdx, intQuants, totVolume);
this->eclOutputModule_->updateFluidInPlace(dofIdx, intQuants, totVolume);
}
} }
}
eclOutputModule_->validateLocalData(); this->eclOutputModule_->validateLocalData();
OPM_END_PARALLEL_TRY_CATCH("EclWriter::prepareLocalCellData() failed: ", simulator_.vanguard().grid().comm());
OPM_END_PARALLEL_TRY_CATCH("EclWriter::prepareLocalCellData() failed: ",
this->simulator_.vanguard().grid().comm());
} }
void captureLocalFluxData() void captureLocalFluxData()
{ {
OPM_TIMEBLOCK(captureLocalData); OPM_TIMEBLOCK(captureLocalData);
const auto& gridView = this->simulator_.vanguard().gridView(); const auto& gridView = this->simulator_.vanguard().gridView();
const auto timeIdx = 0u; const auto timeIdx = 0u;
@@ -612,6 +654,7 @@ private:
Simulator& simulator_; Simulator& simulator_;
std::unique_ptr<EclOutputBlackOilModule<TypeTag>> eclOutputModule_; std::unique_ptr<EclOutputBlackOilModule<TypeTag>> eclOutputModule_;
Scalar restartTimeStepSize_; Scalar restartTimeStepSize_;
#ifdef HAVE_DAMARIS #ifdef HAVE_DAMARIS
bool damarisUpdate_ = false; ///< Whenever this is true writeOutput() will set up Damaris offsets of model fields bool damarisUpdate_ = false; ///< Whenever this is true writeOutput() will set up Damaris offsets of model fields
#endif #endif

View File

@@ -211,6 +211,8 @@ TEST_FOR_TYPE_NAMED(data::SegmentPressures, SegmentPressures)
TEST_FOR_TYPE_NAMED(data::Solution, Solution) TEST_FOR_TYPE_NAMED(data::Solution, Solution)
TEST_FOR_TYPE_NAMED(data::Well, dataWell) TEST_FOR_TYPE_NAMED(data::Well, dataWell)
TEST_FOR_TYPE_NAMED(data::Wells, Wells) TEST_FOR_TYPE_NAMED(data::Wells, Wells)
TEST_FOR_TYPE_NAMED(data::WellBlockAvgPress, dataWBPObject)
TEST_FOR_TYPE_NAMED(data::WellBlockAveragePressures, dataWBPCollection)
TEST_FOR_TYPE(Deck) TEST_FOR_TYPE(Deck)
TEST_FOR_TYPE(DeckItem) TEST_FOR_TYPE(DeckItem)
TEST_FOR_TYPE(DeckKeyword) TEST_FOR_TYPE(DeckKeyword)