moab
|
00001 #include "MeshRefiner.hpp" 00002 00003 #include "EdgeSizeEvaluator.hpp" 00004 #include "EntityRefiner.hpp" 00005 #include "moab/Interface.hpp" 00006 #include "RefinerTagManager.hpp" 00007 #include "MeshOutputFunctor.hpp" 00008 00009 #ifdef USE_MPI 00010 #include "moab/ParallelComm.hpp" 00011 #include "moab_mpi.h" 00012 #else // USE_MPI 00013 typedef int MPI_Comm; 00014 #endif // USE_MPI 00015 00016 namespace moab { 00017 00024 MeshRefiner::MeshRefiner( Interface* imesh, Interface* omesh ) 00025 { 00026 this->mesh_in = imesh; 00027 this->mesh_out = omesh; 00028 this->tag_manager = new RefinerTagManager( this->mesh_in, this->mesh_out ); 00029 this->output_functor = new MeshOutputFunctor( this->tag_manager ); 00030 this->entity_refiner = 0; 00031 this->comm = ParallelComm::get_pcomm( this->mesh_out, 0 ); 00032 } 00033 00039 MeshRefiner::~MeshRefiner() 00040 { 00041 delete this->tag_manager; 00042 delete this->output_functor; 00043 if ( this->entity_refiner ) 00044 delete this->entity_refiner; 00045 } 00046 00052 bool MeshRefiner::set_entity_refiner( EntityRefiner* er ) 00053 { 00054 if ( ! er || er == this->entity_refiner ) 00055 return false; 00056 00057 this->entity_refiner = er; 00058 return true; 00059 } 00060 00064 void MeshRefiner::reset_vertex_tags() 00065 { 00066 this->tag_manager->reset_vertex_tags(); 00067 } 00068 00072 int MeshRefiner::add_vertex_tag( Tag tag_handle ) 00073 { 00074 return this->tag_manager->add_vertex_tag( tag_handle ); 00075 } 00076 00077 struct MeshRefinerIterator { 00078 Range subset; 00079 EntityHandle destination_set; 00080 }; 00081 00088 bool MeshRefiner::refine( Range& range ) 00089 { 00090 this->tag_manager->create_output_tags(); 00091 if ( ! this->entity_refiner->prepare( this->tag_manager, this->output_functor ) ) 00092 { // Oops, perhaps the edge_size_evaluator was not set? 00093 return false; 00094 } 00095 00096 MeshRefinerIterator entry; 00097 std::vector<MeshRefinerIterator> work; 00098 00099 entry.subset = range; 00100 entry.destination_set = 0; 00101 work.push_back( entry ); 00102 00103 while ( ! work.empty() ) 00104 { 00105 entry = work.back(); 00106 work.pop_back(); 00107 this->output_functor->destination_set = entry.destination_set; 00108 for ( Range::const_iterator it = entry.subset.begin(); it != entry.subset.end(); ++ it ) 00109 { 00110 EntityType etyp = this->mesh_in->type_from_handle( *it ); 00111 if ( etyp == MBENTITYSET ) 00112 { 00113 Range set_ents; 00114 if ( this->mesh_in->get_entities_by_handle( *it, set_ents, false ) == MB_SUCCESS ) 00115 { 00116 // Create a matching set on the output mesh. 00117 MeshRefinerIterator set_work; 00118 unsigned int set_work_opts; 00119 this->mesh_in->get_meshset_options( *it, set_work_opts ); 00120 this->mesh_out->create_meshset( set_work_opts, set_work.destination_set ); 00121 set_work.subset = set_ents; 00122 work.push_back( set_work ); 00123 // Copy any per-element tag values the user has requested to the output set. 00124 this->tag_manager->set_element_tags_from_ent( *it ); 00125 this->tag_manager->assign_element_tags( set_work.destination_set ); 00126 // Copy the global ID to the new set (assuming it exists). 00127 this->tag_manager->copy_gid( *it, set_work.destination_set ); 00128 } 00129 } 00130 else 00131 { 00132 this->tag_manager->set_element_tags_from_ent( *it ); 00133 this->tag_manager->set_element_procs_from_ent( *it ); 00134 this->entity_refiner->refine_entity( etyp, *it ); 00135 } 00136 } 00137 } 00138 this->output_functor->assign_global_ids( this->comm ); 00139 00140 return true; 00141 } 00142 00143 } // namespace moab