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  using std::sqrt;
250  return sqrt(l2);
251 }
252 
253 template <typename T>
254 void
255 RankThreeTensorTempl<T>::fillFromInputVector(const std::vector<T> & input, FillMethod fill_method)
256 {
257  zero();
258 
259  if (fill_method == automatic)
260  {
261  if (input.size() == 27)
262  fill_method = general;
263  else if (input.size() == 3)
264  fill_method = plane_normal;
265  else
266  mooseError("Unsupported automatic fill method, use 27 values for 'general' and 3 for "
267  "'plane_normal', the supplied size was ",
268  input.size(),
269  ".");
270  }
271 
272  if (fill_method == general)
273  fillGeneralFromInputVector(input);
274 
275  else if (fill_method == plane_normal)
276  {
277  if (input.size() != 3)
278  mooseError("To use fillFromPlaneNormal, your input must have size 3, the supplied size was ",
279  input.size(),
280  ".");
281  fillFromPlaneNormal(libMesh::VectorValue<T>(input[0], input[1], input[2]));
282  }
283 
284  else
285  // This is un-reachable unless a FillMethod is added and the if statement is not updated
286  mooseError("fillFromInputVector called with unknown fill_method of ", fill_method);
287 }
288 
289 template <typename T>
290 void
292 {
293  unsigned int index = 0;
294  for (auto i : make_range(N))
295  {
296  const T a = input(i);
297  for (auto j : make_range(N))
298  {
299  const T b = input(j);
300  for (auto k : make_range(N))
301  {
302  const T c = input(k);
303  T sum = 0;
304  sum = -2.0 * a * b * c;
305  if (i == j)
306  sum += c;
307  if (i == k)
308  sum += b;
309  _vals[index++] = sum / 2.0;
310  }
311  }
312  }
313 }
314 
315 template <typename T>
318 {
319  RankFourTensorTempl<T> result;
320 
321  unsigned int index = 0;
322  for (auto i : make_range(N))
323  for (auto j : make_range(N))
324  for (auto k : make_range(N))
325  for (auto l : make_range(N))
326  {
327  for (auto m : make_range(N))
328  for (auto n : make_range(N))
329  result._vals[index] += (*this)(m, i, j) * a(m, n) * (*this)(n, k, l);
330  index++;
331  }
332 
333  return result;
334 }
335 
336 template <typename T>
337 void
339 {
340  RankThreeTensorTempl<T> old = *this;
341 
342  unsigned int index = 0;
343  for (auto i : make_range(N))
344  for (auto j : make_range(N))
345  for (auto k : make_range(N))
346  {
347  T sum = 0.0;
348  unsigned int index2 = 0;
349  for (auto m : make_range(N))
350  {
351  T a = R(i, m);
352  for (auto n : make_range(N))
353  {
354  T ab = a * R(j, n);
355  for (auto o : make_range(N))
356  sum += ab * R(k, o) * old._vals[index2++];
357  }
358  }
359  _vals[index++] = sum;
360  }
361 }
362 
363 template <typename T>
364 void
366 {
367  if (input.size() != 27)
368  mooseError(
369  "To use fillGeneralFromInputVector, your input must have size 27, the supplied size was ",
370  input.size(),
371  ".");
372 
373  for (auto i : make_range(N3))
374  _vals[i] = input[i];
375 }
376 
377 template <typename T>
380 {
382 
383  for (auto i : make_range(N))
384  for (auto j : make_range(N2))
385  result(i) += _vals[i * N2 + j] * b._coords[j];
386 
387  return result;
388 }
389 
390 template <typename T>
391 void
392 RankThreeTensorTempl<T>::print(std::ostream & stm) const
393 {
394  for (auto i : make_range(N))
395  {
396  stm << "a(" << i << ", j, k) = \n";
397  for (auto j : make_range(N))
398  {
399  for (auto k : make_range(N))
400  stm << std::setw(15) << (*this)(i, j, k) << ' ';
401  stm << "\n";
402  }
403  stm << "\n";
404  }
405 
406  stm << std::flush;
407 }
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:323
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