https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
31namespace MathUtils
32{
33template <>
35template <>
37}
38
39template <typename T>
42{
43 return MooseEnum("general plane_normal");
44}
45
46template <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
55template <typename T>
57{
58 switch (init)
59 {
60 case initNone:
61 break;
62
63 default:
64 mooseError("Unknown RankThreeTensor initialization pattern.");
65 }
66}
67
68template <typename T>
69RankThreeTensorTempl<T>::RankThreeTensorTempl(const std::vector<T> & input, FillMethod fill_method)
70{
71 fillFromInputVector(input, fill_method);
72}
73
74template <typename T>
75void
77{
78 for (auto i : make_range(N3))
79 _vals[i] = 0;
80}
81
82template <typename T>
85{
86 for (auto i : make_range(N3))
87 _vals[i] = value;
88 return *this;
89}
90
91template <typename T>
94{
95 for (auto i : make_range(N3))
96 _vals[i] = a._vals[i];
97
98 return *this;
99}
100
101template <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
120template <typename T>
123{
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
140template <typename T>
143{
145
146 for (auto i : make_range(N3))
147 result._vals[i] = _vals[i] * b;
148
149 return result;
150}
151
152template <typename T>
155{
156 for (auto i : make_range(N3))
157 _vals[i] *= a;
158
159 return *this;
160}
161
162template <typename T>
165{
167
168 for (auto i : make_range(N3))
169 result._vals[i] = _vals[i] / b;
170
171 return result;
172}
173
174template <typename T>
177{
178 for (auto i : make_range(N3))
179 _vals[i] /= a;
180
181 return *this;
182}
183
184template <typename T>
187{
188 for (auto i : make_range(N3))
189 _vals[i] += a._vals[i];
190
191 return *this;
192}
193
194template <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
206template <typename T>
209{
210 for (auto i : make_range(N3))
211 _vals[i] -= a._vals[i];
212
213 return *this;
214}
215
216template <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
228template <typename T>
231{
233
234 for (auto i : make_range(N3))
235 result._vals[i] = -_vals[i];
236
237 return result;
238}
239
240template <typename T>
241T
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
253template <typename T>
254void
255RankThreeTensorTempl<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
289template <typename T>
290void
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
315template <typename T>
318{
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
336template <typename T>
337void
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
363template <typename T>
364void
366{
367 if (input.size() != 27)
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
377template <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
390template <typename T>
391void
392RankThreeTensorTempl<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}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
RankFourTensorTempl is designed to handle any N-dimensional fourth order tensor, C.
T _vals[N4]
The values of the rank-four tensor stored by index=(((i * LIBMESH_DIM + j) * LIBMESH_DIM + k) * LIBME...
RankThreeTensor is designed to handle any N-dimensional third order tensor, r.
FillMethod
To fill up the 27 entries in the 3rd-order tensor, fillFromInputVector is called with one of the foll...
void print(std::ostream &stm=Moose::out) const
Print the rank three tensor.
libMesh::VectorValue< T > operator*(const RankTwoTensorTempl< T > &a) const
b_i = r_ijk * a_jk
RankThreeTensorTempl< T > operator-() const
-r_ijk
T _vals[N3]
The values of the rank-three tensor stored by index=((i * LIBMESH_DIM + j) * LIBMESH_DIM + k)
InitMethod
Initialization method.
RankThreeTensorTempl< T > & operator-=(const RankThreeTensorTempl< T > &a)
r_ijk -= a_ijk
RankThreeTensorTempl< T > & operator/=(const T a)
r_ijk /= a for all i, j, k
RankThreeTensorTempl< T > & operator*=(const T a)
r_ijk *= a
RankThreeTensorTempl< T > & operator=(const T &value)
Assignment-from-scalar operator.
void fillFromInputVector(const std::vector< T > &input, FillMethod fill_method=automatic)
fillFromInputVector takes some number of inputs to fill the Rank-3 tensor.
RankThreeTensorTempl< T > operator/(const T a) const
r_ijk/a
void zero()
Zeros out the tensor.
libMesh::VectorValue< T > doubleContraction(const RankTwoTensorTempl< T > &b) const
Creates a vector from the double contraction of a rank three and rank two tensor.
void rotate(const T2 &R)
Rotate the tensor using r_ijk = R_im R_in R_ko r_mno.
T L2norm() const
\sqrt(r_ijk*r_ijk)
RankThreeTensorTempl< T > & operator+=(const RankThreeTensorTempl< T > &a)
r_ijk += a_ijk for all i, j, k
void fillFromPlaneNormal(const libMesh::VectorValue< T > &input)
Fills RankThreeTensor from plane normal vectors ref.
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.
static MooseEnum fillMethodEnum()
Static method for use in validParams for getting the "fill_method".
RankThreeTensorTempl< T > operator+(const RankThreeTensorTempl< T > &a) const
r_ijkl + a_ijk
friend class RankThreeTensorTempl
void fillGeneralFromInputVector(const std::vector< T > &input)
RankTwoTensorTempl is designed to handle the Stress or Strain Tensor for a fully anisotropic material...
T _coords[LIBMESH_DIM *LIBMESH_DIM]
void mooseSetToZero< RankThreeTensor >(RankThreeTensor &v)
void mooseSetToZero< ADRankThreeTensor >(ADRankThreeTensor &v)