13#include <dune/common/fvector.hh>
14#include <dune/localfefunctions/eigenDuneTransformations.hh>
15#include <dune/localfefunctions/expressions/greenLagrangeStrains.hh>
44 template <
typename GEO,
typename EAST>
47 const EAST& easFunction,
const auto& alpha) {
48 using ST =
typename std::remove_cvref_t<
decltype(uFunction)>::ctype;
49 constexpr int myDim = GEO::mydimension;
50 using MatrixType = Eigen::Matrix<ST, myDim, myDim>;
52 using namespace Dune::DerivativeDirections;
55 const MatrixType Hc = toEigen(uFunction.evaluateDerivative(gpPos, wrt(spatialAll), on(gridElement))).eval();
56 const typename EAST::HType Harray = easFunction(gpPos);
57 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
58 typename EAST::AnsatzType Htilde;
60 for (
const auto p : Dune::range(enhancedStrainSize))
61 Htilde += Harray[p] * alpha[p];
62 const MatrixType H = Hc + Htilde;
80 template <
typename GEO,
typename EAST>
82 const EAST& easFunction,
const auto& alpha) {
83 using ST =
typename std::remove_cvref_t<
decltype(uFunction)>::ctype;
84 constexpr int myDim = GEO::mydimension;
86 const Eigen::Matrix<ST, myDim, myDim> E = 0.5 * (H + H.transpose() + H.transpose() * H);
110 template <
int wrtCoeff,
typename GEO,
typename EAST>
111 static auto firstDerivative(
const GEO& geo,
const auto& uFunction,
const auto& localBasis,
const auto& gpIndex,
113 const auto& alpha,
const int node = sNaN) {
114 using namespace Dune::DerivativeDirections;
115 using namespace Dune;
116 using ST =
typename std::remove_cvref_t<
decltype(uFunction)>::ctype;
117 constexpr int myDim = GEO::mydimension;
118 static_assert(myDim == 2 or myDim == 3,
119 "An enhancement of displacement gradient can only be performed for the 2D or 3D case.");
120 constexpr int strainSize = myDim * (myDim + 1) / 2;
121 using MatrixType = Eigen::Matrix<ST, myDim, myDim>;
123 const MatrixType F = computeDeformationGradient(geo, uFunction, gpPos, easFunction, alpha)
126 const auto g0 = F.row(0);
127 const auto g1 = F.row(1);
129 if constexpr (wrtCoeff == 0) {
130 const auto gradUdI = uFunction.evaluateDerivative(gpIndex, wrt(spatialAll, coeff(node)), on(gridElement));
132 Eigen::Vector<ST, myDim> dN;
133 for (
const auto i : Dune::range(myDim))
134 dN[i] = getDiagonalEntry(gradUdI[i], 0);
135 Eigen::Matrix<ST, strainSize, myDim> bopI;
136 bopI.row(0) = dN[0] * g0;
137 bopI.row(1) = dN[1] * g1;
138 if constexpr (myDim == 2)
139 bopI.row(2) = dN[1] * g0 + dN[0] * g1;
141 const auto g2 = F.row(2);
142 bopI.row(2) = dN[2] * g2;
143 bopI.row(3) = dN[2] * g1 + dN[1] * g2;
144 bopI.row(4) = dN[2] * g0 + dN[0] * g2;
145 bopI.row(5) = dN[1] * g0 + dN[0] * g1;
148 }
else if constexpr (wrtCoeff == 1) {
149 const typename EAST::HType Harray = easFunction(gpPos);
150 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
151 Eigen::Matrix<ST, strainSize, enhancedStrainSize> M;
153 for (
const auto p : Dune::range(enhancedStrainSize)) {
154 const MatrixType Htilde = Harray[p];
155 M(0, p) = Htilde.col(0).dot(g0);
156 M(1, p) = Htilde.col(1).dot(g1);
157 if constexpr (myDim == 2)
158 M(2, p) = Htilde.col(1).dot(g0) + Htilde.col(0).dot(g1);
160 const auto g2 = F.row(2);
161 M(2, p) = Htilde.col(2).dot(g2);
162 M(3, p) = Htilde.col(2).dot(g1) + Htilde.col(1).dot(g2);
163 M(4, p) = Htilde.col(2).dot(g0) + Htilde.col(0).dot(g2);
164 M(5, p) = Htilde.col(1).dot(g0) + Htilde.col(0).dot(g1);
169 static_assert(Dune::AlwaysFalse<GEO>::value,
170 "firstDerivative can only be called with wrtCoeff as 0 and 1 indicating first derivative of the "
171 "Green-Lagrange strain w.r.t d and "
172 "alpha, respectively.");
199 template <
int wrtCoeff,
typename GEO,
typename ST,
typename EAST>
200 static auto secondDerivative(
const GEO& geo,
const auto& uFunction,
const auto& localBasis,
const auto& gpIndex,
202 const Eigen::Vector<ST, GEO::mydimension*(GEO::mydimension + 1) / 2>& S,
203 const EAST& easFunction,
const auto& alpha,
const int I = sNaN,
const int J = sNaN) {
204 constexpr int myDim = GEO::mydimension;
205 using namespace Dune::DerivativeDirections;
206 using namespace Dune;
207 static_assert(myDim == 2 or myDim == 3,
208 "An enhancement of displacement gradient can only be performed for the 2D or 3D case.");
209 if constexpr (wrtCoeff == 0) {
210 const auto strainFunction = Dune::greenLagrangeStrains(uFunction);
211 const auto kg = strainFunction.evaluateDerivative(gpIndex, wrt(coeff(I, J)), along(S), on(gridElement));
213 }
else if constexpr (wrtCoeff == 1) {
214 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
215 const typename EAST::HType Harray = easFunction(gpPos);
216 auto kg = Eigen::Matrix<ST, enhancedStrainSize, enhancedStrainSize>::Zero().eval();
218 for (
const auto i : Dune::range(myDim)) {
219 for (
const auto j : Dune::range(myDim)) {
220 const auto sij = 0.5 * S[toVoigt<myDim>(i, j)];
221 for (
const auto p : Dune::range(enhancedStrainSize))
222 for (
const auto q : Dune::range(enhancedStrainSize)) {
223 const auto Hq = Harray[q];
224 kg(p, q) += sij * (Harray[p].col(i).transpose() * Harray[q].col(j) +
225 Harray[p].col(j).transpose() * Harray[q].col(i))
231 }
else if constexpr (wrtCoeff == 2) {
232 constexpr int enhancedStrainSize = EAST::enhancedStrainSize;
233 const typename EAST::HType Harray = easFunction(gpPos);
234 auto kg = Eigen::Matrix<ST, enhancedStrainSize, myDim>::Zero().eval();
235 const auto gradUdI = uFunction.evaluateDerivative(gpIndex, wrt(spatialAll, coeff(I)), on(gridElement));
237 std::array<Eigen::Matrix<ST, myDim, myDim>, myDim> dNIdT;
238 std::ranges::fill(dNIdT, Eigen::Matrix<ST, myDim, myDim>::Zero());
239 for (
const auto i : Dune::range(myDim))
240 for (
const auto j : Dune::range(myDim))
241 dNIdT[i](i, j) = getDiagonalEntry(gradUdI[j], 0);
243 for (
const auto i : Dune::range(myDim)) {
244 for (
const auto j : Dune::range(myDim)) {
245 const auto sij = 0.5 * S[toVoigt<myDim>(i, j)];
246 for (
const auto p : Dune::range(enhancedStrainSize))
247 for (
const auto q : Dune::range(myDim)) {
248 kg(p, q) += sij * (Harray[p].col(i).transpose() * dNIdT[q].col(j) +
249 Harray[p].col(j).transpose() * dNIdT[q].col(i))
257 Dune::AlwaysFalse<GEO>::value,
258 "secondDerivative can only be called with wrtCoeff as 0, 1 and 2 indicating second derivative of the "
259 "Green-Lagrange strain w.r.t d and "
260 "alpha and the mixed derivative, respectively.");
264 static constexpr auto name() {
return std::string(
"Displacement Gradient"); }
267 static constexpr int sNaN = std::numeric_limits<int>::signaling_NaN();
269 template <
typename GEO,
typename EAST>
270 static auto computeDeformationGradient(
const GEO& geo,
const auto& uFunction,
272 const EAST& easFunction,
const auto& alpha) {
273 using ST =
typename std::remove_cvref_t<
decltype(uFunction)>::ctype;
274 constexpr int myDim = GEO::mydimension;
275 using MatrixType = Eigen::Matrix<ST, myDim, myDim>;
277 const MatrixType F = (MatrixType::Identity() + H).eval();
Helper for the Eigen::Tensor types.
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:182
Definition: easfunctions/displacementgradient.hh:21
Definition: utils/dirichletvalues.hh:36
A struct computing the value, first and second derivatives of the Green-Lagrange strain tensor (in Vo...
Definition: easfunctions/displacementgradient.hh:29
static auto computeDisplacementGradient(const GEO &geo, const auto &uFunction, const Dune::FieldVector< double, GEO::mydimension > &gpPos, const EAST &easFunction, const auto &alpha)
Compute the displacement gradient at a given integration point.
Definition: easfunctions/displacementgradient.hh:45
static auto value(const GEO &geo, const auto &uFunction, const Dune::FieldVector< double, GEO::mydimension > &gpPos, const EAST &easFunction, const auto &alpha)
Compute the strain vector at a given integration point.
Definition: easfunctions/displacementgradient.hh:81
static constexpr auto name()
The name of the strain measure enhanced w.r.t EAS method.
Definition: easfunctions/displacementgradient.hh:264
static auto firstDerivative(const GEO &geo, const auto &uFunction, const auto &localBasis, const auto &gpIndex, const Dune::FieldVector< double, GEO::mydimension > &gpPos, const EAST &easFunction, const auto &alpha, const int node=sNaN)
Compute the first derivative of the Green-Lagrange strain w.r.t d or alpha for a given node and integ...
Definition: easfunctions/displacementgradient.hh:111
static auto secondDerivative(const GEO &geo, const auto &uFunction, const auto &localBasis, const auto &gpIndex, const Dune::FieldVector< double, GEO::mydimension > &gpPos, const Eigen::Vector< ST, GEO::mydimension *(GEO::mydimension+1)/2 > &S, const EAST &easFunction, const auto &alpha, const int I=sNaN, const int J=sNaN)
Compute the second derivative of the Green-Lagrange strain w.r.t d or alpha for a given node and inte...
Definition: easfunctions/displacementgradient.hh:200
Definition: utils/dirichletvalues.hh:38