27 #error "The opm-parser module is required to use the ECL material manager!"
30 #ifndef OPM_ECL_MATERIAL_LAW_MANAGER_HPP
31 #define OPM_ECL_MATERIAL_LAW_MANAGER_HPP
44 #include <opm/common/Exceptions.hpp>
45 #include <opm/common/ErrorMacros.hpp>
47 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
48 #include <opm/parser/eclipse/Deck/Deck.hpp>
61 template <
class TraitsT>
65 typedef TraitsT Traits;
66 typedef typename Traits::Scalar Scalar;
67 enum { waterPhaseIdx = Traits::wettingPhaseIdx };
68 enum { oilPhaseIdx = Traits::nonWettingPhaseIdx };
69 enum { gasPhaseIdx = Traits::gasPhaseIdx };
70 enum { numPhases = Traits::numPhases };
100 typedef std::vector<std::shared_ptr<GasOilEffectiveTwoPhaseParams> > GasOilEffectiveParamVector;
101 typedef std::vector<std::shared_ptr<OilWaterEffectiveTwoPhaseParams> > OilWaterEffectiveParamVector;
102 typedef std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar> > > GasOilScalingPointsVector;
103 typedef std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar> > > OilWaterScalingPointsVector;
104 typedef std::vector<std::shared_ptr<EclEpsScalingPointsInfo<Scalar> > > GasOilScalingInfoVector;
105 typedef std::vector<std::shared_ptr<EclEpsScalingPointsInfo<Scalar> > > OilWaterScalingInfoVector;
106 typedef std::vector<std::shared_ptr<GasOilTwoPhaseHystParams> > GasOilParamVector;
107 typedef std::vector<std::shared_ptr<OilWaterTwoPhaseHystParams> > OilWaterParamVector;
108 typedef std::vector<std::shared_ptr<MaterialLawParams> > MaterialLawParamsVector;
115 Opm::EclipseStateConstPtr eclState,
116 const std::vector<int>& compressedToCartesianElemIdx)
119 unsigned numSatRegions =
static_cast<unsigned>(deck->getKeyword(
"TABDIMS")->getRecord(0)->getItem(
"NTSFUN")->getInt(0));
120 size_t numCompressedElems = compressedToCartesianElemIdx.size();
124 std::vector<int> satnumRegionArray(numCompressedElems);
125 if (eclState->hasIntGridProperty(
"SATNUM")) {
126 const auto& satnumRawData = eclState->getIntGridProperty(
"SATNUM")->getData();
127 for (
unsigned elemIdx = 0; elemIdx < numCompressedElems; ++elemIdx) {
128 unsigned cartesianElemIdx =
static_cast<unsigned>(compressedToCartesianElemIdx[elemIdx]);
129 satnumRegionArray[elemIdx] = satnumRawData[cartesianElemIdx] - 1;
133 std::fill(satnumRegionArray.begin(), satnumRegionArray.end(), 0);
135 readGlobalEpsOptions_(deck, eclState);
136 readGlobalHysteresisOptions_(deck);
137 readGlobalThreePhaseOptions_(deck);
139 unscaledEpsInfo_.resize(numSatRegions);
140 for (
unsigned satnumIdx = 0; satnumIdx < numSatRegions; ++satnumIdx)
141 unscaledEpsInfo_[satnumIdx].extractUnscaled(deck, eclState, satnumIdx);
143 initParamsForElements_(deck, eclState, compressedToCartesianElemIdx, satnumRegionArray);
158 auto& elemScaledEpsInfo = *oilWaterScaledEpsInfoDrainage_[elemIdx];
161 if (Sw <= elemScaledEpsInfo.Swl)
162 Sw = elemScaledEpsInfo.Swl;
164 Sw = elemScaledEpsInfo.Swu;
180 fs.setSaturation(waterPhaseIdx, Sw);
181 fs.setSaturation(gasPhaseIdx, 0);
182 fs.setSaturation(oilPhaseIdx, 0);
183 Scalar pc[numPhases];
186 Scalar pcowAtSw = pc[oilPhaseIdx] - pc[waterPhaseIdx];
187 if (pcowAtSw > 0.0) {
188 elemScaledEpsInfo.maxPcow *= pcow/pcowAtSw;
189 auto& elemEclEpsScalingPoints = getOilWaterScaledEpsPointsDrainage_(elemIdx);
198 {
return enableEndPointScaling_; }
201 {
return hysteresisConfig_->enableHysteresis(); }
205 assert(0 <= elemIdx && elemIdx < materialLawParams_.size());
206 return *materialLawParams_[elemIdx];
211 assert(0 <= elemIdx && elemIdx < (
int) materialLawParams_.size());
212 return *materialLawParams_[elemIdx];
215 template <
class Flu
idState>
221 auto threePhaseParams = materialLawParams_[elemIdx];
222 MaterialLaw::updateHysteresis(*threePhaseParams, fluidState);
227 return *oilWaterScaledEpsInfoDrainage_[elemIdx];
231 void readGlobalEpsOptions_(Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclState)
233 oilWaterEclEpsConfig_ = std::make_shared<Opm::EclEpsConfig>();
236 enableEndPointScaling_ = deck->hasKeyword(
"ENDSCALE");
240 Opm::DeckKeywordConstPtr endscaleKeyword = deck->getKeyword(
"ENDSCALE");
241 Opm::DeckRecordConstPtr endscaleRecord = endscaleKeyword->getRecord(0);
242 for (
unsigned itemIdx = 0; itemIdx < endscaleRecord->size() && itemIdx < 2; ++ itemIdx) {
243 std::string optionValue = endscaleRecord->getItem(itemIdx)->getTrimmedString(0);
246 std::transform(optionValue.begin(),
251 if (optionValue ==
"DIRECT") {
252 OPM_THROW(std::runtime_error,
253 "Directional end-point scaling (indicated by the 'DIRECT' option"
254 " of the 'ENDSCALE' keyword) is not yet supported");
256 if (optionValue ==
"IRREVERS") {
257 OPM_THROW(std::runtime_error,
258 "Irreversible end-point scaling (indicated by the 'IRREVERS' option"
259 " of the 'ENDSCALE' keyword) is not yet supported");
265 void readGlobalHysteresisOptions_(Opm::DeckConstPtr deck)
267 hysteresisConfig_ = std::make_shared<Opm::EclHysteresisConfig>();
268 hysteresisConfig_->initFromDeck(deck);
271 void readGlobalThreePhaseOptions_(Opm::DeckConstPtr deck)
273 bool gasEnabled = deck->hasKeyword(
"GAS");
274 bool oilEnabled = deck->hasKeyword(
"OIL");
275 bool waterEnabled = deck->hasKeyword(
"WATER");
280 + (waterEnabled?1:0);
283 OPM_THROW(std::runtime_error,
284 "At least two fluid phases must be enabled. (Is: " << numEnabled <<
")");
286 if (numEnabled == 2) {
290 else if (!oilEnabled)
292 else if (!waterEnabled)
296 assert(numEnabled == 3);
299 if (deck->hasKeyword(
"STONE") || deck->hasKeyword(
"STONE2"))
301 else if (deck->hasKeyword(
"STONE1"))
306 void initParamsForElements_(DeckConstPtr deck, EclipseStateConstPtr eclState,
307 const std::vector<int>& compressedToCartesianElemIdx,
308 const std::vector<int>& satnumRegionArray)
310 unsigned numSatRegions =
static_cast<unsigned>(deck->getKeyword(
"TABDIMS")->getRecord(0)->getItem(
"NTSFUN")->getInt(0));
311 unsigned numCompressedElems =
static_cast<unsigned>(compressedToCartesianElemIdx.size());
315 auto gasOilConfig = std::make_shared<Opm::EclEpsConfig>();
316 auto oilWaterConfig = std::make_shared<Opm::EclEpsConfig>();
321 GasOilScalingPointsVector gasOilUnscaledPointsVector(numSatRegions);
322 OilWaterScalingPointsVector oilWaterUnscaledPointsVector(numSatRegions);
323 GasOilEffectiveParamVector gasOilEffectiveParamVector(numSatRegions);
324 OilWaterEffectiveParamVector oilWaterEffectiveParamVector(numSatRegions);
325 for (
unsigned satnumIdx = 0; satnumIdx < numSatRegions; ++satnumIdx) {
327 readGasOilUnscaledPoints_(gasOilUnscaledPointsVector, gasOilConfig, deck, eclState, satnumIdx);
328 readOilWaterUnscaledPoints_(oilWaterUnscaledPointsVector, oilWaterConfig, deck, eclState, satnumIdx);
331 readGasOilEffectiveParameters_(gasOilEffectiveParamVector, deck, eclState, satnumIdx);
332 readOilWaterEffectiveParameters_(oilWaterEffectiveParamVector, deck, eclState, satnumIdx);
335 unscaledEpsInfo_[satnumIdx].extractUnscaled(deck, eclState, satnumIdx);
341 GasOilScalingInfoVector gasOilScaledInfoVector(numCompressedElems);
342 oilWaterScaledEpsInfoDrainage_.resize(numCompressedElems);
343 GasOilScalingInfoVector gasOilScaledImbInfoVector;
344 OilWaterScalingInfoVector oilWaterScaledImbInfoVector;
346 GasOilScalingPointsVector gasOilScaledPointsVector(numCompressedElems);
347 GasOilScalingPointsVector oilWaterScaledEpsPointsDrainage(numCompressedElems);
348 GasOilScalingPointsVector gasOilScaledImbPointsVector;
349 OilWaterScalingPointsVector oilWaterScaledImbPointsVector;
352 gasOilScaledImbInfoVector.resize(numCompressedElems);
353 gasOilScaledImbPointsVector.resize(numCompressedElems);
354 oilWaterScaledImbInfoVector.resize(numCompressedElems);
355 oilWaterScaledImbPointsVector.resize(numCompressedElems);
358 EclEpsGridProperties epsGridProperties, epsImbGridProperties;
359 epsGridProperties.initFromDeck(deck, eclState,
false);
361 epsImbGridProperties.initFromDeck(deck, eclState,
true);
362 for (
unsigned elemIdx = 0; elemIdx < numCompressedElems; ++elemIdx) {
363 unsigned cartElemIdx =
static_cast<unsigned>(compressedToCartesianElemIdx[elemIdx]);
364 readGasOilScaledPoints_(gasOilScaledInfoVector,
365 gasOilScaledPointsVector,
370 readOilWaterScaledPoints_(oilWaterScaledEpsInfoDrainage_,
371 oilWaterScaledEpsPointsDrainage,
378 readGasOilScaledPoints_(gasOilScaledImbInfoVector,
379 gasOilScaledImbPointsVector,
381 epsImbGridProperties,
384 readOilWaterScaledPoints_(oilWaterScaledImbInfoVector,
385 oilWaterScaledImbPointsVector,
387 epsImbGridProperties,
394 GasOilParamVector gasOilParams(numCompressedElems);
395 OilWaterParamVector oilWaterParams(numCompressedElems);
396 GasOilParamVector gasOilImbParams;
397 OilWaterParamVector oilWaterImbParams;
400 gasOilImbParams.resize(numCompressedElems);
401 oilWaterImbParams.resize(numCompressedElems);
404 const auto& imbnumData = eclState->getIntGridProperty(
"IMBNUM")->getData();
405 assert(numCompressedElems == satnumRegionArray.size());
406 for (
unsigned elemIdx = 0; elemIdx < numCompressedElems; ++elemIdx) {
407 unsigned satnumIdx =
static_cast<unsigned>(satnumRegionArray[elemIdx]);
409 gasOilParams[elemIdx] = std::make_shared<GasOilTwoPhaseHystParams>();
410 oilWaterParams[elemIdx] = std::make_shared<OilWaterTwoPhaseHystParams>();
412 gasOilParams[elemIdx]->setConfig(hysteresisConfig_);
413 oilWaterParams[elemIdx]->setConfig(hysteresisConfig_);
415 auto gasOilDrainParams = std::make_shared<GasOilEpsTwoPhaseParams>();
416 gasOilDrainParams->setConfig(gasOilConfig);
417 gasOilDrainParams->setUnscaledPoints(gasOilUnscaledPointsVector[satnumIdx]);
418 gasOilDrainParams->setScaledPoints(gasOilScaledPointsVector[elemIdx]);
419 gasOilDrainParams->setEffectiveLawParams(gasOilEffectiveParamVector[satnumIdx]);
420 gasOilDrainParams->finalize();
422 auto oilWaterDrainParams = std::make_shared<OilWaterEpsTwoPhaseParams>();
423 oilWaterDrainParams->setConfig(oilWaterConfig);
424 oilWaterDrainParams->setUnscaledPoints(oilWaterUnscaledPointsVector[satnumIdx]);
425 oilWaterDrainParams->setScaledPoints(oilWaterScaledEpsPointsDrainage[elemIdx]);
426 oilWaterDrainParams->setEffectiveLawParams(oilWaterEffectiveParamVector[satnumIdx]);
427 oilWaterDrainParams->finalize();
429 gasOilParams[elemIdx]->setDrainageParams(gasOilDrainParams,
430 *gasOilScaledInfoVector[elemIdx],
432 oilWaterParams[elemIdx]->setDrainageParams(oilWaterDrainParams,
433 *oilWaterScaledEpsInfoDrainage_[elemIdx],
437 unsigned imbRegionIdx =
static_cast<unsigned>(imbnumData[elemIdx]) - 1;
439 auto gasOilImbParamsHyst = std::make_shared<GasOilEpsTwoPhaseParams>();
440 gasOilImbParamsHyst->setConfig(gasOilConfig);
441 gasOilImbParamsHyst->setUnscaledPoints(gasOilUnscaledPointsVector[imbRegionIdx]);
442 gasOilImbParamsHyst->setScaledPoints(gasOilScaledImbPointsVector[elemIdx]);
443 gasOilImbParamsHyst->setEffectiveLawParams(gasOilEffectiveParamVector[imbRegionIdx]);
444 gasOilImbParamsHyst->finalize();
446 auto oilWaterImbParamsHyst = std::make_shared<OilWaterEpsTwoPhaseParams>();
447 oilWaterImbParamsHyst->setConfig(oilWaterConfig);
448 oilWaterImbParamsHyst->setUnscaledPoints(oilWaterUnscaledPointsVector[imbRegionIdx]);
449 oilWaterImbParamsHyst->setScaledPoints(oilWaterScaledImbPointsVector[elemIdx]);
450 oilWaterImbParamsHyst->setEffectiveLawParams(oilWaterEffectiveParamVector[imbRegionIdx]);
451 oilWaterImbParamsHyst->finalize();
453 gasOilParams[elemIdx]->setImbibitionParams(gasOilImbParamsHyst,
454 *gasOilScaledImbInfoVector[elemIdx],
456 oilWaterParams[elemIdx]->setImbibitionParams(oilWaterImbParamsHyst,
457 *gasOilScaledImbInfoVector[elemIdx],
461 gasOilParams[elemIdx]->finalize();
462 oilWaterParams[elemIdx]->finalize();
466 materialLawParams_.resize(numCompressedElems);
467 for (
unsigned elemIdx = 0; elemIdx < numCompressedElems; ++elemIdx) {
468 materialLawParams_[elemIdx] = std::make_shared<MaterialLawParams>();
469 unsigned satnumIdx =
static_cast<unsigned>(satnumRegionArray[elemIdx]);
471 initThreePhaseParams_(deck,
473 *materialLawParams_[elemIdx],
475 *oilWaterScaledEpsInfoDrainage_[elemIdx],
476 oilWaterParams[elemIdx],
477 gasOilParams[elemIdx]);
479 materialLawParams_[elemIdx]->finalize();
487 enum SaturationFunctionFamily {
493 SaturationFunctionFamily getSaturationFunctionFamily(Opm::EclipseStateConstPtr eclState)
const
495 const auto& tableManager = eclState->getTableManager();
496 const TableContainer& swofTables = tableManager->getSwofTables();
497 const TableContainer& slgofTables= tableManager->getSlgofTables();
498 const TableContainer& sgofTables = tableManager->getSgofTables();
499 const TableContainer& swfnTables = tableManager->getSwfnTables();
500 const TableContainer& sgfnTables = tableManager->getSgfnTables();
501 const TableContainer& sof3Tables = tableManager->getSof3Tables();
503 bool family1 = (!sgofTables.empty() || !slgofTables.empty()) && !swofTables.empty();
504 bool family2 = !swfnTables.empty() && !sgfnTables.empty() && !sof3Tables.empty();
506 if (family1 && family2) {
507 throw std::invalid_argument(
"Saturation families should not be mixed \n"
508 "Use either SGOF and SWOF or SGFN, SWFN and SOF3");
511 if (!family1 && !family2) {
512 throw std::invalid_argument(
"Saturations function must be specified using either "
513 "family 1 or family 2 keywords \n"
514 "Use either SGOF and SWOF or SGFN, SWFN and SOF3" );
517 if (family1 && !family2)
518 return SaturationFunctionFamily::FamilyI;
519 else if (family2 && !family1)
520 return SaturationFunctionFamily::FamilyII;
521 return SaturationFunctionFamily::noFamily;
524 template <
class Container>
525 void readGasOilEffectiveParameters_(Container& dest,
526 Opm::DeckConstPtr deck,
527 Opm::EclipseStateConstPtr eclState,
530 dest[satnumIdx] = std::make_shared<GasOilEffectiveTwoPhaseParams>();
532 bool hasWater = deck->hasKeyword(
"WATER");
533 bool hasGas = deck->hasKeyword(
"GAS");
534 bool hasOil = deck->hasKeyword(
"OIL");
536 auto& effParams = *dest[satnumIdx];
540 Scalar Swco = unscaledEpsInfo_[satnumIdx].Swl;
543 const auto& tableManager = eclState->getTableManager();
545 const TableContainer& sgofTables = tableManager->getSgofTables();
546 const TableContainer& slgofTables = tableManager->getSlgofTables();
547 if (!sgofTables.empty())
548 readGasOilEffectiveParametersSgof_(effParams,
550 sgofTables.getTable<SgofTable>(satnumIdx));
552 assert(!slgofTables.empty());
553 readGasOilEffectiveParametersSlgof_(effParams,
555 slgofTables.getTable<SlgofTable>(satnumIdx));
567 if (!hasWater || !hasGas || !hasOil)
568 throw std::domain_error(
"The specified phase configuration is not suppored");
570 switch (getSaturationFunctionFamily(eclState)) {
573 const TableContainer& sgofTables = tableManager->getSgofTables();
574 const TableContainer& slgofTables = tableManager->getSlgofTables();
575 if (!sgofTables.empty())
576 readGasOilEffectiveParametersSgof_(effParams,
578 sgofTables.getTable<SgofTable>(satnumIdx));
579 else if (!slgofTables.empty())
580 readGasOilEffectiveParametersSlgof_(effParams,
582 slgofTables.getTable<SlgofTable>(satnumIdx));
588 const Sof3Table& sof3Table = tableManager->getSof3Tables().getTable<Sof3Table>( satnumIdx );
589 const SgfnTable& sgfnTable = tableManager->getSgfnTables().getTable<SgfnTable>( satnumIdx );
590 readGasOilEffectiveParametersFamily2_(effParams,
599 throw std::domain_error(
"No valid saturation keyword family specified");
604 void readGasOilEffectiveParametersSgof_(GasOilEffectiveTwoPhaseParams& effParams,
606 const Opm::SgofTable& sgofTable)
609 std::vector<double> SoSamples(sgofTable.numRows());
610 std::vector<double> SoKroSamples(sgofTable.numRows());
611 for (
size_t sampleIdx = 0; sampleIdx < sgofTable.numRows(); ++ sampleIdx) {
612 SoSamples[sampleIdx] = 1 - sgofTable.getSgColumn()[sampleIdx];
613 SoKroSamples[sampleIdx] = SoSamples[sampleIdx] - Swco;
616 effParams.setKrwSamples(SoKroSamples, sgofTable.getKrogColumn());
617 effParams.setKrnSamples(SoSamples, sgofTable.getKrgColumn());
618 effParams.setPcnwSamples(SoSamples, sgofTable.getPcogColumn());
619 effParams.finalize();
622 void readGasOilEffectiveParametersSlgof_(GasOilEffectiveTwoPhaseParams& effParams,
624 const Opm::SlgofTable& slgofTable)
627 std::vector<double> SoSamples(slgofTable.numRows());
628 std::vector<double> SoKroSamples(slgofTable.numRows());
629 for (
size_t sampleIdx = 0; sampleIdx < slgofTable.numRows(); ++ sampleIdx) {
630 SoSamples[sampleIdx] = slgofTable.getSlColumn()[sampleIdx];
631 SoKroSamples[sampleIdx] = slgofTable.getSlColumn()[sampleIdx] - Swco;
634 effParams.setKrwSamples(SoKroSamples, slgofTable.getKrogColumn());
635 effParams.setKrnSamples(SoSamples, slgofTable.getKrgColumn());
636 effParams.setPcnwSamples(SoSamples, slgofTable.getPcogColumn());
637 effParams.finalize();
640 void readGasOilEffectiveParametersFamily2_(GasOilEffectiveTwoPhaseParams& effParams,
642 const Opm::Sof3Table& sof3Table,
643 const Opm::SgfnTable& sgfnTable)
646 std::vector<double> SoSamples(sgfnTable.numRows());
647 const auto &SoColumn = sof3Table.getSoColumn();
648 for (
size_t sampleIdx = 0; sampleIdx < sgfnTable.numRows(); ++ sampleIdx) {
649 SoSamples[sampleIdx] = 1 - sgfnTable.getSgColumn()[sampleIdx];
652 effParams.setKrwSamples(SoColumn, sof3Table.getKrogColumn());
653 effParams.setKrnSamples(SoSamples, sgfnTable.getKrgColumn());
654 effParams.setPcnwSamples(SoSamples, sgfnTable.getPcogColumn());
655 effParams.finalize();
658 template <
class Container>
659 void readOilWaterEffectiveParameters_(Container& dest,
660 Opm::DeckConstPtr deck,
661 Opm::EclipseStateConstPtr eclState,
664 dest[satnumIdx] = std::make_shared<OilWaterEffectiveTwoPhaseParams>();
666 bool hasWater = deck->hasKeyword(
"WATER");
667 bool hasGas = deck->hasKeyword(
"GAS");
668 bool hasOil = deck->hasKeyword(
"OIL");
670 const auto tableManager = eclState->getTableManager();
671 auto& effParams = *dest[satnumIdx];
678 const auto& swofTable = tableManager->getSwofTables().getTable<SwofTable>(satnumIdx);
679 const auto &SwColumn = swofTable.getSwColumn();
681 effParams.setKrwSamples(SwColumn, swofTable.getKrwColumn());
682 effParams.setKrnSamples(SwColumn, swofTable.getKrowColumn());
683 effParams.setPcnwSamples(SwColumn, swofTable.getPcowColumn());
684 effParams.finalize();
692 if (!hasWater || !hasGas || !hasOil)
693 throw std::domain_error(
"The specified phase configuration is not suppored");
695 switch (getSaturationFunctionFamily(eclState)) {
697 const auto& swofTable = tableManager->getSwofTables().getTable<SwofTable>(satnumIdx);
698 const auto &SwColumn = swofTable.getSwColumn();
700 effParams.setKrwSamples(SwColumn, swofTable.getKrwColumn());
701 effParams.setKrnSamples(SwColumn, swofTable.getKrowColumn());
702 effParams.setPcnwSamples(SwColumn, swofTable.getPcowColumn());
703 effParams.finalize();
708 const auto& swfnTable = tableManager->getSwfnTables().getTable<SwfnTable>(satnumIdx);
709 const auto& sof3Table = tableManager->getSof3Tables().getTable<Sof3Table>(satnumIdx);
710 const auto &SwColumn = swfnTable.getSwColumn();
713 std::vector<double> SwSamples(sof3Table.numRows());
714 for (
size_t sampleIdx = 0; sampleIdx < sof3Table.numRows(); ++ sampleIdx)
715 SwSamples[sampleIdx] = 1 - sof3Table.getSoColumn()[sampleIdx];
717 effParams.setKrwSamples(SwColumn, swfnTable.getKrwColumn());
718 effParams.setKrnSamples(SwSamples, sof3Table.getKrowColumn());
719 effParams.setPcnwSamples(SwColumn, swfnTable.getPcowColumn());
720 effParams.finalize();
726 throw std::domain_error(
"No valid saturation keyword family specified");
732 template <
class Container>
733 void readGasOilUnscaledPoints_(Container &dest,
734 std::shared_ptr<EclEpsConfig> config,
736 Opm::EclipseStateConstPtr ,
739 dest[satnumIdx] = std::make_shared<EclEpsScalingPoints<Scalar> >();
740 dest[satnumIdx]->init(unscaledEpsInfo_[satnumIdx], *config,
EclGasOilSystem);
743 template <
class Container>
744 void readOilWaterUnscaledPoints_(Container &dest,
745 std::shared_ptr<EclEpsConfig> config,
747 Opm::EclipseStateConstPtr ,
750 dest[satnumIdx] = std::make_shared<EclEpsScalingPoints<Scalar> >();
754 template <
class InfoContainer,
class Po
intsContainer>
755 void readGasOilScaledPoints_(InfoContainer& destInfo,
756 PointsContainer& destPoints,
757 std::shared_ptr<EclEpsConfig> config,
758 const EclEpsGridProperties& epsGridProperties,
760 unsigned cartElemIdx)
762 unsigned satnumIdx =
static_cast<unsigned>((*epsGridProperties.satnum)[cartElemIdx]) - 1;
764 destInfo[elemIdx] = std::make_shared<EclEpsScalingPointsInfo<Scalar> >(unscaledEpsInfo_[satnumIdx]);
765 destInfo[elemIdx]->extractScaled(epsGridProperties, cartElemIdx);
767 destPoints[elemIdx] = std::make_shared<EclEpsScalingPoints<Scalar> >();
768 destPoints[elemIdx]->init(*destInfo[elemIdx], *config,
EclGasOilSystem);
771 template <
class InfoContainer,
class Po
intsContainer>
772 void readOilWaterScaledPoints_(InfoContainer& destInfo,
773 PointsContainer& destPoints,
774 std::shared_ptr<EclEpsConfig> config,
775 const EclEpsGridProperties& epsGridProperties,
777 unsigned cartElemIdx)
779 unsigned satnumIdx =
static_cast<unsigned>((*epsGridProperties.satnum)[cartElemIdx]) - 1;
781 destInfo[elemIdx] = std::make_shared<EclEpsScalingPointsInfo<Scalar> >(unscaledEpsInfo_[satnumIdx]);
782 destInfo[elemIdx]->extractScaled(epsGridProperties, cartElemIdx);
784 destPoints[elemIdx] = std::make_shared<EclEpsScalingPoints<Scalar> >();
788 void initThreePhaseParams_(Opm::DeckConstPtr deck,
789 Opm::EclipseStateConstPtr ,
790 MaterialLawParams& materialParams,
792 const EclEpsScalingPointsInfo<Scalar>& epsInfo,
793 std::shared_ptr<OilWaterTwoPhaseHystParams> oilWaterParams,
794 std::shared_ptr<GasOilTwoPhaseHystParams> gasOilParams)
796 materialParams.setApproach(threePhaseApproach_);
798 switch (materialParams.approach()) {
800 auto& realParams = materialParams.template getRealParams<Opm::EclStone1Approach>();
801 realParams.setGasOilParams(gasOilParams);
802 realParams.setOilWaterParams(oilWaterParams);
803 realParams.setSwl(epsInfo.Swl);
804 realParams.setSowcr(epsInfo.Sowcr);
806 if (deck->hasKeyword(
"STONE1EX")) {
808 deck->getKeyword(
"STONE1EX")->getRecord(satnumIdx)->getItem(0)->getSIDouble(0);
809 realParams.setSogcr(eta);
812 realParams.setSogcr(1.0);
813 realParams.finalize();
818 auto& realParams = materialParams.template getRealParams<Opm::EclStone2Approach>();
819 realParams.setGasOilParams(gasOilParams);
820 realParams.setOilWaterParams(oilWaterParams);
821 realParams.setSwl(epsInfo.Swl);
822 realParams.finalize();
827 auto& realParams = materialParams.template getRealParams<Opm::EclDefaultApproach>();
828 realParams.setGasOilParams(gasOilParams);
829 realParams.setOilWaterParams(oilWaterParams);
830 realParams.setSwl(epsInfo.Swl);
831 realParams.finalize();
836 auto& realParams = materialParams.template getRealParams<Opm::EclTwoPhaseApproach>();
837 realParams.setGasOilParams(gasOilParams);
838 realParams.setOilWaterParams(oilWaterParams);
839 realParams.setApproach(twoPhaseApproach_);
840 realParams.finalize();
846 EclEpsScalingPoints<Scalar>& getOilWaterScaledEpsPointsDrainage_(
unsigned elemIdx)
848 auto& materialParams = *materialLawParams_[elemIdx];
849 switch (materialParams.approach()) {
851 auto& realParams = materialParams.template getRealParams<Opm::EclStone1Approach>();
852 return realParams.oilWaterParams().drainageParams().scaledPoints();
856 auto& realParams = materialParams.template getRealParams<Opm::EclStone2Approach>();
857 return realParams.oilWaterParams().drainageParams().scaledPoints();
861 auto& realParams = materialParams.template getRealParams<Opm::EclDefaultApproach>();
862 return realParams.oilWaterParams().drainageParams().scaledPoints();
866 auto& realParams = materialParams.template getRealParams<Opm::EclTwoPhaseApproach>();
867 return realParams.oilWaterParams().drainageParams().scaledPoints();
870 OPM_THROW(std::logic_error,
"Enum value for material approach unknown!");
874 bool enableEndPointScaling_;
875 std::shared_ptr<EclHysteresisConfig> hysteresisConfig_;
877 std::shared_ptr<EclEpsConfig> oilWaterEclEpsConfig_;
878 std::vector<Opm::EclEpsScalingPointsInfo<Scalar>> unscaledEpsInfo_;
879 OilWaterScalingInfoVector oilWaterScaledEpsInfoDrainage_;
886 std::vector<std::shared_ptr<MaterialLawParams> > materialLawParams_;
ParamsT Params
The type of the parameter objects for this law.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:60
This material law implements the hysteresis model of the ECL file format.
Specifies the configuration used by the ECL kr/pC hysteresis code.
Definition: EclTwoPhaseMaterialParams.hpp:35
Definition: Air_Mesitylene.hpp:31
Definition: EclMultiplexerMaterialParams.hpp:42
void updateHysteresis(const FluidState &fluidState, unsigned elemIdx)
Definition: EclMaterialLawManager.hpp:216
bool enableHysteresis() const
Definition: EclMaterialLawManager.hpp:200
Implementation for the parameters required by the material law for two-phase simulations.
Provides an simple way to create and manage the material law objects for a complete ECL deck...
Definition: EclMaterialLawManager.hpp:62
MaterialLaw::Params MaterialLawParams
Definition: EclMaterialLawManager.hpp:96
bool enableEndPointScaling() const
Definition: EclMaterialLawManager.hpp:197
EclTwoPhaseApproach
Definition: EclTwoPhaseMaterialParams.hpp:33
Definition: EclTwoPhaseMaterialParams.hpp:34
Implements a multiplexer class that provides all three phase capillary pressure laws used by the ECLi...
Definition: EclMultiplexerMaterial.hpp:55
MaterialLawParams & materialLawParams(unsigned elemIdx)
Definition: EclMaterialLawManager.hpp:203
This structure represents all values which can be possibly used as scaling points in the endpoint sca...
Definition: EclEpsScalingPoints.hpp:122
ParamsT Params
Definition: EclHysteresisTwoPhaseLaw.hpp:45
EclMultiplexerMaterial< Traits, GasOilTwoPhaseLaw, OilWaterTwoPhaseLaw > MaterialLaw
Definition: EclMaterialLawManager.hpp:95
Definition: EclMultiplexerMaterialParams.hpp:41
EclMultiplexerApproach
Definition: EclMultiplexerMaterialParams.hpp:39
EclMaterialLawManager()
Definition: EclMaterialLawManager.hpp:111
void initFromDeck(Opm::DeckConstPtr deck, Opm::EclipseStateConstPtr eclState, const std::vector< int > &compressedToCartesianElemIdx)
Definition: EclMaterialLawManager.hpp:114
This file contains helper classes for the material laws.
const Opm::EclEpsScalingPointsInfo< Scalar > & oilWaterScaledEpsInfoDrainage(size_t elemIdx) const
Definition: EclMaterialLawManager.hpp:225
Scalar applySwatinit(unsigned elemIdx, Scalar pcow, Scalar Sw)
Modify the initial condition according to the SWATINIT keyword.
Definition: EclMaterialLawManager.hpp:154
A generic traits class for two-phase material laws.
Definition: MaterialTraits.hpp:57
Definition: EclEpsConfig.hpp:44
ParamsT Params
Definition: EclEpsTwoPhaseLaw.hpp:54
This material law takes a material law defined for unscaled saturation and converts it to a material ...
Implements a multiplexer class that provides all three phase capillary pressure laws used by the ECLi...
This material law implements the hysteresis model of the ECL file format.
Definition: EclHysteresisTwoPhaseLaw.hpp:38
This material law takes a material law defined for unscaled saturation and converts it to a material ...
Definition: EclEpsTwoPhaseLaw.hpp:48
Specifies the configuration used by the endpoint scaling code.
const MaterialLawParams & materialLawParams(unsigned elemIdx) const
Definition: EclMaterialLawManager.hpp:209
Definition: EclEpsConfig.hpp:43
Represents all relevant thermodynamic quantities of a multi-phase, multi-component fluid system assum...
Definition: EclTwoPhaseMaterialParams.hpp:36
Implementation of a tabulated, piecewise linear capillary pressure law.
Definition: PiecewiseLinearTwoPhaseMaterial.hpp:51
Implementation of a tabulated, piecewise linear capillary pressure law.
Definition: EclMultiplexerMaterialParams.hpp:40
Represents all relevant thermodynamic quantities of a multi-phase, multi-component fluid system assum...
Definition: SimpleModularFluidState.hpp:75