Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/src/Shared/MiniTensor/Intrepid_MiniTensor_Tensor4.i.h
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