$extrastylesheet
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