@@ -36,20 +36,20 @@ namespace Ikarus {
36
36
template <typename Basis_, typename FERequirements_ = FErequirements<>, bool useEigenRef = false >
37
37
class KirchhoffLoveShell : public PowerBasisFE <typename Basis_::FlatBasis> {
38
38
public:
39
- using Basis = Basis_;
40
- using FlatBasis = typename Basis::FlatBasis;
41
- using BasePowerFE = PowerBasisFE<FlatBasis>; // Handles globalIndices function
42
- using FERequirementType = FERequirements_;
43
- using ResultRequirementsType = ResultRequirements<FERequirementType>;
44
- using LocalView = typename FlatBasis::LocalView;
45
- using Element = typename LocalView::Element;
46
- using Geometry = typename Element::Geometry;
47
- using GridView = typename FlatBasis::GridView;
48
- using Traits = TraitsFromLocalView<LocalView, useEigenRef>;
49
- static constexpr int myDim = Traits::mydim;
50
- static constexpr int worlddim = Traits::worlddim;
39
+ using Basis = Basis_;
40
+ using FlatBasis = typename Basis::FlatBasis;
41
+ using BasePowerFE = PowerBasisFE<FlatBasis>; // Handles globalIndices function
42
+ using FERequirementType = FERequirements_;
43
+ using ResultRequirementsType = ResultRequirements<FERequirementType>;
44
+ using LocalView = typename FlatBasis::LocalView;
45
+ using Element = typename LocalView::Element;
46
+ using Geometry = typename Element::Geometry;
47
+ using GridView = typename FlatBasis::GridView;
48
+ using Traits = TraitsFromLocalView<LocalView, useEigenRef>;
49
+ static constexpr int myDim = Traits::mydim;
50
+ static constexpr int worlddim = Traits::worlddim;
51
51
static constexpr int membraneStrainSize = 3 ;
52
- static constexpr int bendingStrainSize = 3 ;
52
+ static constexpr int bendingStrainSize = 3 ;
53
53
54
54
/* *
55
55
* @brief Constructor for the KirchhoffLoveShell class.
@@ -203,82 +203,81 @@ namespace Ikarus {
203
203
204
204
protected:
205
205
/* *
206
- * \brief Compute material properties and strains at a given integration point.
207
- *
208
- * \param gpPos The position of the integration point.
209
- * \param gpIndex The index of the integration point.
210
- * \param geo The geometry object providing position and derivatives.
211
- * \param uFunction The function representing the displacement field.
212
- *
213
- * \tparam gpPos The type of the integration point position.
214
- * \tparam gpIndex The type of the integration point index.
215
- * \tparam geo The type of the geometry object.
216
- * \tparam uFunction The type of the displacement field function.
217
- *
218
- * \return A tuple containing the material tangent, membrane strain, curvature variation,
219
- * Jacobian matrix, metric tensor, Hessian matrix, second fundamental form,
220
- * normalized normal vector, and normal vector at the given integration point.
221
- */
222
- auto computeMaterialAndStrains (const Dune::FieldVector<double , 2 > &gpPos, int gpIndex, const Geometry &geo,
223
- const auto &uFunction) const {
224
- // Deduce the scalar type of the function
225
- using ScalarType = typename std::remove_cvref_t <decltype (uFunction)>::ctype;
226
-
227
- using namespace Dune ;
228
- using namespace Dune ::DerivativeDirections;
206
+ * \brief Compute material properties and strains at a given integration point.
207
+ *
208
+ * \param gpPos The position of the integration point.
209
+ * \param gpIndex The index of the integration point.
210
+ * \param geo The geometry object providing position and derivatives.
211
+ * \param uFunction The function representing the displacement field.
212
+ *
213
+ * \tparam gpPos The type of the integration point position.
214
+ * \tparam gpIndex The type of the integration point index.
215
+ * \tparam geo The type of the geometry object.
216
+ * \tparam uFunction The type of the displacement field function.
217
+ *
218
+ * \return A tuple containing the material tangent, membrane strain, curvature variation,
219
+ * Jacobian matrix, metric tensor, Hessian matrix, second fundamental form,
220
+ * normalized normal vector, and normal vector at the given integration point.
221
+ */
222
+ auto computeMaterialAndStrains (const Dune::FieldVector<double , 2 > &gpPos, int gpIndex, const Geometry &geo,
223
+ const auto &uFunction) const {
224
+ // Deduce the scalar type of the function
225
+ using ScalarType = typename std::remove_cvref_t <decltype (uFunction)>::ctype;
229
226
230
- // Extract position and derivatives from the geometry
231
- const auto [X, Jd, Hd] = geo.impl ().zeroFirstAndSecondDerivativeOfPosition (gpPos);
232
- const auto J = toEigen (Jd);
233
- const auto H = toEigen (Hd);
227
+ using namespace Dune ;
228
+ using namespace Dune ::DerivativeDirections;
234
229
235
- // Compute the metric tensor A
236
- const Eigen::Matrix<double , 2 , 2 > A = J * J.transpose ();
230
+ // Extract position and derivatives from the geometry
231
+ const auto [X, Jd, Hd] = geo.impl ().zeroFirstAndSecondDerivativeOfPosition (gpPos);
232
+ const auto J = toEigen (Jd);
233
+ const auto H = toEigen (Hd);
237
234
238
- // Build the metric tensor G in 3D
239
- Eigen::Matrix<double , worlddim, worlddim> G;
240
- G.setZero ();
241
- G.template block <2 , 2 >(0 , 0 ) = A;
242
- G (2 , 2 ) = 1 ;
235
+ // Compute the metric tensor A
236
+ const Eigen::Matrix<double , 2 , 2 > A = J * J.transpose ();
243
237
244
- const Eigen::Matrix<double , worlddim, worlddim> GInv = G.inverse ();
238
+ // Build the metric tensor G in 3D
239
+ Eigen::Matrix<double , worlddim, worlddim> G;
240
+ G.setZero ();
241
+ G.template block <2 , 2 >(0 , 0 ) = A;
242
+ G (2 , 2 ) = 1 ;
245
243
246
- // Compute the material tangent
247
- const auto C = materialTangent (GInv);
244
+ const Eigen::Matrix<double , worlddim, worlddim> GInv = G.inverse ();
248
245
249
- // Compute membrane strain
250
- Eigen::Vector3<ScalarType> epsV = membraneStrain. value (gpPos, geo, uFunction );
246
+ // Compute the material tangent
247
+ const auto C = materialTangent (GInv );
251
248
252
- const auto &Ndd = localBasis.evaluateSecondDerivatives (gpIndex);
249
+ // Compute membrane strain
250
+ Eigen::Vector3<ScalarType> epsV = membraneStrain.value (gpPos, geo, uFunction);
253
251
254
- const auto uasMatrix = Dune::viewAsEigenMatrixAsDynFixed (uFunction. coefficientsRef () );
252
+ const auto &Ndd = localBasis. evaluateSecondDerivatives (gpIndex );
255
253
256
- // Compute the Hessian of the deformed midsurface
257
- const auto hessianu = Ndd.transpose ().template cast <ScalarType>() * uasMatrix;
258
- const Eigen::Matrix3<ScalarType> h = H + hessianu;
254
+ const auto uasMatrix = Dune::viewAsEigenMatrixAsDynFixed (uFunction.coefficientsRef ());
259
255
260
- // Compute the gradient and Jacobian matrices
261
- const Eigen::Matrix<ScalarType, worlddim, myDim> gradu =
262
- toEigen (uFunction.evaluateDerivative (gpIndex, Dune::wrt (spatialAll), Dune::on (Dune::DerivativeDirections::referenceElement)));
263
- const Eigen::Matrix<ScalarType, myDim, worlddim> j = J + gradu.transpose ();
256
+ // Compute the Hessian of the deformed midsurface
257
+ const auto hessianu = Ndd.transpose ().template cast <ScalarType>() * uasMatrix;
258
+ const Eigen::Matrix3<ScalarType> h = H + hessianu;
264
259
265
- // Compute the normal vector
266
- const Eigen::Vector3<ScalarType> a3N = (j.row (0 ).cross (j.row (1 ))).normalized ();
260
+ // Compute the gradient and Jacobian matrices
261
+ const Eigen::Matrix<ScalarType, worlddim, myDim> gradu = toEigen (uFunction.evaluateDerivative (
262
+ gpIndex, Dune::wrt (spatialAll), Dune::on (Dune::DerivativeDirections::referenceElement)));
263
+ const Eigen::Matrix<ScalarType, myDim, worlddim> j = J + gradu.transpose ();
267
264
268
- // Compute the normalized normal vector a3
269
- const Eigen::Vector3<ScalarType> a3 = a3N .normalized ();
265
+ // Compute the normal vector
266
+ const Eigen::Vector3<ScalarType> a3N = (j. row ( 0 ). cross (j. row ( 1 ))) .normalized ();
270
267
271
- // Compute the vector bV
272
- Eigen::Vector<ScalarType, worlddim> bV = h * a3;
273
- bV (2 ) *= 2 ; // Voigt notation requires the factor of 2 here
268
+ // Compute the normalized normal vector a3
269
+ const Eigen::Vector3<ScalarType> a3 = a3N.normalized ();
274
270
275
- // Compute BV and kappaV
276
- const auto BV = toVoigt ( toEigen (geo. impl (). secondFundamentalForm (gpPos))) ;
277
- const auto kappaV = (BV - bV). eval ();
271
+ // Compute the vector bV
272
+ Eigen::Vector<ScalarType, worlddim> bV = h * a3 ;
273
+ bV ( 2 ) *= 2 ; // Voigt notation requires the factor of 2 here
278
274
279
- return std::make_tuple (C, epsV, kappaV, j, J, h, H, a3N, a3);
280
- }
275
+ // Compute BV and kappaV
276
+ const auto BV = toVoigt (toEigen (geo.impl ().secondFundamentalForm (gpPos)));
277
+ const auto kappaV = (BV - bV).eval ();
281
278
279
+ return std::make_tuple (C, epsV, kappaV, j, J, h, H, a3N, a3);
280
+ }
282
281
283
282
template <typename ScalarType>
284
283
void calculateMatrixImpl (const FERequirementType &par, typename Traits::template MatrixType<ScalarType> K,
@@ -296,7 +295,7 @@ auto computeMaterialAndStrains(const Dune::FieldVector<double, 2> &gpPos, int gp
296
295
const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3]
297
296
= computeMaterialAndStrains (gp.position (), gpIndex, geo, uFunction);
298
297
const Eigen::Vector<ScalarType, membraneStrainSize> membraneForces = thickness_ * C * epsV;
299
- const Eigen::Vector<ScalarType, bendingStrainSize> moments = Dune::power (thickness_, 3 ) / 12.0 * C * kappaV;
298
+ const Eigen::Vector<ScalarType, bendingStrainSize> moments = Dune::power (thickness_, 3 ) / 12.0 * C * kappaV;
300
299
301
300
const auto &Nd = localBasis.evaluateJacobian (gpIndex);
302
301
const auto &Ndd = localBasis.evaluateSecondDerivatives (gpIndex);
@@ -306,18 +305,17 @@ auto computeMaterialAndStrains(const Dune::FieldVector<double, 2> &gpPos, int gp
306
305
307
306
Eigen::Matrix<ScalarType, bendingStrainSize, worlddim> bopIBending = bopBending (jE, h, Nd, Ndd, i, a3N, a3);
308
307
for (size_t j = i; j < numberOfNodes; ++j) {
309
- auto KBlock = K.template block <worlddim,worlddim>(worlddim * i, worlddim * j);
308
+ auto KBlock = K.template block <worlddim, worlddim>(worlddim * i, worlddim * j);
310
309
Eigen::Matrix<ScalarType, membraneStrainSize, worlddim> bopJMembrane
311
310
= membraneStrain.derivative (gp.position (), jE, Nd, geo, uFunction, localBasis, j);
312
311
Eigen::Matrix<ScalarType, bendingStrainSize, worlddim> bopJBending = bopBending (jE, h, Nd, Ndd, j, a3N, a3);
313
- KBlock
314
- += thickness_ * bopIMembrane.transpose () * C * bopJMembrane * intElement;
315
- KBlock
316
- += Dune::power (thickness_, 3 ) / 12.0 * bopIBending.transpose () * C * bopJBending * intElement;
312
+ KBlock += thickness_ * bopIMembrane.transpose () * C * bopJMembrane * intElement;
313
+ KBlock += Dune::power (thickness_, 3 ) / 12.0 * bopIBending.transpose () * C * bopJBending * intElement;
317
314
318
- Eigen::Matrix<ScalarType, worlddim,worlddim> kgMembraneIJ
315
+ Eigen::Matrix<ScalarType, worlddim, worlddim> kgMembraneIJ
319
316
= membraneStrain.secondDerivative (gp.position (), Nd, geo, uFunction, localBasis, membraneForces, i, j);
320
- Eigen::Matrix<ScalarType, worlddim, worlddim> kgBendingIJ = kgBending (jE, h, Nd, Ndd, a3N, a3, moments, i, j);
317
+ Eigen::Matrix<ScalarType, worlddim, worlddim> kgBendingIJ
318
+ = kgBending (jE, h, Nd, Ndd, a3N, a3, moments, i, j);
321
319
KBlock += kgMembraneIJ * intElement;
322
320
KBlock += kgBendingIJ * intElement;
323
321
}
0 commit comments