FlowGenericProblem_impl.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*/
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
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>
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
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 std::transform(comp.begin(), comp.end(), std::back_inserter(rockParams_),
143 [](const auto& c)
144 {
145 return RockParams{static_cast<Scalar>(c.pref),
146 static_cast<Scalar>(c.compressibility)};
147 });
148 }
150 // Warn that ROCK and ROCKOPTS item 2 = STORE is used together
151 if (rock_config.store()) {
152 OpmLog::warning("ROCKOPTS item 2 set to STORE, ROCK item 1 replaced with initial (equilibrated) pressures");
153 }
154
155 // read the parameters for water-induced rock compaction
156 readRockCompactionParameters_();
157
158 unsigned numElem = gridView_.size(0);
159 if (eclState_.fieldProps().has_int(rock_config.rocknum_property())) {
160 // Auxiliary function to check rockTableIdx_ values belong to the right range. Otherwise, throws.
161 std::function<void(int, int)> valueCheck = [&ijkIndex,&rock_config,this](int fieldPropValue, int coarseElemIdx)
162 {
163 auto fmtError = [fieldPropValue, coarseElemIdx,&ijkIndex,&rock_config](const char* type, std::size_t size)
164 {
165 return fmt::format("{} table index {} for elem {} read from {}"
166 " is out of bounds for number of tables {}",
167 type, fieldPropValue,
168 ijkIndex(coarseElemIdx),
169 rock_config.rocknum_property(), size);
170 };
171 if (!rockCompPoroMult_.empty() &&
172 fieldPropValue > static_cast<int>(rockCompPoroMult_.size())) {
173 throw std::runtime_error(fmtError("Rock compaction",
174 rockCompPoroMult_.size()));
175 }
176 if (!rockCompPoroMultWc_.empty() &&
177 fieldPropValue > static_cast<int>(rockCompPoroMultWc_.size())) {
178 throw std::runtime_error(fmtError("Rock water compaction",
179 rockCompPoroMultWc_.size()));
180 }
181 };
183 rockTableIdx_ = this->lookUpData_.template assignFieldPropsIntOnLeaf<short unsigned int>(eclState_.fieldProps(),
184 rock_config.rocknum_property(),
185 true /*needsTranslation*/,
186 valueCheck);
188
189 // Store overburden pressure pr element
190 const auto& overburdTables = eclState_.getTableManager().getOverburdTables();
191 if (!overburdTables.empty() && !rock_config.store()) {
192 overburdenPressure_.resize(numElem,0.0);
193 std::size_t numRocktabTables = rock_config.num_rock_tables();
194
195 if (overburdTables.size() != numRocktabTables)
196 throw std::runtime_error(std::to_string(numRocktabTables) +" OVERBURD tables is expected, but " + std::to_string(overburdTables.size()) +" is provided");
198 std::vector<Tabulated1DFunction<Scalar>> overburdenTables(numRocktabTables);
199 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
200 const OverburdTable& overburdTable = overburdTables.template getTable<OverburdTable>(regionIdx);
201 overburdenTables[regionIdx].setXYContainers(overburdTable.getDepthColumn(),overburdTable.getOverburdenPressureColumn());
203
204 for (std::size_t elemIdx = 0; elemIdx < numElem; ++ elemIdx) {
205 unsigned tableIdx = 0;
206 if (!rockTableIdx_.empty()) {
207 tableIdx = rockTableIdx_[elemIdx];
208 }
209 overburdenPressure_[elemIdx] =
210 overburdenTables[tableIdx].eval(cellCenterDepths[elemIdx], /*extrapolation=*/true);
211 }
212 }
213 else if (!overburdTables.empty() && rock_config.store()) {
214 OpmLog::warning("ROCKOPTS item 2 set to STORE, OVERBURD ignored!");
215 }
216}
217
218template<class GridView, class FluidSystem>
221{
222 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
223
224 if (!rock_config.active())
225 return; // deck does not enable rock compaction
226
227 unsigned numElem = gridView_.size(0);
228 switch (rock_config.hysteresis_mode()) {
229 case RockConfig::Hysteresis::REVERS:
230 break;
231 case RockConfig::Hysteresis::IRREVERS:
232 // interpolate the porv volume multiplier using the minimum pressure in the cell
233 // i.e. don't allow re-inflation.
234 minRefPressure_.resize(numElem, 1e99);
235 break;
236 default:
237 throw std::runtime_error("Not support ROCKOMP hysteresis option ");
238 }
240 std::size_t numRocktabTables = rock_config.num_rock_tables();
241 bool waterCompaction = rock_config.water_compaction();
242
243 if (!waterCompaction) {
244 const auto& rocktabTables = eclState_.getTableManager().getRocktabTables();
245 if (rocktabTables.size() != numRocktabTables)
246 throw std::runtime_error("ROCKCOMP is activated." + std::to_string(numRocktabTables)
247 +" ROCKTAB tables is expected, but " + std::to_string(rocktabTables.size()) +" is provided");
248
249 rockCompPoroMult_.resize(numRocktabTables);
250 rockCompTransMult_.resize(numRocktabTables);
251 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
252 const auto& rocktabTable = rocktabTables.template getTable<RocktabTable>(regionIdx);
253 const auto& pressureColumn = rocktabTable.getPressureColumn();
254 const auto& poroColumn = rocktabTable.getPoreVolumeMultiplierColumn();
255 const auto& transColumn = rocktabTable.getTransmissibilityMultiplierColumn();
256 rockCompPoroMult_[regionIdx].setXYContainers(pressureColumn, poroColumn);
257 rockCompTransMult_[regionIdx].setXYContainers(pressureColumn, transColumn);
258 }
259 } else {
260 const auto& rock2dTables = eclState_.getTableManager().getRock2dTables();
261 const auto& rock2dtrTables = eclState_.getTableManager().getRock2dtrTables();
262 const auto& rockwnodTables = eclState_.getTableManager().getRockwnodTables();
263 maxWaterSaturation_.resize(numElem, 0.0);
264
265 if (rock2dTables.size() != numRocktabTables)
266 throw std::runtime_error("Water compation option is selected in ROCKCOMP." + std::to_string(numRocktabTables)
267 +" ROCK2D tables is expected, but " + std::to_string(rock2dTables.size()) +" is provided");
268
269 if (rockwnodTables.size() != numRocktabTables)
270 throw std::runtime_error("Water compation option is selected in ROCKCOMP." + std::to_string(numRocktabTables)
271 +" ROCKWNOD tables is expected, but " + std::to_string(rockwnodTables.size()) +" is provided");
272 //TODO check size match
273 rockCompPoroMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
274 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
275 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
276 const auto& rock2dTable = rock2dTables[regionIdx];
277
278 if (rockwnodTable.getSaturationColumn().size() != rock2dTable.sizeMultValues())
279 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2D needs to match.");
280
281 for (std::size_t xIdx = 0; xIdx < rock2dTable.size(); ++xIdx) {
282 rockCompPoroMultWc_[regionIdx].appendXPos(rock2dTable.getPressureValue(xIdx));
283 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
284 rockCompPoroMultWc_[regionIdx].appendSamplePoint(xIdx,
285 rockwnodTable.getSaturationColumn()[yIdx],
286 rock2dTable.getPvmultValue(xIdx, yIdx));
287 }
288 }
290 if (!rock2dtrTables.empty()) {
291 rockCompTransMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
292 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
293 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
294 const auto& rock2dtrTable = rock2dtrTables[regionIdx];
295
296 if (rockwnodTable.getSaturationColumn().size() != rock2dtrTable.sizeMultValues())
297 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2DTR needs to match.");
298
299 for (std::size_t xIdx = 0; xIdx < rock2dtrTable.size(); ++xIdx) {
300 rockCompTransMultWc_[regionIdx].appendXPos(rock2dtrTable.getPressureValue(xIdx));
301 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
302 rockCompTransMultWc_[regionIdx].appendSamplePoint(xIdx,
303 rockwnodTable.getSaturationColumn()[yIdx],
304 rock2dtrTable.getTransMultValue(xIdx, yIdx));
305 }
306 }
307 }
308 }
311template<class GridView, class FluidSystem>
314rockCompressibility(unsigned globalSpaceIdx) const
315{
316 if (this->rockParams_.empty())
317 return 0.0;
318
319 unsigned tableIdx = 0;
320 if (!this->rockTableIdx_.empty()) {
321 tableIdx = this->rockTableIdx_[globalSpaceIdx];
322 }
323 return this->rockParams_[tableIdx].compressibility;
324}
325
326template<class GridView, class FluidSystem>
329porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
330{
331 return this->referencePorosity_[timeIdx][globalSpaceIdx];
332}
333
334template<class GridView, class FluidSystem>
337rockFraction(unsigned elementIdx, unsigned timeIdx) const
338{
339 // the reference porosity is defined as the accumulated pore volume divided by the
340 // geometric volume of the element. Note that it can
341 // be larger than 1.0 if porevolume multipliers are used
342 // to for instance implement larger boundary cells
343 auto porosity = this->lookUpData_.fieldPropDouble(eclState_.fieldProps(), "PORO", elementIdx);
344 return referencePorosity(elementIdx, timeIdx) / porosity * (1 - porosity);
345}
346
347template<class GridView, class FluidSystem>
348template<class T>
350updateNum(const std::string& name, std::vector<T>& numbers, std::size_t num_regions)
351{
352 if (!eclState_.fieldProps().has_int(name))
353 return;
354
355 std::function<void(T, int)> valueCheck = [num_regions,name](T fieldPropValue, [[maybe_unused]] int fieldPropIdx) {
356 if ( fieldPropValue > (int)num_regions) {
357 throw std::runtime_error("Values larger than maximum number of regions "
358 + std::to_string(num_regions) + " provided in " + name);
359 }
360 if ( fieldPropValue <= 0) {
361 throw std::runtime_error("zero or negative values provided for region array: " + name);
362 }
363 };
364
365 numbers = this->lookUpData_.template assignFieldPropsIntOnLeaf<T>(eclState_.fieldProps(), name,
366 true /*needsTranslation*/, valueCheck);
367}
368
369template<class GridView, class FluidSystem>
372{
373 const auto num_regions = eclState_.getTableManager().getTabdims().getNumPVTTables();
374 updateNum("PVTNUM", pvtnum_, num_regions);
375}
376
377template<class GridView, class FluidSystem>
380{
381 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
382 updateNum("SATNUM", satnum_, num_regions);
383}
384
385template<class GridView, class FluidSystem>
388{
389 const auto num_regions = 1; // we only support single region
390 updateNum("MISCNUM", miscnum_, num_regions);
391}
392
393template<class GridView, class FluidSystem>
396{
397 const auto num_regions = 1; // we only support single region
398 updateNum("PLMIXNUM", plmixnum_, num_regions);
399}
400
401template<class GridView, class FluidSystem>
403vapparsActive(int episodeIdx) const
404{
405 const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
406 return (oilVaporizationControl.getType() == OilVaporizationProperties::OilVaporization::VAPPARS);
407}
408
409template<class GridView, class FluidSystem>
411beginEpisode_(bool enableExperiments,
412 int episodeIdx)
413{
414 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
415 // print some useful information in experimental mode. (the production
416 // simulator does this externally.)
417 std::ostringstream ss;
418 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
419 boost::posix_time::ptime curDateTime =
420 boost::posix_time::from_time_t(schedule_.simTime(episodeIdx));
421 ss.imbue(std::locale(std::locale::classic(), facet));
422 ss << "Report step " << episodeIdx + 1
423 << "/" << schedule_.size() - 1
424 << " at day " << schedule_.seconds(episodeIdx)/(24*3600)
425 << "/" << schedule_.seconds(schedule_.size() - 1)/(24*3600)
426 << ", date = " << curDateTime.date()
427 << "\n ";
428 OpmLog::info(ss.str());
429 }
430
431 const auto& events = schedule_[episodeIdx].events();
432
433 // react to TUNING changes
434 if (episodeIdx > 0 && enableTuning_ && events.hasEvent(ScheduleEvents::TUNING_CHANGE))
435 {
436 const auto& sched_state = schedule_[episodeIdx];
437 const auto& tuning = sched_state.tuning();
438 initialTimeStepSize_ = sched_state.max_next_tstep(enableTuning_);
439 maxTimeStepAfterWellEvent_ = tuning.TMAXWC;
440 return true;
441 }
442
443 return false;
444}
445
446template<class GridView, class FluidSystem>
448beginTimeStep_(bool enableExperiments,
449 int episodeIdx,
450 int timeStepIndex,
451 Scalar startTime,
452 Scalar time,
453 Scalar timeStepSize,
454 Scalar endTime)
455{
456 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
457 std::ostringstream ss;
458 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
459 boost::posix_time::ptime date = boost::posix_time::from_time_t(startTime) + boost::posix_time::milliseconds(static_cast<long long>(time / prefix::milli));
460 ss.imbue(std::locale(std::locale::classic(), facet));
461 ss <<"\nTime step " << timeStepIndex << ", stepsize "
462 << unit::convert::to(timeStepSize, unit::day) << " days,"
463 << " at day " << (double)unit::convert::to(time, unit::day)
464 << "/" << (double)unit::convert::to(endTime, unit::day)
465 << ", date = " << date;
466 OpmLog::info(ss.str());
467 }
468}
469
470template<class GridView, class FluidSystem>
473{
474 FluidSystem::initFromState(eclState_, schedule_);
475}
476
477template<class GridView, class FluidSystem>
480 bool enableSolvent,
481 bool enablePolymer,
482 bool enablePolymerMolarWeight,
483 bool enableMICP)
484{
485 auto getArray = [](const std::vector<double>& input)
486 {
487 if constexpr (std::is_same_v<Scalar,double>) {
488 return input;
489 } else {
490 return std::vector<Scalar>{input.begin(), input.end()};
491 }
492 };
493
494 if (enableSolvent) {
495 if (eclState_.fieldProps().has_double("SSOL")) {
496 solventSaturation_ = getArray(eclState_.fieldProps().get_double("SSOL"));
497 } else {
498 solventSaturation_.resize(numDof, 0.0);
499 }
500
501 solventRsw_.resize(numDof, 0.0);
502 }
503
504 if (enablePolymer) {
505 if (eclState_.fieldProps().has_double("SPOLY")) {
506 polymer_.concentration = getArray(eclState_.fieldProps().get_double("SPOLY"));
507 } else {
508 polymer_.concentration.resize(numDof, 0.0);
509 }
510 }
511
512 if (enablePolymerMolarWeight) {
513 if (eclState_.fieldProps().has_double("SPOLYMW")) {
514 polymer_.moleWeight = getArray(eclState_.fieldProps().get_double("SPOLYMW"));
515 } else {
516 polymer_.moleWeight.resize(numDof, 0.0);
517 }
518 }
519
520 if (enableMICP) {
521 if (eclState_.fieldProps().has_double("SMICR")) {
522 micp_.microbialConcentration = getArray(eclState_.fieldProps().get_double("SMICR"));
523 } else {
524 micp_.microbialConcentration.resize(numDof, 0.0);
525 }
526 if (eclState_.fieldProps().has_double("SOXYG")) {
527 micp_.oxygenConcentration = getArray(eclState_.fieldProps().get_double("SOXYG"));
528 } else {
529 micp_.oxygenConcentration.resize(numDof, 0.0);
530 }
531 if (eclState_.fieldProps().has_double("SUREA")) {
532 micp_.ureaConcentration = getArray(eclState_.fieldProps().get_double("SUREA"));
533 } else {
534 micp_.ureaConcentration.resize(numDof, 0.0);
535 }
536 if (eclState_.fieldProps().has_double("SBIOF")) {
537 micp_.biofilmConcentration = getArray(eclState_.fieldProps().get_double("SBIOF"));
538 } else {
539 micp_.biofilmConcentration.resize(numDof, 0.0);
540 }
541 if (eclState_.fieldProps().has_double("SCALC")) {
542 micp_.calciteConcentration = getArray(eclState_.fieldProps().get_double("SCALC"));
543 } else {
544 micp_.calciteConcentration.resize(numDof, 0.0);
545 }
546 }
547}
548
549template<class GridView, class FluidSystem>
552maxWaterSaturation(unsigned globalDofIdx) const
553{
554 if (maxWaterSaturation_.empty())
555 return 0.0;
556
557 return maxWaterSaturation_[globalDofIdx];
558}
559
560template<class GridView, class FluidSystem>
563minOilPressure(unsigned globalDofIdx) const
564{
565 if (minRefPressure_.empty())
566 return 0.0;
567
568 return minRefPressure_[globalDofIdx];
569}
570
571template<class GridView, class FluidSystem>
574overburdenPressure(unsigned elementIdx) const
575{
576 if (overburdenPressure_.empty())
577 return 0.0;
578
579 return overburdenPressure_[elementIdx];
580}
581
582template<class GridView, class FluidSystem>
585solventSaturation(unsigned elemIdx) const
586{
587 if (solventSaturation_.empty())
588 return 0;
589
590 return solventSaturation_[elemIdx];
591}
592
593template<class GridView, class FluidSystem>
596solventRsw(unsigned elemIdx) const
597{
598 if (solventRsw_.empty())
599 return 0;
600
601 return solventRsw_[elemIdx];
602}
603
604
605
606template<class GridView, class FluidSystem>
609polymerConcentration(unsigned elemIdx) const
610{
611 if (polymer_.concentration.empty()) {
612 return 0;
613 }
614
615 return polymer_.concentration[elemIdx];
616}
617
618template<class GridView, class FluidSystem>
621polymerMolecularWeight(const unsigned elemIdx) const
622{
623 if (polymer_.moleWeight.empty()) {
624 return 0.0;
625 }
626
627 return polymer_.moleWeight[elemIdx];
628}
629
630template<class GridView, class FluidSystem>
633microbialConcentration(unsigned elemIdx) const
634{
635 if (micp_.microbialConcentration.empty()) {
636 return 0;
637 }
638
639 return micp_.microbialConcentration[elemIdx];
640}
641
642template<class GridView, class FluidSystem>
645oxygenConcentration(unsigned elemIdx) const
646{
647 if (micp_.oxygenConcentration.empty()) {
648 return 0;
649 }
650
651 return micp_.oxygenConcentration[elemIdx];
652}
653
654template<class GridView, class FluidSystem>
657ureaConcentration(unsigned elemIdx) const
658{
659 if (micp_.ureaConcentration.empty()) {
660 return 0;
661 }
662
663 return micp_.ureaConcentration[elemIdx];
664}
665
666template<class GridView, class FluidSystem>
669biofilmConcentration(unsigned elemIdx) const
670{
671 if (micp_.biofilmConcentration.empty()) {
672 return 0;
673 }
674
675 return micp_.biofilmConcentration[elemIdx];
676}
677
678template<class GridView, class FluidSystem>
681calciteConcentration(unsigned elemIdx) const
682{
683 if (micp_.calciteConcentration.empty()) {
684 return 0;
685 }
686
687 return micp_.calciteConcentration[elemIdx];
688}
689
690template<class GridView, class FluidSystem>
692pvtRegionIndex(unsigned elemIdx) const
693{
694 if (pvtnum_.empty())
695 return 0;
696
697 return pvtnum_[elemIdx];
698}
699
700template<class GridView, class FluidSystem>
702satnumRegionIndex(unsigned elemIdx) const
703{
704 if (satnum_.empty())
705 return 0;
706
707 return satnum_[elemIdx];
708}
709
710template<class GridView, class FluidSystem>
712miscnumRegionIndex(unsigned elemIdx) const
713{
714 if (miscnum_.empty())
715 return 0;
716
717 return miscnum_[elemIdx];
718}
719
720template<class GridView, class FluidSystem>
722plmixnumRegionIndex(unsigned elemIdx) const
723{
724 if (plmixnum_.empty())
725 return 0;
726
727 return plmixnum_[elemIdx];
728}
729
730template<class GridView, class FluidSystem>
733maxPolymerAdsorption(unsigned elemIdx) const
734{
735 if (polymer_.maxAdsorption.empty()) {
736 return 0;
737 }
738
739 return polymer_.maxAdsorption[elemIdx];
740}
741
742template<class GridView, class FluidSystem>
744operator==(const FlowGenericProblem& rhs) const
745{
746 return this->maxWaterSaturation_ == rhs.maxWaterSaturation_ &&
747 this->minRefPressure_ == rhs.minRefPressure_ &&
748 this->overburdenPressure_ == rhs.overburdenPressure_ &&
749 this->solventSaturation_ == rhs.solventSaturation_ &&
750 this->solventRsw_ == rhs.solventRsw_ &&
751 this->polymer_ == rhs.polymer_ &&
752 this->micp_ == rhs.micp_;
753}
754
755} // namespace Opm
756
757#endif // OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
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
UniformXTabulated2DFunction< Scalar > TabulatedTwoDFunction
Definition: FlowGenericProblem.hpp:64
Scalar oxygenConcentration(unsigned elemIdx) const
Returns the initial oxygen concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:645
Scalar microbialConcentration(unsigned elemIdx) const
Returns the initial microbial concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:633
PolymerSolutionContainer< Scalar > polymer_
Definition: FlowGenericProblem.hpp:334
static std::string briefDescription()
Returns a human readable description of the problem for the help message.
Definition: FlowGenericProblem_impl.hpp:126
Scalar initialTimeStepSize_
Definition: FlowGenericProblem.hpp:345
std::vector< Scalar > solventSaturation_
Definition: FlowGenericProblem.hpp:339
bool enableDriftCompensation_
Definition: FlowGenericProblem.hpp:351
static FlowGenericProblem serializationTestObject(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:91
FlowGenericProblem(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:60
bool enableTuning_
Definition: FlowGenericProblem.hpp:344
Scalar biofilmConcentration(unsigned elemIdx) const
Returns the initial biofilm concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:669
MICPSolutionContainer< Scalar > micp_
Definition: FlowGenericProblem.hpp:341
void readRockParameters_(const std::vector< Scalar > &cellCenterDepths, std::function< std::array< int, 3 >(const unsigned)> ijkIndex)
Definition: FlowGenericProblem_impl.hpp:133
std::vector< Scalar > maxOilSaturation_
Definition: FlowGenericProblem.hpp:335
int numPressurePointsEquil_
Definition: FlowGenericProblem.hpp:349
std::vector< Scalar > maxWaterSaturation_
Definition: FlowGenericProblem.hpp:336
Scalar maxTimeStepAfterWellEvent_
Definition: FlowGenericProblem.hpp:346
Scalar calciteConcentration(unsigned elemIdx) const
Returns the initial calcite concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:681
Scalar ureaConcentration(unsigned elemIdx) const
Returns the initial urea concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:657
std::vector< Scalar > minRefPressure_
Definition: FlowGenericProblem.hpp:337
std::vector< Scalar > solventRsw_
Definition: FlowGenericProblem.hpp:340
static std::string helpPreamble(int, const char **argv)
Returns the string that is printed before the list of command line parameters in the help message.
Definition: FlowGenericProblem_impl.hpp:111
std::vector< Scalar > overburdenPressure_
Definition: FlowGenericProblem.hpp:338
bool explicitRockCompaction_
Definition: FlowGenericProblem.hpp:352
typename FluidSystem::Scalar Scalar
Definition: FlowGenericProblem.hpp:63
Declare the properties used by the infrastructure code of the finite volume discretizations.
auto Get(bool errorIfNotRegistered=true)
Retrieve a runtime parameter.
Definition: parametersystem.hpp:185
Definition: blackoilboundaryratevector.hh:39
bool operator==(const aligned_allocator< T1, Alignment > &, const aligned_allocator< T2, Alignment > &) noexcept
Definition: alignedallocator.hh:200
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
This file provides the infrastructure to retrieve run-time parameters.
static MICPSolutionContainer serializationTestObject()
Definition: EclTimeSteppingParams.hpp:45
static PolymerSolutionContainer serializationTestObject()