GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/test/solidmechanics/hyperelastic_dynamic/problem.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 35 35 100.0%
Functions: 4 4 100.0%
Branches: 12 16 75.0%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 #ifndef DUMUX_DYNAMIC_HYPERELASTICITY_TEST_PROBLEM_HH
8 #define DUMUX_DYNAMIC_HYPERELASTICITY_TEST_PROBLEM_HH
9
10 #include <dumux/common/boundarytypes.hh>
11 #include <dumux/common/fvproblemwithspatialparams.hh>
12 #include <dumux/common/numeqvector.hh>
13 #include <dumux/common/parameters.hh>
14 #include <dumux/common/properties.hh>
15 #include <dumux/common/math.hh>
16
17 #include <dumux/experimental/timestepping/newmarkbeta.hh>
18
19 namespace Dumux {
20
21 // This test case corresponds to the CSM benchmark problem
22 // of a hyperelastic solid material under gravity given in
23 // Turek, S., Hron, J. (2006). "Proposal for Numerical Benchmarking of Fluid-Structure Interaction
24 // between an Elastic Object and Laminar Incompressible Flow."
25 // https://doi.org/10.1007/3-540-34596-5_15
26 template<class TypeTag>
27 class DynamicHyperelasticityProblem : public FVProblemWithSpatialParams<TypeTag>
28 {
29 using ParentType = FVProblemWithSpatialParams<TypeTag>;
30 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
31 using SubControlVolume = typename GridGeometry::SubControlVolume;
32 using GridView = typename GridGeometry::GridView;
33 using Element = typename GridView::template Codim<0>::Entity;
34 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
35 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
36 using NumEqVector = Dumux::NumEqVector<PrimaryVariables>;
37 using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>;
38 static constexpr int dim = GridView::dimension;
39 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
40 using Tensor = Dune::FieldMatrix<Scalar, dim, dim>;
41
42 using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
43
44 public:
45 1 DynamicHyperelasticityProblem(std::shared_ptr<const GridGeometry> gridGeometry)
46 : ParentType(gridGeometry)
47
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
3 , gravity_(getParam<Scalar>("Problem.Gravity"))
48 1 {}
49
50 /*!
51 * \brief Specifies which kind of boundary condition should be
52 * used for which equation on a given boundary control volume.
53 *
54 * \param globalPos The position of the center of the finite volume
55 */
56 212432 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
57 {
58
2/2
✓ Branch 0 taken 205900 times.
✓ Branch 1 taken 6532 times.
212432 BoundaryTypes values;
59 212432 const auto r = std::hypot(globalPos[0]-0.2, globalPos[1]-0.2);
60
2/2
✓ Branch 0 taken 205900 times.
✓ Branch 1 taken 6532 times.
212432 if (r < 0.05 + eps_)
61 {
62 6532 values.setDirichlet(0);
63 6532 values.setDirichlet(1);
64 }
65 else
66 212432 values.setAllNeumann();
67 212432 return values;
68 }
69
70 6532 PrimaryVariables dirichletAtPos(const GlobalPosition& globalPos) const
71 13064 { return PrimaryVariables(0.0); }
72
73 11468772 NumEqVector sourceAtPos(const GlobalPosition& globalPos) const
74 {
75 // gravity forcing
76 11468772 return {0.0, -this->spatialParams().solidDensity()*gravity_};
77 }
78
79 // Saint-Venant Kirchhoff material
80 11468772 Tensor firstPiolaKirchhoffStressTensor(const Tensor& F) const
81 {
82 // material parameters
83 11468772 const auto mu = this->spatialParams().shearModulus();
84 11468772 const auto lambda = this->spatialParams().firstLameParameter();
85
86 // Lagrangian Green strain E = 1/2*(F^T F - I)
87 11468772 auto E = multiplyMatrices(transpose(F), F);
88 11468772 E *= 0.5;
89 Scalar trace = 0.0;
90
2/2
✓ Branch 0 taken 22937544 times.
✓ Branch 1 taken 11468772 times.
34406316 for (int i = 0; i < dim; ++i)
91 {
92 22937544 E[i][i] -= 0.5;
93 22937544 trace += E[i][i];
94 }
95
96 // 2nd Piola Kirchhoff stress tensor S = λtr(E)I + 2µE
97 11468772 auto& S = E;
98 11468772 S *= 2*mu;
99
2/2
✓ Branch 0 taken 22937544 times.
✓ Branch 1 taken 11468772 times.
34406316 for (int i = 0; i < dim; ++i)
100 22937544 S[i][i] += lambda*trace;
101
102 // 1st Piola Kirchhoff stress tensor P = FS
103 11468772 return multiplyMatrices(F, S);
104 }
105
106 // the following methods are needed to solve structural dynamics
107 // with the Newmark-beta time integration scheme
108
109 // we use the Newmark scheme for time integration
110 1 void setNewmarkScheme(std::shared_ptr<const Experimental::NewmarkBeta<Scalar, SolutionVector>> newmark)
111
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 { newmark_ = std::move(newmark); }
112
113 // the effective density of the solid material
114 11468772 Scalar solidDensity(const Element&, const SubControlVolume&) const
115 11468772 { return this->spatialParams().solidDensity(); }
116
117 // the Newmark scheme is used for time integration and this
118 // computes the acceleration at the current time step for us
119 11468772 auto acceleration(const Element& element,
120 const SubControlVolume& scv,
121 const Scalar dt,
122 const PrimaryVariables& d) const
123 {
124 11468772 const auto dofIndex = scv.dofIndex();
125 11468772 return newmark_->acceleration(dofIndex, dt, d);
126 }
127
128 private:
129 static constexpr Scalar eps_ = 1e-7;
130 Scalar gravity_;
131
132 std::shared_ptr<const Experimental::NewmarkBeta<Scalar, SolutionVector>> newmark_;
133 };
134
135 } // end namespace Dumux
136
137 #endif
138