My Project
Loading...
Searching...
No Matches
OutputCompositionalModule.hpp
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
27#ifndef OPM_OUTPUT_COMPOSITIONAL_MODULE_HPP
28#define OPM_OUTPUT_COMPOSITIONAL_MODULE_HPP
29
30#include <dune/grid/common/gridenums.hh>
31
32#include <opm/simulators/utils/moduleVersion.hpp>
33
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>
38
39#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
40
41#include <opm/material/common/Valgrind.hpp>
42
47
52
53#include <algorithm>
54#include <cstddef>
55#include <stdexcept>
56#include <string>
57#include <type_traits>
58#include <utility>
59#include <vector>
60
61
62namespace Opm {
63
64// forward declaration
65template <class TypeTag>
66class EcfvDiscretization;
67
74template <class TypeTag>
75class OutputCompositionalModule : public GenericOutputBlackoilModule<GetPropType<TypeTag, Properties::FluidSystem>>
76{
85
86 enum { numPhases = FluidSystem::numPhases };
87 enum { numComponents = FluidSystem::numComponents };
88 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
89 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
90 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
91
92public:
93 template <class CollectDataToIORankType>
94 OutputCompositionalModule(const Simulator& simulator,
97 : BaseType(simulator.vanguard().eclState(),
98 simulator.vanguard().schedule(),
99 smryCfg,
100 simulator.vanguard().summaryState(),
102 [this](const int idx)
103 { return simulator_.problem().eclWriter().collectOnIORank().localIdxToGlobalIdx(idx); },
104 simulator.vanguard().grid().comm(),
115 , simulator_(simulator)
116 {
117 for (auto& region_pair : this->regions_) {
118 this->createLocalRegion_(region_pair.second);
119 }
120
121 auto isCartIdxOnThisRank = [&collectToIORank](const int idx) {
122 return collectToIORank.isCartIdxOnThisRank(idx);
123 };
124
125 this->setupBlockData(isCartIdxOnThisRank);
126
127 if (! Parameters::Get<Parameters::OwnerCellsFirst>()) {
128 const std::string msg = "The output code does not support --owner-cells-first=false.";
129 if (collectToIORank.isIORank()) {
130 OpmLog::error(msg);
131 }
132 OPM_THROW_NOLOG(std::runtime_error, msg);
133 }
134
135 if (smryCfg.match("[FB]PP[OGW]") || smryCfg.match("RPP[OGW]*")) {
136 auto rset = this->eclState_.fieldProps().fip_regions();
137 rset.push_back("PVTNUM");
138
139 // Note: We explicitly use decltype(auto) here because the
140 // default scheme (-> auto) will deduce an undesirable type. We
141 // need the "reference to vector" semantics in this instance.
142 this->regionAvgDensity_
143 .emplace(this->simulator_.gridView().comm(),
144 FluidSystem::numPhases, rset,
145 [fp = std::cref(this->eclState_.fieldProps())]
146 (const std::string& rsetName) -> decltype(auto)
147 { return fp.get().get_int(rsetName); });
148 }
149 }
150
155 void
156 allocBuffers(const unsigned bufferSize,
157 const unsigned reportStepNum,
158 const bool substep,
159 const bool log,
160 const bool isRestart)
161 {
162 if (! std::is_same<Discretization, EcfvDiscretization<TypeTag>>::value) {
163 return;
164 }
165
166 auto rstKeywords = this->schedule_.rst_keywords(reportStepNum);
167 this->compC_.allocate(bufferSize, rstKeywords);
168
169 this->doAllocBuffers(bufferSize, reportStepNum, substep, log, isRestart,
170 /* hysteresisConfig = */ nullptr,
171 /* numOutputNnc =*/ 0,
172 std::move(rstKeywords));
173 }
174
175 void assignToSolution(data::Solution& sol)
176 {
177 this->compC_.outputRestart(sol, this->saturation_[oilPhaseIdx]);
179 }
180
182 void setupExtractors(const bool /*isSubStep*/,
183 const std::size_t /*reportStepNum*/)
184 {
185 using Entry = typename Extractor::Entry;
186 using ExtractContext = typename Extractor::Context;
187 using ScalarEntry = typename Extractor::ScalarEntry;
188 using PhaseEntry = typename Extractor::PhaseEntry;
189
190 auto extractors = std::array{
191 Entry{PhaseEntry{&this->saturation_,
192 [](const unsigned phase, const ExtractContext& ectx)
193 { return getValue(ectx.fs.saturation(phase)); }}
194 },
195 Entry{ScalarEntry{&this->fluidPressure_,
196 [](const ExtractContext& ectx)
197 {
198 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
199 // Output oil pressure as default
200 return getValue(ectx.fs.pressure(oilPhaseIdx));
201 }
202 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
203 // Output gas if oil is not present
204 return getValue(ectx.fs.pressure(gasPhaseIdx));
205 }
206 else {
207 // Output water if neither oil nor gas is present
208 return getValue(ectx.fs.pressure(waterPhaseIdx));
209 }
210 }}
211 },
212 Entry{ScalarEntry{&this->temperature_,
213 [](const ExtractContext& ectx)
214 { return getValue(ectx.fs.temperature(oilPhaseIdx)); }}
215 },
216 Entry{[&compC = this->compC_](const ExtractContext& ectx)
217 {
218 compC.assignMoleFractions(ectx.globalDofIdx,
219 [&fs = ectx.fs](const unsigned compIdx)
220 { return getValue(fs.moleFraction(compIdx)); });
221
222 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
223 compC.assignGasFractions(ectx.globalDofIdx,
224 [&fs = ectx.fs](const unsigned compIdx)
225 { return getValue(fs.moleFraction(gasPhaseIdx, compIdx)); });
226 }
227
228 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
229 compC.assignOilFractions(ectx.globalDofIdx,
230 [&fs = ectx.fs](const unsigned compIdx)
231 { return getValue(fs.moleFraction(oilPhaseIdx, compIdx)); });
232 }
233 }, this->compC_.allocated()
234 },
235 };
236
237 this->extractors_ = Extractor::removeInactive(extractors);
238 }
239
242 { this->extractors_.clear(); }
243
248 void processElement(const ElementContext& elemCtx)
249 {
251 if (!std::is_same<Discretization, EcfvDiscretization<TypeTag>>::value) {
252 return;
253 }
254
256 for (unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); ++dofIdx) {
257 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0);
258 const auto& fs = intQuants.fluidState();
259
260 const typename Extractor::Context ectx{
261 elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0),
262 0, // elemCtx.primaryVars(dofIdx, /*timeIdx=*/0).pvtRegionIndex(),
263 elemCtx.simulator().episodeIndex(),
264 fs,
265 intQuants,
267 };
268
269 Extractor::process(ectx, extractors_);
270 }
271 }
272
273 void processElementFlows(const ElementContext& /* elemCtx */)
274 {
275 OPM_TIMEBLOCK_LOCAL(processElementBlockData);
276 if (!std::is_same_v<Discretization, EcfvDiscretization<TypeTag>>)
277 return;
278 }
279
280 void processElementBlockData(const ElementContext& /* elemCtx */)
281 {
282 OPM_TIMEBLOCK_LOCAL(processElementBlockData);
283 if (!std::is_same<Discretization, EcfvDiscretization<TypeTag>>::value)
284 return;
285 }
286
315 template <class ActiveIndex, class CartesianIndex>
316 void processFluxes(const ElementContext& /* elemCtx */,
317 ActiveIndex&& /* activeIndex*/,
318 CartesianIndex&& /* cartesianIndex */)
319 {
320 }
321
327 {
328 // Inter-region flow rates. Note: ".clear()" prepares to accumulate
329 // contributions per bulk connection between FIP regions.
330 this->interRegionFlows_.clear();
331 }
332
337 {
338 this->interRegionFlows_.compress();
339 }
340
345 {
346 return this->interRegionFlows_;
347 }
348
349 void updateFluidInPlace(const unsigned /* globalDofIdx */,
350 const IntensiveQuantities& /* intQuants */,
351 const double /* totVolume */)
352 {
353 // this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
354 }
355
356private:
357 bool isDefunctParallelWell(std::string wname) const override
358 {
359 if (simulator_.gridView().comm().size() == 1)
360 return false;
361 const auto& parallelWells = simulator_.vanguard().parallelWells();
362 std::pair<std::string, bool> value {wname, true};
363 auto candidate = std::lower_bound(parallelWells.begin(), parallelWells.end(), value);
364 return candidate == parallelWells.end() || *candidate != value;
365 }
366
367 void createLocalRegion_(std::vector<int>& region)
368 {
369 std::size_t elemIdx = 0;
370 for (const auto& elem : elements(simulator_.gridView())) {
371 if (elem.partitionType() != Dune::InteriorEntity) {
372 region[elemIdx] = 0;
373 }
374
375 ++elemIdx;
376 }
377 }
378
379 const Simulator& simulator_;
381 std::vector<typename Extractor::Entry> extractors_;
382};
383
384} // namespace Opm
385
386#endif // OPM_OUTPUT_COMPOSITIONAL_MODULE_HPP
Output module for the results black oil model writing in ECL binary format.
Helper class for grid instantiation of ECL file-format using problems.
Output module for the results black oil model writing in ECL binary format.
Output module for the results black oil model writing in ECL binary format.
Declares the properties required by the black oil model.
The base class for the element-centered finite-volume discretization scheme.
Definition ecfvdiscretization.hh:147
Definition GenericOutputBlackoilModule.hpp:76
void assignToSolution(data::Solution &sol)
Move all buffers to data::Solution.
Definition GenericOutputBlackoilModule.cpp:319
Inter-region flow accumulation maps for all region definition arrays.
Definition InterRegFlows.hpp:179
void compress()
Form CSR adjacency matrix representation of input graph from connections established in previous call...
Definition InterRegFlows.cpp:165
void clear()
Clear all internal buffers, but preserve allocated capacity.
Definition InterRegFlows.cpp:172
Output module for the results black oil model writing in ECL binary format.
Definition OutputCompositionalModule.hpp:76
void clearExtractors()
Clear list of active element-level data extractors.
Definition OutputCompositionalModule.hpp:241
void initializeFluxData()
Prepare for capturing connection fluxes, particularly to account for inter-region flows.
Definition OutputCompositionalModule.hpp:326
void setupExtractors(const bool, const std::size_t)
Setup list of active element-level data extractors.
Definition OutputCompositionalModule.hpp:182
void finalizeFluxData()
Finalize capturing connection fluxes.
Definition OutputCompositionalModule.hpp:336
void processElement(const ElementContext &elemCtx)
Modify the internal buffers according to the intensive quanties relevant for an element.
Definition OutputCompositionalModule.hpp:248
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:156
void processFluxes(const ElementContext &, ActiveIndex &&, CartesianIndex &&)
Capture connection fluxes, particularly to account for inter-region flows.
Definition OutputCompositionalModule.hpp:316
const InterRegFlowMap & getInterRegFlows() const
Get read-only access to collection of inter-region flows.
Definition OutputCompositionalModule.hpp:344
Defines the common properties required by the porous medium multi-phase models.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilboundaryratevector.hh:37
std::string moduleVersionName()
Return the version name of the module, for example "2015.10" (for a release branch) or "2016....
Definition moduleVersion.cpp:34
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:242
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:235
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
Context passed to extractor functions.
Definition OutputExtractor.hpp:74
int episodeIndex
Current report step.
Definition OutputExtractor.hpp:77
Descriptor for extractors.
Definition OutputExtractor.hpp:113
Struct holding hysteresis parameters.
Definition OutputExtractor.hpp:63
A phase buffer extractor descriptor.
Definition OutputExtractor.hpp:106
A scalar extractor descriptor.
Definition OutputExtractor.hpp:99
Wrapping struct holding types used for element-level data extraction.
Definition OutputExtractor.hpp:54
static void process(const Context &ectx, const std::vector< Entry > &extractors)
Process the given extractor entries.
Definition OutputExtractor.hpp:158
static std::vector< Entry > removeInactive(std::array< Entry, size > &input)
Obtain vector of active extractors from an array of extractors.
Definition OutputExtractor.hpp:120