OpenWalnut  1.5.0dev
WTensorSym_test.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_TEST_H
26 #define WTENSORSYM_TEST_H
27 
28 #include <string>
29 #include <vector>
30 #include <algorithm>
31 
32 #include <cxxtest/TestSuite.h>
33 #include "../WTensorSym.h"
34 
35 /**
36  * Test class for the WTensorSym template.
37  */
38 class WTensorSymTest : public CxxTest::TestSuite
39 {
40 public:
41  /**
42  * Test access operator ().
43  */
45  {
47  w( 0, 0, 0 ) = 2;
48  w( 0, 0, 1 ) = 3;
49  w( 0, 1, 0 ) = 0;
50  w( 0, 1, 1 ) = 5;
51  w( 1, 0, 0 ) = 2;
52  w( 1, 0, 1 ) = 1;
53  w( 1, 1, 0 ) = 8;
54  w( 1, 1, 1 ) = 10;
55 
56  TS_ASSERT_EQUALS( w( 0, 0, 0 ), 2 );
57  TS_ASSERT_EQUALS( w( 0, 0, 1 ), 2 );
58  TS_ASSERT_EQUALS( w( 0, 1, 0 ), 2 );
59  TS_ASSERT_EQUALS( w( 0, 1, 1 ), 8 );
60  TS_ASSERT_EQUALS( w( 1, 0, 0 ), 2 );
61  TS_ASSERT_EQUALS( w( 1, 0, 1 ), 8 );
62  TS_ASSERT_EQUALS( w( 1, 1, 0 ), 8 );
63  TS_ASSERT_EQUALS( w( 1, 1, 1 ), 10 );
64 
65  // test a symmetric tensor of dimension 1
66  // this should not segfault
68 
69  t( 0, 0, 0, 0 ) = 2.0;
70 
71  TS_ASSERT_EQUALS( t( 0, 0, 0, 0 ), 2.0 );
72  }
73 
74  /**
75  * Test access operator [].
76  */
78  {
79  std::vector< unsigned int > v( 3, 0 );
81 
82  for( v[ 0 ] = 0; v[ 0 ] < 4; ++v[ 0 ] )
83  {
84  for( v[ 1 ] = 0; v[ 1 ] < 4; ++v[ 1 ] )
85  {
86  for( v[ 2 ] = 0; v[ 2 ] < 4; ++v[ 2 ] )
87  {
88  w[ v ] = v[ 0 ] + v[ 1 ] + v[ 2 ];
89  std::vector< unsigned int > v0 = v;
90  std::sort( v0.begin(), v0.end() );
91  TS_ASSERT_EQUALS( w[ v0 ], v[ 0 ] + v[ 1 ] + v[ 2 ] );
92  }
93  }
94  }
95  }
96 
97  /**
98  * Test the standard constructor.
99  */
101  {
102  // create lots of tensors
103  WTensorSym< 1, 1 > t11d;
104  WTensorSym< 1, 2 > t12d;
105  WTensorSym< 1, 3 > t13d;
106  WTensorSym< 1, 4 > t14d;
111  WTensorSym< 2, 1 > t21d;
112  WTensorSym< 2, 2 > t22d;
113  WTensorSym< 2, 3 > t23d;
114  WTensorSym< 2, 4 > t24d;
119  WTensorSym< 3, 5 > t35d;
120  WTensorSym< 4, 3 > t43d;
121  WTensorSym< 5, 2 > t52d;
122  WTensorSym< 6, 3 > t63d;
123 
124  TS_ASSERT_EQUALS( t35d( 0, 4, 2 ), 0.0 );
125  TS_ASSERT_EQUALS( t35d( 1, 4, 0 ), 0.0 );
126  TS_ASSERT_EQUALS( t35d( 0, 3, 0 ), 0.0 );
127  TS_ASSERT_EQUALS( t35d( 2, 4, 1 ), 0.0 );
128  TS_ASSERT_EQUALS( t35d( 0, 2, 2 ), 0.0 );
129  TS_ASSERT_EQUALS( t35d( 4, 1, 4 ), 0.0 );
130  TS_ASSERT_EQUALS( t35d( 4, 4, 4 ), 0.0 );
131  TS_ASSERT_EQUALS( t35d( 3, 4, 3 ), 0.0 );
132 
133  TS_ASSERT_EQUALS( t11d( 0 ), 0.0 );
134  TS_ASSERT_EQUALS( t22d( 0, 1 ), 0.0 );
135  }
136 
137  /**
138  * Test copy constructor.
139  */
141  {
143  w( 0, 1 ) = 2;
144  w( 2, 1 ) = 0.456;
145 
146  WTensorSym< 2, 3 > m( w );
147  TS_ASSERT_EQUALS( m( 1, 0 ), 2 );
148  TS_ASSERT_EQUALS( m( 1, 2 ), 0.456 );
149  }
150 
151  /**
152  * Test copy operator.
153  */
155  {
157  w( 0, 0, 1, 1, 0, 1 ) = 4.0;
158  w( 1, 1, 0, 0, 0, 0 ) = 0.56;
160 
161  {
162  m = w;
163  TS_ASSERT_EQUALS( m( 0, 1, 0, 1, 0, 1 ), 4.0 );
164  TS_ASSERT_EQUALS( m( 1, 0, 0, 0, 1, 0 ), 0.56 );
165  TS_ASSERT_EQUALS( m( 0, 0, 0, 1, 0, 0 ), 0.0 );
166  }
167  }
168 
169  /**
170  * Test casts to Data_T, WValue or WMatrix, depending on the order of the Tensor.
171  */
173  {
174  // make sure these casts compile
175  // we don't actually want to thoroughly test functionality here
176  // more sophisticated tests can be found in WTensorFuncTest
177  // cast to Data_T
178  {
180  t() = 3.0;
181  double d = t;
182  TS_ASSERT_EQUALS( d, 3.0 );
183  }
184  // cast to WValue
185  {
187  t( 0 ) = 3.0;
188  WValue< int > v = t;
189  TS_ASSERT_EQUALS( v[ 0 ], 3.0 );
190  }
191  // cast to WMatrix
192  {
194  t( 0, 1 ) = 3.0;
195  WMatrix< float > m = t;
196  TS_ASSERT_EQUALS( m( 1, 0 ), 3.0 );
197  }
198  }
199 
200  /**
201  * The optimizations for symmetric tensors should not corrupt the result, so we
202  * compare the optimized evaluation function to a simple implementaion.
203  */
205  {
207  // the tensor
208  t( 0, 0, 0, 0 ) = 2.5476;
209  t( 1, 1, 1, 1 ) = 3.5476;
210  t( 2, 2, 2, 2 ) = 4.5476;
211  t( 0, 0, 0, 1 ) = 5.5476;
212  t( 0, 0, 0, 2 ) = 6.5476;
213  t( 1, 1, 1, 0 ) = 7.5476;
214  t( 1, 1, 1, 2 ) = 8.5476;
215  t( 2, 2, 2, 0 ) = 9.5476;
216  t( 2, 2, 2, 1 ) = 10.5476;
217  t( 0, 0, 1, 2 ) = 11.5476;
218  t( 1, 1, 0, 2 ) = 12.5476;
219  t( 2, 2, 0, 1 ) = 13.5476;
220  t( 0, 0, 1, 1 ) = 14.5476;
221  t( 0, 0, 2, 2 ) = 15.5476;
222  t( 1, 1, 2, 2 ) = 16.5476;
223 
224  // the gradients
225  std::vector< WVector3d > gradients;
226  gradients.push_back( WVector3d( 1.0, 0.0, 0.0 ) );
227  gradients.push_back( WVector3d( 0.0, 1.0, 0.0 ) );
228  gradients.push_back( normalize( WVector3d( 1.0, 1.0, 0.0 ) ) );
229  gradients.push_back( normalize( WVector3d( 0.3, 0.4, 0.5 ) ) );
230  gradients.push_back( normalize( WVector3d( -7.0, 3.0, -1.0 ) ) );
231 
232  for( int k = 0; k < 5; ++k )
233  {
234  double res = calcTens( t, gradients[ k ] );
235  TS_ASSERT_DELTA( res, t.evaluateSphericalFunction( gradients[ k ] ), 0.001 );
236  }
237  }
238 
239 private:
240  /**
241  * A helper function that implements the simple approach to tensor evaluation.
242  *
243  * \param t The tensor.
244  * \param v The gradient.
245  *
246  * \return The value of the spherical function in the direction of the gradient.
247  */
248  double calcTens( WTensorSym< 4, 3, double > const& t, WVector3d const& v )
249  {
250  double res = 0.0;
251  for( int a = 0; a < 3; ++a )
252  {
253  for( int b = 0; b < 3; ++b )
254  {
255  for( int c = 0; c < 3; ++c )
256  {
257  for( int d = 0; d < 3; ++d )
258  {
259  res += v[ a ] * v[ b ] * v[ c ] * v[ d ] * t( a, b, c, d );
260  }
261  }
262  }
263  }
264  return res;
265  }
266 };
267 
268 #endif // WTENSORSYM_TEST_H
Matrix template class with variable number of rows and columns.
Definition: WMatrix.h:44
Test class for the WTensorSym template.
void testAccessOperator2()
Test access operator [].
void testCopyConstructor()
Test copy constructor.
void testEvaluateSphericalFunction()
The optimizations for symmetric tensors should not corrupt the result, so we compare the optimized ev...
void testCopyOperator()
Test copy operator.
void testStandardConstructor()
Test the standard constructor.
void testAccessOperator1()
Test access operator ().
double calcTens(WTensorSym< 4, 3, double > const &t, WVector3d const &v)
A helper function that implements the simple approach to tensor evaluation.
void testCastToVariousTypes()
Test casts to Data_T, WValue or WMatrix, depending on the order of the Tensor.
Implements a symmetric tensor that has the same number of components in every direction.
Definition: WTensorSym.h:73
Data_T evaluateSphericalFunction(WValue< Data_T > const &gradient) const
Evaluate - for a given gradient - the spherical function represented by this symmetric tensor.
Definition: WTensorSym.h:152
Base class for all higher level values like tensors, vectors, matrices and so on.
Definition: WValue.h:41