MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 MOAB_HAVE_MPI 00010 #include "moab/ParallelComm.hpp" 00011 #include "moab_mpi.h" 00012 #else // MOAB_HAVE_MPI 00013 typedef int MPI_Comm; 00014 #endif // MOAB_HAVE_MPI 00015 00016 namespace moab 00017 { 00018 00019 /**\brief Construct a mesh refiner. 00020 * The input and output mesh pointers may be identical. 00021 * Existing elements will <b>not</b> be removed from the input mesh 00022 * as they are refined, so the adjacencies for entitities may appear 00023 * strange after refinement. 00024 */ 00025 MeshRefiner::MeshRefiner( Interface* imesh, Interface* omesh ) 00026 { 00027 this->mesh_in = imesh; 00028 this->mesh_out = omesh; 00029 this->tag_manager = new RefinerTagManager( this->mesh_in, this->mesh_out ); 00030 this->output_functor = new MeshOutputFunctor( this->tag_manager ); 00031 this->entity_refiner = 0; 00032 this->comm = ParallelComm::get_pcomm( this->mesh_out, 0 ); 00033 } 00034 00035 /**\brief Destroy a mesh refiner. 00036 * 00037 * Note that any EntityRefiner object associated with the mesh refiner will be deleted inside this 00038 * destructor. Destruction is virtual so subclasses may clean up after refinement. 00039 */ 00040 MeshRefiner::~MeshRefiner() 00041 { 00042 delete this->tag_manager; 00043 delete this->output_functor; 00044 if( this->entity_refiner ) delete this->entity_refiner; 00045 } 00046 00047 /**\brief Specify which techniqe will be used to refine entities in the mesh. 00048 * The entity refiner object you specify is ``owned'' by the mesh refiner after this call; 00049 * the entity refiner will be deleted when this mesh refiner is destroyed. 00050 * You should not delete the entity refiner yourself. 00051 */ 00052 bool MeshRefiner::set_entity_refiner( EntityRefiner* er ) 00053 { 00054 if( !er || er == this->entity_refiner ) return false; 00055 00056 this->entity_refiner = er; 00057 return true; 00058 } 00059 00060 /**\brief A convenience method to reset the list of tags to be copied to output vertices. 00061 * This simply calls the method of the same name on the tag manager. 00062 */ 00063 void MeshRefiner::reset_vertex_tags() 00064 { 00065 this->tag_manager->reset_vertex_tags(); 00066 } 00067 00068 /**\brief A convenience method to add a tag to be copied/interpolated from input vertices to output 00069 * vertices. This simply calls the method of the same name on the tag manager. 00070 */ 00071 int MeshRefiner::add_vertex_tag( Tag tag_handle ) 00072 { 00073 return this->tag_manager->add_vertex_tag( tag_handle ); 00074 } 00075 00076 struct MeshRefinerIterator 00077 { 00078 Range subset; 00079 EntityHandle destination_set; 00080 }; 00081 00082 /**\brief Refine entities in a mesh set. 00083 * This will recursively descend any mesh sets contained in the \a range. 00084 * It returns false when not able to refine (because no entity refiner is 00085 * set or no edge size evaluator has been set on the entity refiner) and 00086 * true otherwise. 00087 */ 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