3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
26#ifndef DUMUX_ENERGY_VOLUME_VARIABLES_HH
27#define DUMUX_ENERGY_VOLUME_VARIABLES_HH
28
29#include <type_traits>
30#include <dune/common/std/type_traits.hh>
31
34
35namespace Dumux {
36
37#ifndef DOXYGEN
38namespace Detail {
39// helper structs and functions detecting if the user-defined spatial params class has user-specified functions
40// for solidHeatCapacity, solidDensity, and solidThermalConductivity.
41
42template <typename T, typename ...Ts>
43using SolidHeatCapacityDetector = decltype(std::declval<T>().solidHeatCapacity(std::declval<Ts>()...));
44
45template<class T, typename ...Args>
46static constexpr bool hasSolidHeatCapacity()
47{ return Dune::Std::is_detected<SolidHeatCapacityDetector, T, Args...>::value; }
48
49template <typename T, typename ...Ts>
50using SolidDensityDetector = decltype(std::declval<T>().solidDensity(std::declval<Ts>()...));
51
52template<class T, typename ...Args>
53static constexpr bool hasSolidDensity()
54{ return Dune::Std::is_detected<SolidDensityDetector, T, Args...>::value; }
55
56template <typename T, typename ...Ts>
57using SolidThermalConductivityDetector = decltype(std::declval<T>().solidThermalConductivity(std::declval<Ts>()...));
58
59template<class T, typename ...Args>
60static constexpr bool hasSolidThermalConductivity()
61{ return Dune::Std::is_detected<SolidThermalConductivityDetector, T, Args...>::value; }
62
63template<class SolidSystem>
64struct isInertSolidPhase : public std::false_type {};
65
66template<class Scalar, class Component>
67struct isInertSolidPhase<SolidSystems::InertSolidPhase<Scalar, Component>> : public std::true_type {};
68
69} // end namespace Detail
70#endif
71
72
73// forward declaration
74template <class IsothermalTraits, class Impl, bool enableEnergyBalance>
76
84template<class IsothermalTraits, class Impl>
85using EnergyVolumeVariables = EnergyVolumeVariablesImplementation<IsothermalTraits,Impl, IsothermalTraits::ModelTraits::enableEnergyBalance()>;
86
91template<class IsothermalTraits, class Impl>
92class EnergyVolumeVariablesImplementation<IsothermalTraits, Impl, false>
93{
94 using Scalar = typename IsothermalTraits::PrimaryVariables::value_type;
95
96public:
97 using FluidState = typename IsothermalTraits::FluidState;
98 using SolidState = typename IsothermalTraits::SolidState;
99 using FluidSystem = typename IsothermalTraits::FluidSystem;
100
102 template<class ElemSol, class Problem, class Element, class Scv>
103 void updateTemperature(const ElemSol& elemSol,
104 const Problem& problem,
105 const Element& element,
106 const Scv& scv,
107 FluidState& fluidState,
108 SolidState& solidState)
109 {
110 // retrieve temperature from solution vector, all phases have the same temperature
111 Scalar T = problem.temperatureAtPos(scv.dofPosition());
112 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
113 {
114 fluidState.setTemperature(phaseIdx, T);
115 }
116 solidState.setTemperature(T);
117 }
118
119 template<class ElemSol, class Problem, class Element, class Scv>
120 void updateSolidEnergyParams(const ElemSol &elemSol,
121 const Problem& problem,
122 const Element &element,
123 const Scv &scv,
124 SolidState & solidState)
125 {}
126
129 template<class FluidState, class ParameterCache>
130 static Scalar enthalpy(const FluidState& fluidState,
131 const ParameterCache& paramCache,
132 const int phaseIdx)
133 {
134 return 0;
135 }
136
139 {}
140
141};
142
144template<class Traits, class Impl>
145class EnergyVolumeVariablesImplementation<Traits, Impl, true>
146{
147 using Scalar = typename Traits::PrimaryVariables::value_type;
148 using Idx = typename Traits::ModelTraits::Indices;
150 using EffCondModel = typename Traits::EffectiveThermalConductivityModel;
151
152 static constexpr int temperatureIdx = Idx::temperatureIdx;
153 static constexpr int numEnergyEq = Traits::ModelTraits::numEnergyEq();
154
155 static constexpr bool fullThermalEquilibrium = (numEnergyEq == 1);
156 static constexpr bool fluidThermalEquilibrium = (numEnergyEq == 2);
157
158public:
159 // export the fluidstate
160 using FluidState = typename Traits::FluidState;
162 using FluidSystem = typename Traits::FluidSystem;
164 using Indices = Idx;
165 // export the solidstate
166 using SolidState = typename Traits::SolidState;
168 using SolidSystem = typename Traits::SolidSystem;
169
171 template<class ElemSol, class Problem, class Element, class Scv>
172 void updateTemperature(const ElemSol& elemSol,
173 const Problem& problem,
174 const Element& element,
175 const Scv& scv,
176 FluidState& fluidState,
177 SolidState& solidState)
178 {
179 if constexpr (fullThermalEquilibrium)
180 {
181 // retrieve temperature from solution vector, all phases have the same temperature
182 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx];
183 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
184 {
185 fluidState.setTemperature(phaseIdx, T);
186 }
187 solidState.setTemperature(T);
188 }
189
190 else
191 {
192 // this means we have 1 temp for fluid phase, one for solid
193 if constexpr (fluidThermalEquilibrium)
194 {
195 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx];
196 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
197 {
198 fluidState.setTemperature(phaseIdx, T);
199 }
200 }
201 // this is for numEnergyEqFluid > 1
202 else
203 {
204 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
205 {
206 // retrieve temperatures from solution vector, phases might have different temperature
207 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx + phaseIdx];
208 fluidState.setTemperature(phaseIdx, T);
209 }
210 }
211 const Scalar solidTemperature = elemSol[scv.localDofIndex()][temperatureIdx+numEnergyEq-1];
212 solidState.setTemperature(solidTemperature);
213 }
214 }
215
216 template<class ElemSol, class Problem, class Element, class Scv>
217 void updateSolidEnergyParams(const ElemSol &elemSol,
218 const Problem& problem,
219 const Element &element,
220 const Scv &scv,
221 SolidState & solidState)
222 {
223 Scalar cs = solidHeatCapacity_(elemSol, problem, element, scv, solidState);
224 solidState.setHeatCapacity(cs);
225
226 Scalar rhos = solidDensity_(elemSol, problem, element, scv, solidState);
227 solidState.setDensity(rhos);
228
229 Scalar lambdas = solidThermalConductivity_(elemSol, problem, element, scv, solidState);
230 solidState.setThermalConductivity(lambdas);
231 }
232
233 // updates the effective thermal conductivity
235 {
236 if constexpr (fullThermalEquilibrium)
237 {
238 // Full Thermal Equilibirum: One effectiveThermalConductivity value for all phases (solid & fluid).
239 lambdaEff_[0] = EffCondModel::effectiveThermalConductivity(asImp_());
240 }
241 else if constexpr (fluidThermalEquilibrium)
242 {
243 // Fluid Thermal Equilibrium (Partial Nonequilibrium): One effectiveThermalConductivity for the fluids, one for the solids.
244 Scalar fluidLambda = 0.0;
245 for (int phaseIdx = 0; phaseIdx < FluidSystem::numPhases; phaseIdx++)
246 fluidLambda += fluidThermalConductivity(phaseIdx) * asImp_().saturation(phaseIdx) * asImp_().porosity();
247
248 lambdaEff_[0] = fluidLambda;
249 lambdaEff_[numEnergyEq-1] = solidThermalConductivity() * (1.0 - asImp_().porosity());
250 }
251 else
252 {
253 // Full Thermal Nonequilibrium: One effectiveThermal Conductivity per phase (solid & fluid).
254 for (int phaseIdx = 0; phaseIdx < FluidSystem::numPhases; phaseIdx++)
255 lambdaEff_[phaseIdx] = fluidThermalConductivity(phaseIdx) * asImp_().saturation(phaseIdx) * asImp_().porosity();
256 lambdaEff_[numEnergyEq-1] = solidThermalConductivity() * (1.0 - asImp_().porosity());
257 }
258 }
259
266 Scalar internalEnergy(const int phaseIdx) const
267 { return asImp_().fluidState().internalEnergy(phaseIdx); }
268
275 Scalar enthalpy(const int phaseIdx) const
276 { return asImp_().fluidState().enthalpy(phaseIdx); }
277
282 Scalar temperatureSolid() const
283 { return asImp_().solidState().temperature(); }
284
285
291 Scalar temperatureFluid(const int phaseIdx) const
292 { return asImp_().fluidState().temperature(phaseIdx); }
293
298 Scalar solidHeatCapacity() const
299 { return asImp_().solidState().heatCapacity(); }
300
305 Scalar solidDensity() const
306 { return asImp_().solidState().density(); }
307
313 { return asImp_().solidState().thermalConductivity(); }
314
319 Scalar fluidThermalConductivity(const int phaseIdx) const
320 { return FluidSystem::thermalConductivity(asImp_().fluidState(), phaseIdx); }
321
326 template< bool enable = fullThermalEquilibrium,
327 std::enable_if_t<enable, int> = 0>
329 { return lambdaEff_[0]; }
330
335 template< bool enable = fluidThermalEquilibrium,
336 std::enable_if_t<enable, int> = 0>
338 { return lambdaEff_[0]; }
339
345 template< bool enable = fluidThermalEquilibrium,
346 std::enable_if_t<enable, int> = 0>
348 { return lambdaEff_[numEnergyEq-1]; }
349
355 template< bool enable = (!fullThermalEquilibrium && !fluidThermalEquilibrium),
356 std::enable_if_t<enable, int> = 0>
357 Scalar effectivePhaseThermalConductivity(const int phaseIdx) const
358 { return lambdaEff_[phaseIdx]; }
359
362 template<class ParameterCache>
363 static Scalar enthalpy(const FluidState& fluidState,
364 const ParameterCache& paramCache,
365 const int phaseIdx)
366 {
367 return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx);
368 }
369
370protected:
371 const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
372 Impl &asImp_() { return *static_cast<Impl*>(this); }
373
374private:
388 // \{
389
400 template<class ElemSol, class Problem, class Element, class Scv,
401 std::enable_if_t<!Detail::hasSolidHeatCapacity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
402 Scalar solidHeatCapacity_(const ElemSol& elemSol,
403 const Problem& problem,
404 const Element& element,
405 const Scv& scv,
406 const SolidState& solidState)
407 {
408 return SolidSystem::heatCapacity(solidState);
409 }
410
421 template<class ElemSol, class Problem, class Element, class Scv,
422 std::enable_if_t<!Detail::hasSolidDensity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
423 Scalar solidDensity_(const ElemSol& elemSol,
424 const Problem& problem,
425 const Element& element,
426 const Scv& scv,
427 const SolidState& solidState)
428 {
429 return SolidSystem::density(solidState);
430 }
431
442 template<class ElemSol, class Problem, class Element, class Scv,
443 std::enable_if_t<!Detail::hasSolidThermalConductivity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
444 Scalar solidThermalConductivity_(const ElemSol& elemSol,
445 const Problem& problem,
446 const Element& element,
447 const Scv& scv,
448 const SolidState& solidState)
449 {
450 return SolidSystem::thermalConductivity(solidState);
451 }
452
453 // \}
454
459 // \{
460
472 template<class ElemSol, class Problem, class Element, class Scv,
473 std::enable_if_t<Detail::hasSolidHeatCapacity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
474 Scalar solidHeatCapacity_(const ElemSol& elemSol,
475 const Problem& problem,
476 const Element& element,
477 const Scv& scv,
478 const SolidState& solidState)
479 {
480 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
481 "solidHeatCapacity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
482 "If you select a proper solid system, the solid heat capacity will be computed as stated in the solid system!");
483 return problem.spatialParams().solidHeatCapacity(element, scv, elemSol, solidState);
484 }
485
497 template<class ElemSol, class Problem, class Element, class Scv,
498 std::enable_if_t<Detail::hasSolidDensity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
499 Scalar solidDensity_(const ElemSol& elemSol,
500 const Problem& problem,
501 const Element& element,
502 const Scv& scv,
503 const SolidState& solidState)
504 {
505 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
506 "solidDensity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
507 "If you select a proper solid system, the solid density will be computed as stated in the solid system!");
508 return problem.spatialParams().solidDensity(element, scv, elemSol, solidState);
509 }
510
522 template<class ElemSol, class Problem, class Element, class Scv,
523 std::enable_if_t<Detail::hasSolidThermalConductivity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
524 Scalar solidThermalConductivity_(const ElemSol& elemSol,
525 const Problem& problem,
526 const Element& element,
527 const Scv& scv,
528 const SolidState& solidState)
529 {
530 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
531 "solidThermalConductivity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
532 "If you select a proper solid system, the solid thermal conductivity will be computed as stated in the solid system!");
533 return problem.spatialParams().solidThermalConductivity(element, scv, elemSol, solidState);
534 }
535
536 std::array<Scalar, numEnergyEq> lambdaEff_;
537 // \}
538
539};
540
541} // end namespace Dumux
542
543#endif
The simplest solid phase consisting of a single solid component.
OneCSolid< Scalar, ComponentT, true > InertSolidPhase
A solid phase consisting of a single inert solid component.
Definition: 1csolid.hh:137
Definition: adapt.hh:29
std::string solidTemperature() noexcept
I/O name of solid temperature for non-equilibrium models.
Definition: name.hh:60
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
Definition: porousmediumflow/nonisothermal/volumevariables.hh:75
void updateSolidEnergyParams(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:120
static Scalar enthalpy(const FluidState &fluidState, const ParameterCache &paramCache, const int phaseIdx)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:130
typename IsothermalTraits::FluidSystem FluidSystem
Definition: porousmediumflow/nonisothermal/volumevariables.hh:99
typename IsothermalTraits::SolidState SolidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:98
typename IsothermalTraits::FluidState FluidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:97
void updateEffectiveThermalConductivity()
The effective thermal conductivity is zero for isothermal models.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:138
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:103
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:291
typename Traits::FluidSystem FluidSystem
export the underlying fluid system
Definition: porousmediumflow/nonisothermal/volumevariables.hh:162
Scalar solidDensity() const
Returns the mass density of the rock matrix in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:305
const Impl & asImp_() const
Definition: porousmediumflow/nonisothermal/volumevariables.hh:371
Scalar enthalpy(const int phaseIdx) const
Returns the total enthalpy of a phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:275
Scalar effectivePhaseThermalConductivity(const int phaseIdx) const
Returns the effective thermal conductivity per fluid phase in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:357
Scalar fluidThermalConductivity(const int phaseIdx) const
Returns the thermal conductivity of a fluid phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:319
Scalar temperatureSolid() const
Returns the temperature in fluid / solid phase(s) the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:282
Scalar internalEnergy(const int phaseIdx) const
Returns the total internal energy of a phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:266
void updateEffectiveThermalConductivity()
Definition: porousmediumflow/nonisothermal/volumevariables.hh:234
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:160
Scalar solidHeatCapacity() const
Returns the total heat capacity of the rock matrix in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:298
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:172
Scalar effectiveSolidThermalConductivity() const
Returns the effective thermal conductivity of the solid phase in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:347
Idx Indices
Export the indices.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:164
static Scalar enthalpy(const FluidState &fluidState, const ParameterCache &paramCache, const int phaseIdx)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:363
typename Traits::SolidState SolidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:166
void updateSolidEnergyParams(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:217
Scalar effectiveThermalConductivity() const
Returns the effective thermal conductivity in the sub-control volume. Specific to equilibirum models...
Definition: porousmediumflow/nonisothermal/volumevariables.hh:328
Scalar solidThermalConductivity() const
Returns the thermal conductivity of the solid phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:312
Scalar effectiveFluidThermalConductivity() const
Returns the effective thermal conductivity of the fluids in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:337
Impl & asImp_()
Definition: porousmediumflow/nonisothermal/volumevariables.hh:372
typename Traits::SolidSystem SolidSystem
export the underlying solid system
Definition: porousmediumflow/nonisothermal/volumevariables.hh:168
The isothermal base class.
Definition: porousmediumflow/volumevariables.hh:40
Base class for the model specific class which provides access to all volume averaged quantities.