MOAB: Mesh Oriented datABase  (version 5.2.1)
EntityRefiner.cpp
Go to the documentation of this file.
00001 #include "EntityRefiner.hpp"
00002 
00003 #include "EdgeSizeEvaluator.hpp"
00004 #include "moab/Interface.hpp"
00005 
00006 namespace moab
00007 {
00008 
00009 /// Construct an entity refiner.
00010 EntityRefiner::EntityRefiner()
00011 {
00012     this->mesh_in             = 0;
00013     this->edge_size_evaluator = 0;
00014     this->output_functor      = 0;
00015     // By default, allow at most one subdivision per edge
00016     this->minimum_number_of_subdivisions = 0;
00017     this->maximum_number_of_subdivisions = 1;
00018 }
00019 
00020 /// Destruction is virtual so subclasses may clean up after refinement.
00021 EntityRefiner::~EntityRefiner()
00022 {
00023     if( this->edge_size_evaluator ) delete this->edge_size_evaluator;
00024 }
00025 
00026 /**\brief Prepare to start refining entities on a given mesh.
00027  * This is called once before refine_entity() is ever invoked.
00028  * The tag manager specifies the input and output meshes upon which the refiner will act.
00029  *
00030  * This function returns false if calling refine_entity() immediately
00031  * afterwards would cause a failure (due, for example, to a NULL edge_size_evaluator).
00032  * Otherwise it returns true.
00033  */
00034 bool EntityRefiner::prepare( RefinerTagManager* tmgr, EntityRefinerOutputFunctor* ofunc )
00035 {
00036     bool rval = true;
00037     if( this->edge_size_evaluator ) { this->edge_size_evaluator->set_tag_manager( tmgr ); }
00038     else
00039     {
00040         rval = false;
00041     }
00042     this->set_output_functor( ofunc );
00043     this->mesh_in = tmgr->get_input_mesh();
00044     this->update_heap_size();
00045     return rval;
00046 }
00047 
00048 /**\fn bool EntityRefiner::refine_entity( EntityHandle )
00049  *\brief Method implemented by subclasses to create decompositions of entities using edge
00050  *subdivisions.
00051  */
00052 
00053 /**\fn int EntityRefiner::get_heap_size_bound( int max_recursions ) const
00054  *\brief When an entity is refined, what is the maximum number of new vertices that will be created?
00055  *
00056  * This must be the maximum number of initial corner vertices for any entity type (hex, tet, etc.)
00057  * to be processed plus the maximum number of new vertices that might be created at edge or face
00058  * mid-points during the refinement of a single entity.
00059  */
00060 
00061 /**\brief Set the object that specifies which edges of a given entity should be subdivided.
00062  *
00063  * The entity refiner takes ownership of edge size evaluator and will delete it when
00064  * a new value is set or when the entity refiner is destroyed.
00065  *
00066  * @param ese The new edge size evaluator object.
00067  * @retval Returns true if the value was changed and false otherwise.
00068  */
00069 bool EntityRefiner::set_edge_size_evaluator( EdgeSizeEvaluator* ese )
00070 {
00071     if( !ese || ese == this->edge_size_evaluator ) return false;
00072 
00073     if( this->edge_size_evaluator ) { delete this->edge_size_evaluator; }
00074     this->edge_size_evaluator = ese;
00075 
00076     return true;
00077 }
00078 
00079 /**\fn EdgeSizeEvaluator* EntityRefiner::get_edge_size_evaluator()
00080  *\brief Return a pointer to the object that specifies which edges of a given entity should be
00081  *subdivided.
00082  *
00083  * This may return NULL if no value has been previously specified.
00084  *
00085  * @retval A pointer to an edge size evaluator object or NULL.
00086  */
00087 
00088 /**\brief Set the functor through which output entities are streamed.
00089  *
00090  * Any previously assigned functor will be deleted when a new functor is set.
00091  *
00092  * @retvalReturns true if the value was changed and false otherwise.
00093  */
00094 bool EntityRefiner::set_output_functor( EntityRefinerOutputFunctor* func_obj )
00095 {
00096     if( !func_obj || func_obj == this->output_functor ) return false;
00097 
00098     if( this->output_functor ) { delete this->output_functor; }
00099     this->output_functor = func_obj;
00100     return true;
00101 }
00102 
00103 /**\fn EntityRefinerOutputFunctor* EntityRefiner::get_output_functor()
00104  *\brief Return the functor used to stream output.
00105  *
00106  * @retval A pointer to the functor. This may be NULL.
00107  */
00108 
00109 /**\brief Set the minimum number of recursive subdivisions that should occur, regardless of the
00110  * edge_size_evaluator's response.
00111  *
00112  * This is useful for forcing global refinement.
00113  *
00114  * @retval True if the number of subdivisions was changed; false otherwise.
00115  */
00116 bool EntityRefiner::set_minimum_number_of_subdivisions( int mn )
00117 {
00118     if( mn < 0 || mn == this->minimum_number_of_subdivisions ) { return false; }
00119 
00120     this->minimum_number_of_subdivisions = mn;
00121     return true;
00122 }
00123 
00124 /**\fn int EntityRefiner::get_minimum_number_of_subdivisions() const
00125  *\brief Return the minimum number of recursive edge subdivisions guaranteed to take place,
00126  *regardless of the edge size evaluator.
00127  *
00128  * This may any non-negative integer.
00129  *
00130  * @retval The guaranteed minimum number of subdivisions that will take place on each and every edge
00131  *of the mesh.
00132  */
00133 
00134 /**\brief Set the maximum number of recursive subdivisions that should occur, regardless of the
00135  * edge_size_evaluator's response.
00136  *
00137  * This is useful for preventing infinite recursion.
00138  * A value of 0 is allowed although not terribly practical.
00139  *
00140  * @retval True if the number of subdivisions was changed; false otherwise.
00141  */
00142 bool EntityRefiner::set_maximum_number_of_subdivisions( int mx )
00143 {
00144     if( mx < 0 || mx == this->maximum_number_of_subdivisions ) { return false; }
00145 
00146     this->maximum_number_of_subdivisions = mx;
00147     this->update_heap_size();
00148     return true;
00149 }
00150 
00151 /**\fn int EntityRefiner::get_maximum_number_of_subdivisions() const
00152  *\brief Return the maximum number of recursive edge subdivisions guaranteed to take place,
00153  *regardless of the edge size evaluator.
00154  *
00155  * This may any non-negative integer.
00156  *
00157  * @retval The guaranteed maximum number of subdivisions that will take place on each and every edge
00158  *of the mesh.
00159  */
00160 
00161 /**\brief This is called when the edge size evaluator or maximum number of subdivisions is changed
00162  *       to make sure the heaps are properly sized.
00163  *
00164  * Tag heap size cannot be computed if the edge_size_evaluator is NULL.
00165  */
00166 void EntityRefiner::update_heap_size()
00167 {
00168     unsigned long n = this->get_heap_size_bound( this->maximum_number_of_subdivisions );
00169     this->coord_heap.resize( 6 * n );
00170     if( this->edge_size_evaluator )
00171     {
00172         unsigned long m = this->edge_size_evaluator->get_tag_manager()->get_vertex_tag_size();
00173         this->tag_heap.resize( m * n );
00174     }
00175 }
00176 
00177 /**\brief Subclasses should call this on entry to refine_entity().
00178  *
00179  * When called, future calls to heap_coord_storage() and heap_tag_storage() will
00180  * re-use the allocated storage starting from the beginning.
00181  */
00182 void EntityRefiner::reset_heap_pointers()
00183 {
00184     this->current_coord = this->coord_heap.begin();
00185     this->current_tag   = this->tag_heap.begin();
00186 }
00187 
00188 /**\brief Return a pointer to temporary storage for edge midpoint vertex coordinates inside
00189  * refine_entity().
00190  *
00191  * The returned pointer references 6 uninitialized double values to hold parametric coordinates and
00192  * world coordinates.
00193  */
00194 double* EntityRefiner::heap_coord_storage()
00195 {
00196     double* rval;
00197     if( this->current_coord != this->coord_heap.end() )
00198     {
00199         rval = &( *this->current_coord );
00200         this->current_coord += 6;
00201     }
00202     else
00203     {
00204         rval = 0;
00205     }
00206     return rval;
00207 }
00208 
00209 /**\brief Return a pointer to temporary storage for edge midpoint vertex coordinates inside
00210  * refine_entity().
00211  *
00212  * The returned pointer references enough bytes to store all the tags for a vertex as reported by
00213  * the current edge size evaluator's EdgeSizeEvaluator::get_vertex_tag_size().
00214  */
00215 void* EntityRefiner::heap_tag_storage()
00216 {
00217     void* rval;
00218     if( this->edge_size_evaluator && this->current_tag != this->tag_heap.end() )
00219     {
00220         rval = (void*)&( *this->current_tag );
00221         this->current_tag += this->edge_size_evaluator->get_tag_manager()->get_vertex_tag_size();
00222     }
00223     else
00224     {
00225         rval = 0;
00226     }
00227     return rval;
00228 }
00229 
00230 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines