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