GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/flux/box/dispersionflux.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 40 46 87.0%
Functions: 14 14 100.0%
Branches: 19 28 67.9%

Line Branch Exec Source
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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup BoxFlux
10 * \brief This file contains the data which is required to calculate
11 * dispersive fluxes.
12 */
13 #ifndef DUMUX_DISCRETIZATION_BOX_DISPERSION_FLUX_HH
14 #define DUMUX_DISCRETIZATION_BOX_DISPERSION_FLUX_HH
15
16 #include <dune/common/fvector.hh>
17 #include <dune/common/fmatrix.hh>
18 #include <dune/common/float_cmp.hh>
19
20 #include <dumux/common/math.hh>
21 #include <dumux/common/properties.hh>
22 #include <dumux/discretization/method.hh>
23 #include <dumux/discretization/extrusion.hh>
24 #include <dumux/flux/traits.hh>
25 #include <dumux/flux/referencesystemformulation.hh>
26 #include <dumux/flux/facetensoraverage.hh>
27
28 namespace Dumux {
29
30 // forward declaration
31 template<class TypeTag, class DiscretizationMethod, ReferenceSystemFormulation referenceSystem>
32 class DispersionFluxImplementation;
33
34 /*!
35 * \ingroup BoxFlux
36 * \brief Specialization of a dispersion flux for the box method
37 */
38 template <class TypeTag, ReferenceSystemFormulation referenceSystem>
39 class DispersionFluxImplementation<TypeTag, DiscretizationMethods::Box, referenceSystem>
40 {
41 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
42 using Problem = GetPropType<TypeTag, Properties::Problem>;
43 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
44 using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>;
45 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
46 using FVElementGeometry = typename GridGeometry::LocalView;
47 using SubControlVolume = typename GridGeometry::SubControlVolume;
48 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
49 using Extrusion = Extrusion_t<GridGeometry>;
50 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
51 using GridFluxVariablesCache = GetPropType<TypeTag, Properties::GridFluxVariablesCache>;
52 using ElementFluxVariablesCache = typename GridFluxVariablesCache::LocalView;
53 using FluxVarCache = typename GridFluxVariablesCache::FluxVariablesCache;
54 using FluxVariables = GetPropType<TypeTag, Properties::FluxVariables>;
55 using FluxTraits = typename Dumux::FluxTraits<FluxVariables>;
56 using BalanceEqOpts = GetPropType<TypeTag, Properties::BalanceEqOpts>;
57 using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView;
58 using Element = typename GridView::template Codim<0>::Entity;
59 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
60 using Indices = typename ModelTraits::Indices;
61
62 static constexpr int dim = GridView::dimension;
63 static constexpr int dimWorld = GridView::dimensionworld;
64
65 static constexpr int numPhases = ModelTraits::numFluidPhases();
66 static constexpr int numComponents = ModelTraits::numFluidComponents();
67
68 using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
69 using ComponentFluxVector = Dune::FieldVector<Scalar, numComponents>;
70 using HeatFluxScalar = Scalar;
71
72 static constexpr bool stationaryVelocityField = FluxTraits::hasStationaryVelocityField();
73
74 public:
75
76 //return the reference system
77 static constexpr ReferenceSystemFormulation referenceSystemFormulation()
78 { return referenceSystem; }
79
80 /*!
81 * \brief Returns the dispersive fluxes of all components within
82 * a fluid phase across the given sub-control volume face.
83 * The computed fluxes are given in mole/s or kg/s, depending
84 * on the template parameter ReferenceSystemFormulation.
85 */
86 11286800 static ComponentFluxVector compositionalDispersionFlux(const Problem& problem,
87 const Element& element,
88 const FVElementGeometry& fvGeometry,
89 const ElementVolumeVariables& elemVolVars,
90 const SubControlVolumeFace& scvf,
91 const int phaseIdx,
92 const ElementFluxVariablesCache& elemFluxVarsCache)
93 {
94 11286800 ComponentFluxVector componentFlux(0.0);
95
96 11286800 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
97 11286800 const auto& shapeValues = fluxVarsCache.shapeValues();
98
99 // density interpolation
100 11286800 Scalar rhoMassOrMole(0.0);
101
2/2
✓ Branch 0 taken 45147200 times.
✓ Branch 1 taken 11286800 times.
56434000 for (auto&& scv : scvs(fvGeometry))
102 {
103 45147200 const auto rho = massOrMolarDensity(elemVolVars[scv], referenceSystem, phaseIdx);
104 45147200 rhoMassOrMole += rho * shapeValues[scv.indexInElement()][0];
105 }
106
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11286800 times.
11286800 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
108 11286800 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
109
110
2/2
✓ Branch 0 taken 22573600 times.
✓ Branch 1 taken 11286800 times.
33860400 for (int compIdx = 0; compIdx < numComponents; compIdx++)
111 {
112 if constexpr (!FluidSystem::isTracerFluidSystem())
113
2/2
✓ Branch 0 taken 10276800 times.
✓ Branch 1 taken 10276800 times.
20553600 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
114 10276800 continue;
115
116 // collect the dispersion tensor, the fluxVarsCache and the shape values
117 29658400 const auto& dispersionTensor = [&]()
118 {
119 12296800 const auto& tensor =
120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7232000 times.
12296800 ModelTraits::CompositionalDispersionModel::compositionalDispersionTensor(problem, scvf, fvGeometry,
121 elemVolVars, elemFluxVarsCache,
122 phaseIdx, compIdx);
123
124
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12296800 times.
✓ Branch 2 taken 12296800 times.
✗ Branch 3 not taken.
12296800 if (Dune::FloatCmp::eq(insideVolVars.extrusionFactor(), outsideVolVars.extrusionFactor(), 1e-6))
125 12296800 return insideVolVars.extrusionFactor()*tensor;
126 else
127 {
128 const auto insideTensor = insideVolVars.extrusionFactor() * tensor;
129 const auto outsideTensor = outsideVolVars.extrusionFactor() * tensor;
130
131 // the resulting averaged dispersion tensor
132 return faceTensorAverage(insideTensor, outsideTensor, scvf.unitOuterNormal());
133 }
134 12296800 }();
135
136 // the mole/mass fraction gradient
137 12296800 Dune::FieldVector<Scalar, dimWorld> gradX(0.0);
138
2/2
✓ Branch 0 taken 49187200 times.
✓ Branch 1 taken 12296800 times.
61484000 for (auto&& scv : scvs(fvGeometry))
139 {
140 49187200 const auto x = massOrMoleFraction(elemVolVars[scv], referenceSystem, phaseIdx, compIdx);
141 98374400 gradX.axpy(x, fluxVarsCache.gradN(scv.indexInElement()));
142 }
143
144 // compute the dispersion flux
145 12296800 componentFlux[compIdx] = -1.0 * rhoMassOrMole * vtmv(scvf.unitOuterNormal(), dispersionTensor, gradX)*Extrusion::area(fvGeometry, scvf);
146 if constexpr (!FluidSystem::isTracerFluidSystem())
147 3044800 if (BalanceEqOpts::mainComponentIsBalanced(phaseIdx))
148 10276800 componentFlux[FluidSystem::getMainComponent(phaseIdx)] -= componentFlux[compIdx];
149 }
150 11286800 return componentFlux;
151 }
152
153 /*!
154 * \brief Returns the thermal dispersive flux
155 * across the given sub-control volume face.
156 */
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5622400 times.
5622400 static HeatFluxScalar thermalDispersionFlux(const Problem& problem,
158 const Element& element,
159 const FVElementGeometry& fvGeometry,
160 const ElementVolumeVariables& elemVolVars,
161 const SubControlVolumeFace& scvf,
162 const int phaseIdx,
163 const ElementFluxVariablesCache& elemFluxVarsCache)
164 {
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5622400 times.
5622400 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
166 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
167
168 // collect the dispersion tensor
169 9161600 const auto& dispersionTensor = [&]()
170 {
171 5622400 const auto& tensor =
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3539200 times.
5622400 ModelTraits::ThermalDispersionModel::thermalDispersionTensor(problem, scvf, fvGeometry,
173 elemVolVars, elemFluxVarsCache,
174 phaseIdx);
175
176
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5622400 times.
✓ Branch 2 taken 5622400 times.
✗ Branch 3 not taken.
5622400 if (Dune::FloatCmp::eq(insideVolVars.extrusionFactor(), outsideVolVars.extrusionFactor(), 1e-6))
177 5622400 return insideVolVars.extrusionFactor()*tensor;
178 else
179 {
180 const auto insideTensor = insideVolVars.extrusionFactor() * tensor;
181 const auto outsideTensor = outsideVolVars.extrusionFactor() * tensor;
182
183 // the resulting averaged dispersion tensor
184 return faceTensorAverage(insideTensor, outsideTensor, scvf.unitOuterNormal());
185 }
186 5622400 }();
187
188 // compute the temperature gradient with the shape functions
189 5622400 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
190 5622400 Dune::FieldVector<Scalar, GridView::dimensionworld> gradTemp(0.0);
191
2/2
✓ Branch 0 taken 22489600 times.
✓ Branch 1 taken 5622400 times.
28112000 for (auto&& scv : scvs(fvGeometry))
192 44979200 gradTemp.axpy(elemVolVars[scv].temperature(), fluxVarsCache.gradN(scv.indexInElement()));
193
194 // compute the heat conduction flux
195 5622400 return -1.0*vtmv(scvf.unitOuterNormal(), dispersionTensor, gradTemp)*Extrusion::area(fvGeometry, scvf);
196 }
197
198 };
199
200 } // end namespace Dumux
201
202 #endif
203