Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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