12#if HAVE_DUNE_LOCALFEFUNCTIONS
13 #include <dune/localfefunctions/derivativetransformators.hh>
14 #include <dune/localfefunctions/linearAlgebraHelper.hh>
15 #include <dune/localfefunctions/meta.hh>
25template <
typename PreFE,
typename FE>
26class EnhancedAssumedStrains;
35 template <
typename PreFE,
typename FE>
49template <
typename PreFE,
typename FE>
102 template <
template <
typename,
int,
int>
class RT>
104 Dune::PriorityTag<2>)
const {
106 return underlying().template calculateAtImpl<RT>(req, local, Dune::PriorityTag<1>());
108 using namespace Dune::Indices;
109 using namespace Dune::DerivativeDirections;
110 auto resultVector = underlying().template calculateAtImpl<RT>(req, local, Dune::PriorityTag<1>());
111 if constexpr (isSameResultType<RT, ResultTypes::linearStress>) {
113 RTWrapper resultWrapper;
115 auto calculateAtContribution = [&]<
typename EAST>(
const EAST& easFunction) {
116 typename EAST::DType D;
117 calculateDAndLMatrix(easFunction, req, D, L_);
118 const auto ufunc = underlying().displacementFunction(req);
120 const auto C = underlying().materialTangentFunction(req);
121 const auto alpha = (-D.inverse() * L_ * disp).eval();
122 const auto M = easFunction.calcM(local);
123 const auto CEval = C(local);
124 auto easStress = (CEval * M * alpha).eval();
125 resultWrapper = resultVector.asVec() + easStress;
127 easVariant_(calculateAtContribution);
128 return resultWrapper;
145 assert(underlying().localView().bound());
146 easVariant_.bind(underlying().localView().element().geometry());
152 const auto& numberOfNodes = underlying().numberOfNodes();
155 "EAS only supported for Q1 or H1 elements");
158 template <
typename ScalarType>
161 const std::optional<std::reference_wrapper<
const Eigen::VectorX<ScalarType>>>& dx = std::nullopt)
const {
162 using namespace Dune::DerivativeDirections;
163 using namespace Dune;
168 decltype(
auto) LMat = [
this]() ->
decltype(
auto) {
170 return Eigen::MatrixX<ScalarType>{};
172 return [
this]() -> Eigen::MatrixXd& {
return L_; }();
175 auto calculateMatrixContribution = [&]<
typename EAST>(
const EAST& easFunction) {
176 typename EAST::DType D;
177 calculateDAndLMatrix(easFunction, par, D, LMat, dx);
179 K.template triangularView<Eigen::Upper>() -= LMat.transpose() * D.inverse() * LMat;
180 K.template triangularView<Eigen::StrictlyLower>() = K.transpose();
182 easVariant_(calculateMatrixContribution);
185 template <
typename ScalarType>
188 const std::optional<std::reference_wrapper<
const Eigen::VectorX<ScalarType>>>& dx = std::nullopt)
const {
192 DUNE_THROW(Dune::NotImplemented,
193 "EAS element do not support any scalar calculations, i.e. they are not derivable from a potential");
196 template <
typename ScalarType>
199 const std::optional<std::reference_wrapper<
const Eigen::VectorX<ScalarType>>>& dx = std::nullopt)
const {
201 using namespace Dune;
202 using namespace Dune::DerivativeDirections;
203 const auto uFunction = underlying().displacementFunction(par, dx);
204 auto strainFunction = underlying().strainFunction(par, dx);
205 const auto& numberOfNodes = underlying().numberOfNodes();
207 auto calculateForceContribution = [&]<
typename EAST>(
const EAST& easFunction) {
208 typename EAST::DType D;
209 calculateDAndLMatrix(easFunction, par, D, L_);
211 decltype(
auto) LMat = [
this]() ->
decltype(
auto) {
213 return Eigen::MatrixX<ScalarType>{};
215 return [
this]() -> Eigen::MatrixXd& {
return L_; }();
218 const auto alpha = (-D.inverse() * L_ * disp).eval();
219 const auto geo = underlying().localView().element().geometry();
220 auto C = underlying().materialTangentFunction(par);
222 for (
const auto& [gpIndex, gp] : strainFunction.viewOverIntegrationPoints()) {
223 const auto M = easFunction.calcM(gp.position());
224 const double intElement = geo.integrationElement(gp.position()) * gp.weight();
225 const auto CEval = C(gpIndex);
226 auto stresses = (CEval * M * alpha).eval();
227 for (
size_t i = 0; i < numberOfNodes; ++i) {
228 const auto bopI = strainFunction.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
229 force.template segment<Traits::worlddim>(
Traits::worlddim * i) += bopI.transpose() * stresses * intElement;
233 easVariant_(calculateForceContribution);
237 EAS::Impl::EASVariant<Geometry> easVariant_;
238 mutable Eigen::MatrixXd L_;
241 const auto& underlying()
const {
return static_cast<const FE&
>(*this); }
242 auto& underlying() {
return static_cast<FE&
>(*this); }
244 template <
typename ScalarType,
int enhancedStrainSize>
245 void calculateDAndLMatrix(
246 const auto& easFunction,
const auto& par, Eigen::Matrix<double, enhancedStrainSize, enhancedStrainSize>& DMat,
247 Eigen::MatrixX<ScalarType>& LMat,
248 const std::optional<std::reference_wrapper<
const Eigen::VectorX<ScalarType>>>& dx = std::nullopt)
const {
249 using namespace Dune;
250 using namespace Dune::DerivativeDirections;
252 auto strainFunction = underlying().strainFunction(par, dx);
253 const auto C = underlying().materialTangentFunction(par);
254 const auto geo = underlying().localView().element().geometry();
255 const auto numberOfNodes = underlying().numberOfNodes();
257 LMat.setZero(enhancedStrainSize, underlying().localView().size());
258 for (
const auto& [gpIndex, gp] : strainFunction.viewOverIntegrationPoints()) {
259 const auto M = easFunction.calcM(gp.position());
260 const auto CEval = C(gpIndex);
261 const double detJTimesW = geo.integrationElement(gp.position()) * gp.weight();
262 DMat += M.transpose() * CEval * M * detJTimesW;
263 for (
size_t i = 0U; i < numberOfNodes; ++i) {
265 const auto Bi = strainFunction.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
266 LMat.template block<enhancedStrainSize, Traits::worlddim>(0, I) += M.transpose() * CEval * Bi * detJTimesW;
277auto eas(
int numberOfEASParameters = 0) {
286 #error EnhancedAssumedStrains depends on dune-localfefunctions, which is not included
Definition of the LinearElastic class for finite element mechanics computations.
Implementation of the finite element CRTP mixin class.
Definition of the EAS variants.
auto viewAsFlatEigenVector(Dune::BlockVector< ValueType > &blockedVector)
View Dune::BlockVector as an Eigen::Vector.
Definition: linearalgebrahelper.hh:57
Definition: assemblermanipulatorbuildingblocks.hh:22
MatrixAffordance
A strongly typed enum class representing the matrix affordance.
Definition: ferequirements.hh:63
auto eas(int numberOfEASParameters=0)
A helper function to create an enhanced assumed strain pre finite element.
Definition: enhancedassumedstrains.hh:277
VectorAffordance
A strongly typed enum class representing the vector affordance.
Definition: ferequirements.hh:48
ScalarAffordance
A strongly typed enum class representing the scalar affordance.
Definition: ferequirements.hh:37
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:252
Container that is used for FE Results. It gives access to the stored value, but can also be used to a...
Definition: feresulttypes.hh:159
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
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
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:63
Wrapper class for using Enhanced Assumed Strains (EAS) with displacement based elements.
Definition: enhancedassumedstrains.hh:51
typename Traits::GridView GridView
Definition: enhancedassumedstrains.hh:58
void calculateMatrixImpl(const Requirement &par, const MatrixAffordance &affordance, typename Traits::template MatrixType<> K, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Definition: enhancedassumedstrains.hh:159
typename Traits::LocalView LocalView
Definition: enhancedassumedstrains.hh:56
EnhancedAssumedStrains(const Pre &pre)
Constructor for Enhanced Assumed Strains elements.
Definition: enhancedassumedstrains.hh:65
const auto & easVariant() const
Gets the variant representing the type of Enhanced Assumed Strains (EAS).
Definition: enhancedassumedstrains.hh:79
void easApplicabilityCheck() const
Definition: enhancedassumedstrains.hh:151
void calculateVectorImpl(const Requirement &par, VectorAffordance affordance, typename Traits::template VectorType< ScalarType > force, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Definition: enhancedassumedstrains.hh:197
void bindImpl()
Definition: enhancedassumedstrains.hh:144
bool isDisplacementBased() const
Checks if the element is displacement-based and the EAS is turned off.
Definition: enhancedassumedstrains.hh:72
void setEASType(int numberOfEASParameters)
Sets the EAS type for 2D elements.
Definition: enhancedassumedstrains.hh:137
auto numberOfEASParameters() const
Gets the number of EAS parameters based on the current EAS type.
Definition: enhancedassumedstrains.hh:86
ScalarType calculateScalarImpl(const Requirement &par, ScalarAffordance affordance, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Definition: enhancedassumedstrains.hh:186
typename Traits::Geometry Geometry
Definition: enhancedassumedstrains.hh:57
auto calculateAtImpl(const Requirement &req, const Dune::FieldVector< double, Traits::mydim > &local, Dune::PriorityTag< 2 >) const
Calculates a requested result at a specific local position using the Enhanced Assumed Strains (EAS) m...
Definition: enhancedassumedstrains.hh:103
A PreFE struct for Enhanced Assumed Strains.
Definition: enhancedassumedstrains.hh:32
int numberOfParameters
Definition: enhancedassumedstrains.hh:33
Definition: utils/dirichletvalues.hh:32
Concept to check if the underlying scalar type is a dual type.
Definition: concepts.hh:608