Alamo
Solid.H
Go to the documentation of this file.
1//
2// Solid models are used with the :ref:`Integrator::Mechanics` integrator, which
3// implements the :ref:`Solver::Nonlocal::Newton` elasticity solver.
4// All solid models inherit from the :code:`Model::Solid` base class, which requires
5// all of the necessary components to be used in a mechanics solve.
6// Model classes have basically two functions:
7//
8// #. Provide energy (W), stress (DW), and modulus (DDW) based on a kinematic variable
9// #. Evolve internal variables in time.
10//
11
12#ifndef MODEL_SOLID_H_
13#define MODEL_SOLID_H_
14
15#include <AMReX.H>
16#include <AMReX_REAL.H>
17#include <eigen3/Eigen/Core>
18
19#include "Set/Set.H"
20
21namespace Model
22{
23namespace Solid
24{
25
27
28template<Set::Sym SYM>
29class Solid
30{
31public:
32 Solid() {} ;
33
34 virtual ~Solid() {};
35
36 static constexpr Set::Sym sym = SYM;
37
38 virtual Set::Scalar W(const Set::Matrix &) const
39 {Util::Abort(INFO,"W not implemented"); return 0.0;};
40 virtual Set::Matrix DW(const Set::Matrix &) const
41 {Util::Abort(INFO,"DW not implemented"); return Set::Matrix::Zero();};
43 {Util::Abort(INFO,"DDW not implemented"); return Set::Matrix4<AMREX_SPACEDIM,SYM>::Zero();};
44
45 virtual void Advance(Set::Scalar /*dt*/, Set::Matrix /*strain*/, Set::Matrix /*stress*/, Set::Scalar /*time*/) {}
46
47 // Todo: implement for all models and make this pure virtual
48 virtual bool ContainsNan() {return true;};
49
50
51public:
53
54
55 friend std::ostream& operator<<(std::ostream &out, const Solid &a)
56 {
57 a.Print(out);
58 return out;
59 }
60 virtual void Print(std::ostream &out) const
61 {
62 out << "No print function written for this model.";
63 }
64
65public:
66 template <class T>
67 static int ArithmeticTest(int verbose = 0)
68 {
69 const T z = T::Zero();
70 if (!(z==z) && verbose)
71 {
72 Util::Message(INFO,"Zero() failed: z = \n",z); return 1;
73 }
74
75 const T a = T::Random();
76 if (!(a==a) && verbose)
77 {
78 Util::Message(INFO,"Random() failed: a = \n",a); return 1;
79 }
80
81 const T b = T::Random();
82
83 T c = a;
84 if (!(c==a) && verbose) {Util::Message(INFO); return 1;}
85 c = 1.0 * a;
86 if (!(c==a) && verbose) {Util::Message(INFO); return 1;}
87 c = 0.0 * a;
88 if (!(c==z) && verbose)
89 {
90 Util::Message(INFO,"0.0*a = \n",c);
91 Util::Message(INFO,"Zero() returns \n",z);
92 return 1;
93 }
94
95 // Todo: add some more arithmetic checks in here
96
97 return 0;
98 }
99
100 template <class T>
101 static int DerivativeTest1(int verbose = 0)
102 {
103 for (int iter = 0; iter < 10; iter++)
104 {
105 T model = T::Random();
106
107 Set::Scalar dx = 1E-8, tol = 1E-6;
108
109 Set::Matrix F = Set::Matrix::Random();
110 while (F.determinant() < 0.1) F = Set::Matrix::Random(); // Ensure that F in GL(3)
111
112 Set::Matrix dw_exact = model.DW(F);
113 Set::Matrix dw_numeric = Set::Matrix::Zero();
114 for (int i = 0; i < AMREX_SPACEDIM; i++)
115 for (int j = 0; j < AMREX_SPACEDIM; j++)
116 {
117 Set::Matrix dF = Set::Matrix::Zero();
118 dF(i,j) = dx;
119 dw_numeric(i,j) = (model.W(F+dF) - model.W(F-dF)) / (2.0 * dx);
120 }
121 Set::Scalar relnorm = (dw_numeric-dw_exact).norm()/(dw_numeric.norm());
122 if (relnorm > tol || std::isnan(relnorm) || std::isinf(relnorm))
123 {
124 if (verbose)
125 {
126 Util::Message(INFO,"F \n",F);
127 Util::Message(INFO,"det(F) = ",F.determinant());
128 Util::Message(INFO,"dw exact \n",dw_exact);
129 Util::Message(INFO,"dw numeric \n",dw_numeric);
130 Util::Message(INFO,"error norm \n",relnorm);
131 }
132 return 1;
133 }
134 }
135 return 0;
136 }
137
138 template <class T>
139 static int DerivativeTest2(int verbose = 0)
140 {
141 for (int iter = 0; iter < 10; iter++)
142 {
143 T model = T::Random();
144
145 Set::Scalar dx = 1E-8, tol = 1E-4;
146 Set::Matrix F = Set::Matrix::Random();
147 while (F.determinant() < 0.1) F = Set::Matrix::Random(); // Ensure that F in GL(3)
148
149 Set::Matrix4<AMREX_SPACEDIM,Set::Sym::Major> ddw_exact = model.DDW(F);
151 for (int i = 0; i < AMREX_SPACEDIM; i++)
152 for (int j = 0; j < AMREX_SPACEDIM; j++)
153 for (int k = 0; k < AMREX_SPACEDIM; k++)
154 for (int l = 0; l < AMREX_SPACEDIM; l++)
155 {
156 Set::Matrix dF = Set::Matrix::Zero();
157 dF(k,l) = dx;
158 ddw_numeric(i,j,k,l) = (model.DW(F+dF) - model.DW(F-dF))(i,j) / (2.0 * dx);
159 }
160 Set::Matrix4<AMREX_SPACEDIM,Set::Sym::Major> error = ddw_numeric-ddw_exact;
161 Set::Scalar relnorm = error.Norm()/ddw_numeric.Norm();
162 if (relnorm > tol || std::isnan(relnorm) || std::isinf(relnorm))
163 {
164 if (verbose)
165 {
166 Util::Message(INFO,"F \n",F);
167 Util::Message(INFO,"det(F) = ",F.determinant());
168 Util::Message(INFO,"ddw exact \n",ddw_exact);
169 Util::Message(INFO,"ddw numeric \n",ddw_numeric);
170 Util::Message(INFO,"ddw difference \n",ddw_exact - ddw_numeric);
171 Util::Message(INFO,"error norm \n",relnorm);
172 }
173 return 1;
174 }
175 }
176 return 0;
177 }
178
179 template <class T>
180 static int MaterialFrameIndifference(int verbose = 0)
181 {
182 if (T::kinvar != Model::Solid::KinematicVariable::F)
183 Util::Abort(INFO,"Attempting to test material frame indifference in a non-finite-kinematics model will fail");
184
185 for (int iter = 0; iter < 10; iter++)
186 {
187 T model = T::Random();
188
189 Set::Scalar tol = 1E-4;
190 Set::Matrix F = Set::Matrix::Random();
191 while (
192 F.determinant() < 0.5 || // skip if determinant negative or too small
193 F.determinant() > 2 // also skip if determinant too large
194 )
195 F = Set::Matrix::Random(); // Ensure that F is reasonably well-behaved.
196
197 Set::Scalar W_unrotated = model.W(F);
198
199 for (int jter = 0; jter < 10; jter++)
200 {
201 #if AMREX_SPACEDIM == 2
203 Set::Matrix R;
204 R(0,0) = cos(theta);
205 R(0,1) = sin(theta);
206 R(1,0) = -sin(theta);
207 R(1,1) = cos(theta);
208 #elif AMREX_SPACEDIM == 3
209 Set::Scalar phi1 = 2.0 * Set::Constant::Pi *(Util::Random() - 0.5);
211 Set::Scalar phi2 = 2.0 * Set::Constant::Pi *(Util::Random() - 0.5);
212 Eigen::Matrix3d R;
213 R = Eigen::AngleAxisd(phi2, Eigen::Vector3d::UnitX()) *
214 Eigen::AngleAxisd(Phi, Eigen::Vector3d::UnitZ()) *
215 Eigen::AngleAxisd(phi1, Eigen::Vector3d::UnitX());
216 #endif
217
218 Util::Assert(INFO,TEST( fabs(R.determinant() - 1.0) < tol ));
219 Util::Assert(INFO,TEST( fabs((R.transpose() * R - Set::Matrix::Identity()).norm()) < tol ));
220
221 Set::Scalar W_rotated = model.W(R*F);
222 Set::Scalar error = fabs(W_rotated - W_unrotated) / fabs(W_rotated + W_unrotated + tol);
223
224 if (error > tol)
225 {
226 if (verbose)
227 {
228 Util::Message(INFO,"F = \n",F);
229 Util::Message(INFO,"R = \n",R);
230 Util::Message(INFO,"W unrotated = ",W_unrotated);
231 Util::Message(INFO,"W rotated = ",W_rotated);
232 }
233 return 1;
234 }
235 }
236 }
237 return 0;
238 }
239
240};
241
242}
243}
244
245
246#endif
#define TEST(x)
Definition Util.H:21
#define INFO
Definition Util.H:20
static int MaterialFrameIndifference(int verbose=0)
Definition Solid.H:180
virtual void Print(std::ostream &out) const
Definition Solid.H:60
virtual bool ContainsNan()
Definition Solid.H:48
virtual void Advance(Set::Scalar, Set::Matrix, Set::Matrix, Set::Scalar)
Definition Solid.H:45
virtual Set::Scalar W(const Set::Matrix &) const
Definition Solid.H:38
static int DerivativeTest2(int verbose=0)
Definition Solid.H:139
virtual Set::Matrix DW(const Set::Matrix &) const
Definition Solid.H:40
virtual Set::Matrix4< AMREX_SPACEDIM, SYM > DDW(const Set::Matrix &) const
Definition Solid.H:42
static int ArithmeticTest(int verbose=0)
Definition Solid.H:67
friend std::ostream & operator<<(std::ostream &out, const Solid &a)
Definition Solid.H:55
virtual ~Solid()
Definition Solid.H:34
static const KinematicVariable kinvar
Definition Solid.H:52
static constexpr Set::Sym sym
Definition Solid.H:36
static int DerivativeTest1(int verbose=0)
Definition Solid.H:101
KinematicVariable
Definition Solid.H:26
static const Set::Scalar Pi
Definition Set.H:286
Sym
Definition Base.H:197
amrex::Real Scalar
Definition Base.H:19
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:20
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, AMREX_SPACEDIM > Matrix
Definition Base.H:23
void Abort(const char *msg)
Definition Util.cpp:170
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition Util.H:70
Set::Scalar Random()
Definition Set.cpp:9
void Message(std::string file, std::string func, int line, Args const &... args)
Definition Util.H:141