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