3.5-git
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
35
36namespace Dumux {
37
38#ifndef DOXYGEN
39namespace Detail {
40// helper structs and functions detecting if the user-defined spatial params class has user-specified functions
41// for solidHeatCapacity, solidDensity, and solidThermalConductivity.
42
43template <typename T, typename ...Ts>
44using SolidHeatCapacityDetector = decltype(std::declval<T>().solidHeatCapacity(std::declval<Ts>()...));
45
46template<class T, typename ...Args>
47static constexpr bool hasSolidHeatCapacity()
48{ return Dune::Std::is_detected<SolidHeatCapacityDetector, T, Args...>::value; }
49
50template <typename T, typename ...Ts>
51using SolidDensityDetector = decltype(std::declval<T>().solidDensity(std::declval<Ts>()...));
52
53template<class T, typename ...Args>
54static constexpr bool hasSolidDensity()
55{ return Dune::Std::is_detected<SolidDensityDetector, T, Args...>::value; }
56
57template <typename T, typename ...Ts>
58using SolidThermalConductivityDetector = decltype(std::declval<T>().solidThermalConductivity(std::declval<Ts>()...));
59
60template<class T, typename ...Args>
61static constexpr bool hasSolidThermalConductivity()
62{ return Dune::Std::is_detected<SolidThermalConductivityDetector, T, Args...>::value; }
63
64template<class SolidSystem>
65struct isInertSolidPhase : public std::false_type {};
66
67template<class Scalar, class Component>
68struct isInertSolidPhase<SolidSystems::InertSolidPhase<Scalar, Component>> : public std::true_type {};
69
70} // end namespace Detail
71#endif
72
73
74// forward declaration
75template <class IsothermalTraits, class Impl, bool enableEnergyBalance>
77
85template<class IsothermalTraits, class Impl>
86using EnergyVolumeVariables = EnergyVolumeVariablesImplementation<IsothermalTraits,Impl, IsothermalTraits::ModelTraits::enableEnergyBalance()>;
87
92template<class IsothermalTraits, class Impl>
93class EnergyVolumeVariablesImplementation<IsothermalTraits, Impl, false>
94{
95 using Scalar = typename IsothermalTraits::PrimaryVariables::value_type;
96
97public:
98 using FluidState = typename IsothermalTraits::FluidState;
99 using SolidState = typename IsothermalTraits::SolidState;
100 using FluidSystem = typename IsothermalTraits::FluidSystem;
101
103 template<class ElemSol, class Problem, class Element, class Scv>
104 void updateTemperature(const ElemSol& elemSol,
105 const Problem& problem,
106 const Element& element,
107 const Scv& scv,
108 FluidState& fluidState,
109 SolidState& solidState)
110 {
111 // retrieve temperature from solution vector, all phases have the same temperature
112 Scalar T = Deprecated::temperature(problem, element, scv, elemSol);
113 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
114 {
115 fluidState.setTemperature(phaseIdx, T);
116 }
117 solidState.setTemperature(T);
118 }
119
120 template<class ElemSol, class Problem, class Element, class Scv>
121 void updateSolidEnergyParams(const ElemSol &elemSol,
122 const Problem& problem,
123 const Element &element,
124 const Scv &scv,
125 SolidState & solidState)
126 {}
127
130 template<class FluidState, class ParameterCache>
131 static Scalar enthalpy(const FluidState& fluidState,
132 const ParameterCache& paramCache,
133 const int phaseIdx)
134 {
135 return 0;
136 }
137
140 {}
141
142};
143
145template<class Traits, class Impl>
146class EnergyVolumeVariablesImplementation<Traits, Impl, true>
147{
148 using Scalar = typename Traits::PrimaryVariables::value_type;
149 using Idx = typename Traits::ModelTraits::Indices;
151 using EffCondModel = typename Traits::EffectiveThermalConductivityModel;
152
153 static constexpr int temperatureIdx = Idx::temperatureIdx;
154 static constexpr int numEnergyEq = Traits::ModelTraits::numEnergyEq();
155
156 static constexpr bool fullThermalEquilibrium = (numEnergyEq == 1);
157 static constexpr bool fluidThermalEquilibrium = (numEnergyEq == 2);
158
159public:
160 // export the fluidstate
161 using FluidState = typename Traits::FluidState;
163 using FluidSystem = typename Traits::FluidSystem;
165 using Indices = Idx;
166 // export the solidstate
167 using SolidState = typename Traits::SolidState;
169 using SolidSystem = typename Traits::SolidSystem;
170
172 template<class ElemSol, class Problem, class Element, class Scv>
173 void updateTemperature(const ElemSol& elemSol,
174 const Problem& problem,
175 const Element& element,
176 const Scv& scv,
177 FluidState& fluidState,
178 SolidState& solidState)
179 {
180 if constexpr (fullThermalEquilibrium)
181 {
182 // retrieve temperature from solution vector, all phases have the same temperature
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 solidState.setTemperature(T);
189 }
190
191 else
192 {
193 // this means we have 1 temp for fluid phase, one for solid
194 if constexpr (fluidThermalEquilibrium)
195 {
196 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx];
197 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
198 {
199 fluidState.setTemperature(phaseIdx, T);
200 }
201 }
202 // this is for numEnergyEqFluid > 1
203 else
204 {
205 for(int phaseIdx=0; phaseIdx < FluidSystem::numPhases; ++phaseIdx)
206 {
207 // retrieve temperatures from solution vector, phases might have different temperature
208 const Scalar T = elemSol[scv.localDofIndex()][temperatureIdx + phaseIdx];
209 fluidState.setTemperature(phaseIdx, T);
210 }
211 }
212 const Scalar solidTemperature = elemSol[scv.localDofIndex()][temperatureIdx+numEnergyEq-1];
213 solidState.setTemperature(solidTemperature);
214 }
215 }
216
217 template<class ElemSol, class Problem, class Element, class Scv>
218 void updateSolidEnergyParams(const ElemSol &elemSol,
219 const Problem& problem,
220 const Element &element,
221 const Scv &scv,
222 SolidState & solidState)
223 {
224 Scalar cs = solidHeatCapacity_(elemSol, problem, element, scv, solidState);
225 solidState.setHeatCapacity(cs);
226
227 Scalar rhos = solidDensity_(elemSol, problem, element, scv, solidState);
228 solidState.setDensity(rhos);
229
230 Scalar lambdas = solidThermalConductivity_(elemSol, problem, element, scv, solidState);
231 solidState.setThermalConductivity(lambdas);
232 }
233
234 // updates the effective thermal conductivity
236 {
237 if constexpr (fullThermalEquilibrium)
238 {
239 // Full Thermal Equilibirum: One effectiveThermalConductivity value for all phases (solid & fluid).
240 lambdaEff_[0] = EffCondModel::effectiveThermalConductivity(asImp_());
241 }
242 else if constexpr (fluidThermalEquilibrium)
243 {
244 // Fluid Thermal Equilibrium (Partial Nonequilibrium): One effectiveThermalConductivity for the fluids, one for the solids.
245 Scalar fluidLambda = 0.0;
246 for (int phaseIdx = 0; phaseIdx < FluidSystem::numPhases; phaseIdx++)
247 fluidLambda += fluidThermalConductivity(phaseIdx) * asImp_().saturation(phaseIdx) * asImp_().porosity();
248
249 lambdaEff_[0] = fluidLambda;
250 lambdaEff_[numEnergyEq-1] = solidThermalConductivity() * (1.0 - asImp_().porosity());
251 }
252 else
253 {
254 // Full Thermal Nonequilibrium: One effectiveThermal Conductivity per phase (solid & fluid).
255 for (int phaseIdx = 0; phaseIdx < FluidSystem::numPhases; phaseIdx++)
256 lambdaEff_[phaseIdx] = fluidThermalConductivity(phaseIdx) * asImp_().saturation(phaseIdx) * asImp_().porosity();
257 lambdaEff_[numEnergyEq-1] = solidThermalConductivity() * (1.0 - asImp_().porosity());
258 }
259 }
260
267 Scalar internalEnergy(const int phaseIdx) const
268 { return asImp_().fluidState().internalEnergy(phaseIdx); }
269
276 Scalar enthalpy(const int phaseIdx) const
277 { return asImp_().fluidState().enthalpy(phaseIdx); }
278
283 Scalar temperatureSolid() const
284 { return asImp_().solidState().temperature(); }
285
286
292 Scalar temperatureFluid(const int phaseIdx) const
293 { return asImp_().fluidState().temperature(phaseIdx); }
294
299 Scalar solidHeatCapacity() const
300 { return asImp_().solidState().heatCapacity(); }
301
306 Scalar solidDensity() const
307 { return asImp_().solidState().density(); }
308
314 { return asImp_().solidState().thermalConductivity(); }
315
320 Scalar fluidThermalConductivity(const int phaseIdx) const
321 { return FluidSystem::thermalConductivity(asImp_().fluidState(), phaseIdx); }
322
327 template< bool enable = fullThermalEquilibrium,
328 std::enable_if_t<enable, int> = 0>
330 { return lambdaEff_[0]; }
331
336 template< bool enable = fluidThermalEquilibrium,
337 std::enable_if_t<enable, int> = 0>
339 { return lambdaEff_[0]; }
340
346 template< bool enable = fluidThermalEquilibrium,
347 std::enable_if_t<enable, int> = 0>
349 { return lambdaEff_[numEnergyEq-1]; }
350
356 template< bool enable = (!fullThermalEquilibrium && !fluidThermalEquilibrium),
357 std::enable_if_t<enable, int> = 0>
358 Scalar effectivePhaseThermalConductivity(const int phaseIdx) const
359 { return lambdaEff_[phaseIdx]; }
360
363 template<class ParameterCache>
364 static Scalar enthalpy(const FluidState& fluidState,
365 const ParameterCache& paramCache,
366 const int phaseIdx)
367 {
368 return FluidSystem::enthalpy(fluidState, paramCache, phaseIdx);
369 }
370
371protected:
372 const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
373 Impl &asImp_() { return *static_cast<Impl*>(this); }
374
375private:
389 // \{
390
401 template<class ElemSol, class Problem, class Element, class Scv,
402 std::enable_if_t<!Detail::hasSolidHeatCapacity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
403 Scalar solidHeatCapacity_(const ElemSol& elemSol,
404 const Problem& problem,
405 const Element& element,
406 const Scv& scv,
407 const SolidState& solidState)
408 {
409 return SolidSystem::heatCapacity(solidState);
410 }
411
422 template<class ElemSol, class Problem, class Element, class Scv,
423 std::enable_if_t<!Detail::hasSolidDensity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
424 Scalar solidDensity_(const ElemSol& elemSol,
425 const Problem& problem,
426 const Element& element,
427 const Scv& scv,
428 const SolidState& solidState)
429 {
430 return SolidSystem::density(solidState);
431 }
432
443 template<class ElemSol, class Problem, class Element, class Scv,
444 std::enable_if_t<!Detail::hasSolidThermalConductivity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
445 Scalar solidThermalConductivity_(const ElemSol& elemSol,
446 const Problem& problem,
447 const Element& element,
448 const Scv& scv,
449 const SolidState& solidState)
450 {
451 return SolidSystem::thermalConductivity(solidState);
452 }
453
454 // \}
455
460 // \{
461
473 template<class ElemSol, class Problem, class Element, class Scv,
474 std::enable_if_t<Detail::hasSolidHeatCapacity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
475 Scalar solidHeatCapacity_(const ElemSol& elemSol,
476 const Problem& problem,
477 const Element& element,
478 const Scv& scv,
479 const SolidState& solidState)
480 {
481 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
482 "solidHeatCapacity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
483 "If you select a proper solid system, the solid heat capacity will be computed as stated in the solid system!");
484 return problem.spatialParams().solidHeatCapacity(element, scv, elemSol, solidState);
485 }
486
498 template<class ElemSol, class Problem, class Element, class Scv,
499 std::enable_if_t<Detail::hasSolidDensity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
500 Scalar solidDensity_(const ElemSol& elemSol,
501 const Problem& problem,
502 const Element& element,
503 const Scv& scv,
504 const SolidState& solidState)
505 {
506 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
507 "solidDensity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
508 "If you select a proper solid system, the solid density will be computed as stated in the solid system!");
509 return problem.spatialParams().solidDensity(element, scv, elemSol, solidState);
510 }
511
523 template<class ElemSol, class Problem, class Element, class Scv,
524 std::enable_if_t<Detail::hasSolidThermalConductivity<typename Problem::SpatialParams, Element, Scv, ElemSol, SolidState>(), int> = 0>
525 Scalar solidThermalConductivity_(const ElemSol& elemSol,
526 const Problem& problem,
527 const Element& element,
528 const Scv& scv,
529 const SolidState& solidState)
530 {
531 static_assert(Detail::isInertSolidPhase<SolidSystem>::value,
532 "solidThermalConductivity can only be overwritten in the spatial params when the solid system is a simple InertSolidPhase\n"
533 "If you select a proper solid system, the solid thermal conductivity will be computed as stated in the solid system!");
534 return problem.spatialParams().solidThermalConductivity(element, scv, elemSol, solidState);
535 }
536
537 std::array<Scalar, numEnergyEq> lambdaEff_;
538 // \}
539
540};
541
542} // end namespace Dumux
543
544#endif
Helpers for deprecation.
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 temperature() noexcept
I/O name of temperature for equilibrium models.
Definition: name.hh:51
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:76
void updateSolidEnergyParams(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:121
static Scalar enthalpy(const FluidState &fluidState, const ParameterCache &paramCache, const int phaseIdx)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:131
typename IsothermalTraits::FluidSystem FluidSystem
Definition: porousmediumflow/nonisothermal/volumevariables.hh:100
typename IsothermalTraits::SolidState SolidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:99
typename IsothermalTraits::FluidState FluidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:98
void updateEffectiveThermalConductivity()
The effective thermal conductivity is zero for isothermal models.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:139
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:104
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:292
typename Traits::FluidSystem FluidSystem
export the underlying fluid system
Definition: porousmediumflow/nonisothermal/volumevariables.hh:163
Scalar solidDensity() const
Returns the mass density of the rock matrix in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:306
const Impl & asImp_() const
Definition: porousmediumflow/nonisothermal/volumevariables.hh:372
Scalar enthalpy(const int phaseIdx) const
Returns the total enthalpy of a phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:276
Scalar effectivePhaseThermalConductivity(const int phaseIdx) const
Returns the effective thermal conductivity per fluid phase in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:358
Scalar fluidThermalConductivity(const int phaseIdx) const
Returns the thermal conductivity of a fluid phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:320
Scalar temperatureSolid() const
Returns the temperature in fluid / solid phase(s) the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:283
Scalar internalEnergy(const int phaseIdx) const
Returns the total internal energy of a phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:267
void updateEffectiveThermalConductivity()
Definition: porousmediumflow/nonisothermal/volumevariables.hh:235
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:161
Scalar solidHeatCapacity() const
Returns the total heat capacity of the rock matrix in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:299
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:173
Scalar effectiveSolidThermalConductivity() const
Returns the effective thermal conductivity of the solid phase in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:348
Idx Indices
Export the indices.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:165
static Scalar enthalpy(const FluidState &fluidState, const ParameterCache &paramCache, const int phaseIdx)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:364
typename Traits::SolidState SolidState
Definition: porousmediumflow/nonisothermal/volumevariables.hh:167
void updateSolidEnergyParams(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState)
Definition: porousmediumflow/nonisothermal/volumevariables.hh:218
Scalar effectiveThermalConductivity() const
Returns the effective thermal conductivity in the sub-control volume. Specific to equilibirum models...
Definition: porousmediumflow/nonisothermal/volumevariables.hh:329
Scalar solidThermalConductivity() const
Returns the thermal conductivity of the solid phase in the sub-control volume.
Definition: porousmediumflow/nonisothermal/volumevariables.hh:313
Scalar effectiveFluidThermalConductivity() const
Returns the effective thermal conductivity of the fluids in the sub-control volume....
Definition: porousmediumflow/nonisothermal/volumevariables.hh:338
Impl & asImp_()
Definition: porousmediumflow/nonisothermal/volumevariables.hh:373
typename Traits::SolidSystem SolidSystem
export the underlying solid system
Definition: porousmediumflow/nonisothermal/volumevariables.hh:169
The isothermal base class.
Definition: porousmediumflow/volumevariables.hh:42
Base class for the model specific class which provides access to all volume averaged quantities.