version 0.4.1
kirchhoffloveshell.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2025 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
10
11#include <dune/geometry/quadraturerules.hh>
12#include <dune/localfefunctions/cachedlocalBasis/cachedlocalBasis.hh>
13#include <dune/localfefunctions/impl/standardLocalFunction.hh>
14
22
23namespace Ikarus {
24template <typename PreFE, typename FE>
25class KirchhoffLoveShell;
26
31{
33 double thickness;
34
35 template <typename PreFE, typename FE>
37};
38
49template <typename PreFE, typename FE>
51{
52public:
55 using FlatBasis = typename Traits::FlatBasis;
57 using LocalView = typename Traits::LocalView;
58 using Geometry = typename Traits::Geometry;
59 using GridView = typename Traits::GridView;
60 using Element = typename Traits::Element;
61 using LocalBasisType = decltype(std::declval<LocalView>().tree().child(0).finiteElement().localBasis());
63
64 static constexpr int myDim = Traits::mydim;
65 static constexpr int worldDim = Traits::worlddim;
66 static constexpr int membraneStrainSize = 3;
67 static constexpr int bendingStrainSize = 3;
68
78 template <typename ST = double>
80 {
81 Eigen::Matrix<double, 3, 3> C;
82 Eigen::Vector3<ST> epsV;
83 Eigen::Vector3<ST> kappaV;
84 Eigen::Matrix<ST, 2, 3> j;
85 Eigen::Matrix<double, 2, 3> J;
86 Eigen::Matrix3<ST> h;
87 Eigen::Matrix3<double> H;
88 Eigen::Vector3<ST> a3N;
89 Eigen::Vector3<ST> a3;
90 };
91
100 : mat_{pre.material},
101 thickness_{pre.thickness} {}
102
103protected:
107 void bindImpl() {
108 const auto& localView = underlying().localView();
109 assert(localView.bound());
110 const auto& element = localView.element();
111 auto& firstChild = localView.tree().child(0);
112
113 const auto& fe = firstChild.finiteElement();
114 // geo_.emplace(element.geometry());
115 numberOfNodes_ = fe.size();
116 order_ = 2 * (fe.localBasis().order());
117 localBasis_ = Dune::CachedLocalBasis(fe.localBasis());
118 if constexpr (requires { element.impl().getQuadratureRule(order_); })
119 if (element.impl().isTrimmed())
120 localBasis_.bind(element.impl().getQuadratureRule(order_), Dune::bindDerivatives(0, 1, 2));
121 else
122 localBasis_.bind(Dune::QuadratureRules<double, myDim>::rule(element.type(), order_),
123 Dune::bindDerivatives(0, 1, 2));
124 else
125 localBasis_.bind(Dune::QuadratureRules<double, myDim>::rule(element.type(), order_),
126 Dune::bindDerivatives(0, 1, 2));
127 }
128
129public:
140 template <typename ST = double>
142 const Requirement& par,
143 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
144 const auto& d = par.globalSolution();
145 auto disp = Ikarus::FEHelper::localSolutionBlockVector<Traits>(d, underlying().localView(), dx);
146 Dune::StandardLocalFunction uFunction(
147 localBasis_, disp, std::make_shared<const Geometry>(underlying().localView().element().geometry()));
148 return uFunction;
149 }
150
151 Geometry geometry() const { return underlying().localView().element().geometry(); }
152 [[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
153 [[nodiscard]] int order() const { return order_; }
154
164 template <template <typename, int, int> class RT>
165 requires(supportsResultType<RT>())
166 auto calculateAtImpl([[maybe_unused]] const Requirement& req,
167 [[maybe_unused]] const Dune::FieldVector<double, Traits::mydim>& local)
169 DUNE_THROW(Dune::NotImplemented, "No results are implemented");
170 }
171
172private:
173 //> CRTP
174 const auto& underlying() const { return static_cast<const FE&>(*this); }
175 auto& underlying() { return static_cast<FE&>(*this); }
176 // std::optional<Geometry> geo_;
177 Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>> localBasis_;
178 // DefaultMembraneStrain membraneStrain_;
179 YoungsModulusAndPoissonsRatio mat_;
180 double thickness_;
181
182 size_t numberOfNodes_{0};
183 int order_{};
184
185protected:
200 auto computeMaterialAndStrains(const Dune::FieldVector<double, 2>& gpPos, int gpIndex, const Geometry& geo,
201 const auto& uFunction) const {
202 using ST = typename std::remove_cvref_t<decltype(uFunction)>::ctype;
203
205 using namespace Dune;
206 using namespace Dune::DerivativeDirections;
207 const auto [X, Jd, Hd] = geo.impl().zeroFirstAndSecondDerivativeOfPosition(gpPos);
208 kin.J = toEigen(Jd);
209 kin.H = toEigen(Hd);
210 const Eigen::Matrix<double, 2, 2> A = kin.J * kin.J.transpose();
211 Eigen::Matrix<double, 3, 3> G = Eigen::Matrix<double, 3, 3>::Zero();
212
213 G.block<2, 2>(0, 0) = A;
214 G(2, 2) = 1;
215 const Eigen::Matrix<double, 3, 3> GInv = G.inverse();
216 kin.C = materialTangent(GInv);
217
218 kin.epsV = DefaultMembraneStrain::value(gpPos, geo, uFunction);
219
220 const auto& Ndd = localBasis_.evaluateSecondDerivatives(gpIndex);
221 const auto uasMatrix = Dune::viewAsEigenMatrixAsDynFixed(uFunction.coefficientsRef());
222 const auto hessianu = Ndd.transpose().template cast<ST>() * uasMatrix;
223 kin.h = kin.H + hessianu;
224 const Eigen::Matrix<ST, 3, 2> gradu = toEigen(uFunction.evaluateDerivative(
225 gpIndex, Dune::wrt(spatialAll), Dune::on(Dune::DerivativeDirections::referenceElement)));
226 kin.j = kin.J + gradu.transpose();
227 kin.a3N = (kin.j.row(0).cross(kin.j.row(1)));
228 kin.a3 = kin.a3N.normalized();
229 Eigen::Vector<ST, 3> bV = kin.h * kin.a3;
230 bV(2) *= 2; // Voigt notation requires the two here
231 const auto BV = toVoigt(toEigen(geo.impl().secondFundamentalForm(gpPos)));
232 kin.kappaV = BV - bV;
233 return kin;
234 }
235
236 template <typename ST>
238 const Requirement& par, const MatrixAffordance& affordance, typename Traits::template MatrixType<ST> K,
239 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
240 if (affordance != MatrixAffordance::stiffness)
241 DUNE_THROW(Dune::NotImplemented, "MatrixAffordance not implemented: " + toString(affordance));
242 using namespace Dune::DerivativeDirections;
243 using namespace Dune;
244 const auto uFunction = displacementFunction(par, dx);
245 const auto& lambda = par.parameter();
246 const auto geo = underlying().localView().element().geometry();
247
248 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
249 const auto intElement = geo.integrationElement(gp.position()) * gp.weight();
250 const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3] =
251 computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
252 const Eigen::Vector<ST, membraneStrainSize> membraneForces = thickness_ * C * epsV;
253 const Eigen::Vector<ST, bendingStrainSize> moments = Dune::power(thickness_, 3) / 12.0 * C * kappaV;
254
255 const auto& Nd = localBasis_.evaluateJacobian(gpIndex);
256 const auto& Ndd = localBasis_.evaluateSecondDerivatives(gpIndex);
257 for (size_t i = 0; i < numberOfNodes_; ++i) {
258 Eigen::Matrix<ST, membraneStrainSize, worldDim> bopIMembrane =
259 DefaultMembraneStrain::derivative(gp.position(), jE, Nd, geo, uFunction, localBasis_, i);
260
261 Eigen::Matrix<ST, bendingStrainSize, worldDim> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
262 for (size_t j = i; j < numberOfNodes_; ++j) {
263 auto KBlock = K.template block<worldDim, worldDim>(worldDim * i, worldDim * j);
264 Eigen::Matrix<ST, membraneStrainSize, worldDim> bopJMembrane =
265 DefaultMembraneStrain::derivative(gp.position(), jE, Nd, geo, uFunction, localBasis_, j);
266 Eigen::Matrix<ST, bendingStrainSize, worldDim> bopJBending = bopBending(jE, h, Nd, Ndd, j, a3N, a3);
267 KBlock += thickness_ * bopIMembrane.transpose() * C * bopJMembrane * intElement;
268 KBlock += Dune::power(thickness_, 3) / 12.0 * bopIBending.transpose() * C * bopJBending * intElement;
269
270 Eigen::Matrix<ST, worldDim, worldDim> kgMembraneIJ = DefaultMembraneStrain::secondDerivative(
271 gp.position(), Nd, geo, uFunction, localBasis_, membraneForces, i, j);
272 Eigen::Matrix<ST, worldDim, worldDim> kgBendingIJ = kgBending(jE, h, Nd, Ndd, a3N, a3, moments, i, j);
273 KBlock += kgMembraneIJ * intElement;
274 KBlock += kgBendingIJ * intElement;
275 }
276 }
277 }
278 K.template triangularView<Eigen::StrictlyLower>() = K.transpose();
279 }
280
281 template <typename ST>
283 const Requirement& par, const VectorAffordance& affordance, typename Traits::template VectorType<ST> force,
284 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
285 if (affordance != VectorAffordance::forces)
286 DUNE_THROW(Dune::NotImplemented, "VectorAffordance not implemented: " + toString(affordance));
287 using namespace Dune::DerivativeDirections;
288 using namespace Dune;
289 const auto uFunction = displacementFunction(par, dx);
290 const auto& lambda = par.parameter();
291 const auto geo = underlying().localView().element().geometry();
292
293 // Internal forces
294 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
295 const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3] =
296 computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
297 const Eigen::Vector<ST, 3> membraneForces = thickness_ * C * epsV;
298 const Eigen::Vector<ST, 3> moments = Dune::power(thickness_, 3) / 12.0 * C * kappaV;
299
300 const auto& Nd = localBasis_.evaluateJacobian(gpIndex);
301 const auto& Ndd = localBasis_.evaluateSecondDerivatives(gpIndex);
302 for (size_t i = 0; i < numberOfNodes_; ++i) {
303 Eigen::Matrix<ST, 3, 3> bopIMembrane =
304 DefaultMembraneStrain::derivative(gp.position(), jE, Nd, geo, uFunction, localBasis_, i);
305 Eigen::Matrix<ST, 3, 3> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
306 force.template segment<3>(3 * i) +=
307 bopIMembrane.transpose() * membraneForces * geo.integrationElement(gp.position()) * gp.weight();
308 force.template segment<3>(3 * i) +=
309 bopIBending.transpose() * moments * geo.integrationElement(gp.position()) * gp.weight();
310 }
311 }
312 }
313
314 template <typename ST>
316 const Requirement& par, const ScalarAffordance& affordance,
317 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const -> ST {
319 DUNE_THROW(Dune::NotImplemented, "ScalarAffordance not implemented: " + toString(affordance));
320 using namespace Dune::DerivativeDirections;
321 using namespace Dune;
322 const auto uFunction = displacementFunction(par, dx);
323 const auto& lambda = par.parameter();
324 ST energy = 0.0;
325
326 const auto geo = underlying().localView().element().geometry();
327
328 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
329 const auto [C, epsV, kappaV, j, J, h, H, a3N, a3] =
330 computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
331
332 const ST membraneEnergy = 0.5 * thickness_ * epsV.dot(C * epsV);
333 const ST bendingEnergy = 0.5 * Dune::power(thickness_, 3) / 12.0 * kappaV.dot(C * kappaV);
334 energy += (membraneEnergy + bendingEnergy) * geo.integrationElement(gp.position()) * gp.weight();
335 }
336
337 return energy;
338 }
339
340 template <typename ST>
341 Eigen::Matrix<ST, 3, 3> kgBending(const Eigen::Matrix<ST, 2, 3>& jcur, const Eigen::Matrix3<ST>& h, const auto& dN,
342 const auto& ddN, const Eigen::Vector3<ST>& a3N, const Eigen::Vector3<ST>& a3,
343 const Eigen::Vector3<ST>& S, int I, int J) const {
344 Eigen::Matrix<ST, 3, 3> kg;
345 kg.setZero();
346
347 const auto& dN1i = dN(I, 0);
348 const auto& dN1j = dN(J, 0);
349 const auto& dN2i = dN(I, 1);
350 const auto& dN2j = dN(J, 1);
351
352 const Eigen::Matrix<ST, 3, 3> P =
353 1.0 / a3N.norm() * (Eigen::Matrix<double, 3, 3>::Identity() - a3 * a3.transpose());
354
355 const auto a1dxI = Eigen::Matrix<double, 3, 3>::Identity() *
356 dN1i; // the auto here allows the exploitation of the identity matrices,
357 // due to Eigen's expression templates
358 const auto a2dxI = Eigen::Matrix<double, 3, 3>::Identity() * dN2i;
359 const auto a1dxJ = Eigen::Matrix<double, 3, 3>::Identity() * dN1j;
360 const auto a2dxJ = Eigen::Matrix<double, 3, 3>::Identity() * dN2j;
361 const auto a1 = jcur.row(0);
362 const auto a2 = jcur.row(1);
363 const Eigen::Matrix<ST, 3, 3> a3NdI = a1dxI.colwise().cross(a2) - a2dxI.colwise().cross(a1);
364 const Eigen::Matrix<ST, 3, 3> a3NdJ = a1dxJ.colwise().cross(a2) - a2dxJ.colwise().cross(a1);
365 Eigen::Matrix<ST, 3, 3> a3dI = P * a3NdI;
366 Eigen::Matrix<ST, 3, 3> a3dJ = P * a3NdJ;
367 for (int i = 0; i < 3; ++i) {
368 const auto a_albe = h.row(i).transpose();
369 const auto& ddNI = ddN(I, i);
370 const auto& ddNJ = ddN(J, i);
371 Eigen::Vector3<ST> vecd = P * a_albe;
372
373 Eigen::Matrix<ST, 3, 3> a3Ndd =
374 1.0 / a3N.squaredNorm() *
375 ((3 * a3 * a3.transpose() - Eigen::Matrix<double, 3, 3>::Identity()) * (a3.dot(a_albe)) -
376 a_albe * a3.transpose() - a3 * a_albe.transpose());
377
378 Eigen::Matrix<ST, 3, 3> secondDerivativeDirectorIJ = skew(((dN2i * dN1j - dN1i * dN2j) * vecd).eval());
379 kg -= (a3NdI.transpose() * a3Ndd * a3NdJ + secondDerivativeDirectorIJ + (ddNI * a3dJ + ddNJ * a3dI.transpose())) *
380 S[i] * (i == 2 ? 2 : 1);
381 }
382
383 return kg;
384 }
385
386 template <typename ST>
387 Eigen::Matrix<ST, 3, 3> bopBending(const Eigen::Matrix<ST, 2, 3>& jcur, const Eigen::Matrix3<ST>& h, const auto& dN,
388 const auto& ddN, const int node, const Eigen::Vector3<ST>& a3N,
389 const Eigen::Vector3<ST>& a3) const {
390 const Eigen::Matrix<ST, 3, 3> a1dxI =
391 Eigen::Matrix<double, 3, 3>::Identity() * dN(node, 0); // this should be double
392 // but the cross-product below complains otherwise
393 const Eigen::Matrix<ST, 3, 3> a2dxI = Eigen::Matrix<double, 3, 3>::Identity() * dN(node, 1);
394 const auto a1 = jcur.row(0);
395 const auto a2 = jcur.row(1);
396 const Eigen::Matrix<ST, 3, 3> a3NdI =
397 a1dxI.colwise().cross(a2) - a2dxI.colwise().cross(a1); // minus needed since order has
398 // to be swapped to get column-wise cross product working
399 const Eigen::Matrix<ST, 3, 3> a3d1 =
400 1.0 / a3N.norm() * (Eigen::Matrix<double, 3, 3>::Identity() - a3 * a3.transpose()) * a3NdI;
401
402 Eigen::Matrix<ST, 3, 3> bop = -(h * a3d1 + (a3 * ddN.row(node)).transpose());
403 bop.row(2) *= 2;
404
405 return bop;
406 }
407
414 Eigen::Matrix<double, 3, 3> materialTangent(const Eigen::Matrix<double, 3, 3>& Aconv) const {
415 const double lambda = mat_.emodul * mat_.nu / ((1.0 + mat_.nu) * (1.0 - 2.0 * mat_.nu));
416 const double mu = mat_.emodul / (2.0 * (1.0 + mat_.nu));
417 const double lambdbar = 2.0 * lambda * mu / (lambda + 2.0 * mu);
418 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 3, 3, 3>> moduli;
419 const auto AconvT = tensorView(Aconv, std::array<Eigen::Index, 2>({3, 3}));
420 moduli = lambdbar * dyadic(AconvT, AconvT).eval() + 2.0 * mu * symmetricFourthOrder<double>(Aconv, Aconv);
421
422 auto C = toVoigt(moduli);
423 Eigen::Matrix<double, 3, 3> C33 = C({0, 1, 5}, {0, 1, 5});
424 return C33;
425 }
426};
427
432struct KlArgs
433{
435 double nu;
436 double thickness;
437};
438
444auto kirchhoffLoveShell(const KlArgs& args) {
445 KirchhoffLoveShellPre pre({.emodul = args.youngs_modulus, .nu = args.nu}, args.thickness);
446
447 return pre;
448}
449} // namespace Ikarus
Helper for the autodiff library.
Definition of the LinearElastic class for finite element mechanics computations.
Definitions of ResultTypes used for finite element results.
Material property functions and conversion utilities.
Implementation of membrane strain for shells.
Header file for types of loads in Ikarus finite element mechanics.
Derived skew(const Eigen::MatrixBase< Derived > &A)
Returns the skew part of a matrix.
Definition: linearalgebrahelper.hh:410
auto viewAsEigenMatrixAsDynFixed(Dune::BlockVector< ValueType > &blockedVector)
View Dune::BlockVector as an Eigen::Matrix with dynamic rows and fixed columns depending on the size ...
Definition: linearalgebrahelper.hh:88
Eigen::Tensor< typename Derived::Scalar, rank > tensorView(const Eigen::EigenBase< Derived > &matrix, const std::array< T, rank > &dims)
View an Eigen matrix as an Eigen Tensor with specified dimensions.
Definition: tensorutils.hh:32
auto dyadic(const auto &A_ij, const auto &B_kl)
Computes the dyadic product of two Eigen tensors.
Definition: tensorutils.hh:47
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:182
Definition: assemblermanipulatorbuildingblocks.hh:22
MatrixAffordance
A strongly typed enum class representing the matrix affordance.
Definition: ferequirements.hh:64
VectorAffordance
A strongly typed enum class representing the vector affordance.
Definition: ferequirements.hh:49
auto transpose(const Eigen::EigenBase< Derived > &A)
auto kirchhoffLoveShell(const KlArgs &args)
A helper function to create a Kirchhoff-Love shell pre finite element.
Definition: kirchhoffloveshell.hh:444
constexpr std::string toString(DBCOption _e)
Definition: dirichletbcenforcement.hh:8
ScalarAffordance
A strongly typed enum class representing the scalar affordance.
Definition: ferequirements.hh:38
Definition: utils/dirichletvalues.hh:30
FE class is a base class for all finite elements.
Definition: febase.hh:79
FETraits< BH, useEigenRef, useFlat > Traits
Definition: febase.hh:38
Class representing the requirements for finite element calculations.
Definition: ferequirements.hh:223
const SolutionVectorType & globalSolution() const
Get the global solution vector.
Definition: ferequirements.hh:313
const PM & parameter() const
Get the parameter value.
Definition: ferequirements.hh:336
Container that is used for FE Results. It gives access to the stored value, but can also be used to a...
Definition: feresulttypes.hh:164
Base class for element definitions that provides common functionality for ResultTypes.
Definition: feresulttypes.hh:277
Traits for handling finite elements.
Definition: fetraits.hh:25
typename Basis::LocalView LocalView
Type of the local view.
Definition: fetraits.hh:42
typename Element::Geometry Geometry
Type of the element geometry.
Definition: fetraits.hh:51
BH BasisHandler
Type of the basis of the finite element.
Definition: fetraits.hh:27
typename Basis::GridView GridView
Type of the grid view.
Definition: fetraits.hh:45
static constexpr int worlddim
Dimension of the world space.
Definition: fetraits.hh:60
typename BasisHandler::FlatBasis FlatBasis
Type of the flat basis.
Definition: fetraits.hh:33
typename LocalView::Element Element
Type of the grid element.
Definition: fetraits.hh:48
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:63
Kirchhoff-Love shell finite element class.
Definition: kirchhoffloveshell.hh:51
Eigen::Matrix< double, 3, 3 > materialTangent(const Eigen::Matrix< double, 3, 3 > &Aconv) const
Gets the material tangent matrix for the linear elastic material.
Definition: kirchhoffloveshell.hh:414
typename Traits::Element Element
Definition: kirchhoffloveshell.hh:60
typename Traits::Geometry Geometry
Definition: kirchhoffloveshell.hh:58
void calculateVectorImpl(const Requirement &par, const VectorAffordance &affordance, typename Traits::template VectorType< ST > force, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Definition: kirchhoffloveshell.hh:282
auto displacementFunction(const Requirement &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Get the displacement function and nodal displacements.
Definition: kirchhoffloveshell.hh:141
auto computeMaterialAndStrains(const Dune::FieldVector< double, 2 > &gpPos, int gpIndex, const Geometry &geo, const auto &uFunction) const
Compute material properties and strains at a given integration point.
Definition: kirchhoffloveshell.hh:200
size_t numberOfNodes() const
Definition: kirchhoffloveshell.hh:152
static constexpr int myDim
Definition: kirchhoffloveshell.hh:64
static constexpr int bendingStrainSize
Definition: kirchhoffloveshell.hh:67
auto calculateAtImpl(const Requirement &req, const Dune::FieldVector< double, Traits::mydim > &local) -> ResultWrapper< RT< double, myDim, worldDim >, ResultShape::Vector >
Calculates a requested result at a specific local position.
Definition: kirchhoffloveshell.hh:166
Geometry geometry() const
Definition: kirchhoffloveshell.hh:151
decltype(std::declval< LocalView >().tree().child(0).finiteElement().localBasis()) LocalBasisType
Definition: kirchhoffloveshell.hh:61
typename Traits::GridView GridView
Definition: kirchhoffloveshell.hh:59
static constexpr int worldDim
Definition: kirchhoffloveshell.hh:65
void bindImpl()
A helper function to bind the local view to the element.
Definition: kirchhoffloveshell.hh:107
typename Traits::FlatBasis FlatBasis
Definition: kirchhoffloveshell.hh:55
KirchhoffLoveShell(const Pre &pre)
Constructor for the KirchhoffLoveShell class.
Definition: kirchhoffloveshell.hh:99
void calculateMatrixImpl(const Requirement &par, const MatrixAffordance &affordance, typename Traits::template MatrixType< ST > K, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Definition: kirchhoffloveshell.hh:237
typename Traits::LocalView LocalView
Definition: kirchhoffloveshell.hh:57
typename Traits::BasisHandler BasisHandler
Definition: kirchhoffloveshell.hh:54
Eigen::Matrix< ST, 3, 3 > kgBending(const Eigen::Matrix< ST, 2, 3 > &jcur, const Eigen::Matrix3< ST > &h, const auto &dN, const auto &ddN, const Eigen::Vector3< ST > &a3N, const Eigen::Vector3< ST > &a3, const Eigen::Vector3< ST > &S, int I, int J) const
Definition: kirchhoffloveshell.hh:341
Eigen::Matrix< ST, 3, 3 > bopBending(const Eigen::Matrix< ST, 2, 3 > &jcur, const Eigen::Matrix3< ST > &h, const auto &dN, const auto &ddN, const int node, const Eigen::Vector3< ST > &a3N, const Eigen::Vector3< ST > &a3) const
Definition: kirchhoffloveshell.hh:387
static constexpr int membraneStrainSize
Definition: kirchhoffloveshell.hh:66
auto calculateScalarImpl(const Requirement &par, const ScalarAffordance &affordance, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const -> ST
Definition: kirchhoffloveshell.hh:315
int order() const
Definition: kirchhoffloveshell.hh:153
A PreFE struct for Kirchhoff-Love shell elements.
Definition: kirchhoffloveshell.hh:31
double thickness
Definition: kirchhoffloveshell.hh:33
YoungsModulusAndPoissonsRatio material
Definition: kirchhoffloveshell.hh:32
A structure representing kinematic variables.
Definition: kirchhoffloveshell.hh:80
Eigen::Matrix3< double > H
Hessian of the reference geometry.
Definition: kirchhoffloveshell.hh:87
Eigen::Vector3< ST > kappaV
bending strain in Voigt notation
Definition: kirchhoffloveshell.hh:83
Eigen::Matrix< double, 3, 3 > C
material tangent
Definition: kirchhoffloveshell.hh:81
Eigen::Matrix< ST, 2, 3 > j
Jacobian of the deformed geometry.
Definition: kirchhoffloveshell.hh:84
Eigen::Vector3< ST > epsV
membrane strain in Voigt notation
Definition: kirchhoffloveshell.hh:82
Eigen::Matrix3< ST > h
Hessian of the deformed geometry.
Definition: kirchhoffloveshell.hh:86
Eigen::Vector3< ST > a3N
Normal vector of the deformed geometry.
Definition: kirchhoffloveshell.hh:88
Eigen::Vector3< ST > a3
normalized normal vector of the deformed geometry
Definition: kirchhoffloveshell.hh:89
Eigen::Matrix< double, 2, 3 > J
Jacobian of the reference geometry.
Definition: kirchhoffloveshell.hh:85
A struct containing information about the Youngs Modulus, Poisson's ratio and the thickness for the K...
Definition: kirchhoffloveshell.hh:433
double youngs_modulus
Definition: kirchhoffloveshell.hh:434
double nu
Definition: kirchhoffloveshell.hh:435
double thickness
Definition: kirchhoffloveshell.hh:436
static auto derivative(const Dune::FieldVector< double, 2 > &gpPos, const Eigen::Matrix< ST, 2, 3 > &jcur, const auto &dNAtGp, const GEO &geo, const auto &uFunction, const auto &localBasis, const int node)
Compute the strain-displacement matrix for a given node and integration point.
Definition: membranestrains.hh:64
static auto secondDerivative(const Dune::FieldVector< double, 2 > &gpPos, const auto &dNAtGp, const GEO &geo, const auto &uFunction, const auto &localBasis, const Eigen::Vector3< ST > &S, int I, int J)
Compute the second derivative of the membrane strain for a given node pair and integration point.
Definition: membranestrains.hh:95
static auto value(const Dune::FieldVector< double, 2 > &gpPos, const GEO &geo, const auto &uFunction) -> Eigen::Vector3< typename std::remove_cvref_t< decltype(uFunction)>::ctype >
Compute the strain vector at a given integration point.
Definition: membranestrains.hh:30
see https://en.wikipedia.org/wiki/Lam%C3%A9_parameters Structure representing Young's modulus and she...
Definition: physicshelper.hh:19
Definition: utils/dirichletvalues.hh:32