28#ifndef EWOMS_BLACK_OIL_ENERGY_MODULE_HH
29#define EWOMS_BLACK_OIL_ENERGY_MODULE_HH
31#include <dune/common/fvector.hh>
33#include <opm/material/common/Tabulated1DFunction.hpp>
34#include <opm/material/common/Valgrind.hpp>
56template <class TypeTag, bool enableEnergyV = getPropValue<TypeTag, Properties::EnableEnergy>()>
71 static constexpr unsigned temperatureIdx = Indices::temperatureIdx;
72 static constexpr unsigned contiEnergyEqIdx = Indices::contiEnergyEqIdx;
74 static constexpr unsigned enableEnergy = enableEnergyV;
75 static constexpr unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
76 static constexpr unsigned numPhases = FluidSystem::numPhases;
86 if constexpr (enableEnergy) {
97 if constexpr (enableEnergy) {
104 if constexpr (enableEnergy) {
105 return pvIdx == temperatureIdx;
116 return "temperature";
124 return static_cast<Scalar
>(1.0);
129 if constexpr (enableEnergy) {
130 return eqIdx == contiEnergyEqIdx;
137 static std::string
eqName([[maybe_unused]]
unsigned eqIdx)
141 return "conti^energy";
144 static Scalar
eqWeight([[maybe_unused]]
unsigned eqIdx)
152 template <
class LhsEval>
153 static void addStorage(Dune::FieldVector<LhsEval, numEq>& storage,
154 const IntensiveQuantities& intQuants)
156 if constexpr (enableEnergy) {
157 const auto& poro = decay<LhsEval>(intQuants.porosity());
160 const auto& fs = intQuants.fluidState();
161 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
162 if (!FluidSystem::phaseIsActive(phaseIdx)) {
166 const auto& u = decay<LhsEval>(fs.internalEnergy(phaseIdx));
167 const auto& S = decay<LhsEval>(fs.saturation(phaseIdx));
168 const auto& rho = decay<LhsEval>(fs.density(phaseIdx));
170 storage[contiEnergyEqIdx] += poro*S*u*rho;
174 const Scalar rockFraction = intQuants.rockFraction();
175 const auto& uRock = decay<LhsEval>(intQuants.rockInternalEnergy());
176 storage[contiEnergyEqIdx] += rockFraction * uRock;
177 storage[contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
182 [[maybe_unused]]
const ElementContext& elemCtx,
183 [[maybe_unused]]
unsigned scvfIdx,
184 [[maybe_unused]]
unsigned timeIdx)
186 if constexpr (enableEnergy) {
187 flux[contiEnergyEqIdx] = 0.0;
189 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
190 const unsigned focusIdx = elemCtx.focusDofIndex();
191 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
192 if (!FluidSystem::phaseIsActive(phaseIdx)) {
196 const unsigned upIdx = extQuants.upstreamIndex(phaseIdx);
197 if (upIdx == focusIdx) {
198 addPhaseEnthalpyFlux_<Evaluation>(flux, phaseIdx, elemCtx, scvfIdx, timeIdx);
201 addPhaseEnthalpyFlux_<Scalar>(flux, phaseIdx, elemCtx, scvfIdx, timeIdx);
206 flux[contiEnergyEqIdx] += extQuants.energyFlux();
207 flux[contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
212 const Evaluation& heatFlux)
214 if constexpr (enableEnergy) {
216 flux[contiEnergyEqIdx] += heatFlux;
217 flux[contiEnergyEqIdx] *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
221 template <
class UpEval,
class Eval,
class Flu
idState>
224 const Eval& volumeFlux,
225 const FluidState& upFs)
227 flux[contiEnergyEqIdx] +=
228 decay<UpEval>(upFs.enthalpy(phaseIdx)) *
229 decay<UpEval>(upFs.density(phaseIdx)) *
233 template <
class UpstreamEval>
236 const ElementContext& elemCtx,
240 const auto& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
241 const unsigned upIdx = extQuants.upstreamIndex(phaseIdx);
242 const auto& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
243 const auto& fs = up.fluidState();
244 const auto& volFlux = extQuants.volumeFlux(phaseIdx);
245 addPhaseEnthalpyFluxes_<UpstreamEval>(flux,
252 const Evaluation& hRate)
254 if constexpr (enableEnergy) {
255 flux[contiEnergyEqIdx] += hRate;
262 template <
class Flu
idState>
264 const FluidState& fluidState)
266 if constexpr (enableEnergy) {
267 priVars[temperatureIdx] = fluidState.temperature(0);
275 const PrimaryVariables& oldPv,
276 const EqVector& delta)
278 if constexpr (enableEnergy) {
280 newPv[temperatureIdx] = oldPv[temperatureIdx] - delta[temperatureIdx];
293 return static_cast<Scalar
>(0.0);
302 return std::abs(scalarValue(resid[contiEnergyEqIdx]));
305 template <
class DofEntity>
306 static void serializeEntity(
const Model& model, std::ostream& outstream,
const DofEntity& dof)
308 if constexpr (enableEnergy) {
309 const unsigned dofIdx = model.dofMapper().index(dof);
310 const PrimaryVariables& priVars = model.solution(0)[dofIdx];
311 outstream << priVars[temperatureIdx];
315 template <
class DofEntity>
318 if constexpr (enableEnergy) {
319 const unsigned dofIdx = model.dofMapper().index(dof);
320 PrimaryVariables& priVars0 = model.solution(0)[dofIdx];
321 PrimaryVariables& priVars1 = model.solution(1)[dofIdx];
323 instream >> priVars0[temperatureIdx];
326 priVars1 = priVars0[temperatureIdx];
331template <
class TypeTag,
bool enableEnergyV>
341template <
class TypeTag>
358 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
359 static constexpr int temperatureIdx = Indices::temperatureIdx;
360 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
371 auto& fs = asImp_().fluidState_;
372 const auto& priVars = elemCtx.primaryVars(dofIdx, timeIdx);
375 fs.setTemperature(priVars.makeEvaluation(temperatureIdx, timeIdx, elemCtx.linearizationType()));
383 const PrimaryVariables& priVars,
384 [[maybe_unused]]
unsigned globalDofIdx,
385 const unsigned timeIdx,
388 auto& fs = asImp_().fluidState_;
389 fs.setTemperature(priVars.makeEvaluation(temperatureIdx, timeIdx, lintype));
400 updateEnergyQuantities_(elemCtx.problem(), elemCtx.globalSpaceIndex(dofIdx, timeIdx), timeIdx);
404 const unsigned globalSpaceIdx,
405 const unsigned timeIdx)
407 auto& fs = asImp_().fluidState_;
411 for (
int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
412 if (!FluidSystem::phaseIsActive(phaseIdx)) {
416 const auto& h = FluidSystem::enthalpy(fs, phaseIdx, problem.pvtRegionIndex(globalSpaceIdx));
417 fs.setEnthalpy(phaseIdx, h);
420 const auto& solidEnergyLawParams = problem.solidEnergyLawParams(globalSpaceIdx, timeIdx);
421 rockInternalEnergy_ = SolidEnergyLaw::solidInternalEnergy(solidEnergyLawParams, fs);
423 const auto& thermalConductionLawParams = problem.thermalConductionLawParams(globalSpaceIdx, timeIdx);
424 totalThermalConductivity_ = ThermalConductionLaw::thermalConductivity(thermalConductionLawParams, fs);
431 rockFraction_ = problem.rockFraction(globalSpaceIdx, timeIdx);
435 {
return rockInternalEnergy_; }
438 {
return totalThermalConductivity_; }
441 {
return rockFraction_; }
445 {
return *
static_cast<Implementation*
>(
this); }
452template <
class TypeTag>
463 static constexpr bool enableTemperature = getPropValue<TypeTag, Properties::EnableTemperature>();
467 [[maybe_unused]]
unsigned dofIdx,
468 [[maybe_unused]]
unsigned timeIdx)
470 if constexpr (enableTemperature) {
473 auto& fs = asImp_().fluidState_;
474 const Scalar T = elemCtx.problem().temperature(elemCtx, dofIdx, timeIdx);
475 fs.setTemperature(T);
479 template<
class Problem>
481 [[maybe_unused]]
const PrimaryVariables& priVars,
482 [[maybe_unused]]
unsigned globalDofIdx,
483 [[maybe_unused]]
unsigned timeIdx,
487 if constexpr (enableTemperature) {
488 auto& fs = asImp_().fluidState_;
491 const Scalar T = problem.temperature(globalDofIdx, timeIdx);
492 fs.setTemperature(T);
499 const typename FluidSystem::template ParameterCache<Evaluation>&)
504 throw std::logic_error(
"Requested the rock internal energy, which is "
505 "unavailable because energy is not conserved");
510 throw std::logic_error(
"Requested the total thermal conductivity, which is "
511 "unavailable because energy is not conserved");
516 {
return *
static_cast<Implementation*
>(
this); }
519template <
class TypeTag,
bool enableEnergyV>
529template <
class TypeTag>
542 using Toolbox = MathToolbox<Evaluation>;
546 static constexpr int dimWorld = GridView::dimensionworld;
547 using DimVector = Dune::FieldVector<Scalar, dimWorld>;
548 using DimEvalVector = Dune::FieldVector<Evaluation, dimWorld>;
551 template<
class Flu
idState>
553 const unsigned& focusDofIndex,
554 const unsigned& inIdx,
555 const unsigned& exIdx,
556 const IntensiveQuantities& inIq,
557 const IntensiveQuantities& exIq,
558 const FluidState& inFs,
559 const FluidState& exFs,
560 const Scalar& inAlpha,
561 const Scalar& outAlpha,
562 const Scalar& faceArea)
565 if (focusDofIndex == inIdx) {
566 deltaT = decay<Scalar>(exFs.temperature(0)) -
569 else if (focusDofIndex == exIdx) {
570 deltaT = exFs.temperature(0) -
571 decay<Scalar>(inFs.temperature(0));
574 deltaT = decay<Scalar>(exFs.temperature(0)) -
575 decay<Scalar>(inFs.temperature(0));
579 if (focusDofIndex == inIdx) {
580 inLambda = inIq.totalThermalConductivity();
583 inLambda = decay<Scalar>(inIq.totalThermalConductivity());
587 if (focusDofIndex == exIdx) {
588 exLambda = exIq.totalThermalConductivity();
591 exLambda = decay<Scalar>(exIq.totalThermalConductivity());
595 const Evaluation& inH = inLambda*inAlpha;
596 const Evaluation& exH = exLambda*outAlpha;
597 if (inH > 0 && exH > 0) {
602 H = 1.0 / (1.0 / inH + 1.0 / exH);
608 energyFlux = deltaT * (-H / faceArea);
615 const auto& stencil = elemCtx.stencil(timeIdx);
616 const auto& scvf = stencil.interiorFace(scvfIdx);
618 const Scalar faceArea = scvf.area();
619 const unsigned inIdx = scvf.interiorIndex();
620 const unsigned exIdx = scvf.exteriorIndex();
621 const auto& inIq = elemCtx.intensiveQuantities(inIdx, timeIdx);
622 const auto& exIq = elemCtx.intensiveQuantities(exIdx, timeIdx);
623 const auto& inFs = inIq.fluidState();
624 const auto& exFs = exIq.fluidState();
625 const Scalar inAlpha = elemCtx.problem().thermalHalfTransmissibilityIn(elemCtx, scvfIdx, timeIdx);
626 const Scalar outAlpha = elemCtx.problem().thermalHalfTransmissibilityOut(elemCtx, scvfIdx, timeIdx);
627 updateEnergy(energyFlux_,
628 elemCtx.focusDofIndex(),
640 template <
class Context,
class BoundaryFlu
idState>
644 const BoundaryFluidState& boundaryFs)
646 const auto& stencil = ctx.stencil(timeIdx);
647 const auto& scvf = stencil.boundaryFace(scvfIdx);
649 const unsigned inIdx = scvf.interiorIndex();
650 const auto& inIq = ctx.intensiveQuantities(inIdx, timeIdx);
651 const auto& focusDofIdx = ctx.focusDofIndex();
652 const Scalar alpha = ctx.problem().thermalHalfTransmissibilityBoundary(ctx, scvfIdx);
653 updateEnergyBoundary(energyFlux_, inIq, focusDofIdx, inIdx, alpha, boundaryFs);
656 template <
class BoundaryFlu
idState>
658 const IntensiveQuantities& inIq,
659 unsigned focusDofIndex,
662 const BoundaryFluidState& boundaryFs)
664 const auto& inFs = inIq.fluidState();
666 if (focusDofIndex == inIdx) {
667 deltaT = boundaryFs.temperature(0) -
671 deltaT = decay<Scalar>(boundaryFs.temperature(0)) -
672 decay<Scalar>(inFs.temperature(0));
676 if (focusDofIndex == inIdx) {
677 lambda = inIq.totalThermalConductivity();
680 lambda = decay<Scalar>(inIq.totalThermalConductivity());
688 energyFlux = deltaT * lambda * -alpha;
696 {
return energyFlux_; }
699 Implementation& asImp_()
700 {
return *
static_cast<Implementation*
>(
this); }
702 Evaluation energyFlux_;
705template <
class TypeTag>
714 template<
class Flu
idState>
719 const IntensiveQuantities& ,
720 const IntensiveQuantities& ,
733 template <
class Context,
class BoundaryFlu
idState>
737 const BoundaryFluidState&)
740 template <
class BoundaryFlu
idState>
742 const IntensiveQuantities& ,
747 const BoundaryFluidState& )
751 {
throw std::logic_error(
"Requested the energy flux, but energy is not conserved"); }
Declares the properties required by the black oil model.
void updateEnergyBoundary(const Context &, unsigned, unsigned, const BoundaryFluidState &)
Definition: blackoilenergymodules.hh:734
static void updateEnergy(Evaluation &, const unsigned &, const unsigned &, const unsigned &, const IntensiveQuantities &, const IntensiveQuantities &, const FluidState &, const FluidState &, const Scalar &, const Scalar &, const Scalar &)
Definition: blackoilenergymodules.hh:715
static void updateEnergyBoundary(Evaluation &, const IntensiveQuantities &, unsigned, unsigned, unsigned, Scalar, const BoundaryFluidState &)
Definition: blackoilenergymodules.hh:741
void updateEnergy(const ElementContext &, unsigned, unsigned)
Definition: blackoilenergymodules.hh:728
const Evaluation & energyFlux() const
Definition: blackoilenergymodules.hh:750
void updateEnergyBoundary(const Context &ctx, unsigned scvfIdx, unsigned timeIdx, const BoundaryFluidState &boundaryFs)
Definition: blackoilenergymodules.hh:641
static void updateEnergyBoundary(Evaluation &energyFlux, const IntensiveQuantities &inIq, unsigned focusDofIndex, unsigned inIdx, Scalar alpha, const BoundaryFluidState &boundaryFs)
Definition: blackoilenergymodules.hh:657
static void updateEnergy(Evaluation &energyFlux, const unsigned &focusDofIndex, const unsigned &inIdx, const unsigned &exIdx, const IntensiveQuantities &inIq, const IntensiveQuantities &exIq, const FluidState &inFs, const FluidState &exFs, const Scalar &inAlpha, const Scalar &outAlpha, const Scalar &faceArea)
Definition: blackoilenergymodules.hh:552
const Evaluation & energyFlux() const
Definition: blackoilenergymodules.hh:695
void updateEnergy(const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:611
Provides the energy specific extensive quantities to the generic black-oil module's extensive quantit...
Definition: blackoilenergymodules.hh:520
void updateEnergyQuantities_(const ElementContext &, unsigned, unsigned, const typename FluidSystem::template ParameterCache< Evaluation > &)
Definition: blackoilenergymodules.hh:496
const Evaluation & rockInternalEnergy() const
Definition: blackoilenergymodules.hh:502
const Evaluation & totalThermalConductivity() const
Definition: blackoilenergymodules.hh:508
void updateTemperature_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:466
void updateTemperature_(const Problem &problem, const PrimaryVariables &priVars, unsigned globalDofIdx, unsigned timeIdx, const LinearizationType &lintype)
Definition: blackoilenergymodules.hh:480
Implementation & asImp_()
Definition: blackoilenergymodules.hh:515
Evaluation totalThermalConductivity_
Definition: blackoilenergymodules.hh:448
const Evaluation & totalThermalConductivity() const
Definition: blackoilenergymodules.hh:437
void updateEnergyQuantities_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Compute the intensive quantities needed to handle energy conservation.
Definition: blackoilenergymodules.hh:396
Scalar rockFraction() const
Definition: blackoilenergymodules.hh:440
Implementation & asImp_()
Definition: blackoilenergymodules.hh:444
void updateTemperature_(const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx)
Update the temperature of the intensive quantity's fluid state.
Definition: blackoilenergymodules.hh:367
Scalar rockFraction_
Definition: blackoilenergymodules.hh:449
void updateTemperature_(const Problem &problem, const PrimaryVariables &priVars, unsigned globalDofIdx, const unsigned timeIdx, const LinearizationType &lintype)
Update the temperature of the intensive quantity's fluid state.
Definition: blackoilenergymodules.hh:382
const Evaluation & rockInternalEnergy() const
Definition: blackoilenergymodules.hh:434
void updateEnergyQuantities_(const Problem &problem, const unsigned globalSpaceIdx, const unsigned timeIdx)
Definition: blackoilenergymodules.hh:403
Evaluation rockInternalEnergy_
Definition: blackoilenergymodules.hh:447
Provides the volumetric quantities required for the equations needed by the energys extension of the ...
Definition: blackoilenergymodules.hh:332
Contains the high level supplements required to extend the black oil model by energy.
Definition: blackoilenergymodules.hh:58
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:181
static void registerParameters()
Register all run-time parameters for the black-oil energy module.
Definition: blackoilenergymodules.hh:84
GetPropType< TypeTag, Properties::ExtensiveQuantities > ExtensiveQuantities
Definition: blackoilenergymodules.hh:79
static Scalar computeResidualError(const EqVector &resid)
Return how much a residual is considered an error.
Definition: blackoilenergymodules.hh:299
static void deserializeEntity(Model &model, std::istream &instream, const DofEntity &dof)
Definition: blackoilenergymodules.hh:316
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilenergymodules.hh:153
static bool primaryVarApplies(unsigned pvIdx)
Definition: blackoilenergymodules.hh:102
static std::string primaryVarName(unsigned pvIdx)
Definition: blackoilenergymodules.hh:112
static std::string eqName(unsigned eqIdx)
Definition: blackoilenergymodules.hh:137
static void serializeEntity(const Model &model, std::ostream &outstream, const DofEntity &dof)
Definition: blackoilenergymodules.hh:306
static Scalar primaryVarWeight(unsigned pvIdx)
Definition: blackoilenergymodules.hh:119
static void updatePrimaryVars(PrimaryVariables &newPv, const PrimaryVariables &oldPv, const EqVector &delta)
Do a Newton-Raphson update the primary variables of the energys.
Definition: blackoilenergymodules.hh:274
static void addToEnthalpyRate(RateVector &flux, const Evaluation &hRate)
Definition: blackoilenergymodules.hh:251
static void addHeatFlux(RateVector &flux, const Evaluation &heatFlux)
Definition: blackoilenergymodules.hh:211
static void registerOutputModules(Model &model, Simulator &simulator)
Register all energy specific VTK and ECL output modules.
Definition: blackoilenergymodules.hh:94
static void addPhaseEnthalpyFlux_(RateVector &flux, unsigned phaseIdx, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:234
static void addPhaseEnthalpyFluxes_(RateVector &flux, unsigned phaseIdx, const Eval &volumeFlux, const FluidState &upFs)
Definition: blackoilenergymodules.hh:222
static bool eqApplies(unsigned eqIdx)
Definition: blackoilenergymodules.hh:127
static Scalar computeUpdateError(const PrimaryVariables &, const EqVector &)
Return how much a Newton-Raphson update is considered an error.
Definition: blackoilenergymodules.hh:287
static void assignPrimaryVars(PrimaryVariables &priVars, const FluidState &fluidState)
Assign the energy specific primary variables to a PrimaryVariables object.
Definition: blackoilenergymodules.hh:263
static Scalar eqWeight(unsigned eqIdx)
Definition: blackoilenergymodules.hh:144
VTK output module for the black oil model's energy related quantities.
Definition: vtkblackoilenergymodule.hpp:54
static void registerParameters()
Register all run-time parameters for the multi-phase VTK output module.
Definition: vtkblackoilenergymodule.hpp:87
Definition: blackoilboundaryratevector.hh:39
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
This method contains all callback classes for quantities that are required by some extensive quantiti...
Definition: linearizationtype.hh:34