MOAB: Mesh Oriented datABase  (version 5.4.0)
EntityRefiner.hpp
Go to the documentation of this file.
00001 /*
00002  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003  * storing and accessing finite element mesh data.
00004  *
00005  * Copyright 2007 Sandia Corporation.  Under the terms of Contract
00006  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007  * retains certain rights in this software.
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  */
00015 
00016 /** \class moab::EntityRefiner
00017  *
00018  * This is an abstract class that contains the method used for per-entity refinement.
00019  * Subclasses must implement the pure virtual refine_entity() function and
00020  * may implement the vertices_per_split() function.
00021  * This class constructor requires a non-NULL pointer to a mesh so that, given an
00022  * entity handle, it can look up vertex coordinates and tags to prepare arguments for
00023  * the refine_entity() method.
00024  *
00025  * Although the MeshRefiner class may not initially support it, entity refiners
00026  * are required to support some level of recursion.
00027  * The maximum number of recursive calls allowed may be set with
00028  * EntityRefiner::set_maximum_number_of_subdivisions().
00029  * As a convenience, some of the framework for recursion is provided by the
00030  * EntityRefiner class.
00031  *
00032  * Specifically, EntityRefiner stores a pair of heap arrays
00033  * to hold edge midpoint vertex coordinates and tag values pre-allocated to the
00034  * maximum recursion depth so that no repeated allocation and deallocation
00035  * needs to take place during refinement.
00036  * To use these heaps, subclasses should call reset_heap_pointers() upon entry to
00037  * EntityRefiner::refine_entity().
00038  * Then, when the edge size evaluator requires an edge to be split, subclasses
00039  * should call heap_coord_storage() and heap_tag_storage() to obtain pointers as
00040  * required.
00041  *
00042  * \author David Thompson
00043  * \author Philippe Pebay
00044  *
00045  * \date 24 December 2007
00046  */
00047 
00048 /**\class EntityRefinerOutputFunctor
00049  *
00050  * This is an abstract class used by EntityRefiner to output entities that are the product of
00051  * refinement. The parenthesis operator is overloaded with two forms: one used for appending a
00052  * vertex to an entity, the other used to finalize the creation of the entity by specifying its
00053  * type.
00054  *
00055  * You are also responsible for implementing the map_vertex() function to map an input vertex handle
00056  * into an output vertex handle (which may then be appended to an entity using the first form
00057  * of the parenthesis operator above).
00058  *
00059  * \author David Thompson
00060  * \author Philippe Pebay
00061  *
00062  * \date 26 December 2007
00063  */
00064 #ifndef MOAB_ENTITY_REFINER_HPP
00065 #define MOAB_ENTITY_REFINER_HPP
00066 
00067 #include "moab/Types.hpp"
00068 #include "moab/Compiler.hpp"  // for MB_DLL_EXPORT
00069 
00070 #include <vector>
00071 
00072 namespace moab
00073 {
00074 
00075 class Interface;
00076 class EdgeSizeEvaluator;
00077 class RefinerTagManager;
00078 
00079 class EntityRefinerOutputFunctor
00080 {
00081   public:
00082     virtual ~EntityRefinerOutputFunctor() {}
00083     /// Map an input vertex to the output mesh. This should return the same value when given the
00084     /// same input across multiple calls.
00085     virtual EntityHandle map_vertex( EntityHandle vhash, const double* vcoords, const void* vtags ) = 0;
00086     /**\brief Create a new vertex along an edge.
00087      *
00088      * @param[in] h0 An edge endpoint handle on the output mesh.
00089      * @param[in] h1 An edge endpoint handle on the output mesh.
00090      * @param[in] vcoords The location of the midpoint in world coordinates.
00091      * @param[in] vtags Field values at the midpoint.
00092      * @retval    A handle for the midpoint on the output mesh.
00093      */
00094     EntityHandle operator()( EntityHandle h0, EntityHandle h1, const double* vcoords, const void* vtags )
00095     {
00096         EntityHandle harr[2];
00097         // Cppcheck warning (false positive): variable harr is assigned a value that is never used
00098         harr[0] = h0;
00099         harr[1] = h1;
00100         return ( *this )( 2, harr, vcoords, vtags );
00101     }
00102     /**\brief Create a new vertex on a triangular face.
00103      *
00104      * @param[in] h0 A triangle corner handle on the output mesh.
00105      * @param[in] h1 A triangle corner handle on the output mesh.
00106      * @param[in] h2 A triangle corner handle on the output mesh.
00107      * @param[in] vcoords The location of the mid-face point in world coordinates.
00108      * @param[in] vtags Field values at the mid-face point.
00109      * @retval    A handle for the mid-face point on the output mesh.
00110      */
00111     virtual EntityHandle operator()( EntityHandle h0,
00112                                      EntityHandle h1,
00113                                      EntityHandle h2,
00114                                      const double* vcoords,
00115                                      const void* vtags )
00116     {
00117         EntityHandle harr[3];
00118         // Cppcheck warning (false positive): variable harr is assigned a value that is never used
00119         harr[0] = h0;
00120         harr[1] = h1;
00121         harr[2] = h2;
00122         return ( *this )( 3, harr, vcoords, vtags );
00123     }
00124     /**\brief Create a new vertex along a \f$k\f$-facet.
00125      *
00126      * @param[in] nhash The number of corner vertices (i.e, \f$k\f$ ).
00127      * @param[in] hash An array of corner handles on the output mesh.
00128      * @param[in] vcoords The location of the new point in world coordinates.
00129      * @param[in] vtags Field values at the new point.
00130      * @retval    A handle for the new point on the output mesh.
00131      */
00132     virtual EntityHandle operator()( int nhash, EntityHandle* hash, const double* vcoords, const void* vtags ) = 0;
00133     /**\brief Append an output vertex to the list of vertices defining a new entity.
00134      *
00135      * @param[in] vhash A vertex of the output mesh.
00136      */
00137     virtual void operator()( EntityHandle vhash ) = 0;
00138     /**\brief Create a new entity from all previously appended output vertices.
00139      *
00140      * This resets the list of appended vertices.
00141      * @param[in] etyp The type of entity to create.
00142      */
00143     virtual void operator()( EntityType etyp ) = 0;
00144 };
00145 
00146 class EntityRefiner
00147 {
00148   public:
00149     EntityRefiner();
00150     virtual ~EntityRefiner();
00151 
00152     virtual bool prepare( RefinerTagManager* tmgr, EntityRefinerOutputFunctor* ofunc );
00153     virtual bool refine_entity( EntityType typ, EntityHandle ent )        = 0;
00154     virtual unsigned long get_heap_size_bound( int max_recursions ) const = 0;
00155 
00156     virtual bool set_edge_size_evaluator( EdgeSizeEvaluator* );
00157     EdgeSizeEvaluator* get_edge_size_evaluator()
00158     {
00159         return this->edge_size_evaluator;
00160     }
00161 
00162     virtual bool set_output_functor( EntityRefinerOutputFunctor* func_obj );
00163     EntityRefinerOutputFunctor* get_output_functor()
00164     {
00165         return this->output_functor;
00166     }
00167 
00168     virtual bool set_minimum_number_of_subdivisions( int mn );
00169     int get_minimum_number_of_subdivisions() const
00170     {
00171         return this->minimum_number_of_subdivisions;
00172     }
00173 
00174     virtual bool set_maximum_number_of_subdivisions( int mx );
00175     int get_maximum_number_of_subdivisions() const
00176     {
00177         return this->maximum_number_of_subdivisions;
00178     }
00179 
00180   protected:
00181     Interface* mesh_in;
00182     EdgeSizeEvaluator* edge_size_evaluator;
00183     EntityRefinerOutputFunctor* output_functor;
00184     int minimum_number_of_subdivisions;
00185     int maximum_number_of_subdivisions;
00186     std::vector< double > coord_heap;
00187     std::vector< double >::iterator current_coord;
00188     std::vector< char > tag_heap;
00189     std::vector< char >::iterator current_tag;
00190 
00191     void update_heap_size();
00192     void reset_heap_pointers();
00193     double* heap_coord_storage();
00194     void* heap_tag_storage();
00195 };
00196 
00197 }  // namespace moab
00198 
00199 #endif  // MOAB_ENTITY_REFINER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines