OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WTensorSym.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WTENSORSYM_H
26 #define WTENSORSYM_H
27 
28 #include <iostream>
29 #include <vector>
30 
31 #include "WTensorBase.h"
32 
33 // ############################# class WTensorSym<> #############################################
34 
35 /**
36  * Implements a symmetric tensor that has the same number of components in every
37  * direction. A symmetric tensor has the same value for every permutation of the indices.
38  *
39  * For example, t(i,j) = t(j,i) for a tensor of order 2, and t(i,j,k) = t(j,i,k) = t(i,k,j)
40  * = t(j,k,i) = t(k,i,j) = t(k,j,i) for a tensor of order 3.
41  *
42  * \tparam order The order of the tensor.
43  * \tparam dim The dimension of the tensor, i.e. the number of components
44  * in each direction.
45  * \tparam Data_T The datatype of the components, double by default.
46  *
47  * \note The dimension may never be 0.
48  * \note The type Data_T may not throw exceptions on construction, destruction or
49  * during any assignment operator.
50  *
51  * Access to specific elements of the tensor can be achieved in 2 ways:
52  *
53  * - operator (), whose number of parameters matches the template parameter order.
54  * - operator [], whose parameter is either an array or a std::vector of appropriate size.
55  *
56  * \note The datatype of the array or std::vector can be any type castable to std::size_t.
57  * \note There is no bounds checking for the array version of operator [].
58  * \note Operator () is not supported for orders larger than 6.
59  *
60  * This class optimizes memory usage. For example, for a symmetric tensor of order 2 and
61  * dimension 3, only 6 values (instead of 9) need to be stored. However, there is additional
62  * memory overhead per class (i.e. per allocation of the template parameters), which is of
63  * constant size and thus does not depend on the number of instances.
64  *
65  * Usage and operators are the same as with WTensor. Note that changes to an
66  * element t(i,j,k,...) also change every element whose indices are a permutation of i,j,k... .
67  * \see WTensor
68  */
69 template< std::size_t order, std::size_t dim, typename Data_T = double >
70 class WTensorSym : public WTensorFunc< WTensorBaseSym, order, dim, Data_T >
71 {
72 public:
73  /**
74  * Default constructor of the symmetric tensor.
75  */
76  WTensorSym();
77 
78  /**
79  * Constructs and initializes the symmetrical Tensor with a WValue.
80  *
81  * \note The same ordering as for the data member is required.
82  *
83  * \param data The components in same ordering as for the data member \c m_data is required, (\see m_data).
84  */
85  explicit WTensorSym( const WValue< Data_T >& data );
86 
87 protected:
88 private:
89 };
90 
91 template< std::size_t order, std::size_t dim, typename Data_T >
93  : WTensorFunc< WTensorBaseSym, order, dim, Data_T >()
94 {
95 }
96 
97 template< std::size_t order, std::size_t dim, typename Data_T >
99  : WTensorFunc< WTensorBaseSym, order, dim, Data_T >( data )
100 {
101 }
102 // ######################## stream output operators #################################
103 
104 /**
105  * Write a symmetric tensor of order 0 to an output stream.
106  *
107  * \param o An output stream.
108  * \param t A WTensorSym.
109  *
110  * \return The output stream.
111  */
112 template< std::size_t dim, typename Data_T >
113 std::ostream& operator << ( std::ostream& o, WTensorSym< 0, dim, Data_T > const& t )
114 {
115  o << t() << std::endl;
116  return o;
117 }
118 
119 /**
120  * Write a symmetric tensor of order 1 to an output stream.
121  *
122  * \param o An output stream.
123  * \param t A WTensorSym.
124  *
125  * \return The output stream.
126  */
127 template< std::size_t dim, typename Data_T >
128 std::ostream& operator << ( std::ostream& o, WTensorSym< 1, dim, Data_T > const& t )
129 {
130  for( std::size_t k = 0; k < dim; ++k )
131  {
132  o << t( k ) << " ";
133  }
134  o << std::endl;
135  return o;
136 }
137 
138 /**
139  * Write a symmetric tensor of order 2 to an output stream.
140  *
141  * \param o An output stream.
142  * \param t A WTensorSym.
143  *
144  * \return The output stream.
145  */
146 template< std::size_t dim, typename Data_T >
147 std::ostream& operator << ( std::ostream& o, WTensorSym< 2, dim, Data_T > const& t )
148 {
149  for( std::size_t k = 0; k < dim; ++k )
150  {
151  for( std::size_t l = 0; l < dim; ++l )
152  {
153  o << t( k, l ) << " ";
154  }
155  o << std::endl;
156  }
157  return o;
158 }
159 // ######################## a utility function #################################
160 
161 /**
162  * This calculates the multiplicity of the elements of a 3-dimensional
163  * symmetric tensor. (see Özarslan's paper from 2003)
164  * In a (super-)symmetric tensor, all permutations of a given set of Indices
165  * i_1, i_2, ... i_order ( i_j in 0,1,2 ) refer to the same data element.
166  * This means each data element can be identified by the amount of 0's, 1's
167  * and 2's in its index list. Permutations do not change these amounts, thus
168  * different data elements must differ in amount of 0's, 1's and 2's. The number of
169  * permutations that exist on the index list of a data element is its multiplicity.
170  *
171  * \param order The order of the tensor.
172  * \param numZeros How many elements of the permutation equal 0.
173  * \param numOnes How many elements of the permutation equal 1.
174  * \param numTwos How many elements of the permutation equal 2.
175  */
176 std::size_t calcSupersymmetricTensorMultiplicity( std::size_t order, std::size_t numZeros, std::size_t numOnes, std::size_t numTwos );
177 
178 #endif // WTENSORSYM_H