OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WTENSOR_H 00026 #define WTENSOR_H 00027 00028 #include <iostream> 00029 #include <vector> 00030 00031 #include "WTensorSym.h" 00032 00033 // ############################# class WTensor<> ############################################# 00034 /** 00035 * Implements a tensor that has the same number of components in every 00036 * direction. 00037 * 00038 * \tparam order The order of the tensor. 00039 * \tparam dim The dimension of the tensor, i.e. the number of components 00040 * in each direction. 00041 * \tparam Data_T The datatype of the components, double by default. 00042 * 00043 * \note The dimension may never be 0. 00044 * \note The type Data_T may not throw exceptions on construction, destruction or 00045 * during any assignment operator. 00046 * 00047 * Access to specific elements of the tensor can be achieved in 2 ways: 00048 * 00049 * - operator (), whose number of parameters matches the template parameter order. 00050 * - operator [], whose parameter is either an array or a std::vector of appropriate size. 00051 * 00052 * \note The datatype of the array or std::vector can be any type castable to std::size_t. 00053 * \note There is no bounds checking for the array version of operator []. 00054 * \note Operator () is not supported for orders larger than 6. 00055 * 00056 * Examples: 00057 * 00058 * - Construct a tensor of order 2 and dimension 3 (i.e. a 3x3-Matrix): 00059 * 00060 * WTensor< 2, 3 > w; 00061 * 00062 * - Change Element (2,0) to 4.0: 00063 * 00064 * w( 2, 0 ) = 4.0; 00065 * 00066 * - Construct a 4D-vector: 00067 * 00068 * WTensor< 1, 4 > v; 00069 * 00070 * - Access v at position 2: 00071 * 00072 * v( 2 ) = ...; 00073 * 00074 * std::vector< int > i( 1, 2 ); 00075 * v[ i ] = ...; 00076 */ 00077 template< std::size_t order, std::size_t dim, typename Data_T = double > 00078 class WTensor : public WTensorFunc< WTensorBase, order, dim, Data_T > 00079 { 00080 public: 00081 /** 00082 * Standard constructor. 00083 */ 00084 WTensor(); 00085 00086 /** 00087 * Construct a Tensor from a symmetric tensor. 00088 * 00089 * \param t A symmetric tensor. 00090 */ 00091 WTensor( WTensorSym< order, dim, Data_T > const& t ); 00092 00093 /** 00094 * Copy from a symmetric tensor. 00095 * 00096 * \param t A symmetric tensor. 00097 * 00098 * \return new tensor 00099 */ 00100 WTensor const& operator = ( WTensorSym< order, dim, Data_T > const& t ); 00101 }; 00102 00103 template< std::size_t order, std::size_t dim, typename Data_T > 00104 WTensor< order, dim, Data_T >::WTensor() 00105 : WTensorFunc< WTensorBase, order, dim, Data_T >() 00106 { 00107 } 00108 00109 template< std::size_t order, std::size_t dim, typename Data_T > 00110 WTensor< order, dim, Data_T >::WTensor( WTensorSym< order, dim, Data_T > const& t ) 00111 : WTensorFunc< WTensorBase, order, dim, Data_T >() 00112 { 00113 WTensorBase< order, dim, Data_T >::operator = ( t ); 00114 } 00115 00116 template< std::size_t order, std::size_t dim, typename Data_T > 00117 WTensor< order, dim, Data_T > const& WTensor< order, dim, Data_T >::operator = ( WTensorSym< order, dim, Data_T > const& t ) 00118 { 00119 WTensorBase< order, dim, Data_T >::operator = ( t ); 00120 return *this; 00121 } 00122 00123 // ######################## stream output operators ################################# 00124 00125 /** 00126 * Write a tensor of order 0 to an output stream. 00127 * 00128 * \param o An output stream. 00129 * \param t A WTensor. 00130 * 00131 * \return The output stream. 00132 */ 00133 template< std::size_t dim, typename Data_T > 00134 std::ostream& operator << ( std::ostream& o, WTensor< 0, dim, Data_T > const& t ) 00135 { 00136 o << t() << std::endl; 00137 return o; 00138 } 00139 00140 /** 00141 * Write a tensor of order 1 to an output stream. 00142 * 00143 * \param o An output stream. 00144 * \param t A WTensor. 00145 * 00146 * \return The output stream. 00147 */ 00148 template< std::size_t dim, typename Data_T > 00149 std::ostream& operator << ( std::ostream& o, WTensor< 1, dim, Data_T > const& t ) 00150 { 00151 for( std::size_t k = 0; k < dim; ++k ) 00152 { 00153 o << t( k ) << " "; 00154 } 00155 o << std::endl; 00156 return o; 00157 } 00158 00159 /** 00160 * Write a tensor of order 2 to an output stream. 00161 * 00162 * \param o An output stream. 00163 * \param t A WTensor. 00164 * 00165 * \return The output stream. 00166 */ 00167 template< std::size_t dim, typename Data_T > 00168 std::ostream& operator << ( std::ostream& o, WTensor< 2, dim, Data_T > const& t ) 00169 { 00170 for( std::size_t k = 0; k < dim; ++k ) 00171 { 00172 for( std::size_t l = 0; l < dim; ++l ) 00173 { 00174 o << t( k, l ) << " "; 00175 } 00176 o << std::endl; 00177 } 00178 return o; 00179 } 00180 00181 #endif // WTENSOR_H