28#ifndef EWOMS_BLACK_OIL_BRINE_MODULE_HH
29#define EWOMS_BLACK_OIL_BRINE_MODULE_HH
36#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
37#include <opm/input/eclipse/EclipseState/Tables/PvtwsaltTable.hpp>
38#include <opm/input/eclipse/EclipseState/Tables/PcfactTable.hpp>
39#include <opm/input/eclipse/EclipseState/Tables/PermfactTable.hpp>
40#include <opm/input/eclipse/EclipseState/Tables/SaltSolubilityTable.hpp>
41#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
42#include <opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp>
45#include <dune/common/fvector.hh>
56template <class TypeTag, bool enableBrineV = getPropValue<TypeTag, Properties::EnableBrine>()>
72 using Toolbox = MathToolbox<Evaluation>;
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 unsigned enableBrine = enableBrineV;
82 static constexpr unsigned enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
84 static constexpr unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
85 static constexpr unsigned numPhases = FluidSystem::numPhases;
93 static void initFromState(
const EclipseState& eclState)
97 if (enableBrine && !eclState.runspec().phases().active(Phase::BRINE)) {
98 throw std::runtime_error(
"Non-trivial brine treatment requested at compile time, but "
99 "the deck does not contain the BRINE keyword");
101 else if (!enableBrine && eclState.runspec().phases().active(Phase::BRINE)) {
102 throw std::runtime_error(
"Brine treatment disabled at compile time, but the deck "
103 "contains the BRINE keyword");
106 if (!eclState.runspec().phases().active(Phase::BRINE))
109 const auto& tableManager = eclState.getTableManager();
111 unsigned numPvtRegions = tableManager.getTabdims().getNumPVTTables();
112 params_.referencePressure_.resize(numPvtRegions);
114 const auto& pvtwsaltTables = tableManager.getPvtwSaltTables();
117 const auto& bdensityTables = tableManager.getBrineDensityTables();
118 if (!bdensityTables.empty()) {
119 params_.bdensityTable_.resize(numPvtRegions);
120 assert(numPvtRegions == bdensityTables.size());
121 for (
unsigned pvtRegionIdx = 0; pvtRegionIdx < numPvtRegions; ++ pvtRegionIdx) {
123 const auto& pvtwsaltTable = pvtwsaltTables[pvtRegionIdx];
124 const auto& c = pvtwsaltTable.getSaltConcentrationColumn();
125 params_.bdensityTable_[pvtRegionIdx].setXYContainers(c,
bdensityTable);
129 if constexpr (enableSaltPrecipitation) {
130 const TableContainer& permfactTables = tableManager.getPermfactTables();
131 params_.permfactTable_.resize(numPvtRegions);
132 for (
size_t i = 0; i < permfactTables.size(); ++i) {
133 const PermfactTable&
permfactTable = permfactTables.getTable<PermfactTable>(i);
134 params_.permfactTable_[i].setXYContainers(
permfactTable.getPorosityChangeColumn(),
permfactTable.getPermeabilityMultiplierColumn());
137 const TableContainer& saltsolTables = tableManager.getSaltsolTables();
138 if (!saltsolTables.empty()) {
139 params_.saltsolTable_.resize(numPvtRegions);
140 params_.saltdenTable_.resize(numPvtRegions);
141 assert(numPvtRegions == saltsolTables.size());
142 for (
unsigned pvtRegionIdx = 0; pvtRegionIdx < numPvtRegions; ++ pvtRegionIdx) {
143 const SaltsolTable&
saltsolTable = saltsolTables.getTable<SaltsolTable>(pvtRegionIdx );
144 params_.saltsolTable_[pvtRegionIdx] =
saltsolTable.getSaltsolColumn().front();
145 params_.saltdenTable_[pvtRegionIdx] =
saltsolTable.getSaltdenColumn().front();
149 const TableContainer& pcfactTables = tableManager.getPcfactTables();
150 if (!pcfactTables.empty()) {
151 unsigned numSatRegions = tableManager.getTabdims().getNumSatTables();
152 params_.pcfactTable_.resize(numSatRegions);
153 for (
size_t i = 0; i < pcfactTables.size(); ++i) {
154 const PcfactTable&
pcfactTable = pcfactTables.getTable<PcfactTable>(i);
155 params_.pcfactTable_[i].setXYContainers(
pcfactTable.getPorosityChangeColumn(),
pcfactTable.getPcMultiplierColumn());
171 if constexpr (enableBrine)
172 return pvIdx == saltConcentrationIdx;
180 template <
class Flu
idState>
182 const FluidState& fluidState)
184 if constexpr (enableBrine)
185 priVars[saltConcentrationIdx] = fluidState.saltConcentration();
192 return "saltConcentration";
200 return static_cast<Scalar
>(1.0);
205 if constexpr (enableBrine)
206 return eqIdx == contiBrineEqIdx;
211 static std::string
eqName([[maybe_unused]]
unsigned eqIdx)
215 return "conti^brine";
218 static Scalar
eqWeight([[maybe_unused]]
unsigned eqIdx)
223 return static_cast<Scalar
>(1.0);
227 template <
class LhsEval>
228 static void addStorage(Dune::FieldVector<LhsEval, numEq>& storage,
229 const IntensiveQuantities& intQuants)
231 if constexpr (enableBrine) {
232 const auto& fs = intQuants.fluidState();
234 LhsEval surfaceVolumeWater =
235 Toolbox::template decay<LhsEval>(fs.saturation(waterPhaseIdx))
236 * Toolbox::template decay<LhsEval>(fs.invB(waterPhaseIdx))
237 * Toolbox::template decay<LhsEval>(intQuants.porosity());
240 surfaceVolumeWater = max(surfaceVolumeWater, 1e-10);
243 const LhsEval massBrine = surfaceVolumeWater
244 * Toolbox::template decay<LhsEval>(fs.saltConcentration());
246 if (enableSaltPrecipitation){
247 double saltDensity = intQuants.saltDensity();
248 const LhsEval solidSalt =
249 Toolbox::template decay<LhsEval>(intQuants.porosity())
250 / (1.0 - Toolbox::template decay<LhsEval>(intQuants.saltSaturation()) + 1.e-8)
252 * Toolbox::template decay<LhsEval>(intQuants.saltSaturation());
254 storage[contiBrineEqIdx] += massBrine + solidSalt;
256 else { storage[contiBrineEqIdx] += massBrine;}
261 [[maybe_unused]]
const ElementContext& elemCtx,
262 [[maybe_unused]]
unsigned scvfIdx,
263 [[maybe_unused]]
unsigned timeIdx)
266 if constexpr (enableBrine) {
267 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
269 const unsigned upIdx = extQuants.upstreamIndex(FluidSystem::waterPhaseIdx);
270 const unsigned inIdx = extQuants.interiorIndex();
271 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
273 if (upIdx == inIdx) {
274 flux[contiBrineEqIdx] =
275 extQuants.volumeFlux(waterPhaseIdx)
276 *up.fluidState().invB(waterPhaseIdx)
277 *up.fluidState().saltConcentration();
280 flux[contiBrineEqIdx] =
281 extQuants.volumeFlux(waterPhaseIdx)
282 *decay<Scalar>(up.fluidState().invB(waterPhaseIdx))
283 *decay<Scalar>(up.fluidState().saltConcentration());
297 return static_cast<Scalar
>(0.0);
300 template <
class DofEntity>
301 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
303 if constexpr (enableBrine) {
304 unsigned dofIdx = model.dofMapper().index(dof);
305 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
306 outstream << priVars[saltConcentrationIdx];
310 template <
class DofEntity>
313 if constexpr (enableBrine) {
314 unsigned dofIdx = model.dofMapper().index(dof);
315 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
316 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
318 instream >> priVars0[saltConcentrationIdx];
321 priVars1[saltConcentrationIdx] = priVars0[saltConcentrationIdx];
329 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
330 return params_.referencePressure_[pvtnumRegionIdx];
334 static const TabulatedFunction&
bdensityTable(
const ElementContext& elemCtx,
338 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
339 return params_.bdensityTable_[pvtnumRegionIdx];
342 static const TabulatedFunction&
pcfactTable(
unsigned satnumRegionIdx)
344 return params_.pcfactTable_[satnumRegionIdx];
347 static const TabulatedFunction&
permfactTable(
const ElementContext& elemCtx,
351 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
352 return params_.permfactTable_[pvtnumRegionIdx];
357 return params_.permfactTable_[pvtnumRegionIdx];
364 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
365 return params_.saltsolTable_[pvtnumRegionIdx];
372 unsigned pvtnumRegionIdx = elemCtx.problem().pvtRegionIndex(elemCtx, scvIdx, timeIdx);
373 return params_.saltdenTable_[pvtnumRegionIdx];
378 return !params_.bdensityTable_.empty();
383 return !params_.saltsolTable_.empty();
388 if constexpr (enableSaltPrecipitation)
389 return !params_.pcfactTable_.empty();
395 return params_.saltsolTable_[regionIdx];
403template <
class TypeTag,
bool enableBrineV>
404BlackOilBrineParams<typename BlackOilBrineModule<TypeTag, enableBrineV>::Scalar>
405BlackOilBrineModule<TypeTag, enableBrineV>::params_;
414template <class TypeTag, bool enableBrineV = getPropValue<TypeTag, Properties::EnableBrine>()>
429 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
430 static constexpr int saltConcentrationIdx = Indices::saltConcentrationIdx;
431 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
432 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
433 static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
434 static constexpr unsigned enableBrine = enableBrineV;
435 static constexpr unsigned enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
436 static constexpr int contiBrineEqIdx = Indices::contiBrineEqIdx;
449 const PrimaryVariables& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
451 auto& fs =
asImp_().fluidState_;
453 if constexpr (enableSaltPrecipitation) {
460 if (priVars.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
461 saltSaturation_ = priVars.makeEvaluation(saltConcentrationIdx, timeIdx);
478 [[maybe_unused]]
unsigned dofIdx,
479 [[maybe_unused]]
unsigned timeIdx)
481 if constexpr (enableSaltPrecipitation) {
482 const Evaluation porosityFactor = min(1.0 -
saltSaturation(), 1.0);
487 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
488 if (!FluidSystem::phaseIsActive(phaseIdx))
516 {
return *
static_cast<Implementation*
>(
this); }
527template <
class TypeTag>
546 {
throw std::runtime_error(
"saltConcentration() called but brine are disabled"); }
549 {
throw std::runtime_error(
"brineRefDensity() called but brine are disabled"); }
552 {
throw std::logic_error(
"saltSaturation() called but salt precipitation is disabled"); }
555 {
throw std::logic_error(
"saltSolubility() called but salt precipitation is disabled"); }
558 {
throw std::logic_error(
"saltDensity() called but salt precipitation is disabled"); }
561 {
throw std::logic_error(
"permFactor() called but salt precipitation is disabled"); }
Contains the parameters required to extend the black-oil model by brine.
Declares the properties required by the black oil model.
void updateSaltConcentration_(const ElementContext &, unsigned, unsigned)
Definition: blackoilbrinemodules.hh:535
const Scalar saltDensity() const
Definition: blackoilbrinemodules.hh:557
const Evaluation & permFactor() const
Definition: blackoilbrinemodules.hh:560
const Evaluation & saltSaturation() const
Definition: blackoilbrinemodules.hh:551
void saltPropertiesUpdate_(const ElementContext &, unsigned, unsigned)
Definition: blackoilbrinemodules.hh:540
const Scalar saltSolubility() const
Definition: blackoilbrinemodules.hh:554
const Evaluation & brineRefDensity() const
Definition: blackoilbrinemodules.hh:548
const Evaluation & saltConcentration() const
Definition: blackoilbrinemodules.hh:545
Definition: blackoilbrinemodules.hh:416
void updateSaltConcentration_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the intensive properties needed to handle brine from the primary variables.
Definition: blackoilbrinemodules.hh:445
const Evaluation & brineRefDensity() const
Definition: blackoilbrinemodules.hh:499
const Evaluation & saltSaturation() const
Definition: blackoilbrinemodules.hh:502
Evaluation permFactor_
Definition: blackoilbrinemodules.hh:521
Evaluation refDensity_
Definition: blackoilbrinemodules.hh:519
Scalar saltDensity_
Definition: blackoilbrinemodules.hh:523
const Evaluation & saltConcentration() const
Definition: blackoilbrinemodules.hh:496
Scalar saltSolubility_
Definition: blackoilbrinemodules.hh:522
Implementation & asImp_()
Definition: blackoilbrinemodules.hh:515
Evaluation saltSaturation_
Definition: blackoilbrinemodules.hh:520
Scalar saltDensity() const
Definition: blackoilbrinemodules.hh:508
Evaluation saltConcentration_
Definition: blackoilbrinemodules.hh:518
const Evaluation & permFactor() const
Definition: blackoilbrinemodules.hh:511
Scalar saltSolubility() const
Definition: blackoilbrinemodules.hh:505
void saltPropertiesUpdate_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:477
Contains the high level supplements required to extend the black oil model by brine.
Definition: blackoilbrinemodules.hh:58
static bool hasBDensityTables()
Definition: blackoilbrinemodules.hh:376
static const TabulatedFunction & bdensityTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:334
static void serializeEntity(const Model &model, std::ostream &outstream, const DofEntity &dof)
Definition: blackoilbrinemodules.hh:301
static const TabulatedFunction & permfactTable(unsigned pvtnumRegionIdx)
Definition: blackoilbrinemodules.hh:355
static Scalar saltSol(unsigned regionIdx)
Definition: blackoilbrinemodules.hh:394
static std::string eqName(unsigned eqIdx)
Definition: blackoilbrinemodules.hh:211
static bool primaryVarApplies(unsigned pvIdx)
Definition: blackoilbrinemodules.hh:169
static const TabulatedFunction & pcfactTable(unsigned satnumRegionIdx)
Definition: blackoilbrinemodules.hh:342
static const Scalar saltdenTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:368
static const TabulatedFunction & permfactTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:347
static bool hasPcfactTables()
Definition: blackoilbrinemodules.hh:386
static std::string primaryVarName(unsigned pvIdx)
Definition: blackoilbrinemodules.hh:188
static void registerParameters()
Register all run-time parameters for the black-oil brine module.
Definition: blackoilbrinemodules.hh:165
static bool hasSaltsolTables()
Definition: blackoilbrinemodules.hh:381
static Scalar eqWeight(unsigned eqIdx)
Definition: blackoilbrinemodules.hh:218
static const Scalar saltsolTable(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:360
static Scalar primaryVarWeight(unsigned pvIdx)
Definition: blackoilbrinemodules.hh:195
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:260
static bool eqApplies(unsigned eqIdx)
Definition: blackoilbrinemodules.hh:203
static void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the brine specific primary variables to a PrimaryVariables object.
Definition: blackoilbrinemodules.hh:181
static void deserializeEntity(Model &model, std::istream &instream, const DofEntity &dof)
Definition: blackoilbrinemodules.hh:311
static const Scalar & referencePressure(const ElementContext &elemCtx, unsigned scvIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:325
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilbrinemodules.hh:228
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilbrinemodules.hh:291
Definition: blackoilboundaryratevector.hh:37
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:235
Struct holding the parameters for the BlackoilBrineModule class.
Definition: blackoilbrineparams.hh:39
Tabulated1DFunction< Scalar > TabulatedFunction
Definition: blackoilbrineparams.hh:40