MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2007 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2008) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file SymMatrix3D.hpp 00028 * \brief Symetric 3x3 Matrix 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #ifndef MSQ_SYM_MATRIX_3D_HPP 00033 #define MSQ_SYM_MATRIX_3D_HPP 00034 00035 #include "Mesquite.hpp" 00036 #include "Vector3D.hpp" 00037 00038 namespace MBMesquite 00039 { 00040 00041 class MESQUITE_EXPORT SymMatrix3D 00042 { 00043 private: 00044 double d_[6]; 00045 00046 public: 00047 enum Term 00048 { 00049 T00 = 0, 00050 T01 = 1, 00051 T02 = 2, 00052 T10 = T01, 00053 T11 = 3, 00054 T12 = 4, 00055 T20 = T02, 00056 T21 = T12, 00057 T22 = 5 00058 }; 00059 00060 inline static Term term( unsigned r, unsigned c ) 00061 { 00062 return (Term)( r <= c ? 3 * r - r * ( r + 1 ) / 2 + c : 3 * c - c * ( c + 1 ) / 2 + r ); 00063 } 00064 00065 SymMatrix3D() {} 00066 00067 SymMatrix3D( double diagonal_value ) 00068 { 00069 d_[T00] = d_[T11] = d_[T22] = diagonal_value; 00070 d_[T01] = d_[T02] = d_[T12] = 0.0; 00071 } 00072 00073 SymMatrix3D( double t00, double t01, double t02, double t11, double t12, double t22 ) 00074 { 00075 d_[T00] = t00; 00076 d_[T01] = t01; 00077 d_[T02] = t02; 00078 d_[T11] = t11; 00079 d_[T12] = t12; 00080 d_[T22] = t22; 00081 } 00082 00083 /**\brief Outer product */ 00084 SymMatrix3D( const Vector3D& u ) 00085 { 00086 d_[T00] = u[0] * u[0]; 00087 d_[T01] = u[0] * u[1]; 00088 d_[T02] = u[0] * u[2]; 00089 d_[T11] = u[1] * u[1]; 00090 d_[T12] = u[1] * u[2]; 00091 d_[T22] = u[2] * u[2]; 00092 } 00093 00094 double& operator[]( unsigned t ) 00095 { 00096 return d_[t]; 00097 } 00098 double operator[]( unsigned t ) const 00099 { 00100 return d_[t]; 00101 } 00102 00103 double& operator()( unsigned short r, unsigned short c ) 00104 { 00105 return d_[term( r, c )]; 00106 } 00107 double operator()( unsigned short r, unsigned short c ) const 00108 { 00109 return d_[term( r, c )]; 00110 } 00111 00112 inline SymMatrix3D& operator+=( const SymMatrix3D& other ); 00113 inline SymMatrix3D& operator-=( const SymMatrix3D& other ); 00114 inline SymMatrix3D& operator*=( double scalar ); 00115 inline SymMatrix3D& operator/=( double scalar ); 00116 }; 00117 00118 inline SymMatrix3D operator-( const SymMatrix3D& m ) 00119 { 00120 return SymMatrix3D( -m[SymMatrix3D::T00], -m[SymMatrix3D::T01], -m[SymMatrix3D::T02], -m[SymMatrix3D::T11], 00121 -m[SymMatrix3D::T12], -m[SymMatrix3D::T22] ); 00122 } 00123 00124 inline SymMatrix3D& SymMatrix3D::operator+=( const SymMatrix3D& other ) 00125 { 00126 d_[0] += other.d_[0]; 00127 d_[1] += other.d_[1]; 00128 d_[2] += other.d_[2]; 00129 d_[3] += other.d_[3]; 00130 d_[4] += other.d_[4]; 00131 d_[5] += other.d_[5]; 00132 return *this; 00133 } 00134 00135 inline SymMatrix3D& SymMatrix3D::operator-=( const SymMatrix3D& other ) 00136 { 00137 d_[0] -= other.d_[0]; 00138 d_[1] -= other.d_[1]; 00139 d_[2] -= other.d_[2]; 00140 d_[3] -= other.d_[3]; 00141 d_[4] -= other.d_[4]; 00142 d_[5] -= other.d_[5]; 00143 return *this; 00144 } 00145 00146 inline SymMatrix3D& SymMatrix3D::operator*=( double s ) 00147 { 00148 d_[0] *= s; 00149 d_[1] *= s; 00150 d_[2] *= s; 00151 d_[3] *= s; 00152 d_[4] *= s; 00153 d_[5] *= s; 00154 return *this; 00155 } 00156 00157 inline SymMatrix3D& SymMatrix3D::operator/=( double s ) 00158 { 00159 d_[0] /= s; 00160 d_[1] /= s; 00161 d_[2] /= s; 00162 d_[3] /= s; 00163 d_[4] /= s; 00164 d_[5] /= s; 00165 return *this; 00166 } 00167 00168 inline SymMatrix3D operator+( const SymMatrix3D& a, const SymMatrix3D& b ) 00169 { 00170 SymMatrix3D r( a ); 00171 r += b; 00172 return r; 00173 } 00174 inline SymMatrix3D operator-( const SymMatrix3D& a, const SymMatrix3D& b ) 00175 { 00176 SymMatrix3D r( a ); 00177 r -= b; 00178 return r; 00179 } 00180 inline SymMatrix3D operator*( const SymMatrix3D& a, double s ) 00181 { 00182 SymMatrix3D r( a ); 00183 r *= s; 00184 return r; 00185 } 00186 inline SymMatrix3D operator*( double s, const SymMatrix3D& a ) 00187 { 00188 SymMatrix3D r( a ); 00189 r *= s; 00190 return r; 00191 } 00192 inline SymMatrix3D operator/( const SymMatrix3D& a, double s ) 00193 { 00194 SymMatrix3D r( a ); 00195 r /= s; 00196 return r; 00197 } 00198 inline SymMatrix3D operator/( double s, const SymMatrix3D& a ) 00199 { 00200 SymMatrix3D r( a ); 00201 r /= s; 00202 return r; 00203 } 00204 00205 inline Vector3D operator*( const Vector3D& v, const SymMatrix3D& m ) 00206 { 00207 return Vector3D( v[0] * m[0] + v[1] * m[1] + v[2] * m[2], v[0] * m[1] + v[1] * m[3] + v[2] * m[4], 00208 v[0] * m[2] + v[1] * m[4] + v[2] * m[5] ); 00209 } 00210 inline Vector3D operator*( const SymMatrix3D& m, const Vector3D& v ) 00211 { 00212 return v * m; 00213 } 00214 00215 /** Calculate the outer product of a vector with itself */ 00216 inline SymMatrix3D outer( const Vector3D& v ) 00217 { 00218 return SymMatrix3D( v[0] * v[0], v[0] * v[1], v[0] * v[2], v[1] * v[1], v[1] * v[2], v[2] * v[2] ); 00219 } 00220 00221 /** Given to vectors u and v, calculate the symmetric matrix 00222 * equal to outer(u,v) + transpose(outer(u,v)) 00223 * equal to outer(v,u) + transpose(outer(v,u)) 00224 */ 00225 inline SymMatrix3D outer_plus_transpose( const Vector3D& u, const Vector3D& v ) 00226 { 00227 return SymMatrix3D( 2 * u[0] * v[0], u[0] * v[1] + u[1] * v[0], u[0] * v[2] + u[2] * v[0], 2 * u[1] * v[1], 00228 u[1] * v[2] + u[2] * v[1], 2 * u[2] * v[2] ); 00229 } 00230 00231 inline const SymMatrix3D& transpose( const SymMatrix3D& a ) 00232 { 00233 return a; 00234 } 00235 00236 inline double det( const SymMatrix3D& a ) 00237 { 00238 return a[0] * a[3] * a[5] + 2.0 * a[1] * a[2] * a[4] - a[0] * a[4] * a[4] - a[3] * a[2] * a[2] - a[5] * a[1] * a[1]; 00239 } 00240 00241 inline SymMatrix3D inverse( const SymMatrix3D& a ) 00242 { 00243 SymMatrix3D result( a[3] * a[5] - a[4] * a[4], a[2] * a[4] - a[1] * a[5], a[1] * a[4] - a[2] * a[3], 00244 a[0] * a[5] - a[2] * a[2], a[1] * a[2] - a[0] * a[4], a[0] * a[3] - a[1] * a[1] ); 00245 result /= det( a ); 00246 return result; 00247 } 00248 00249 inline double Frobenius_2( const SymMatrix3D& a ) 00250 { 00251 return a[0] * a[0] + 2 * a[1] * a[1] + 2 * a[2] * a[2] + a[3] * a[3] + 2 * a[4] * a[5] + a[5] * a[5]; 00252 } 00253 00254 inline double Frobenius( const SymMatrix3D& a ) 00255 { 00256 return std::sqrt( Frobenius_2( a ) ); 00257 } 00258 00259 } // namespace MBMesquite 00260 00261 #endif