11#if HAVE_DUNE_LOCALFEFUNCTIONS
12# include <dune/localfefunctions/derivativetransformators.hh>
13# include <dune/localfefunctions/linearAlgebraHelper.hh>
14# include <dune/localfefunctions/meta.hh>
31 template <
typename Geometry>
33 const auto& referenceElement = Dune::ReferenceElements<double, 2>::general(geometry.type());
34 const auto quadPos0 = referenceElement.position(0, 0);
36 const auto jacobianinvT0 = toEigen(geometry.jacobianInverseTransposed(quadPos0));
37 const auto detJ0 = geometry.integrationElement(quadPos0);
39 auto jaco = (jacobianinvT0).inverse().eval();
40 auto J11 = jaco(0, 0);
41 auto J12 = jaco(0, 1);
42 auto J21 = jaco(1, 0);
43 auto J22 = jaco(1, 1);
47 T0 << J11 * J11, J12 * J12, J11 * J12,
48 J21 * J21, J22 * J22, J21 * J22,
49 2.0 * J11 * J21, 2.0 * J12 * J22, J21 * J12 + J11 * J22;
51 return T0.inverse() * detJ0;
63 template <
typename Geometry>
65 const auto& referenceElement = Dune::ReferenceElements<double, 3>::general(geometry.type());
66 const auto quadPos0 = referenceElement.position(0, 0);
68 const auto jacobianinvT0 = toEigen(geometry.jacobianInverseTransposed(quadPos0));
69 const auto detJ0 = geometry.integrationElement(quadPos0);
71 auto jaco = (jacobianinvT0).inverse().eval();
72 auto J11 = jaco(0, 0);
73 auto J12 = jaco(0, 1);
74 auto J13 = jaco(0, 2);
75 auto J21 = jaco(1, 0);
76 auto J22 = jaco(1, 1);
77 auto J23 = jaco(1, 2);
78 auto J31 = jaco(2, 0);
79 auto J32 = jaco(2, 1);
80 auto J33 = jaco(2, 2);
82 Eigen::Matrix<double, 6, 6> T0;
84 T0 << J11 * J11, J12 * J12, J13 * J13, J11 * J12, J11 * J13, J12 * J13,
85 J21 * J21, J22 * J22, J23 * J23, J21 * J22, J21 * J23, J22 * J23,
86 J31 * J31, J32 * J32, J33 * J33, J31 * J32, J31 * J33, J32 * J33,
87 2.0 * J11 * J21, 2.0 * J12 * J22, 2.0 * J13 * J23, J11 * J22 + J21 * J12, J11 * J23 + J21 * J13, J12 * J23 + J22 * J13,
88 2.0 * J11 * J31, 2.0 * J12 * J32, 2.0 * J13 * J33, J11 * J32 + J31 * J12, J11 * J33 + J31 * J13, J12 * J33 + J32 * J13,
89 2.0 * J31 * J21, 2.0 * J32 * J22, 2.0 * J33 * J23, J31 * J22 + J21 * J32, J31 * J23 + J21 * J33, J32 * J23 + J22 * J33;
92 return T0.inverse() * detJ0;
104 template <
typename Geometry>
108 using MType = Eigen::Matrix<double, strainSize, enhancedStrainSize>;
112 :
geometry{std::make_shared<Geometry>(geometry_)},
118 const double xi = quadPos[0];
119 const double eta = quadPos[1];
120 M(0, 0) = 2 * xi - 1.0;
121 M(1, 1) = 2 * eta - 1.0;
122 M(2, 2) = 2 * xi - 1.0;
123 M(2, 3) = 2 * eta - 1.0;
124 const double detJ =
geometry->integrationElement(quadPos);
140 template <
typename Geometry>
144 using MType = Eigen::Matrix<double, strainSize, enhancedStrainSize>;
148 :
geometry{std::make_shared<Geometry>(geometry_)},
154 const double xi = quadPos[0];
155 const double eta = quadPos[1];
156 M(0, 0) = 2 * xi - 1.0;
157 M(1, 1) = 2 * eta - 1.0;
158 M(2, 2) = 2 * xi - 1.0;
159 M(2, 3) = 2 * eta - 1.0;
160 M(2, 4) = (2 * xi - 1.0) * (2 * eta - 1.0);
161 const double detJ =
geometry->integrationElement(quadPos);
177 template <
typename Geometry>
181 using MType = Eigen::Matrix<double, strainSize, enhancedStrainSize>;
185 :
geometry{std::make_shared<Geometry>(geometry_)},
191 const double xi = quadPos[0];
192 const double eta = quadPos[1];
193 M(0, 0) = 2 * xi - 1.0;
194 M(1, 1) = 2 * eta - 1.0;
195 M(2, 2) = 2 * xi - 1.0;
196 M(2, 3) = 2 * eta - 1.0;
197 M(0, 4) = (2 * xi - 1.0) * (2 * eta - 1.0);
198 M(1, 5) = (2 * xi - 1.0) * (2 * eta - 1.0);
199 M(2, 6) = (2 * xi - 1.0) * (2 * eta - 1.0);
200 const double detJ =
geometry->integrationElement(quadPos);
216 template <
typename Geometry>
220 using MType = Eigen::Matrix<double, strainSize, enhancedStrainSize>;
224 :
geometry{std::make_shared<Geometry>(geometry_)},
230 const double xi = quadPos[0];
231 const double eta = quadPos[1];
232 const double zeta = quadPos[2];
233 M(0, 0) = 2 * xi - 1.0;
234 M(1, 1) = 2 * eta - 1.0;
235 M(2, 2) = 2 * zeta - 1.0;
236 M(3, 3) = 2 * xi - 1.0;
237 M(3, 4) = 2 * eta - 1.0;
238 M(4, 5) = 2 * xi - 1.0;
239 M(4, 6) = 2 * zeta - 1.0;
240 M(5, 7) = 2 * eta - 1.0;
241 M(5, 8) = 2 * zeta - 1.0;
242 const double detJ =
geometry->integrationElement(quadPos);
257 template <
typename Geometry>
261 using MType = Eigen::Matrix<double, strainSize, enhancedStrainSize>;
265 :
geometry{std::make_shared<Geometry>(geometry_)},
271 const double xi = quadPos[0];
272 const double eta = quadPos[1];
273 const double zeta = quadPos[2];
274 M(0, 0) = 2 * xi - 1.0;
275 M(1, 1) = 2 * eta - 1.0;
276 M(2, 2) = 2 * zeta - 1.0;
277 M(3, 3) = 2 * xi - 1.0;
278 M(3, 4) = 2 * eta - 1.0;
279 M(4, 5) = 2 * xi - 1.0;
280 M(4, 6) = 2 * zeta - 1.0;
281 M(5, 7) = 2 * eta - 1.0;
282 M(5, 8) = 2 * zeta - 1.0;
284 M(3, 9) = (2 * xi - 1.0) * (2 * zeta - 1.0);
285 M(3, 10) = (2 * eta - 1.0) * (2 * zeta - 1.0);
286 M(4, 11) = (2 * xi - 1.0) * (2 * eta - 1.0);
287 M(4, 12) = (2 * eta - 1.0) * (2 * zeta - 1.0);
288 M(5, 13) = (2 * xi - 1.0) * (2 * eta - 1.0);
289 M(5, 14) = (2 * xi - 1.0) * (2 * zeta - 1.0);
291 M(0, 15) = (2 * xi - 1.0) * (2 * eta - 1.0);
292 M(0, 16) = (2 * xi - 1.0) * (2 * zeta - 1.0);
293 M(1, 17) = (2 * xi - 1.0) * (2 * eta - 1.0);
294 M(1, 18) = (2 * eta - 1.0) * (2 * zeta - 1.0);
295 M(2, 19) = (2 * xi - 1.0) * (2 * zeta - 1.0);
296 M(2, 20) = (2 * eta - 1.0) * (2 * zeta - 1.0);
298 const double detJ =
geometry->integrationElement(quadPos);
314 template <
typename Geometry>
324 template <
typename Geometry>
336 template <
typename DisplacementBasedElement>
341 using LocalView =
typename DisplacementBasedElement::LocalView;
342 using GridView =
typename DisplacementBasedElement::GridView;
343 using Traits =
typename DisplacementBasedElement::Traits;
344 using DisplacementBasedElement::localView;
354 template <
typename... Args>
355 requires(not std::is_same_v<std::remove_cvref_t<std::tuple_element_t<0, std::tuple<Args...>>>,
357 : DisplacementBasedElement(std::forward<Args>(args)...) {}
369 DUNE_THROW(Dune::NotImplemented,
370 "EAS element do not support any scalar calculations, i.e. they are not derivable from a potential");
389 calculateVectorImpl<double>(par, force);
406 [&]<
typename EAST>(
const EAST&) {
407 if constexpr (std::is_same_v<std::monostate, EAST>)
410 return EAST::enhancedStrainSize;
424 using namespace Dune::DerivativeDirections;
425 using namespace Dune;
430 DisplacementBasedElement::calculateMatrix(par, K);
435 [&]<
typename EAST>(
const EAST& easFunction) {
436 if constexpr (not std::is_same_v<std::monostate, EAST>) {
437 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
438 Eigen::Matrix<double, enhancedStrainSize, enhancedStrainSize> D;
439 calculateDAndLMatrix(easFunction, par, D, L);
441 K.template triangularView<Eigen::Upper>() -= L.transpose() * D.inverse() * L;
442 K.template triangularView<Eigen::StrictlyLower>() = K.transpose();
464 using namespace Dune::Indices;
465 using namespace Dune::DerivativeDirections;
466 using namespace Dune;
468 DisplacementBasedElement::calculateAt(req, local, result);
472 const auto& par = req.getFERequirements();
473 const auto C = DisplacementBasedElement::materialTangentFunction(req.getFERequirements());
474 const auto& numberOfNodes = DisplacementBasedElement::numberOfNodes();
475 auto uFunction = DisplacementBasedElement::displacementFunction(par);
479 [&]<
typename EAST>(
const EAST& easFunction) {
480 if constexpr (not std::is_same_v<std::monostate, EAST>) {
481 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
482 Eigen::Matrix<double, enhancedStrainSize, enhancedStrainSize> D;
483 calculateDAndLMatrix(easFunction, req.getFERequirements(), D, L);
484 const auto alpha = (-D.inverse() * L * disp).eval();
485 const auto M = easFunction.calcM(local);
486 const auto CEval = C(local);
487 auto easStress = (CEval * M * alpha).eval();
490 resultVector.resize(3, 1);
494 DUNE_THROW(Dune::NotImplemented,
"The requested result type is NOT implemented.");
506 const auto& numberOfNodes = DisplacementBasedElement::numberOfNodes();
507 if (not((numberOfNodes == 4 and Traits::mydim == 2) or (numberOfNodes == 8 and Traits::mydim == 3))
509 DUNE_THROW(Dune::NotImplemented,
"EAS only supported for Q1 or H1 elements");
511 if constexpr (Traits::mydim == 2) {
512 switch (numberOfEASParameters_) {
514 easVariant_ = std::monostate();
517 easVariant_ =
EASQ1E4(localView().element().geometry());
520 easVariant_ =
EASQ1E5(localView().element().geometry());
523 easVariant_ =
EASQ1E7(localView().element().geometry());
526 DUNE_THROW(Dune::NotImplemented,
"The given EAS parameters are not available for the 2D case.");
529 }
else if constexpr (Traits::mydim == 3) {
530 switch (numberOfEASParameters_) {
532 easVariant_ = std::monostate();
535 easVariant_ =
EASH1E9(localView().element().geometry());
538 easVariant_ =
EASH1E21(localView().element().geometry());
541 DUNE_THROW(Dune::NotImplemented,
"The given EAS parameters are not available for the 3D case.");
548 template <
typename ScalarType>
550 const std::optional<
const Eigen::VectorX<ScalarType>>& dx
551 = std::nullopt)
const {
552 if (
isDisplacementBased())
return DisplacementBasedElement::template calculateScalarImpl<ScalarType>(par, dx);
553 DUNE_THROW(Dune::NotImplemented,
554 "EAS element do not support any scalar calculations, i.e. they are not derivable from a potential");
557 template <
typename ScalarType>
559 const std::optional<
const Eigen::VectorX<ScalarType>>& dx = std::nullopt)
const {
560 DisplacementBasedElement::calculateVectorImpl(par, force, dx);
562 using namespace Dune;
563 const auto uFunction = DisplacementBasedElement::displacementFunction(par, dx);
564 auto strainFunction = DisplacementBasedElement::strainFunction(par, dx);
565 const auto& numberOfNodes = DisplacementBasedElement::numberOfNodes();
568 using namespace Dune::DerivativeDirections;
570 auto C = DisplacementBasedElement::materialTangentFunction(par);
571 const auto geo = localView().element().geometry();
575 [&]<
typename EAST>(
const EAST& easFunction) {
576 if constexpr (not std::is_same_v<std::monostate, EAST>) {
577 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
578 Eigen::Matrix<double, enhancedStrainSize, enhancedStrainSize> D;
579 calculateDAndLMatrix(easFunction, par, D, L);
581 const auto alpha = (-D.inverse() * L * disp).eval();
583 for (
const auto& [gpIndex, gp] : strainFunction.viewOverIntegrationPoints()) {
584 const auto M = easFunction.calcM(gp.position());
585 const double intElement = geo.integrationElement(gp.position()) * gp.weight();
586 const auto CEval = C(gpIndex);
587 auto stresses = (CEval * M * alpha).eval();
588 for (
size_t i = 0; i < numberOfNodes; ++i) {
589 const auto bopI = strainFunction.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
590 force.template segment<Traits::worlddim>(Traits::worlddim * i)
591 += bopI.transpose() * stresses * intElement;
602 std::conditional_t<Traits::mydim == 2, EAS2DVariantImpl, EAS3DVariantImpl> easVariant_;
603 mutable Eigen::MatrixXd L;
604 template <
int enhancedStrainSize>
605 void calculateDAndLMatrix(
const auto& easFunction,
const auto& par,
606 Eigen::Matrix<double, enhancedStrainSize, enhancedStrainSize>& DMat,
607 Eigen::MatrixXd& LMat)
const {
608 using namespace Dune;
609 using namespace Dune::DerivativeDirections;
611 auto strainFunction = DisplacementBasedElement::strainFunction(par);
612 const auto C = DisplacementBasedElement::materialTangentFunction(par);
613 const auto geo = localView().element().geometry();
614 const auto numberOfNodes = DisplacementBasedElement::numberOfNodes();
616 LMat.setZero(enhancedStrainSize, localView().size());
617 for (
const auto& [gpIndex, gp] : strainFunction.viewOverIntegrationPoints()) {
618 const auto M = easFunction.calcM(gp.position());
619 const auto CEval = C(gpIndex);
620 const double detJ = geo.integrationElement(gp.position());
621 DMat += M.transpose() * CEval * M * detJ * gp.weight();
622 for (
size_t i = 0U; i < numberOfNodes; ++i) {
623 const size_t I = Traits::worlddim * i;
624 const auto Bi = strainFunction.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
625 LMat.template block<enhancedStrainSize, Traits::worlddim>(0, I)
626 += M.transpose() * CEval * Bi * detJ * gp.weight();
634# error EnhancedAssumedStrains depends on dune-localfefunctions, which is not included
Helper for transform between Dune linear algebra types and Eigen.
Definition of the LinearElastic class for finite element mechanics computations.
auto viewAsFlatEigenVector(Dune::BlockVector< ValueType > &blockedVector)
View Dune::BlockVector as an Eigen::Vector.
Definition: linearalgebrahelper.hh:57
Definition: simpleassemblers.hh:21
std::variant< std::monostate, EASH1E9< Geometry >, EASH1E21< Geometry > > EAS3DVariant
Variant type for 3D EAS structures.
Definition: enhancedassumedstrains.hh:325
Eigen::Matrix3d calcTransformationMatrix2D(const Geometry &geometry)
Calculates the 2D transformation matrix for Enhanced Assumed Strains (EAS).
Definition: enhancedassumedstrains.hh:32
std::variant< std::monostate, EASQ1E4< Geometry >, EASQ1E5< Geometry >, EASQ1E7< Geometry > > EAS2DVariant
Variant type for 2D EAS structures.
Definition: enhancedassumedstrains.hh:315
Eigen::Matrix< double, 6, 6 > calcTransformationMatrix3D(const Geometry &geometry)
Calculates the 3D transformation matrix for Enhanced Assumed Strains (EAS).
Definition: enhancedassumedstrains.hh:64
Definition: resultevaluators.hh:17
Class representing a map of result types to result arrays.
Definition: ferequirements.hh:342
Eigen::Matrix< ParameterType, Eigen::Dynamic, Eigen::Dynamic, 0, 9, 3 > ResultArray
Definition: ferequirements.hh:344
ResultArray & getResult(const ResultType &resultType)
Get the result array for a specific result type.
Definition: ferequirements.hh:368
void insertOrAssignResult(ResultType &&resultType, const ResultArray &resultArray)
Insert or assign a result to the map.
Definition: ferequirements.hh:354
EASQ1E4 structure for Enhanced Assumed Strains (EAS) with linear strains and 4 enhanced modes.
Definition: enhancedassumedstrains.hh:105
static constexpr int strainSize
Definition: enhancedassumedstrains.hh:106
EASQ1E4(const Geometry &geometry_)
Definition: enhancedassumedstrains.hh:111
Eigen::Matrix3d T0InverseTransformed
Definition: enhancedassumedstrains.hh:130
auto calcM(const Dune::FieldVector< double, 2 > &quadPos) const
Definition: enhancedassumedstrains.hh:115
std::shared_ptr< Geometry > geometry
Definition: enhancedassumedstrains.hh:129
Eigen::Matrix< double, strainSize, enhancedStrainSize > MType
Definition: enhancedassumedstrains.hh:108
static constexpr int enhancedStrainSize
Definition: enhancedassumedstrains.hh:107
Structure representing EAS for Q1 with 5 enhanced strains.
Definition: enhancedassumedstrains.hh:141
Eigen::Matrix< double, strainSize, enhancedStrainSize > MType
Definition: enhancedassumedstrains.hh:144
static constexpr int enhancedStrainSize
Definition: enhancedassumedstrains.hh:143
EASQ1E5(const Geometry &geometry_)
Definition: enhancedassumedstrains.hh:147
auto calcM(const Dune::FieldVector< double, 2 > &quadPos) const
Definition: enhancedassumedstrains.hh:151
std::shared_ptr< Geometry > geometry
Definition: enhancedassumedstrains.hh:166
Eigen::Matrix3d T0InverseTransformed
Definition: enhancedassumedstrains.hh:167
static constexpr int strainSize
Definition: enhancedassumedstrains.hh:142
Structure representing EAS for Q1 with 7 enhanced strains.
Definition: enhancedassumedstrains.hh:178
Eigen::Matrix< double, strainSize, enhancedStrainSize > MType
Definition: enhancedassumedstrains.hh:181
static constexpr int strainSize
Definition: enhancedassumedstrains.hh:179
EASQ1E7(const Geometry &geometry_)
Definition: enhancedassumedstrains.hh:184
auto calcM(const Dune::FieldVector< double, 2 > &quadPos) const
Definition: enhancedassumedstrains.hh:188
std::shared_ptr< Geometry > geometry
Definition: enhancedassumedstrains.hh:205
Eigen::Matrix3d T0InverseTransformed
Definition: enhancedassumedstrains.hh:206
static constexpr int enhancedStrainSize
Definition: enhancedassumedstrains.hh:180
Structure representing EAS for H1 with 9 enhanced strains.
Definition: enhancedassumedstrains.hh:217
auto calcM(const Dune::FieldVector< double, 3 > &quadPos) const
Definition: enhancedassumedstrains.hh:227
EASH1E9(const Geometry &geometry_)
Definition: enhancedassumedstrains.hh:223
static constexpr int strainSize
Definition: enhancedassumedstrains.hh:218
Eigen::Matrix< double, 6, 6 > T0InverseTransformed
Definition: enhancedassumedstrains.hh:247
Eigen::Matrix< double, strainSize, enhancedStrainSize > MType
Definition: enhancedassumedstrains.hh:220
std::shared_ptr< Geometry > geometry
Definition: enhancedassumedstrains.hh:246
static constexpr int enhancedStrainSize
Definition: enhancedassumedstrains.hh:219
Structure representing EAS for H1 with 21 enhanced strains.
Definition: enhancedassumedstrains.hh:258
auto calcM(const Dune::FieldVector< double, 3 > &quadPos) const
Definition: enhancedassumedstrains.hh:268
EASH1E21(const Geometry &geometry_)
Definition: enhancedassumedstrains.hh:264
static constexpr int strainSize
Definition: enhancedassumedstrains.hh:259
std::shared_ptr< Geometry > geometry
Definition: enhancedassumedstrains.hh:303
Eigen::Matrix< double, strainSize, enhancedStrainSize > MType
Definition: enhancedassumedstrains.hh:261
static constexpr int enhancedStrainSize
Definition: enhancedassumedstrains.hh:260
Eigen::Matrix< double, 6, 6 > T0InverseTransformed
Definition: enhancedassumedstrains.hh:304
Wrapper class for using Enhanced Assumed Strains (EAS) with displacement based elements.
Definition: enhancedassumedstrains.hh:337
EnhancedAssumedStrains(Args &&... args)
Constructor for Enhanced Assumed Strains elements.
Definition: enhancedassumedstrains.hh:356
void calculateAt(const ResultRequirementsType &req, const Dune::FieldVector< double, Traits::mydim > &local, ResultTypeMap< double > &result) const
Calculates the results at a given set of local coordinates using the Enhanced Assumed Strains (EAS) m...
Definition: enhancedassumedstrains.hh:462
bool isDisplacementBased() const
Checks if the element is displacement-based and the EAS is turned off.
Definition: enhancedassumedstrains.hh:378
void setEASType(int numberOfEASParameters_)
Sets the EAS type for 2D elements.
Definition: enhancedassumedstrains.hh:505
void calculateVector(const FERequirementType &par, typename Traits::template VectorType<> force) const
Calculates vectorial quantities for the element.
Definition: enhancedassumedstrains.hh:388
typename DisplacementBasedElement::Traits Traits
Definition: enhancedassumedstrains.hh:343
typename DisplacementBasedElement::LocalView LocalView
Definition: enhancedassumedstrains.hh:341
typename DisplacementBasedElement::FERequirementType FERequirementType
Definition: enhancedassumedstrains.hh:339
typename DisplacementBasedElement::ResultRequirementsType ResultRequirementsType
Definition: enhancedassumedstrains.hh:340
void calculateMatrix(const FERequirementType &par, typename Traits::template MatrixType<> K) const
Calculates the matrix for the element.
Definition: enhancedassumedstrains.hh:423
double calculateScalar(const FERequirementType &par) const
Calculates a scalar quantity for the element.
Definition: enhancedassumedstrains.hh:367
auto getNumberOfEASParameters() const
Gets the number of EAS parameters based on the current EAS type.
Definition: enhancedassumedstrains.hh:404
const auto & easVariant() const
Gets the variant representing the type of Enhanced Assumed Strains (EAS).
Definition: enhancedassumedstrains.hh:397
typename DisplacementBasedElement::GridView GridView
Definition: enhancedassumedstrains.hh:342
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ScalarType > force, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Definition: enhancedassumedstrains.hh:558
ScalarType calculateScalarImpl(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Definition: enhancedassumedstrains.hh:549
Definition: resultevaluators.hh:20