OpenWalnut  1.5.0dev
WTensorFunctions.cpp
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 #include <vector>
26 
27 #include "WTensorFunctions.h"
28 
29 std::ostream& operator<<( std::ostream& os, const RealEigenSystem& sys )
30 {
31  os << sys[0].first << ", " << sys[0].second << std::endl;
32  os << sys[1].first << ", " << sys[1].second << std::endl;
33  os << sys[2].first << ", " << sys[2].second << std::endl;
34  return os;
35 }
36 
37 std::vector< double > getEigenvaluesCardano( WTensorSym< 2, 3 > const& m )
38 {
39  // this is copied from the gpu glyph shader
40  // src/graphicsEngine/shaders/tensorTools.fs
41  // originally implemented by Mario Hlawitschka
42  const double M_SQRT3 = 1.73205080756887729352744634151;
43  double de = m( 1, 2 ) * m( 1, 0 );
44  double dd = m( 1, 2 ) * m( 1, 2 );
45  double ee = m( 1, 0 ) * m( 1, 0 );
46  double ff = m( 2, 0 ) * m( 2, 0 );
47  double m0 = m( 0, 0 ) + m( 1, 1 ) + m( 2, 2 );
48  double c1 = m( 0, 0 ) * m( 1, 1 ) + m( 0, 0 ) * m( 2, 2 ) + m( 1, 1 ) * m( 2, 2 )
49  - ( dd + ee + ff );
50  double c0 = m( 2, 2 ) * dd + m( 0, 0 ) * ee + m( 1, 1 ) * ff - m( 0, 0 ) * m( 1, 1 ) * m( 2, 2 ) - 2. * m( 2, 0 ) * de;
51 
52  double p, sqrt_p, q, c, s, phi;
53  p = m0 * m0 - 3. * c1;
54  q = m0 * ( p - ( 3. / 2. ) * c1 ) - ( 27. / 2. ) * c0;
55  sqrt_p = sqrt( fabs( p ) );
56 
57  phi = 27. * ( 0.25 * c1 * c1 * ( p - c1 ) + c0 * ( q + 27. / 4. * c0 ) );
58  phi = ( 1. / 3. ) * atan2( sqrt( fabs( phi ) ), q );
59 
60  c = sqrt_p * cos( phi );
61  s = ( 1. / M_SQRT3 ) * sqrt_p * sin( phi );
62 
63  std::vector< double > w( 3 );
64  // fix: swapped w[ 2 ] and w[ 1 ]
65  w[ 2 ] = ( 1. / 3. ) * ( m0 - c );
66  w[ 1 ] = w[ 2 ] + s;
67  w[ 0 ] = w[ 2 ] + c;
68  w[ 2 ] -= s;
69  return w;
70 }
Implements a symmetric tensor that has the same number of components in every direction.
Definition: WTensorSym.h:73