Alamo
Matrix4_Isotropic.H
Go to the documentation of this file.
1//
2// The isotropic tensor is defined to be
3//
4// .. math::
5//
6// C_{ijkl} = \mu(d_{il}d_{jk} + d_{ik}d_{jl}) + \lambda d_{ij} d_{kl}
7//
8// The inverse ("compliance") tensor is
9//
10// .. math::
11//
12// S_{ijkl} = ((1+\nu)/2E)(d_{il}d_{jl} + d_{ik}d_{jl}) - (\nu/E)d_{ij}d_{kl}
13//
14// Replacing E, nu with Lame constants gives:
15//
16// .. math::
17//
18// S_{ijkl} = (1/(4 \mu))(d_{il}d_{jl} + d_{ik}d_{jl}) + (\lambda/(2*\mu*(3\lambda+2\mu))) * d_{ij} * d_{kl}
19//
20// For reference: http://solidmechanics.org/text/Chapter3_2/Chapter3_2.htm
21// https://en.wikipedia.org/wiki/Lam%C3%A9_parameters
22//
23
24#ifndef SET_MATRIX4_ISOTROPIC_H
25#define SET_MATRIX4_ISOTROPIC_H
26
27#include "AMReX_Config.H"
28#include "Util/Util.H"
29#include "Set/Set.H"
30#include "Set/Base.H"
31#include "Matrix3.H"
32#include "Matrix4.H"
33
34namespace Set
35{
36template<>
38{
39 Set::Scalar lambda=NAN, mu=NAN;
40public:
43
44 /// Note: for the Isotropic Matrix4 this routine works for **retrieval only**!
45 /// If you try to assign a value using this with, say
46 ///
47 /// isotropicmatrix4(i,j,k,l) = 8.0
48 ///
49 /// you will get a `lvalue required as left operand of assignment` compile error.
50 /// You should probably consider using a lower symmetry operator.
52 Scalar operator () (const int i, const int j, const int k, const int l) const
53 {
54 Set::Scalar ret = 0.0;
55 if (i==k && j==l) ret += mu;
56 if (i==l && j==k) ret += mu;
57 if (i==j && k==l) ret += lambda;
58 return ret;
59 }
60 void Randomize()
61 {
62 lambda = Util::Random();
63 mu = Util::Random();
64 }
71 void Print (std::ostream& os )
72 {
73 os << "lambda = " << lambda << " mu = " << mu;
74 }
76 {
77 return lambda;
78 }
79 Set::Scalar Mu () const
80 {
81 return mu;
82 }
84 {
85 return mu * ( 3.0*lambda + 2.0*mu ) / (lambda + mu);
86 }
88 {
89 return 0.5 * lambda / (lambda + mu);
90 }
98
99
101 {
103 inv.mu = 1./4./mu;
104 inv.lambda = lambda / (2*mu*(3*lambda + 2*mu));
105 return inv;
106 }
116
117 //AMREX_GPU_HOST_DEVICE void operator = (Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda = a.lambda; mu = a.mu;}
118 AMREX_GPU_HOST_DEVICE void operator += (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda += a.lambda; mu += a.mu;}
119 AMREX_GPU_HOST_DEVICE void operator -= (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda -= a.lambda; mu -= a.mu;}
120 AMREX_GPU_HOST_DEVICE void operator *= (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda *= a.lambda; mu *= a.mu;}
121 AMREX_GPU_HOST_DEVICE void operator /= (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda /= a.lambda; mu /= a.mu;}
122 AMREX_GPU_HOST_DEVICE void operator *= (const Set::Scalar &alpha) {lambda *= alpha; mu *= alpha;}
123 AMREX_GPU_HOST_DEVICE void operator /= (const Set::Scalar &alpha) {lambda /= alpha; mu /= alpha;}
124
126 {
127 return std::sqrt(lambda*lambda + mu*mu);
128 }
129
130 bool contains_nan() const
131 {
132 if (std::isnan(lambda)) return true;
133 if (std::isnan(mu)) return true;
134 return false;
135 }
136};
139{
141
142 #if AMREX_SPACEDIM == 2
143 ret(0,0) = (a.lambda + 2.*a.mu) * b(0,0) + a.lambda *b(1,1);
144 ret(1,1) = a.lambda * b(0,0) + (a.lambda + 2.*a.mu)*b(1,1);
145 ret(0,1) = a.mu*(b(0,1) + b(1,0)); ret(1,0) = ret(0,1);
146
147 #elif AMREX_SPACEDIM == 3
148 ret(0,0) = (a.lambda + 2.*a.mu) * b(0,0) + a.lambda *b(1,1) + a.lambda *b(2,2);
149 ret(1,1) = a.lambda * b(0,0) + (a.lambda + 2.*a.mu)*b(1,1) + a.lambda *b(2,2);
150 ret(2,2) = a.lambda * b(0,0) + a.lambda *b(1,1) + (a.lambda + 2.*a.mu)*b(2,2);
151 ret(1,2) = a.mu*(b(1,2) + b(2,1)); ret(2,1) = ret(1,2);
152 ret(2,0) = a.mu*(b(2,0) + b(0,2)); ret(0,2) = ret(2,0);
153 ret(0,1) = a.mu*(b(0,1) + b(1,0)); ret(1,0) = ret(0,1);
154
155 #endif
156 return ret;
157}
161
162
165{
166 Set::Vector ret = Set::Vector::Zero();
167
168 for (int i = 0; i < AMREX_SPACEDIM; i++)
169 for (int j=0; j < AMREX_SPACEDIM; j++)
170 ret(i) += a.mu*(b(i,j,j) + b(j,i,j)) + a.lambda*b(j,j,i);
171
172 return ret;
173}
174
177{
178 Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;// = Set::Vector::Zero();
179 ret.mu = a.mu * b;
180 ret.lambda = a.lambda * b;
181 return ret;
182}
185{
186 Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;// = Set::Vector::Zero();
187 ret.mu = a.mu / b;
188 ret.lambda = a.lambda / b;
189 return ret;
190}
196
199{
200 if (a.mu != b.mu) return false;
201 if (a.lambda != b.lambda) return false;
202 return true;
203}
206{
207 Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;// = Set::Vector::Zero();
208 ret.mu = a.mu + b.mu;
209 ret.lambda = a.lambda + b.lambda;
210 return ret;
211}
212
222
223
224}
225#endif
Matrix< _Scalar, _Rows, _Cols > & operator*=(const amrex::Vector< amrex::Real > &x)
Definition Eigen_Amrex.H:18
AMREX_FORCE_INLINE void operator+=(const OP_CLASS &rhs)
AMREX_GPU_HOST_DEVICE Matrix4(Set::Scalar a_lambda, Set::Scalar a_mu)
Matrix4< AMREX_SPACEDIM, Sym::Isotropic > Inverse() const
static Matrix4< AMREX_SPACEDIM, Sym::Isotropic > Zero()
static Matrix4< AMREX_SPACEDIM, Sym::Isotropic > Random()
A collection of data types and symmetry-reduced data structures.
Definition Base.H:17
AMREX_FORCE_INLINE Quaternion operator-(const Quaternion a, const Quaternion b)
Definition Base.H:99
Sym
Definition Matrix4.H:12
@ Isotropic
Definition Matrix4.H:12
amrex::Real Scalar
Definition Base.H:18
AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Matrix4< AMREX_SPACEDIM, Sym::Diagonal > operator/(const Matrix4< AMREX_SPACEDIM, Sym::Diagonal > &a, const Set::Scalar &b)
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:19
AMREX_FORCE_INLINE bool operator==(const Quaternion a, const Quaternion b)
Definition Base.H:107
AMREX_FORCE_INLINE Quaternion operator+(const Quaternion a, const Quaternion b)
Definition Base.H:91
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, AMREX_SPACEDIM > Matrix
Definition Base.H:22
AMREX_FORCE_INLINE Quaternion operator*(const Set::Scalar alpha, const Quaternion b)
Definition Base.H:77
Set::Scalar Random()
Definition Set.cpp:34