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>
17#include <dumux/common/typetraits/localdofs_.hh>
21
22#include "flux.hh"
23
24namespace Dumux {
25
30template<class Scalar, class NumEqVector, class LocalBasis, class Extrusion>
32{
33 using RangeType = typename LocalBasis::Traits::RangeType;
34
35public:
45 template<class ResidualVector, class Problem, class ElementDiscretization, class ElementVariables>
46 static void addStorageTerms(ResidualVector& storage,
47 const Problem& problem,
48 const ElementDiscretization& elemDisc,
49 const ElementVariables& elemVars,
50 const bool isPreviousTimeLevel)
51 {
52 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
53 {
54 // Make sure we don't iterate over quadrature points if there are no hybrid dofs
55 if (nonCVLocalDofs(elemDisc).empty())
56 return;
57
58 const auto& localBasis = elemDisc.feLocalBasis();
59 std::vector<RangeType> integralShapeFunctions(localBasis.size(), RangeType(0.0));
60
61 // We apply mass lumping such that we only need to calculate the integral of basis functions
62 const auto& geometry = elemDisc.elementGeometry();
63 const auto& element = elemDisc.element();
66
67 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
68 {
69 const auto& ipData = qpData.ipData();
70 // Obtain and store shape function values and gradients at the current quad point
71 FeIpData feIpData(geometry, ipData.local(), ipData.global(), localBasis);
72
73 // get density from the problem
74 for (const auto& localDof : nonCVLocalDofs(elemDisc))
75 integralShapeFunctions[localDof.index()] += qpData.weight() * feIpData.shapeValue(localDof.index());
76 }
77
78 for (const auto& localDof : nonCVLocalDofs(elemDisc))
79 {
80 const auto localDofIdx = localDof.index();
81 const auto& data = ipData(elemDisc, localDof);
82 const auto density = problem.density(element, elemDisc, data, isPreviousTimeLevel);
83 const auto momentum = density*elemVars[localDofIdx].velocity();
84
85 for (int eqIdx = 0; eqIdx < NumEqVector::dimension; ++eqIdx)
86 storage[localDofIdx][eqIdx] += integralShapeFunctions[localDofIdx][0]*momentum[eqIdx];
87 }
88 }
89 }
90
99 template<class ResidualVector, class Problem, class ElementDiscretization, class ElementVariables>
100 static void addFluxAndSourceTerms(ResidualVector& residual,
101 const Problem& problem,
102 const ElementDiscretization& elemDisc,
103 const ElementVariables& elemVars)
104 {
105 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
106 {
107 // Make sure we don't iterate over quadrature points if there are no hybrid dofs
108 if (nonCVLocalDofs(elemDisc).empty())
109 return;
110
111 if constexpr (requires { problem.pointSources(); })
112 {
113 if (!problem.pointSources().empty())
114 DUNE_THROW(Dune::NotImplemented, "Point sources are not implemented for hybrid momentum schemes.");
115 }
116
117 using GridDiscretization = GridDiscretization_t<ElementDiscretization>;
119
120 const auto& element = elemDisc.element();
121 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
122 {
123 const auto& ipData = qpData.ipData();
124 const auto& ipCache = cache(elemVars, ipData);
125 const auto& shapeValues = ipCache.shapeValues();
126
127 auto fluxTerm = FluxTerms::diffusiveFluxTerm(problem, element, elemDisc, elemVars, ipData, ipCache);
128
129 // the density enters both the advective and the gravity term
130 const Scalar density = problem.density(element, elemDisc, ipData);
131
132 // there is no face to upwind across, so the advective term is interpolated as well
133 if (problem.enableInertiaTerms())
134 {
135 const auto velocity = FluxTerms::velocity(elemDisc, elemVars, ipCache);
136 const auto momentum = [&](const auto&, const auto&, const auto&) { return density*velocity; };
137 const auto transportingVelocity = [&](const auto&, const auto&, const auto&) { return velocity; };
138 fluxTerm += FluxTerms::advectiveFluxTerm(elemDisc, elemVars, ipData, momentum, transportingVelocity);
139 }
140
141 // add gravity term rho*g (note that gravity might be zero in case it's disabled in the problem)
142 auto source = problem.source(elemDisc, elemVars, ipData);
143 source.axpy(density, problem.gravity());
144
145 const auto pressureFluxTerm = FluxTerms::pressureFluxTerm(problem, element, elemDisc, ipData);
146
147 // the weak form -F grad N_i - N_i q
148 for (const auto& localDof : nonCVLocalDofs(elemDisc))
149 {
150 const auto localDofIdx = localDof.index();
151 NumEqVector fluxAndSourceTerm(0.0);
152 fluxTerm.mmv(ipCache.gradN(localDofIdx), fluxAndSourceTerm);
153 pressureFluxTerm.mmv(ipCache.gradN(localDofIdx), fluxAndSourceTerm);
154 fluxAndSourceTerm.axpy(-shapeValues[localDofIdx][0], source);
155
156 for (int eqIdx = 0; eqIdx < NumEqVector::dimension; ++eqIdx)
157 residual[localDofIdx][eqIdx] += qpData.weight()*fluxAndSourceTerm[eqIdx];
158 }
159 }
160 }
161 }
162
163};
164
169template<class TypeTag>
172{
174
176 using GridVariablesCache = typename GridVariables::GridVariablesCache;
177 using ElementVariables = typename GridVariablesCache::LocalView;
178
181 using GridDiscretization = GetPropType<TypeTag, Properties::GridGeometry>;
182 using ElementDiscretization = typename GridDiscretization::LocalView;
183 using GridView = typename GridDiscretization::GridView;
184 using Element = typename GridView::template Codim<0>::Entity;
186 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
187
188 using Extrusion = Extrusion_t<GridDiscretization>;
189
190 using LocalBasis = typename GridDiscretization::FeCache::FiniteElementType::Traits::LocalBasisType;
192
193public:
194 using ElementResidualVector = typename ParentType::ElementResidualVector;
195 using ParentType::ParentType;
196
198 const Problem& problem,
199 const Element& element,
200 const ElementDiscretization& elemDisc,
201 const ElementVariables& elemVars,
202 bool isPreviousTimeLevel) const
203 {
204 FeResidual::addStorageTerms(storage, problem, elemDisc, elemVars, isPreviousTimeLevel);
205 }
206
208 const Problem& problem,
209 const Element& element,
210 const ElementDiscretization& elemDisc,
211 const ElementVariables& elemVars) const
212 {
214 residual, problem, elemDisc, elemVars
215 );
216 }
217};
218
219} // end namespace Dumux
220
221#endif
Boundary flag to store e.g. in sub control volume faces.
Momentum flux of the Navier-Stokes equations for control-volume finite element schemes,...
Definition flux.hh:245
Definition fem/interpolationpointdata.hh:21
Element-wise calculation of the Navier-Stokes residual for models using FE discretizations.
Definition momentum/cvfe/felocalresidual.hh:172
typename ParentType::ElementResidualVector ElementResidualVector
Definition momentum/cvfe/felocalresidual.hh:194
void addToElementStorage(ElementResidualVector &storage, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, bool isPreviousTimeLevel) const
Definition momentum/cvfe/felocalresidual.hh:197
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
Definition momentum/cvfe/felocalresidual.hh:207
Helper class for evaluating FE-based local residuals.
Definition momentum/cvfe/felocalresidual.hh:32
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:46
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:100
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.
Type traits for classes providing a grid discretization.
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
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
typename Detail::GridDiscretizationType< T >::type GridDiscretization_t
The grid discretization type of a class exporting it.
Definition griddiscretization.hh:54
auto quadratureRule(const FVElementGeometry &fvGeometry, const typename FVElementGeometry::SubControlVolume &scv, QuadratureRules::MidpointQuadrature)
Midpoint quadrature for scv.
Definition quadraturerules.hh:160
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