version 3.11-dev
Loading...
Searching...
No Matches
solidmechanics/hyperelastic_voliso/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//
23#ifndef DUMUX_SOLIDMECHANICS_HYPERELASTIC_VOLISO_LOCAL_RESIDUAL_HH
24#define DUMUX_SOLIDMECHANICS_HYPERELASTIC_VOLISO_LOCAL_RESIDUAL_HH
25
26#include <dune/common/fmatrix.hh>
27#include <dune/grid/common/intersectioniterator.hh>
28
29#include <dumux/common/math.hh>
32#include <dumux/common/typetraits/localdofs_.hh>
36
37namespace Dumux {
38
51template<class TypeTag>
53{
59 using ElementDiscretization = typename GridGeometry::LocalView;
60 using GridView = typename GridGeometry::GridView;
61 using GlobalPosition = typename GridView::template Codim<0>::Entity::Geometry::GlobalCoordinate;
63 using Tensor = Dune::FieldMatrix<Scalar, GridView::dimension, GridView::dimension>;
64 static constexpr int dim = GridView::dimension;
65
67 using ElementVariables = typename GridVariables::GridVariablesCache::LocalView;
68
69public:
70 using ParentType::ParentType;
71 using ElementResidualVector = typename ParentType::ElementResidualVector;
72
73 NumEqVector computeStorage(const auto&, const auto&, const auto&) const
74 { return NumEqVector(0.0); }
75
76 NumEqVector storageIntegral(const ElementDiscretization&, const ElementVariables&,
77 const auto&, bool) const
78 { return NumEqVector(0.0); }
79
82 const Problem& problem,
83 const auto& element,
84 const ElementDiscretization& elemDisc,
85 const ElementVariables& elemVars) const
86 {
87 if constexpr (Dumux::Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
88 {
89 if (nonCVLocalDofs(elemDisc).empty())
90 return;
91
92 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element))
93 {
94 const auto& ipCache = cache(elemVars, qpData.ipData());
95 const auto& ipGlobal = qpData.ipData().global();
96
97 const auto F = deformationGradient_(elemDisc, elemVars, ipCache);
98 const auto P = firstPiolaKirchhoffStressTensor_(problem, F, elemDisc, ipGlobal);
99 const auto f = problem.source(elemDisc, elemVars, qpData.ipData());
100 const auto& shapeValues = ipCache.shapeValues();
101
102 for (const auto& nonCVdof : nonCVLocalDofs(elemDisc))
103 {
104 const auto idx = nonCVdof.index();
105 for (int i = 0; i < dim; ++i)
106 {
107 for (int j = 0; j < dim; ++j)
108 residual[idx][Indices::momentum(i)] += P[i][j] * ipCache.gradN(idx)[j] * qpData.weight();
109 residual[idx][Indices::momentum(i)] -= f[Indices::momentum(i)] * shapeValues[idx][0] * qpData.weight();
110 }
111 }
112 }
113 }
114 }
115
117 template<class SubControlVolumeFace>
118 NumEqVector fluxIntegral(const ElementDiscretization& elemDisc,
119 const ElementVariables& elemVars,
120 const SubControlVolumeFace& scvf) const
121 {
122 const auto& problem = this->asImp().problem();
123 const auto& n = scvf.unitOuterNormal();
124 NumEqVector f(0.0);
125
126 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scvf))
127 {
128 const auto& ipCache = cache(elemVars, qpData.ipData());
129 const auto F = deformationGradient_(elemDisc, elemVars, ipCache);
130 const auto P = firstPiolaKirchhoffStressTensor_(problem, F, elemDisc, qpData.ipData().global());
131
132 for (int i = 0; i < dim; ++i)
133 for (int j = 0; j < dim; ++j)
134 f[Indices::momentum(i)] -= P[i][j] * n[j] * qpData.weight();
135 }
136 return f;
137 }
138
140 Scalar volumetricStressPressure(const Problem& problem,
141 const ElementDiscretization& elemDisc,
142 const GlobalPosition& ipGlobal) const
143 { return problem.couplingManager().pressureAtPoint(elemDisc, ipGlobal); }
144
145private:
146 template<class IpCache>
147 Tensor deformationGradient_(const ElementDiscretization& elemDisc,
148 const ElementVariables& elemVars,
149 const IpCache& ipCache) const
150 {
151 Tensor F(0.0);
152 for (const auto& localDof : localDofs(elemDisc))
153 for (int d = 0; d < dim; ++d)
154 F[d].axpy(elemVars[localDof].displacement(d), ipCache.gradN(localDof.index()));
155 for (int d = 0; d < dim; ++d)
156 F[d][d] += 1.0;
157 return F;
158 }
159
160 Tensor firstPiolaKirchhoffStressTensor_(const Problem& problem,
161 const Tensor& F,
162 const ElementDiscretization& elemDisc,
163 const GlobalPosition& ipGlobal) const
164 {
165 auto P = problem.isochoricFirstPiolaKirchhoffStressTensor(F, elemDisc, ipGlobal);
166
167 Tensor Finv(F);
168 Finv.invert();
169 const Scalar pJ = this->asImp().volumetricStressPressure(problem, elemDisc, ipGlobal)*F.determinant();
170 for (int i = 0; i < dim; ++i)
171 for (int j = 0; j < dim; ++j)
172 P[i][j] += pJ*Finv[j][i];
173
174 return P;
175 }
176};
177
187template<class TypeTag>
189{
195 using ElementDiscretization = typename GridGeometry::LocalView;
196 using GridView = typename GridGeometry::GridView;
197 using Tensor = Dune::FieldMatrix<Scalar, GridView::dimension, GridView::dimension>;
198
200 using ElementVariables = typename GridVariables::GridVariablesCache::LocalView;
201
202public:
203 using ParentType::ParentType;
204 using ElementResidualVector = typename ParentType::ElementResidualVector;
205
206 NumEqVector computeStorage(const Problem&, const auto&, const auto&) const
207 { return NumEqVector(0.0); }
208
209 NumEqVector storageIntegral(const ElementDiscretization&, const ElementVariables&,
210 const auto&, bool) const
211 { return NumEqVector(0.0); }
212
213 NumEqVector fluxIntegral(const ElementDiscretization&, const ElementVariables&,
214 const auto&) const
215 { return NumEqVector(0.0); }
216
224 template<class SubControlVolume_>
225 NumEqVector sourceIntegral(const ElementDiscretization& elemDisc,
226 const ElementVariables& elemVars,
227 const SubControlVolume_& scv) const
228 {
229 NumEqVector source(0.0);
230
231 const auto& problem = this->asImp().problem();
232 const auto& localBasis = elemDisc.gridDiscretization().feCache().get(elemDisc.element().type()).localBasis();
233 std::vector< Dune::FieldVector<Scalar, 1> > shapeValues;
234
235 for (const auto& qpData : CVFE::quadratureRule(elemDisc, scv, QuadratureRules::DuneQuadrature<3>{}))
236 {
237 const Tensor F = problem.couplingManager().deformationGradientAtPoint(
238 elemDisc, qpData.ipData().global());
239 const Scalar J = F.determinant();
240 const Scalar psEq = problem.volumetricPressure(J);
241
242 localBasis.evaluateFunction(qpData.ipData().local(), shapeValues);
243 Scalar ps = 0.0;
244 for (const auto& localDof : localDofs(elemDisc))
245 ps += elemVars[localDof].pressure() * shapeValues[localDof.index()][0];
246
247 source[0] -= (psEq - ps) * qpData.weight();
248 }
249
250 return source;
251 }
252
257 const Problem& problem,
258 const auto& element,
259 const ElementDiscretization& elemDisc,
260 const ElementVariables& elemVars) const
261 {
262 if constexpr (Dumux::Detail::LocalDofs::hasNonCVLocalDofsInterface<ElementDiscretization>())
263 {
264 if (nonCVLocalDofs(elemDisc).empty())
265 return;
266
267 const auto& problem = this->asImp().problem();
268 const auto& localBasis = elemDisc.gridDiscretization().feCache().get(elemDisc.element().type()).localBasis();
269 std::vector< Dune::FieldVector<Scalar, 1> > shapeValues;
270
271 for (const auto& qpData : CVFE::quadratureRule(elemDisc, element, QuadratureRules::DuneQuadrature<3>{}))
272 {
273 const Tensor F = problem.couplingManager().deformationGradientAtPoint(
274 elemDisc, qpData.ipData().global());
275 const Scalar J = F.determinant();
276 const Scalar psEq = problem.volumetricPressure(J);
277
278 localBasis.evaluateFunction(qpData.ipData().local(), shapeValues);
279 Scalar ps = 0.0;
280 for (const auto& localDof : localDofs(elemDisc))
281 ps += elemVars[localDof].pressure() * shapeValues[localDof.index()][0];
282
283 for (const auto& nonCVdof : nonCVLocalDofs(elemDisc))
284 {
285 const auto idx = nonCVdof.index();
286 residual[idx][0] -= (psEq - ps) * shapeValues[idx][0] * qpData.weight();
287 }
288 }
289
290 }
291 }
292
293};
294
295} // end namespace Dumux
296#endif
Momentum local residual for the mixed u–p hyperelastic model.
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:53
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const auto &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
FE contributions of stress divergence and body force for non-CV dofs (e.g. PQ2 hybrid).
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:81
NumEqVector storageIntegral(const ElementDiscretization &, const ElementVariables &, const auto &, bool) const
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:76
NumEqVector fluxIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolumeFace &scvf) const
Interior flux integral: .
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:118
typename ParentType::ElementResidualVector ElementResidualVector
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:71
Scalar volumetricStressPressure(const Problem &problem, const ElementDiscretization &elemDisc, const GlobalPosition &ipGlobal) const
The scalar of the volumetric stress .
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:140
NumEqVector computeStorage(const auto &, const auto &, const auto &) const
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:73
Pressure local residual for the mixed u–p hyperelastic model.
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:189
NumEqVector computeStorage(const Problem &, const auto &, const auto &) const
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:206
void addToElementFluxAndSourceResidual(ElementResidualVector &residual, const Problem &problem, const auto &element, const ElementDiscretization &elemDisc, const ElementVariables &elemVars) const
FE contributions for non-CV DOFs.
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:256
NumEqVector sourceIntegral(const ElementDiscretization &elemDisc, const ElementVariables &elemVars, const SubControlVolume_ &scv) const
Pressure constraint integrated over an SCV.
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:225
NumEqVector fluxIntegral(const ElementDiscretization &, const ElementVariables &, const auto &) const
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:213
typename ParentType::ElementResidualVector ElementResidualVector
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:204
NumEqVector storageIntegral(const ElementDiscretization &, const ElementVariables &, const auto &, bool) const
Definition solidmechanics/hyperelastic_voliso/localresidual.hh:209
Defines all properties used in Dumux.
The default local operator than can be specialized for each discretization scheme.
free functions for the evaluation of primary variables inside elements.
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
Define some often used mathematical functions.
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.
Quadrature rules over sub-control volumes and sub-control volume faces.
Dune-based quadrature rule with specified order.
Definition quadraturerules.hh:66