OpenWalnut  1.4.0
WTensor.h
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