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 
21 namespace Model
22 {
23 namespace Solid
24 {
25 
27 
28 template<Set::Sym SYM>
29 class Solid
30 {
31 public:
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 
51 public:
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 
65 public:
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 
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;
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;
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
202  Set::Scalar theta = 2.0 * Set::Constant::Pi * Util::Random();
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
Model::Solid::gradu
@ gradu
Definition: Solid.H:26
Model::Solid::Solid::MaterialFrameIndifference
static int MaterialFrameIndifference(int verbose=0)
Definition: Solid.H:180
Set::Sym
Sym
Definition: Base.H:197
Model::Solid::Solid::ArithmeticTest
static int ArithmeticTest(int verbose=0)
Definition: Solid.H:67
TEST
#define TEST(x)
Definition: Util.H:21
Model::Solid::Solid::DDW
virtual Set::Matrix4< AMREX_SPACEDIM, SYM > DDW(const Set::Matrix &) const
Definition: Solid.H:42
Model::Solid::Solid::sym
static constexpr Set::Sym sym
Definition: Solid.H:36
Model::Solid::Solid::W
virtual Set::Scalar W(const Set::Matrix &) const
Definition: Solid.H:38
Model::Solid::Solid::operator<<
friend std::ostream & operator<<(std::ostream &out, const Solid &a)
Definition: Solid.H:55
Util::Random
Set::Scalar Random()
Definition: Set.cpp:9
Set::Scalar
amrex::Real Scalar
Definition: Base.H:19
Set::Matrix
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, AMREX_SPACEDIM > Matrix
Definition: Base.H:23
Model::Solid::Solid::Print
virtual void Print(std::ostream &out) const
Definition: Solid.H:60
Model::Solid::Solid::DerivativeTest2
static int DerivativeTest2(int verbose=0)
Definition: Solid.H:139
Model::Solid::Solid::ContainsNan
virtual bool ContainsNan()
Definition: Solid.H:48
Model::Solid::epsilon
@ epsilon
Definition: Solid.H:26
Model::Solid::Solid::Advance
virtual void Advance(Set::Scalar, Set::Matrix, Set::Matrix, Set::Scalar)
Definition: Solid.H:45
Util::Assert
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition: Util.H:65
Model::Solid::Solid::Solid
Solid()
Definition: Solid.H:32
Util::Abort
void Abort(const char *msg)
Definition: Util.cpp:165
Model::Solid::Solid
Definition: Solid.H:29
Set::Matrix4< AMREX_SPACEDIM, SYM >
Model::Solid::Solid::DW
virtual Set::Matrix DW(const Set::Matrix &) const
Definition: Solid.H:40
Set.H
Set::Constant::Pi
static const Set::Scalar Pi
Definition: Set.H:286
Model::Solid::Solid::~Solid
virtual ~Solid()
Definition: Solid.H:34
Model::Solid::KinematicVariable
KinematicVariable
Definition: Solid.H:26
Model::Solid::Solid::kinvar
static const KinematicVariable kinvar
Definition: Solid.H:52
INFO
#define INFO
Definition: Util.H:20
Model
Definition: Constant.H:12
Set::Matrix3d
Eigen::Matrix3d Matrix3d
Definition: Base.H:24
Model::Solid::F
@ F
Definition: Solid.H:26
Util::Message
void Message(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:133
Model::Solid::Solid::DerivativeTest1
static int DerivativeTest1(int verbose=0)
Definition: Solid.H:101