27 #ifndef OPM_OUTPUT_COMPOSITIONAL_MODULE_HPP 28 #define OPM_OUTPUT_COMPOSITIONAL_MODULE_HPP 30 #include <dune/grid/common/gridenums.hh> 32 #include <opm/simulators/utils/moduleVersion.hpp> 34 #include <opm/common/Exceptions.hpp> 35 #include <opm/common/ErrorMacros.hpp> 36 #include <opm/common/TimingMacros.hpp> 37 #include <opm/common/OpmLog/OpmLog.hpp> 39 #include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp> 41 #include <opm/material/common/Valgrind.hpp> 61 #include <type_traits> 69 template <
class TypeTag>
70 class EcfvDiscretization;
78 template <
class TypeTag>
90 enum { numPhases = FluidSystem::numPhases };
91 enum { numComponents = FluidSystem::numComponents };
92 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
93 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
94 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
97 static void registerParameters()
103 template <
class CollectDataToIORankType>
105 const SummaryConfig& smryCfg,
106 const CollectDataToIORankType& collectToIORank)
107 :
BaseType(simulator.vanguard().eclState(),
108 simulator.vanguard().schedule(),
110 simulator.vanguard().summaryState(),
112 [
this](
const int idx)
113 {
return simulator_.problem().eclWriter().collectOnIORank().localIdxToGlobalIdx(idx); },
114 [&collectToIORank](
const int idx)
115 {
return collectToIORank.isCartIdxOnThisRank(idx); },
116 simulator.vanguard().grid().comm(),
117 getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal,
118 getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::ConstantTemperature,
119 getPropValue<TypeTag, Properties::EnableMech>(),
120 getPropValue<TypeTag, Properties::EnableSolvent>(),
121 getPropValue<TypeTag, Properties::EnablePolymer>(),
122 getPropValue<TypeTag, Properties::EnableFoam>(),
123 getPropValue<TypeTag, Properties::EnableBrine>(),
124 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>(),
125 getPropValue<TypeTag, Properties::EnableExtbo>(),
126 getPropValue<TypeTag, Properties::EnableBioeffects>(),
127 getPropValue<TypeTag, Properties::EnableGeochemistry>())
128 , simulator_(simulator)
130 for (
auto& region_pair : this->regions_) {
131 this->createLocalRegion_(region_pair.second);
134 auto isCartIdxOnThisRank = [&collectToIORank](
const int idx) {
135 return collectToIORank.isCartIdxOnThisRank(idx);
138 this->setupBlockData(isCartIdxOnThisRank);
145 if (! collectToIORank.isParallel()) {
148 this->setupLgrBlockData({}, [](
const int,
const int) {
return true; });
151 if (! Parameters::Get<Parameters::OwnerCellsFirst>()) {
152 const std::string msg =
"The output code does not support --owner-cells-first=false.";
153 if (collectToIORank.isIORank()) {
156 OPM_THROW_NOLOG(std::runtime_error, msg);
159 if (smryCfg.match(
"[FB]PP[OGW]") || smryCfg.match(
"RPP[OGW]*")) {
160 auto rset = this->eclState_.fieldProps().fip_regions();
161 rset.push_back(
"PVTNUM");
166 this->regionAvgDensity_
167 .emplace(this->simulator_.gridView().comm(),
168 FluidSystem::numPhases, rset,
169 [fp = std::cref(this->eclState_.fieldProps())]
170 (
const std::string& rsetName) -> decltype(
auto)
171 {
return fp.get().get_int(rsetName); });
181 const unsigned reportStepNum,
184 const bool isRestart)
190 auto rstKeywords = this->schedule_.rst_keywords(reportStepNum);
191 this->compC_.allocate(bufferSize, rstKeywords);
193 this->doAllocBuffers(bufferSize, reportStepNum, substep, log, isRestart,
196 std::move(rstKeywords));
199 void assignToSolution(data::Solution& sol)
201 this->compC_.outputRestart(sol, this->saturation_[oilPhaseIdx]);
205 void outputFipAndResvLog(
const Inplace& inplace,
206 const std::size_t reportStepNum,
208 boost::posix_time::ptime currentDate,
210 const Parallel::Communication& comm)
212 if (comm.rank() != 0) {
216 std::unique_ptr<FIPConfig> fipSched;
217 if (reportStepNum > 0) {
218 const auto& rpt = this->schedule_[reportStepNum - 1].rpt_config.get();
219 fipSched = std::make_unique<FIPConfig>(rpt);
222 const FIPConfig& fipc = reportStepNum == 0
223 ? this->eclState_.getEclipseConfig().fip()
226 if (!substep && !this->forceDisableFipOutput_ && fipc.output(FIPConfig::OutputField::FIELD)) {
227 this->logOutput_.timeStamp(
"BALANCE", elapsed, reportStepNum, currentDate);
229 const auto& initial_inplace = *this->initialInplace();
230 this->logOutput_.fip(inplace, initial_inplace,
"");
232 if (fipc.output(FIPConfig::OutputField::FIPNUM)) {
233 this->logOutput_.fip(inplace, initial_inplace,
"FIPNUM");
235 if (fipc.output(FIPConfig::OutputField::RESV)) {
236 this->logOutput_.fipResv(inplace,
"FIPNUM");
240 if (fipc.output(FIPConfig::OutputField::FIP)) {
241 for (
const auto& reg : this->regions_) {
242 if (reg.first !=
"FIPNUM") {
243 std::ostringstream ss;
244 ss <<
"BAL" << reg.first.substr(3);
245 this->logOutput_.timeStamp(ss.str(), elapsed, reportStepNum, currentDate);
246 this->logOutput_.fip(inplace, initial_inplace, reg.first);
248 if (fipc.output(FIPConfig::OutputField::RESV)) {
249 this->logOutput_.fipResv(inplace, reg.first);
257 void outputFipAndResvLogToCSV(
const std::size_t reportStepNum,
259 const Parallel::Communication& comm)
261 if (comm.rank() != 0) {
265 if ((reportStepNum == 0) && (!substep) &&
266 (this->schedule_.initialReportConfiguration().has_value()) &&
267 (this->schedule_.initialReportConfiguration()->contains(
"CSVFIP"))) {
269 std::ostringstream csv_stream;
271 this->logOutput_.csv_header(csv_stream);
273 const auto& initial_inplace = *this->initialInplace();
275 this->logOutput_.fip_csv(csv_stream, initial_inplace,
"FIPNUM");
277 for (
const auto& reg : this->regions_) {
278 if (reg.first !=
"FIPNUM") {
279 this->logOutput_.fip_csv(csv_stream, initial_inplace, reg.first);
283 const IOConfig& io = this->eclState_.getIOConfig();
284 auto csv_fname = io.getOutputDir() +
"/" + io.getBaseName() +
".CSV";
286 std::ofstream outputFile(csv_fname);
287 outputFile << csv_stream.str();
300 auto extractors = std::array{
301 Entry{PhaseEntry{&this->saturation_,
302 [](
const unsigned phase,
const ExtractContext& ectx)
303 {
return getValue(ectx.fs.saturation(phase)); }}
305 Entry{ScalarEntry{&this->fluidPressure_,
306 [](
const ExtractContext& ectx)
308 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
310 return getValue(ectx.fs.pressure(oilPhaseIdx));
312 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
314 return getValue(ectx.fs.pressure(gasPhaseIdx));
318 return getValue(ectx.fs.pressure(waterPhaseIdx));
322 Entry{ScalarEntry{&this->temperature_,
323 [](
const ExtractContext& ectx)
324 {
return getValue(ectx.fs.temperature(oilPhaseIdx)); }}
326 Entry{[&compC = this->compC_](
const ExtractContext& ectx)
328 compC.assignMoleFractions(ectx.globalDofIdx,
329 [&fs = ectx.fs](
const unsigned compIdx)
330 { return getValue(fs.moleFraction(compIdx)); });
332 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
333 compC.assignGasFractions(ectx.globalDofIdx,
334 [&fs = ectx.fs](
const unsigned compIdx)
335 { return getValue(fs.moleFraction(gasPhaseIdx, compIdx)); });
338 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
339 compC.assignOilFractions(ectx.globalDofIdx,
340 [&fs = ectx.fs](
const unsigned compIdx)
341 { return getValue(fs.moleFraction(oilPhaseIdx, compIdx)); });
343 }, this->compC_.allocated()
352 { this->extractors_.clear(); }
366 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
367 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
368 const auto& fs = intQuants.fluidState();
371 elemCtx.globalSpaceIndex(dofIdx, 0),
383 void processElementFlows(
const ElementContext& )
385 OPM_TIMEBLOCK_LOCAL(processElementBlockData, Subsystem::Output);
390 void processElementBlockData(
const ElementContext& )
392 OPM_TIMEBLOCK_LOCAL(processElementBlockData, Subsystem::Output);
393 if (!std::is_same<Discretization, EcfvDiscretization<TypeTag>>::value)
425 template <
class ActiveIndex,
class CartesianIndex>
440 this->interRegionFlows_.
clear();
456 return this->interRegionFlows_;
459 void updateFluidInPlace(
const unsigned ,
460 const IntensiveQuantities& ,
467 bool isDefunctParallelWell(
const std::string& wname)
const override 469 if (simulator_.gridView().comm().size() == 1)
471 const auto& parallelWells = simulator_.vanguard().parallelWells();
472 std::pair<std::string, bool> value {wname,
true};
473 auto candidate = std::lower_bound(parallelWells.begin(), parallelWells.end(), value);
474 return candidate == parallelWells.end() || *candidate != value;
477 bool isOwnedByCurrentRank(
const std::string& wname)
const override 482 return ! this->isDefunctParallelWell(wname);
485 bool isOnCurrentRank(
const std::string& wname)
const override 490 return ! this->isDefunctParallelWell(wname);
493 void createLocalRegion_(std::vector<int>& region)
495 std::size_t elemIdx = 0;
496 for (
const auto& elem : elements(simulator_.gridView())) {
497 if (elem.partitionType() != Dune::InteriorEntity) {
505 const Simulator& simulator_;
506 CompositionalContainer<FluidSystem> compC_;
507 std::vector<typename Extractor::Entry> extractors_;
512 #endif // OPM_OUTPUT_COMPOSITIONAL_MODULE_HPP Output module for the results black oil model writing in ECL binary format.
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
void finalizeFluxData()
Finalize capturing connection fluxes.
Definition: OutputCompositionalModule.hpp:446
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: GenericOutputBlackoilModule.cpp:194
The base class for the element-centered finite-volume discretization scheme.
Definition: fvbasegradientcalculator.hh:42
std::string moduleVersionName()
Return the version name of the module, for example "2015.10" (for a release branch) or "2016...
Definition: moduleVersion.cpp:34
VTK output module for the black oil model's parameters.
Helper class for grid instantiation of ECL file-format using problems.
This file provides the infrastructure to retrieve run-time parameters.
Output module for the results black oil model writing in ECL binary format.
const InterRegFlowMap & getInterRegFlows() const
Get read-only access to collection of inter-region flows.
Definition: OutputCompositionalModule.hpp:454
Defines the common properties required by the porous medium multi-phase models.
void clearExtractors()
Clear list of active element-level data extractors.
Definition: OutputCompositionalModule.hpp:351
void compress()
Form CSR adjacency matrix representation of input graph from connections established in previous call...
Definition: InterRegFlows.cpp:164
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Declares the properties required by the black oil model.
Definition: GenericOutputBlackoilModule.hpp:80
Inter-region flow accumulation maps for all region definition arrays.
Definition: InterRegFlows.hpp:178
void setupExtractors(const bool, const std::size_t)
Setup list of active element-level data extractors.
Definition: OutputCompositionalModule.hpp:292
void clear()
Clear all internal buffers, but preserve allocated capacity.
Definition: InterRegFlows.cpp:171
void initializeFluxData()
Prepare for capturing connection fluxes, particularly to account for inter-region flows...
Definition: OutputCompositionalModule.hpp:436
void processElement(const ElementContext &elemCtx)
Modify the internal buffers according to the intensive quanties relevant for an element.
Definition: OutputCompositionalModule.hpp:358
Output module for the results black oil model writing in ECL binary format.
Definition: OutputCompositionalModule.hpp:79
The Opm property system, traits with inheritance.
void allocBuffers(const unsigned bufferSize, const unsigned reportStepNum, const bool substep, const bool log, const bool isRestart)
Allocate memory for the scalar fields we would like to write to ECL output files. ...
Definition: OutputCompositionalModule.hpp:180
void processFluxes(const ElementContext &, ActiveIndex &&, CartesianIndex &&)
Capture connection fluxes, particularly to account for inter-region flows.
Definition: OutputCompositionalModule.hpp:426
void assignToSolution(data::Solution &sol)
Move all buffers to data::Solution.
Definition: GenericOutputBlackoilModule.cpp:316
static void registerParameters()
Registers the parameters in parameter system.
Definition: vtkblackoilparams.cpp:31