23 #include "libmesh/utility.h" 24 #include "libmesh/tensor_value.h" 25 #include "libmesh/vector_value.h" 43 return MooseEnum(
"symmetric9 symmetric21 symmetric_isotropic symmetric_isotropic_E_nu " 44 "axisymmetric_rz principal orthotropic");
50 mooseAssert(Ndim == 3,
51 "SymmetricRankFourTensorTempl<T> is designed to only work in 3 dimensions.");
69 case initIdentitySymmetricFour:
76 mooseError(
"Unknown SymmetricRankFourTensorTempl<T> initialization pattern.");
86 const auto &
idx = full_index[a][b];
92 (t(i, j, k, l) + t(j, i, l, k) + t(j, i, k, l) + t(i, j, l, k)) / 4 * mandelFactor(a, b);
104 const auto i = full_index[a][b][0];
105 const auto j = full_index[a][b][1];
106 const auto k = full_index[a][b][2];
107 const auto l = full_index[a][b][3];
110 r(i, j, k, l) = q(a, b) / mandelFactor(a, b);
111 r(j, i, k, l) = q(a, b) / mandelFactor(a, b);
112 r(i, j, l, k) = q(a, b) / mandelFactor(a, b);
113 r(j, i, l, k) = q(a, b) / mandelFactor(a, b);
119 template <
typename T>
123 fillFromInputVector(input, fill_method);
126 template <
typename T>
130 std::fill(_vals.begin(), _vals.end(), 0.0);
133 template <
typename T>
138 const static std::array<std::size_t, 3> a = {{1, 0, 0}};
139 const static std::array<std::size_t, 3> b = {{2, 2, 1}};
140 for (std::size_t i = 0; i < 3; ++i)
141 for (std::size_t j = 0; j < 3; ++j)
143 M(i, j) = R(i, j) * R(i, j);
146 M(i + 3, j + 3) = R(a[i], a[j]) * R(b[i], b[j]) + R(a[i], b[j]) * R(b[i], a[j]);
151 template <
typename T>
159 (*this) = M * (*this) * M.transposeMajor();
162 template <
typename T>
171 template <
typename T>
180 template <
typename T>
185 _vals[i] += a.
_vals[i];
189 template <
typename T>
190 template <
typename T2>
197 result.
_vals[i] = _vals[i] + b._vals[i];
201 template <
typename T>
206 _vals[i] -= a.
_vals[i];
210 template <
typename T>
211 template <
typename T2>
218 result.
_vals[i] = _vals[i] - b._vals[i];
222 template <
typename T>
228 result.
_vals[i] = -_vals[i];
232 template <
typename T>
233 template <
typename T2>
238 typedef decltype(T() * T2()) ValueType;
244 result(i, j) += (*this)(i, p) * b(p, j);
249 template <
typename T>
259 template <
typename T>
266 stm << std::setw(15) << _vals[i *
N + j] <<
" ";
272 template <
typename T>
285 template <
typename T>
289 std::size_t index = 0;
293 ret.
_vals[index++] = _vals[i +
N * j];
297 template <
typename T>
306 fillSymmetric9FromInputVector(input);
309 fillSymmetric21FromInputVector(input);
311 case symmetric_isotropic:
312 fillSymmetricIsotropicFromInputVector(input);
314 case symmetric_isotropic_E_nu:
315 fillSymmetricIsotropicEandNuFromInputVector(input);
317 case axisymmetric_rz:
318 fillAxisymmetricRZFromInputVector(input);
321 fillPrincipalFromInputVector(input);
324 fillGeneralOrthotropicFromInputVector(input);
327 mooseError(
"fillFromInputVector called with unknown fill_method of ", fill_method);
331 template <
typename T>
335 mooseAssert(input.size() == 2,
336 "To use fillSymmetricIsotropicFromInputVector, your input must have size 2.");
337 fillSymmetricIsotropic(input[0], input[1]);
340 template <
typename T>
345 fillSymmetric21FromInputVector(std::array<T,21>
346 {{lambda + 2.0 * G, lambda, lambda, 0.0, 0.0, 0.0,
347 lambda + 2.0 * G, lambda, 0.0, 0.0, 0.0,
348 lambda + 2.0 * G, 0.0, 0.0, 0.0,
355 template <
typename T>
358 const std::vector<T> & input)
360 if (input.size() != 2)
362 "To use fillSymmetricIsotropicEandNuFromInputVector, your input must have size 2. Yours " 366 fillSymmetricIsotropicEandNu(input[0], input[1]);
369 template <
typename T>
374 const T & lambda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
375 const T & G = E / (2.0 * (1.0 + nu));
377 fillSymmetricIsotropic(lambda, G);
380 template <
typename T>
384 mooseAssert(input.size() == 5,
385 "To use fillAxisymmetricRZFromInputVector, your input must have size 5.");
394 fillSymmetric21FromInputVector(std::array<T,21>
395 {{input[0],input[1],input[2], 0.0, 0.0, 0.0,
396 input[0],input[2], 0.0, 0.0, 0.0,
397 input[3], 0.0, 0.0, 0.0,
400 (input[0] - input[1]) * 0.5}});
404 template <
typename T>
408 if (input.size() != 9)
409 mooseError(
"To use fillPrincipalFromInputVector, your input must have size 9. Yours has size ",
421 _vals[12] = input[6];
422 _vals[13] = input[7];
423 _vals[14] = input[8];
426 template <
typename T>
430 mooseAssert(LIBMESH_DIM == 3,
"This method assumes LIBMESH_DIM == 3");
431 if (input.size() != 12)
432 mooseError(
"To use fillGeneralOrhotropicFromInputVector, your input must have size 12. Yours " 436 const T & Ea = input[0];
437 const T & Eb = input[1];
438 const T & Ec = input[2];
439 const T & Gab = input[3];
440 const T & Gbc = input[4];
441 const T & Gca = input[5];
442 const T & nuba = input[6];
443 const T & nuca = input[7];
444 const T & nucb = input[8];
445 const T & nuab = input[9];
446 const T & nuac = input[10];
447 const T & nubc = input[11];
454 if (!preserve_symmetry)
455 mooseError(
"Orthotropic elasticity tensor input is not consistent with symmetry requirements. " 456 "Check input for accuracy");
459 T k = 1 - nuab * nuba - nubc * nucb - nuca * nuac - nuab * nubc * nuca - nuba * nucb * nuac;
461 bool is_positive_definite =
462 (k > 0) && (1 - nubc * nucb) > 0 && (1 - nuac * nuca) > 0 && (1 - nuab * nuba) > 0;
463 if (!is_positive_definite)
464 mooseError(
"Orthotropic elasticity tensor input is not positive definite. Check input for " 467 _vals[0] = Ea * (1 - nubc * nucb) / k;
468 _vals[1] = Ea * (nubc * nuca + nuba) / k;
469 _vals[2] = Ea * (nuba * nucb + nuca) / k;
471 _vals[6] = Eb * (nuac * nucb + nuab) / k;
472 _vals[7] = Eb * (1 - nuac * nuca) / k;
473 _vals[8] = Eb * (nuab * nuca + nucb) / k;
475 _vals[12] = Ec * (nuab * nubc + nuac) / k;
476 _vals[13] = Ec * (nuac * nuba + nubc) / k;
477 _vals[14] = Ec * (1 - nuab * nuba) / k;
484 template <
typename T>
488 mooseAssert(LIBMESH_DIM == 3,
"This method assumes LIBMESH_DIM == 3");
493 sum += (*this)(i, j);
497 template <
typename T>
501 mooseAssert(LIBMESH_DIM == 3,
"This method assumes LIBMESH_DIM == 3");
504 _vals[6] + _vals[7] + _vals[8],
505 _vals[12] + _vals[13] + _vals[14]);
508 template <
typename T>
512 for (
unsigned int i = 0; i <
N; ++i)
513 for (
unsigned int j = 0; j <
N; ++j)
515 if (_vals[i +
N * j] != _vals[
N * i + j])
520 template <
typename T>
529 const T & mu = _vals[35];
532 if (_vals[28] != mu || _vals[21] != mu)
536 if (_vals[22] != 0.0 || _vals[23] != 0.0 || _vals[29] != 0.0)
542 if (_vals[3 + i +
N * j] != 0.0)
546 const T & K1 = _vals[0];
547 const T & K2 = _vals[1];
550 if (_vals[7] != K1 || _vals[14] != K1)
555 if (_vals[i +
N * j] != K2)
void fillAxisymmetricRZFromInputVector(const std::vector< T > &input)
fillAxisymmetricRZFromInputVector takes 5 inputs to fill the axisymmetric Rank-4 tensor with the appr...
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
std::array< T, N2 > _vals
The values of the rank-four tensor.
libMesh::VectorValue< T > sum3x1() const
Calculates the vector a[i] = sum over j Ciijj for i and j varying from 0 to 2.
void fillSymmetricIsotropicEandNu(const T &E, const T &nu)
static MooseEnum fillMethodEnum()
Static method for use in validParams for getting the "fill_method".
bool isIsotropic() const
checks if the tensor is isotropic
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
auto operator+(const SymmetricRankFourTensorTempl< T2 > &a) const -> SymmetricRankFourTensorTempl< decltype(T()+T2())>
C_ijkl + a_ijkl.
FillMethod
To fill up the 36 entries in the 4th-order tensor, fillFromInputVector is called with one of the foll...
void fillSymmetricIsotropic(const T &i0, const T &i1)
Vector-less fill API functions. See docs of the corresponding ...FromInputVector methods.
SymmetricRankFourTensorTempl< T > & operator-=(const SymmetricRankFourTensorTempl< T > &a)
C_ijkl -= a_ijkl.
auto operator*(const SymmetricRankTwoTensorTempl< T2 > &b) const -> SymmetricRankTwoTensorTempl< decltype(T() *T2())>
C_ijkl*a_kl.
T sum3x3() const
Calculates the sum of Ciijj for i and j varying from 0 to 2.
T L2norm() const
sqrt(C_ijkl*C_ijkl)
static SymmetricRankFourTensorTempl< T > rotationMatrix(const TypeTensor< T > &R)
Build a 6x6 rotation matrix MEHRABADI, MORTEZA M.
SymmetricRankFourTensorTempl< T > & operator+=(const SymmetricRankFourTensorTempl< T > &a)
C_ijkl += a_ijkl for all i, j, k, l.
void fillSymmetricIsotropicEandNuFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicEandNuFromInputVector is a variation of the fillSymmetricIsotropicFromInputVect...
InitMethod
Initialization method.
void init(triangulateio &t)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
void rotate(const TypeTensor< T > &R)
Rotate the tensor using C_ijkl = R_im R_jn R_ko R_lp C_mnop.
SymmetricRankFourTensorTempl< T > & operator*=(const T &a)
C_ijkl *= a.
void fillPrincipalFromInputVector(const std::vector< T > &input)
fillPrincipalFromInputVector takes 9 inputs to fill a Rank-4 tensor C1111 = input0 C1122 = input1 C11...
void printReal(std::ostream &stm=Moose::out) const
Print the values of the rank four tensor.
void fillSymmetricIsotropicFromInputVector(const std::vector< T > &input)
fillSymmetricIsotropicFromInputVector takes 2 inputs to fill the the symmetric Rank-4 tensor with the...
SymmetricRankFourTensorTempl< T > transposeMajor() const
Transpose the tensor by swapping the first pair with the second pair of indices This amounts to a reg...
void print(std::ostream &stm=Moose::out) const
Print the rank four tensor.
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method)
fillFromInputVector takes some number of inputs to fill the Rank-4 tensor.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
SymmetricRankFourTensorTempl< T > operator-() const
-C_ijkl
bool relativeFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
void fillGeneralOrthotropicFromInputVector(const std::vector< T > &input)
fillGeneralOrhotropicFromInputVector takes 10 inputs to fill the Rank-4 tensor It defines a general o...
void zero()
Zeros out the tensor.
SymmetricRankFourTensorTempl is designed to handle an N-dimensional fourth order tensor with minor sy...
IntRange< T > make_range(T beg, T end)
bool isSymmetric() const
checks if the tensor is symmetric
SymmetricRankFourTensorTempl< T > & operator/=(const T &a)
C_ijkl /= a for all i, j, k, l.
SymmetricRankFourTensorTempl()
Default constructor; fills to zero.
static constexpr Real sqrt2
std::sqrt is not constexpr, so we add sqrt(2) as a constant (used in Mandel notation) ...
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt