dune-grid
2.1.1
|
00001 #ifndef DUNE_ALBERTA_ALGEBRA_HH 00002 #define DUNE_ALBERTA_ALGEBRA_HH 00003 00004 #include <dune/common/misc.hh> 00005 #include <dune/common/fvector.hh> 00006 #include <dune/common/fmatrix.hh> 00007 00008 namespace Dune 00009 { 00010 00011 namespace Alberta 00012 { 00013 00014 template< class K > 00015 inline static FieldVector< K, 3 > 00016 vectorProduct ( const FieldVector< K, 3 > &u, const FieldVector< K, 3 > &v ) 00017 { 00018 FieldVector< K, 3 > w; 00019 w[ 0 ] = u[ 1 ] * v[ 2 ] - u[ 2 ] * v[ 1 ]; 00020 w[ 1 ] = u[ 2 ] * v[ 0 ] - u[ 0 ] * v[ 2 ]; 00021 w[ 2 ] = u[ 0 ] * v[ 1 ] - u[ 1 ] * v[ 0 ]; 00022 return w; 00023 } 00024 00025 00026 template< class K, int m > 00027 inline static K determinant ( const FieldMatrix< K, 0, m > &matrix ) 00028 { 00029 return K( 1 ); 00030 } 00031 00032 template< class K > 00033 inline static K determinant ( const FieldMatrix< K, 1, 1 > &matrix ) 00034 { 00035 return matrix[ 0 ][ 0 ]; 00036 } 00037 00038 template< class K, int m > 00039 inline static K determinant ( const FieldMatrix< K, 1, m > &matrix ) 00040 { 00041 K sum = SQR( matrix[ 0 ][ 0 ] ); 00042 for( int i = 1; i < m; ++i ) 00043 sum += SQR( matrix[ 0 ][ i ] ); 00044 return sqrt( sum ); 00045 } 00046 00047 template< class K > 00048 inline static K determinant ( const FieldMatrix< K, 2, 2 > &matrix ) 00049 { 00050 return matrix[ 0 ][ 0 ] * matrix[ 1 ][ 1 ] - matrix[ 0 ][ 1 ] * matrix[ 1 ][ 0 ]; 00051 } 00052 00053 template< class K > 00054 inline static K determinant ( const FieldMatrix< K, 2, 3 > &matrix ) 00055 { 00056 return vectorProduct( matrix[ 0 ], matrix[ 1 ] ).two_norm(); 00057 } 00058 00059 template< class K, int m > 00060 inline static K determinant ( const FieldMatrix< K, 2, m > &matrix ) 00061 { 00062 const K tmpA = matrix[ 0 ].two_norm2(); 00063 const K tmpB = matrix[ 1 ].two_norm2(); 00064 const K tmpC = matrix[ 0 ] * matrix[ 1 ]; 00065 return sqrt( tmpA * tmpB - SQR( tmpC ) ); 00066 } 00067 00068 template< class K > 00069 inline static K determinant ( const FieldMatrix< K, 3, 3 > &matrix ) 00070 { 00071 return matrix[ 0 ] * vectorProduct( matrix[ 1 ], matrix[ 2 ] ); 00072 } 00073 00074 00075 template< class K, int m > 00076 inline static K invert ( const FieldMatrix< K, 0, m > &matrix, 00077 FieldMatrix< K, m, 0 > &inverse ) 00078 { 00079 return K( 1 ); 00080 } 00081 00082 template< class K > 00083 inline static K invert ( const FieldMatrix< K, 1, 1 > &matrix, 00084 FieldMatrix< K, 1, 1 > &inverse ) 00085 { 00086 inverse[ 0 ][ 0 ] = K( 1 ) / matrix[ 0 ][ 0 ]; 00087 return matrix[ 0 ][ 0 ]; 00088 } 00089 00090 template< class K, int m > 00091 inline static K invert ( const FieldMatrix< K, 1, m > &matrix, 00092 FieldMatrix< K, m, 1 > &inverse ) 00093 { 00094 K detSqr = matrix[ 0 ].two_norm2(); 00095 K invDetSqr = K( 1 ) / detSqr; 00096 for( int i = 0; i < m; ++i ) 00097 inverse[ i ][ 0 ] = invDetSqr * matrix[ 0 ][ i ]; 00098 return sqrt( detSqr ); 00099 } 00100 00101 template< class K > 00102 inline static K invert ( const FieldMatrix< K, 2, 2 > &matrix, 00103 FieldMatrix< K, 2, 2 > &inverse ) 00104 { 00105 K det = determinant( matrix ); 00106 K invDet = K( 1 ) / det; 00107 inverse[ 0 ][ 0 ] = invDet * matrix[ 1 ][ 1 ]; 00108 inverse[ 0 ][ 1 ] = - invDet * matrix[ 0 ][ 1 ]; 00109 inverse[ 1 ][ 0 ] = - invDet * matrix[ 1 ][ 0 ]; 00110 inverse[ 1 ][ 1 ] = invDet * matrix[ 0 ][ 0 ]; 00111 return det; 00112 } 00113 00114 template< class K, int m > 00115 inline static K invert ( const FieldMatrix< K, 2, m > &matrix, 00116 FieldMatrix< K, m, 2 > &inverse ) 00117 { 00118 const K tmpA = matrix[ 0 ].two_norm2(); 00119 const K tmpB = matrix[ 1 ].two_norm2(); 00120 const K tmpC = matrix[ 0 ] * matrix[ 1 ]; 00121 const K detSqr = tmpA * tmpB - SQR( tmpC ); 00122 const K invDetSqr = K( 1 ) / detSqr; 00123 for( int i = 0; i < m; ++i ) 00124 { 00125 inverse[ i ][ 0 ] = invDetSqr * (tmpB * matrix[ 0 ][ i ] - tmpC * matrix[ 1 ][ i ]); 00126 inverse[ i ][ 1 ] = invDetSqr * (tmpA * matrix[ 1 ][ i ] - tmpC * matrix[ 0 ][ i ]); 00127 } 00128 return sqrt( detSqr ); 00129 } 00130 00131 template< class K > 00132 inline static K invert ( const FieldMatrix< K, 3, 3 > &matrix, 00133 FieldMatrix< K, 3, 3 > &inverse ) 00134 { 00135 return FMatrixHelp::invertMatrix( matrix, inverse ); 00136 } 00137 } 00138 00139 } 00140 00141 #endif // #ifndef DUNE_ALBERTA_ALGEBRA_HH