1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20 #ifndef LIBMESH_TENSOR_VALUE_H
21 #define LIBMESH_TENSOR_VALUE_H
22
23 // Local includes
24 #include "libmesh/type_tensor.h"
25
26 #ifdef LIBMESH_HAVE_METAPHYSICL
27 #include "metaphysicl/raw_type.h"
28 #endif
29
30 namespace libMesh
31 {
32
33 /**
34 * This class defines a tensor in LIBMESH_DIM dimensional Real or Complex
35 * space. The typedef RealTensorValue always defines a real-valued tensor,
36 * and NumberTensorValue defines a real or complex-valued tensor depending
37 * on how the library was configured.
38 *
39 * \author Roy H. Stogner
40 * \date 2004
41 */
42 template <typename T>
43 class TensorValue : public TypeTensor<T>
44 {
45 public:
46 typedef T value_type;
47
48 template <typename T2>
49 struct rebind
50 {
51 typedef TensorValue<T2> other;
52 };
53
54 /**
55 * Empty constructor.
56 * Gives the tensor 0 in \p LIBMESH_DIM dimensional T space.
57 */
58 TensorValue ();
59
60 /**
61 * Constructor-from-T. By default sets higher dimensional
62 * entries to 0.
63 */
64 explicit TensorValue (const T & xx,
65 const T & xy=0,
66 const T & xz=0,
67 const T & yx=0,
68 const T & yy=0,
69 const T & yz=0,
70 const T & zx=0,
71 const T & zy=0,
72 const T & zz=0);
73
74 /**
75 * Constructor-from-scalars. By default sets higher dimensional
76 * entries to 0.
77 */
78 template <typename Scalar>
79 explicit TensorValue (const Scalar & xx,
80 const Scalar & xy=0,
81 const Scalar & xz=0,
82 const Scalar & yx=0,
83 const Scalar & yy=0,
84 const Scalar & yz=0,
85 const Scalar & zx=0,
86 const Scalar & zy=0,
87 typename
88 boostcopy::enable_if_c<ScalarTraits<Scalar>::value,
89 const Scalar>::type & zz=0);
90
91 /**
92 * Constructor. Takes 1 row vector for LIBMESH_DIM=1
93 */
94 template <typename T2>
95 TensorValue (const TypeVector<T2> & vx);
96
97 /**
98 * Constructor. Takes 2 row vectors for LIBMESH_DIM=2
99 */
100 template <typename T2>
101 TensorValue (const TypeVector<T2> & vx,
102 const TypeVector<T2> & vy);
103
104 /**
105 * Constructor. Takes 3 row vectors for LIBMESH_DIM=3
106 */
107 template <typename T2>
108 TensorValue (const TypeVector<T2> & vx,
109 const TypeVector<T2> & vy,
110 const TypeVector<T2> & vz);
111
112
113 /**
114 * Copy-constructor.
115 */
116 template <typename T2>
117 TensorValue (const TensorValue<T2> & p);
118
119 /**
120 * Copy-constructor.
121 */
122 template <typename T2>
123 TensorValue (const TypeTensor<T2> & p);
124
125
126 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
127 /**
128 * Constructor that takes two \p TypeTensor<Real>
129 * representing the real and imaginary part as
130 * arguments.
131 */
132 TensorValue (const TypeTensor<Real> & p_re,
133 const TypeTensor<Real> & p_im);
134 #endif
135
136
137 /**
138 * Assignment-from-scalar operator. Used only to zero out tensors.
139 */
140 template <typename Scalar>
141 typename boostcopy::enable_if_c<
142 ScalarTraits<Scalar>::value,
143 TensorValue &>::type
144 operator = (const Scalar & libmesh_dbg_var(p) )
145 { libmesh_assert_equal_to (p, Scalar(0)); this->zero(); return *this; }
146 };
147
148
149
150 /**
151 * Useful typedefs to allow transparent switching
152 * between Real and Complex data types.
153 */
154 typedef TensorValue<Real> RealTensorValue;
155 typedef TensorValue<Number> NumberTensorValue;
156 typedef RealTensorValue RealTensor;
157 typedef NumberTensorValue Tensor;
158
159
160
161 //------------------------------------------------------
162 // Inline functions
163 template <typename T>
164 inline
TensorValue()165 TensorValue<T>::TensorValue () :
166 TypeTensor<T> ()
167 {
168 }
169
170
171
172 template <typename T>
173 inline
TensorValue(const T & xx,const T & xy,const T & xz,const T & yx,const T & yy,const T & yz,const T & zx,const T & zy,const T & zz)174 TensorValue<T>::TensorValue (const T & xx,
175 const T & xy,
176 const T & xz,
177 const T & yx,
178 const T & yy,
179 const T & yz,
180 const T & zx,
181 const T & zy,
182 const T & zz) :
183 TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
184 {
185 }
186
187
188 template <typename T>
189 template <typename Scalar>
190 inline
TensorValue(const Scalar & xx,const Scalar & xy,const Scalar & xz,const Scalar & yx,const Scalar & yy,const Scalar & yz,const Scalar & zx,const Scalar & zy,typename boostcopy::enable_if_c<ScalarTraits<Scalar>::value,const Scalar>::type & zz)191 TensorValue<T>::TensorValue (const Scalar & xx,
192 const Scalar & xy,
193 const Scalar & xz,
194 const Scalar & yx,
195 const Scalar & yy,
196 const Scalar & yz,
197 const Scalar & zx,
198 const Scalar & zy,
199 typename
200 boostcopy::enable_if_c<ScalarTraits<Scalar>::value,
201 const Scalar>::type & zz) :
202 TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
203 {
204 }
205
206
207
208 template <typename T>
209 template <typename T2>
210 inline
TensorValue(const TensorValue<T2> & p)211 TensorValue<T>::TensorValue (const TensorValue<T2> & p) :
212 TypeTensor<T> (p)
213 {
214 }
215
216
217
218 template <typename T>
219 template <typename T2>
220 inline
TensorValue(const TypeVector<T2> & vx)221 TensorValue<T>::TensorValue (const TypeVector<T2> & vx) :
222 TypeTensor<T> (vx)
223 {
224 }
225
226
227
228 template <typename T>
229 template <typename T2>
230 inline
TensorValue(const TypeVector<T2> & vx,const TypeVector<T2> & vy)231 TensorValue<T>::TensorValue (const TypeVector<T2> & vx,
232 const TypeVector<T2> & vy) :
233 TypeTensor<T> (vx, vy)
234 {
235 }
236
237
238
239 template <typename T>
240 template <typename T2>
241 inline
TensorValue(const TypeVector<T2> & vx,const TypeVector<T2> & vy,const TypeVector<T2> & vz)242 TensorValue<T>::TensorValue (const TypeVector<T2> & vx,
243 const TypeVector<T2> & vy,
244 const TypeVector<T2> & vz) :
245 TypeTensor<T> (vx, vy, vz)
246 {
247 }
248
249
250
251 template <typename T>
252 template <typename T2>
253 inline
TensorValue(const TypeTensor<T2> & p)254 TensorValue<T>::TensorValue (const TypeTensor<T2> & p) :
255 TypeTensor<T> (p)
256 {
257 }
258
259
260 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
261 template <typename T>
262 inline
TensorValue(const TypeTensor<Real> & p_re,const TypeTensor<Real> & p_im)263 TensorValue<T>::TensorValue (const TypeTensor<Real> & p_re,
264 const TypeTensor<Real> & p_im) :
265 TypeTensor<T> (Complex (p_re(0,0), p_im(0,0)),
266 Complex (p_re(0,1), p_im(0,1)),
267 Complex (p_re(0,2), p_im(0,2)),
268 Complex (p_re(1,0), p_im(1,0)),
269 Complex (p_re(1,1), p_im(1,1)),
270 Complex (p_re(1,2), p_im(1,2)),
271 Complex (p_re(2,0), p_im(2,0)),
272 Complex (p_re(2,1), p_im(2,1)),
273 Complex (p_re(2,2), p_im(2,2)))
274 {
275 }
276 #endif
277
278
279 } // namespace libMesh
280
281 #ifdef LIBMESH_HAVE_METAPHYSICL
282 namespace MetaPhysicL
283 {
284 template <typename T>
285 struct RawType<libMesh::TensorValue<T>>
286 {
287 typedef libMesh::TensorValue<typename RawType<T>::value_type> value_type;
288
289 static value_type value (const libMesh::TensorValue<T> & in)
290 {
291 value_type ret;
292 for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
293 for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
294 ret(i,j) = raw_value(in(i,j));
295
296 return ret;
297 }
298 };
299 }
300 #endif
301
302 #endif // LIBMESH_TENSOR_VALUE_H
303