moab
|
00001 /* 00002 * Copyright (c) 2005 Lawrence Livermore National Laboratory under 00003 * contract number B545069 with the University of Wisconsin - Madison. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00017 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 */ 00025 00026 #include <math.h> 00027 00028 #include "measure.hpp" 00029 00030 class CartVect { 00031 private: 00032 double coords[3]; 00033 00034 public: 00035 00036 inline CartVect() {} 00037 00038 inline CartVect( double tx, double ty, double tz ) { set(tx,ty,tz); } 00039 00040 inline CartVect( const CartVect& other ) { set( other.coords); } 00041 00042 inline void set( double tx, double ty, double tz ) 00043 { coords[0] = tx; coords[1] = ty; coords[2] = tz; } 00044 00045 inline void set( const double* c ) 00046 { coords[0] = c[0]; coords[1] = c[1]; coords[2] = c[2]; } 00047 00048 inline double x() const { return coords[0]; } 00049 inline double y() const { return coords[1]; } 00050 inline double z() const { return coords[2]; } 00051 00052 inline CartVect& operator+=( const CartVect& other ) 00053 { 00054 coords[0] += other.coords[0]; 00055 coords[1] += other.coords[1]; 00056 coords[2] += other.coords[2]; 00057 return *this; 00058 } 00059 00060 inline CartVect& operator-=( const CartVect& other ) 00061 { 00062 coords[0] -= other.coords[0]; 00063 coords[1] -= other.coords[1]; 00064 coords[2] -= other.coords[2]; 00065 return *this; 00066 } 00067 00068 inline CartVect& operator*=( const CartVect& other ); 00069 00070 inline double lensqr() const; 00071 00072 inline double len() const; 00073 00074 inline CartVect operator~( ) const; 00075 00076 00077 inline CartVect& operator*=( double a ) 00078 { 00079 coords[0] *= a; 00080 coords[1] *= a; 00081 coords[2] *= a; 00082 return *this; 00083 } 00084 00085 inline CartVect& operator/=( double a ) 00086 { 00087 coords[0] /= a; 00088 coords[1] /= a; 00089 coords[2] /= a; 00090 return *this; 00091 } 00092 00093 00094 }; 00095 00096 inline CartVect operator+( const CartVect& v1, const CartVect& v2 ) 00097 { 00098 CartVect rval(v1); 00099 rval += v2; 00100 return rval; 00101 } 00102 00103 inline CartVect operator-( const CartVect& v1, const CartVect& v2 ) 00104 { 00105 CartVect rval(v1); 00106 rval -= v2; 00107 return rval; 00108 } 00109 00110 inline double operator%( const CartVect& v1, const CartVect& v2 ) 00111 { 00112 return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z(); 00113 } 00114 00115 inline CartVect operator*( const CartVect& v1, const CartVect& v2 ) 00116 { 00117 return CartVect( v1.y() * v2.z() - v1.z() * v2.y(), 00118 v1.z() * v2.x() - v1.x() * v2.z(), 00119 v1.x() * v2.y() - v1.y() * v2.x() ); 00120 } 00121 00122 inline CartVect CartVect::operator~() const 00123 { 00124 double invlen = 1.0 / len(); 00125 return CartVect( invlen * x(), invlen * y(), invlen * z() ); 00126 } 00127 00128 inline CartVect& CartVect::operator*=( const CartVect& other ) 00129 { return *this = *this * other; } 00130 00131 inline double CartVect::lensqr() const 00132 { return *this % *this; } 00133 00134 inline double CartVect::len() const 00135 { return sqrt(lensqr()); } 00136 00137 inline static double tet_volume( const CartVect& v0, 00138 const CartVect& v1, 00139 const CartVect& v2, 00140 const CartVect& v3 ) 00141 { 00142 return 1./6. * ( ((v1 - v0) * (v2 - v0)) % (v3 - v0) ); 00143 } 00144 00145 double edge_length( const double* start_vtx_coords, 00146 const double* end_vtx_coords ) 00147 { 00148 const CartVect* start = reinterpret_cast<const CartVect*>(start_vtx_coords); 00149 const CartVect* end = reinterpret_cast<const CartVect*>( end_vtx_coords); 00150 return (*start - *end).len(); 00151 } 00152 00153 double measure( moab::EntityType type, 00154 int num_vertices, 00155 const double* vertex_coordinates ) 00156 { 00157 const CartVect* coords = reinterpret_cast<const CartVect*>(vertex_coordinates); 00158 switch( type ) 00159 { 00160 case moab::MBEDGE: 00161 return (coords[0] - coords[1]).len(); 00162 case moab::MBTRI: 00163 return 0.5 * ((coords[1] - coords[0]) * (coords[2] - coords[0])).len(); 00164 case moab::MBQUAD: 00165 num_vertices = 4; 00166 case moab::MBPOLYGON: 00167 { 00168 CartVect mid(0,0,0); 00169 for (int i = 0; i < num_vertices; ++i) 00170 mid += coords[i]; 00171 mid /= num_vertices; 00172 00173 double sum = 0.0; 00174 for (int i = 0; i < num_vertices; ++i) 00175 { 00176 int j = (i+1)%num_vertices; 00177 sum += ((mid - coords[i]) * (mid - coords[j])).len(); 00178 } 00179 return 0.5 * sum; 00180 } 00181 case moab::MBTET: 00182 return tet_volume( coords[0], coords[1], coords[2], coords[3] ) ; 00183 case moab::MBPYRAMID: 00184 return tet_volume( coords[0], coords[1], coords[2], coords[4] ) + 00185 tet_volume( coords[0], coords[2], coords[3], coords[4] ) ; 00186 case moab::MBPRISM: 00187 return tet_volume( coords[0], coords[1], coords[2], coords[5] ) + 00188 tet_volume( coords[3], coords[5], coords[4], coords[0] ) + 00189 tet_volume( coords[1], coords[4], coords[5], coords[0] ) ; 00190 case moab::MBHEX: 00191 return tet_volume( coords[0], coords[1], coords[3], coords[4] ) + 00192 tet_volume( coords[7], coords[3], coords[6], coords[4] ) + 00193 tet_volume( coords[4], coords[5], coords[1], coords[6] ) + 00194 tet_volume( coords[1], coords[6], coords[3], coords[4] ) + 00195 tet_volume( coords[2], coords[6], coords[3], coords[1] ) ; 00196 default: 00197 return 0.0; 00198 } 00199 } 00200