https://mooseframework.inl.gov
RankThreeTensorImplementation.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "RankThreeTensor.h"
13 #include "RankTwoTensor.h"
14 #include "RankFourTensor.h"
15 
16 // MOOSE includes
17 #include "MooseEnum.h"
18 #include "MooseException.h"
19 #include "MooseUtils.h"
20 #include "MatrixTools.h"
21 #include "PermutationTensor.h"
22 
23 #include "libmesh/utility.h"
24 #include "libmesh/vector_value.h"
25 #include "libmesh/tensor_value.h"
26 
27 // C++ includes
28 #include <iomanip>
29 #include <ostream>
30 
31 namespace MathUtils
32 {
33 template <>
35 template <>
37 }
38 
39 template <typename T>
42 {
43  return MooseEnum("general plane_normal");
44 }
45 
46 template <typename T>
48 {
49  mooseAssert(N == 3, "RankThreeTensor is currently only tested for 3 dimensions.");
50 
51  for (auto i : make_range(N3))
52  _vals[i] = 0;
53 }
54 
55 template <typename T>
57 {
58  switch (init)
59  {
60  case initNone:
61  break;
62 
63  default:
64  mooseError("Unknown RankThreeTensor initialization pattern.");
65  }
66 }
67 
68 template <typename T>
69 RankThreeTensorTempl<T>::RankThreeTensorTempl(const std::vector<T> & input, FillMethod fill_method)
70 {
71  fillFromInputVector(input, fill_method);
72 }
73 
74 template <typename T>
75 void
77 {
78  for (auto i : make_range(N3))
79  _vals[i] = 0;
80 }
81 
82 template <typename T>
85 {
86  for (auto i : make_range(N3))
87  _vals[i] = value;
88  return *this;
89 }
90 
91 template <typename T>
94 {
95  for (auto i : make_range(N3))
96  _vals[i] = a._vals[i];
97 
98  return *this;
99 }
100 
101 template <typename T>
104 {
106 
107  for (auto i : make_range(N))
108  {
109  T sum = 0;
110  unsigned int i1 = i * N2;
111  for (unsigned int j1 = 0; j1 < N2; j1 += N)
112  for (auto k : make_range(N))
113  sum += _vals[i1 + j1 + k] * a._coords[j1 + k];
114  result(i) = sum;
115  }
116 
117  return result;
118 }
119 
120 template <typename T>
123 {
124  RankTwoTensorTempl<T> result;
125 
126  for (auto i : make_range(N))
127  for (auto j : make_range(N))
128  {
129  T sum = 0;
130  unsigned int i1 = i * N2;
131  unsigned int j1 = j * N;
132  for (auto k : make_range(N))
133  sum += _vals[i1 + j1 + k] * a(k);
134  result(i, j) = sum;
135  }
136 
137  return result;
138 }
139 
140 template <typename T>
143 {
145 
146  for (auto i : make_range(N3))
147  result._vals[i] = _vals[i] * b;
148 
149  return result;
150 }
151 
152 template <typename T>
155 {
156  for (auto i : make_range(N3))
157  _vals[i] *= a;
158 
159  return *this;
160 }
161 
162 template <typename T>
165 {
167 
168  for (auto i : make_range(N3))
169  result._vals[i] = _vals[i] / b;
170 
171  return result;
172 }
173 
174 template <typename T>
177 {
178  for (auto i : make_range(N3))
179  _vals[i] /= a;
180 
181  return *this;
182 }
183 
184 template <typename T>
187 {
188  for (auto i : make_range(N3))
189  _vals[i] += a._vals[i];
190 
191  return *this;
192 }
193 
194 template <typename T>
197 {
199 
200  for (auto i : make_range(N3))
201  result._vals[i] = _vals[i] + b._vals[i];
202 
203  return result;
204 }
205 
206 template <typename T>
209 {
210  for (auto i : make_range(N3))
211  _vals[i] -= a._vals[i];
212 
213  return *this;
214 }
215 
216 template <typename T>
219 {
221 
222  for (auto i : make_range(N3))
223  result._vals[i] = _vals[i] - b._vals[i];
224 
225  return result;
226 }
227 
228 template <typename T>
231 {
233 
234  for (auto i : make_range(N3))
235  result._vals[i] = -_vals[i];
236 
237  return result;
238 }
239 
240 template <typename T>
241 T
243 {
244  T l2 = 0;
245 
246  for (auto i : make_range(N3))
247  l2 += Utility::pow<2>(_vals[i]);
248 
249  return std::sqrt(l2);
250 }
251 
252 template <typename T>
253 void
254 RankThreeTensorTempl<T>::fillFromInputVector(const std::vector<T> & input, FillMethod fill_method)
255 {
256  zero();
257 
258  if (fill_method == automatic)
259  {
260  if (input.size() == 27)
261  fill_method = general;
262  else if (input.size() == 3)
263  fill_method = plane_normal;
264  else
265  mooseError("Unsupported automatic fill method, use 27 values for 'general' and 3 for "
266  "'plane_normal', the supplied size was ",
267  input.size(),
268  ".");
269  }
270 
271  if (fill_method == general)
272  fillGeneralFromInputVector(input);
273 
274  else if (fill_method == plane_normal)
275  {
276  if (input.size() != 3)
277  mooseError("To use fillFromPlaneNormal, your input must have size 3, the supplied size was ",
278  input.size(),
279  ".");
280  fillFromPlaneNormal(libMesh::VectorValue<T>(input[0], input[1], input[2]));
281  }
282 
283  else
284  // This is un-reachable unless a FillMethod is added and the if statement is not updated
285  mooseError("fillFromInputVector called with unknown fill_method of ", fill_method);
286 }
287 
288 template <typename T>
289 void
291 {
292  unsigned int index = 0;
293  for (auto i : make_range(N))
294  {
295  const T a = input(i);
296  for (auto j : make_range(N))
297  {
298  const T b = input(j);
299  for (auto k : make_range(N))
300  {
301  const T c = input(k);
302  T sum = 0;
303  sum = -2.0 * a * b * c;
304  if (i == j)
305  sum += c;
306  if (i == k)
307  sum += b;
308  _vals[index++] = sum / 2.0;
309  }
310  }
311  }
312 }
313 
314 template <typename T>
317 {
318  RankFourTensorTempl<T> result;
319 
320  unsigned int index = 0;
321  for (auto i : make_range(N))
322  for (auto j : make_range(N))
323  for (auto k : make_range(N))
324  for (auto l : make_range(N))
325  {
326  for (auto m : make_range(N))
327  for (auto n : make_range(N))
328  result._vals[index] += (*this)(m, i, j) * a(m, n) * (*this)(n, k, l);
329  index++;
330  }
331 
332  return result;
333 }
334 
335 template <typename T>
336 void
338 {
339  RankThreeTensorTempl<T> old = *this;
340 
341  unsigned int index = 0;
342  for (auto i : make_range(N))
343  for (auto j : make_range(N))
344  for (auto k : make_range(N))
345  {
346  T sum = 0.0;
347  unsigned int index2 = 0;
348  for (auto m : make_range(N))
349  {
350  T a = R(i, m);
351  for (auto n : make_range(N))
352  {
353  T ab = a * R(j, n);
354  for (auto o : make_range(N))
355  sum += ab * R(k, o) * old._vals[index2++];
356  }
357  }
358  _vals[index++] = sum;
359  }
360 }
361 
362 template <typename T>
363 void
365 {
366  if (input.size() != 27)
367  mooseError(
368  "To use fillGeneralFromInputVector, your input must have size 27, the supplied size was ",
369  input.size(),
370  ".");
371 
372  for (auto i : make_range(N3))
373  _vals[i] = input[i];
374 }
375 
376 template <typename T>
379 {
381 
382  for (auto i : make_range(N))
383  for (auto j : make_range(N2))
384  result(i) += _vals[i * N2 + j] * b._coords[j];
385 
386  return result;
387 }
388 
389 template <typename T>
390 void
391 RankThreeTensorTempl<T>::print(std::ostream & stm) const
392 {
393  for (auto i : make_range(N))
394  {
395  stm << "a(" << i << ", j, k) = \n";
396  for (auto j : make_range(N))
397  {
398  for (auto k : make_range(N))
399  stm << std::setw(15) << (*this)(i, j, k) << ' ';
400  stm << "\n";
401  }
402  stm << "\n";
403  }
404 
405  stm << std::flush;
406 }
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
RankFourTensorTempl< T > mixedProductRankFour(const RankTwoTensorTempl< T > &a) const
Creates fourth order tensor D_{ijkl}=A_{mij}*b_{mn}*A_{nkl} where A is rank 3 and b is rank 2...
void mooseSetToZero< RankThreeTensor >(RankThreeTensor &v)
void fillFromPlaneNormal(const libMesh::VectorValue< T > &input)
Fills RankThreeTensor from plane normal vectors ref.
RankThreeTensorTempl< T > & operator/=(const T a)
r_ijk /= a for all i, j, k
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
libMesh::VectorValue< T > doubleContraction(const RankTwoTensorTempl< T > &b) const
Creates a vector from the double contraction of a rank three and rank two tensor. ...
RankThreeTensorTempl< T > & operator-=(const RankThreeTensorTempl< T > &a)
r_ijk -= a_ijk
const Number zero
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method=automatic)
fillFromInputVector takes some number of inputs to fill the Rank-3 tensor.
T _coords[LIBMESH_DIM *LIBMESH_DIM]
RankThreeTensorTempl< T > operator/(const T a) const
r_ijk/a
RankThreeTensor is designed to handle any N-dimensional third order tensor, r.
RankThreeTensorTempl< T > operator-() const
-r_ijk
FillMethod
To fill up the 27 entries in the 3rd-order tensor, fillFromInputVector is called with one of the foll...
RankThreeTensorTempl< T > & operator+=(const RankThreeTensorTempl< T > &a)
r_ijk += a_ijk for all i, j, k
static MooseEnum fillMethodEnum()
Static method for use in validParams for getting the "fill_method".
RankThreeTensorTempl< T > & operator*=(const T a)
r_ijk *= a
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void rotate(const T2 &R)
Rotate the tensor using r_ijk = R_im R_in R_ko r_mno.
libMesh::VectorValue< T > operator*(const RankTwoTensorTempl< T > &a) const
b_i = r_ijk * a_jk
RankThreeTensorTempl< T > & operator=(const T &value)
Assignment-from-scalar operator.
void init(triangulateio &t)
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
T _vals[N3]
The values of the rank-three tensor stored by index=((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) ...
InitMethod
Initialization method.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
RankThreeTensorTempl()
Default constructor; fills to zero.
RankThreeTensorTempl< T > operator+(const RankThreeTensorTempl< T > &a) const
r_ijkl + a_ijk
T L2norm() const
(r_ijk*r_ijk)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
Definition: RankTwoTensor.h:87
void mooseSetToZero< ADRankThreeTensor >(ADRankThreeTensor &v)
IntRange< T > make_range(T beg, T end)
void zero()
Zeros out the tensor.
void fillGeneralFromInputVector(const std::vector< T > &input)
void print(std::ostream &stm=Moose::out) const
Print the rank three tensor.
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