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::ranges::transform(comp, std::back_inserter(rockParams_),
147 [](const auto& c)
148 {
149 return RockParams{
150 static_cast<Scalar>(c.pref),
151 static_cast<Scalar>(c.compressibility)
152 };
153 });
154 }
155
156 // Warn that ROCK and ROCKOPTS item 2 = STORE is used together
157 if (rock_config.store()) {
158 OpmLog::warning("ROCKOPTS item 2 set to STORE, ROCK item 1 replaced with initial (equilibrated) pressures");
159 }
160
161 // read the parameters for water-induced rock compaction
162 readRockCompactionParameters_();
163
164 unsigned numElem = gridView_.size(0);
165 if (eclState_.fieldProps().has_int(rock_config.rocknum_property())) {
166 // Auxiliary function to check rockTableIdx_ values belong to the right range. Otherwise, throws.
167 std::function<void(int, int)> valueCheck = [&ijkIndex,&rock_config,this](int fieldPropValue, int coarseElemIdx)
168 {
169 auto fmtError = [fieldPropValue, coarseElemIdx,&ijkIndex,&rock_config](const char* type, std::size_t size)
170 {
171 return fmt::format("{} table index {} for elem {} read from {}"
172 " is out of bounds for number of tables {}",
173 type, fieldPropValue,
174 ijkIndex(coarseElemIdx),
175 rock_config.rocknum_property(), size);
176 };
177 if (!rockCompPoroMult_.empty() &&
178 fieldPropValue > static_cast<int>(rockCompPoroMult_.size())) {
179 throw std::runtime_error(fmtError("Rock compaction",
180 rockCompPoroMult_.size()));
181 }
182 if (!rockCompPoroMultWc_.empty() &&
183 fieldPropValue > static_cast<int>(rockCompPoroMultWc_.size())) {
184 throw std::runtime_error(fmtError("Rock water compaction",
185 rockCompPoroMultWc_.size()));
186 }
187 };
189 rockTableIdx_ = this->lookUpData_.template assignFieldPropsIntOnLeaf<short unsigned int>(eclState_.fieldProps(),
190 rock_config.rocknum_property(),
191 true /*needsTranslation*/,
192 valueCheck);
193 }
195 // Store overburden pressure pr element
196 const auto& overburdTables = eclState_.getTableManager().getOverburdTables();
197 if (!overburdTables.empty() && !rock_config.store()) {
198 overburdenPressure_.resize(numElem,0.0);
199 std::size_t numRocktabTables = rock_config.num_rock_tables();
200
201 if (overburdTables.size() != numRocktabTables)
202 throw std::runtime_error(fmt::format("{} OVERBURD tables is expected, but {} is provided",
203 numRocktabTables, overburdTables.size()));
205 std::vector<Tabulated1DFunction<Scalar>> overburdenTables(numRocktabTables);
206 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
207 const OverburdTable& overburdTable = overburdTables.template getTable<OverburdTable>(regionIdx);
208 overburdenTables[regionIdx].setXYContainers(overburdTable.getDepthColumn(),overburdTable.getOverburdenPressureColumn());
210
211 for (std::size_t elemIdx = 0; elemIdx < numElem; ++ elemIdx) {
212 unsigned tableIdx = 0;
213 if (!rockTableIdx_.empty()) {
214 tableIdx = rockTableIdx_[elemIdx];
215 }
216 overburdenPressure_[elemIdx] =
217 overburdenTables[tableIdx].eval(cellCenterDepths[elemIdx], /*extrapolation=*/true);
218 }
220 else if (!overburdTables.empty() && rock_config.store()) {
221 OpmLog::warning("ROCKOPTS item 2 set to STORE, OVERBURD ignored!");
222 }
223}
225template<class GridView, class FluidSystem>
228{
229 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
230
231 if (!rock_config.active())
232 return; // deck does not enable rock compaction
233
234 unsigned numElem = gridView_.size(0);
235 switch (rock_config.hysteresis_mode()) {
236 case RockConfig::Hysteresis::REVERS:
237 break;
238 case RockConfig::Hysteresis::IRREVERS:
239 // interpolate the porv volume multiplier using the minimum pressure in the cell
240 // i.e. don't allow re-inflation.
241 minRefPressure_.resize(numElem, 1e99);
242 break;
243 default:
244 throw std::runtime_error("Not support ROCKOMP hysteresis option ");
245 }
246
247 std::size_t numRocktabTables = rock_config.num_rock_tables();
248 bool waterCompaction = rock_config.water_compaction();
249
250 if (!waterCompaction) {
251 const auto& rocktabTables = eclState_.getTableManager().getRocktabTables();
252 if (rocktabTables.size() != numRocktabTables)
253 throw std::runtime_error("ROCKCOMP is activated." + std::to_string(numRocktabTables)
254 +" ROCKTAB tables is expected, but " + std::to_string(rocktabTables.size()) +" is provided");
255
256 rockCompPoroMult_.resize(numRocktabTables);
257 rockCompTransMult_.resize(numRocktabTables);
258 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
259 const auto& rocktabTable = rocktabTables.template getTable<RocktabTable>(regionIdx);
260 const auto& pressureColumn = rocktabTable.getPressureColumn();
261 const auto& poroColumn = rocktabTable.getPoreVolumeMultiplierColumn();
262 const auto& transColumn = rocktabTable.getTransmissibilityMultiplierColumn();
263 rockCompPoroMult_[regionIdx].setXYContainers(pressureColumn, poroColumn);
264 rockCompTransMult_[regionIdx].setXYContainers(pressureColumn, transColumn);
265 }
266 } else {
267 const auto& rock2dTables = eclState_.getTableManager().getRock2dTables();
268 const auto& rock2dtrTables = eclState_.getTableManager().getRock2dtrTables();
269 const auto& rockwnodTables = eclState_.getTableManager().getRockwnodTables();
270 maxWaterSaturation_.resize(numElem, 0.0);
271
272 if (rock2dTables.size() != numRocktabTables)
273 throw std::runtime_error(fmt::format("Water compation option is selected in ROCKCOMP."
274 " {} ROCK2D tables is expected, but {} is provided",
275 numRocktabTables, rock2dTables.size()));
276
277 if (rockwnodTables.size() != numRocktabTables)
278 throw std::runtime_error(fmt::format("Water compation option is selected in ROCKCOMP."
279 " {} ROCKWNOD tables is expected, but {} is provided",
280 numRocktabTables, rockwnodTables.size()));
281 //TODO check size match
282 rockCompPoroMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
283 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
284 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
285 const auto& rock2dTable = rock2dTables[regionIdx];
286
287 if (rockwnodTable.getSaturationColumn().size() != rock2dTable.sizeMultValues())
288 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2D needs to match.");
290 for (std::size_t xIdx = 0; xIdx < rock2dTable.size(); ++xIdx) {
291 rockCompPoroMultWc_[regionIdx].appendXPos(rock2dTable.getPressureValue(xIdx));
292 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
293 rockCompPoroMultWc_[regionIdx].appendSamplePoint(xIdx,
294 rockwnodTable.getSaturationColumn()[yIdx],
295 rock2dTable.getPvmultValue(xIdx, yIdx));
296 }
297 }
298
299 if (!rock2dtrTables.empty()) {
300 rockCompTransMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
301 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
302 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
303 const auto& rock2dtrTable = rock2dtrTables[regionIdx];
304
305 if (rockwnodTable.getSaturationColumn().size() != rock2dtrTable.sizeMultValues())
306 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2DTR needs to match.");
307
308 for (std::size_t xIdx = 0; xIdx < rock2dtrTable.size(); ++xIdx) {
309 rockCompTransMultWc_[regionIdx].appendXPos(rock2dtrTable.getPressureValue(xIdx));
310 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
311 rockCompTransMultWc_[regionIdx].appendSamplePoint(xIdx,
312 rockwnodTable.getSaturationColumn()[yIdx],
313 rock2dtrTable.getTransMultValue(xIdx, yIdx));
314 }
315 }
317 }
319
320template<class GridView, class FluidSystem>
323rockCompressibility(unsigned globalSpaceIdx) const
324{
325 if (this->rockParams_.empty())
326 return 0.0;
328 unsigned tableIdx = 0;
329 if (!this->rockTableIdx_.empty()) {
330 tableIdx = this->rockTableIdx_[globalSpaceIdx];
331 }
332 return this->rockParams_[tableIdx].compressibility;
333}
334
335template<class GridView, class FluidSystem>
338porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
339{
340 return this->referencePorosity_[timeIdx][globalSpaceIdx];
341}
342
343template<class GridView, class FluidSystem>
346rockBiotComp(unsigned elementIdx) const
347{
348 // Additional compressibility of the rock due to Biot poroelasticity
349 auto biot = biotCoeff(elementIdx);
350 auto lameParam = lame(elementIdx);
351 return biot * biot / lameParam;
352}
353
354template<class GridView, class FluidSystem>
357lame(unsigned elementIdx) const
358{
359 Scalar lameParam;
360 const auto& fp = eclState_.fieldProps();
361 if (fp.has_double("LAME")) {
362 lameParam = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "LAME", elementIdx);
363 }
364 else if (fp.has_double("YMODULE") && fp.has_double("SMODULUS")) {
365 const auto& yModulus = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "YMODULE", elementIdx);
366 const auto& sModulus = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "SMODULUS", elementIdx);
367 lameParam = sModulus * (yModulus - 2 * sModulus) / (3 * sModulus - yModulus);
368 }
369 else if (fp.has_double("YMODULE") && fp.has_double("PRATIO")) {
370 const auto& yModulus = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "YMODULE", elementIdx);
371 const auto& pRatio = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "PRATIO", elementIdx);
372 lameParam = yModulus * pRatio / ((1 + pRatio) * (1 - 2 * pRatio));
373 }
374 else if (fp.has_double("SMODULUS") && fp.has_double("PRATIO")) {
375 const auto& sModulus = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "SMODULUS", elementIdx);
376 const auto& pRatio = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "PRATIO", elementIdx);
377 lameParam = 2 * sModulus * pRatio / (1 - 2 * pRatio);
378 }
379 else {
380 return 0.0;
381 }
382 return lameParam;
383}
384
385template<class GridView, class FluidSystem>
388biotCoeff(unsigned elementIdx) const
389{
390 Scalar biotC;
391 const auto& fp = eclState_.fieldProps();
392 if (fp.has_double("BIOTCOEF")) {
393 biotC = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "BIOTCOEF", elementIdx);
394 }
395 else if (fp.has_double("POELCOEF") && fp.has_double("PRATIO")) {
396 const auto& poelC = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "POELCOEF", elementIdx);
397 const auto& pRatio = this->lookUpData_.fieldPropDouble(this->eclState_.fieldProps(), "PRATIO", elementIdx);
398 biotC = poelC * (1 - pRatio) / (1 - 2 * pRatio);
399 }
400 else {
401 return 0.0;
402 }
403 return biotC;
404}
405
406
407template<class GridView, class FluidSystem>
408template<class T>
410updateNum(const std::string& name, std::vector<T>& numbers, std::size_t num_regions)
411{
412 if (!eclState_.fieldProps().has_int(name))
413 return;
414
415 std::function<void(T, int)> valueCheck = [num_regions,name](T fieldPropValue, [[maybe_unused]] int fieldPropIdx) {
416 if (fieldPropValue > static_cast<int>(num_regions)) {
417 throw std::runtime_error(fmt::format("Values larger than maximum number of regions {} provided in {}",
418 num_regions, name));
419 }
420 if (fieldPropValue <= 0) {
421 throw std::runtime_error("zero or negative values provided for region array: " + name);
422 }
423 };
424
425 numbers = this->lookUpData_.template assignFieldPropsIntOnLeaf<T>(eclState_.fieldProps(), name,
426 true /*needsTranslation*/, valueCheck);
427}
428
429template<class GridView, class FluidSystem>
432{
433 const auto num_regions = eclState_.getTableManager().getTabdims().getNumPVTTables();
434 updateNum("PVTNUM", pvtnum_, num_regions);
435}
436
437template<class GridView, class FluidSystem>
440{
441 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
442 updateNum("SATNUM", satnum_, num_regions);
443}
444
445template<class GridView, class FluidSystem>
448{
449 const auto num_regions = 1; // we only support single region
450 updateNum("MISCNUM", miscnum_, num_regions);
451}
452
453template<class GridView, class FluidSystem>
456{
457 const auto num_regions = 1; // we only support single region
458 updateNum("PLMIXNUM", plmixnum_, num_regions);
459}
460
461template<class GridView, class FluidSystem>
463vapparsActive(int episodeIdx) const
464{
465 const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
466 return (oilVaporizationControl.getType() == OilVaporizationProperties::OilVaporization::VAPPARS);
467}
468
469template<class GridView, class FluidSystem>
471beginEpisode_(bool enableExperiments,
472 int episodeIdx)
473{
474 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
475 // print some useful information in experimental mode. (the production
476 // simulator does this externally.)
477 std::ostringstream ss;
478 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
479 boost::posix_time::ptime curDateTime =
480 boost::posix_time::from_time_t(schedule_.simTime(episodeIdx));
481 ss.imbue(std::locale(std::locale::classic(), facet));
482 ss << "Report step " << episodeIdx + 1
483 << "/" << schedule_.size() - 1
484 << " at day " << schedule_.seconds(episodeIdx)/(24*3600)
485 << "/" << schedule_.seconds(schedule_.size() - 1)/(24*3600)
486 << ", date = " << curDateTime.date()
487 << "\n ";
488 OpmLog::info(ss.str());
489 }
490
491 const auto& events = schedule_[episodeIdx].events();
492
493 // react to TUNING changes
494 if (episodeIdx > 0 && enableTuning_ && events.hasEvent(ScheduleEvents::TUNING_CHANGE))
495 {
496 const auto& sched_state = schedule_[episodeIdx];
497 const auto& tuning = sched_state.tuning();
498 initialTimeStepSize_ = sched_state.max_next_tstep(enableTuning_);
499 maxTimeStepAfterWellEvent_ = tuning.TMAXWC;
500 return true;
501 }
502
503 return false;
504}
505
506template<class GridView, class FluidSystem>
508beginTimeStep_(bool enableExperiments,
509 int episodeIdx,
510 int timeStepIndex,
511 Scalar startTime,
512 Scalar time,
513 Scalar timeStepSize,
514 Scalar endTime)
515{
516 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
517 std::ostringstream ss;
518 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
519 boost::posix_time::ptime date = boost::posix_time::from_time_t(startTime) +
520 boost::posix_time::milliseconds(static_cast<long long>(time / prefix::milli));
521 ss.imbue(std::locale(std::locale::classic(), facet));
522 ss <<"\nTime step " << timeStepIndex << ", stepsize "
523 << unit::convert::to(timeStepSize, unit::day) << " days,"
524 << " at day " << (double)unit::convert::to(time, unit::day)
525 << "/" << (double)unit::convert::to(endTime, unit::day)
526 << ", date = " << date;
527 OpmLog::info(ss.str());
528 }
529}
530
531template<class GridView, class FluidSystem>
534{
535 FluidSystem::initFromState(eclState_, schedule_);
536}
537
538template<class GridView, class FluidSystem>
541 bool enableSolvent,
542 bool enablePolymer,
543 bool enablePolymerMolarWeight,
544 bool enableBioeffects,
545 bool enableMICP)
546{
547 auto getArray = [](const std::vector<double>& input)
548 {
549 if constexpr (std::is_same_v<Scalar,double>) {
550 return input;
551 } else {
552 return std::vector<Scalar>{input.begin(), input.end()};
553 }
554 };
555
556 if (enableSolvent) {
557 if (eclState_.fieldProps().has_double("SSOL")) {
558 solventSaturation_ = getArray(eclState_.fieldProps().get_double("SSOL"));
559 } else {
560 solventSaturation_.resize(numDof, 0.0);
561 }
562
563 solventRsw_.resize(numDof, 0.0);
564 }
565
566 if (enablePolymer) {
567 if (eclState_.fieldProps().has_double("SPOLY")) {
568 polymer_.concentration = getArray(eclState_.fieldProps().get_double("SPOLY"));
569 } else {
570 polymer_.concentration.resize(numDof, 0.0);
571 }
572 }
573
574 if (enablePolymerMolarWeight) {
575 if (eclState_.fieldProps().has_double("SPOLYMW")) {
576 polymer_.moleWeight = getArray(eclState_.fieldProps().get_double("SPOLYMW"));
577 } else {
578 polymer_.moleWeight.resize(numDof, 0.0);
579 }
580 }
581
582 if (enableBioeffects) {
583 if (eclState_.fieldProps().has_double("SMICR")) {
584 bioeffects_.microbialConcentration = getArray(eclState_.fieldProps().get_double("SMICR"));
585 } else {
586 bioeffects_.microbialConcentration.resize(numDof, 0.0);
587 }
588 if (eclState_.fieldProps().has_double("SBIOF")) {
589 bioeffects_.biofilmVolumeFraction = getArray(eclState_.fieldProps().get_double("SBIOF"));
590 } else {
591 bioeffects_.biofilmVolumeFraction.resize(numDof, 0.0);
592 }
593 if (enableMICP) {
594 if (eclState_.fieldProps().has_double("SOXYG")) {
595 bioeffects_.oxygenConcentration = getArray(eclState_.fieldProps().get_double("SOXYG"));
596 } else {
597 bioeffects_.oxygenConcentration.resize(numDof, 0.0);
598 }
599 if (eclState_.fieldProps().has_double("SUREA")) {
600 bioeffects_.ureaConcentration = getArray(eclState_.fieldProps().get_double("SUREA"));
601 } else {
602 bioeffects_.ureaConcentration.resize(numDof, 0.0);
603 }
604 if (eclState_.fieldProps().has_double("SCALC")) {
605 bioeffects_.calciteVolumeFraction = getArray(eclState_.fieldProps().get_double("SCALC"));
606 } else {
607 bioeffects_.calciteVolumeFraction.resize(numDof, 0.0);
608 }
609 }
610 }
611}
612
613template<class GridView, class FluidSystem>
616maxWaterSaturation(unsigned globalDofIdx) const
617{
618 if (maxWaterSaturation_.empty())
619 return 0.0;
620
621 return maxWaterSaturation_[globalDofIdx];
622}
623
624template<class GridView, class FluidSystem>
627minOilPressure(unsigned globalDofIdx) const
628{
629 if (minRefPressure_.empty())
630 return 0.0;
631
632 return minRefPressure_[globalDofIdx];
633}
634
635template<class GridView, class FluidSystem>
638overburdenPressure(unsigned elementIdx) const
639{
640 if (overburdenPressure_.empty())
641 return 0.0;
642
643 return overburdenPressure_[elementIdx];
644}
645
646template<class GridView, class FluidSystem>
649solventSaturation(unsigned elemIdx) const
650{
651 if (solventSaturation_.empty())
652 return 0;
653
654 return solventSaturation_[elemIdx];
655}
656
657template<class GridView, class FluidSystem>
660solventRsw(unsigned elemIdx) const
661{
662 if (solventRsw_.empty())
663 return 0;
664
665 return solventRsw_[elemIdx];
666}
667
668
669
670template<class GridView, class FluidSystem>
673polymerConcentration(unsigned elemIdx) const
674{
675 if (polymer_.concentration.empty()) {
676 return 0;
677 }
678
679 return polymer_.concentration[elemIdx];
680}
681
682template<class GridView, class FluidSystem>
685polymerMolecularWeight(const unsigned elemIdx) const
686{
687 if (polymer_.moleWeight.empty()) {
688 return 0.0;
689 }
690
691 return polymer_.moleWeight[elemIdx];
692}
693
694template<class GridView, class FluidSystem>
697microbialConcentration(unsigned elemIdx) const
698{
699 if (bioeffects_.microbialConcentration.empty()) {
700 return 0;
701 }
702
703 return bioeffects_.microbialConcentration[elemIdx];
704}
705
706template<class GridView, class FluidSystem>
709oxygenConcentration(unsigned elemIdx) const
710{
711 if (bioeffects_.oxygenConcentration.empty()) {
712 return 0;
713 }
714
715 return bioeffects_.oxygenConcentration[elemIdx];
716}
717
718template<class GridView, class FluidSystem>
721ureaConcentration(unsigned elemIdx) const
722{
723 if (bioeffects_.ureaConcentration.empty()) {
724 return 0;
725 }
726
727 return bioeffects_.ureaConcentration[elemIdx];
728}
729
730template<class GridView, class FluidSystem>
733biofilmVolumeFraction(unsigned elemIdx) const
734{
735 if (bioeffects_.biofilmVolumeFraction.empty()) {
736 return 0;
737 }
738
739 return bioeffects_.biofilmVolumeFraction[elemIdx];
740}
741
742template<class GridView, class FluidSystem>
745calciteVolumeFraction(unsigned elemIdx) const
746{
747 if (bioeffects_.calciteVolumeFraction.empty()) {
748 return 0;
749 }
750
751 return bioeffects_.calciteVolumeFraction[elemIdx];
752}
753
754template<class GridView, class FluidSystem>
756pvtRegionIndex(unsigned elemIdx) const
757{
758 if (pvtnum_.empty())
759 return 0;
760
761 return pvtnum_[elemIdx];
762}
763
764template<class GridView, class FluidSystem>
766satnumRegionIndex(unsigned elemIdx) const
767{
768 if (satnum_.empty())
769 return 0;
770
771 return satnum_[elemIdx];
772}
773
774template<class GridView, class FluidSystem>
776miscnumRegionIndex(unsigned elemIdx) const
777{
778 if (miscnum_.empty())
779 return 0;
780
781 return miscnum_[elemIdx];
782}
783
784template<class GridView, class FluidSystem>
786plmixnumRegionIndex(unsigned elemIdx) const
787{
788 if (plmixnum_.empty())
789 return 0;
790
791 return plmixnum_[elemIdx];
792}
793
794template<class GridView, class FluidSystem>
797maxPolymerAdsorption(unsigned elemIdx) const
798{
799 if (polymer_.maxAdsorption.empty()) {
800 return 0;
801 }
802
803 return polymer_.maxAdsorption[elemIdx];
804}
805
806template<class GridView, class FluidSystem>
808operator==(const FlowGenericProblem& rhs) const
809{
810 return this->maxWaterSaturation_ == rhs.maxWaterSaturation_ &&
811 this->minRefPressure_ == rhs.minRefPressure_ &&
812 this->overburdenPressure_ == rhs.overburdenPressure_ &&
813 this->solventSaturation_ == rhs.solventSaturation_ &&
814 this->solventRsw_ == rhs.solventRsw_ &&
815 this->polymer_ == rhs.polymer_ &&
816 this->bioeffects_ == rhs.bioeffects_;
817}
818
819} // namespace Opm
820
821#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 maxPolymerAdsorption(unsigned elemIdx) const
Returns the max polymer adsorption value.
Definition: FlowGenericProblem_impl.hpp:797
unsigned pvtRegionIndex(unsigned elemIdx) const
Returns the index the relevant PVT region given a cell index.
Definition: FlowGenericProblem_impl.hpp:756
Scalar oxygenConcentration(unsigned elemIdx) const
Returns the initial oxygen concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:709
Scalar microbialConcentration(unsigned elemIdx) const
Returns the initial microbial concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:697
PolymerSolutionContainer< Scalar > polymer_
Definition: FlowGenericProblem.hpp:353
static std::string briefDescription()
Returns a human readable description of the problem for the help message.
Definition: FlowGenericProblem_impl.hpp:130
Scalar solventRsw(unsigned elemIdx) const
Returns the initial solvent dissolved in water for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:660
Scalar overburdenPressure(unsigned elementIdx) const
Get the pressure of the overburden.
Definition: FlowGenericProblem_impl.hpp:638
void updateMiscnum_()
Definition: FlowGenericProblem_impl.hpp:447
Scalar porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
Direct indexed access to the porosity.
Definition: FlowGenericProblem_impl.hpp:338
Scalar rockCompressibility(unsigned globalSpaceIdx) const
Definition: FlowGenericProblem_impl.hpp:323
Scalar initialTimeStepSize_
Definition: FlowGenericProblem.hpp:365
unsigned miscnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant MISC region given a cell index.
Definition: FlowGenericProblem_impl.hpp:776
bool vapparsActive(int episodeIdx) const
Definition: FlowGenericProblem_impl.hpp:463
unsigned satnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant saturation function region given a cell index.
Definition: FlowGenericProblem_impl.hpp:766
Scalar maxWaterSaturation(unsigned globalDofIdx) const
Returns an element's historic maximum water phase saturation that was observed during the simulation.
Definition: FlowGenericProblem_impl.hpp:616
std::vector< Scalar > solventSaturation_
Definition: FlowGenericProblem.hpp:358
void readRockCompactionParameters_()
Definition: FlowGenericProblem_impl.hpp:227
void updateSatnum_()
Definition: FlowGenericProblem_impl.hpp:439
void updatePvtnum_()
Definition: FlowGenericProblem_impl.hpp:431
bool enableDriftCompensation_
Definition: FlowGenericProblem.hpp:371
Scalar lame(unsigned elementIdx) const
Direct access to Lame's second parameter in an element.
Definition: FlowGenericProblem_impl.hpp:357
static FlowGenericProblem serializationTestObject(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:94
void beginTimeStep_(bool enableExperiments, int episodeIdx, int timeStepIndex, Scalar startTime, Scalar time, Scalar timeStepSize, Scalar endTime)
Definition: FlowGenericProblem_impl.hpp:508
Scalar calciteVolumeFraction(unsigned elemIdx) const
Returns the initial calcite volume fraction for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:745
CO2H2SolutionContainer< Scalar > CO2H2_
Definition: FlowGenericProblem.hpp:361
unsigned plmixnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant PLMIXNUM (for polymer module) region given a cell index.
Definition: FlowGenericProblem_impl.hpp:786
FlowGenericProblem(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:60
BioeffectsSolutionContainer< Scalar > bioeffects_
Definition: FlowGenericProblem.hpp:360
bool enableTuning_
Definition: FlowGenericProblem.hpp:364
Scalar solventSaturation(unsigned elemIdx) const
Returns the initial solvent saturation for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:649
Scalar polymerMolecularWeight(const unsigned elemIdx) const
Returns the polymer molecule weight for a given cell index.
Definition: FlowGenericProblem_impl.hpp:685
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:354
Scalar rockBiotComp(unsigned elementIdx) const
Returns the rock compressibility of an element due to poroelasticity.
Definition: FlowGenericProblem_impl.hpp:346
int numPressurePointsEquil_
Definition: FlowGenericProblem.hpp:369
Scalar minOilPressure(unsigned globalDofIdx) const
Returns an element's historic minimum pressure of the oil phase that was observed during the simulati...
Definition: FlowGenericProblem_impl.hpp:627
std::vector< Scalar > maxWaterSaturation_
Definition: FlowGenericProblem.hpp:355
void initFluidSystem_()
Definition: FlowGenericProblem_impl.hpp:533
bool operator==(const FlowGenericProblem &rhs) const
Definition: FlowGenericProblem_impl.hpp:808
Scalar maxTimeStepAfterWellEvent_
Definition: FlowGenericProblem.hpp:366
Scalar ureaConcentration(unsigned elemIdx) const
Returns the initial urea concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:721
std::vector< Scalar > minRefPressure_
Definition: FlowGenericProblem.hpp:356
bool beginEpisode_(bool enableExperiments, int episodeIdx)
Definition: FlowGenericProblem_impl.hpp:471
Scalar biofilmVolumeFraction(unsigned elemIdx) const
Returns the initial biofilm volume fraction for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:733
std::vector< Scalar > solventRsw_
Definition: FlowGenericProblem.hpp:359
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:357
void readBlackoilExtentionsInitialConditions_(std::size_t numDof, bool enableSolvent, bool enablePolymer, bool enablePolymerMolarWeight, bool enableBioeffects, bool enableMICP)
Definition: FlowGenericProblem_impl.hpp:540
Scalar biotCoeff(unsigned elementIdx) const
Direct access to Biot coefficient in an element.
Definition: FlowGenericProblem_impl.hpp:388
void updatePlmixnum_()
Definition: FlowGenericProblem_impl.hpp:455
bool explicitRockCompaction_
Definition: FlowGenericProblem.hpp:373
typename FluidSystem::Scalar Scalar
Definition: FlowGenericProblem.hpp:63
Scalar polymerConcentration(unsigned elemIdx) const
Returns the initial polymer concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:673
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:45
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: FlowGenericProblem.hpp:67
Definition: EclTimeSteppingParams.hpp:45
static PolymerSolutionContainer serializationTestObject()