MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "MeshDomain1D.hpp" 00002 #include "PlanarDomain.hpp" 00003 #include "CylinderDomain.hpp" 00004 #include "ConicDomain.hpp" 00005 #include "SphericalDomain.hpp" 00006 #include "DomainClassifier.hpp" 00007 #include "MeshImpl.hpp" 00008 #include "CLArgs.hpp" 00009 #include "MsqError.hpp" 00010 #include "TopologyInfo.hpp" 00011 00012 #include "domain.hpp" 00013 #include <iostream> 00014 #include <algorithm> 00015 #include <cstdlib> 00016 00017 using namespace MBMesquite; 00018 00019 class SphereDomainArg : public CLArgs::DoubleListArgI 00020 { 00021 private: 00022 std::vector< MeshDomain* >& domList; 00023 std::vector< int >& dimList; 00024 00025 public: 00026 SphereDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) 00027 : domList( domlist ), dimList( dims ) 00028 { 00029 } 00030 virtual bool value( const std::vector< double >& list ); 00031 }; 00032 bool SphereDomainArg::value( const std::vector< double >& list ) 00033 { 00034 double rad = list[0]; 00035 if( rad <= 0.0 ) return false; 00036 Vector3D center( 0, 0, 0 ); 00037 if( list.size() == 4 ) center.set( list[1], list[2], list[3] ); 00038 domList.push_back( new SphericalDomain( center, rad ) ); 00039 dimList.push_back( 2 ); 00040 return true; 00041 } 00042 00043 class ConicDomainArg : public CLArgs::DoubleListArgI 00044 { 00045 private: 00046 std::vector< MeshDomain* >& domList; 00047 std::vector< int >& dimList; 00048 00049 public: 00050 ConicDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) 00051 : domList( domlist ), dimList( dims ) 00052 { 00053 } 00054 virtual bool value( const std::vector< double >& list ); 00055 }; 00056 bool ConicDomainArg::value( const std::vector< double >& vals ) 00057 { 00058 double base_rad = vals[0]; 00059 double height = vals[1]; 00060 Vector3D axis( 0, 0, 1 ); 00061 if( vals.size() >= 5 ) 00062 { 00063 axis[0] = vals[2]; 00064 axis[1] = vals[3]; 00065 axis[2] = vals[4]; 00066 } 00067 Vector3D point( 0, 0, 0 ); 00068 if( vals.size() == 8 ) 00069 { 00070 axis[0] = vals[5]; 00071 axis[1] = vals[6]; 00072 axis[2] = vals[7]; 00073 } 00074 00075 domList.push_back( new ConicDomain( base_rad, height, axis, point ) ); 00076 dimList.push_back( 2 ); 00077 return true; 00078 } 00079 00080 class CylinderDomainArg : public CLArgs::DoubleListArgI 00081 { 00082 private: 00083 std::vector< MeshDomain* >& domList; 00084 std::vector< int >& dimList; 00085 00086 public: 00087 CylinderDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) 00088 : domList( domlist ), dimList( dims ) 00089 { 00090 } 00091 virtual bool value( const std::vector< double >& list ); 00092 }; 00093 bool CylinderDomainArg::value( const std::vector< double >& vals ) 00094 { 00095 double rad = vals[0]; 00096 Vector3D normal( vals[1], vals[2], vals[3] ); 00097 Vector3D point( 0, 0, 0 ); 00098 if( vals.size() == 7 ) point.set( vals[4], vals[5], vals[6] ); 00099 domList.push_back( new CylinderDomain( rad, normal, point ) ); 00100 dimList.push_back( 2 ); 00101 return true; 00102 } 00103 00104 class PlanarDomainArg : public CLArgs::DoubleListArgI 00105 { 00106 private: 00107 std::vector< MeshDomain* >& domList; 00108 std::vector< int >& dimList; 00109 00110 public: 00111 PlanarDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) 00112 : domList( domlist ), dimList( dims ) 00113 { 00114 } 00115 virtual bool value( const std::vector< double >& list ); 00116 }; 00117 bool PlanarDomainArg::value( const std::vector< double >& list ) 00118 { 00119 Vector3D normal( list[0], list[1], list[2] ); 00120 Vector3D point( 0, 0, 0 ); 00121 if( list.size() == 6 ) point.set( list[3], list[4], list[5] ); 00122 domList.push_back( new PlanarDomain( normal, point ) ); 00123 dimList.push_back( 2 ); 00124 return true; 00125 } 00126 00127 class LineDomainArg : public CLArgs::DoubleListArgI 00128 { 00129 private: 00130 std::vector< MeshDomain* >& domList; 00131 std::vector< int >& dimList; 00132 00133 public: 00134 LineDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) : domList( domlist ), dimList( dims ) 00135 { 00136 } 00137 virtual bool value( const std::vector< double >& list ); 00138 }; 00139 bool LineDomainArg::value( const std::vector< double >& vals ) 00140 { 00141 Vector3D dir( vals[0], vals[1], vals[2] ); 00142 Vector3D point( 0, 0, 0 ); 00143 if( vals.size() == 6 ) point.set( vals[3], vals[4], vals[5] ); 00144 LineDomain* pdom = new LineDomain( point, dir ); 00145 domList.push_back( pdom ); 00146 dimList.push_back( 1 ); 00147 return true; 00148 } 00149 00150 class CircleDomainArg : public CLArgs::DoubleListArgI 00151 { 00152 private: 00153 std::vector< MeshDomain* >& domList; 00154 std::vector< int >& dimList; 00155 00156 public: 00157 CircleDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) 00158 : domList( domlist ), dimList( dims ) 00159 { 00160 } 00161 virtual bool value( const std::vector< double >& list ); 00162 }; 00163 bool CircleDomainArg::value( const std::vector< double >& vals ) 00164 { 00165 double rad = vals[0]; 00166 Vector3D normal( vals[1], vals[2], vals[3] ); 00167 Vector3D point( 0, 0, 0 ); 00168 if( vals.size() == 7 ) point.set( vals[4], vals[5], vals[6] ); 00169 CircleDomain* pdom = new CircleDomain( point, normal, rad ); 00170 domList.push_back( pdom ); 00171 dimList.push_back( 1 ); 00172 return true; 00173 } 00174 00175 class PointDomainArg : public CLArgs::DoubleListArgI 00176 { 00177 private: 00178 std::vector< MeshDomain* >& domList; 00179 std::vector< int >& dimList; 00180 00181 public: 00182 PointDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) 00183 : domList( domlist ), dimList( dims ) 00184 { 00185 } 00186 virtual bool value( const std::vector< double >& list ); 00187 }; 00188 bool PointDomainArg::value( const std::vector< double >& vals ) 00189 { 00190 Vector3D point( vals[0], vals[1], vals[2] ); 00191 PointDomain* pdom = new PointDomain( point ); 00192 domList.push_back( pdom ); 00193 dimList.push_back( 0 ); 00194 return true; 00195 } 00196 00197 std::vector< MeshDomain* > domains; 00198 std::vector< int > domain_dims; 00199 SphereDomainArg sphere_arg( domains, domain_dims ); 00200 ConicDomainArg conic_arg( domains, domain_dims ); 00201 CylinderDomainArg cylinder_arg( domains, domain_dims ); 00202 PlanarDomainArg plane_arg( domains, domain_dims ); 00203 CircleDomainArg circle_arg( domains, domain_dims ); 00204 LineDomainArg line_arg( domains, domain_dims ); 00205 PointDomainArg point_arg( domains, domain_dims ); 00206 CLArgs::ToggleArg skin_mesh( false ); 00207 00208 const char* SPHERE_VALUES[] = { "rad", "x", "y", "z" }; 00209 const char* CYLINDER_VALUES[] = { "rad", "i", "j", "k", "x", "y", "z" }; 00210 const char* CONE_VALUES[] = { "rad", "h", "i", "j", "k", "x", "y", "z" }; 00211 00212 void add_domain_args( CLArgs& args ) 00213 { 00214 args.toggle_flag( SKIN_FLAG, "Mark boundary vertices as fixed (default if no domain specified)", &skin_mesh ); 00215 args.double_list_flag( SPHERE_FLAG, "Spherical domain as center and radius", &sphere_arg ); 00216 args.limit_list_flag( SPHERE_FLAG, 4, SPHERE_VALUES ); 00217 args.limit_list_flag( SPHERE_FLAG, 1, SPHERE_VALUES ); 00218 args.double_list_flag( PLANE_FLAG, "Planar domain as normal and point", &plane_arg ); 00219 args.limit_list_flag( PLANE_FLAG, 3, CYLINDER_VALUES + 1 ); 00220 args.limit_list_flag( PLANE_FLAG, 6, CYLINDER_VALUES + 1 ); 00221 args.double_list_flag( CYLINDER_FLAG, "Cylindrical radius, axis, and point", &cylinder_arg ); 00222 args.limit_list_flag( CYLINDER_FLAG, 4, CYLINDER_VALUES ); 00223 args.limit_list_flag( CYLINDER_FLAG, 7, CYLINDER_VALUES ); 00224 args.double_list_flag( CONE_FLAG, "Conic domain as base radius, height, axis, and base center", &conic_arg ); 00225 args.limit_list_flag( CONE_FLAG, 2, CONE_VALUES ); 00226 args.limit_list_flag( CONE_FLAG, 5, CONE_VALUES ); 00227 args.limit_list_flag( CONE_FLAG, 8, CONE_VALUES ); 00228 args.double_list_flag( LINE_FLAG, "Linear domain as direction and point", &line_arg ); 00229 args.limit_list_flag( LINE_FLAG, 3, CYLINDER_VALUES + 1 ); 00230 args.limit_list_flag( LINE_FLAG, 6, CYLINDER_VALUES + 1 ); 00231 args.double_list_flag( CIRCLE_FLAG, "Circular domain as radius, normal, and center", &circle_arg ); 00232 args.limit_list_flag( CIRCLE_FLAG, 4, CYLINDER_VALUES ); 00233 args.limit_list_flag( CIRCLE_FLAG, 7, CYLINDER_VALUES ); 00234 args.double_list_flag( POINT_FLAG, "Point domain", &point_arg ); 00235 args.limit_list_flag( POINT_FLAG, 3, SPHERE_VALUES + 1 ); 00236 } 00237 00238 MeshDomain* process_domain_args( MeshImpl* mesh ) 00239 { 00240 MsqPrintError err( std::cerr ); 00241 MeshDomain* rval = 0; 00242 00243 if( !domains.empty() ) 00244 { 00245 int max_domain_dim = *std::max_element( domain_dims.begin(), domain_dims.end() ); 00246 std::vector< Mesh::ElementHandle > elems; 00247 mesh->get_all_elements( elems, err ); 00248 std::vector< EntityTopology > types( elems.size() ); 00249 mesh->elements_get_topologies( arrptr( elems ), arrptr( types ), elems.size(), err ); 00250 EntityTopology max_type = *std::max_element( types.begin(), types.end() ); 00251 int max_elem_dim = TopologyInfo::dimension( max_type ); 00252 00253 if( max_domain_dim == max_elem_dim && domains.size() == 1 ) 00254 { 00255 rval = domains.front(); 00256 } 00257 else 00258 { 00259 DomainClassifier* result = new DomainClassifier(); 00260 if( max_domain_dim < max_elem_dim ) 00261 { 00262 DomainClassifier::classify_skin_geometrically( *result, mesh, 1e-4, arrptr( domains ), 00263 arrptr( domain_dims ), domains.size(), err ); 00264 } 00265 else 00266 { 00267 DomainClassifier::classify_geometrically( *result, mesh, 1e-4, arrptr( domains ), arrptr( domain_dims ), 00268 domains.size(), err ); 00269 } 00270 rval = result; 00271 } 00272 } 00273 if( skin_mesh.value() ) 00274 { 00275 mesh->mark_skin_fixed( err, false ); 00276 } 00277 if( err ) 00278 { 00279 std::cerr << err << std::endl; 00280 exit( 3 ); 00281 } 00282 00283 return rval; 00284 }