version 3.10-dev
grainfourierslaw.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//
13#ifndef DUMUX_FLUX_PNM_GRAIN_FOURIERS_LAW_HH
14#define DUMUX_FLUX_PNM_GRAIN_FOURIERS_LAW_HH
15
16#include <cmath>
17#include <dumux/common/math.hh>
19
20namespace Dumux::PoreNetwork {
21
28template <class Scalar>
30{
31 template<class Problem, class Element, class FVElementGeometry, class ElementVolumeVariables, class ElementFluxVariablesCache>
32 static Scalar flux(const Problem& problem,
33 const Element& element,
34 const FVElementGeometry& fvGeometry,
35 const ElementVolumeVariables& elemVolVars,
36 const typename FVElementGeometry::SubControlVolumeFace& scvf,
37 const ElementFluxVariablesCache& elemFluxVarsCache)
38 {
39 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
40 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
41 const auto& insideVolVars = elemVolVars[insideScv];
42 const auto& outsideVolVars = elemVolVars[outsideScv];
43 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
44
45 const Scalar topSideLength = 2.0*fluxVarsCache.throatInscribedRadius();
46
47 // We assume that the distance between pore centroid and throat
48 // centroid (i.e., the height of the pyramid) equals the inscribed pore radius.
49 const Scalar insideHeight = insideVolVars.poreInscribedRadius();
50 const Scalar outsideHeight = outsideVolVars.poreInscribedRadius();
51
52 auto getPyramidBaseLengthFromVolume = [&](const Scalar v, const Scalar h)
53 {
54 // Using the formula for the volume of a pyramid frustum to calculate its base length:
55 // v = 1/3 h * (a^2 + a*b + b^2), where a is the base side length, b the top side length,
56 // h the height and v the volume of the frustum.
57 const Scalar b = topSideLength;
58 using std::sqrt;
59 return 0.5*sqrt(3.0) * sqrt(-(b*b*h-4.0*v)/h) -0.5*b;
60 };
61
62 // the pyramid base length of the inside pore
63 const Scalar insideBaseSideLength = [&]()
64 {
65 static const bool useAdaptedVolume = getParamFromGroup<bool>(problem.paramGroup(), "FouriersLaw.UseVolumeEqualPyramid", false);
66
67 if (useAdaptedVolume)
68 return getPyramidBaseLengthFromVolume(0.5*insideVolVars.poreVolume(), insideHeight);
69 else
70 return 2.0 * insideVolVars.poreInscribedRadius();
71 }();
72
73 // the pyramid base length of the outside pore
74 const Scalar outsideBaseSideLength = [&]()
75 {
76 static const bool useAdaptedVolume = getParamFromGroup<bool>(problem.paramGroup(), "FouriersLaw.UseVolumeEqualPyramid", false);
77
78 if (useAdaptedVolume)
79 return getPyramidBaseLengthFromVolume(0.5*outsideVolVars.poreVolume(), outsideHeight);
80 else
81 return 2.0 * outsideVolVars.poreInscribedRadius();
82 }();
83
84 auto insideThermalConducitivity = insideVolVars.solidThermalConductivity();
85 auto outsideThermalConducitivity = outsideVolVars.solidThermalConductivity();
86
87 const Scalar gInside = 4.0*insideThermalConducitivity * 0.5*topSideLength * 0.5*insideBaseSideLength / insideHeight;
88 const Scalar gOutside = 4.0*outsideThermalConducitivity * 0.5*topSideLength * 0.5*outsideBaseSideLength / outsideHeight;
89 const Scalar gThroat = Dumux::harmonicMean(insideThermalConducitivity, outsideThermalConducitivity)
90 * fluxVarsCache.grainContactArea() / fluxVarsCache.throatLength();
91
92 const Scalar g = 1.0 / (1.0/gInside + 1.0/gOutside + 1.0/gThroat);
93
94 // calculate the temperature gradient
95 const Scalar deltaT = insideVolVars.temperature() - outsideVolVars.temperature();
96
97 return deltaT * g;
98 }
99};
100
106template <class Scalar>
108{
109 template<class Problem, class Element, class FVElementGeometry, class ElementVolumeVariables, class ElementFluxVariablesCache>
110 static Scalar flux(const Problem& problem,
111 const Element& element,
112 const FVElementGeometry& fvGeometry,
113 const ElementVolumeVariables& elemVolVars,
114 const typename FVElementGeometry::SubControlVolumeFace& scvf,
115 const ElementFluxVariablesCache& elemFluxVarsCache)
116 {
117 const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx());
118 const auto& outsideScv = fvGeometry.scv(scvf.outsideScvIdx());
119 const auto& insideVolVars = elemVolVars[insideScv];
120 const auto& outsideVolVars = elemVolVars[outsideScv];
121 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
122
123 auto gSphereCap = [&](const auto& scv, const auto& volVars)
124 {
125 const Scalar R = problem.spatialParams.extendedPoreRadius(scv.dofIndex());
126 const Scalar lambda = volVars.solidThermalConductivity();
127 const Scalar rC = volVars.poreRadius();
128 using std::atanh;
129 return (lambda*M_PI*R) / atanh(rC/R);
130 };
131
132 auto insideThermalConducitivity = insideVolVars.solidThermalConductivity();
133 auto outsideThermalConducitivity = outsideVolVars.solidThermalConductivity();
134
135 const Scalar gInside = gSphereCap(insideScv, insideVolVars);
136 const Scalar gOutside = gSphereCap(outsideScv, outsideVolVars);
137 const Scalar gThroat = Dumux::harmonicMean(insideThermalConducitivity, outsideThermalConducitivity)
138 * fluxVarsCache.grainContactArea() / fluxVarsCache.throatLength();
139
140 const Scalar g = 1.0 / (1.0/gInside + 1.0/gOutside + 1.0/gThroat);
141
142 // calculate the temperature gradient
143 const Scalar deltaT = insideVolVars.temperature() - outsideVolVars.temperature();
144
145 return deltaT * g;
146 }
147
148};
149
150} // end namespace Dumux::PoreNetwork
151
152#endif
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
Define some often used mathematical functions.
Definition: discretization/porenetwork/fvelementgeometry.hh:24
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Specialization of Fourier's Law for the pore-network SOLID model.
Definition: grainfourierslaw.hh:108
static Scalar flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache)
Definition: grainfourierslaw.hh:110
Specialization of Fourier's Law for the pore-network SOLID model.
Definition: grainfourierslaw.hh:30
static Scalar flux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const typename FVElementGeometry::SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache)
Definition: grainfourierslaw.hh:32