My Project
Loading...
Searching...
No Matches
FlowGenericProblem_impl.hpp
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*/
23#ifndef OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
24#define OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
25
26#ifndef OPM_FLOW_GENERIC_PROBLEM_HPP
27#include <config.h>
29#endif
30
31#include <dune/common/parametertree.hh>
32
33#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
34#include <opm/input/eclipse/EclipseState/Tables/OverburdTable.hpp>
35#include <opm/input/eclipse/EclipseState/Tables/RockwnodTable.hpp>
36#include <opm/input/eclipse/Schedule/Schedule.hpp>
37#include <opm/input/eclipse/Units/Units.hpp>
38
42
45
46#include <opm/simulators/timestepping/EclTimeSteppingParams.hpp>
47
48#include <boost/date_time.hpp>
49
50#include <fmt/format.h>
51#include <fmt/ranges.h>
52
53#include <iostream>
54#include <stdexcept>
55
56namespace Opm {
57
58template<class GridView, class FluidSystem>
59FlowGenericProblem<GridView,FluidSystem>::
60FlowGenericProblem(const EclipseState& eclState,
61 const Schedule& schedule,
62 const GridView& gridView)
63 : eclState_(eclState)
64 , schedule_(schedule)
65 , gridView_(gridView)
66 , lookUpData_(gridView)
67{
68 enableTuning_ = Parameters::Get<Parameters::EnableTuning>();
69 enableDriftCompensation_ = Parameters::Get<Parameters::EnableDriftCompensation>();
70 initialTimeStepSize_ = Parameters::Get<Parameters::InitialTimeStepSize<Scalar>>();
71 maxTimeStepAfterWellEvent_ = unit::convert::from
72 (Parameters::Get<Parameters::TimeStepAfterEventInDays<Scalar>>(), unit::day);
73
74 // The value N for this parameter is defined in the following order of precedence:
75 //
76 // 1. Command line value (--num-pressure-points-equil=N)
77 //
78 // 2. EQLDIMS item 2. Default value from
79 // opm-common/opm/input/eclipse/share/keywords/000_Eclipse100/E/EQLDIMS
80
81 numPressurePointsEquil_ = Parameters::IsSet<Parameters::NumPressurePointsEquil>()
82 ? Parameters::Get<Parameters::NumPressurePointsEquil>()
83 : eclState.getTableManager().getEqldims().getNumDepthNodesP();
85 explicitRockCompaction_ = Parameters::Get<Parameters::ExplicitRockCompaction>();
86}
87
88template<class GridView, class FluidSystem>
91serializationTestObject(const EclipseState& eclState,
92 const Schedule& schedule,
93 const GridView& gridView)
94{
95 FlowGenericProblem result(eclState, schedule, gridView);
96 result.maxOilSaturation_ = {1.0, 2.0};
97 result.maxWaterSaturation_ = {6.0};
98 result.minRefPressure_ = {7.0, 8.0, 9.0, 10.0};
99 result.overburdenPressure_ = {11.0};
100 result.solventSaturation_ = {15.0};
101 result.solventRsw_ = {18.0};
104
105 return result;
106}
107
108template<class GridView, class FluidSystem>
109std::string
111helpPreamble(int,
112 const char **argv)
113{
114 std::string desc = FlowGenericProblem::briefDescription();
115 if (!desc.empty())
116 desc = desc + "\n";
117
118 return
119 "Usage: "+std::string(argv[0]) + " [OPTIONS] [ECL_DECK_FILENAME]\n"
120 + desc;
121}
122
123template<class GridView, class FluidSystem>
124std::string
128 return briefDescription_;
129}
130
131template<class GridView, class FluidSystem>
133readRockParameters_(const std::vector<Scalar>& cellCenterDepths,
134 std::function<std::array<int,3>(const unsigned)> ijkIndex)
135{
136 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
137
138 // read the rock compressibility parameters
139 {
140 const auto& comp = rock_config.comp();
141 rockParams_.clear();
142 for (const auto& c : comp) {
143 rockParams_.push_back({static_cast<Scalar>(c.pref),
144 static_cast<Scalar>(c.compressibility)});
145 }
146 }
147
148 // Warn that ROCK and ROCKOPTS item 2 = STORE is used together
149 if (rock_config.store()) {
150 OpmLog::warning("ROCKOPTS item 2 set to STORE, ROCK item 1 replaced with initial (equilibrated) pressures");
151 }
152
153 // read the parameters for water-induced rock compaction
154 readRockCompactionParameters_();
155
156 unsigned numElem = gridView_.size(0);
157 if (eclState_.fieldProps().has_int(rock_config.rocknum_property())) {
158 // Auxiliary function to check rockTableIdx_ values belong to the right range. Otherwise, throws.
159 std::function<void(int, int)> valueCheck = [&ijkIndex,&rock_config,this](int fieldPropValue, int coarseElemIdx)
160 {
161 auto fmtError = [fieldPropValue, coarseElemIdx,&ijkIndex,&rock_config](const char* type, std::size_t size)
162 {
163 return fmt::format("{} table index {} for elem {} read from {}"
164 " is out of bounds for number of tables {}",
165 type, fieldPropValue,
166 ijkIndex(coarseElemIdx),
167 rock_config.rocknum_property(), size);
168 };
169 if (!rockCompPoroMult_.empty() &&
170 fieldPropValue > static_cast<int>(rockCompPoroMult_.size())) {
171 throw std::runtime_error(fmtError("Rock compaction",
172 rockCompPoroMult_.size()));
173 }
174 if (!rockCompPoroMultWc_.empty() &&
175 fieldPropValue > static_cast<int>(rockCompPoroMultWc_.size())) {
176 throw std::runtime_error(fmtError("Rock water compaction",
177 rockCompPoroMultWc_.size()));
178 }
179 };
180
181 rockTableIdx_ = this->lookUpData_.template assignFieldPropsIntOnLeaf<short unsigned int>(eclState_.fieldProps(),
182 rock_config.rocknum_property(),
183 true /*needsTranslation*/,
184 valueCheck);
185 }
186
187 // Store overburden pressure pr element
188 const auto& overburdTables = eclState_.getTableManager().getOverburdTables();
189 if (!overburdTables.empty() && !rock_config.store()) {
190 overburdenPressure_.resize(numElem,0.0);
191 std::size_t numRocktabTables = rock_config.num_rock_tables();
193 if (overburdTables.size() != numRocktabTables)
194 throw std::runtime_error(std::to_string(numRocktabTables) +" OVERBURD tables is expected, but " + std::to_string(overburdTables.size()) +" is provided");
195
196 std::vector<Tabulated1DFunction<Scalar>> overburdenTables(numRocktabTables);
197 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
198 const OverburdTable& overburdTable = overburdTables.template getTable<OverburdTable>(regionIdx);
199 overburdenTables[regionIdx].setXYContainers(overburdTable.getDepthColumn(),overburdTable.getOverburdenPressureColumn());
200 }
201
202 for (std::size_t elemIdx = 0; elemIdx < numElem; ++ elemIdx) {
203 unsigned tableIdx = 0;
204 if (!rockTableIdx_.empty()) {
205 tableIdx = rockTableIdx_[elemIdx];
206 }
207 overburdenPressure_[elemIdx] =
208 overburdenTables[tableIdx].eval(cellCenterDepths[elemIdx], /*extrapolation=*/true);
209 }
210 }
211 else if (!overburdTables.empty() && rock_config.store()) {
212 OpmLog::warning("ROCKOPTS item 2 set to STORE, OVERBURD ignored!");
213 }
214}
216template<class GridView, class FluidSystem>
219{
220 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
221
222 if (!rock_config.active())
223 return; // deck does not enable rock compaction
224
225 unsigned numElem = gridView_.size(0);
226 switch (rock_config.hysteresis_mode()) {
227 case RockConfig::Hysteresis::REVERS:
228 break;
229 case RockConfig::Hysteresis::IRREVERS:
230 // interpolate the porv volume multiplier using the minimum pressure in the cell
231 // i.e. don't allow re-inflation.
232 minRefPressure_.resize(numElem, 1e99);
233 break;
234 default:
235 throw std::runtime_error("Not support ROCKOMP hysteresis option ");
236 }
237
238 std::size_t numRocktabTables = rock_config.num_rock_tables();
239 bool waterCompaction = rock_config.water_compaction();
240
241 if (!waterCompaction) {
242 const auto& rocktabTables = eclState_.getTableManager().getRocktabTables();
243 if (rocktabTables.size() != numRocktabTables)
244 throw std::runtime_error("ROCKCOMP is activated." + std::to_string(numRocktabTables)
245 +" ROCKTAB tables is expected, but " + std::to_string(rocktabTables.size()) +" is provided");
246
247 rockCompPoroMult_.resize(numRocktabTables);
248 rockCompTransMult_.resize(numRocktabTables);
249 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
250 const auto& rocktabTable = rocktabTables.template getTable<RocktabTable>(regionIdx);
251 const auto& pressureColumn = rocktabTable.getPressureColumn();
252 const auto& poroColumn = rocktabTable.getPoreVolumeMultiplierColumn();
253 const auto& transColumn = rocktabTable.getTransmissibilityMultiplierColumn();
254 rockCompPoroMult_[regionIdx].setXYContainers(pressureColumn, poroColumn);
255 rockCompTransMult_[regionIdx].setXYContainers(pressureColumn, transColumn);
256 }
257 } else {
258 const auto& rock2dTables = eclState_.getTableManager().getRock2dTables();
259 const auto& rock2dtrTables = eclState_.getTableManager().getRock2dtrTables();
260 const auto& rockwnodTables = eclState_.getTableManager().getRockwnodTables();
261 maxWaterSaturation_.resize(numElem, 0.0);
262
263 if (rock2dTables.size() != numRocktabTables)
264 throw std::runtime_error("Water compation option is selected in ROCKCOMP." + std::to_string(numRocktabTables)
265 +" ROCK2D tables is expected, but " + std::to_string(rock2dTables.size()) +" is provided");
266
267 if (rockwnodTables.size() != numRocktabTables)
268 throw std::runtime_error("Water compation option is selected in ROCKCOMP." + std::to_string(numRocktabTables)
269 +" ROCKWNOD tables is expected, but " + std::to_string(rockwnodTables.size()) +" is provided");
270 //TODO check size match
271 rockCompPoroMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
272 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
273 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
274 const auto& rock2dTable = rock2dTables[regionIdx];
275
276 if (rockwnodTable.getSaturationColumn().size() != rock2dTable.sizeMultValues())
277 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2D needs to match.");
278
279 for (std::size_t xIdx = 0; xIdx < rock2dTable.size(); ++xIdx) {
280 rockCompPoroMultWc_[regionIdx].appendXPos(rock2dTable.getPressureValue(xIdx));
281 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
282 rockCompPoroMultWc_[regionIdx].appendSamplePoint(xIdx,
283 rockwnodTable.getSaturationColumn()[yIdx],
284 rock2dTable.getPvmultValue(xIdx, yIdx));
285 }
286 }
287
288 if (!rock2dtrTables.empty()) {
289 rockCompTransMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
290 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
291 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
292 const auto& rock2dtrTable = rock2dtrTables[regionIdx];
293
294 if (rockwnodTable.getSaturationColumn().size() != rock2dtrTable.sizeMultValues())
295 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2DTR needs to match.");
296
297 for (std::size_t xIdx = 0; xIdx < rock2dtrTable.size(); ++xIdx) {
298 rockCompTransMultWc_[regionIdx].appendXPos(rock2dtrTable.getPressureValue(xIdx));
299 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
300 rockCompTransMultWc_[regionIdx].appendSamplePoint(xIdx,
301 rockwnodTable.getSaturationColumn()[yIdx],
302 rock2dtrTable.getTransMultValue(xIdx, yIdx));
303 }
304 }
305 }
306 }
307}
308
309template<class GridView, class FluidSystem>
310typename FlowGenericProblem<GridView,FluidSystem>::Scalar
312rockCompressibility(unsigned globalSpaceIdx) const
313{
314 if (this->rockParams_.empty())
315 return 0.0;
316
317 unsigned tableIdx = 0;
318 if (!this->rockTableIdx_.empty()) {
319 tableIdx = this->rockTableIdx_[globalSpaceIdx];
320 }
321 return this->rockParams_[tableIdx].compressibility;
322}
323
324template<class GridView, class FluidSystem>
325typename FlowGenericProblem<GridView,FluidSystem>::Scalar
327porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
328{
329 return this->referencePorosity_[timeIdx][globalSpaceIdx];
330}
331
332template<class GridView, class FluidSystem>
333typename FlowGenericProblem<GridView,FluidSystem>::Scalar
335rockFraction(unsigned elementIdx, unsigned timeIdx) const
336{
337 // the reference porosity is defined as the accumulated pore volume divided by the
338 // geometric volume of the element. Note that it can
339 // be larger than 1.0 if porevolume multipliers are used
340 // to for instance implement larger boundary cells
341 auto porosity = this->lookUpData_.fieldPropDouble(eclState_.fieldProps(), "PORO", elementIdx);
342 return referencePorosity(elementIdx, timeIdx) / porosity * (1 - porosity);
343}
344
345template<class GridView, class FluidSystem>
346template<class T>
348updateNum(const std::string& name, std::vector<T>& numbers, std::size_t num_regions)
349{
350 if (!eclState_.fieldProps().has_int(name))
351 return;
352
353 std::function<void(T, int)> valueCheck = [num_regions,name](T fieldPropValue, [[maybe_unused]] int fieldPropIdx) {
354 if ( fieldPropValue > (int)num_regions) {
355 throw std::runtime_error("Values larger than maximum number of regions "
356 + std::to_string(num_regions) + " provided in " + name);
357 }
358 if ( fieldPropValue <= 0) {
359 throw std::runtime_error("zero or negative values provided for region array: " + name);
360 }
361 };
362
363 numbers = this->lookUpData_.template assignFieldPropsIntOnLeaf<T>(eclState_.fieldProps(), name,
364 true /*needsTranslation*/, valueCheck);
365}
366
367template<class GridView, class FluidSystem>
368void FlowGenericProblem<GridView,FluidSystem>::
369updatePvtnum_()
370{
371 const auto num_regions = eclState_.getTableManager().getTabdims().getNumPVTTables();
372 updateNum("PVTNUM", pvtnum_, num_regions);
373}
374
375template<class GridView, class FluidSystem>
376void FlowGenericProblem<GridView,FluidSystem>::
377updateSatnum_()
378{
379 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
380 updateNum("SATNUM", satnum_, num_regions);
381}
382
383template<class GridView, class FluidSystem>
384void FlowGenericProblem<GridView,FluidSystem>::
385updateMiscnum_()
386{
387 const auto num_regions = 1; // we only support single region
388 updateNum("MISCNUM", miscnum_, num_regions);
389}
390
391template<class GridView, class FluidSystem>
392void FlowGenericProblem<GridView,FluidSystem>::
393updatePlmixnum_()
394{
395 const auto num_regions = 1; // we only support single region
396 updateNum("PLMIXNUM", plmixnum_, num_regions);
397}
398
399template<class GridView, class FluidSystem>
400bool FlowGenericProblem<GridView,FluidSystem>::
401vapparsActive(int episodeIdx) const
402{
403 const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
404 return (oilVaporizationControl.getType() == OilVaporizationProperties::OilVaporization::VAPPARS);
405}
406
407template<class GridView, class FluidSystem>
408bool FlowGenericProblem<GridView,FluidSystem>::
409beginEpisode_(bool enableExperiments,
410 int episodeIdx)
411{
412 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
413 // print some useful information in experimental mode. (the production
414 // simulator does this externally.)
415 std::ostringstream ss;
416 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
417 boost::posix_time::ptime curDateTime =
418 boost::posix_time::from_time_t(schedule_.simTime(episodeIdx));
419 ss.imbue(std::locale(std::locale::classic(), facet));
420 ss << "Report step " << episodeIdx + 1
421 << "/" << schedule_.size() - 1
422 << " at day " << schedule_.seconds(episodeIdx)/(24*3600)
423 << "/" << schedule_.seconds(schedule_.size() - 1)/(24*3600)
424 << ", date = " << curDateTime.date()
425 << "\n ";
426 OpmLog::info(ss.str());
427 }
428
429 const auto& events = schedule_[episodeIdx].events();
430
431 // react to TUNING changes
432 if (episodeIdx > 0 && enableTuning_ && events.hasEvent(ScheduleEvents::TUNING_CHANGE))
433 {
434 const auto& sched_state = schedule_[episodeIdx];
435 const auto& tuning = sched_state.tuning();
436 initialTimeStepSize_ = sched_state.max_next_tstep(enableTuning_);
437 maxTimeStepAfterWellEvent_ = tuning.TMAXWC;
438 return true;
439 }
440
441 return false;
442}
443
444template<class GridView, class FluidSystem>
445void FlowGenericProblem<GridView,FluidSystem>::
446beginTimeStep_(bool enableExperiments,
447 int episodeIdx,
448 int timeStepIndex,
449 Scalar startTime,
450 Scalar time,
451 Scalar timeStepSize,
452 Scalar endTime)
453{
454 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
455 std::ostringstream ss;
456 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
457 boost::posix_time::ptime date = boost::posix_time::from_time_t(startTime) + boost::posix_time::milliseconds(static_cast<long long>(time / prefix::milli));
458 ss.imbue(std::locale(std::locale::classic(), facet));
459 ss <<"\nTime step " << timeStepIndex << ", stepsize "
460 << unit::convert::to(timeStepSize, unit::day) << " days,"
461 << " at day " << (double)unit::convert::to(time, unit::day)
462 << "/" << (double)unit::convert::to(endTime, unit::day)
463 << ", date = " << date;
464 OpmLog::info(ss.str());
465 }
466}
467
468template<class GridView, class FluidSystem>
469void FlowGenericProblem<GridView,FluidSystem>::
470initFluidSystem_()
471{
472 FluidSystem::initFromState(eclState_, schedule_);
473}
474
475template<class GridView, class FluidSystem>
476void FlowGenericProblem<GridView,FluidSystem>::
477readBlackoilExtentionsInitialConditions_(std::size_t numDof,
478 bool enableSolvent,
479 bool enablePolymer,
480 bool enablePolymerMolarWeight,
481 bool enableMICP)
482{
483 auto getArray = [](const std::vector<double>& input)
484 {
485 if constexpr (std::is_same_v<Scalar,double>) {
486 return input;
487 } else {
488 return std::vector<Scalar>{input.begin(), input.end()};
489 }
490 };
491
492 if (enableSolvent) {
493 if (eclState_.fieldProps().has_double("SSOL")) {
494 solventSaturation_ = getArray(eclState_.fieldProps().get_double("SSOL"));
495 } else {
496 solventSaturation_.resize(numDof, 0.0);
497 }
498
499 solventRsw_.resize(numDof, 0.0);
500 }
501
502 if (enablePolymer) {
503 if (eclState_.fieldProps().has_double("SPOLY")) {
504 polymer_.concentration = getArray(eclState_.fieldProps().get_double("SPOLY"));
505 } else {
506 polymer_.concentration.resize(numDof, 0.0);
507 }
508 }
509
510 if (enablePolymerMolarWeight) {
511 if (eclState_.fieldProps().has_double("SPOLYMW")) {
512 polymer_.moleWeight = getArray(eclState_.fieldProps().get_double("SPOLYMW"));
513 } else {
514 polymer_.moleWeight.resize(numDof, 0.0);
515 }
516 }
517
518 if (enableMICP) {
519 if (eclState_.fieldProps().has_double("SMICR")) {
520 micp_.microbialConcentration = getArray(eclState_.fieldProps().get_double("SMICR"));
521 } else {
522 micp_.microbialConcentration.resize(numDof, 0.0);
523 }
524 if (eclState_.fieldProps().has_double("SOXYG")) {
525 micp_.oxygenConcentration = getArray(eclState_.fieldProps().get_double("SOXYG"));
526 } else {
527 micp_.oxygenConcentration.resize(numDof, 0.0);
528 }
529 if (eclState_.fieldProps().has_double("SUREA")) {
530 micp_.ureaConcentration = getArray(eclState_.fieldProps().get_double("SUREA"));
531 } else {
532 micp_.ureaConcentration.resize(numDof, 0.0);
533 }
534 if (eclState_.fieldProps().has_double("SBIOF")) {
535 micp_.biofilmConcentration = getArray(eclState_.fieldProps().get_double("SBIOF"));
536 } else {
537 micp_.biofilmConcentration.resize(numDof, 0.0);
538 }
539 if (eclState_.fieldProps().has_double("SCALC")) {
540 micp_.calciteConcentration = getArray(eclState_.fieldProps().get_double("SCALC"));
541 } else {
542 micp_.calciteConcentration.resize(numDof, 0.0);
543 }
544 }
545}
546
547template<class GridView, class FluidSystem>
548typename FlowGenericProblem<GridView,FluidSystem>::Scalar
550maxWaterSaturation(unsigned globalDofIdx) const
551{
552 if (maxWaterSaturation_.empty())
553 return 0.0;
554
555 return maxWaterSaturation_[globalDofIdx];
556}
557
558template<class GridView, class FluidSystem>
559typename FlowGenericProblem<GridView,FluidSystem>::Scalar
561minOilPressure(unsigned globalDofIdx) const
562{
563 if (minRefPressure_.empty())
564 return 0.0;
565
566 return minRefPressure_[globalDofIdx];
567}
568
569template<class GridView, class FluidSystem>
570typename FlowGenericProblem<GridView,FluidSystem>::Scalar
572overburdenPressure(unsigned elementIdx) const
573{
574 if (overburdenPressure_.empty())
575 return 0.0;
576
577 return overburdenPressure_[elementIdx];
578}
579
580template<class GridView, class FluidSystem>
581typename FlowGenericProblem<GridView,FluidSystem>::Scalar
583solventSaturation(unsigned elemIdx) const
584{
585 if (solventSaturation_.empty())
586 return 0;
587
588 return solventSaturation_[elemIdx];
589}
590
591template<class GridView, class FluidSystem>
592typename FlowGenericProblem<GridView,FluidSystem>::Scalar
594solventRsw(unsigned elemIdx) const
595{
596 if (solventRsw_.empty())
597 return 0;
598
599 return solventRsw_[elemIdx];
600}
601
602
603
604template<class GridView, class FluidSystem>
605typename FlowGenericProblem<GridView,FluidSystem>::Scalar
607polymerConcentration(unsigned elemIdx) const
608{
609 if (polymer_.concentration.empty()) {
610 return 0;
611 }
612
613 return polymer_.concentration[elemIdx];
614}
615
616template<class GridView, class FluidSystem>
617typename FlowGenericProblem<GridView,FluidSystem>::Scalar
619polymerMolecularWeight(const unsigned elemIdx) const
620{
621 if (polymer_.moleWeight.empty()) {
622 return 0.0;
623 }
624
625 return polymer_.moleWeight[elemIdx];
626}
627
628template<class GridView, class FluidSystem>
629typename FlowGenericProblem<GridView,FluidSystem>::Scalar
631microbialConcentration(unsigned elemIdx) const
632{
633 if (micp_.microbialConcentration.empty()) {
634 return 0;
635 }
636
637 return micp_.microbialConcentration[elemIdx];
638}
639
640template<class GridView, class FluidSystem>
641typename FlowGenericProblem<GridView,FluidSystem>::Scalar
643oxygenConcentration(unsigned elemIdx) const
644{
645 if (micp_.oxygenConcentration.empty()) {
646 return 0;
647 }
648
649 return micp_.oxygenConcentration[elemIdx];
650}
651
652template<class GridView, class FluidSystem>
653typename FlowGenericProblem<GridView,FluidSystem>::Scalar
655ureaConcentration(unsigned elemIdx) const
656{
657 if (micp_.ureaConcentration.empty()) {
658 return 0;
659 }
660
661 return micp_.ureaConcentration[elemIdx];
662}
663
664template<class GridView, class FluidSystem>
665typename FlowGenericProblem<GridView,FluidSystem>::Scalar
667biofilmConcentration(unsigned elemIdx) const
668{
669 if (micp_.biofilmConcentration.empty()) {
670 return 0;
671 }
672
673 return micp_.biofilmConcentration[elemIdx];
674}
675
676template<class GridView, class FluidSystem>
677typename FlowGenericProblem<GridView,FluidSystem>::Scalar
679calciteConcentration(unsigned elemIdx) const
680{
681 if (micp_.calciteConcentration.empty()) {
682 return 0;
683 }
684
685 return micp_.calciteConcentration[elemIdx];
686}
687
688template<class GridView, class FluidSystem>
690pvtRegionIndex(unsigned elemIdx) const
691{
692 if (pvtnum_.empty())
693 return 0;
694
695 return pvtnum_[elemIdx];
696}
697
698template<class GridView, class FluidSystem>
700satnumRegionIndex(unsigned elemIdx) const
701{
702 if (satnum_.empty())
703 return 0;
704
705 return satnum_[elemIdx];
706}
707
708template<class GridView, class FluidSystem>
710miscnumRegionIndex(unsigned elemIdx) const
711{
712 if (miscnum_.empty())
713 return 0;
714
715 return miscnum_[elemIdx];
716}
717
718template<class GridView, class FluidSystem>
720plmixnumRegionIndex(unsigned elemIdx) const
721{
722 if (plmixnum_.empty())
723 return 0;
724
725 return plmixnum_[elemIdx];
726}
727
728template<class GridView, class FluidSystem>
729typename FlowGenericProblem<GridView,FluidSystem>::Scalar
731maxPolymerAdsorption(unsigned elemIdx) const
732{
733 if (polymer_.maxAdsorption.empty()) {
734 return 0;
735 }
736
737 return polymer_.maxAdsorption[elemIdx];
738}
739
740template<class GridView, class FluidSystem>
742operator==(const FlowGenericProblem& rhs) const
743{
744 return this->maxWaterSaturation_ == rhs.maxWaterSaturation_ &&
745 this->minRefPressure_ == rhs.minRefPressure_ &&
746 this->overburdenPressure_ == rhs.overburdenPressure_ &&
747 this->solventSaturation_ == rhs.solventSaturation_ &&
748 this->solventRsw_ == rhs.solventRsw_ &&
749 this->polymer_ == rhs.polymer_ &&
750 this->micp_ == rhs.micp_;
751}
752
753} // namespace Opm
754
755#endif // OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Defines some fundamental parameters for all models.
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition FlowGenericProblem.hpp:61
Scalar oxygenConcentration(unsigned elemIdx) const
Returns the initial oxygen concentration for a given a cell index.
Definition FlowGenericProblem_impl.hpp:643
Scalar microbialConcentration(unsigned elemIdx) const
Returns the initial microbial concentration for a given a cell index.
Definition FlowGenericProblem_impl.hpp:631
Scalar biofilmConcentration(unsigned elemIdx) const
Returns the initial biofilm concentration for a given a cell index.
Definition FlowGenericProblem_impl.hpp:667
Scalar calciteConcentration(unsigned elemIdx) const
Returns the initial calcite concentration for a given a cell index.
Definition FlowGenericProblem_impl.hpp:679
Scalar ureaConcentration(unsigned elemIdx) const
Returns the initial urea concentration for a given a cell index.
Definition FlowGenericProblem_impl.hpp:655
Declare the properties used by the infrastructure code of the finite volume discretizations.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilboundaryratevector.hh:37
constexpr auto getPropValue()
get the value data member of a property
Definition propertysystem.hh:242
This file provides the infrastructure to retrieve run-time parameters.
Struct holding MICP extension data.
Definition SolutionContainers.hpp:57
Struct holding polymer extension data.
Definition SolutionContainers.hpp:37