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>
57 class BlackOilBrineModule<TypeTag, true>
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 =
true;
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 OPM_HOST_DEVICE
bool primaryVarApplies(
unsigned pvIdx)
103 return pvIdx == saltConcentrationIdx;
109 template <
class Flu
idState>
111 const FluidState& fluidState)
113 priVars[saltConcentrationIdx] = fluidState.saltConcentration();
116 static std::string primaryVarName([[maybe_unused]]
unsigned pvIdx)
118 assert(primaryVarApplies(pvIdx));
120 return "saltConcentration";
123 static Scalar primaryVarWeight([[maybe_unused]]
unsigned pvIdx)
125 assert(primaryVarApplies(pvIdx));
128 return static_cast<Scalar
>(1.0);
131 static OPM_HOST_DEVICE
bool eqApplies(
unsigned eqIdx)
133 return eqIdx == contiBrineEqIdx;
136 static std::string eqName([[maybe_unused]]
unsigned eqIdx)
138 assert(eqApplies(eqIdx));
140 return "conti^brine";
143 static Scalar eqWeight([[maybe_unused]]
unsigned eqIdx)
145 assert(eqApplies(eqIdx));
148 return static_cast<Scalar
>(1.0);
152 template <
class StorageType>
153 OPM_HOST_DEVICE
static void addStorage(StorageType& storage,
154 const IntensiveQuantities& intQuants)
156 using LhsEval =
typename StorageType::value_type;
158 const auto& fs = intQuants.fluidState();
161 const LhsEval surfaceVolumeWater =
162 max(Toolbox::template decay<LhsEval>(fs.saturation(waterPhaseIdx)) *
163 Toolbox::template decay<LhsEval>(fs.invB(waterPhaseIdx)) *
164 Toolbox::template decay<LhsEval>(intQuants.porosity()),
168 const LhsEval massBrine = surfaceVolumeWater *
169 Toolbox::template decay<LhsEval>(fs.saltConcentration());
171 if constexpr (enableSaltPrecipitation) {
172 const double saltDensity = intQuants.saltDensity();
173 const LhsEval solidSalt =
174 Toolbox::template decay<LhsEval>(intQuants.porosity()) /
175 (1.0 - Toolbox::template decay<LhsEval>(fs.saltSaturation()) + 1.e-8) *
177 Toolbox::template decay<LhsEval>(fs.saltSaturation());
179 storage[contiBrineEqIdx] += massBrine + solidSalt;
182 storage[contiBrineEqIdx] += massBrine;
186 static void computeFlux(RateVector& flux,
187 const ElementContext& elemCtx,
191 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
192 unsigned focusIdx = elemCtx.focusDofIndex();
193 unsigned upIdx = extQuants.upstreamIndex(waterPhaseIdx);
194 flux[contiBrineEqIdx] = 0.0;
195 if (upIdx == focusIdx) {
196 addBrineFluxes_<Evaluation>(flux, elemCtx, scvfIdx, timeIdx);
199 addBrineFluxes_<Scalar>(flux, elemCtx, scvfIdx, timeIdx);
203 template <
class UpstreamEval>
204 static void addBrineFluxes_(RateVector& flux,
205 const ElementContext& elemCtx,
209 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
210 unsigned upIdx = extQuants.upstreamIndex(waterPhaseIdx);
211 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
212 const auto& upFs = up.fluidState();
213 const auto& volFlux = extQuants.volumeFlux(waterPhaseIdx);
214 addBrineFluxes_<UpstreamEval>(flux, waterPhaseIdx, volFlux, upFs);
217 template <
class UpEval,
class Flu
idState>
218 static void addBrineFluxes_(RateVector& flux,
220 const Evaluation& volFlux,
221 const FluidState& upFs)
223 if (phaseIdx == waterPhaseIdx) {
224 flux[contiBrineEqIdx] =
225 decay<UpEval>(upFs.saltConcentration())
226 * decay<UpEval>(upFs.invB(waterPhaseIdx))
240 return static_cast<Scalar
>(0.0);
243 template <
class DofEntity>
244 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
246 const unsigned dofIdx = model.dofMapper().index(dof);
247 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
248 outstream << priVars[saltConcentrationIdx];
251 template <
class DofEntity>
252 static void deserializeEntity(Model& model, std::istream& instream,
const DofEntity& dof)
254 const unsigned dofIdx = model.dofMapper().index(dof);
255 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
256 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
258 instream >> priVars0[saltConcentrationIdx];
261 priVars1[saltConcentrationIdx] = priVars0[saltConcentrationIdx];
264 static Scalar referencePressure(
const ElementContext& elemCtx,
268 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
269 return params_.referencePressure_[pvtnumRegionIdx];
272 static const TabulatedFunction& bdensityTable(
const ElementContext& elemCtx,
276 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
277 return params_.bdensityTable_[pvtnumRegionIdx];
280 static const TabulatedFunction& pcfactTable(
unsigned satnumRegionIdx)
281 {
return params_.pcfactTable_[satnumRegionIdx]; }
283 static const TabulatedFunction& permfactTable(
const ElementContext& elemCtx,
287 const unsigned satnumRegionIdx = elemCtx.problem().satnumRegionIndex(elemCtx, scvIdx, timeIdx);
288 return params_.permfactTable_[satnumRegionIdx];
291 static const TabulatedFunction& permfactTable(
unsigned satnumRegionIdx)
292 {
return params_.permfactTable_[satnumRegionIdx]; }
294 static Scalar saltsolTable(
const ElementContext& elemCtx,
298 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
299 return params_.saltsolTable_[pvtnumRegionIdx];
302 static Scalar saltsolTable(
const unsigned pvtnumRegionIdx)
304 return params_.saltsolTable_[pvtnumRegionIdx];
307 static Scalar saltdenTable(
const ElementContext& elemCtx,
311 const unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
312 return params_.saltdenTable_[pvtnumRegionIdx];
315 static Scalar saltdenTable(
const unsigned pvtnumRegionIdx)
317 return params_.saltdenTable_[pvtnumRegionIdx];
320 static bool hasBDensityTables()
321 {
return !params_.bdensityTable_.empty(); }
323 static bool hasSaltsolTables()
324 {
return !params_.saltsolTable_.empty(); }
326 static bool hasPcfactTables()
328 if constexpr (enableSaltPrecipitation) {
329 return !params_.pcfactTable_.empty();
336 static Scalar saltSol(
unsigned regionIdx)
337 {
return params_.saltsolTable_[regionIdx]; }
340 static BlackOilBrineParams<Scalar> params_;
343 template <
class TypeTag>
344 BlackOilBrineParams<typename BlackOilBrineModule<TypeTag, true>::Scalar>
345 BlackOilBrineModule<TypeTag, true>::params_;
354 template <
class TypeTag>
355 class BlackOilBrineIntensiveQuantities<TypeTag, true>
369 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
370 static constexpr
unsigned saltConcentrationIdx = Indices::saltConcentrationIdx;
371 static constexpr
int waterPhaseIdx = FluidSystem::waterPhaseIdx;
372 static constexpr
int gasPhaseIdx = FluidSystem::gasPhaseIdx;
373 static constexpr
int oilPhaseIdx = FluidSystem::oilPhaseIdx;
374 static constexpr
bool enableBrine =
true;
375 static constexpr
bool enableSaltPrecipitation =
376 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
377 static constexpr
int contiBrineEqIdx = Indices::contiBrineEqIdx;
389 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
391 updateSaltConcentration_(priVars, timeIdx, lintype);
394 OPM_HOST_DEVICE
void updateSaltConcentration_(
const PrimaryVariables& priVars,
395 const unsigned timeIdx,
398 const unsigned pvtnumRegionIdx = priVars.pvtRegionIndex();
399 auto& fs = asImp_().fluidState_;
401 if constexpr (enableSaltPrecipitation) {
402 saltSolubility_ = BrineModule::saltsolTable(pvtnumRegionIdx);
403 saltDensity_ = BrineModule::saltdenTable(pvtnumRegionIdx);
405 if (priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
406 saltSaturation_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx, lintype);
407 fs.setSaltConcentration(saltSolubility_);
410 saltConcentration_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx, lintype);
411 fs.setSaltConcentration(saltConcentration_);
412 saltSaturation_ = 0.0;
414 fs.setSaltSaturation(saltSaturation_);
417 saltConcentration_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx, lintype);
418 fs.setSaltConcentration(saltConcentration_);
422 OPM_HOST_DEVICE
void saltPropertiesUpdate_([[maybe_unused]]
const ElementContext& elemCtx,
423 [[maybe_unused]]
unsigned dofIdx,
424 [[maybe_unused]]
unsigned timeIdx)
426 if constexpr (enableSaltPrecipitation) {
427 const Evaluation porosityFactor = min(1.0 - asImp_().fluidState_.saltSaturation(), 1.0);
429 const auto& permfactTable = BrineModule::permfactTable(elemCtx, dofIdx, timeIdx);
431 permFactor_ = permfactTable.eval(porosityFactor);
435 OPM_HOST_DEVICE
const Evaluation& brineRefDensity()
const 436 {
return refDensity_; }
438 OPM_HOST_DEVICE Scalar saltSolubility()
const 439 {
return saltSolubility_; }
441 OPM_HOST_DEVICE Scalar saltDensity()
const 442 {
return saltDensity_; }
444 OPM_HOST_DEVICE
const Evaluation& permFactor()
const 445 {
return permFactor_; }
448 OPM_HOST_DEVICE Implementation& asImp_()
449 {
return *
static_cast<Implementation*
>(
this); }
451 Evaluation saltConcentration_;
452 Evaluation refDensity_;
453 Evaluation saltSaturation_;
454 Evaluation permFactor_;
455 Scalar saltSolubility_;
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 Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilbrinemodules.hh:234
static void registerParameters()
Register all run-time parameters for the black-oil brine module.
Definition: blackoilbrinemodules.hh:98
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Contains classes extending the black-oil model.
Declares the properties required by the black oil model.
static void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the brine specific primary variables to a PrimaryVariables object.
Definition: blackoilbrinemodules.hh:110
Declare the properties used by the infrastructure code of the finite volume discretizations.
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.
Contains the high level supplements required to extend the black oil model by brine.
Definition: blackoilbrinemodules.hh:57
Contains the parameters required to extend the black-oil model by brine.
OPM_HOST_DEVICE void updateSaltConcentration_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the intensive properties needed to handle brine from the primary variables.
Definition: blackoilbrinemodules.hh:385
static void setParams(BlackOilBrineParams< Scalar > &¶ms)
Set parameters.
Definition: blackoilbrinemodules.hh:90
Defines a type tags and some fundamental properties all models.