version 0.3.7
finiteelements/mechanics/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/fufem/boundarypatch.hh>
12#include <dune/geometry/quadraturerules.hh>
13#include <dune/localfefunctions/cachedlocalBasis/cachedlocalBasis.hh>
14#include <dune/localfefunctions/impl/standardLocalFunction.hh>
15#include <dune/localfefunctions/manifolds/realTuple.hh>
16
23
24namespace Ikarus {
25
37 template <typename Basis_, typename FERequirements_ = FERequirements<>, bool useEigenRef = false>
38 class KirchhoffLoveShell : public PowerBasisFE<typename Basis_::FlatBasis> {
39 public:
40 using Basis = Basis_;
41 using FlatBasis = typename Basis::FlatBasis;
42 using BasePowerFE = PowerBasisFE<FlatBasis>; // Handles globalIndices function
43 using FERequirementType = FERequirements_;
45 using LocalView = typename FlatBasis::LocalView;
46 using Element = typename LocalView::Element;
47 using Geometry = typename Element::Geometry;
48 using GridView = typename FlatBasis::GridView;
50 static constexpr int myDim = Traits::mydim;
51 static constexpr int worldDim = Traits::worlddim;
52 using LocalBasisType = decltype(std::declval<LocalView>().tree().child(0).finiteElement().localBasis());
53
54 static constexpr int membraneStrainSize = 3;
55 static constexpr int bendingStrainSize = 3;
56
66 template <typename ScalarType = double>
68 Eigen::Matrix<double, 3, 3> C;
69 Eigen::Vector3<ScalarType> epsV;
70 Eigen::Vector3<ScalarType> kappaV;
71 Eigen::Matrix<ScalarType, 2, 3> j;
72 Eigen::Matrix<double, 2, 3> J;
73 Eigen::Matrix3<ScalarType> h;
74 Eigen::Matrix3<double> H;
75 Eigen::Vector3<ScalarType> a3N;
76 Eigen::Vector3<ScalarType> a3;
77 };
78
95 template <typename VolumeLoad = utils::LoadDefault, typename NeumannBoundaryLoad = utils::LoadDefault>
96 KirchhoffLoveShell(const Basis& globalBasis, const typename LocalView::Element& element, double emod, double nu,
97 double thickness, VolumeLoad p_volumeLoad = {},
98 const BoundaryPatch<GridView>* p_neumannBoundary = nullptr,
99 NeumannBoundaryLoad p_neumannBoundaryLoad = {})
100 : BasePowerFE(globalBasis.flat(), element),
101 neumannBoundary{p_neumannBoundary},
102 emod_{emod},
103 nu_{nu},
104 thickness_{thickness} {
105 this->localView().bind(element);
106 auto& first_child = this->localView().tree().child(0);
107 const auto& fe = first_child.finiteElement();
108 geo_ = std::make_shared<const Geometry>(this->localView().element().geometry());
109 numberOfNodes = fe.size();
110 order = 2 * (fe.localBasis().order());
111 localBasis = Dune::CachedLocalBasis(fe.localBasis());
112 if constexpr (requires { this->localView().element().impl().getQuadratureRule(order); })
113 if (this->localView().element().impl().isTrimmed())
114 localBasis.bind(this->localView().element().impl().getQuadratureRule(order), Dune::bindDerivatives(0, 1, 2));
115 else
116 localBasis.bind(Dune::QuadratureRules<double, myDim>::rule(this->localView().element().type(), order),
117 Dune::bindDerivatives(0, 1, 2));
118 else
119 localBasis.bind(Dune::QuadratureRules<double, myDim>::rule(this->localView().element().type(), order),
120 Dune::bindDerivatives(0, 1, 2));
121
122 if constexpr (!std::is_same_v<VolumeLoad, utils::LoadDefault>) volumeLoad = p_volumeLoad;
123 if constexpr (!std::is_same_v<NeumannBoundaryLoad, utils::LoadDefault>)
124 neumannBoundaryLoad = p_neumannBoundaryLoad;
125
126 assert(((not p_neumannBoundary and not neumannBoundaryLoad) or (p_neumannBoundary and neumannBoundaryLoad))
127 && "If you pass a Neumann boundary you should also pass the function for the Neumann load!");
128 }
129
130 public:
141 template <typename ScalarType = double>
143 const std::optional<const Eigen::VectorX<ScalarType>>& dx = std::nullopt) const {
144 const auto& d = par.getGlobalSolution(Ikarus::FESolutions::displacement);
145 auto disp = Ikarus::FEHelper::localSolutionBlockVector<FERequirementType>(d, this->localView(), dx);
146 Dune::StandardLocalFunction uFunction(localBasis, disp, geo_);
147 return uFunction;
148 }
149
158 double calculateScalar(const FERequirementType& req) const { return calculateScalarImpl<double>(req); }
159
167 void calculateVector(const FERequirementType& req, typename Traits::template VectorType<> force) const {
168 calculateVectorImpl<double>(req, force);
169 }
177 void calculateMatrix(const FERequirementType& req, typename Traits::template MatrixType<> K) const {
178 calculateMatrixImpl<double>(req, K);
179 }
180
191 void calculateAt([[maybe_unused]] const ResultRequirementsType& req,
192 [[maybe_unused]] const Dune::FieldVector<double, Traits::mydim>& local,
193 [[maybe_unused]] ResultTypeMap<double>& result) const {
194 DUNE_THROW(Dune::NotImplemented, "No results are implemented");
195 }
196
197 std::shared_ptr<const Geometry> geo_;
198 Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>> localBasis;
199 std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&, const double&)>
201 std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&, const double&)>
203 const BoundaryPatch<GridView>* neumannBoundary;
205 double emod_;
206 double nu_;
208 size_t numberOfNodes{0};
209 int order{};
210
211 protected:
231 auto computeMaterialAndStrains(const Dune::FieldVector<double, 2>& gpPos, int gpIndex, const Geometry& geo,
232 const auto& uFunction) const {
233 using ScalarType = typename std::remove_cvref_t<decltype(uFunction)>::ctype;
234
236 using namespace Dune;
237 using namespace Dune::DerivativeDirections;
238 const auto [X, Jd, Hd] = geo_->impl().zeroFirstAndSecondDerivativeOfPosition(gpPos);
239 kin.J = toEigen(Jd);
240 kin.H = toEigen(Hd);
241 const Eigen::Matrix<double, 2, 2> A = kin.J * kin.J.transpose();
242 Eigen::Matrix<double, 3, 3> G = Eigen::Matrix<double, 3, 3>::Zero();
243
244 G.block<2, 2>(0, 0) = A;
245 G(2, 2) = 1;
246 const Eigen::Matrix<double, 3, 3> GInv = G.inverse();
247 kin.C = materialTangent(GInv);
248
249 kin.epsV = membraneStrain.value(gpPos, geo, uFunction);
250
251 const auto& Ndd = localBasis.evaluateSecondDerivatives(gpIndex);
252 const auto uasMatrix = Dune::viewAsEigenMatrixAsDynFixed(uFunction.coefficientsRef());
253 const auto hessianu = Ndd.transpose().template cast<ScalarType>() * uasMatrix;
254 kin.h = kin.H + hessianu;
255 const Eigen::Matrix<ScalarType, 3, 2> gradu = toEigen(uFunction.evaluateDerivative(
256 gpIndex, Dune::wrt(spatialAll), Dune::on(Dune::DerivativeDirections::referenceElement)));
257 kin.j = kin.J + gradu.transpose();
258 kin.a3N = (kin.j.row(0).cross(kin.j.row(1)));
259 kin.a3 = kin.a3N.normalized();
260 Eigen::Vector<ScalarType, 3> bV = kin.h * kin.a3;
261 bV(2) *= 2; // Voigt notation requires the two here
262 const auto BV = toVoigt(toEigen(geo_->impl().secondFundamentalForm(gpPos)));
263 kin.kappaV = BV - bV;
264 return kin;
265 }
266
267 template <typename ScalarType>
268 void calculateMatrixImpl(const FERequirementType& par, typename Traits::template MatrixType<ScalarType> K,
269 const std::optional<const Eigen::VectorX<ScalarType>>& dx = std::nullopt) const {
270 K.setZero();
271 using namespace Dune::DerivativeDirections;
272 using namespace Dune;
273 const auto uFunction = displacementFunction(par, dx);
274 const auto& lambda = par.getParameter(FEParameter::loadfactor);
275
276 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
277 const auto intElement = geo_->integrationElement(gp.position()) * gp.weight();
278 const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3]
279 = computeMaterialAndStrains(gp.position(), gpIndex, *geo_, uFunction);
280 const Eigen::Vector<ScalarType, membraneStrainSize> membraneForces = thickness_ * C * epsV;
281 const Eigen::Vector<ScalarType, bendingStrainSize> moments = Dune::power(thickness_, 3) / 12.0 * C * kappaV;
282
283 const auto& Nd = localBasis.evaluateJacobian(gpIndex);
284 const auto& Ndd = localBasis.evaluateSecondDerivatives(gpIndex);
285 for (size_t i = 0; i < numberOfNodes; ++i) {
286 Eigen::Matrix<ScalarType, membraneStrainSize, worldDim> bopIMembrane
287 = membraneStrain.derivative(gp.position(), jE, Nd, *geo_, uFunction, localBasis, i);
288
289 Eigen::Matrix<ScalarType, bendingStrainSize, worldDim> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
290 for (size_t j = i; j < numberOfNodes; ++j) {
291 auto KBlock = K.template block<worldDim, worldDim>(worldDim * i, worldDim * j);
292 Eigen::Matrix<ScalarType, membraneStrainSize, worldDim> bopJMembrane
293 = membraneStrain.derivative(gp.position(), jE, Nd, *geo_, uFunction, localBasis, j);
294 Eigen::Matrix<ScalarType, bendingStrainSize, worldDim> bopJBending = bopBending(jE, h, Nd, Ndd, j, a3N, a3);
295 KBlock += thickness_ * bopIMembrane.transpose() * C * bopJMembrane * intElement;
296 KBlock += Dune::power(thickness_, 3) / 12.0 * bopIBending.transpose() * C * bopJBending * intElement;
297
298 Eigen::Matrix<ScalarType, worldDim, worldDim> kgMembraneIJ = membraneStrain.secondDerivative(
299 gp.position(), Nd, *geo_, uFunction, localBasis, membraneForces, i, j);
300 Eigen::Matrix<ScalarType, worldDim, worldDim> kgBendingIJ
301 = kgBending(jE, h, Nd, Ndd, a3N, a3, moments, i, j);
302 KBlock += kgMembraneIJ * intElement;
303 KBlock += kgBendingIJ * intElement;
304 }
305 }
306 }
307 K.template triangularView<Eigen::StrictlyLower>() = K.transpose();
308 }
309
310 template <typename ScalarType>
311 void calculateVectorImpl(const FERequirementType& par, typename Traits::template VectorType<ScalarType> force,
312 const std::optional<const Eigen::VectorX<ScalarType>>& dx = std::nullopt) const {
313 force.setZero();
314 using namespace Dune::DerivativeDirections;
315 using namespace Dune;
316 const auto uFunction = displacementFunction(par, dx);
317 const auto& lambda = par.getParameter(FEParameter::loadfactor);
318
319 // Internal forces
320 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
321 const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3]
322 = computeMaterialAndStrains(gp.position(), gpIndex, *geo_, uFunction);
323 const Eigen::Vector<ScalarType, 3> membraneForces = thickness_ * C * epsV;
324 const Eigen::Vector<ScalarType, 3> moments = Dune::power(thickness_, 3) / 12.0 * C * kappaV;
325
326 const auto& Nd = localBasis.evaluateJacobian(gpIndex);
327 const auto& Ndd = localBasis.evaluateSecondDerivatives(gpIndex);
328 for (size_t i = 0; i < numberOfNodes; ++i) {
329 Eigen::Matrix<ScalarType, 3, 3> bopIMembrane
330 = membraneStrain.derivative(gp.position(), jE, Nd, *geo_, uFunction, localBasis, i);
331 Eigen::Matrix<ScalarType, 3, 3> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
332 force.template segment<3>(3 * i)
333 += bopIMembrane.transpose() * membraneForces * geo_->integrationElement(gp.position()) * gp.weight();
334 force.template segment<3>(3 * i)
335 += bopIBending.transpose() * moments * geo_->integrationElement(gp.position()) * gp.weight();
336 }
337 }
338
339 // External forces volume forces over the domain
340 if (volumeLoad) {
341 const auto u = displacementFunction(par, dx);
342 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
343 Eigen::Vector<double, worldDim> fext = volumeLoad(geo_->global(gp.position()), lambda);
344 for (size_t i = 0; i < numberOfNodes; ++i) {
345 const auto udCi = uFunction.evaluateDerivative(gpIndex, wrt(coeff(i)));
346 force.template segment<worldDim>(worldDim * i)
347 -= udCi * fext * geo_->integrationElement(gp.position()) * gp.weight();
348 }
349 }
350 }
351
352 if (not neumannBoundary and not neumannBoundaryLoad) return;
353
354 // External forces, boundary forces, i.e. at the Neumann boundary
355 for (auto&& intersection : intersections(neumannBoundary->gridView(), this->localView().element())) {
356 if (not neumannBoundary or not neumannBoundary->contains(intersection)) continue;
357
358 const auto& quadLine = QuadratureRules<double, Element::mydimension - 1>::rule(intersection.type(), order);
359
360 for (const auto& curQuad : quadLine) {
361 // Local position of the quadrature point
363 = intersection.geometryInInside().global(curQuad.position());
364
365 const double intElement = intersection.geometry().integrationElement(curQuad.position()) * curQuad.weight();
366 for (size_t i = 0; i < numberOfNodes; ++i) {
367 const auto udCi = uFunction.evaluateDerivative(quadPos, wrt(coeff(i)));
368
369 // Value of the Neumann data at the current position
370 auto neumannValue = neumannBoundaryLoad(intersection.geometry().global(curQuad.position()), lambda);
371 force.template segment<worldDim>(worldDim * i) -= udCi * neumannValue * intElement;
372 }
373 }
374 }
375 }
376
377 template <typename ScalarType>
378 auto calculateScalarImpl(const FERequirementType& par, const std::optional<const Eigen::VectorX<ScalarType>>& dx
379 = std::nullopt) const -> ScalarType {
380 using namespace Dune::DerivativeDirections;
381 using namespace Dune;
382 const auto uFunction = displacementFunction(par, dx);
383 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
384 ScalarType energy = 0.0;
385
386 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
387 const auto [C, epsV, kappaV, j, J, h, H, a3N, a3]
388 = computeMaterialAndStrains(gp.position(), gpIndex, *geo_, uFunction);
389
390 const ScalarType membraneEnergy = 0.5 * thickness_ * epsV.dot(C * epsV);
391 const ScalarType bendingEnergy = 0.5 * Dune::power(thickness_, 3) / 12.0 * kappaV.dot(C * kappaV);
392 energy += (membraneEnergy + bendingEnergy) * geo_->integrationElement(gp.position()) * gp.weight();
393 }
394
395 if (volumeLoad) {
396 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
397 const auto u = uFunction.evaluate(gpIndex);
398 const Eigen::Vector<double, worldDim> fExt = volumeLoad(geo_->global(gp.position()), lambda);
399 energy -= u.dot(fExt) * geo_->integrationElement(gp.position()) * gp.weight();
400 }
401 }
402
403 if (not neumannBoundary and not neumannBoundaryLoad) return energy;
404
405 // line or surface loads, i.e., neumann boundary
406 const auto& element = this->localView().element();
407 for (auto&& intersection : intersections(neumannBoundary->gridView(), element)) {
408 if (not neumannBoundary or not neumannBoundary->contains(intersection)) continue;
409
410 const auto& quadLine = QuadratureRules<double, Traits::mydim - 1>::rule(intersection.type(), order);
411
412 for (const auto& curQuad : quadLine) {
413 // Local position of the quadrature point
415 = intersection.geometryInInside().global(curQuad.position());
416
417 const double intElement = intersection.geometry().integrationElement(curQuad.position());
418
419 // The value of the local function
420 const auto u = uFunction.evaluate(quadPos);
421
422 // Value of the Neumann data at the current position
423 const auto neumannValue = neumannBoundaryLoad(intersection.geometry().global(curQuad.position()), lambda);
424 energy -= neumannValue.dot(u) * curQuad.weight() * intElement;
425 }
426 }
427 return energy;
428 }
429
430 template <typename ScalarType>
431 Eigen::Matrix<ScalarType, 3, 3> kgBending(const Eigen::Matrix<ScalarType, 2, 3>& jcur,
432 const Eigen::Matrix3<ScalarType>& h, const auto& dN, const auto& ddN,
433 const Eigen::Vector3<ScalarType>& a3N,
434 const Eigen::Vector3<ScalarType>& a3, const Eigen::Vector3<ScalarType>& S,
435 int I, int J) const {
436 Eigen::Matrix<ScalarType, 3, 3> kg;
437 kg.setZero();
438
439 const auto& dN1i = dN(I, 0);
440 const auto& dN1j = dN(J, 0);
441 const auto& dN2i = dN(I, 1);
442 const auto& dN2j = dN(J, 1);
443
444 const Eigen::Matrix<ScalarType, 3, 3> P
445 = 1.0 / a3N.norm() * (Eigen::Matrix<double, 3, 3>::Identity() - a3 * a3.transpose());
446
447 const auto a1dxI = Eigen::Matrix<double, 3, 3>::Identity()
448 * dN1i; // the auto here allows the exploitation of the identity matrices,
449 // due to Eigen's expression templates
450 const auto a2dxI = Eigen::Matrix<double, 3, 3>::Identity() * dN2i;
451 const auto a1dxJ = Eigen::Matrix<double, 3, 3>::Identity() * dN1j;
452 const auto a2dxJ = Eigen::Matrix<double, 3, 3>::Identity() * dN2j;
453 const auto a1 = jcur.row(0);
454 const auto a2 = jcur.row(1);
455 const Eigen::Matrix<ScalarType, 3, 3> a3NdI = a1dxI.colwise().cross(a2) - a2dxI.colwise().cross(a1);
456 const Eigen::Matrix<ScalarType, 3, 3> a3NdJ = a1dxJ.colwise().cross(a2) - a2dxJ.colwise().cross(a1);
457 Eigen::Matrix<ScalarType, 3, 3> a3dI = P * a3NdI;
458 Eigen::Matrix<ScalarType, 3, 3> a3dJ = P * a3NdJ;
459 for (int i = 0; i < 3; ++i) {
460 const auto a_albe = h.row(i).transpose();
461 const auto& ddNI = ddN(I, i);
462 const auto& ddNJ = ddN(J, i);
463 Eigen::Vector3<ScalarType> vecd = P * a_albe;
464
465 Eigen::Matrix<ScalarType, 3, 3> a3Ndd
466 = 1.0 / a3N.squaredNorm()
467 * ((3 * a3 * a3.transpose() - Eigen::Matrix<double, 3, 3>::Identity()) * (a3.dot(a_albe))
468 - a_albe * a3.transpose() - a3 * a_albe.transpose());
469
470 Eigen::Matrix<ScalarType, 3, 3> secondDerivativeDirectorIJ = skew(((dN2i * dN1j - dN1i * dN2j) * vecd).eval());
471 kg -= (a3NdI.transpose() * a3Ndd * a3NdJ + secondDerivativeDirectorIJ + (ddNI * a3dJ + ddNJ * a3dI.transpose()))
472 * S[i] * (i == 2 ? 2 : 1);
473 }
474
475 return kg;
476 }
477
478 template <typename ScalarType>
479 Eigen::Matrix<ScalarType, 3, 3> bopBending(const Eigen::Matrix<ScalarType, 2, 3>& jcur,
480 const Eigen::Matrix3<ScalarType>& h, const auto& dN, const auto& ddN,
481 const int node, const Eigen::Vector3<ScalarType>& a3N,
482 const Eigen::Vector3<ScalarType>& a3) const {
483 const Eigen::Matrix<ScalarType, 3, 3> a1dxI
484 = Eigen::Matrix<double, 3, 3>::Identity() * dN(node, 0); // this should be double
485 // but the cross-product below complains otherwise
486 const Eigen::Matrix<ScalarType, 3, 3> a2dxI = Eigen::Matrix<double, 3, 3>::Identity() * dN(node, 1);
487 const auto a1 = jcur.row(0);
488 const auto a2 = jcur.row(1);
489 const Eigen::Matrix<ScalarType, 3, 3> a3NdI
490 = a1dxI.colwise().cross(a2) - a2dxI.colwise().cross(a1); // minus needed since order has
491 // to be swapped to get column-wise cross product working
492 const Eigen::Matrix<ScalarType, 3, 3> a3d1
493 = 1.0 / a3N.norm() * (Eigen::Matrix<double, 3, 3>::Identity() - a3 * a3.transpose()) * a3NdI;
494
495 Eigen::Matrix<ScalarType, 3, 3> bop = -(h * a3d1 + (a3 * ddN.row(node)).transpose());
496 bop.row(2) *= 2;
497
498 return bop;
499 }
500
501 Eigen::Matrix<double, 3, 3> materialTangent(const Eigen::Matrix<double, 3, 3>& Aconv) const {
502 const double lambda = emod_ * nu_ / ((1.0 + nu_) * (1.0 - 2.0 * nu_));
503 const double mu = emod_ / (2.0 * (1.0 + nu_));
504 const double lambdbar = 2.0 * lambda * mu / (lambda + 2.0 * mu);
505 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 3, 3, 3>> moduli;
506 const auto AconvT = tensorView(Aconv, std::array<Eigen::Index, 2>({3, 3}));
507 moduli = lambdbar * dyadic(AconvT, AconvT).eval() + 2.0 * mu * symmetricFourthOrder<double>(Aconv, Aconv);
508
509 auto C = toVoigt(moduli);
510 Eigen::Matrix<double, 3, 3> C33 = C({0, 1, 5}, {0, 1, 5});
511 return C33;
512 }
513 };
514} // namespace Ikarus
Contains the PowerBasisFE class, which works with a power basis in FlatInterLeaved elements.
Material property functions and conversion utilities.
Definition of the LinearElastic class for finite element mechanics computations.
Header file for material models in Ikarus finite element mechanics.
Implementation of membrane strain for shells.
Derived skew(const Eigen::MatrixBase< Derived > &A)
Returns the skew part of a matrix.
Definition: linearalgebrahelper.hh:407
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:167
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:21
auto transpose(const Eigen::EigenBase< Derived > &A)
Definition: resultevaluators.hh:17
PowerBasisFE class for working with a power basis in FlatInterLeaved elements.
Definition: powerbasisfe.hh:23
const LocalView & localView() const
Get the const reference to the local view.
Definition: powerbasisfe.hh:84
Class representing a map of result types to result arrays.
Definition: ferequirements.hh:342
Class representing the requirements for obtaining specific results.
Definition: ferequirements.hh:405
Kirchhoff-Love shell finite element class.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:38
typename Basis::FlatBasis FlatBasis
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:41
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: finiteelements/mechanics/kirchhoffloveshell.hh:231
const BoundaryPatch< GridView > * neumannBoundary
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:203
Eigen::Matrix< ScalarType, 3, 3 > kgBending(const Eigen::Matrix< ScalarType, 2, 3 > &jcur, const Eigen::Matrix3< ScalarType > &h, const auto &dN, const auto &ddN, const Eigen::Vector3< ScalarType > &a3N, const Eigen::Vector3< ScalarType > &a3, const Eigen::Vector3< ScalarType > &S, int I, int J) const
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:431
typename FlatBasis::LocalView LocalView
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:45
void calculateVector(const FERequirementType &req, typename Traits::template VectorType<> force) const
Calculate the vector associated with the given FERequirementType.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:167
static constexpr int myDim
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:50
static constexpr int membraneStrainSize
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:54
double nu_
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:206
auto displacementFunction(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Get the displacement function and nodal displacements.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:142
std::shared_ptr< const Geometry > geo_
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:197
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ScalarType > force, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:311
double emod_
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:205
std::function< Eigen::Vector< double, worldDim >(const Dune::FieldVector< double, worldDim > &, const double &)> neumannBoundaryLoad
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:202
typename Element::Geometry Geometry
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:47
size_t numberOfNodes
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:208
int order
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:209
Dune::CachedLocalBasis< std::remove_cvref_t< LocalBasisType > > localBasis
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:198
typename LocalView::Element Element
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:46
std::function< Eigen::Vector< double, worldDim >(const Dune::FieldVector< double, worldDim > &, const double &)> volumeLoad
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:200
auto calculateScalarImpl(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const -> ScalarType
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:378
Eigen::Matrix< ScalarType, 3, 3 > bopBending(const Eigen::Matrix< ScalarType, 2, 3 > &jcur, const Eigen::Matrix3< ScalarType > &h, const auto &dN, const auto &ddN, const int node, const Eigen::Vector3< ScalarType > &a3N, const Eigen::Vector3< ScalarType > &a3) const
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:479
double thickness_
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:207
Eigen::Matrix< double, 3, 3 > materialTangent(const Eigen::Matrix< double, 3, 3 > &Aconv) const
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:501
void calculateMatrixImpl(const FERequirementType &par, typename Traits::template MatrixType< ScalarType > K, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:268
decltype(std::declval< LocalView >().tree().child(0).finiteElement().localBasis()) LocalBasisType
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:52
void calculateAt(const ResultRequirementsType &req, const Dune::FieldVector< double, Traits::mydim > &local, ResultTypeMap< double > &result) const
Calculate results at local coordinates.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:191
typename FlatBasis::GridView GridView
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:48
void calculateMatrix(const FERequirementType &req, typename Traits::template MatrixType<> K) const
Calculate the matrix associated with the given FERequirementType.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:177
FERequirements_ FERequirementType
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:43
double calculateScalar(const FERequirementType &req) const
Calculate the scalar value.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:158
static constexpr int worldDim
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:51
KirchhoffLoveShell(const Basis &globalBasis, const typename LocalView::Element &element, double emod, double nu, double thickness, VolumeLoad p_volumeLoad={}, const BoundaryPatch< GridView > *p_neumannBoundary=nullptr, NeumannBoundaryLoad p_neumannBoundaryLoad={})
Constructor for the KirchhoffLoveShell class.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:96
PowerBasisFE< FlatBasis > BasePowerFE
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:42
DefaultMembraneStrain membraneStrain
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:204
Basis_ Basis
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:40
static constexpr int bendingStrainSize
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:55
A structure representing kinematic variables.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:67
Eigen::Matrix< double, 2, 3 > J
Jacobian of the reference geometry.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:72
Eigen::Vector3< ScalarType > a3
normalized normal vector of the deformed geometry
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:76
Eigen::Vector3< ScalarType > kappaV
bending strain in Voigt notation
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:70
Eigen::Matrix< ScalarType, 2, 3 > j
Jacobian of the deformed geometry.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:71
Eigen::Matrix3< ScalarType > h
Hessian of the deformed geometry.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:73
Eigen::Vector3< ScalarType > a3N
Normal vector of the deformed geometry.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:75
Eigen::Matrix< double, 3, 3 > C
material tangent
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:68
Eigen::Matrix3< double > H
Hessian of the reference geometry.
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:74
Eigen::Vector3< ScalarType > epsV
membrane strain in Voigt notation
Definition: finiteelements/mechanics/kirchhoffloveshell.hh:69
Definition: membranestrains.hh:17
auto derivative(const Dune::FieldVector< double, 2 > &gpPos, const Eigen::Matrix< ScalarType, 2, 3 > &jcur, const auto &dNAtGp, const Geometry &geo, const auto &uFunction, const auto &localBasis, const int node) const
Compute the strain-displacement matrix for a given node and integration point.
Definition: membranestrains.hh:65
auto secondDerivative(const Dune::FieldVector< double, 2 > &gpPos, const auto &dNAtGp, const Geometry &geo, const auto &uFunction, const auto &localBasis, const Eigen::Vector3< ScalarType > &S, int I, int J) const
Compute the second derivative of the membrane strain for a given node pair and integration point.
Definition: membranestrains.hh:96
auto value(const Dune::FieldVector< double, 2 > &gpPos, const Geometry &geo, const auto &uFunction) const -> Eigen::Vector3< typename std::remove_cvref_t< decltype(uFunction)>::ctype >
Compute the strain vector at a given integration point.
Definition: membranestrains.hh:30
Traits for handling local views.see https://en.wikipedia.org/wiki/Lam%C3%A9_parameters.
Definition: physicshelper.hh:65
static constexpr int worlddim
Dimension of the world space.
Definition: physicshelper.hh:68
static constexpr int mydim
Dimension of the geometry.
Definition: physicshelper.hh:71
Definition: resultevaluators.hh:20
decltype(Dune::Functions::DefaultGlobalBasis(Ikarus::flatPreBasis(std::declval< PreBasis >()))) FlatBasis
The type of the flattened basis.
Definition: utils/basis.hh:36