Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
MeshRefiner.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines