My Project
Loading...
Searching...
No Matches
EclMaterialLawManager.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*/
27#if ! HAVE_ECL_INPUT
28#error "Eclipse input support in opm-common is required to use the ECL material manager!"
29#endif
30
31#ifndef OPM_ECL_MATERIAL_LAW_MANAGER_HPP
32#define OPM_ECL_MATERIAL_LAW_MANAGER_HPP
33
34#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
35#include <opm/input/eclipse/EclipseState/WagHysteresisConfig.hpp>
36
43
44#include <cassert>
45#include <functional>
46#include <memory>
47#include <tuple>
48#include <vector>
49
50namespace Opm {
51
52class EclipseState;
53class EclEpsConfig;
54class EclEpsGridProperties;
55template<class Scalar> class EclEpsScalingPoints;
56template<class Scalar> struct EclEpsScalingPointsInfo;
57class EclHysteresisConfig;
58enum class EclTwoPhaseSystemType;
59class FieldPropsManager;
60class Runspec;
61class SgfnTable;
62class SgofTable;
63class SlgofTable;
64class TableColumn;
65
72template <class TraitsT>
74{
75private:
76 using Traits = TraitsT;
77 using Scalar = typename Traits::Scalar;
78 enum { waterPhaseIdx = Traits::wettingPhaseIdx };
79 enum { oilPhaseIdx = Traits::nonWettingPhaseIdx };
80 enum { gasPhaseIdx = Traits::gasPhaseIdx };
81 enum { numPhases = Traits::numPhases };
82
86
87 // the two-phase material law which is defined on effective (unscaled) saturations
91
92 using GasOilEffectiveTwoPhaseParams = typename GasOilEffectiveTwoPhaseLaw::Params;
93 using OilWaterEffectiveTwoPhaseParams = typename OilWaterEffectiveTwoPhaseLaw::Params;
94 using GasWaterEffectiveTwoPhaseParams = typename GasWaterEffectiveTwoPhaseLaw::Params;
95
96 // the two-phase material law which is defined on absolute (scaled) saturations
100 using GasOilEpsTwoPhaseParams = typename GasOilEpsTwoPhaseLaw::Params;
101 using OilWaterEpsTwoPhaseParams = typename OilWaterEpsTwoPhaseLaw::Params;
102 using GasWaterEpsTwoPhaseParams = typename GasWaterEpsTwoPhaseLaw::Params;
103
104 // the scaled two-phase material laws with hystersis
108 using GasOilTwoPhaseHystParams = typename GasOilTwoPhaseLaw::Params;
109 using OilWaterTwoPhaseHystParams = typename OilWaterTwoPhaseLaw::Params;
110 using GasWaterTwoPhaseHystParams = typename GasWaterTwoPhaseLaw::Params;
111
112public:
113 // the three-phase material law used by the simulation
115 using MaterialLawParams = typename MaterialLaw::Params;
116 using DirectionalMaterialLawParamsPtr = std::unique_ptr<DirectionalMaterialLawParams<MaterialLawParams>>;
117
120
121private:
122 // internal typedefs
123 using GasOilEffectiveParamVector = std::vector<std::shared_ptr<GasOilEffectiveTwoPhaseParams>>;
124 using OilWaterEffectiveParamVector = std::vector<std::shared_ptr<OilWaterEffectiveTwoPhaseParams>>;
125 using GasWaterEffectiveParamVector = std::vector<std::shared_ptr<GasWaterEffectiveTwoPhaseParams>>;
126
127 using GasOilScalingPointsVector = std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar>>>;
128 using OilWaterScalingPointsVector = std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar>>>;
129 using GasWaterScalingPointsVector = std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar>>>;
130 using OilWaterScalingInfoVector = std::vector<EclEpsScalingPointsInfo<Scalar>>;
131 using GasOilParamVector = std::vector<std::shared_ptr<GasOilTwoPhaseHystParams>>;
132 using OilWaterParamVector = std::vector<std::shared_ptr<OilWaterTwoPhaseHystParams>>;
133 using GasWaterParamVector = std::vector<std::shared_ptr<GasWaterTwoPhaseHystParams>>;
134 using MaterialLawParamsVector = std::vector<std::shared_ptr<MaterialLawParams>>;
135
136 // helper classes
137
138 // This class' implementation is defined in "EclMaterialLawManagerInitParams.cpp"
139 class InitParams {
140 public:
141 InitParams(EclMaterialLawManager<TraitsT>& parent, const EclipseState& eclState, size_t numCompressedElems);
142 // \brief Function argument 'fieldPropIntOnLeadAssigner' needed to lookup
143 // field properties of cells on the leaf grid view for CpGrid with local grid refinement.
144 // Function argument 'lookupIdxOnLevelZeroAssigner' is added to lookup, for each
145 // leaf gridview cell with index 'elemIdx', its 'lookupIdx' (index of the parent/equivalent cell on level zero).
146 void run(const std::function<std::vector<int>(const FieldPropsManager&, const std::string&, bool)>& fieldPropIntOnLeafAssigner,
147 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
148 private:
149 class HystParams;
150 // \brief Function argument 'fieldPropIntOnLeadAssigner' needed to lookup
151 // field properties of cells on the leaf grid view for CpGrid with local grid refinement.
152 void copySatnumArrays_(const std::function<std::vector<int>(const FieldPropsManager&, const std::string&, bool)>&
153 fieldPropIntOnLeafAssigner);
154 // \brief Function argument 'fieldPropIntOnLeadAssigner' needed to lookup
155 // field properties of cells on the leaf grid view for CpGrid with local grid refinement.
156 void copyIntArray_(std::vector<int>& dest, const std::string keyword,
157 const std::function<std::vector<int>(const FieldPropsManager&, const std::string&, bool)>&
158 fieldPropIntOnLeafAssigner);
159 unsigned imbRegion_(std::vector<int>& array, unsigned elemIdx);
160 void initArrays_(
161 std::vector<std::vector<int>*>& satnumArray,
162 std::vector<std::vector<int>*>& imbnumArray,
163 std::vector<std::vector<MaterialLawParams>*>& mlpArray);
164 void initMaterialLawParamVectors_();
165 void initOilWaterScaledEpsInfo_();
166 // \brief Function argument 'fieldProptOnLeadAssigner' needed to lookup
167 // field properties of cells on the leaf grid view for CpGrid with local grid refinement.
168 void initSatnumRegionArray_(const std::function<std::vector<int>(const FieldPropsManager&, const std::string&, bool)>&
169 fieldPropIntOnLeafAssigner);
170 void initThreePhaseParams_(
171 HystParams &hystParams,
172 MaterialLawParams& materialParams,
173 unsigned satRegionIdx,
174 unsigned elemIdx);
175 void readEffectiveParameters_();
176 void readUnscaledEpsPointsVectors_();
177 template <class Container>
178 void readUnscaledEpsPoints_(Container& dest, std::shared_ptr<EclEpsConfig> config, EclTwoPhaseSystemType system_type);
179 unsigned satRegion_(std::vector<int>& array, unsigned elemIdx);
180 unsigned satOrImbRegion_(std::vector<int>& array, std::vector<int>& default_vec, unsigned elemIdx);
181
182 // This class' implementation is defined in "EclMaterialLawManagerHystParams.cpp"
183 class HystParams {
184 public:
185 HystParams(EclMaterialLawManager<TraitsT>::InitParams& init_params);
186 void finalize();
187 std::shared_ptr<GasOilTwoPhaseHystParams> getGasOilParams();
188 std::shared_ptr<OilWaterTwoPhaseHystParams> getOilWaterParams();
189 std::shared_ptr<GasWaterTwoPhaseHystParams> getGasWaterParams();
190 void setConfig(unsigned satRegionIdx);
191 // Function argument 'lookupIdxOnLevelZeroAssigner' is added to lookup, for each
192 // leaf gridview cell with index 'elemIdx', its 'lookupIdx' (index of the parent/equivalent cell on level zero).
193 void setDrainageParamsOilGas(unsigned elemIdx, unsigned satRegionIdx,
194 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
195 void setDrainageParamsOilWater(unsigned elemIdx, unsigned satRegionIdx,
196 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
197 void setDrainageParamsGasWater(unsigned elemIdx, unsigned satRegionIdx,
198 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
199 void setImbibitionParamsOilGas(unsigned elemIdx, unsigned satRegionIdx,
200 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
201 void setImbibitionParamsOilWater(unsigned elemIdx, unsigned satRegionIdx,
202 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
203 void setImbibitionParamsGasWater(unsigned elemIdx, unsigned satRegionIdx,
204 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
205 private:
206 bool hasGasWater_();
207 bool hasGasOil_();
208 bool hasOilWater_();
209
210 // Function argument 'lookupIdxOnLevelZeroAssigner' is added to lookup, for each
211 // leaf gridview cell with index 'elemIdx', its 'lookupIdx' (index of the parent/equivalent cell on level zero).
212 std::tuple<EclEpsScalingPointsInfo<Scalar>, EclEpsScalingPoints<Scalar>>
213 readScaledEpsPoints_(const EclEpsGridProperties& epsGridProperties, unsigned elemIdx, EclTwoPhaseSystemType type,
214 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
215 std::tuple<EclEpsScalingPointsInfo<Scalar>, EclEpsScalingPoints<Scalar>>
216 readScaledEpsPointsDrainage_(unsigned elemIdx, EclTwoPhaseSystemType type,
217 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
218 std::tuple<EclEpsScalingPointsInfo<Scalar>, EclEpsScalingPoints<Scalar>>
219 readScaledEpsPointsImbibition_(unsigned elemIdx, EclTwoPhaseSystemType type,
220 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
221
224 const EclipseState& eclState_;
225 std::shared_ptr<GasOilTwoPhaseHystParams> gasOilParams_;
226 std::shared_ptr<OilWaterTwoPhaseHystParams> oilWaterParams_;
227 std::shared_ptr<GasWaterTwoPhaseHystParams> gasWaterParams_;
228 };
229
230 // This class' implementation is defined in "EclMaterialLawManagerReadEffectiveParams.cpp"
231 class ReadEffectiveParams {
232 public:
233 ReadEffectiveParams(EclMaterialLawManager<TraitsT>::InitParams& init_params);
234 void read();
235 private:
236 std::vector<double> normalizeKrValues_(const double tolcrit, const TableColumn& krValues) const;
237 void readGasOilParameters_(GasOilEffectiveParamVector& dest, unsigned satRegionIdx);
238 template <class TableType>
239 void readGasOilFamily2_(
240 GasOilEffectiveTwoPhaseParams& effParams,
241 const Scalar Swco,
242 const double tolcrit,
243 const TableType& sofTable,
244 const SgfnTable& sgfnTable,
245 const std::string& columnName);
246 void readGasOilSgof_(GasOilEffectiveTwoPhaseParams& effParams,
247 const Scalar Swco,
248 const double tolcrit,
249 const SgofTable& sgofTable);
250
251 void readGasOilSlgof_(GasOilEffectiveTwoPhaseParams& effParams,
252 const Scalar Swco,
253 const double tolcrit,
254 const SlgofTable& slgofTable);
255 void readGasWaterParameters_(GasWaterEffectiveParamVector& dest, unsigned satRegionIdx);
256 void readOilWaterParameters_(OilWaterEffectiveParamVector& dest, unsigned satRegionIdx);
257
260 const EclipseState& eclState_;
261 }; // end of "class ReadEffectiveParams"
262
264 const EclipseState& eclState_;
265 size_t numCompressedElems_;
266
267 std::unique_ptr<EclEpsGridProperties> epsImbGridProperties_; //imbibition
268 std::unique_ptr<EclEpsGridProperties> epsGridProperties_; // drainage
269
270 }; // end of "class InitParams"
271
272public:
273 void initFromState(const EclipseState& eclState);
274
275 // \brief Function argument 'fieldPropIntOnLeadAssigner' needed to lookup
276 // field properties of cells on the leaf grid view for CpGrid with local grid refinement.
277 // Function argument 'lookupIdxOnLevelZeroAssigner' is added to lookup, for each
278 // leaf gridview cell with index 'elemIdx', its 'lookupIdx' (index of the parent/equivalent cell on level zero).
279 void initParamsForElements(const EclipseState& eclState, size_t numCompressedElems,
280 const std::function<std::vector<int>(const FieldPropsManager&, const std::string&, bool)>&
281 fieldPropIntOnLeafAssigner,
282 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
283
292 std::pair<Scalar, bool>
293 applySwatinit(unsigned elemIdx,
294 Scalar pcow,
295 Scalar Sw);
296
305 void applyRestartSwatInit(const unsigned elemIdx, const Scalar maxPcow);
306
307 bool enableEndPointScaling() const
308 { return enableEndPointScaling_; }
309
310 bool enablePpcwmax() const
311 { return enablePpcwmax_; }
312
313 bool enableHysteresis() const
314 { return hysteresisConfig_->enableHysteresis(); }
315
316 MaterialLawParams& materialLawParams(unsigned elemIdx)
317 {
318 assert(elemIdx < materialLawParams_.size());
319 return materialLawParams_[elemIdx];
320 }
321
322 const MaterialLawParams& materialLawParams(unsigned elemIdx) const
323 {
324 assert(elemIdx < materialLawParams_.size());
325 return materialLawParams_[elemIdx];
326 }
327
328 const MaterialLawParams& materialLawParams(unsigned elemIdx, FaceDir::DirEnum facedir) const
329 {
330 return materialLawParamsFunc_(elemIdx, facedir);
331 }
332
333 MaterialLawParams& materialLawParams(unsigned elemIdx, FaceDir::DirEnum facedir)
334 {
335 return const_cast<MaterialLawParams&>(materialLawParamsFunc_(elemIdx, facedir));
336 }
337
346 const MaterialLawParams& connectionMaterialLawParams(unsigned satRegionIdx, unsigned elemIdx) const;
347
348 int satnumRegionIdx(unsigned elemIdx) const
349 { return satnumRegionArray_[elemIdx]; }
350
351 int getKrnumSatIdx(unsigned elemIdx, FaceDir::DirEnum facedir) const;
352
353 bool hasDirectionalRelperms() const
354 {
355 return !krnumXArray_.empty() || !krnumYArray_.empty() || !krnumZArray_.empty();
356 }
357
358 bool hasDirectionalImbnum() const {
359 if (imbnumXArray_.size() > 0 || imbnumYArray_.size() > 0 || imbnumZArray_.size() > 0) {
360 return true;
361 }
362 return false;
363 }
364
365 int imbnumRegionIdx(unsigned elemIdx) const
366 { return imbnumRegionArray_[elemIdx]; }
367
368 template <class FluidState>
369 bool updateHysteresis(const FluidState& fluidState, unsigned elemIdx)
370 {
371 OPM_TIMEFUNCTION_LOCAL();
372 if (!enableHysteresis())
373 return false;
374 bool changed = MaterialLaw::updateHysteresis(materialLawParams(elemIdx), fluidState);
375 if (hasDirectionalRelperms() || hasDirectionalImbnum()) {
376 using Dir = FaceDir::DirEnum;
377 constexpr int ndim = 3;
378 Dir facedirs[ndim] = {Dir::XPlus, Dir::YPlus, Dir::ZPlus};
379 for (int i = 0; i<ndim; i++) {
380 bool ischanged = MaterialLaw::updateHysteresis(materialLawParams(elemIdx, facedirs[i]), fluidState);
381 changed = changed || ischanged;
382 }
383 }
384 return changed;
385 }
386
387 void oilWaterHysteresisParams(Scalar& pcSwMdc,
388 Scalar& krnSwMdc,
389 unsigned elemIdx) const;
390
391 void setOilWaterHysteresisParams(const Scalar& pcSwMdc,
392 const Scalar& krnSwMdc,
393 unsigned elemIdx);
394
395 void gasOilHysteresisParams(Scalar& pcSwMdc,
396 Scalar& krnSwMdc,
397 unsigned elemIdx) const;
398
399 void setGasOilHysteresisParams(const Scalar& pcSwMdc,
400 const Scalar& krnSwMdc,
401 unsigned elemIdx);
402
403 EclEpsScalingPoints<Scalar>& oilWaterScaledEpsPointsDrainage(unsigned elemIdx);
404
405 const EclEpsScalingPointsInfo<Scalar>& oilWaterScaledEpsInfoDrainage(size_t elemIdx) const
406 { return oilWaterScaledEpsInfoDrainage_[elemIdx]; }
407
408 template<class Serializer>
409 void serializeOp(Serializer& serializer)
410 {
411 // This is for restart serialization.
412 // Only dynamic state in the parameters need to be stored.
413 // For that reason we do not serialize the vector
414 // as that would recreate the objects inside.
415 for (auto& mat : materialLawParams_) {
416 serializer(mat);
417 }
418 }
419
420private:
421 const MaterialLawParams& materialLawParamsFunc_(unsigned elemIdx, FaceDir::DirEnum facedir) const;
422
423 void readGlobalEpsOptions_(const EclipseState& eclState);
424
425 void readGlobalHysteresisOptions_(const EclipseState& state);
426
427 void readGlobalThreePhaseOptions_(const Runspec& runspec);
428
429 bool enableEndPointScaling_;
430 std::shared_ptr<EclHysteresisConfig> hysteresisConfig_;
431 std::vector<std::shared_ptr<WagHysteresisConfig::WagHysteresisConfigRecord>> wagHystersisConfig_;
432
433
434 std::shared_ptr<EclEpsConfig> oilWaterEclEpsConfig_;
435 std::vector<EclEpsScalingPointsInfo<Scalar>> unscaledEpsInfo_;
436 OilWaterScalingInfoVector oilWaterScaledEpsInfoDrainage_;
437
438 std::shared_ptr<EclEpsConfig> gasWaterEclEpsConfig_;
439
440 GasOilScalingPointsVector gasOilUnscaledPointsVector_;
441 OilWaterScalingPointsVector oilWaterUnscaledPointsVector_;
442 GasWaterScalingPointsVector gasWaterUnscaledPointsVector_;
443
444 GasOilEffectiveParamVector gasOilEffectiveParamVector_;
445 OilWaterEffectiveParamVector oilWaterEffectiveParamVector_;
446 GasWaterEffectiveParamVector gasWaterEffectiveParamVector_;
447
448 EclMultiplexerApproach threePhaseApproach_ = EclMultiplexerApproach::Default;
449 // this attribute only makes sense for twophase simulations!
450 enum EclTwoPhaseApproach twoPhaseApproach_ = EclTwoPhaseApproach::GasOil;
451
452 std::vector<MaterialLawParams> materialLawParams_;
453 DirectionalMaterialLawParamsPtr dirMaterialLawParams_;
454
455 std::vector<int> satnumRegionArray_;
456 std::vector<int> krnumXArray_;
457 std::vector<int> krnumYArray_;
458 std::vector<int> krnumZArray_;
459 std::vector<int> imbnumXArray_;
460 std::vector<int> imbnumYArray_;
461 std::vector<int> imbnumZArray_;
462 std::vector<int> imbnumRegionArray_;
463 std::vector<Scalar> stoneEtas_;
464
465 bool enablePpcwmax_;
466 std::vector<Scalar> maxAllowPc_;
467 std::vector<bool> modifySwl_;
468
469 bool hasGas;
470 bool hasOil;
471 bool hasWater;
472
473 std::shared_ptr<EclEpsConfig> gasOilConfig_;
474 std::shared_ptr<EclEpsConfig> oilWaterConfig_;
475 std::shared_ptr<EclEpsConfig> gasWaterConfig_;
476};
477} // namespace Opm
478
479#endif
This file contains definitions related to directional material law parameters.
This material law takes a material law defined for unscaled saturation and converts it to a material ...
This material law implements the hysteresis model of the ECL file format.
Implements a multiplexer class that provides all three phase capillary pressure laws used by the ECLi...
This file contains helper classes for the material laws.
Implements a multiplexer class that provides LET curves and piecewise linear saturation functions.
Collects all grid properties which are relevant for end point scaling.
Definition EclEpsGridProperties.hpp:47
Represents the points on the X and Y axis to be scaled if endpoint scaling is used.
Definition EclEpsScalingPoints.hpp:166
This material law takes a material law defined for unscaled saturation and converts it to a material ...
Definition EclEpsTwoPhaseLaw.hpp:51
This material law implements the hysteresis model of the ECL file format.
Definition EclHysteresisTwoPhaseLaw.hpp:43
Provides an simple way to create and manage the material law objects for a complete ECL deck.
Definition EclMaterialLawManager.hpp:74
const MaterialLawParams & connectionMaterialLawParams(unsigned satRegionIdx, unsigned elemIdx) const
Returns a material parameter object for a given element and saturation region.
Definition EclMaterialLawManager.cpp:239
void applyRestartSwatInit(const unsigned elemIdx, const Scalar maxPcow)
Apply SWATINIT-like scaling of oil/water capillary pressure curve at simulation restart.
Definition EclMaterialLawManager.cpp:220
std::pair< Scalar, bool > applySwatinit(unsigned elemIdx, Scalar pcow, Scalar Sw)
Modify the initial condition according to the SWATINIT keyword.
Definition EclMaterialLawManager.cpp:146
Implements a multiplexer class that provides all three phase capillary pressure laws used by the ECLi...
Definition EclMultiplexerMaterial.hpp:58
static bool updateHysteresis(Params &params, const FluidState &fluidState)
Update the hysteresis parameters after a time step.
Definition EclMultiplexerMaterial.hpp:618
Definition EclipseState.hpp:63
Definition FieldPropsManager.hpp:42
Definition Runspec.hpp:481
Implements a multiplexer class that provides LET curves and piecewise linear saturation functions.
Definition SatCurveMultiplexer.hpp:44
Class for (de-)serializing.
Definition Serializer.hpp:84
Definition SgfnTable.hpp:28
Definition SgofTable.hpp:27
Definition SlgofTable.hpp:28
Definition TableColumn.hpp:32
A generic traits class for two-phase material laws.
Definition MaterialTraits.hpp:61
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
EclTwoPhaseSystemType
Specified which fluids are involved in a given twophase material law for endpoint scaling.
Definition EclEpsConfig.hpp:42
This structure represents all values which can be possibly used as scaling points in the endpoint sca...
Definition EclEpsScalingPoints.hpp:57