Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/src/Shared/MiniTensor/Intrepid_MiniTensor_Tensor3.t.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_Tensor3_t_h)
00043 #define Intrepid_MiniTensor_Tensor3_t_h
00044 
00045 namespace Intrepid {
00046 
00047 //
00048 // \return \f$ B = A \cdot u := B_{ij} = A_{ijp} u_p \f$
00049 //
00050 template<typename S, typename T, Index N>
00051 Tensor<typename Promote<S, T>::type, N>
00052 dot(Tensor3<T, N> const & A, Vector<S, N> const & u)
00053 {
00054   Index const
00055   dimension = A.get_dimension();
00056 
00057   assert(u.get_dimension() == dimension);
00058 
00059   Tensor<typename Promote<S, T>::type, N>
00060   B(N);
00061 
00062   for (Index i = 0; i < dimension; ++i) {
00063     for (Index j = 0; j < dimension; ++j) {
00064 
00065       typename Promote<S, T>::type
00066       s = 0.0;
00067 
00068       for (Index p = 0; p < dimension; ++p) {
00069         s += A(i,j,p) * u(p);
00070       }
00071       B(i,j) = s;
00072     }
00073   }
00074 
00075   return B;
00076 }
00077 
00078 //
00079 // \return \f$ B = u \cdot A := B_{ij} = u_p A{pij} \f$
00080 //
00081 template<typename S, typename T, Index N>
00082 Tensor<typename Promote<S, T>::type, N>
00083 dot(Vector<S, N> const & u, Tensor3<T, N> const & A)
00084 {
00085   Index const
00086   dimension = A.get_dimension();
00087 
00088   assert(u.get_dimension() == dimension);
00089 
00090   Tensor<typename Promote<S, T>::type, N>
00091   B(dimension);
00092 
00093   for (Index i = 0; i < dimension; ++i) {
00094     for (Index j = 0; j < dimension; ++j) {
00095 
00096       typename Promote<S, T>::type
00097       s = 0.0;
00098 
00099       for (Index p = 0; p < dimension; ++p) {
00100         s += u(p) * A(p,i,j);
00101       }
00102       B(i,j) = s;
00103     }
00104   }
00105 
00106   return B;
00107 }
00108 
00109 
00110 //
00111 // \return \f$ B = A \cdot u := B_{ij} = A_{ipj} u_p \f$
00112 //
00113 template<typename S, typename T, Index N>
00114 Tensor<typename Promote<S, T>::type, N>
00115 dot2(Tensor3<T, N> const & A, Vector<S, N> const & u)
00116 {
00117   Index const
00118   dimension = A.get_dimension();
00119 
00120   assert(u.get_dimension() == dimension);
00121 
00122   Tensor<typename Promote<S, T>::type, N>
00123   B(dimension);
00124 
00125   for (Index i = 0; i < dimension; ++i) {
00126     for (Index j = 0; j < dimension; ++j) {
00127 
00128       typename Promote<S, T>::type
00129       s = 0.0;
00130 
00131       for (Index p = 0; p < dimension; ++p) {
00132         s += A(i,p,j) * u(p);
00133       }
00134       B(i,j) = s;
00135     }
00136   }
00137 
00138   return B;
00139 }
00140 
00141 //
00142 // \return \f$ B = u \cdot A := B_{ij} = u_p A_{ipj} \f$
00143 //
00144 template<typename S, typename T, Index N>
00145 Tensor<typename Promote<S, T>::type, N>
00146 dot2(Vector<S, N> const & u, Tensor3<T, N> const & A)
00147 {
00148   return dot2(A, u);
00149 }
00150 
00154 template<typename S, typename T, Index N>
00155 Tensor3<typename Promote<S, T>::type, N>
00156 dot(Tensor3<T, N> const & A, Tensor<S, N> const & B)
00157 {
00158   Index const
00159   dimension = A.get_dimension();
00160 
00161   assert(B.get_dimension() == dimension);
00162 
00163   Tensor3<typename Promote<S, T>::type, N>
00164   C(dimension);
00165 
00166   for (Index i = 0; i < dimension; ++i) {
00167     for (Index k = 0; k < dimension; ++k) {
00168       for (Index j = 0; j < dimension; ++j) {
00169 
00170         typename Promote<S, T>::type
00171         s = 0.0;
00172 
00173         for (Index p = 0; p < dimension; ++p) {
00174           s += A(i,j,p) * B(p,k);
00175         }
00176         C(i,j,k) = s;
00177       }
00178     }
00179   }
00180 
00181   return C;
00182 }
00183 
00187 template<typename S, typename T, Index N>
00188 Tensor3<typename Promote<S, T>::type, N>
00189 dot(Tensor<S, N> const & A, Tensor3<T, N> const & B)
00190 {
00191   Index const
00192   dimension = A.get_dimension();
00193 
00194   assert(B.get_dimension() == dimension);
00195 
00196   Tensor3<typename Promote<S, T>::type, N>
00197   C(dimension);
00198 
00199   for (Index i = 0; i < dimension; ++i) {
00200     for (Index k = 0; k < dimension; ++k) {
00201       for (Index j = 0; j < dimension; ++j) {
00202 
00203         typename Promote<S, T>::type
00204         s = 0.0;
00205 
00206         for (Index p = 0; p < dimension; ++p) {
00207           s += A(i,p) * B(p,j,k);
00208         }
00209         C(i,j,k) = s;
00210       }
00211     }
00212   }
00213 
00214   return C;
00215 }
00216 
00220 template<typename S, typename T, Index N>
00221 Tensor3<typename Promote<S, T>::type, N>
00222 dot2(Tensor3<T, N> const & A, Tensor<S, N> const & B)
00223 {
00224   Index const
00225   dimension = A.get_dimension();
00226 
00227   assert(B.get_dimension() == dimension);
00228 
00229   Tensor3<typename Promote<S, T>::type, N>
00230   C(dimension);
00231 
00232   for (Index i = 0; i < dimension; ++i) {
00233     for (Index k = 0; k < dimension; ++k) {
00234       for (Index j = 0; j < dimension; ++j) {
00235 
00236         typename Promote<S, T>::type
00237         s = 0.0;
00238 
00239         for (Index p = 0; p < dimension; ++p) {
00240           s += A(i,p,j) * B(p,k);
00241         }
00242         C(i,j,k) = s;
00243       }
00244     }
00245   }
00246 
00247   return C;
00248 }
00249 
00250 
00254 template<typename S, typename T, Index N>
00255 Tensor3<typename Promote<S, T>::type, N>
00256 dot2(Tensor<S, N> const & A, Tensor3<T, N> const & B)
00257 {
00258   Index const
00259   dimension = A.get_dimension();
00260 
00261   assert(B.get_dimension() == dimension);
00262 
00263   Tensor3<typename Promote<S, T>::type, N>
00264   C(dimension);
00265 
00266   for (Index i = 0; i < dimension; ++i) {
00267     for (Index k = 0; k < dimension; ++k) {
00268       for (Index j = 0; j < dimension; ++j) {
00269 
00270         typename Promote<S, T>::type
00271         s = 0.0;
00272 
00273         for (Index p = 0; p < dimension; ++p) {
00274           s += A(i,p) * B(j,p,k);
00275         }
00276         C(i,j,k) = s;
00277       }
00278     }
00279   }
00280 
00281   return C;
00282 }
00283 
00284 
00285 //
00286 // 3rd-order tensor input
00287 // \param A 3rd-order tensor
00288 // \param is input stream
00289 // \return is input stream
00290 //
00291 template<typename T, Index N>
00292 std::istream &
00293 operator>>(std::istream & is, Tensor3<T, N> & A)
00294 {
00295   Index const
00296   dimension = A.get_dimension();
00297 
00298   for (Index i = 0; i < dimension; ++i) {
00299     for (Index j = 0; j < dimension; ++j) {
00300       for (Index k = 0; k < dimension; ++k) {
00301         is >> A(i,j,k);
00302       }
00303     }
00304   }
00305 
00306   return is;
00307 }
00308 
00309 //
00310 // 3rd-order tensor output
00311 // \param A 3rd-order tensor
00312 // \param os output stream
00313 // \return os output stream
00314 //
00315 template<typename T, Index N>
00316 std::ostream &
00317 operator<<(std::ostream & os, Tensor3<T, N> const & A)
00318 {
00319   Index const
00320   dimension = A.get_dimension();
00321 
00322   if (dimension == 0) {
00323     return os;
00324   }
00325 
00326   for (Index i = 0; i < dimension; ++i) {
00327 
00328     for (Index j = 0; j < dimension; ++j) {
00329 
00330       os << std::scientific << std::setprecision(16) << A(i,j,0);
00331 
00332       for (Index k = 1; k < dimension; ++k) {
00333         os << "," << std::scientific  << std::setprecision(16) << A(i,j,k);
00334       }
00335 
00336       os << std::endl;
00337 
00338     }
00339 
00340     os << std::endl;
00341     os << std::endl;
00342 
00343   }
00344 
00345   return os;
00346 }
00347 
00348 } // namespace Intrepid
00349 
00350 #endif // Intrepid_MiniTensor_Tensor3_t_h