version 3.11-dev
Loading...
Searching...
No Matches
solidmechanics/elastic/localresidual.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//
13#ifndef DUMUX_SOLIDMECHANICS_ELASTIC_LOCAL_RESIDUAL_HH
14#define DUMUX_SOLIDMECHANICS_ELASTIC_LOCAL_RESIDUAL_HH
15
16#include <ranges>
17
18#include <dune/common/fmatrix.hh>
19
23#include <dumux/common/typetraits/localdofs_.hh>
26
27namespace Dumux {
28
43template<class TypeTag>
46{
49
50 using GridView = typename GridGeometry::GridView;
51 using Element = typename GridView::template Codim<0>::Entity;
52
55 using FVElementGeometry = typename GridGeometry::LocalView;
57
58 // class assembling the stress tensor
60
61 static constexpr int dim = GridView::dimension;
62 static constexpr int dimWorld = GridView::dimensionworld;
64 using Tensor = Dune::FieldMatrix<Scalar, dim, dimWorld>;
65
66public:
67 using ParentType::ParentType;
68
77 template<class SubControlVolume, class VolumeVariables>
78 NumEqVector computeStorage(const Problem& problem,
79 const SubControlVolume& scv,
80 const VolumeVariables& volVars) const
81 {
82 return NumEqVector(0.0);
83 }
84
96 template<class ElementVolumeVariables, class SubControlVolumeFace, class ElementFluxVariablesCache>
97 NumEqVector computeFlux(const Problem& problem,
98 const Element& element,
99 const FVElementGeometry& fvGeometry,
100 const ElementVolumeVariables& elemVolVars,
101 const SubControlVolumeFace& scvf,
102 const ElementFluxVariablesCache& elemFluxVarsCache) const
103 {
104 // obtain force on the face from stress type
105 return StressType::force(problem, element, fvGeometry, elemVolVars, scvf, elemFluxVarsCache);
106 }
107
121 template<class ElementVolumeVariables, class SubControlVolume>
122 NumEqVector computeSource(const Problem& problem,
123 const Element& element,
124 const FVElementGeometry& fvGeometry,
125 const ElementVolumeVariables& elemVolVars,
126 const SubControlVolume &scv) const
127 {
128 NumEqVector source(0.0);
129
130 // add contributions from volume flux sources
131 source += problem.source(element, fvGeometry, elemVolVars, scv);
132
133 // add contribution from possible point sources
134 source += problem.scvPointSources(element, fvGeometry, elemVolVars, scv);
135
136 // maybe add gravitational acceleration
137 static const bool gravity = getParamFromGroup<bool>(problem.paramGroup(), "Problem.EnableGravity");
138 if (gravity)
139 {
140 const auto& g = problem.spatialParams().gravity(scv.center());
141 for (int dir = 0; dir < GridView::dimensionworld; ++dir)
142 source[Indices::momentum(dir)] += elemVolVars[scv].solidDensity()*g[dir];
143 }
144
145 return source;
146 }
147
148 template<class ElementDiscretization, class ElementVariables, class Scv>
149 NumEqVector storageIntegral(const ElementDiscretization&, const ElementVariables&, const Scv&, bool) const
150 { return NumEqVector(0.0); }
151
153 template<class ElementDiscretization, class ElementVariables, class Scv>
154 NumEqVector sourceIntegral(const ElementDiscretization& elemDisc,
155 const ElementVariables& elemVars,
156 const Scv& scv) const
157 {
158 const auto& problem = this->asImp().problem();
159 NumEqVector source(0.0);
160 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scv))
161 source.axpy(qpData.weight(), problem.source(elemDisc, elemVars, qpData.ipData()));
162 source *= elemVars[scv].extrusionFactor();
163 return source;
164 }
165
167 template<class ElementDiscretization, class ElementVariables, class Scvf>
168 NumEqVector fluxIntegral(const ElementDiscretization& elemDisc,
169 const ElementVariables& elemVars,
170 const Scvf& scvf) const
171 {
172 const auto& problem = this->asImp().problem();
173 NumEqVector flux(0.0);
174 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scvf))
175 {
176 const auto& ipData = qpData.ipData();
177 const auto sigma = stressTensor_(problem, elemDisc, elemVars, ipData);
178 for (int dir = 0; dir < dim; ++dir)
179 flux[Indices::momentum(dir)] -= qpData.weight()*(sigma[dir]*scvf.unitOuterNormal());
180 }
181 flux *= elemVars[elemDisc.scv(scvf.insideScvIdx())].extrusionFactor();
182 return flux;
183 }
184
189 template<class ElementResidualVector, class ElementDiscretization, class ElementVariables>
190 void addToElementFluxAndSourceResidual(ElementResidualVector& residual,
191 const Problem& problem,
192 const Element& element,
193 const ElementDiscretization& elemDisc,
194 const ElementVariables& elemVars) const
195 {
196 if constexpr (Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
197 {
198 if (std::ranges::empty(nonCVLocalDofs(elemDisc)))
199 return;
200
201 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
202 {
203 const auto& ipData = qpData.ipData();
204 const auto& ipCache = cache(elemVars, ipData);
205 const auto sigma = stressTensor_(problem, elemDisc, elemVars, ipData);
206 const auto bodyForce = problem.source(elemDisc, elemVars, ipData);
207 const auto& shapeValues = ipCache.shapeValues();
208 for (const auto& localDof : nonCVLocalDofs(elemDisc))
209 {
210 const auto idx = localDof.index();
211 for (int dir = 0; dir < dim; ++dir)
212 {
213 const auto eqIdx = Indices::momentum(dir);
214 residual[idx][eqIdx] += qpData.weight()*(sigma[dir]*ipCache.gradN(idx)
215 - shapeValues[idx][0]*bodyForce[eqIdx]);
216 }
217 }
218 }
219 }
220 }
221
222private:
224 template<class ElementDiscretization, class ElementVariables, class IpData>
225 Tensor stressTensor_(const Problem& problem,
226 const ElementDiscretization& elemDisc,
227 const ElementVariables& elemVars,
228 const IpData& ipData) const
229 {
230 const auto& ipCache = cache(elemVars, ipData);
231 Tensor gradU(0.0);
232 for (const auto& localDof : localDofs(elemDisc))
233 for (int dir = 0; dir < dim; ++dir)
234 gradU[dir].axpy(elemVars[localDof].displacement(dir), ipCache.gradN(localDof.index()));
235
236 const auto& lame = problem.spatialParams().lameParams(elemDisc, ipData);
237 Tensor sigma(0.0);
238 Scalar trace = 0.0;
239 for (int i = 0; i < dim; ++i)
240 trace += gradU[i][i];
241 for (int i = 0; i < dim; ++i)
242 {
243 for (int j = 0; j < dimWorld; ++j)
244 sigma[i][j] = lame.mu()*(gradU[i][j] + gradU[j][i]);
245 sigma[i][i] += lame.lambda()*trace;
246 }
247 return sigma;
248 }
249};
250
251} // end namespace Dumux
252
253#endif
Element-wise calculation of the local residual for problems using the elastic model considering linea...
Definition solidmechanics/elastic/localresidual.hh:46
NumEqVector storageIntegral(const ElementDiscretization &, const ElementVariables &, const Scv &, bool) const
The storage term is zero for quasi-static elasticity (assembly with local degrees of freedom).
Definition solidmechanics/elastic/localresidual.hh:149
NumEqVector sourceIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const Scv &scv) const
The body force over a control volume (assembly with local degrees of freedom).
Definition solidmechanics/elastic/localresidual.hh:154
NumEqVector computeStorage(const Problem &problem, const SubControlVolume &scv, const VolumeVariables &volVars) const
For the elastic model the storage term is zero since we neglect inertia forces.
Definition solidmechanics/elastic/localresidual.hh:78
NumEqVector computeSource(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolume &scv) const
Calculate the source term of the equation.
Definition solidmechanics/elastic/localresidual.hh:122
NumEqVector fluxIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const Scvf &scvf) const
The stress flux over a control volume face (assembly with local degrees of freedom).
Definition solidmechanics/elastic/localresidual.hh:168
NumEqVector computeFlux(const Problem &problem, const Element &element, const FVElementGeometry &fvGeometry, const ElementVolumeVariables &elemVolVars, const SubControlVolumeFace &scvf, const ElementFluxVariablesCache &elemFluxVarsCache) const
Evaluates the force in all grid directions acting on a face of a sub-control volume.
Definition solidmechanics/elastic/localresidual.hh:97
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const Element &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
The Galerkin terms of the degrees of freedom without control volume (assembly with local degrees of ...
Definition solidmechanics/elastic/localresidual.hh:190
Defines all properties used in Dumux.
The default local operator than can be specialized for each discretization scheme.
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::DenseMatrix< MatrixType >::field_type trace(const Dune::DenseMatrix< MatrixType > &M)
Trace of a dense matrix.
Definition math.hh:800
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
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.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Quadrature rules over sub-control volumes and sub-control volume faces.