14#ifndef DUMUX_ENERGY_NONEQUILIBRIUM_LOCAL_RESIDUAL_HH
15#define DUMUX_ENERGY_NONEQUILIBRIUM_LOCAL_RESIDUAL_HH
32template <
class TypeTag,
int numEnergyEqFlu
id>
35template<
class TypeTag>
42 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
46 using Element =
typename GridView::template Codim<0>::Entity;
48 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
51 using Indices =
typename ModelTraits::Indices;
53 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
54 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
55 static constexpr auto energyEq0Idx = Indices::energyEq0Idx;
56 static constexpr auto energyEqSolidIdx = Indices::energyEqSolidIdx;
58 static constexpr auto numPhases = ModelTraits::numFluidPhases();
59 static constexpr auto numComponents = ModelTraits::numFluidComponents();
64 const SubControlVolume& scv,
65 const VolumeVariables& volVars,
69 storage[energyEq0Idx] += volVars.porosity()
70 * volVars.density(phaseIdx)
71 * volVars.internalEnergy(phaseIdx)
72 * volVars.saturation(phaseIdx);
79 const SubControlVolume& scv,
80 const VolumeVariables& volVars)
83 for(
int sPhaseIdx = 0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx)
85 storage[energyEqSolidIdx+sPhaseIdx] += volVars.temperatureSolid()
86 * volVars.solidHeatCapacity()
87 * volVars.solidDensity()
88 * (1.0 - volVars.porosity());
99 FluxVariables& fluxVars)
104 FluxVariables& fluxVars,
107 auto upwindTerm = [phaseIdx](
const auto& volVars)
108 {
return volVars.density(phaseIdx)*volVars.mobility(phaseIdx)*volVars.enthalpy(phaseIdx); };
111 flux[energyEq0Idx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
114 const auto diffusiveFluxes = fluxVars.molecularDiffusionFlux(phaseIdx);
115 const auto& elemVolVars = fluxVars.elemVolVars();
116 const auto& scvf = fluxVars.scvFace();
117 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
118 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
120 for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
123 if (phaseIdx == compIdx)
127 if (diffusiveFluxes[compIdx] > 0)
128 enthalpy += insideVolVars.enthalpy(phaseIdx);
130 enthalpy += outsideVolVars.enthalpy(phaseIdx);
134 flux[energyEq0Idx] += diffusiveFluxes[compIdx]*enthalpy;
136 flux[energyEq0Idx] += diffusiveFluxes[compIdx]*FluidSystem::molarMass(compIdx)*enthalpy;
142 FluxVariables& fluxVars)
145 flux[energyEq0Idx] += fluxVars.heatConductionFlux(0);
147 for(
int sPhaseIdx = 0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx)
148 flux[energyEqSolidIdx+sPhaseIdx] += fluxVars.heatConductionFlux(numPhases + sPhaseIdx);
161 const Element& element,
162 const FVElementGeometry& fvGeometry,
163 const ElementVolumeVariables& elemVolVars,
164 const SubControlVolume &scv)
167 const auto& volVars = elemVolVars[scv];
168 const Scalar characteristicLength = volVars.characteristicLength() ;
172 const Scalar as = volVars.fluidSolidInterfacialArea();
175 const Scalar TFluid = volVars.temperatureFluid(0);
176 const Scalar TSolid = volVars.temperatureSolid();
178 Scalar solidToFluidEnergyExchange ;
180 const Scalar fluidConductivity = volVars.fluidThermalConductivity(0) ;
182 const Scalar factorEnergyTransfer = volVars.factorEnergyTransfer() ;
184 solidToFluidEnergyExchange = factorEnergyTransfer * (TSolid - TFluid) / characteristicLength * as * fluidConductivity;
186 solidToFluidEnergyExchange *= volVars.nusseltNumber(0);
188 for(
int energyEqIdx = 0; energyEqIdx < numEnergyEqFluid+numEnergyEqSolid; ++energyEqIdx)
193 source[energyEq0Idx + energyEqIdx] += solidToFluidEnergyExchange;
196 source[energyEq0Idx + energyEqIdx] -= solidToFluidEnergyExchange;
199 DUNE_THROW(Dune::NotImplemented,
210template<
class TypeTag>
218 using SubControlVolume =
typename FVElementGeometry::SubControlVolume;
223 using Element =
typename GridView::template Codim<0>::Entity;
225 using SubControlVolumeFace =
typename FVElementGeometry::SubControlVolumeFace;
228 using Indices =
typename ModelTraits::Indices;
230 enum { numPhases = ModelTraits::numFluidPhases() };
231 enum { numEnergyEqFluid = ModelTraits::numEnergyEqFluid() };
232 enum { numEnergyEqSolid = ModelTraits::numEnergyEqSolid() };
233 enum { energyEq0Idx = Indices::energyEq0Idx };
234 enum { energyEqSolidIdx = Indices::energyEqSolidIdx};
235 enum { conti0EqIdx = Indices::conti0EqIdx };
237 enum { numComponents = ModelTraits::numFluidComponents() };
238 enum { phase0Idx = FluidSystem::phase0Idx};
239 enum { phase1Idx = FluidSystem::phase1Idx};
240 enum { sPhaseIdx = numPhases};
242 static constexpr bool enableChemicalNonEquilibrium = ModelTraits::enableChemicalNonEquilibrium();
248 const SubControlVolume& scv,
249 const VolumeVariables& volVars,
252 storage[energyEq0Idx+phaseIdx] += volVars.porosity()
253 * volVars.density(phaseIdx)
254 * volVars.internalEnergy(phaseIdx)
255 * volVars.saturation(phaseIdx);
260 FluxVariables& fluxVars,
263 auto upwindTerm = [phaseIdx](
const auto& volVars)
264 {
return volVars.density(phaseIdx)*volVars.mobility(phaseIdx)*volVars.enthalpy(phaseIdx); };
267 flux[energyEq0Idx+phaseIdx] += fluxVars.advectiveFlux(phaseIdx, upwindTerm);
270 const auto diffusiveFluxes = fluxVars.molecularDiffusionFlux(phaseIdx);
271 const auto& elemVolVars = fluxVars.elemVolVars();
272 const auto& scvf = fluxVars.scvFace();
273 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
274 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
276 for (
int compIdx = 0; compIdx < numComponents; ++compIdx)
279 if (phaseIdx == compIdx)
283 if (diffusiveFluxes[compIdx] > 0)
284 enthalpy += insideVolVars.enthalpy(phaseIdx);
286 enthalpy += outsideVolVars.enthalpy(phaseIdx);
287 flux[energyEq0Idx+phaseIdx] += diffusiveFluxes[compIdx]*FluidSystem::molarMass(compIdx)*enthalpy;
293 FluxVariables& fluxVars)
295 for(
int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
297 flux[energyEq0Idx+phaseIdx] += fluxVars.heatConductionFlux(phaseIdx);
299 for(
int sPhaseIdx=0; sPhaseIdx<numEnergyEqSolid; ++sPhaseIdx)
301 flux[energyEqSolidIdx+sPhaseIdx] += fluxVars.heatConductionFlux(numPhases + sPhaseIdx);
312 FluxVariables& fluxVars)
325 const Element& element,
326 const FVElementGeometry& fvGeometry,
327 const ElementVolumeVariables& elemVolVars,
328 const SubControlVolume &scv)
331 const auto &volVars = elemVolVars[scv];
333 const Scalar areaWN = volVars.interfacialArea(phase0Idx, phase1Idx);
334 const Scalar areaWS = volVars.interfacialArea(phase0Idx, sPhaseIdx);
335 const Scalar areaNS = volVars.interfacialArea(phase1Idx, sPhaseIdx);
337 const Scalar Tw = volVars.temperatureFluid(phase0Idx);
338 const Scalar Tn = volVars.temperatureFluid(phase1Idx);
339 const Scalar Ts = volVars.temperatureSolid();
341 const Scalar lambdaWetting = volVars.fluidThermalConductivity(phase0Idx);
342 const Scalar lambdaNonwetting = volVars.fluidThermalConductivity(phase1Idx);
343 const Scalar lambdaSolid = volVars.solidThermalConductivity();
345 const Scalar lambdaWN =
harmonicMean(lambdaWetting, lambdaNonwetting);
346 const Scalar lambdaWS =
harmonicMean(lambdaWetting, lambdaSolid);
347 const Scalar lambdaNS =
harmonicMean(lambdaNonwetting, lambdaSolid);
349 const Scalar characteristicLength = volVars.characteristicLength() ;
350 const Scalar factorEnergyTransfer = volVars.factorEnergyTransfer() ;
352 const Scalar nusseltWN =
harmonicMean(volVars.nusseltNumber(phase0Idx), volVars.nusseltNumber(phase1Idx));
353 const Scalar nusseltWS = volVars.nusseltNumber(phase0Idx);
354 const Scalar nusseltNS = volVars.nusseltNumber(phase1Idx);
356 const Scalar wettingToNonwettingEnergyExchange = factorEnergyTransfer * (Tw - Tn) / characteristicLength * areaWN * lambdaWN * nusseltWN ;
357 const Scalar wettingToSolidEnergyExchange = factorEnergyTransfer * (Tw - Ts) / characteristicLength * areaWS * lambdaWS * nusseltWS ;
358 const Scalar nonwettingToSolidEnergyExchange = factorEnergyTransfer * (Tn - Ts) / characteristicLength * areaNS * lambdaNS * nusseltNS ;
360 for(
int phaseIdx = 0; phaseIdx < numEnergyEqFluid+numEnergyEqSolid; ++phaseIdx)
365 source[energyEq0Idx + phaseIdx] += ( - wettingToNonwettingEnergyExchange - wettingToSolidEnergyExchange);
368 source[energyEq0Idx + phaseIdx] += (+ wettingToNonwettingEnergyExchange - nonwettingToSolidEnergyExchange);
371 source[energyEq0Idx + phaseIdx] += (+ wettingToSolidEnergyExchange + nonwettingToSolidEnergyExchange);
374 DUNE_THROW(Dune::NotImplemented,
380 if (!isfinite(source[energyEq0Idx + phaseIdx]))
381 DUNE_THROW(
NumericalProblem,
"Calculated non-finite source, " <<
"Tw="<< Tw <<
" Tn="<< Tn<<
" Ts="<< Ts);
385 if (enableChemicalNonEquilibrium)
398 const auto& fluidState = volVars.fluidState();
400 for(
int phaseIdx = 0; phaseIdx < numEnergyEqFluid+numEnergyEqSolid; ++phaseIdx)
406 for(
int compIdx = 0; compIdx < numComponents; ++compIdx)
408 const unsigned int eqIdx = conti0EqIdx + compIdx + phaseIdx*numComponents;
409 source[energyEq0Idx + phaseIdx] += (source[eqIdx]
410 * FluidSystem::molarMass(compIdx)
411 * FluidSystem::componentEnthalpy(fluidState, phase1Idx, compIdx) );
416 for(
int compIdx =0; compIdx<numComponents; ++compIdx)
418 const unsigned int eqIdx = conti0EqIdx + compIdx + phaseIdx*numComponents;
419 source[energyEq0Idx + phaseIdx] += (source[eqIdx]
420 * FluidSystem::molarMass(compIdx)
421 *FluidSystem::componentEnthalpy(fluidState, phase0Idx, compIdx));
427 DUNE_THROW(Dune::NotImplemented,
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:160
static void solidPhaseStorage(NumEqVector &storage, const SubControlVolume &scv, const VolumeVariables &volVars)
The energy storage in the solid matrix.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:78
static void heatDispersionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The dispersive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:98
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:63
static void heatConductionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The diffusive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:141
static void heatConvectionFlux(NumEqVector &flux, FluxVariables &fluxVars, int phaseIdx)
The advective phase energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:103
static void heatDispersionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The dispersive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:311
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:324
static void heatConvectionFlux(NumEqVector &flux, FluxVariables &fluxVars, int phaseIdx)
The advective phase energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:259
static void heatConductionFlux(NumEqVector &flux, FluxVariables &fluxVars)
The diffusive energy fluxes.
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:292
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:247
This file contains the parts of the local residual to calculate the heat conservation in the thermal ...
Definition: porousmediumflow/nonequilibrium/thermal/localresidual.hh:33
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:27
Defines all properties used in Dumux.
Some exceptions thrown in DuMux
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:57
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:34
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
A helper to deduce a vector with the same size as numbers of equations.
Provides 3rd order polynomial splines.