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