moab
|
00001 #ifndef MOABMC_HPP 00002 #define MOABMC_HPP 00003 00004 #include "moab/Interface.hpp" 00005 #include "MBTagConventions.hpp" 00006 00007 #include <vector> 00008 #include <map> 00009 #include <string> 00010 #include <assert.h> 00011 00012 #include "moab/OrientedBoxTreeTool.hpp" 00013 00014 class RefEntity; 00015 00016 struct DagmcVolData { 00017 int mat_id; 00018 double density, importance; 00019 std::string comp_name; 00020 }; 00021 00022 00023 namespace moab { 00024 00025 class CartVect; 00026 00027 #define DAGMC_VERSION 1.0 00028 #define DAGMC_VERSION_STRING "1.0" 00029 #define DAGMC_INTERFACE_REVISION "$Rev$" 00030 00031 00032 class DagMC 00033 { 00034 public: 00035 static DagMC *instance(Interface *mb_impl = NULL); 00036 00037 00038 ~DagMC(); 00039 00041 static float version(std::string *version_string = NULL); 00043 static unsigned int interface_revision(); 00044 00045 00046 /* SECTION I: Geometry Initialization */ 00047 00058 ErrorCode load_file(const char* cfile, 00059 const double facet_tolerance = 0); 00060 00061 /*\brief Use pre-loaded geometry set 00062 * 00063 * Works like load_file, but using data that has been externally 00064 * loaded into DagMC's MOAB instance. 00065 * Only one of the two functions should be called. 00066 * 00067 * TODO: this function should accept a parameter, being the 00068 * entity set to use for DagMC's data. Currently DagMC always 00069 * assumes that all the contents of its MOAB instance belong to it. 00070 */ 00071 ErrorCode load_existing_contents(); 00072 00079 ErrorCode init_OBBTree(); 00080 00081 private: 00083 ErrorCode finish_loading(); 00084 00086 bool have_obb_tree(); 00087 00089 ErrorCode get_impl_compl(); 00090 00092 ErrorCode build_obbs(Range &surfs, Range &vols); 00093 00095 ErrorCode build_obb_impl_compl(Range &surfs); 00096 00097 00098 /* SECTION II: Fundamental Geometry Operations/Queries */ 00099 public: 00100 00109 class RayHistory { 00110 00111 public: 00116 void reset(); 00117 00123 void reset_to_last_intersection(); 00124 00129 void rollback_last_intersection(); 00130 00134 int size() const { return prev_facets.size(); } 00135 00136 private: 00137 std::vector<EntityHandle> prev_facets; 00138 00139 friend class DagMC; 00140 00141 }; 00142 00180 ErrorCode ray_fire(const EntityHandle volume, 00181 const double ray_start[3], const double ray_dir[3], 00182 EntityHandle& next_surf, double& next_surf_dist, 00183 RayHistory* history = NULL, double dist_limit = 0, 00184 int ray_orientation = 1, 00185 OrientedBoxTreeTool::TrvStats* stats = NULL ); 00186 00202 ErrorCode point_in_volume(const EntityHandle volume, 00203 const double xyz[3], 00204 int& result, 00205 const double* uvw = NULL, 00206 const RayHistory* history = NULL ); 00207 00216 ErrorCode point_in_volume_slow( const EntityHandle volume, const double xyz[3], int& result ); 00217 00218 00235 ErrorCode test_volume_boundary( const EntityHandle volume, const EntityHandle surface, 00236 const double xyz[3], const double uvw[3], int& result, 00237 const RayHistory* history = NULL ); 00238 00245 ErrorCode closest_to_location( EntityHandle volume, const double point[3], double& result); 00246 00248 ErrorCode measure_volume( EntityHandle volume, double& result ); 00249 00251 ErrorCode measure_area( EntityHandle surface, double& result ); 00252 00256 ErrorCode surface_sense( EntityHandle volume, 00257 int num_surfaces, 00258 const EntityHandle* surfaces, 00259 int* senses_out ); 00260 00264 ErrorCode surface_sense( EntityHandle volume, EntityHandle surface, int& sense_out ); 00265 00275 ErrorCode get_angle(EntityHandle surf, const double xyz[3], double angle[3], 00276 const RayHistory* history = NULL ); 00277 00285 ErrorCode next_vol( EntityHandle surface, EntityHandle old_volume, 00286 EntityHandle& new_volume ); 00287 00288 private: 00295 ErrorCode CAD_ray_intersect(const double *point, 00296 const double *dir, 00297 const double huge_val, 00298 std::vector<double> &distances, 00299 std::vector<EntityHandle> &surfaces, 00300 double &len); 00301 00307 ErrorCode boundary_case( EntityHandle volume, int& result, 00308 double u, double v, double w, 00309 EntityHandle facet, 00310 EntityHandle surface); 00311 00315 ErrorCode poly_solid_angle( EntityHandle face, const CartVect& point, double& area ); 00316 00317 /* SECTION III: Indexing & Cross-referencing */ 00318 public: 00319 /* Most calling apps refer to geometric entities with a combination of 00320 * base-1/0 ordinal index (or rank) and global ID (or name). 00321 * DagMC also has an internal EntityHandle reference to each geometric entity. 00322 * These method provide ways to translate from one to the other. 00323 */ 00324 00326 EntityHandle entity_by_index( int dimension, int index ); 00328 int id_by_index( int dimension, int index ); 00330 EntityHandle entity_by_id( int dimension, int id ); 00333 int index_by_handle( EntityHandle handle ); 00335 int get_entity_id(EntityHandle this_ent); 00336 00344 int num_entities( int dimension ); 00345 00346 private: 00348 ErrorCode build_indices(Range &surfs, Range &vols); 00349 00350 00351 /* SECTION IV: Handling DagMC settings */ 00352 public: 00353 00355 double overlap_thickness() {return overlapThickness;} 00357 double numerical_precision() {return numericalPrecision;} 00359 double faceting_tolerance() {return facetingTolerance;} 00361 bool use_CAD() {return useCAD;} 00362 00364 void set_overlap_thickness( double new_overlap_thickness ); 00365 00369 void set_numerical_precision( double new_precision ); 00370 00372 void set_use_CAD( bool use_cad ); 00373 00374 /* SECTION V: Metadata handling */ 00380 ErrorCode detect_available_props( std::vector<std::string>& keywords_out ); 00381 00394 ErrorCode parse_properties( const std::vector<std::string>& keywords, 00395 const std::map<std::string,std::string>& synonyms = no_synonyms ); 00396 00406 ErrorCode prop_value( EntityHandle eh, const std::string& prop, std::string& value ); 00407 00417 ErrorCode prop_values( EntityHandle eh, const std::string& prop, 00418 std::vector< std::string >& value ); 00419 00427 bool has_prop( EntityHandle eh, const std::string& prop ); 00428 00436 ErrorCode get_all_prop_values( const std::string& prop, std::vector<std::string>& return_list ); 00437 00448 ErrorCode entities_by_property( const std::string& prop, std::vector<EntityHandle>& return_list, 00449 int dimension = 0, const std::string* value = NULL ); 00450 00451 bool is_implicit_complement(EntityHandle volume); 00452 00454 Tag name_tag() {return nameTag;} 00455 00456 // Get the tag used to associate OBB trees with geometry in load_file(..). 00457 Tag obb_tag() {return obbTag;} 00458 Tag geom_tag() {return geomTag;} 00459 Tag id_tag() {return idTag;} 00460 Tag sense_tag() { return senseTag; } 00461 00462 private: 00464 void tokenize( const std::string& str, 00465 std::vector<std::string>& tokens, 00466 const char* delimiters ) const; 00467 00468 // a common type within the property and group name functions 00469 typedef std::map<std::string, std::string> prop_map; 00470 00472 ErrorCode get_group_name( EntityHandle group_set, std::string& name ); 00474 ErrorCode parse_group_name( EntityHandle group_set, prop_map& result ); 00476 ErrorCode append_packed_string( Tag, EntityHandle, std::string& ); 00478 ErrorCode unpack_packed_string( Tag tag, EntityHandle eh, 00479 std::vector< std::string >& values ); 00480 00481 std::vector<EntityHandle>& surf_handles() {return entHandles[2];} 00482 std::vector<EntityHandle>& vol_handles() {return entHandles[3];} 00483 std::vector<EntityHandle>& group_handles() {return entHandles[4];} 00484 00485 Tag get_tag( const char* name, int size, TagType store, DataType type, 00486 const void* def_value = NULL, bool create_if_missing = true); 00487 00488 /* SECTION VI: Other */ 00489 public: 00490 OrientedBoxTreeTool *obb_tree() {return &obbTree;} 00491 00492 ErrorCode write_mesh(const char* ffile, 00493 const int flen); 00494 00495 // get the corners of the OBB for a given volume 00496 ErrorCode getobb(EntityHandle volume, double minPt[3], double maxPt[3]); 00497 00498 // get the center point and three vectors for the OBB of a given volume 00499 ErrorCode getobb(EntityHandle volume, double center[3], 00500 double axis1[3], double axis2[3], double axis3[3]); 00501 00502 // get the root of the obbtree for a given entity 00503 ErrorCode get_root(EntityHandle vol_or_surf, EntityHandle &root); 00504 00505 // Get the instance of MOAB used by functions in this file. 00506 Interface* moab_instance() {return mbImpl;} 00507 00508 00509 private: 00510 00511 DagMC(Interface *mb_impl); 00512 00513 static void create_instance(Interface *mb_impl = NULL); 00514 00515 /* PRIVATE MEMBER DATA */ 00516 00517 static DagMC *instance_; 00518 Interface *mbImpl; 00519 00520 OrientedBoxTreeTool obbTree; 00521 EntityHandle impl_compl_handle; 00522 Tag obbTag, geomTag, idTag, nameTag, senseTag, facetingTolTag; 00523 00524 std::vector<EntityHandle> entHandles[5]; 00525 // store some lists indexed by handle 00526 // this is the lowest-valued handle among entity sets representing 00527 // surfaces & volumes 00528 EntityHandle setOffset; 00529 // list of obbTree root sets for surfaces and volumes, 00530 // indexed by [surf_or_vol_handle - setOffset] 00531 std::vector<EntityHandle> rootSets; 00532 // entity index (contiguous 1-N indices) indexed like rootSets are 00533 std::vector<int> entIndices; 00534 00535 // corresponding geometric entities indexed like rootSets are 00536 std::vector<RefEntity *> geomEntities; 00537 00538 // metadata 00539 // an empty synonym map to provide as a default argument to parse_properties() 00540 static const std::map<std::string,std::string> no_synonyms; 00541 // a map from the canonical property names to the tags representing them 00542 std::map<std::string, Tag> property_tagmap; 00543 00544 char implComplName[NAME_TAG_SIZE]; 00545 00546 double overlapThickness; 00547 double numericalPrecision; 00548 double facetingTolerance, defaultFacetingTolerance; 00549 bool useCAD; 00550 bool have_cgm_geom; 00551 00552 // temporary storage so functions don't have to reallocate vectors 00553 // for ray_fire: 00554 std::vector<double> distList; 00555 std::vector<EntityHandle> prevFacetList, surfList, facetList; 00556 // for point_in_volume: 00557 std::vector<double> disList; 00558 std::vector<int> dirList; 00559 std::vector<EntityHandle> surList, facList; 00560 00561 // for (optional) counting 00562 long long int n_pt_in_vol_calls, n_ray_fire_calls; 00563 00564 }; 00565 00566 inline DagMC *DagMC::instance(Interface *mb_impl) 00567 { 00568 if (NULL == instance_) create_instance(mb_impl); 00569 00570 return instance_; 00571 } 00572 00573 inline EntityHandle DagMC::entity_by_index( int dimension, int index ) 00574 { 00575 assert(2 <= dimension && 3 >= dimension && (unsigned) index < entHandles[dimension].size()); 00576 return entHandles[dimension][index]; 00577 } 00578 00579 inline int DagMC::index_by_handle( EntityHandle handle ) 00580 { 00581 assert(handle-setOffset < entIndices.size()); 00582 return entIndices[handle-setOffset]; 00583 } 00584 00585 inline int DagMC::num_entities( int dimension ) 00586 { 00587 assert(0 <= dimension && 3 >= dimension); 00588 00589 return entHandles[dimension].size() - 1; 00590 } 00591 00592 // get the root of the obbtree for a given entity 00593 inline ErrorCode DagMC::get_root(EntityHandle vol_or_surf, EntityHandle &root) 00594 { 00595 unsigned int index = vol_or_surf - setOffset; 00596 root = (index < rootSets.size() ? rootSets[index] : 0); 00597 return (root ? MB_SUCCESS : MB_INDEX_OUT_OF_RANGE); 00598 } 00599 00600 } // namespace moab 00601 00602 #endif 00603