64 using Toolbox = MathToolbox<Evaluation>;
66 using TabulatedFunction =
typename BlackOilBrineParams<Scalar>::TabulatedFunction;
68 static constexpr unsigned saltConcentrationIdx = Indices::saltConcentrationIdx;
69 static constexpr unsigned contiBrineEqIdx = Indices::contiBrineEqIdx;
70 static constexpr unsigned waterPhaseIdx = FluidSystem::waterPhaseIdx;
71 static constexpr bool gasEnabled = Indices::gasEnabled;
72 static constexpr bool oilEnabled = Indices::oilEnabled;
73 static constexpr unsigned enableBrine = enableBrineV;
77 static constexpr unsigned numPhases = FluidSystem::numPhases;
93 static bool primaryVarApplies(
unsigned pvIdx)
95 if constexpr (enableBrine)
96 return pvIdx == saltConcentrationIdx;
104 template <
class Flu
idState>
106 const FluidState& fluidState)
108 if constexpr (enableBrine)
109 priVars[saltConcentrationIdx] = fluidState.saltConcentration();
112 static std::string primaryVarName([[maybe_unused]]
unsigned pvIdx)
114 assert(primaryVarApplies(pvIdx));
116 return "saltConcentration";
119 static Scalar primaryVarWeight([[maybe_unused]]
unsigned pvIdx)
121 assert(primaryVarApplies(pvIdx));
124 return static_cast<Scalar
>(1.0);
127 static bool eqApplies(
unsigned eqIdx)
129 if constexpr (enableBrine)
130 return eqIdx == contiBrineEqIdx;
135 static std::string eqName([[maybe_unused]]
unsigned eqIdx)
137 assert(eqApplies(eqIdx));
139 return "conti^brine";
142 static Scalar eqWeight([[maybe_unused]]
unsigned eqIdx)
144 assert(eqApplies(eqIdx));
147 return static_cast<Scalar
>(1.0);
151 template <
class LhsEval>
152 static void addStorage(Dune::FieldVector<LhsEval, numEq>& storage,
153 const IntensiveQuantities& intQuants)
155 if constexpr (enableBrine) {
156 const auto& fs = intQuants.fluidState();
158 LhsEval surfaceVolumeWater =
159 Toolbox::template decay<LhsEval>(fs.saturation(waterPhaseIdx))
160 * Toolbox::template decay<LhsEval>(fs.invB(waterPhaseIdx))
161 * Toolbox::template decay<LhsEval>(intQuants.porosity());
164 surfaceVolumeWater = max(surfaceVolumeWater, 1e-10);
167 const LhsEval massBrine = surfaceVolumeWater
168 * Toolbox::template decay<LhsEval>(fs.saltConcentration());
170 if (enableSaltPrecipitation){
171 double saltDensity = intQuants.saltDensity();
172 const LhsEval solidSalt =
173 Toolbox::template decay<LhsEval>(intQuants.porosity())
174 / (1.0 - Toolbox::template decay<LhsEval>(intQuants.saltSaturation()) + 1.e-8)
176 * Toolbox::template decay<LhsEval>(intQuants.saltSaturation());
178 storage[contiBrineEqIdx] += massBrine + solidSalt;
180 else { storage[contiBrineEqIdx] += massBrine;}
184 static void computeFlux([[maybe_unused]] RateVector& flux,
185 [[maybe_unused]]
const ElementContext& elemCtx,
186 [[maybe_unused]]
unsigned scvfIdx,
187 [[maybe_unused]]
unsigned timeIdx)
190 if constexpr (enableBrine) {
191 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
193 const unsigned upIdx = extQuants.upstreamIndex(FluidSystem::waterPhaseIdx);
194 const unsigned inIdx = extQuants.interiorIndex();
195 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
197 if (upIdx == inIdx) {
198 flux[contiBrineEqIdx] =
199 extQuants.volumeFlux(waterPhaseIdx)
200 *up.fluidState().invB(waterPhaseIdx)
201 *up.fluidState().saltConcentration();
204 flux[contiBrineEqIdx] =
205 extQuants.volumeFlux(waterPhaseIdx)
206 *decay<Scalar>(up.fluidState().invB(waterPhaseIdx))
207 *decay<Scalar>(up.fluidState().saltConcentration());
221 return static_cast<Scalar
>(0.0);
224 template <
class DofEntity>
225 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
227 if constexpr (enableBrine) {
228 unsigned dofIdx = model.dofMapper().index(dof);
229 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
230 outstream << priVars[saltConcentrationIdx];
234 template <
class DofEntity>
235 static void deserializeEntity(Model& model, std::istream& instream,
const DofEntity& dof)
237 if constexpr (enableBrine) {
238 unsigned dofIdx = model.dofMapper().index(dof);
239 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
240 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
242 instream >> priVars0[saltConcentrationIdx];
245 priVars1[saltConcentrationIdx] = priVars0[saltConcentrationIdx];
249 static const Scalar& referencePressure(
const ElementContext& elemCtx,
253 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
254 return params_.referencePressure_[pvtnumRegionIdx];
258 static const TabulatedFunction& bdensityTable(
const ElementContext& elemCtx,
262 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
263 return params_.bdensityTable_[pvtnumRegionIdx];
266 static const TabulatedFunction& pcfactTable(
unsigned satnumRegionIdx)
268 return params_.pcfactTable_[satnumRegionIdx];
271 static const TabulatedFunction& permfactTable(
const ElementContext& elemCtx,
275 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
276 return params_.permfactTable_[pvtnumRegionIdx];
279 static const TabulatedFunction& permfactTable(
unsigned pvtnumRegionIdx)
281 return params_.permfactTable_[pvtnumRegionIdx];
284 static const Scalar saltsolTable(
const ElementContext& elemCtx,
288 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
289 return params_.saltsolTable_[pvtnumRegionIdx];
292 static const Scalar saltdenTable(
const ElementContext& elemCtx,
296 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
297 return params_.saltdenTable_[pvtnumRegionIdx];
300 static bool hasBDensityTables()
302 return !params_.bdensityTable_.empty();
305 static bool hasSaltsolTables()
307 return !params_.saltsolTable_.empty();
310 static bool hasPcfactTables()
312 if constexpr (enableSaltPrecipitation)
313 return !params_.pcfactTable_.empty();
318 static Scalar saltSol(
unsigned regionIdx) {
319 return params_.saltsolTable_[regionIdx];
323 static BlackOilBrineParams<Scalar> params_;
354 static constexpr int saltConcentrationIdx = Indices::saltConcentrationIdx;
355 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
356 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
357 static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
358 static constexpr unsigned enableBrine = enableBrineV;
360 static constexpr int contiBrineEqIdx = Indices::contiBrineEqIdx;
373 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
375 auto& fs = asImp_().fluidState_;
377 if constexpr (enableSaltPrecipitation) {
378 const auto& saltsolTable = BrineModule::saltsolTable(elemCtx, dofIdx, timeIdx);
379 saltSolubility_ = saltsolTable;
381 const auto& saltdenTable = BrineModule::saltdenTable(elemCtx, dofIdx, timeIdx);
382 saltDensity_ = saltdenTable;
384 if (priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
385 saltSaturation_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx);
386 fs.setSaltConcentration(saltSolubility_);
389 saltConcentration_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx);
390 fs.setSaltConcentration(saltConcentration_);
391 saltSaturation_ = 0.0;
393 fs.setSaltSaturation(saltSaturation_);
396 saltConcentration_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx);
397 fs.setSaltConcentration(saltConcentration_);
401 void saltPropertiesUpdate_([[maybe_unused]]
const ElementContext& elemCtx,
402 [[maybe_unused]]
unsigned dofIdx,
403 [[maybe_unused]]
unsigned timeIdx)
405 if constexpr (enableSaltPrecipitation) {
406 const Evaluation porosityFactor = min(1.0 - saltSaturation(), 1.0);
408 const auto& permfactTable = BrineModule::permfactTable(elemCtx, dofIdx, timeIdx);
410 permFactor_ = permfactTable.eval(porosityFactor);
411 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
412 if (!FluidSystem::phaseIsActive(phaseIdx))
415 asImp_().mobility_[phaseIdx] *= permFactor_;
420 const Evaluation& saltConcentration()
const
421 {
return saltConcentration_; }
423 const Evaluation& brineRefDensity()
const
424 {
return refDensity_; }
426 const Evaluation& saltSaturation()
const
427 {
return saltSaturation_; }
429 Scalar saltSolubility()
const
430 {
return saltSolubility_; }
432 Scalar saltDensity()
const
433 {
return saltDensity_; }
435 const Evaluation& permFactor()
const
436 {
return permFactor_; }
439 Implementation& asImp_()
440 {
return *
static_cast<Implementation*
>(
this); }
442 Evaluation saltConcentration_;
443 Evaluation refDensity_;
444 Evaluation saltSaturation_;
445 Evaluation permFactor_;
446 Scalar saltSolubility_;