version 3.11-dev
Loading...
Searching...
No Matches
momentum/cvfe/felocalresidual.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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_NAVIERSTOKES_MOMENTUM_CVFE_FE_LOCAL_RESIDUAL_HELPER_HH
13#define DUMUX_NAVIERSTOKES_MOMENTUM_CVFE_FE_LOCAL_RESIDUAL_HELPER_HH
14
15#include <dune/geometry/quadraturerules.hh>
16#include <dumux/common/typetraits/localdofs_.hh>
20
21#include "flux.hh"
22
23namespace Dumux {
24
29template<class Scalar, class NumEqVector, class LocalBasis, class Extrusion>
31{
32 using RangeType = typename LocalBasis::Traits::RangeType;
33
34public:
44 template<class ResidualVector, class Problem, class ElementDiscretization, class ElementVariables>
45 static void addStorageTerms(ResidualVector& storage,
46 const Problem& problem,
47 const ElementDiscretization& elemDisc,
48 const ElementVariables& elemVars,
49 const bool isPreviousTimeLevel)
50 {
51 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
52 {
53 // Make sure we don't iterate over quadrature points if there are no hybrid dofs
54 if (nonCVLocalDofs(elemDisc).empty())
55 return;
56
57 const auto& localBasis = elemDisc.feLocalBasis();
58 std::vector<RangeType> integralShapeFunctions(localBasis.size(), RangeType(0.0));
59
60 // We apply mass lumping such that we only need to calculate the integral of basis functions
61 const auto& geometry = elemDisc.elementGeometry();
62 const auto& element = elemDisc.element();
63 using GlobalPosition = typename ElementDiscretization::GridGeometry::GlobalCoordinate;
65
66 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
67 {
68 const auto& ipData = qpData.ipData();
69 // Obtain and store shape function values and gradients at the current quad point
70 FeIpData feIpData(geometry, ipData.local(), ipData.global(), localBasis);
71
72 // get density from the problem
73 for (const auto& localDof : nonCVLocalDofs(elemDisc))
74 integralShapeFunctions[localDof.index()] += qpData.weight() * feIpData.shapeValue(localDof.index());
75 }
76
77 for (const auto& localDof : nonCVLocalDofs(elemDisc))
78 {
79 const auto localDofIdx = localDof.index();
80 const auto& data = ipData(elemDisc, localDof);
81 const auto density = problem.density(element, elemDisc, data, isPreviousTimeLevel);
82 const auto momentum = density*elemVars[localDofIdx].velocity();
83
84 for (int eqIdx = 0; eqIdx < NumEqVector::dimension; ++eqIdx)
85 storage[localDofIdx][eqIdx] += integralShapeFunctions[localDofIdx]*momentum[eqIdx];
86 }
87 }
88 }
89
98 template<class ResidualVector, class Problem, class ElementDiscretization, class ElementVariables>
99 static void addFluxAndSourceTerms(ResidualVector& residual,
100 const Problem& problem,
101 const ElementDiscretization& elemDisc,
102 const ElementVariables& elemVars)
103 {
104 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
105 {
106 // Make sure we don't iterate over quadrature points if there are no hybrid dofs
107 if (nonCVLocalDofs(elemDisc).empty())
108 return;
109
110 if constexpr (requires { problem.pointSources(); })
111 {
112 if (!problem.pointSources().empty())
113 DUNE_THROW(Dune::NotImplemented, "Point sources are not implemented for hybrid momentum schemes.");
114 }
115
116 static const bool enableUnsymmetrizedVelocityGradient
117 = getParamFromGroup<bool>(problem.paramGroup(), "FreeFlow.EnableUnsymmetrizedVelocityGradient", false);
118
119 const auto& element = elemDisc.element();
120 using Cache = typename ElementVariables::InterpolationPointData;
122 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
123 {
124 const auto& ipData = qpData.ipData();
125 // Obtain and store shape function values and gradients at the current quad point
126 const auto& ipCache = cache(elemVars, ipData);
127 FluxFunctionContext context(problem, elemDisc, elemVars, ipCache);
128 const auto& v = context.velocity();
129 const auto& gradV = context.gradVelocity();
130
131 // get viscosity from the problem
132 const Scalar mu = problem.effectiveViscosity(element, elemDisc, ipData);
133 // get density from the problem
134 const Scalar density = problem.density(element, elemDisc, ipData);
135
136 for (const auto& localDof : nonCVLocalDofs(elemDisc))
137 {
138 const auto localDofIdx = localDof.index();
139 NumEqVector fluxAndSourceTerm(0.0);
140 // add advection term
141 if (problem.enableInertiaTerms())
142 fluxAndSourceTerm -= density*(v*ipCache.gradN(localDofIdx))*v;
143
144 // add diffusion term
145 fluxAndSourceTerm += enableUnsymmetrizedVelocityGradient ?
146 mu*mv(gradV, ipCache.gradN(localDofIdx))
147 : mu*mv(gradV + getTransposed(gradV), ipCache.gradN(localDofIdx));
148
149 // add pressure term
150 fluxAndSourceTerm -= problem.pressure(element, elemDisc, ipData) * ipCache.gradN(localDofIdx);
151
152 // finally add source and flux boundary term and add everything to residual
153 auto sourceAtIp = problem.source(elemDisc, elemVars, ipData);
154 // add gravity term rho*g (note that gravity might be zero in case it's disabled in the problem)
155 sourceAtIp += density * problem.gravity();
156
157 const auto& shapeValues = ipCache.shapeValues();
158 for (int eqIdx = 0; eqIdx < NumEqVector::dimension; ++eqIdx)
159 {
160 fluxAndSourceTerm[eqIdx] -= shapeValues[localDofIdx] * sourceAtIp[eqIdx];
161 residual[localDofIdx][eqIdx] += qpData.weight()*fluxAndSourceTerm[eqIdx];
162 }
163 }
164 }
165 }
166 }
167
168};
169
174template<class TypeTag>
177{
179
181 using GridVariablesCache = typename GridVariables::GridVariablesCache;
182 using ElementVariables = typename GridVariablesCache::LocalView;
183
186 using GridDiscretization = GetPropType<TypeTag, Properties::GridGeometry>;
187 using ElementDiscretization = typename GridDiscretization::LocalView;
188 using GridView = typename GridDiscretization::GridView;
189 using Element = typename GridView::template Codim<0>::Entity;
191 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
192
193 using Extrusion = Extrusion_t<GridDiscretization>;
194
195 using LocalBasis = typename GridDiscretization::FeCache::FiniteElementType::Traits::LocalBasisType;
197
198public:
199 using ElementResidualVector = typename ParentType::ElementResidualVector;
200 using ParentType::ParentType;
201
203 const Problem& problem,
204 const Element& element,
205 const ElementDiscretization& elemDisc,
206 const ElementVariables& elemVars,
207 bool isPreviousTimeLevel) const
208 {
209 FeResidual::addStorageTerms(storage, problem, elemDisc, elemVars, isPreviousTimeLevel);
210 }
211
213 const Problem& problem,
214 const Element& element,
215 const ElementDiscretization& elemDisc,
216 const ElementVariables& elemVars) const
217 {
219 residual, problem, elemDisc, elemVars
220 );
221 }
222};
223
224} // end namespace Dumux
225
226#endif
Boundary flag to store e.g. in sub control volume faces.
Definition fem/interpolationpointdata.hh:21
Element-wise calculation of the Navier-Stokes residual for models using FE discretizations.
Definition momentum/cvfe/felocalresidual.hh:177
typename ParentType::ElementResidualVector ElementResidualVector
Definition momentum/cvfe/felocalresidual.hh:199
void addToElementStorage(ElementResidualVector &storage, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, bool isPreviousTimeLevel) const
Definition momentum/cvfe/felocalresidual.hh:202
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
Definition momentum/cvfe/felocalresidual.hh:212
Helper class for evaluating FE-based local residuals.
Definition momentum/cvfe/felocalresidual.hh:31
static void addStorageTerms(ResidualVector &storage, const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const bool isPreviousTimeLevel)
Add the storage of non-CV local dofs at one time level.
Definition momentum/cvfe/felocalresidual.hh:45
static void addFluxAndSourceTerms(ResidualVector &residual, const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &elemVars)
Add flux and source residual contribution for non-CV local dofs.
Definition momentum/cvfe/felocalresidual.hh:99
Context for interpolating data on interpolation points.
Definition flux.hh:99
Helper classes to compute the integration elements.
Shape functions and gradients at an interpolation point.
The flux variables class for the Navier-Stokes model using control-volume finite element schemes.
typename NumEqVectorTraits< PrimaryVariables >::type NumEqVector
A vector with the same size as numbers of equations This is the default implementation and has to be ...
Definition numeqvector.hh:34
Dune::DenseVector< V >::derived_type mv(const Dune::DenseMatrix< MAT > &M, const Dune::DenseVector< V > &v)
Returns the result of the projection of a vector v with a Matrix M.
Definition math.hh:829
Dune::FieldMatrix< Scalar, n, m > getTransposed(const Dune::FieldMatrix< Scalar, m, n > &M)
Transpose a FieldMatrix.
Definition math.hh:712
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:165
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
auto quadratureRule(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolume &scv, QuadratureRules::MidpointQuadrature)
Midpoint quadrature for scv.
Definition quadraturerules.hh:159
Definition adapt.hh:17
typename Detail::DiscretizationDefaultLocalOperator< TypeTag >::type DiscretizationDefaultLocalOperator
Definition defaultlocaloperator.hh:26
typename Extrusion< T >::type Extrusion_t
Convenience alias for obtaining the extrusion type.
Definition extrusion.hh:257