Skip to content

Commit 1565365

Browse files
committed
refactor
1 parent 02168eb commit 1565365

10 files changed

+201
-172
lines changed

ikarus/finiteelements/mechanics/kirchhoffloveshell.hh

Lines changed: 79 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@ namespace Ikarus {
3636
template <typename Basis_, typename FERequirements_ = FErequirements<>, bool useEigenRef = false>
3737
class KirchhoffLoveShell : public PowerBasisFE<typename Basis_::FlatBasis> {
3838
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;
5151
static constexpr int membraneStrainSize = 3;
52-
static constexpr int bendingStrainSize = 3;
52+
static constexpr int bendingStrainSize = 3;
5353

5454
/**
5555
* @brief Constructor for the KirchhoffLoveShell class.
@@ -203,82 +203,81 @@ namespace Ikarus {
203203

204204
protected:
205205
/**
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;
229226

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;
234229

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);
237234

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();
243237

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;
245243

246-
// Compute the material tangent
247-
const auto C = materialTangent(GInv);
244+
const Eigen::Matrix<double, worlddim, worlddim> GInv = G.inverse();
248245

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);
251248

252-
const auto &Ndd = localBasis.evaluateSecondDerivatives(gpIndex);
249+
// Compute membrane strain
250+
Eigen::Vector3<ScalarType> epsV = membraneStrain.value(gpPos, geo, uFunction);
253251

254-
const auto uasMatrix = Dune::viewAsEigenMatrixAsDynFixed(uFunction.coefficientsRef());
252+
const auto &Ndd = localBasis.evaluateSecondDerivatives(gpIndex);
255253

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());
259255

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;
264259

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();
267264

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();
270267

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();
274270

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
278274

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();
281278

279+
return std::make_tuple(C, epsV, kappaV, j, J, h, H, a3N, a3);
280+
}
282281

283282
template <typename ScalarType>
284283
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
296295
const auto [C, epsV, kappaV, jE, J, h, H, a3N, a3]
297296
= computeMaterialAndStrains(gp.position(), gpIndex, geo, uFunction);
298297
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;
300299

301300
const auto &Nd = localBasis.evaluateJacobian(gpIndex);
302301
const auto &Ndd = localBasis.evaluateSecondDerivatives(gpIndex);
@@ -306,18 +305,17 @@ auto computeMaterialAndStrains(const Dune::FieldVector<double, 2> &gpPos, int gp
306305

307306
Eigen::Matrix<ScalarType, bendingStrainSize, worlddim> bopIBending = bopBending(jE, h, Nd, Ndd, i, a3N, a3);
308307
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);
310309
Eigen::Matrix<ScalarType, membraneStrainSize, worlddim> bopJMembrane
311310
= membraneStrain.derivative(gp.position(), jE, Nd, geo, uFunction, localBasis, j);
312311
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;
317314

318-
Eigen::Matrix<ScalarType, worlddim,worlddim> kgMembraneIJ
315+
Eigen::Matrix<ScalarType, worlddim, worlddim> kgMembraneIJ
319316
= 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);
321319
KBlock += kgMembraneIJ * intElement;
322320
KBlock += kgBendingIJ * intElement;
323321
}

ikarus/finiteelements/mechanics/membranestrains.hh

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,21 @@
1111

1212
#include <dune/common/fvector.hh>
1313

14-
1514
#include <Eigen/Core>
1615
namespace Ikarus {
1716

1817
struct DefaultMembraneStrain {
19-
2018
/**
21-
* \brief Compute the strain vector at a given integration point.
22-
*
23-
* \param gpPos The position of the integration point.
24-
* \param geo The geometry object providing the transposed Jacobian.
25-
* \param uFunction The function representing the displacement field.
26-
*
27-
* \tparam Geometry The type of the geometry object.
28-
*
29-
* \return The strain vector at the given integration point.
30-
*/
19+
* \brief Compute the strain vector at a given integration point.
20+
*
21+
* \param gpPos The position of the integration point.
22+
* \param geo The geometry object providing the transposed Jacobian.
23+
* \param uFunction The function representing the displacement field.
24+
*
25+
* \tparam Geometry The type of the geometry object.
26+
*
27+
* \return The strain vector at the given integration point.
28+
*/
3129
template <typename Geometry>
3230
auto value(const Dune::FieldVector<double, 2> &gpPos, const Geometry &geo, const auto &uFunction) const
3331
-> Eigen::Vector3<typename std::remove_cvref_t<decltype(uFunction)>::ctype> {
@@ -47,21 +45,21 @@ namespace Ikarus {
4745
}
4846

4947
/**
50-
* \brief Compute the strain-displacement matrix for a given node and integration point.
51-
*
52-
* \param gpPos The position of the integration point.
53-
* \param jcur The Jacobian matrix.
54-
* \param dNAtGp The derivative of the shape functions at the integration point.
55-
* \param geo The geometry object of the finite element.
56-
* \param uFunction The function representing the displacement field.
57-
* \param localBasis The local basis object.
58-
* \param node The FE node index.
59-
*
60-
* \tparam Geometry The type of the geometry object.
61-
* \tparam ScalarType The scalar type for the matrix elements.
62-
*
63-
* \return The strain-displacement matrix for the given node and integration point.
64-
*/
48+
* \brief Compute the strain-displacement matrix for a given node and integration point.
49+
*
50+
* \param gpPos The position of the integration point.
51+
* \param jcur The Jacobian matrix.
52+
* \param dNAtGp The derivative of the shape functions at the integration point.
53+
* \param geo The geometry object of the finite element.
54+
* \param uFunction The function representing the displacement field.
55+
* \param localBasis The local basis object.
56+
* \param node The FE node index.
57+
*
58+
* \tparam Geometry The type of the geometry object.
59+
* \tparam ScalarType The scalar type for the matrix elements.
60+
*
61+
* \return The strain-displacement matrix for the given node and integration point.
62+
*/
6563
template <typename Geometry, typename ScalarType>
6664
auto derivative(const Dune::FieldVector<double, 2> &gpPos, const Eigen::Matrix<ScalarType, 2, 3> &jcur,
6765
const auto &dNAtGp, const Geometry &geo, const auto &uFunction, const auto &localBasis,
@@ -75,23 +73,24 @@ namespace Ikarus {
7573
}
7674

7775
/**
78-
* \brief Compute the second derivative of the membrane strain for a given node pair and integration point.
79-
* \details This function computes the geometric tangent stiffness for a given node pair at a given integration point.
80-
*
81-
* \param gpPos The position of the integration point.
82-
* \param dNAtGp The derivative of the shape functions at the integration point.
83-
* \param geo The geometry object.
84-
* \param uFunction The function representing the displacement field.
85-
* \param localBasis The local basis object.
86-
* \param S The strain vector.
87-
* \param I The index of the first node.
88-
* \param J The index of the second node.
89-
*
90-
* \tparam Geometry The type of the geometry object.
91-
* \tparam ScalarType The scalar type for the matrix elements.
92-
*
93-
* \return The second derivative of the membrane strain.
94-
*/
76+
* \brief Compute the second derivative of the membrane strain for a given node pair and integration point.
77+
* \details This function computes the geometric tangent stiffness for a given node pair at a given integration
78+
* point.
79+
*
80+
* \param gpPos The position of the integration point.
81+
* \param dNAtGp The derivative of the shape functions at the integration point.
82+
* \param geo The geometry object.
83+
* \param uFunction The function representing the displacement field.
84+
* \param localBasis The local basis object.
85+
* \param S The strain vector.
86+
* \param I The index of the first node.
87+
* \param J The index of the second node.
88+
*
89+
* \tparam Geometry The type of the geometry object.
90+
* \tparam ScalarType The scalar type for the matrix elements.
91+
*
92+
* \return The second derivative of the membrane strain.
93+
*/
9594
template <typename Geometry, typename ScalarType>
9695
auto secondDerivative(const Dune::FieldVector<double, 2> &gpPos, const auto &dNAtGp, const Geometry &geo,
9796
const auto &uFunction, const auto &localBasis, const Eigen::Vector3<ScalarType> &S, int I,

ikarus/finiteelements/mechanics/nonlinearelastic.hh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,7 @@ namespace Ikarus {
333333
const auto u = uFunction.evaluate(quadPos);
334334

335335
// Value of the Neumann data at the current position
336-
const auto neumannValue
337-
= neumannBoundaryLoad(intersection.geometry().global(curQuad.position()), lambda);
336+
const auto neumannValue = neumannBoundaryLoad(intersection.geometry().global(curQuad.position()), lambda);
338337
energy -= neumannValue.dot(u) * curQuad.weight() * intElement;
339338
}
340339
}
@@ -395,8 +394,7 @@ namespace Ikarus {
395394
const auto udCi = u.evaluateDerivative(quadPos, wrt(coeff(i)));
396395

397396
// Value of the Neumann data at the current position
398-
const auto neumannValue
399-
= neumannBoundaryLoad(intersection.geometry().global(curQuad.position()), lambda);
397+
const auto neumannValue = neumannBoundaryLoad(intersection.geometry().global(curQuad.position()), lambda);
400398
force.template segment<myDim>(myDim * i) -= udCi * neumannValue * curQuad.weight() * intElement;
401399
}
402400
}

tests/src/checkfebyautodiff.hh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
// SPDX-FileCopyrightText: 2021-2024 The Ikarus Developers [email protected]
22
// SPDX-License-Identifier: LGPL-3.0-or-later
33

4-
54
#pragma once
65
#include <dune/common/test/testsuite.hh>
6+
#include <ikarus/utils/basis.hh>
7+
#include <ikarus/finiteelements/febases/autodifffe.hh>
8+
#include <Eigen/Core>
79

8-
template <template<typename ,typename > class FE, typename GridView,typename PreBasis, typename... ElementArgsType>
9-
auto checkFEByAutoDiff( const GridView& gridView, const PreBasis& pb,const ElementArgsType&... eleArgs) {
10-
11-
using namespace Dune::Functions::BasisFactory;
10+
template <template <typename...> class FE, typename GridView, typename PreBasis, typename... ElementArgsType>
11+
auto checkFEByAutoDiff(const GridView& gridView, const PreBasis& pb, const ElementArgsType&... eleArgs) {
1212
auto basis = Ikarus::makeBasis(gridView, pb);
1313
auto element = gridView.template begin<0>();
1414
auto nDOF = basis.flat().size();
1515
const double tol = 1e-10;
1616

17-
FE fe(basis,*element,eleArgs...);
17+
FE fe(basis, *element, eleArgs...);
1818

1919
const std::string feClassName = Dune::className(fe);
2020
Dune::TestSuite t("Check calculateScalarImpl() and calculateVectorImpl() by Automatic Differentiation for gridDim = "
21-
+ feClassName);
22-
using AutoDiffBasedFE = Ikarus::AutoDiffFE<decltype(fe)>;
21+
+ feClassName);
22+
using AutoDiffBasedFE = Ikarus::AutoDiffFE<decltype(fe),typename decltype(fe)::FERequirementType,false,true>;
2323
AutoDiffBasedFE feAutoDiff(fe);
2424

2525
Eigen::VectorXd d;

0 commit comments

Comments
 (0)