version 3.8
porousmediumflow/nonisothermal/volumevariables.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
14#ifndef DUMUX_ENERGY_VOLUME_VARIABLES_HH
15#define DUMUX_ENERGY_VOLUME_VARIABLES_HH
16
17#include <type_traits>
18#include <dune/common/std/type_traits.hh>
19
22
23namespace Dumux {
24
25#ifndef DOXYGEN
26namespace Detail {
27// helper structs and functions detecting if the user-defined spatial params class has user-specified functions
28// for solidHeatCapacity, solidDensity, and solidThermalConductivity.
29
30template <typename T, typename ...Ts>
31using SolidHeatCapacityDetector = decltype(std::declval<T>().solidHeatCapacity(std::declval<Ts>()...));
32
33template<class T, typename ...Args>
34static constexpr bool hasSolidHeatCapacity()
35{ return Dune::Std::is_detected<SolidHeatCapacityDetector, T, Args...>::value; }
36
37template <typename T, typename ...Ts>
38using SolidDensityDetector = decltype(std::declval<T>().solidDensity(std::declval<Ts>()...));
39
40template<class T, typename ...Args>
41static constexpr bool hasSolidDensity()
42{ return Dune::Std::is_detected<SolidDensityDetector, T, Args...>::value; }
43
44template <typename T, typename ...Ts>
45using SolidThermalConductivityDetector = decltype(std::declval<T>().solidThermalConductivity(std::declval<Ts>()...));
46
47template<class T, typename ...Args>
48static constexpr bool hasSolidThermalConductivity()
49{ return Dune::Std::is_detected<SolidThermalConductivityDetector, T, Args...>::value; }
50
51template<class SolidSystem>
52struct isInertSolidPhase : public std::false_type {};
53
54template<class Scalar, class Component>
55struct isInertSolidPhase<SolidSystems::InertSolidPhase<Scalar, Component>> : public std::true_type {};
56
57} // end namespace Detail
58#endif
59
60
61// forward declaration
62template <class IsothermalTraits, class Impl, bool enableEnergyBalance>
64
72template<class IsothermalTraits, class Impl>
73using EnergyVolumeVariables = EnergyVolumeVariablesImplementation<IsothermalTraits,Impl, IsothermalTraits::ModelTraits::enableEnergyBalance()>;
74
79template<class IsothermalTraits, class Impl>
80class EnergyVolumeVariablesImplementation<IsothermalTraits, Impl, false>
81{
82 using Scalar = typename IsothermalTraits::PrimaryVariables::value_type;
83
84public:
85 using FluidState = typename IsothermalTraits::FluidState;
86 using SolidState = typename IsothermalTraits::SolidState;
87 using FluidSystem = typename IsothermalTraits::FluidSystem;
88
90 template<class ElemSol, class Problem, class Element, class Scv>
91 void updateTemperature(const ElemSol& elemSol,
92 const Problem& problem,
93 const Element& element,
94 const Scv& scv,
95 FluidState& fluidState,
96 SolidState& solidState)
97 {
98 // retrieve temperature from solution vector, all phases have the same temperature
99 Scalar T = problem.spatialParams().temperature(element, scv, elemSol);
100 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
101 {
102 fluidState.setTemperature(phaseIdx, T);
103 }
104 solidState.setTemperature(T);
105 }
106
107 template<class ElemSol, class Problem, class Element, class Scv>
108 void updateSolidEnergyParams(const ElemSol &elemSol,
109 const Problem& problem,
110 const Element &element,
111 const Scv &scv,
112 SolidState & solidState)
113 {}
114
117 template<class FluidState, class ParameterCache>
118 static Scalar enthalpy(const FluidState& fluidState,
119 const ParameterCache& paramCache,
120 const int phaseIdx)
121 {
122 return 0;
123 }
124
127 {}
128
129};
130
132template<class Traits, class Impl>
133class EnergyVolumeVariablesImplementation<Traits, Impl, true>
134{
135 using Scalar = typename Traits::PrimaryVariables::value_type;
136 using Idx = typename Traits::ModelTraits::Indices;
138 using EffCondModel = typename Traits::EffectiveThermalConductivityModel;
139
140 static constexpr int temperatureIdx = Idx::temperatureIdx;
141 static constexpr int numEnergyEq = Traits::ModelTraits::numEnergyEq();
142
143 static constexpr bool fullThermalEquilibrium = (numEnergyEq == 1);
144 static constexpr bool fluidThermalEquilibrium = (numEnergyEq == 2);
145
146public:
147 // export the fluidstate
148 using FluidState = typename Traits::FluidState;
150 using FluidSystem = typename Traits::FluidSystem;
152 using Indices = Idx;
153 // export the solidstate
154 using SolidState = typename Traits::SolidState;
156 using SolidSystem = typename Traits::SolidSystem;
157
159 template<class ElemSol, class Problem, class Element, class Scv>
160 void updateTemperature(const ElemSol& elemSol,
161 const Problem& problem,
162 const Element& element,
163 const Scv& scv,
164 FluidState& fluidState,
165 SolidState& solidState)
166 {
167 if constexpr (fullThermalEquilibrium)
168 {
169 // retrieve temperature from solution vector, all phases have the same temperature
170 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx];
171 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
172 {
173 fluidState.setTemperature(phaseIdx, T);
174 }
175 solidState.setTemperature(T);
176 }
177
178 else
179 {
180 // this means we have 1 temp for fluid phase, one for solid
181 if constexpr (fluidThermalEquilibrium)
182 {
183 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx];
184 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
185 {
186 fluidState.setTemperature(phaseIdx, T);
187 }
188 }
189 // this is for numEnergyEqFluid > 1
190 else
191 {
192 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
193 {
194 // retrieve temperatures from solution vector, phases might have different temperature
195 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx + phaseIdx];
196 fluidState.setTemperature(phaseIdx, T);
197 }
198 }
199 const Scalar solidTemperature = elemSol[scv.localDofIndex()][temperatureIdx+numEnergyEq-1];
200 solidState.setTemperature(solidTemperature);
201 }
202 }
203
204 template<class ElemSol, class Problem, class Element, class Scv>
205 void updateSolidEnergyParams(const ElemSol &elemSol,
206 const Problem& problem,
207 const Element &element,
208 const Scv &scv,
209 SolidState & solidState)
210 {
211 Scalar cs = solidHeatCapacity_(elemSol, problem, element, scv, solidState);
212 solidState.setHeatCapacity(cs);
213
214 Scalar rhos = solidDensity_(elemSol, problem, element, scv, solidState);
215 solidState.setDensity(rhos);
216
217 Scalar lambdas = solidThermalConductivity_(elemSol, problem, element, scv, solidState);
218 solidState.setThermalConductivity(lambdas);
219 }
220
221 // updates the effective thermal conductivity
223 {
224 if constexpr (fullThermalEquilibrium)
225 {
226 // Full Thermal Equilibirum: One effectiveThermalConductivity value for all phases (solid & fluid).
227 lambdaEff_[0] = EffCondModel::effectiveThermalConductivity(asImp_());
228 }
229 else if constexpr (fluidThermalEquilibrium)
230 {
231 // Fluid Thermal Equilibrium (Partial Nonequilibrium): One effectiveThermalConductivity for the fluids, one for the solids.
232 Scalar fluidLambda = 0.0;
233 for (int phaseIdx = 0; phaseIdx < FluidSystem::numPhases; phaseIdx++)
234 fluidLambda += fluidThermalConductivity(phaseIdx) * asImp_().saturation(phaseIdx) * asImp_().porosity();
235
236 lambdaEff_[0] = fluidLambda;
237 lambdaEff_[numEnergyEq-1] = solidThermalConductivity() * (1.0 - asImp_().porosity());
238 }
239 else
240 {
241 // Full Thermal Nonequilibrium: One effectiveThermal Conductivity per phase (solid & fluid).
242 for (int phaseIdx = 0; phaseIdx < FluidSystem::numPhases; phaseIdx++)
243 lambdaEff_[phaseIdx] = fluidThermalConductivity(phaseIdx) * asImp_().saturation(phaseIdx) * asImp_().porosity();
244 lambdaEff_[numEnergyEq-1] = solidThermalConductivity() * (1.0 - asImp_().porosity());
245 }
246 }
247
254 Scalar internalEnergy(const int phaseIdx) const
255 { return asImp_().fluidState().internalEnergy(phaseIdx); }
256
263 Scalar enthalpy(const int phaseIdx) const
264 { return asImp_().fluidState().enthalpy(phaseIdx); }
265
270 Scalar temperatureSolid() const
271 { return asImp_().solidState().temperature(); }
272
273
279 Scalar temperatureFluid(const int phaseIdx) const
280 { return asImp_().fluidState().temperature(phaseIdx); }
281
286 Scalar solidHeatCapacity() const
287 { return asImp_().solidState().heatCapacity(); }
288
293 Scalar solidDensity() const
294 { return asImp_().solidState().density(); }
295
301 { return asImp_().solidState().thermalConductivity(); }
302
307 Scalar fluidThermalConductivity(const int phaseIdx) const
308 { return FluidSystem::thermalConductivity(asImp_().fluidState(), phaseIdx); }
309
314 template< bool enable = fullThermalEquilibrium,
315 std::enable_if_t<enable, int> = 0>
317 { return lambdaEff_[0]; }
318
323 template< bool enable = fluidThermalEquilibrium,
324 std::enable_if_t<enable, int> = 0>
326 { return lambdaEff_[0]; }
327
333 template< bool enable = fluidThermalEquilibrium,
334 std::enable_if_t<enable, int> = 0>
336 { return lambdaEff_[numEnergyEq-1]; }
337
343 template< bool enable = (!fullThermalEquilibrium && !fluidThermalEquilibrium),
344 std::enable_if_t<enable, int> = 0>
345 Scalar effectivePhaseThermalConductivity(const int phaseIdx) const
346 { return lambdaEff_[phaseIdx]; }
347
350 template<class ParameterCache>
351 static Scalar enthalpy(const FluidState& fluidState,
352 const ParameterCache& paramCache,
353 const int phaseIdx)
354 {
355 return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx);
356 }
357
358protected:
359 const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
360 Impl &asImp_() { return *static_cast<Impl*>(this); }
361
362private:
376 // \{
377
388 template<class ElemSol, class Problem, class Element, class Scv,
389 std::enable_if_t<!Detail::hasSolidHeatCapacity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
390 Scalar solidHeatCapacity_(const ElemSol& elemSol,
391 const Problem& problem,
392 const Element& element,
393 const Scv& scv,
394 const SolidState& solidState)
395 {
396 return SolidSystem::heatCapacity(solidState);
397 }
398
409 template<class ElemSol, class Problem, class Element, class Scv,
410 std::enable_if_t<!Detail::hasSolidDensity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
411 Scalar solidDensity_(const ElemSol& elemSol,
412 const Problem& problem,
413 const Element& element,
414 const Scv& scv,
415 const SolidState& solidState)
416 {
417 return SolidSystem::density(solidState);
418 }
419
430 template<class ElemSol, class Problem, class Element, class Scv,
431 std::enable_if_t<!Detail::hasSolidThermalConductivity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
432 Scalar solidThermalConductivity_(const ElemSol& elemSol,
433 const Problem& problem,
434 const Element& element,
435 const Scv& scv,
436 const SolidState& solidState)
437 {
438 return SolidSystem::thermalConductivity(solidState);
439 }
440
441 // \}
442
447 // \{
448
460 template<class ElemSol, class Problem, class Element, class Scv,
461 std::enable_if_t<Detail::hasSolidHeatCapacity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
462 Scalar solidHeatCapacity_(const ElemSol& elemSol,
463 const Problem& problem,
464 const Element& element,
465 const Scv& scv,
466 const SolidState& solidState)
467 {
468 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
469 "solidHeatCapacity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
470 "If you select a proper solid system, the solid heat capacity will be computed as stated in the solid system!");
471 return problem.spatialParams().solidHeatCapacity(element, scv, elemSol, solidState);
472 }
473
485 template<class ElemSol, class Problem, class Element, class Scv,
486 std::enable_if_t<Detail::hasSolidDensity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
487 Scalar solidDensity_(const ElemSol& elemSol,
488 const Problem& problem,
489 const Element& element,
490 const Scv& scv,
491 const SolidState& solidState)
492 {
493 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
494 "solidDensity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
495 "If you select a proper solid system, the solid density will be computed as stated in the solid system!");
496 return problem.spatialParams().solidDensity(element, scv, elemSol, solidState);
497 }
498
510 template<class ElemSol, class Problem, class Element, class Scv,
511 std::enable_if_t<Detail::hasSolidThermalConductivity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
512 Scalar solidThermalConductivity_(const ElemSol& elemSol,
513 const Problem& problem,
514 const Element& element,
515 const Scv& scv,
516 const SolidState& solidState)
517 {
518 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
519 "solidThermalConductivity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
520 "If you select a proper solid system, the solid thermal conductivity will be computed as stated in the solid system!");
521 return problem.spatialParams().solidThermalConductivity(element, scv, elemSol, solidState);
522 }
523
524 std::array<Scalar, numEnergyEq> lambdaEff_;
525 // \}
526
527};
528
529} // end namespace Dumux
530
531#endif
The simplest solid phase consisting of a single solid component.
void updateSolidEnergyParams(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:108
static Scalar enthalpy(const FluidState &fluidState, const ParameterCache &paramCache, const int phaseIdx)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:118
typename IsothermalTraits::FluidSystem FluidSystem
Definition: porousmediumflow/nonisothermal/volumevariables.hh:87
typename IsothermalTraits::SolidState SolidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:86
typename IsothermalTraits::FluidState FluidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:85
void updateEffectiveThermalConductivity()
The effective thermal conductivity is zero for isothermal models.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:126
void updateTemperature(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, FluidState &fluidState, SolidState &solidState)
The temperature is obtained from the problem as a constant for isothermal models.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:91
Scalar temperatureFluid(const int phaseIdx) const
Returns the temperature of a fluid phase assuming thermal nonequilibrium the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:279
typename Traits::FluidSystem FluidSystem
export the underlying fluid system
Definition: porousmediumflow/nonisothermal/volumevariables.hh:150
Scalar solidDensity() const
Returns the mass density of the rock matrix in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:293
const Impl & asImp_() const
Definition: porousmediumflow/nonisothermal/volumevariables.hh:359
Scalar enthalpy(const int phaseIdx) const
Returns the total enthalpy of a phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:263
Scalar effectivePhaseThermalConductivity(const int phaseIdx) const
Returns the effective thermal conductivity per fluid phase in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:345
Scalar fluidThermalConductivity(const int phaseIdx) const
Returns the thermal conductivity of a fluid phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:307
Scalar temperatureSolid() const
Returns the temperature in fluid / solid phase(s) the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:270
Scalar internalEnergy(const int phaseIdx) const
Returns the total internal energy of a phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:254
void updateEffectiveThermalConductivity()
Definition: porousmediumflow/nonisothermal/volumevariables.hh:222
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:148
Scalar solidHeatCapacity() const
Returns the total heat capacity of the rock matrix in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:286
void updateTemperature(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, FluidState &fluidState, SolidState &solidState)
The temperature is obtained from the problem as a constant for isothermal models.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:160
Scalar effectiveSolidThermalConductivity() const
Returns the effective thermal conductivity of the solid phase in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:335
Idx Indices
Export the indices.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:152
static Scalar enthalpy(const FluidState &fluidState, const ParameterCache &paramCache, const int phaseIdx)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:351
typename Traits::SolidState SolidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:154
void updateSolidEnergyParams(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:205
Scalar effectiveThermalConductivity() const
Returns the effective thermal conductivity in the sub-control volume. Specific to equilibirum models...
Definition: porousmediumflow/nonisothermal/volumevariables.hh:316
Scalar solidThermalConductivity() const
Returns the thermal conductivity of the solid phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:300
Scalar effectiveFluidThermalConductivity() const
Returns the effective thermal conductivity of the fluids in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:325
Impl & asImp_()
Definition: porousmediumflow/nonisothermal/volumevariables.hh:360
typename Traits::SolidSystem SolidSystem
export the underlying solid system
Definition: porousmediumflow/nonisothermal/volumevariables.hh:156
Definition: porousmediumflow/nonisothermal/volumevariables.hh:63
The isothermal base class.
Definition: porousmediumflow/volumevariables.hh:28
OneCSolid< Scalar, ComponentT, true > InertSolidPhase
A solid phase consisting of a single inert solid component.
Definition: 1csolid.hh:125
std::string solidTemperature() noexcept
I/O name of solid temperature for non-equilibrium models.
Definition: name.hh:48
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:53
Definition: adapt.hh:17
Base class for the model specific class which provides access to all volume averaged quantities.