$extrastylesheet
tensor_tools.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 #ifndef LIBMESH_TENSOR_TOOLS_H
00021 #define LIBMESH_TENSOR_TOOLS_H
00022 
00023 // Local includes
00024 #include "libmesh/libmesh_common.h"
00025 #include "libmesh/compare_types.h"
00026 
00027 namespace libMesh
00028 {
00029 // Forward declarations
00030 template <typename T> class TypeVector;
00031 template <typename T> class VectorValue;
00032 template <typename T> class TypeTensor;
00033 template <typename T> class TensorValue;
00034 template <unsigned int N, typename T> class TypeNTensor;
00035 
00036 namespace TensorTools
00037 {
00038 // Any tensor-rank-independent code will need to include
00039 // tensor_tools.h, so we define a product/dot-product here, starting
00040 // with the generic case to apply to scalars.
00041 // Vector specializations will follow.
00042 
00043 template <typename T, typename T2>
00044 inline
00045 typename boostcopy::enable_if_c<
00046   ScalarTraits<T>::value && ScalarTraits<T2>::value,
00047   typename CompareTypes<T, T2>::supertype>::type
00048 inner_product(const T& a, const T2& b)
00049 { return a * b; }
00050 
00051 template <typename T, typename T2>
00052 inline
00053 typename CompareTypes<T, T2>::supertype
00054 inner_product(const TypeVector<T>& a, const TypeVector<T2>& b)
00055 { return a * b; }
00056 
00057 template <typename T, typename T2>
00058 inline
00059 typename CompareTypes<T, T2>::supertype
00060 inner_product(const TypeTensor<T>& a, const TypeTensor<T2>& b)
00061 { return a.contract(b); }
00062 
00063 template <unsigned int N, typename T, typename T2>
00064 inline
00065 typename CompareTypes<T, T2>::supertype
00066 inner_product(const TypeNTensor<N,T>& a, const TypeNTensor<N,T2>& b)
00067 { return a.contract(b); }
00068 
00069 template<typename T>
00070 inline
00071 T norm_sq(T a) { return a*a; }
00072 
00073 template<typename T>
00074 inline
00075 T norm_sq(std::complex<T> a) { return std::norm(a); }
00076 
00077 template <typename T>
00078 inline
00079 Real norm_sq(const TypeVector<T>& a)
00080 {return a.size_sq();}
00081 
00082 template <typename T>
00083 inline
00084 Real norm_sq(const VectorValue<T>& a)
00085 {return a.size_sq();}
00086 
00087 // Any tensor-rank-independent code will need to include
00088 // tensor_tools.h, so we define rank-increasing and real-to-number type
00089 // conversion functions here, starting with the generic case to apply
00090 // to scalars.
00091 // Tensor(and higher?) specializations will go in the tensor
00092 // header(s).
00093 template <typename T>
00094 struct IncrementRank
00095 {
00096   typedef VectorValue<T> type;
00097 };
00098 
00099 template <typename T>
00100 struct IncrementRank<VectorValue<T> >
00101 {
00102   typedef TensorValue<T> type;
00103 };
00104 
00105 
00106 template <typename T>
00107 struct IncrementRank<TypeVector<T> >
00108 {
00109   typedef TensorValue<T> type;
00110 };
00111 
00112 template <typename T>
00113 struct IncrementRank<TypeTensor<T> >
00114 {
00115   typedef TypeNTensor<3,T> type;
00116 };
00117 
00118 
00119 template <typename T>
00120 struct IncrementRank<TensorValue<T> >
00121 {
00122   typedef TypeNTensor<3,T> type;
00123 };
00124 
00125 template <unsigned int N, typename T>
00126 struct IncrementRank<TypeNTensor<N,T> >
00127 {
00128   typedef TypeNTensor<N+1,T> type;
00129 };
00130 
00131 
00132 // Also need rank-decreasing case
00133 template <typename T>
00134 struct DecrementRank
00135 {
00136   // The default case is typically an error, but for simpler
00137   // templated code we need it to be compatible with Number
00138   // operations...
00139   typedef T type;
00140 };
00141 
00142 template <typename T>
00143 struct DecrementRank<VectorValue<T> >
00144 {
00145   typedef T type;
00146 };
00147 
00148 template <typename T>
00149 struct DecrementRank<TypeVector<T> >
00150 {
00151   typedef T type;
00152 };
00153 
00154 template <typename T>
00155 struct DecrementRank<TensorValue<T> >
00156 {
00157   typedef VectorValue<T> type;
00158 };
00159 
00160 template <typename T>
00161 struct DecrementRank<TypeTensor<T> >
00162 {
00163   typedef VectorValue<T> type;
00164 };
00165 
00166 template <unsigned int N, typename T>
00167 struct DecrementRank<TypeNTensor<N,T> >
00168 {
00169   typedef TypeNTensor<N-1,T> type;
00170 };
00171 
00172 // Handle the complex-valued case
00173 template <typename T>
00174 struct MakeNumber
00175 {
00176 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
00177   typedef std::complex<T> type;
00178 #else
00179   typedef T type;
00180 #endif
00181 };
00182 
00183 template <typename T>
00184 struct MakeNumber<std::complex<T> >
00185 {
00186   // Compile-time error: we shouldn't need to make numbers out of
00187   // numbers
00188   //typedef std::complex<T> type;
00189 };
00190 
00191 
00192 template <typename T>
00193 struct MakeNumber<TypeVector<T> >
00194 {
00195   typedef TypeVector<typename MakeNumber<T>::type > type;
00196 };
00197 
00198 template <typename T>
00199 struct MakeNumber<VectorValue<T> >
00200 {
00201   typedef VectorValue<typename MakeNumber<T>::type > type;
00202 };
00203 
00204 template <typename T>
00205 struct MakeNumber<TypeTensor<T> >
00206 {
00207   typedef TypeTensor<typename MakeNumber<T>::type> type;
00208 };
00209 
00210 template <typename T>
00211 struct MakeNumber<TensorValue<T> >
00212 {
00213   typedef TypeTensor<typename MakeNumber<T>::type> type;
00214 };
00215 
00216 template <unsigned int N, typename T>
00217 struct MakeNumber<TypeNTensor<N,T> >
00218 {
00219 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
00220   typedef TypeNTensor<N,std::complex<T> > type;
00221 #else
00222   typedef TypeNTensor<N,T> type;
00223 #endif
00224 };
00225 
00226 // A utility for determining real-valued (e.g. shape function)
00227 // types from corresponding complex-valued types
00228 template <typename T>
00229 struct MakeReal
00230 {
00231   typedef T type;
00232 };
00233 
00234 template <typename T>
00235 struct MakeReal<std::complex<T> >
00236 {
00237   typedef T type;
00238 };
00239 
00240 template <typename T>
00241 struct MakeReal<TypeVector<T> >
00242 {
00243   typedef TypeVector<typename MakeReal<T>::type > type;
00244 };
00245 
00246 template <typename T>
00247 struct MakeReal<VectorValue<T> >
00248 {
00249   typedef VectorValue<typename MakeReal<T>::type > type;
00250 };
00251 
00252 template <typename T>
00253 struct MakeReal<TypeTensor<T> >
00254 {
00255   typedef TypeTensor<typename MakeReal<T>::type> type;
00256 };
00257 
00258 template <typename T>
00259 struct MakeReal<TensorValue<T> >
00260 {
00261   typedef TypeTensor<typename MakeReal<T>::type> type;
00262 };
00263 
00264 template <unsigned int N, typename T>
00265 struct MakeReal<TypeNTensor<N,T> >
00266 {
00267   typedef TypeNTensor<N,typename MakeReal<T>::type> type;
00268 };
00269 
00270 // Needed for ExactSolution to compile
00271 Number curl_from_grad( const VectorValue<Number>& );
00272 
00274 VectorValue<Number> curl_from_grad( const TensorValue<Number>& grad );
00275 
00278 TensorValue<Number> curl_from_grad( const TypeNTensor<3,Number>& grad );
00279 
00281 Number div_from_grad( const VectorValue<Number>& grad );
00282 
00284 Number div_from_grad( const TensorValue<Number>& grad );
00285 
00288 VectorValue<Number> div_from_grad( const TypeNTensor<3,Number>& grad );
00289 
00290 }//namespace TensorTools
00291 
00292 }//namespace libMesh
00293 
00294 #endif // LIBMESH_TENSOR_TOOLS_H