|
Intrepid
|
00001 // @HEADER 00002 // ************************************************************************ 00003 // 00004 // Intrepid Package 00005 // Copyright (2007) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions: Alejandro Mota (amota@sandia.gov) 00038 // 00039 // ************************************************************************ 00040 // @HEADER 00041 00042 #if !defined(Intrepid_MiniTensor_Tensor4_i_h) 00043 #define Intrepid_MiniTensor_Tensor4_i_h 00044 00045 namespace Intrepid 00046 { 00047 00048 // 00049 // 4th-order tensor constructor with NaNs 00050 // 00051 template<typename T, Index N> 00052 inline 00053 Tensor4<T, N>::Tensor4() : 00054 TensorBase<T, Store>::TensorBase() 00055 { 00056 return; 00057 } 00058 00059 template<typename T, Index N> 00060 inline 00061 Tensor4<T, N>::Tensor4(Index const dimension) : 00062 TensorBase<T, Store>::TensorBase(dimension, ORDER) 00063 { 00064 return; 00065 } 00066 00067 // 00068 // 4th-order tensor constructor with a specified value 00069 // 00070 template<typename T, Index N> 00071 inline 00072 Tensor4<T, N>::Tensor4(ComponentValue const value) : 00073 TensorBase<T, Store>::TensorBase(N, ORDER, value) 00074 { 00075 return; 00076 } 00077 00078 template<typename T, Index N> 00079 inline 00080 Tensor4<T, N>::Tensor4(Index const dimension, ComponentValue const value) : 00081 TensorBase<T, Store>::TensorBase(dimension, ORDER, value) 00082 { 00083 return; 00084 } 00085 00086 // 00087 // Create 4th-order tensor from array 00088 // 00089 template<typename T, Index N> 00090 inline 00091 Tensor4<T, N>::Tensor4(T const * data_ptr) : 00092 TensorBase<T, Store>::TensorBase(N, ORDER, data_ptr) 00093 { 00094 return; 00095 } 00096 00097 template<typename T, Index N> 00098 inline 00099 Tensor4<T, N>::Tensor4(Index const dimension, T const * data_ptr) : 00100 TensorBase<T, Store>::TensorBase(dimension, ORDER, data_ptr) 00101 { 00102 return; 00103 } 00104 00105 // 00106 // Copy constructor 00107 // 00108 template<typename T, Index N> 00109 inline 00110 Tensor4<T, N>::Tensor4(Tensor4<T, N> const & A) : 00111 TensorBase<T, Store>::TensorBase(A) 00112 { 00113 return; 00114 } 00115 00116 // 00117 // 4th-order tensor from 2nd-order tensor 00118 // 00119 00120 namespace { 00121 00122 inline 00123 Index 00124 second_to_fourth_dimension(Index const dimension_2nd) 00125 { 00126 Index 00127 dimension_4th = 0; 00128 00129 switch (dimension_2nd) { 00130 00131 default: 00132 std::cerr << "ERROR: " << __PRETTY_FUNCTION__; 00133 std::cerr << std::endl; 00134 std::cerr << "Invalid dimension for 2nd-order tensor."; 00135 std::cerr << std::endl; 00136 exit(1); 00137 break; 00138 00139 case 1: 00140 dimension_4th = 1; 00141 break; 00142 00143 case 4: 00144 dimension_4th = 2; 00145 break; 00146 00147 case 9: 00148 dimension_4th = 3; 00149 break; 00150 00151 case 16: 00152 dimension_4th = 4; 00153 break; 00154 00155 } 00156 00157 return dimension_4th; 00158 } 00159 00160 } //anonymous namespace 00161 00162 template<typename T, Index N> 00163 inline 00164 Tensor4<T, N>::Tensor4(Tensor<T, dimension_square<N>::value> const & A) 00165 { 00166 Index const 00167 dimension_2nd = A.get_dimension(); 00168 00169 Index const 00170 dimension_4th = second_to_fourth_dimension(dimension_2nd); 00171 00172 Tensor4<T, N> & 00173 self = (*this); 00174 00175 self.set_dimension(dimension_4th); 00176 00177 Index const 00178 number_components = dimension_2nd * dimension_2nd; 00179 00180 for (Index i = 0; i < number_components; ++i) { 00181 self[i] = A[i]; 00182 } 00183 00184 return; 00185 } 00186 // 00187 // 4th-order tensor simple destructor 00188 // 00189 template<typename T, Index N> 00190 inline 00191 Tensor4<T, N>::~Tensor4() 00192 { 00193 return; 00194 } 00195 00196 // 00197 // Get dimension 00198 // 00199 template<typename T, Index N> 00200 inline 00201 Index 00202 Tensor4<T, N>::get_dimension() const 00203 { 00204 return IS_DYNAMIC == true ? TensorBase<T, Store>::get_dimension() : N; 00205 } 00206 00207 // 00208 // Set dimension 00209 // 00210 template<typename T, Index N> 00211 inline 00212 void 00213 Tensor4<T, N>::set_dimension(Index const dimension) 00214 { 00215 if (IS_DYNAMIC == true) { 00216 TensorBase<T, Store>::set_dimension(dimension, ORDER); 00217 } 00218 else { 00219 assert(dimension == N); 00220 } 00221 00222 return; 00223 } 00224 00225 // 00226 // 4th-order tensor addition 00227 // 00228 template<typename S, typename T, Index N> 00229 inline 00230 Tensor4<typename Promote<S, T>::type, N> 00231 operator+(Tensor4<S, N> const & A, Tensor4<T, N> const & B) 00232 { 00233 Tensor4<typename Promote<S, T>::type, N> 00234 C(A.get_dimension()); 00235 00236 add(A, B, C); 00237 00238 return C; 00239 } 00240 00241 // 00242 // 4th-order tensor subtraction 00243 // 00244 template<typename S, typename T, Index N> 00245 inline 00246 Tensor4<typename Promote<S, T>::type, N> 00247 operator-(Tensor4<S, N> const & A, Tensor4<T, N> const & B) 00248 { 00249 Tensor4<typename Promote<S, T>::type, N> 00250 C(A.get_dimension()); 00251 00252 subtract(A, B, C); 00253 00254 return C; 00255 } 00256 00257 // 00258 // 4th-order tensor minus 00259 // 00260 template<typename T, Index N> 00261 inline 00262 Tensor4<T, N> 00263 operator-(Tensor4<T, N> const & A) 00264 { 00265 Tensor4<T, N> 00266 B(A.get_dimension()); 00267 00268 minus(A, B); 00269 00270 return B; 00271 } 00272 00273 // 00274 // 4th-order equality 00275 // 00276 template<typename T, Index N> 00277 inline 00278 bool 00279 operator==(Tensor4<T, N> const & A, Tensor4<T, N> const & B) 00280 { 00281 return equal(A, B); 00282 } 00283 00284 // 00285 // 4th-order inequality 00286 // 00287 template<typename T, Index N> 00288 inline 00289 bool 00290 operator!=(Tensor4<T, N> const & A, Tensor4<T, N> const & B) 00291 { 00292 return not_equal(A, B); 00293 } 00294 00295 // 00296 // Scalar 4th-order tensor product 00297 // 00298 template<typename S, typename T, Index N> 00299 inline 00300 typename lazy_disable_if< order_1234<S>, apply_tensor4< Promote<S,T>, N> >::type 00301 operator*(S const & s, Tensor4<T, N> const & A) 00302 { 00303 Tensor4<typename Promote<S, T>::type, N> 00304 B(A.get_dimension()); 00305 00306 scale(A, s, B); 00307 00308 return B; 00309 } 00310 00311 // 00312 // 4th-order tensor scalar product 00313 // 00314 template<typename S, typename T, Index N> 00315 inline 00316 typename lazy_disable_if< order_1234<S>, apply_tensor4< Promote<S,T>, N> >::type 00317 operator*(Tensor4<T, N> const & A, S const & s) 00318 { 00319 Tensor4<typename Promote<S, T>::type, N> 00320 B(A.get_dimension()); 00321 00322 scale(A, s, B); 00323 00324 return B; 00325 } 00326 00327 // 00328 // 4th-order tensor scalar division 00329 // 00330 template<typename S, typename T, Index N> 00331 inline 00332 Tensor4<typename Promote<S, T>::type, N> 00333 operator/(Tensor4<T, N> const & A, S const & s) 00334 { 00335 Tensor4<typename Promote<S, T>::type, N> 00336 B(A.get_dimension()); 00337 00338 divide(A, s, B); 00339 00340 return B; 00341 } 00342 00343 // 00344 // 4th-order scalar tensor division 00345 // 00346 template<typename S, typename T, Index N> 00347 inline 00348 Tensor4<typename Promote<S, T>::type, N> 00349 operator/(S const & s, Tensor4<T, N> const & A) 00350 { 00351 Tensor4<typename Promote<S, T>::type, N> 00352 B(A.get_dimension()); 00353 00354 split(A, s, B); 00355 00356 return B; 00357 } 00358 00359 // 00360 // Indexing for constant 4th order tensor 00361 // \param i index 00362 // \param j index 00363 // \param k index 00364 // \param l index 00365 // 00366 template<typename T, Index N> 00367 inline 00368 T const & 00369 Tensor4<T, N>::operator()( 00370 Index const i, Index const j, Index const k, Index const l) const 00371 { 00372 Tensor4<T, N> const & 00373 self = (*this); 00374 00375 Index const 00376 dimension = self.get_dimension(); 00377 00378 return self[((i * dimension + j) * dimension + k) * dimension + l]; 00379 } 00380 00381 // 00382 // 4th-order tensor indexing 00383 // \param i index 00384 // \param j index 00385 // \param k index 00386 // \param l index 00387 // 00388 template<typename T, Index N> 00389 inline 00390 T & 00391 Tensor4<T, N>::operator()( 00392 Index const i, Index const j, Index const k, Index const l) 00393 { 00394 Tensor4<T, N> & 00395 self = (*this); 00396 00397 Index const 00398 dimension = self.get_dimension(); 00399 00400 return self[((i * dimension + j) * dimension + k) * dimension + l]; 00401 } 00402 00406 template<typename T, Index N> 00407 Tensor4<T, N> 00408 inverse(Tensor4<T, N> const & A) 00409 { 00410 return Tensor4<T, N>(inverse(Tensor<T, N>(A))); 00411 } 00412 00413 } // namespace Intrepid 00414 00415 #endif // Intrepid_MiniTensor_Tensor4_i_h
1.7.6.1