opm-common
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
45
46#include <cassert>
47#include <functional>
48#include <memory>
49#include <vector>
50
51namespace Opm {
52
53class EclipseState;
55template<class Scalar> class EclEpsScalingPoints;
56template<class Scalar> struct EclEpsScalingPointsInfo;
58enum class EclTwoPhaseSystemType;
60class Runspec;
61class SgfnTable;
62class SgofTable;
63class SlgofTable;
64class TableColumn;
65
66}
67
68namespace Opm::EclMaterialLaw {
69
70template<class Traits> class InitParams;
71
78template <class TraitsT>
80{
81 using Traits = TraitsT;
82 using Scalar = typename Traits::Scalar;
83 static constexpr int gasPhaseIdx = Traits::gasPhaseIdx;
84 static constexpr int oilPhaseIdx = Traits::nonWettingPhaseIdx;
85 static constexpr int waterPhaseIdx = Traits::wettingPhaseIdx;
86 static constexpr int numPhases = Traits::numPhases;
87 using GasOilEffectiveParamVector = typename EclMaterialLaw::TwoPhaseTypes<Traits>::GasOilEffectiveParamVector;
88 using GasWaterEffectiveParamVector = typename EclMaterialLaw::TwoPhaseTypes<Traits>::GasWaterEffectiveParamVector;
89 using OilWaterEffectiveParamVector = typename EclMaterialLaw::TwoPhaseTypes<Traits>::OilWaterEffectiveParamVector;
90
91public:
92 // the three-phase material law used by the simulation
93 using MaterialLaw = EclMultiplexerMaterial<Traits,
94 typename EclMaterialLaw::TwoPhaseTypes<Traits>::GasOilLaw,
95 typename EclMaterialLaw::TwoPhaseTypes<Traits>::OilWaterLaw,
96 typename EclMaterialLaw::TwoPhaseTypes<Traits>::GasWaterLaw>;
97 using MaterialLawParams = typename MaterialLaw::Params;
98 using DirectionalMaterialLawParamsPtr = std::unique_ptr<DirectionalMaterialLawParams<MaterialLawParams>>;
99
100private:
101 using GasOilScalingPointsVector = std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar>>>;
102 using OilWaterScalingPointsVector = std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar>>>;
103 using GasWaterScalingPointsVector = std::vector<std::shared_ptr<EclEpsScalingPoints<Scalar>>>;
104 using OilWaterScalingInfoVector = std::vector<EclEpsScalingPointsInfo<Scalar>>;
105 using MaterialLawParamsVector = std::vector<std::shared_ptr<MaterialLawParams>>;
106
107public:
108 struct Params
109 {
110 OilWaterScalingInfoVector oilWaterScaledEpsInfoDrainage{};
111 GasOilEffectiveParamVector gasOilEffectiveParamVector{};
112 OilWaterEffectiveParamVector oilWaterEffectiveParamVector{};
113 GasWaterEffectiveParamVector gasWaterEffectiveParamVector{};
114 GasOilScalingPointsVector gasOilUnscaledPointsVector{};
115 OilWaterScalingPointsVector oilWaterUnscaledPointsVector{};
116 GasWaterScalingPointsVector gasWaterUnscaledPointsVector{};
117 std::vector<int> krnumXArray{};
118 std::vector<int> krnumYArray{};
119 std::vector<int> krnumZArray{};
120 std::vector<int> imbnumXArray{};
121 std::vector<int> imbnumYArray{};
122 std::vector<int> imbnumZArray{};
123 std::vector<int> satnumRegionArray{};
124 std::vector<int> imbnumRegionArray{};
125 std::vector<MaterialLawParams> materialLawParams{};
126 DirectionalMaterialLawParamsPtr dirMaterialLawParams{};
127 bool onlyPiecewiseLinear = true;
128
129 bool hasDirectionalRelperms() const
130 {
131 return !krnumXArray.empty() ||
132 !krnumYArray.empty() ||
133 !krnumZArray.empty();
134 }
135
136 bool hasDirectionalImbnum() const
137 {
138 return !imbnumXArray.empty() ||
139 !imbnumYArray.empty() ||
140 !imbnumZArray.empty();
141 }
142 };
143
144 void initFromState(const EclipseState& eclState);
145
146 // \brief Function argument 'fieldPropIntOnLeadAssigner' needed to lookup
147 // field properties of cells on the leaf grid view for CpGrid with local grid refinement.
148 // Function argument 'lookupIdxOnLevelZeroAssigner' is added to lookup, for each
149 // leaf gridview cell with index 'elemIdx', its 'lookupIdx' (index of the parent/equivalent cell on level zero).
150 void initParamsForElements(const EclipseState& eclState, size_t numCompressedElems,
151 const std::function<std::vector<int>(const FieldPropsManager&, const std::string&, bool)>&
152 fieldPropIntOnLeafAssigner,
153 const std::function<unsigned(unsigned)>& lookupIdxOnLevelZeroAssigner);
154
163 std::pair<Scalar, bool>
164 applySwatinit(unsigned elemIdx,
165 Scalar pcow,
166 Scalar Sw);
167
176 void applyRestartSwatInit(const unsigned elemIdx, const Scalar maxPcow);
177
178 bool enableEndPointScaling() const
179 { return enableEndPointScaling_; }
180
181 bool enablePpcwmax() const
182 { return enablePpcwmax_; }
183
184 const EclHysteresisConfig& hysteresisConfig() const
185 { return hysteresisConfig_; }
186
187 bool enableHysteresis() const
188 { return hysteresisConfig_.enableHysteresis(); }
189
190 bool enablePCHysteresis() const
191 { return hysteresisConfig_.enablePCHysteresis(); }
192
193 bool enableWettingHysteresis() const
194 { return hysteresisConfig_.enableWettingHysteresis(); }
195
196 bool enableNonWettingHysteresis() const
197 { return hysteresisConfig_.enableNonWettingHysteresis(); }
198
199 bool hasGas() const
200 { return hasGas_; }
201
202 bool hasOil() const
203 { return hasOil_; }
204
205 bool hasWater() const
206 { return hasWater_; }
207
208 const EclEpsScalingPointsInfo<Scalar>& unscaledEpsInfo(unsigned satRegionIdx) const
209 { return unscaledEpsInfo_[satRegionIdx]; }
210
211 std::shared_ptr<WagHysteresisConfig::WagHysteresisConfigRecord>
212 wagHystersisConfig(unsigned satRegionIdx) const
213 { return wagHystersisConfig_[satRegionIdx]; }
214
215 const EclEpsConfig& gasOilConfig() const
216 { return gasOilConfig_; }
217
218 const EclEpsConfig& gasWaterConfig() const
219 { return gasWaterConfig_; }
220
221 const EclEpsConfig& oilWaterConfig() const
222 { return oilWaterConfig_; }
223
224 MaterialLawParams& materialLawParams(unsigned elemIdx)
225 {
226 assert(elemIdx < params_.materialLawParams.size());
227 return params_.materialLawParams[elemIdx];
228 }
229
230 const MaterialLawParams& materialLawParams(unsigned elemIdx) const
231 {
232 assert(elemIdx < params_.materialLawParams.size());
233 return params_.materialLawParams[elemIdx];
234 }
235
236 const MaterialLawParams& materialLawParams(unsigned elemIdx, FaceDir::DirEnum facedir) const
237 { return materialLawParamsFunc_(elemIdx, facedir); }
238
239 MaterialLawParams& materialLawParams(unsigned elemIdx, FaceDir::DirEnum facedir)
240 { return const_cast<MaterialLawParams&>(materialLawParamsFunc_(elemIdx, facedir)); }
241
250 const MaterialLawParams& connectionMaterialLawParams(unsigned satRegionIdx, unsigned elemIdx) const;
251
252 int satnumRegionIdx(unsigned elemIdx) const
253 { return params_.satnumRegionArray[elemIdx]; }
254
255 int getKrnumSatIdx(unsigned elemIdx, FaceDir::DirEnum facedir) const;
256
257 bool hasDirectionalRelperms() const
258 { return params_.hasDirectionalRelperms(); }
259
260 bool hasDirectionalImbnum() const
261 { return params_.hasDirectionalImbnum(); }
262
263 int imbnumRegionIdx(unsigned elemIdx) const
264 { return params_.imbnumRegionArray[elemIdx]; }
265
266 EclMultiplexerApproach threePhaseApproach() const
267 { return threePhaseApproach_; }
268
269 EclTwoPhaseApproach twoPhaseApproach() const
270 { return twoPhaseApproach_; }
271
272 const std::vector<Scalar>& stoneEtas() const
273 { return stoneEtas_; }
274
275 template <class FluidState>
276 bool updateHysteresis(const FluidState& fluidState, unsigned elemIdx)
277 {
278 OPM_TIMEFUNCTION_LOCAL(Subsystem::SatProps);
279 if (!enableHysteresis())
280 return false;
281 bool changed = MaterialLaw::updateHysteresis(materialLawParams(elemIdx), fluidState);
282 if (hasDirectionalRelperms() || hasDirectionalImbnum()) {
283 using Dir = FaceDir::DirEnum;
284 constexpr int ndim = 3;
285 const Dir facedirs[] = {Dir::XPlus, Dir::YPlus, Dir::ZPlus};
286 for (int i = 0; i<ndim; i++) {
287 const bool ischanged =
288 MaterialLaw::updateHysteresis(materialLawParams(elemIdx, facedirs[i]), fluidState);
289 changed = changed || ischanged;
290 }
291 }
292 return changed;
293 }
294
295 void oilWaterHysteresisParams(Scalar& soMax,
296 Scalar& swMax,
297 Scalar& swMin,
298 unsigned elemIdx) const;
299
300 void setOilWaterHysteresisParams(const Scalar& soMax,
301 const Scalar& swMax,
302 const Scalar& swMin,
303 unsigned elemIdx);
304
305 void gasOilHysteresisParams(Scalar& sgmax,
306 Scalar& shmax,
307 Scalar& somin,
308 unsigned elemIdx) const;
309
310 void setGasOilHysteresisParams(const Scalar& sgmax,
311 const Scalar& shmax,
312 const Scalar& somin,
313 unsigned elemIdx);
314
315 EclEpsScalingPoints<Scalar>& oilWaterScaledEpsPointsDrainage(unsigned elemIdx);
316
317 const EclEpsScalingPointsInfo<Scalar>& oilWaterScaledEpsInfoDrainage(size_t elemIdx) const
318 { return params_.oilWaterScaledEpsInfoDrainage[elemIdx]; }
319
320 template<class Serializer>
321 void serializeOp(Serializer& serializer)
322 {
323 // This is for restart serialization.
324 // Only dynamic state in the parameters need to be stored.
325 // For that reason we do not serialize the vector
326 // as that would recreate the objects inside.
327 for (auto& mat : params_.materialLawParams) {
328 serializer(mat);
329 }
330 }
331
332 bool satCurveIsAllPiecewiseLinear() const
333 {
334 return this->params_.onlyPiecewiseLinear;
335 }
336
337private:
338 const MaterialLawParams& materialLawParamsFunc_(unsigned elemIdx, FaceDir::DirEnum facedir) const;
339
340 void readGlobalEpsOptions_(const EclipseState& eclState);
341
342 void readGlobalHysteresisOptions_(const EclipseState& state);
343
344 void readGlobalThreePhaseOptions_(const Runspec& runspec);
345
346 bool enableEndPointScaling_{false};
347 EclHysteresisConfig hysteresisConfig_;
348 std::vector<std::shared_ptr<WagHysteresisConfig::WagHysteresisConfigRecord>> wagHystersisConfig_;
349
350 std::vector<EclEpsScalingPointsInfo<Scalar>> unscaledEpsInfo_;
351
352 Params params_;
353
354 EclMultiplexerApproach threePhaseApproach_ = EclMultiplexerApproach::Default;
355 // this attribute only makes sense for twophase simulations!
356 EclTwoPhaseApproach twoPhaseApproach_ = EclTwoPhaseApproach::GasOil;
357
358 std::vector<Scalar> stoneEtas_;
359
360 bool enablePpcwmax_{false};
361 std::vector<Scalar> maxAllowPc_;
362 std::vector<bool> modifySwl_;
363
364 bool hasGas_{true};
365 bool hasOil_{true};
366 bool hasWater_{true};
367
368 EclEpsConfig gasOilConfig_;
369 EclEpsConfig oilWaterConfig_;
370 EclEpsConfig gasWaterConfig_;
371};
372
373} // namespace Opm::EclMaterialLaw
374
375#endif
This file contains definitions related to directional material law parameters.
Specifies the configuration used by the endpoint scaling code.
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:155
Specifies the configuration used by the ECL kr/pC hysteresis code.
Definition EclHysteresisConfig.hpp:42
bool enableHysteresis() const
Returns whether hysteresis is enabled.
Definition EclHysteresisConfig.hpp:53
Definition EclMaterialLawInitParams.hpp:51
Provides an simple way to create and manage the material law objects for a complete ECL deck.
Definition EclMaterialLawManager.hpp:80
std::pair< Scalar, bool > applySwatinit(unsigned elemIdx, Scalar pcow, Scalar Sw)
Modify the initial condition according to the SWATINIT keyword.
Definition EclMaterialLawManager.cpp:139
void applyRestartSwatInit(const unsigned elemIdx, const Scalar maxPcow)
Apply SWATINIT-like scaling of oil/water capillary pressure curve at simulation restart.
Definition EclMaterialLawManager.cpp:214
const MaterialLawParams & connectionMaterialLawParams(unsigned satRegionIdx, unsigned elemIdx) const
Returns a material parameter object for a given element and saturation region.
Definition EclMaterialLawManager.cpp:247
Implements a multiplexer class that provides all three phase capillary pressure laws used by the ECLi...
Definition EclMultiplexerMaterial.hpp:133
static bool updateHysteresis(Params &params, const FluidState &fluidState)
Update the hysteresis parameters after a time step.
Definition EclMultiplexerMaterial.hpp:555
Definition EclipseState.hpp:62
Definition FieldPropsManager.hpp:42
Definition Runspec.hpp:489
Definition SgfnTable.hpp:28
Definition SgofTable.hpp:27
Definition SlgofTable.hpp:28
Definition TableColumn.hpp:32
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
Definition EclMaterialLawManager.hpp:109