version 0.4.1
kirchhoffloveshell.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 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
21
22namespace Ikarus {
23template <typename PreFE, typename FE>
24class KirchhoffLoveShell;
25
30{
32 double thickness;
33
34 template <typename PreFE, typename FE>
36};
37
48template <typename PreFE, typename FE>
50{
51public:
54 using FlatBasis = typename Traits::FlatBasis;
56 using LocalView = typename Traits::LocalView;
57 using Geometry = typename Traits::Geometry;
58 using GridView = typename Traits::GridView;
59 using Element = typename Traits::Element;
60 using LocalBasisType = decltype(std::declval<LocalView>().tree().child(0).finiteElement().localBasis());
62
63 static constexpr int myDim = Traits::mydim;
64 static constexpr int worldDim = Traits::worlddim;
65 static constexpr int membraneStrainSize = 3;
66 static constexpr int bendingStrainSize = 3;
67
77 template <typename ST = double>
79 {
80 Eigen::Matrix<double, 3, 3> C;
81 Eigen::Vector3<ST> epsV;
82 Eigen::Vector3<ST> kappaV;
83 Eigen::Matrix<ST, 2, 3> j;
84 Eigen::Matrix<double, 2, 3> J;
85 Eigen::Matrix3<ST> h;
86 Eigen::Matrix3<double> H;
87 Eigen::Vector3<ST> a3N;
88 Eigen::Vector3<ST> a3;
89 };
90
99 : mat_{pre.material},
100 thickness_{pre.thickness} {}
101
102protected:
106 void bindImpl() {
107 const auto& localView = underlying().localView();
108 assert(localView.bound());
109 const auto& element = localView.element();
110 auto& firstChild = localView.tree().child(0);
111
112 const auto& fe = firstChild.finiteElement();
113 // geo_.emplace(element.geometry());
114 numberOfNodes_ = fe.size();
115 order_ = 2 * (fe.localBasis().order());
116 localBasis_ = Dune::CachedLocalBasis(fe.localBasis());
117 if constexpr (requires { element.impl().getQuadratureRule(order_); })
118 if (element.impl().isTrimmed())
119 localBasis_.bind(element.impl().getQuadratureRule(order_), Dune::bindDerivatives(0, 1, 2));
120 else
121 localBasis_.bind(Dune::QuadratureRules<double, myDim>::rule(element.type(), order_),
122 Dune::bindDerivatives(0, 1, 2));
123 else
124 localBasis_.bind(Dune::QuadratureRules<double, myDim>::rule(element.type(), order_),
125 Dune::bindDerivatives(0, 1, 2));
126 }
127
128public:
139 template <typename ST = double>
141 const FERequirementType& par,
142 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
143 const auto& d = par.getGlobalSolution(Ikarus::FESolutions::displacement);
144 auto disp = Ikarus::FEHelper::localSolutionBlockVector<Traits>(d, underlying().localView(), dx);
145 Dune::StandardLocalFunction uFunction(
146 localBasis_, disp, std::make_shared<const Geometry>(underlying().localView().element().geometry()));
147 return uFunction;
148 }
149
150 Geometry geometry() const { return underlying().localView().element().geometry(); }
151 [[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
152 [[nodiscard]] int order() const { return order_; }
153
159 template <template <typename, int, int> class RT>
160 static consteval bool canProvideResultType() {
161 return false;
162 }
163
164 using SupportedResultTypes = std::tuple<>;
165
175 template <template <typename, int, int> class RT>
176 requires(canProvideResultType<RT>())
177 auto calculateAtImpl([[maybe_unused]] const FERequirementType& req,
178 [[maybe_unused]] const Dune::FieldVector<double, Traits::mydim>& local)
180 DUNE_THROW(Dune::NotImplemented, "No results are implemented");
181 }
182
183private:
184 //> CRTP
185 const auto& underlying() const { return static_cast<const FE&>(*this); }
186 auto& underlying() { return static_cast<FE&>(*this); }
187 // std::optional<Geometry> geo_;
188 Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>> localBasis_;
189 // DefaultMembraneStrain membraneStrain_;
190 YoungsModulusAndPoissonsRatio mat_;
191 double thickness_;
192
193 size_t numberOfNodes_{0};
194 int order_{};
195
196protected:
211 auto computeMaterialAndStrains(const Dune::FieldVector<double, 2>& gpPos, int gpIndex, const Geometry& geo,
212 const auto& uFunction) const {
213 using ST = typename std::remove_cvref_t<decltype(uFunction)>::ctype;
214
216 using namespace Dune;
217 using namespace Dune::DerivativeDirections;
218 const auto [X, Jd, Hd] = geo.impl().zeroFirstAndSecondDerivativeOfPosition(gpPos);
219 kin.J = toEigen(Jd);
220 kin.H = toEigen(Hd);
221 const Eigen::Matrix<double, 2, 2> A = kin.J * kin.J.transpose();
222 Eigen::Matrix<double, 3, 3> G = Eigen::Matrix<double, 3, 3>::Zero();
223
224 G.block<2, 2>(0, 0) = A;
225 G(2, 2) = 1;
226 const Eigen::Matrix<double, 3, 3> GInv = G.inverse();
227 kin.C = materialTangent(GInv);
228
229 kin.epsV = DefaultMembraneStrain::value(gpPos, geo, uFunction);
230
231 const auto& Ndd = localBasis_.evaluateSecondDerivatives(gpIndex);
232 const auto uasMatrix = Dune::viewAsEigenMatrixAsDynFixed(uFunction.coefficientsRef());
233 const auto hessianu = Ndd.transpose().template cast<ST>() * uasMatrix;
234 kin.h = kin.H + hessianu;
235 const Eigen::Matrix<ST, 3, 2> gradu = toEigen(uFunction.evaluateDerivative(
236 gpIndex, Dune::wrt(spatialAll), Dune::on(Dune::DerivativeDirections::referenceElement)));
237 kin.j = kin.J + gradu.transpose();
238 kin.a3N = (kin.j.row(0).cross(kin.j.row(1)));
239 kin.a3 = kin.a3N.normalized();
240 Eigen::Vector<ST, 3> bV = kin.h * kin.a3;
241 bV(2) *= 2; // Voigt notation requires the two here
242 const auto BV = toVoigt(toEigen(geo.impl().secondFundamentalForm(gpPos)));
243 kin.kappaV = BV - bV;
244 return kin;
245 }
246
247 template <typename ST>
249 const FERequirementType& par, typename Traits::template MatrixType<ST> K,
250 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
251 using namespace Dune::DerivativeDirections;
252 using namespace Dune;
253 const auto uFunction = displacementFunction(par, dx);
254 const auto& lambda = par.getParameter(FEParameter::loadfactor);
255 const auto geo = underlying().localView().element().geometry();
256
257 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
258 const auto intElement = geo.integrationElement(gp.position()) * gp.weight();
259 const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3] =
260 computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
261 const Eigen::Vector<ST, membraneStrainSize> membraneForces = thickness_ * C * epsV;
262 const Eigen::Vector<ST, bendingStrainSize> moments = Dune::power(thickness_, 3) / 12.0 * C * kappaV;
263
264 const auto& Nd = localBasis_.evaluateJacobian(gpIndex);
265 const auto& Ndd = localBasis_.evaluateSecondDerivatives(gpIndex);
266 for (size_t i = 0; i < numberOfNodes_; ++i) {
267 Eigen::Matrix<ST, membraneStrainSize, worldDim> bopIMembrane =
268 DefaultMembraneStrain::derivative(gp.position(), jE, Nd, geo, uFunction, localBasis_, i);
269
270 Eigen::Matrix<ST, bendingStrainSize, worldDim> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
271 for (size_t j = i; j < numberOfNodes_; ++j) {
272 auto KBlock = K.template block<worldDim, worldDim>(worldDim * i, worldDim * j);
273 Eigen::Matrix<ST, membraneStrainSize, worldDim> bopJMembrane =
274 DefaultMembraneStrain::derivative(gp.position(), jE, Nd, geo, uFunction, localBasis_, j);
275 Eigen::Matrix<ST, bendingStrainSize, worldDim> bopJBending = bopBending(jE, h, Nd, Ndd, j, a3N, a3);
276 KBlock += thickness_ * bopIMembrane.transpose() * C * bopJMembrane * intElement;
277 KBlock += Dune::power(thickness_, 3) / 12.0 * bopIBending.transpose() * C * bopJBending * intElement;
278
279 Eigen::Matrix<ST, worldDim, worldDim> kgMembraneIJ = DefaultMembraneStrain::secondDerivative(
280 gp.position(), Nd, geo, uFunction, localBasis_, membraneForces, i, j);
281 Eigen::Matrix<ST, worldDim, worldDim> kgBendingIJ = kgBending(jE, h, Nd, Ndd, a3N, a3, moments, i, j);
282 KBlock += kgMembraneIJ * intElement;
283 KBlock += kgBendingIJ * intElement;
284 }
285 }
286 }
287 K.template triangularView<Eigen::StrictlyLower>() = K.transpose();
288 }
289
290 template <typename ST>
292 const FERequirementType& par, typename Traits::template VectorType<ST> force,
293 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
294 using namespace Dune::DerivativeDirections;
295 using namespace Dune;
296 const auto uFunction = displacementFunction(par, dx);
297 const auto& lambda = par.getParameter(FEParameter::loadfactor);
298 const auto geo = underlying().localView().element().geometry();
299
300 // Internal forces
301 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
302 const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3] =
303 computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
304 const Eigen::Vector<ST, 3> membraneForces = thickness_ * C * epsV;
305 const Eigen::Vector<ST, 3> moments = Dune::power(thickness_, 3) / 12.0 * C * kappaV;
306
307 const auto& Nd = localBasis_.evaluateJacobian(gpIndex);
308 const auto& Ndd = localBasis_.evaluateSecondDerivatives(gpIndex);
309 for (size_t i = 0; i < numberOfNodes_; ++i) {
310 Eigen::Matrix<ST, 3, 3> bopIMembrane =
311 DefaultMembraneStrain::derivative(gp.position(), jE, Nd, geo, uFunction, localBasis_, i);
312 Eigen::Matrix<ST, 3, 3> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
313 force.template segment<3>(3 * i) +=
314 bopIMembrane.transpose() * membraneForces * geo.integrationElement(gp.position()) * gp.weight();
315 force.template segment<3>(3 * i) +=
316 bopIBending.transpose() * moments * geo.integrationElement(gp.position()) * gp.weight();
317 }
318 }
319 }
320
321 template <typename ST>
323 const FERequirementType& par,
324 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const -> ST {
325 using namespace Dune::DerivativeDirections;
326 using namespace Dune;
327 const auto uFunction = displacementFunction(par, dx);
328 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
329 ST energy = 0.0;
330
331 const auto geo = underlying().localView().element().geometry();
332
333 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
334 const auto [C, epsV, kappaV, j, J, h, H, a3N, a3] =
335 computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
336
337 const ST membraneEnergy = 0.5 * thickness_ * epsV.dot(C * epsV);
338 const ST bendingEnergy = 0.5 * Dune::power(thickness_, 3) / 12.0 * kappaV.dot(C * kappaV);
339 energy += (membraneEnergy + bendingEnergy) * geo.integrationElement(gp.position()) * gp.weight();
340 }
341
342 return energy;
343 }
344
345 template <typename ST>
346 Eigen::Matrix<ST, 3, 3> kgBending(const Eigen::Matrix<ST, 2, 3>& jcur, const Eigen::Matrix3<ST>& h, const auto& dN,
347 const auto& ddN, const Eigen::Vector3<ST>& a3N, const Eigen::Vector3<ST>& a3,
348 const Eigen::Vector3<ST>& S, int I, int J) const {
349 Eigen::Matrix<ST, 3, 3> kg;
350 kg.setZero();
351
352 const auto& dN1i = dN(I, 0);
353 const auto& dN1j = dN(J, 0);
354 const auto& dN2i = dN(I, 1);
355 const auto& dN2j = dN(J, 1);
356
357 const Eigen::Matrix<ST, 3, 3> P =
358 1.0 / a3N.norm() * (Eigen::Matrix<double, 3, 3>::Identity() - a3 * a3.transpose());
359
360 const auto a1dxI = Eigen::Matrix<double, 3, 3>::Identity() *
361 dN1i; // the auto here allows the exploitation of the identity matrices,
362 // due to Eigen's expression templates
363 const auto a2dxI = Eigen::Matrix<double, 3, 3>::Identity() * dN2i;
364 const auto a1dxJ = Eigen::Matrix<double, 3, 3>::Identity() * dN1j;
365 const auto a2dxJ = Eigen::Matrix<double, 3, 3>::Identity() * dN2j;
366 const auto a1 = jcur.row(0);
367 const auto a2 = jcur.row(1);
368 const Eigen::Matrix<ST, 3, 3> a3NdI = a1dxI.colwise().cross(a2) - a2dxI.colwise().cross(a1);
369 const Eigen::Matrix<ST, 3, 3> a3NdJ = a1dxJ.colwise().cross(a2) - a2dxJ.colwise().cross(a1);
370 Eigen::Matrix<ST, 3, 3> a3dI = P * a3NdI;
371 Eigen::Matrix<ST, 3, 3> a3dJ = P * a3NdJ;
372 for (int i = 0; i < 3; ++i) {
373 const auto a_albe = h.row(i).transpose();
374 const auto& ddNI = ddN(I, i);
375 const auto& ddNJ = ddN(J, i);
376 Eigen::Vector3<ST> vecd = P * a_albe;
377
378 Eigen::Matrix<ST, 3, 3> a3Ndd =
379 1.0 / a3N.squaredNorm() *
380 ((3 * a3 * a3.transpose() - Eigen::Matrix<double, 3, 3>::Identity()) * (a3.dot(a_albe)) -
381 a_albe * a3.transpose() - a3 * a_albe.transpose());
382
383 Eigen::Matrix<ST, 3, 3> secondDerivativeDirectorIJ = skew(((dN2i * dN1j - dN1i * dN2j) * vecd).eval());
384 kg -= (a3NdI.transpose() * a3Ndd * a3NdJ + secondDerivativeDirectorIJ + (ddNI * a3dJ + ddNJ * a3dI.transpose())) *
385 S[i] * (i == 2 ? 2 : 1);
386 }
387
388 return kg;
389 }
390
391 template <typename ST>
392 Eigen::Matrix<ST, 3, 3> bopBending(const Eigen::Matrix<ST, 2, 3>& jcur, const Eigen::Matrix3<ST>& h, const auto& dN,
393 const auto& ddN, const int node, const Eigen::Vector3<ST>& a3N,
394 const Eigen::Vector3<ST>& a3) const {
395 const Eigen::Matrix<ST, 3, 3> a1dxI =
396 Eigen::Matrix<double, 3, 3>::Identity() * dN(node, 0); // this should be double
397 // but the cross-product below complains otherwise
398 const Eigen::Matrix<ST, 3, 3> a2dxI = Eigen::Matrix<double, 3, 3>::Identity() * dN(node, 1);
399 const auto a1 = jcur.row(0);
400 const auto a2 = jcur.row(1);
401 const Eigen::Matrix<ST, 3, 3> a3NdI =
402 a1dxI.colwise().cross(a2) - a2dxI.colwise().cross(a1); // minus needed since order has
403 // to be swapped to get column-wise cross product working
404 const Eigen::Matrix<ST, 3, 3> a3d1 =
405 1.0 / a3N.norm() * (Eigen::Matrix<double, 3, 3>::Identity() - a3 * a3.transpose()) * a3NdI;
406
407 Eigen::Matrix<ST, 3, 3> bop = -(h * a3d1 + (a3 * ddN.row(node)).transpose());
408 bop.row(2) *= 2;
409
410 return bop;
411 }
412
419 Eigen::Matrix<double, 3, 3> materialTangent(const Eigen::Matrix<double, 3, 3>& Aconv) const {
420 const double lambda = mat_.emodul * mat_.nu / ((1.0 + mat_.nu) * (1.0 - 2.0 * mat_.nu));
421 const double mu = mat_.emodul / (2.0 * (1.0 + mat_.nu));
422 const double lambdbar = 2.0 * lambda * mu / (lambda + 2.0 * mu);
423 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 3, 3, 3>> moduli;
424 const auto AconvT = tensorView(Aconv, std::array<Eigen::Index, 2>({3, 3}));
425 moduli = lambdbar * dyadic(AconvT, AconvT).eval() + 2.0 * mu * symmetricFourthOrder<double>(Aconv, Aconv);
426
427 auto C = toVoigt(moduli);
428 Eigen::Matrix<double, 3, 3> C33 = C({0, 1, 5}, {0, 1, 5});
429 return C33;
430 }
431};
432
437struct KlArgs
438{
440 double nu;
441 double thickness;
442};
443
449auto kirchhoffLoveShell(const KlArgs& args) {
450 KirchhoffLoveShellPre pre({.emodul = args.youngs_modulus, .nu = args.nu}, args.thickness);
451
452 return pre;
453}
454} // namespace Ikarus
Helper for the autodiff library.
Material property functions and conversion utilities.
Definition of the LinearElastic class for finite element mechanics computations.
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
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:166
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
Definition: simpleassemblers.hh:22
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:449
Definition: utils/dirichletvalues.hh:28
FE class is a base class for all finite elements.
Definition: febase.hh:81
FETraits< BH, FER, useEigenRef, useFlat > Traits
Definition: febase.hh:40
Container that is used for FE Results. It gives access to the stored value, but can also be used to a...
Definition: feresulttypes.hh:155
Traits for handling finite elements.
Definition: fetraits.hh:26
FER FERequirementType
Type of the requirements for the finite element.
Definition: fetraits.hh:31
typename Basis::LocalView LocalView
Type of the local view.
Definition: fetraits.hh:46
BH BasisHandler
Type of the basis of the finite element.
Definition: fetraits.hh:28
typename Basis::GridView GridView
Type of the grid view.
Definition: fetraits.hh:49
typename BasisHandler::FlatBasis FlatBasis
Type of the flat basis.
Definition: fetraits.hh:37
static constexpr int worlddim
Dimension of the world space.
Definition: fetraits.hh:64
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:67
typename LocalView::Element Element
Type of the grid element.
Definition: fetraits.hh:52
typename Element::Geometry Geometry
Type of the element geometry.
Definition: fetraits.hh:55
Kirchhoff-Love shell finite element class.
Definition: kirchhoffloveshell.hh:50
void calculateMatrixImpl(const FERequirementType &par, typename Traits::template MatrixType< ST > K, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Definition: kirchhoffloveshell.hh:248
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:419
typename Traits::Element Element
Definition: kirchhoffloveshell.hh:59
typename Traits::Geometry Geometry
Definition: kirchhoffloveshell.hh:57
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:211
size_t numberOfNodes() const
Definition: kirchhoffloveshell.hh:151
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ST > force, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Definition: kirchhoffloveshell.hh:291
static constexpr int myDim
Definition: kirchhoffloveshell.hh:63
typename Traits::FERequirementType FERequirementType
Definition: kirchhoffloveshell.hh:55
static constexpr int bendingStrainSize
Definition: kirchhoffloveshell.hh:66
static consteval bool canProvideResultType()
Returns whether an element can provide a requested result. Can be used in constant expressions.
Definition: kirchhoffloveshell.hh:160
Geometry geometry() const
Definition: kirchhoffloveshell.hh:150
decltype(std::declval< LocalView >().tree().child(0).finiteElement().localBasis()) LocalBasisType
Definition: kirchhoffloveshell.hh:60
typename Traits::GridView GridView
Definition: kirchhoffloveshell.hh:58
static constexpr int worldDim
Definition: kirchhoffloveshell.hh:64
void bindImpl()
A helper function to bind the local view to the element.
Definition: kirchhoffloveshell.hh:106
typename Traits::FlatBasis FlatBasis
Definition: kirchhoffloveshell.hh:54
KirchhoffLoveShell(const Pre &pre)
Constructor for the KirchhoffLoveShell class.
Definition: kirchhoffloveshell.hh:98
typename Traits::LocalView LocalView
Definition: kirchhoffloveshell.hh:56
typename Traits::BasisHandler BasisHandler
Definition: kirchhoffloveshell.hh:53
auto calculateAtImpl(const FERequirementType &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:177
auto calculateScalarImpl(const FERequirementType &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const -> ST
Definition: kirchhoffloveshell.hh:322
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:346
auto displacementFunction(const FERequirementType &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:140
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:392
static constexpr int membraneStrainSize
Definition: kirchhoffloveshell.hh:65
std::tuple<> SupportedResultTypes
Definition: kirchhoffloveshell.hh:164
int order() const
Definition: kirchhoffloveshell.hh:152
A PreFE struct for Kirchhoff-Love shell elements.
Definition: kirchhoffloveshell.hh:30
double thickness
Definition: kirchhoffloveshell.hh:32
YoungsModulusAndPoissonsRatio material
Definition: kirchhoffloveshell.hh:31
A structure representing kinematic variables.
Definition: kirchhoffloveshell.hh:79
Eigen::Matrix3< double > H
Hessian of the reference geometry.
Definition: kirchhoffloveshell.hh:86
Eigen::Vector3< ST > kappaV
bending strain in Voigt notation
Definition: kirchhoffloveshell.hh:82
Eigen::Matrix< double, 3, 3 > C
material tangent
Definition: kirchhoffloveshell.hh:80
Eigen::Matrix< ST, 2, 3 > j
Jacobian of the deformed geometry.
Definition: kirchhoffloveshell.hh:83
Eigen::Vector3< ST > epsV
membrane strain in Voigt notation
Definition: kirchhoffloveshell.hh:81
Eigen::Matrix3< ST > h
Hessian of the deformed geometry.
Definition: kirchhoffloveshell.hh:85
Eigen::Vector3< ST > a3N
Normal vector of the deformed geometry.
Definition: kirchhoffloveshell.hh:87
Eigen::Vector3< ST > a3
normalized normal vector of the deformed geometry
Definition: kirchhoffloveshell.hh:88
Eigen::Matrix< double, 2, 3 > J
Jacobian of the reference geometry.
Definition: kirchhoffloveshell.hh:84
A struct containing information about the Youngs Modulus, Poisson's ratio and the thickness for the K...
Definition: kirchhoffloveshell.hh:438
double youngs_modulus
Definition: kirchhoffloveshell.hh:439
double nu
Definition: kirchhoffloveshell.hh:440
double thickness
Definition: kirchhoffloveshell.hh:441
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:65
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:96
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:31
Structure representing Young's modulus and shear modulus.
Definition: physicshelper.hh:53
Definition: utils/dirichletvalues.hh:30