version 3.8
scheidegger.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//
12#ifndef DUMUX_MATERIAL_FLUIDMATRIX_DISPERSIONTENSORS_SCHEIDEGGER_HH
13#define DUMUX_MATERIAL_FLUIDMATRIX_DISPERSIONTENSORS_SCHEIDEGGER_HH
14
15#include <algorithm>
16#include <cmath>
17#include <dune/common/math.hh>
18#include <dune/common/std/type_traits.hh>
19#include <dune/common/fmatrix.hh>
24#include <dumux/flux/traits.hh>
25
26namespace Dumux {
27
28namespace Detail {
29template <class Problem, class SubControlVolumeFace>
30using HasVelocityInSpatialParams = decltype(std::declval<Problem>().spatialParams().velocity(std::declval<SubControlVolumeFace>()));
31
32template<class Problem, class SubControlVolumeFace>
33static constexpr bool hasVelocityInSpatialParams()
34{ return Dune::Std::is_detected<HasVelocityInSpatialParams, Problem, SubControlVolumeFace>::value; }
35}
36
41template<class TypeTag>
43{
46 using FVElementGeometry = typename GridGeometry::LocalView;
47 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
48 using ElementVolumeVariables = typename GetPropType<TypeTag, Properties::GridVolumeVariables>::LocalView;
49
52 static const int dimWorld = GridView::dimensionworld;
53 using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
54
56 using FluxTraits = typename Dumux::FluxTraits<FluxVariables>;
57 static constexpr bool stationaryVelocityField = FluxTraits::hasStationaryVelocityField();
58
59public:
60 template <class ElementFluxVariablesCache>
61 static DimWorldMatrix compositionalDispersionTensor(const Problem& problem,
62 const SubControlVolumeFace& scvf,
63 const FVElementGeometry& fvGeometry,
64 const ElementVolumeVariables& elemVolVars,
65 const ElementFluxVariablesCache& elemFluxVarsCache,
66 const int phaseIdx,
67 const int compIdx)
68 {
69 DimWorldMatrix dispersionTensor(0.0);
70
71 // Get the velocity either from the reconstruction, or from the spatialparams
72 auto velocity = dispersionVelocity_(problem, scvf, fvGeometry, elemVolVars, elemFluxVarsCache);
73
74 // collect the dispersion alphas at this location
75 std::array<Scalar,2> dispersivity = problem.spatialParams().dispersionAlphas(scvf.center(), phaseIdx, compIdx);
76
77 return scheideggerTensor_(dispersivity, velocity);
78 }
79
80 template <class ElementFluxVariablesCache>
81 static DimWorldMatrix thermalDispersionTensor(const Problem& problem,
82 const SubControlVolumeFace& scvf,
83 const FVElementGeometry& fvGeometry,
84 const ElementVolumeVariables& elemVolVars,
85 const ElementFluxVariablesCache& elemFluxVarsCache,
86 const int phaseIdx)
87 {
88 DimWorldMatrix dispersionTensor(0.0);
89
90 // Get the velocity either from the reconstruction, or from the spatialparams
91 auto velocity = dispersionVelocity_(problem, scvf, fvGeometry, elemVolVars, elemFluxVarsCache);
92
93 // collect the dispersion alphas at this location
94 std::array<Scalar,2> dispersivity = problem.spatialParams().dispersionAlphas(scvf.center(), phaseIdx); //TODO: fix this?
95
96 return scheideggerTensor_(dispersivity, velocity);
97 }
98
99private:
100
101 template <class ElementFluxVariablesCache>
102 static Dune::FieldVector<Scalar, dimWorld> dispersionVelocity_(const Problem& problem,
103 const SubControlVolumeFace& scvf,
104 [[maybe_unused]] const FVElementGeometry& fvGeometry,
105 [[maybe_unused]] const ElementVolumeVariables& elemVolVars,
106 [[maybe_unused]] const ElementFluxVariablesCache& elemFluxVarsCache)
107 {
108 // Calculate Darcy's velocity
109 Dune::FieldVector<Scalar, dimWorld> velocity(0.0);
110 if constexpr (stationaryVelocityField)
111 {
112 if constexpr (!Detail::hasVelocityInSpatialParams<Problem,SubControlVolumeFace>() )
113 DUNE_THROW(Dune::NotImplemented, "\n Please provide the stationary velocity field in the spatialparams via a velocity function.");
114 else
115 velocity = problem.spatialParams().velocity(scvf);
116 }
117 else
118 {
119 if constexpr (FVElementGeometry::GridGeometry::discMethod == DiscretizationMethods::box)
120 {
121 const auto& fluxVarsCache = elemFluxVarsCache[scvf];
122 const auto& shapeValues = fluxVarsCache.shapeValues();
123
124 // get inside and outside permeability tensors and calculate the harmonic mean
125 const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()];
126 const auto& outsideVolVars = elemVolVars[scvf.outsideScvIdx()];
127 const auto K = faceTensorAverage(insideVolVars.permeability(),
128 outsideVolVars.permeability(),
129 scvf.unitOuterNormal());
130
131 // evaluate gradP - rho*g at integration point
132 Dune::FieldVector<Scalar, dimWorld> gradP(0.0);
133 Scalar rho(0.0);
134 static const bool enableGravity = getParamFromGroup<bool>(problem.paramGroup(), "Problem.EnableGravity");
135 for (auto&& scv : scvs(fvGeometry))
136 {
137 const auto& volVars = elemVolVars[scv];
138
139 if (enableGravity)
140 rho += volVars.density(0)*shapeValues[scv.indexInElement()][0];
141 // the global shape function gradient
142 gradP.axpy(volVars.pressure(0), fluxVarsCache.gradN(scv.indexInElement()));
143 }
144
145 if (enableGravity)
146 gradP.axpy(-rho, problem.spatialParams().gravity(scvf.center()));
147
148 velocity = gradP;
149 velocity *= K;
150
151 velocity /= -0.5 * (insideVolVars.viscosity() + outsideVolVars.viscosity());
152 }
153 else
154 DUNE_THROW(Dune::NotImplemented, "\n Scheidegger Dispersion for compositional models without given constant velocity field is only implemented using the Box method.");
155 }
156
157 return velocity;
158 }
159
160 static DimWorldMatrix scheideggerTensor_(const std::array<Scalar,2>& dispersivity,
161 const Dune::FieldVector<Scalar, dimWorld>& velocity)
162 {
163 DimWorldMatrix scheideggerTensor(0.0);
164
165 //matrix multiplication of the velocity at the interface: vv^T
166 for (int i=0; i < dimWorld; i++)
167 for (int j = 0; j < dimWorld; j++)
168 scheideggerTensor[i][j] = velocity[i]*velocity[j];
169
170 //normalize velocity product --> vv^T/||v||, [m/s]
171 Scalar vNorm = velocity.two_norm();
172
173 scheideggerTensor /= vNorm;
174 if (vNorm < 1e-20)
175 scheideggerTensor = 0;
176
177 //multiply with dispersivity difference: vv^T/||v||*(alphaL - alphaT), [m^2/s] --> alphaL = longitudinal disp., alphaT = transverse disp.
178 scheideggerTensor *= (dispersivity[0] - dispersivity[1]);
179
180 //add ||v||*alphaT to the main diagonal:vv^T/||v||*(alphaL - alphaT) + ||v||*alphaT, [m^2/s]
181 for (int i = 0; i < dimWorld; i++)
182 scheideggerTensor[i][i] += vNorm*dispersivity[1];
183
184 return scheideggerTensor;
185 }
186
187};
188
189} // end namespace Dumux
190
191#endif
Scheidegger's dispersion tensor.
Definition: scheidegger.hh:43
static DimWorldMatrix compositionalDispersionTensor(const Problem &problem, const SubControlVolumeFace &scvf, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const int phaseIdx, const int compIdx)
Definition: scheidegger.hh:61
static DimWorldMatrix thermalDispersionTensor(const Problem &problem, const SubControlVolumeFace &scvf, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const ElementFluxVariablesCache &elemFluxVarsCache, const int phaseIdx)
Definition: scheidegger.hh:81
Defines all properties used in Dumux.
A free function to average a Tensor at an interface.
Defines the flux traits.
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition: propertysystem.hh:296
The available discretization methods in Dumux.
decltype(std::declval< Problem >().spatialParams().velocity(std::declval< SubControlVolumeFace >())) HasVelocityInSpatialParams
Definition: scheidegger.hh:30
static constexpr bool hasVelocityInSpatialParams()
Definition: scheidegger.hh:33
constexpr Box box
Definition: method.hh:147
Definition: adapt.hh:17
Scalar faceTensorAverage(const Scalar T1, const Scalar T2, const Dune::FieldVector< Scalar, dim > &normal)
Average of a discontinuous scalar field at discontinuity interface (for compatibility reasons with th...
Definition: facetensoraverage.hh:29
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Traits of a flux variables type.
Definition: flux/traits.hh:32
static constexpr bool hasStationaryVelocityField()
Definition: flux/traits.hh:33