Alamo
NeoHookean.H
Go to the documentation of this file.
1#ifndef MODEL_SOLID_FINITE_NEOHOOKEAN_H_
2#define MODEL_SOLID_FINITE_NEOHOOKEAN_H_
3
4#include "IO/ParmParse.H"
5#include "Model/Solid/Solid.H"
6#include "Unit/Unit.H"
7
8namespace Model
9{
10namespace Solid
11{
12namespace Finite
13{
14class NeoHookean : public Solid<Set::Sym::Major>
15{
16public:
17 AMREX_GPU_HOST_DEVICE NeoHookean() = default;
18 AMREX_GPU_HOST_DEVICE
19 NeoHookean(Solid<Set::Sym::Major> base) : Solid<Set::Sym::Major>(base) {};
20 ~NeoHookean() = default;
21
22 AMREX_GPU_HOST_DEVICE
23 Set::Scalar W(const Set::Matrix& a_F) const
24 {
25#if AMREX_SPACEDIM==2
26 Eigen::Matrix3d F = Eigen::Matrix3d::Identity();
27 F(0, 0) = a_F(0, 0);
28 F(0, 1) = a_F(0, 1);
29 F(1, 0) = a_F(1, 0);
30 F(1, 1) = a_F(1, 1);
31#elif AMREX_SPACEDIM==3
32 Eigen::Matrix3d F = a_F;
33#endif
34
35 Set::Scalar J = F.determinant();
36 Set::Scalar J23 = std::pow(fabs(J), 2. / 3.);
37 Set::Scalar w = 0.0;
38 w += 0.5 * mu * ((F * F.transpose()).trace() / J23 - 3.);
39 w += 0.5 * kappa * (J - 1.0) * (J - 1.0);
40 return w;
41 }
42 AMREX_GPU_HOST_DEVICE
43 Set::Matrix DW(const Set::Matrix& a_F) const
44 {
45#if AMREX_SPACEDIM==2
46 Eigen::Matrix3d F = Eigen::Matrix3d::Identity();
47 F(0, 0) = a_F(0, 0);
48 F(0, 1) = a_F(0, 1);
49 F(1, 0) = a_F(1, 0);
50 F(1, 1) = a_F(1, 1);
51#elif AMREX_SPACEDIM==3
52 Eigen::Matrix3d F = a_F;
53#endif
54
55 Set::Scalar J = F.determinant();
56 Set::Scalar J23 = std::pow(fabs(J), 2. / 3.);
57 Eigen::Matrix3d FinvT = F.inverse().transpose();
58
59 Eigen::Matrix3d dw = Eigen::Matrix3d::Zero();
60
61 dw += mu * (F / J23 - (F * F.transpose()).trace() * FinvT / (3. * J23));
62 dw += kappa * (J - 1) * J * FinvT;
63
64#if AMREX_SPACEDIM==2
65 Set::Matrix r_dw;
66 r_dw(0, 0) = dw(0, 0);
67 r_dw(0, 1) = dw(0, 1);
68 r_dw(1, 0) = dw(1, 0);
69 r_dw(1, 1) = dw(1, 1);
70 return r_dw;
71#elif AMREX_SPACEDIM==3
72 return dw;
73#endif
74 }
75 AMREX_GPU_HOST_DEVICE
77 {
78#if AMREX_SPACEDIM==2
79 Eigen::Matrix3d F = Eigen::Matrix3d::Identity();
80 F(0, 0) = a_F(0, 0);
81 F(0, 1) = a_F(0, 1);
82 F(1, 0) = a_F(1, 0);
83 F(1, 1) = a_F(1, 1);
84#elif AMREX_SPACEDIM==3
85 Eigen::Matrix3d F = a_F;
86#endif
87
89 Set::Scalar J = F.determinant();
90 Set::Scalar J23 = std::pow(fabs(J), 2. / 3.);
91 Eigen::Matrix3d FinvT = F.inverse().transpose();
92 for (int i = 0; i < 3; i++)
93 for (int j = 0; j < 3; j++)
94 for (int k = 0; k < 3; k++)
95 for (int l = 0; l < 3; l++)
96 {
97 ddw(i, j, k, l) = 0.0;
98
99 Set::Scalar t1 = 0.0, t2 = 0.0;
100
101 if (i == k && j == l) t1 += 1.0;
102 t1 -= (2. / 3.) * F(i, j) * FinvT(k, l);
103 t1 -= (2. / 3.) * FinvT(i, j) * F(k, l);
104 t1 += (2. / 9.) * (F * F.transpose()).trace() * FinvT(i, j) * FinvT(k, l);
105 t1 += (1. / 3.) * (F * F.transpose()).trace() * FinvT(i, l) * FinvT(k, j);
106
107 t2 += (2. * J - 1.) * FinvT(i, j) * FinvT(k, l);
108 t2 += (1. - J) * FinvT(i, l) * FinvT(k, j);
109
110 ddw(i, j, k, l) = (mu / J23) * t1 + kappa * J * t2;
111 }
112#if AMREX_SPACEDIM==2
114 for (int i = 0; i < 2; i++)
115 for (int j = 0; j < 2; j++)
116 for (int k = 0; k < 2; k++)
117 for (int l = 0; l < 2; l++)
118 r_ddw(i, j, k, l) = ddw(i, j, k, l);
119 return r_ddw;
120#elif AMREX_SPACEDIM==3
121 return ddw;
122#endif
123 }
124 void Print(std::ostream& out) const
125 {
126 out << "mu = " << mu << " kappa = " << kappa;
127 }
128
129public:
130 Set::Scalar mu = NAN, kappa = NAN;
132
133public:
135 {
136 NeoHookean ret;
137 ret.mu = 0.0;
138 ret.kappa = 0.0;
139 return ret;
140 }
142 {
143 NeoHookean ret;
144 ret.mu = Util::Random();
145 ret.kappa = Util::Random();
146 return ret;
147 }
148 static void Parse(NeoHookean& value, IO::ParmParse& pp)
149 {
150
151 std::pair<std::string, Set::Scalar> moduli[2];
152
153 pp.forbid("lame","Use 'lambda' instead for lame constant");
154 pp.forbid("shear","Use 'mu' instead for shear modulus");
155 pp.forbid("bulk","Use 'K' instead for bulk modulus");
156
157 // Lame constant \‍(\lambda\‍),
158 // shear modulus \‍(\mu\‍), Young's modulus \‍(E\‍), Poisson's ratio \‍(\nu\‍),
159 // bulk modulus \‍(K\‍).
160 // You can currently specify (mu and kappa), (lambda and mu), or (E and nu).
161 // std::vector{Unit::Pressure, Unit::Pressure, Unit::Pressure, Unit::Less, Unit::Pressure};
162 pp.query_exactly<2>({"lambda","mu","E","nu","kappa"}, moduli, std::vector<Unit>{Unit::Pressure(), Unit::Pressure(), Unit::Pressure(), Unit::Less(), Unit::Pressure()});
163
164
165 if (moduli[0].first == "mu" && moduli[1].first == "kappa")
166 {
167 value.mu = moduli[0].second;
168 value.kappa = moduli[1].second;
169 }
170 else if (moduli[0].first == "lambda" && moduli[1].first == "mu")
171 {
172 Set::Scalar lambda = moduli[0].second;
173 value.mu = moduli[1].second;
174 value.kappa = lambda + (2.0 * value.mu) / 3.0;
175 }
176 else if (pp.contains("E") && pp.contains("nu")) {
177 Set::Scalar E = moduli[0].second;
178 Set::Scalar nu = moduli[1].second;
179 value.kappa = E / (3.0 - 6.0 * nu);
180 value.mu = E / (2.0 + 2.0 * nu);
181 }
182 else
183 {
184 Util::Exception(INFO,"Haven't implemented",moduli[0].first," and ",moduli[1].first," yet (sorry!)");
185 }
186 }
187
188#define OP_CLASS NeoHookean
189#define OP_VARS X(kappa) X(mu)
191};
193
194}
195}
196}
197
198#endif
#define INFO
Definition Util.H:24
void forbid(std::string name, std::string explanation, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:301
void query_exactly(std::vector< std::string > names, std::pair< std::string, Set::Scalar > values[N], std::vector< Unit > units=std::vector< Unit >(), const std::source_location &location=std::source_location::current())
Definition ParmParse.H:2326
bool contains(std::string name, const std::source_location &location=std::source_location::current())
Definition ParmParse.H:318
AMREX_GPU_HOST_DEVICE Set::Scalar W(const Set::Matrix &a_F) const
Definition NeoHookean.H:23
static void Parse(NeoHookean &value, IO::ParmParse &pp)
Definition NeoHookean.H:148
static constexpr KinematicVariable kinvar
Definition NeoHookean.H:131
AMREX_GPU_HOST_DEVICE NeoHookean(Solid< Set::Sym::Major > base)
Definition NeoHookean.H:19
AMREX_GPU_HOST_DEVICE Set::Matrix DW(const Set::Matrix &a_F) const
Definition NeoHookean.H:43
void Print(std::ostream &out) const
Definition NeoHookean.H:124
AMREX_GPU_HOST_DEVICE Set::Matrix4< AMREX_SPACEDIM, Set::Sym::Major > DDW(const Set::Matrix &a_F) const
Definition NeoHookean.H:76
AMREX_GPU_HOST_DEVICE NeoHookean()=default
KinematicVariable
Definition Solid.H:34
A collection of data types and symmetry-reduced data structures.
Definition Base.H:18
amrex::Real Scalar
Definition Base.H:19
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:21
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, AMREX_SPACEDIM > Matrix
Definition Base.H:24
Set::Scalar Random()
Definition Set.cpp:34
void Exception(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:237
static Unit Pressure()
Definition Unit.H:217
static Unit Less()
Definition Unit.H:197