25#ifndef DUMUX_ENERGY_NONEQUILIBRIUM_LOCAL_RESIDUAL_HH
26#define DUMUX_ENERGY_NONEQUILIBRIUM_LOCAL_RESIDUAL_HH
43template <
class TypeTag,
int numEnergyEqFlu
id>
46template<
class TypeTag>
53 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
57 using Element =
typename GridView::template Codim<0>::Entity;
59 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
62 using Indices =
typename ModelTraits::Indices;
64 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
65 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
66 static constexpr auto energyEq0Idx = Indices::energyEq0Idx;
67 static constexpr auto energyEqSolidIdx = Indices::energyEqSolidIdx;
69 static constexpr auto numPhases = ModelTraits::numFluidPhases();
70 static constexpr auto numComponents = ModelTraits::numFluidComponents();
75 const SubControlVolume& scv,
76 const VolumeVariables& volVars,
80 storage[energyEq0Idx] += volVars.porosity()
81 * volVars.density(phaseIdx)
82 * volVars.internalEnergy(phaseIdx)
83 * volVars.saturation(phaseIdx);
90 const SubControlVolume& scv,
91 const VolumeVariables& volVars)
94 for(
int sPhaseIdx = 0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx)
96 storage[energyEqSolidIdx+sPhaseIdx] += volVars.temperatureSolid()
97 * volVars.solidHeatCapacity()
98 * volVars.solidDensity()
99 * (1.0 - volVars.porosity());
110 FluxVariables& fluxVars)
115 FluxVariables& fluxVars,
118 auto upwindTerm = [phaseIdx](
const auto& volVars)
119 {
return volVars.density(phaseIdx)*volVars.mobility(phaseIdx)*volVars.enthalpy(phaseIdx); };
122 flux[energyEq0Idx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
125 const auto diffusiveFluxes = fluxVars.molecularDiffusionFlux(phaseIdx);
126 const auto& elemVolVars = fluxVars.elemVolVars();
127 const auto& scvf = fluxVars.scvFace();
128 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
129 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
131 for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
134 if (phaseIdx == compIdx)
138 if (diffusiveFluxes[compIdx] > 0)
139 enthalpy += insideVolVars.enthalpy(phaseIdx);
141 enthalpy += outsideVolVars.enthalpy(phaseIdx);
145 flux[energyEq0Idx] += diffusiveFluxes[compIdx]*enthalpy;
147 flux[energyEq0Idx] += diffusiveFluxes[compIdx]*FluidSystem::molarMass(compIdx)*enthalpy;
153 FluxVariables& fluxVars)
156 flux[energyEq0Idx] += fluxVars.heatConductionFlux(0);
158 for(
int sPhaseIdx = 0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx)
159 flux[energyEqSolidIdx+sPhaseIdx] += fluxVars.heatConductionFlux(numPhases + sPhaseIdx);
172 const Element& element,
173 const FVElementGeometry& fvGeometry,
174 const ElementVolumeVariables& elemVolVars,
175 const SubControlVolume &scv)
178 const auto& volVars = elemVolVars[scv];
179 const Scalar characteristicLength = volVars.characteristicLength() ;
183 const Scalar as = volVars.fluidSolidInterfacialArea();
186 const Scalar TFluid = volVars.temperatureFluid(0);
187 const Scalar TSolid = volVars.temperatureSolid();
189 Scalar solidToFluidEnergyExchange ;
191 const Scalar fluidConductivity = volVars.fluidThermalConductivity(0) ;
193 const Scalar factorEnergyTransfer = volVars.factorEnergyTransfer() ;
195 solidToFluidEnergyExchange = factorEnergyTransfer * (TSolid - TFluid) / characteristicLength * as * fluidConductivity;
197 solidToFluidEnergyExchange *= volVars.nusseltNumber(0);
199 for(
int energyEqIdx = 0; energyEqIdx < numEnergyEqFluid+numEnergyEqSolid; ++energyEqIdx)
204 source[energyEq0Idx + energyEqIdx] += solidToFluidEnergyExchange;
207 source[energyEq0Idx + energyEqIdx] -= solidToFluidEnergyExchange;
210 DUNE_THROW(Dune::NotImplemented,
217template<
class TypeTag>
225 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
230 using Element =
typename GridView::template Codim<0>::Entity;
232 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
235 using Indices =
typename ModelTraits::Indices;
237 enum { numPhases = ModelTraits::numFluidPhases() };
238 enum { numEnergyEqFluid = ModelTraits::numEnergyEqFluid() };
239 enum { numEnergyEqSolid = ModelTraits::numEnergyEqSolid() };
240 enum { energyEq0Idx = Indices::energyEq0Idx };
241 enum { energyEqSolidIdx = Indices::energyEqSolidIdx};
242 enum { conti0EqIdx = Indices::conti0EqIdx };
244 enum { numComponents = ModelTraits::numFluidComponents() };
245 enum { phase0Idx = FluidSystem::phase0Idx};
246 enum { phase1Idx = FluidSystem::phase1Idx};
247 enum { sPhaseIdx = numPhases};
249 static constexpr bool enableChemicalNonEquilibrium = ModelTraits::enableChemicalNonEquilibrium();
255 const SubControlVolume& scv,
256 const VolumeVariables& volVars,
259 storage[energyEq0Idx+phaseIdx] += volVars.porosity()
260 * volVars.density(phaseIdx)
261 * volVars.internalEnergy(phaseIdx)
262 * volVars.saturation(phaseIdx);
267 FluxVariables& fluxVars,
270 auto upwindTerm = [phaseIdx](
const auto& volVars)
271 {
return volVars.density(phaseIdx)*volVars.mobility(phaseIdx)*volVars.enthalpy(phaseIdx); };
274 flux[energyEq0Idx+phaseIdx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
277 const auto diffusiveFluxes = fluxVars.molecularDiffusionFlux(phaseIdx);
278 const auto& elemVolVars = fluxVars.elemVolVars();
279 const auto& scvf = fluxVars.scvFace();
280 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
281 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
283 for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
286 if (phaseIdx == compIdx)
290 if (diffusiveFluxes[compIdx] > 0)
291 enthalpy += insideVolVars.enthalpy(phaseIdx);
293 enthalpy += outsideVolVars.enthalpy(phaseIdx);
294 flux[energyEq0Idx+phaseIdx] += diffusiveFluxes[compIdx]*FluidSystem::molarMass(compIdx)*enthalpy;
300 FluxVariables& fluxVars)
302 for(
int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
304 flux[energyEq0Idx+phaseIdx] += fluxVars.heatConductionFlux(phaseIdx);
306 for(
int sPhaseIdx=0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx)
308 flux[energyEqSolidIdx+sPhaseIdx] += fluxVars.heatConductionFlux(numPhases + sPhaseIdx);
319 FluxVariables& fluxVars)
332 const Element& element,
333 const FVElementGeometry& fvGeometry,
334 const ElementVolumeVariables& elemVolVars,
335 const SubControlVolume &scv)
338 const auto &volVars = elemVolVars[scv];
340 const Scalar awn = volVars.interfacialArea(phase0Idx, phase1Idx);
341 const Scalar aws = volVars.interfacialArea(phase0Idx, sPhaseIdx);
342 const Scalar ans = volVars.interfacialArea(phase1Idx, sPhaseIdx);
344 const Scalar Tw = volVars.temperatureFluid(phase0Idx);
345 const Scalar Tn = volVars.temperatureFluid(phase1Idx);
346 const Scalar Ts = volVars.temperatureSolid();
348 const Scalar lambdaWetting = volVars.fluidThermalConductivity(phase0Idx);
349 const Scalar lambdaNonwetting = volVars.fluidThermalConductivity(phase1Idx);
350 const Scalar lambdaSolid = volVars.solidThermalConductivity();
352 const Scalar lambdaWN =
harmonicMean(lambdaWetting, lambdaNonwetting);
353 const Scalar lambdaWS =
harmonicMean(lambdaWetting, lambdaSolid);
354 const Scalar lambdaNS =
harmonicMean(lambdaNonwetting, lambdaSolid);
356 const Scalar characteristicLength = volVars.characteristicLength() ;
357 const Scalar factorEnergyTransfer = volVars.factorEnergyTransfer() ;
359 const Scalar nusseltWN =
harmonicMean(volVars.nusseltNumber(phase0Idx), volVars.nusseltNumber(phase1Idx));
360 const Scalar nusseltWS = volVars.nusseltNumber(phase0Idx);
361 const Scalar nusseltNS = volVars.nusseltNumber(phase1Idx);
363 const Scalar wettingToNonwettingEnergyExchange = factorEnergyTransfer * (Tw - Tn) / characteristicLength * awn * lambdaWN * nusseltWN ;
364 const Scalar wettingToSolidEnergyExchange = factorEnergyTransfer * (Tw - Ts) / characteristicLength * aws * lambdaWS * nusseltWS ;
365 const Scalar nonwettingToSolidEnergyExchange = factorEnergyTransfer * (Tn - Ts) / characteristicLength * ans * lambdaNS * nusseltNS ;
367 for(
int phaseIdx = 0; phaseIdx < numEnergyEqFluid+numEnergyEqSolid; ++phaseIdx)
372 source[energyEq0Idx + phaseIdx] += ( - wettingToNonwettingEnergyExchange - wettingToSolidEnergyExchange);
375 source[energyEq0Idx + phaseIdx] += (+ wettingToNonwettingEnergyExchange - nonwettingToSolidEnergyExchange);
378 source[energyEq0Idx + phaseIdx] += (+ wettingToSolidEnergyExchange + nonwettingToSolidEnergyExchange);
381 DUNE_THROW(Dune::NotImplemented,
387 if (!isfinite(source[energyEq0Idx + phaseIdx]))
388 DUNE_THROW(
NumericalProblem,
"Calculated non-finite source, " <<
"Tw="<< Tw <<
" Tn="<< Tn<<
" Ts="<< Ts);
392 if (enableChemicalNonEquilibrium)
405 const auto& fluidState = volVars.fluidState();
407 for(
int phaseIdx = 0; phaseIdx < numEnergyEqFluid+numEnergyEqSolid; ++phaseIdx)
413 for(
int compIdx = 0; compIdx < numComponents; ++compIdx)
415 const unsigned int eqIdx = conti0EqIdx + compIdx + phaseIdx*numComponents;
416 source[energyEq0Idx + phaseIdx] += (source[eqIdx]
417 * FluidSystem::molarMass(compIdx)
418 * FluidSystem::componentEnthalpy(fluidState, phase1Idx, compIdx) );
423 for(
int compIdx =0; compIdx<numComponents; ++compIdx)
425 const unsigned int eqIdx = conti0EqIdx + compIdx + phaseIdx*numComponents;
426 source[energyEq0Idx + phaseIdx] += (source[eqIdx]
427 * FluidSystem::molarMass(compIdx)
428 *FluidSystem::componentEnthalpy(fluidState, phase0Idx, compIdx));
434 DUNE_THROW(Dune::NotImplemented,
The reference frameworks and formulations available for splitting total fluxes into a advective and d...
A helper to deduce a vector with the same size as numbers of equations.
Some exceptions thrown in DuMux
Provides 3rd order polynomial splines.
constexpr Scalar harmonicMean(Scalar x, Scalar y, Scalar wx=1.0, Scalar wy=1.0) noexcept
Calculate the (weighted) harmonic mean of two scalar values.
Definition: math.hh:69
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition: numeqvector.hh:46
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:150
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:39
This file contains the parts of the local residual to calculate the heat conservation in the thermal ...
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:44
static void computeSourceEnergy(NumEqVector &source, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv)
heat transfer between the phases for nonequilibrium models
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:171
static void solidPhaseStorage(NumEqVector &storage, const SubControlVolume &scv, const VolumeVariables &volVars)
The energy storage in the solid matrix.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:89
static void heatDispersionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The dispersive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:109
static void fluidPhaseStorage(NumEqVector &storage, const SubControlVolume &scv, const VolumeVariables &volVars, int phaseIdx)
The energy storage in the fluid phase with index phaseIdx.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:74
static void heatConductionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The diffusive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:152
static void heatConvectionFlux(NumEqVector &flux, FluxVariables &fluxVars, int phaseIdx)
The advective phase energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:114
static void heatDispersionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The dispersive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:318
static void computeSourceEnergy(NumEqVector &source, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv)
Calculates the source term of the equation.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:331
static void heatConvectionFlux(NumEqVector &flux, FluxVariables &fluxVars, int phaseIdx)
The advective phase energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:266
static void heatConductionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The diffusive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:299
static void fluidPhaseStorage(NumEqVector &storage, const SubControlVolume &scv, const VolumeVariables &volVars, int phaseIdx)
The energy storage in the fluid phase with index phaseIdx.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:254
Declares all properties used in Dumux.