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 // 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
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");
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 }
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.");
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 }
314template<class GridView, class FluidSystem>
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>
332porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
333{
334 return this->referencePorosity_[timeIdx][globalSpaceIdx];
335}
336
337template<class GridView, class FluidSystem>
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>
375{
376 const auto num_regions = eclState_.getTableManager().getTabdims().getNumPVTTables();
377 updateNum("PVTNUM", pvtnum_, num_regions);
378}
379
380template<class GridView, class FluidSystem>
383{
384 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
385 updateNum("SATNUM", satnum_, num_regions);
386}
387
388template<class GridView, class FluidSystem>
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>
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>
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>
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>
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>
476{
477 FluidSystem::initFromState(eclState_, schedule_);
478}
479
480template<class GridView, class FluidSystem>
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>
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>
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>
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>
591solventSaturation(unsigned elemIdx) const
592{
593 if (solventSaturation_.empty())
594 return 0;
595
596 return solventSaturation_[elemIdx];
597}
598
599template<class GridView, class FluidSystem>
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>
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>
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>
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>
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>
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>
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>
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>
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
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:651
Scalar microbialConcentration(unsigned elemIdx) const
Returns the initial microbial concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:639
PolymerSolutionContainer< Scalar > polymer_
Definition: FlowGenericProblem.hpp:335
static std::string briefDescription()
Returns a human readable description of the problem for the help message.
Definition: FlowGenericProblem_impl.hpp:129
Scalar initialTimeStepSize_
Definition: FlowGenericProblem.hpp:346
std::vector< Scalar > solventSaturation_
Definition: FlowGenericProblem.hpp:340
bool enableDriftCompensation_
Definition: FlowGenericProblem.hpp:352
static FlowGenericProblem serializationTestObject(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:94
Scalar calciteVolumeFraction(unsigned elemIdx) const
Returns the initial calcite volume fraction for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:687
FlowGenericProblem(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:60
BioeffectsSolutionContainer< Scalar > bioeffects_
Definition: FlowGenericProblem.hpp:342
bool enableTuning_
Definition: FlowGenericProblem.hpp:345
void readRockParameters_(const std::vector< Scalar > &cellCenterDepths, std::function< std::array< int, 3 >(const unsigned)> ijkIndex)
Definition: FlowGenericProblem_impl.hpp:136
std::vector< Scalar > maxOilSaturation_
Definition: FlowGenericProblem.hpp:336
int numPressurePointsEquil_
Definition: FlowGenericProblem.hpp:350
std::vector< Scalar > maxWaterSaturation_
Definition: FlowGenericProblem.hpp:337
void initFluidSystem_()
Definition: FlowGenericProblem_impl.hpp:475
Scalar maxTimeStepAfterWellEvent_
Definition: FlowGenericProblem.hpp:347
Scalar ureaConcentration(unsigned elemIdx) const
Returns the initial urea concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:663
std::vector< Scalar > minRefPressure_
Definition: FlowGenericProblem.hpp:338
Scalar biofilmVolumeFraction(unsigned elemIdx) const
Returns the initial biofilm volume fraction for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:675
std::vector< Scalar > solventRsw_
Definition: FlowGenericProblem.hpp:341
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:114
std::vector< Scalar > overburdenPressure_
Definition: FlowGenericProblem.hpp:339
bool explicitRockCompaction_
Definition: FlowGenericProblem.hpp:353
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:187
Definition: blackoilbioeffectsmodules.hh:43
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 BioeffectsSolutionContainer serializationTestObject()
Definition: EclTimeSteppingParams.hpp:45
static PolymerSolutionContainer serializationTestObject()