version 3.11-dev
Loading...
Searching...
No Matches
mass/1p/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_MASS_ONEP_FE_LOCAL_RESIDUAL_HH
13#define DUMUX_NAVIERSTOKES_MASS_ONEP_FE_LOCAL_RESIDUAL_HH
14
15#include <vector>
16
17#include <dune/common/exceptions.hh>
18
22#include <dumux/common/typetraits/localdofs_.hh>
26
27namespace Dumux {
28
33template<class Scalar, class Indices>
35{
36public:
46 template<class ResidualVector, class Problem, class ElementDiscretization, class ElementVariables>
47 static void addStorageTerms(ResidualVector& storage,
48 const Problem& problem,
49 const ElementDiscretization& elemDisc,
50 const ElementVariables& elemVars,
51 const bool isPreviousTimeLevel)
52 {
53 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
54 {
55 // Make sure we don't iterate over quadrature points if there are no hybrid dofs
56 if (nonCVLocalDofs(elemDisc).empty())
57 return;
58
59 std::vector<Scalar> integralShapeFunctions(Detail::LocalDofs::numLocalDofs(elemDisc), 0.0);
60
61 // We apply mass lumping such that we only need to calculate the integral of basis functions
62 const auto& element = elemDisc.element();
63 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
64 {
65 const auto& ipData = qpData.ipData();
66 const auto& shapeValues = cache(elemVars, ipData).shapeValues();
67 for (const auto& localDof : nonCVLocalDofs(elemDisc))
68 integralShapeFunctions[localDof.index()] += qpData.weight()*shapeValues[localDof.index()][0];
69 }
70
71 for (const auto& localDof : nonCVLocalDofs(elemDisc))
72 {
73 const auto localDofIdx = localDof.index();
74 storage[localDofIdx][Indices::conti0EqIdx]
75 += integralShapeFunctions[localDofIdx]*elemVars[localDofIdx].density();
76 }
77 }
78 }
79
88 template<class ResidualVector, class Problem, class ElementDiscretization, class ElementVariables>
89 static void addFluxAndSourceTerms(ResidualVector& residual,
90 const Problem& problem,
91 const ElementDiscretization& elemDisc,
92 const ElementVariables& elemVars)
93 {
94 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
95 {
96 // Make sure we don't iterate over quadrature points if there are no hybrid dofs
97 if (nonCVLocalDofs(elemDisc).empty())
98 return;
99
100 if constexpr (requires { problem.pointSources(); })
101 {
102 if (!problem.pointSources().empty())
103 DUNE_THROW(Dune::NotImplemented, "Point sources are not implemented for hybrid mass schemes.");
104 }
105
107
108 const auto& element = elemDisc.element();
109 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
110 {
111 const auto& ipData = qpData.ipData();
112 const auto& ipCache = cache(elemVars, ipData);
113 const auto& shapeValues = ipCache.shapeValues();
114
115 const Scalar divV = problem.velocityDivergence(elemDisc, ipData);
116
117 Scalar density = 0.0;
118 GlobalPosition gradDensity(0.0);
119 for (const auto& localDof : localDofs(elemDisc))
120 {
121 const auto localDensity = elemVars[localDof.index()].density();
122 density += localDensity*shapeValues[localDof.index()][0];
123 gradDensity.axpy(localDensity, ipCache.gradN(localDof.index()));
124 }
125
126 const auto velocity = problem.velocity(elemDisc, ipData);
127 const auto source = problem.source(elemDisc, elemVars, ipData);
128 const Scalar divMassFlux = density*divV + (velocity*gradDensity);
129
130 // the strong form N_i (div(rho v) - q), the continuity equation is not integrated by parts
131 for (const auto& localDof : nonCVLocalDofs(elemDisc))
132 {
133 const auto localDofIdx = localDof.index();
134 residual[localDofIdx][Indices::conti0EqIdx]
135 += qpData.weight() * shapeValues[localDofIdx][0] * (divMassFlux - source[Indices::conti0EqIdx]);
136 }
137 }
138 }
139 }
140};
141
146template<class TypeTag>
149{
151
153 using GridVariablesCache = typename GridVariables::GridVariablesCache;
154 using ElementVariables = typename GridVariablesCache::LocalView;
155
158 using ElementDiscretization = typename GridGeometry::LocalView;
159 using GridView = typename GridGeometry::GridView;
160 using Element = typename GridView::template Codim<0>::Entity;
164
165public:
166 using ElementResidualVector = typename ParentType::ElementResidualVector;
167 using ParentType::ParentType;
168
174 const Problem& problem,
175 const Element& element,
176 const ElementDiscretization& elemDisc,
177 const ElementVariables& elemVars,
178 bool isPreviousTimeLevel) const
179 {
180 FeResidual::addStorageTerms(storage, problem, elemDisc, elemVars, isPreviousTimeLevel);
181 }
182
188 const Problem& problem,
189 const Element& element,
190 const ElementDiscretization& elemDisc,
191 const ElementVariables& elemVars) const
192 {
193 FeResidual::addFluxAndSourceTerms(residual, problem, elemDisc, elemVars);
194 }
195
203 const Problem& problem,
204 const ElementDiscretization& elemDisc,
205 const ElementVariables& elemVars) const
206 {}
207};
208
209} // end namespace Dumux
210
211#endif
Element-wise calculation of the Navier-Stokes mass residual for single-phase flow when using fe discr...
Definition mass/1p/felocalresidual.hh:149
typename ParentType::ElementResidualVector ElementResidualVector
Definition mass/1p/felocalresidual.hh:166
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
Adds the continuity residual.
Definition mass/1p/felocalresidual.hh:187
void addBoundaryFluxIntegral(ElementResidualVector &residual, const Problem &problem, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
Add boundary flux contributions.
Definition mass/1p/felocalresidual.hh:202
void addToElementStorage(ElementResidualVector &storage, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars, bool isPreviousTimeLevel) const
Adds the storage at one time level.
Definition mass/1p/felocalresidual.hh:173
Helper class for evaluating FE-based local residuals.
Definition mass/1p/felocalresidual.hh:35
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 mass/1p/felocalresidual.hh:47
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 mass/1p/felocalresidual.hh:89
Defines all properties used in Dumux.
The default local operator than can be specialized for each discretization scheme.
Type traits for classes providing a grid discretization.
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
Class representing dofs on elements for control-volume finite element schemes.
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
auto localDofs(const FVElementGeometry &fvGeometry)
range over local dofs
Definition localdof.hh:50
A helper to deduce a vector with the same size as numbers of equations.
Quadrature rules over sub-control volumes and sub-control volume faces.