28 #ifndef EWOMS_BLACK_OIL_BRINE_MODULE_HH 29 #define EWOMS_BLACK_OIL_BRINE_MODULE_HH 31 #include <dune/common/fvector.hh> 33 #include <opm/common/utility/gpuDecorators.hpp> 56 template <
class TypeTag,
bool enableBrineV = getPropValue<TypeTag, Properties::EnableBrine>()>
72 using Toolbox = MathToolbox<Evaluation>;
74 using TabulatedFunction =
typename BlackOilBrineParams<Scalar>::TabulatedFunction;
76 static constexpr
unsigned saltConcentrationIdx = Indices::saltConcentrationIdx;
77 static constexpr
unsigned contiBrineEqIdx = Indices::contiBrineEqIdx;
78 static constexpr
unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
79 static constexpr
bool gasEnabled = Indices::gasEnabled;
80 static constexpr
bool oilEnabled = Indices::oilEnabled;
81 static constexpr
bool enableBrine = enableBrineV;
82 static constexpr
bool enableSaltPrecipitation =
83 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
85 static constexpr
unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
86 static constexpr
unsigned numPhases = FluidSystem::numPhases;
101 static bool primaryVarApplies(
unsigned pvIdx)
103 if constexpr (enableBrine) {
104 return pvIdx == saltConcentrationIdx;
114 template <
class Flu
idState>
116 const FluidState& fluidState)
118 if constexpr (enableBrine) {
119 priVars[saltConcentrationIdx] = fluidState.saltConcentration();
123 static std::string primaryVarName([[maybe_unused]]
unsigned pvIdx)
125 assert(primaryVarApplies(pvIdx));
127 return "saltConcentration";
130 static Scalar primaryVarWeight([[maybe_unused]]
unsigned pvIdx)
132 assert(primaryVarApplies(pvIdx));
135 return static_cast<Scalar
>(1.0);
138 static bool eqApplies(
unsigned eqIdx)
140 if constexpr (enableBrine) {
141 return eqIdx == contiBrineEqIdx;
148 static std::string eqName([[maybe_unused]]
unsigned eqIdx)
150 assert(eqApplies(eqIdx));
152 return "conti^brine";
155 static Scalar eqWeight([[maybe_unused]]
unsigned eqIdx)
157 assert(eqApplies(eqIdx));
160 return static_cast<Scalar
>(1.0);
164 template <
class StorageType>
165 OPM_HOST_DEVICE
static void addStorage(StorageType& storage,
166 const IntensiveQuantities& intQuants)
168 using LhsEval =
typename StorageType::value_type;
170 if constexpr (enableBrine) {
171 const auto& fs = intQuants.fluidState();
174 const LhsEval surfaceVolumeWater =
175 max(Toolbox::template decay<LhsEval>(fs.saturation(waterPhaseIdx)) *
176 Toolbox::template decay<LhsEval>(fs.invB(waterPhaseIdx)) *
177 Toolbox::template decay<LhsEval>(intQuants.porosity()),
181 const LhsEval massBrine = surfaceVolumeWater *
182 Toolbox::template decay<LhsEval>(fs.saltConcentration());
184 if constexpr (enableSaltPrecipitation) {
185 const double saltDensity = intQuants.saltDensity();
186 const LhsEval solidSalt =
187 Toolbox::template decay<LhsEval>(intQuants.porosity()) /
188 (1.0 - Toolbox::template decay<LhsEval>(fs.saltSaturation()) + 1.e-8) *
190 Toolbox::template decay<LhsEval>(fs.saltSaturation());
192 storage[contiBrineEqIdx] += massBrine + solidSalt;
195 storage[contiBrineEqIdx] += massBrine;
200 static void computeFlux([[maybe_unused]] RateVector& flux,
201 [[maybe_unused]]
const ElementContext& elemCtx,
202 [[maybe_unused]]
unsigned scvfIdx,
203 [[maybe_unused]]
unsigned timeIdx)
205 if constexpr (enableBrine) {
206 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
207 unsigned focusIdx = elemCtx.focusDofIndex();
208 unsigned upIdx = extQuants.upstreamIndex(waterPhaseIdx);
209 flux[contiBrineEqIdx] = 0.0;
210 if (upIdx == focusIdx)
211 addBrineFluxes_<Evaluation>(flux, elemCtx, scvfIdx, timeIdx);
213 addBrineFluxes_<Scalar>(flux, elemCtx, scvfIdx, timeIdx);
217 template <
class UpstreamEval>
218 static void addBrineFluxes_(RateVector& flux,
219 const ElementContext& elemCtx,
223 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
224 unsigned upIdx = extQuants.upstreamIndex(waterPhaseIdx);
225 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
226 const auto& upFs = up.fluidState();
227 const auto& volFlux = extQuants.volumeFlux(waterPhaseIdx);
228 addBrineFluxes_<UpstreamEval>(flux, waterPhaseIdx, volFlux, upFs);
231 template <
class UpEval,
class Flu
idState>
232 static void addBrineFluxes_(RateVector& flux,
234 const Evaluation& volFlux,
235 const FluidState& upFs)
237 if constexpr (enableBrine) {
238 if (phaseIdx == waterPhaseIdx) {
239 flux[contiBrineEqIdx] =
240 decay<UpEval>(upFs.saltConcentration())
241 * decay<UpEval>(upFs.invB(waterPhaseIdx))
256 return static_cast<Scalar
>(0.0);
259 template <
class DofEntity>
260 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
262 if constexpr (enableBrine) {
263 const unsigned dofIdx = model.dofMapper().index(dof);
264 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
265 outstream << priVars[saltConcentrationIdx];
269 template <
class DofEntity>
270 static void deserializeEntity(Model& model, std::istream& instream,
const DofEntity& dof)
272 if constexpr (enableBrine) {
273 const unsigned dofIdx = model.dofMapper().index(dof);
274 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
275 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
277 instream >> priVars0[saltConcentrationIdx];
280 priVars1[saltConcentrationIdx] = priVars0[saltConcentrationIdx];
284 static Scalar referencePressure(
const ElementContext& elemCtx,
288 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
289 return params_.referencePressure_[pvtnumRegionIdx];
292 static const TabulatedFunction& bdensityTable(
const ElementContext& elemCtx,
296 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
297 return params_.bdensityTable_[pvtnumRegionIdx];
300 static const TabulatedFunction& pcfactTable(
unsigned satnumRegionIdx)
301 {
return params_.pcfactTable_[satnumRegionIdx]; }
303 static const TabulatedFunction& permfactTable(
const ElementContext& elemCtx,
307 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
308 return params_.permfactTable_[satnumRegionIdx];
311 static const TabulatedFunction& permfactTable(
unsigned satnumRegionIdx)
312 {
return params_.permfactTable_[satnumRegionIdx]; }
314 static Scalar saltsolTable(
const ElementContext& elemCtx,
318 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
319 return params_.saltsolTable_[pvtnumRegionIdx];
322 static Scalar saltsolTable(
const unsigned pvtnumRegionIdx)
324 return params_.saltsolTable_[pvtnumRegionIdx];
327 static Scalar saltdenTable(
const ElementContext& elemCtx,
331 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
332 return params_.saltdenTable_[pvtnumRegionIdx];
335 static Scalar saltdenTable(
const unsigned pvtnumRegionIdx)
337 return params_.saltdenTable_[pvtnumRegionIdx];
340 static bool hasBDensityTables()
341 {
return !params_.bdensityTable_.empty(); }
343 static bool hasSaltsolTables()
344 {
return !params_.saltsolTable_.empty(); }
346 static bool hasPcfactTables()
348 if constexpr (enableSaltPrecipitation) {
349 return !params_.pcfactTable_.empty();
356 static Scalar saltSol(
unsigned regionIdx)
357 {
return params_.saltsolTable_[regionIdx]; }
360 static BlackOilBrineParams<Scalar> params_;
363 template <
class TypeTag,
bool enableBrineV>
364 BlackOilBrineParams<typename BlackOilBrineModule<TypeTag, enableBrineV>::Scalar>
365 BlackOilBrineModule<TypeTag, enableBrineV>::params_;
367 template <
class TypeTag,
bool enableBrineV>
377 template <
class TypeTag>
392 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
393 static constexpr
int saltConcentrationIdx = Indices::saltConcentrationIdx;
394 static constexpr
int waterPhaseIdx = FluidSystem::waterPhaseIdx;
395 static constexpr
int gasPhaseIdx = FluidSystem::gasPhaseIdx;
396 static constexpr
int oilPhaseIdx = FluidSystem::oilPhaseIdx;
397 static constexpr
bool enableBrine =
true;
398 static constexpr
bool enableSaltPrecipitation =
399 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
400 static constexpr
int contiBrineEqIdx = Indices::contiBrineEqIdx;
412 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
414 updateSaltConcentration_(priVars, timeIdx, lintype);
417 void updateSaltConcentration_(
const PrimaryVariables& priVars,
418 const unsigned timeIdx,
421 const unsigned pvtnumRegionIdx = priVars.pvtRegionIndex();
422 auto& fs = asImp_().fluidState_;
424 if constexpr (enableSaltPrecipitation) {
425 saltSolubility_ = BrineModule::saltsolTable(pvtnumRegionIdx);
426 saltDensity_ = BrineModule::saltdenTable(pvtnumRegionIdx);
428 if (priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
429 saltSaturation_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx, lintype);
430 fs.setSaltConcentration(saltSolubility_);
433 saltConcentration_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx, lintype);
434 fs.setSaltConcentration(saltConcentration_);
435 saltSaturation_ = 0.0;
437 fs.setSaltSaturation(saltSaturation_);
440 saltConcentration_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx, lintype);
441 fs.setSaltConcentration(saltConcentration_);
445 void saltPropertiesUpdate_([[maybe_unused]]
const ElementContext& elemCtx,
446 [[maybe_unused]]
unsigned dofIdx,
447 [[maybe_unused]]
unsigned timeIdx)
449 if constexpr (enableSaltPrecipitation) {
450 const Evaluation porosityFactor = min(1.0 - asImp_().fluidState_.saltSaturation(), 1.0);
452 const auto& permfactTable = BrineModule::permfactTable(elemCtx, dofIdx, timeIdx);
454 permFactor_ = permfactTable.eval(porosityFactor);
458 const Evaluation& brineRefDensity()
const 459 {
return refDensity_; }
461 Scalar saltSolubility()
const 462 {
return saltSolubility_; }
464 Scalar saltDensity()
const 465 {
return saltDensity_; }
467 const Evaluation& permFactor()
const 468 {
return permFactor_; }
471 Implementation& asImp_()
472 {
return *
static_cast<Implementation*
>(
this); }
474 Evaluation saltConcentration_;
475 Evaluation refDensity_;
476 Evaluation saltSaturation_;
477 Evaluation permFactor_;
478 Scalar saltSolubility_;
482 template <
class TypeTag>
490 void updateSaltConcentration_(
const ElementContext&,
495 void saltPropertiesUpdate_(
const ElementContext&,
500 const Evaluation& brineRefDensity()
const 501 {
throw std::runtime_error(
"brineRefDensity() called but brine are disabled"); }
503 const Scalar saltSolubility()
const 504 {
throw std::logic_error(
"saltSolubility() called but salt precipitation is disabled"); }
506 const Scalar saltDensity()
const 507 {
throw std::logic_error(
"saltDensity() called but salt precipitation is disabled"); }
509 const Evaluation& permFactor()
const 510 {
throw std::logic_error(
"permFactor() called but salt precipitation is disabled"); }
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
static void setParams(BlackOilBrineParams< Scalar > &¶ms)
Set parameters.
Definition: blackoilbrinemodules.hh:90
Contains the high level supplements required to extend the black oil model by brine.
Definition: blackoilbrinemodules.hh:57
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
static void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the brine specific primary variables to a PrimaryVariables object.
Definition: blackoilbrinemodules.hh:115
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilbrinemodules.hh:250
Declares the properties required by the black oil model.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Provides the volumetric quantities required for the equations needed by the brine extension of the bl...
Definition: blackoilbrinemodules.hh:368
Struct holding the parameters for the BlackoilBrineModule class.
Definition: blackoilbrineparams.hpp:41
Definition: linearizationtype.hh:33
The common code for the linearizers of non-linear systems of equations.
void updateSaltConcentration_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the intensive properties needed to handle brine from the primary variables.
Definition: blackoilbrinemodules.hh:408
Contains the parameters required to extend the black-oil model by brine.
static void registerParameters()
Register all run-time parameters for the black-oil brine module.
Definition: blackoilbrinemodules.hh:98
Defines a type tags and some fundamental properties all models.
Definition: blackoilbrinemodules.hh:368