MOAB: Mesh Oriented datABase  (version 5.2.1)
Skinner.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 2004 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 #ifndef MOAB_SKINNER_HPP
00017 #define MOAB_SKINNER_HPP
00018 
00019 #include "moab/Forward.hpp"
00020 #include "moab/Range.hpp"
00021 #include <vector>
00022 
00023 namespace moab
00024 {
00025 
00026 class ScdBox;
00027 
00028 /** \class Skinner
00029  * \brief Class for constructing and querying skin of a mesh
00030  * Class for constructing and querying skin of a mesh, defined as the outside lower-dimensional
00031  * boundary of a mesh or a given set of entities.  This class provides options for finding the
00032  * forward- and reverse-oriented members of the skin.  Several methods are available for computing
00033  * the skin, e.g. using geometric topology sets, vertex-entity adjacencies, or directly from
00034  * (n-1)-dimensional entities.
00035  */
00036 class Skinner
00037 {
00038 
00039     enum direction
00040     {
00041         FORWARD = 1,
00042         REVERSE = -1
00043     };
00044 
00045   protected:
00046     //! the MB instance that this works with
00047     Interface* thisMB;
00048 
00049     Tag mDeletableMBTag;
00050     Tag mAdjTag;
00051     int mTargetDim;
00052 
00053   public:
00054     //! constructor, takes mdb instance
00055     Skinner( Interface* mdb ) : thisMB( mdb ), mDeletableMBTag( 0 ), mAdjTag( 0 ), mTargetDim( 0 ) {}
00056 
00057     //! destructor
00058     ~Skinner();
00059 
00060     ErrorCode find_geometric_skin( const EntityHandle meshset, Range& forward_target_entities );
00061 
00062     /**\brief will accept entities all of one dimension and
00063      *        return entities of n-1 dimension; NOTE: get_vertices argument controls whether
00064      * vertices or entities of n-1 dimension are returned, and only one of these is allowed
00065      * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both)
00066      * \param entities The elements for which to find the skin
00067      * \param get_vertices If true, vertices on the skin are returned
00068      *        in the range, otherwise elements are returned
00069      * \param output_handles Range holding skin entities returned
00070      * \param output_reverse_handles Range holding entities on skin which
00071      *        are reversed wrt entities
00072      * \param create_vert_elem_adjs If true, this function will cause
00073      *        vertex-element adjacencies to be generated
00074      * \param create_skin_elements If true, this function will cause creation
00075      *        of skin entities, otherwise only skin entities already extant
00076      *        will be returned
00077      */
00078     ErrorCode find_skin( const EntityHandle meshset, const Range& entities, bool get_vertices, Range& output_handles,
00079                          Range* output_reverse_handles = 0, bool create_vert_elem_adjs = false,
00080                          bool create_skin_elements = true, bool look_for_scd = false );
00081 
00082     /**\brief will accept entities all of one dimension and
00083      *        return entities of n-1 dimension; NOTE: get_vertices argument controls whether
00084      * vertices or entities of n-1 dimension are returned, and only one of these is allowed
00085      * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both)
00086      * \param entities Pointer to elements for which to find the skin
00087      * \param num_entities Number of entities in vector
00088      * \param get_vertices If true, vertices on the skin are returned
00089      *        in the range, otherwise elements are returned
00090      * \param output_handles Range holding skin entities returned
00091      * \param output_reverse_handles Range holding entities on skin which
00092      *        are reversed wrt entities
00093      * \param create_vert_elem_adjs If true, this function will cause
00094      *        vertex-element adjacencies to be generated
00095      * \param create_skin_elements If true, this function will cause creation
00096      *        of skin entities, otherwise only skin entities already extant
00097      *        will be returned
00098      */
00099     ErrorCode find_skin( const EntityHandle this_set, const EntityHandle* entities, int num_entities, bool get_vertices,
00100                          Range& output_handles, Range* output_reverse_handles = 0, bool create_vert_elem_adjs = false,
00101                          bool create_skin_elements = true, bool look_for_scd = false );
00102 
00103     /**\brief get skin entities of prescribed dimension
00104      * \param entities The elements for which to find the skin
00105      * \param dim Dimension of skin entities requested
00106      * \param skin_entities Range holding skin entities returned
00107      * \param create_vert_elem_adjs If true, this function will cause
00108      *        vertex-element adjacencies to be generated
00109      */
00110     ErrorCode find_skin( const EntityHandle this_set, const Range& entities, int dim, Range& skin_entities,
00111                          bool create_vert_elem_adjs = false, bool create_skin_elements = true );
00112 
00113     ErrorCode classify_2d_boundary( const Range& boundary, const Range& bar_elements, EntityHandle boundary_edges,
00114                                     EntityHandle inferred_edges, EntityHandle non_manifold_edges,
00115                                     EntityHandle other_edges, int& number_boundary_nodes );
00116 
00117     //! given a skin of dimension 2, will classify and return edges
00118     //! as boundary, inferred, and non-manifold, and the rest (other)
00119     ErrorCode classify_2d_boundary( const Range& boundary, const Range& mesh_1d_elements, Range& boundary_edges,
00120                                     Range& inferred_edges, Range& non_manifold_edges, Range& other_edges,
00121                                     int& number_boundary_nodes );
00122 
00123   protected:
00124     ErrorCode initialize();
00125 
00126     ErrorCode deinitialize();
00127 
00128     ErrorCode find_skin_noadj( const Range& source_entities, Range& forward_target_entities,
00129                                Range& reverse_target_entities );
00130 
00131     ErrorCode add_adjacency( EntityHandle entity );
00132 
00133     void add_adjacency( EntityHandle entity, const EntityHandle* conn, const int num_nodes );
00134 
00135     ErrorCode remove_adjacency( EntityHandle entity );
00136 
00137     bool entity_deletable( EntityHandle entity );
00138 
00139     void find_match( EntityType type, const EntityHandle* conn, const int num_nodes, EntityHandle& match,
00140                      Skinner::direction& direct );
00141 
00142     bool connectivity_match( const EntityHandle* conn1, const EntityHandle* conn2, const int num_verts,
00143                              Skinner::direction& direct );
00144 
00145     void find_inferred_edges( Range& skin_boundary, Range& candidate_edges, Range& inferred_edges,
00146                               double reference_angle_degrees );
00147 
00148     bool has_larger_angle( EntityHandle& entity1, EntityHandle& entity2, double reference_angle_cosine );
00149 
00150     /**\brief Find vertices on the skin of a set of mesh entities.
00151      *\param entities The elements for which to find the skin.  Range
00152      *                may NOT contain vertices, polyhedra, or entity sets.
00153      *                All elements in range must be of the same dimension.
00154      *\param skin_verts Output: the vertices on the skin.
00155      *\param skin_elems Optional output: elements representing sides of entities
00156      *                    that are on the skin
00157      *\param create_if_missing If skin_elemts is non-null and this is true,
00158      *                    create new elements representing the sides of
00159      *                    entities on the skin.  If this is false, skin_elems
00160      *                    will contain only those skin elements that already
00161      *                    exist.
00162      */
00163     ErrorCode find_skin_vertices( const EntityHandle this_set, const Range& entities, Range* skin_verts = 0,
00164                                   Range* skin_elems = 0, Range* rev_elems = 0, bool create_if_missing = true,
00165                                   bool corners_only = false );
00166 
00167     /**\brief Skin edges
00168      *
00169      * Return any vertices adjacent to exactly one of the input edges.
00170      */
00171     ErrorCode find_skin_vertices_1D( Tag tag, const Range& edges, Range& skin_verts );
00172 
00173     /**\brief Skin faces
00174      *
00175      * For the set of face sides (logical edges), return
00176      * vertices on such sides and/or edges equivalent to such sides.
00177      *\param faces  Set of toplogically 2D entities to skin.
00178      *\param skin_verts If non-NULL, skin vertices will be added to this container.
00179      *\param skin_edges If non-NULL, skin edges will be added to this container
00180      *\param reverse_edges If skin_edges is not NULL and this is not NULL, then
00181      *                  any existing skin edges that are reversed with respect
00182      *                  to the skin side will be placed in this range instead of
00183      *                  skin_edges.  Note: this argument is ignored if skin_edges
00184      *                  is NULL.
00185      *\param create_edges If true, edges equivalent to face sides on the skin
00186      *                  that don't already exist will be created.  Note: this
00187      *                  parameter is honored regardless of whether or not skin
00188      *                  edges or vertices are returned.
00189      *\param corners_only If true, only skin vertices that correspond to the
00190      *                  corners of sides will be returned (i.e. no higher-order
00191      *                  nodes.)  This argument is ignored if skin_verts is NULL.
00192      */
00193     ErrorCode find_skin_vertices_2D( const EntityHandle this_set, Tag tag, const Range& faces, Range* skin_verts = 0,
00194                                      Range* skin_edges = 0, Range* reverse_edges = 0, bool create_edges = false,
00195                                      bool corners_only = false );
00196 
00197     /**\brief Skin volume mesh
00198      *
00199      * For the set of element sides (logical faces), return
00200      * vertices on such sides and/or faces equivalent to such sides.
00201      *\param entities  Set of toplogically 3D entities to skin.
00202      *\param skin_verts If non-NULL, skin vertices will be added to this container.
00203      *\param skin_faces If non-NULL, skin faces will be added to this container
00204      *\param reverse_faces If skin_faces is not NULL and this is not NULL, then
00205      *                  any existing skin faces that are reversed with respect
00206      *                  to the skin side will be placed in this range instead of
00207      *                  skin_faces.  Note: this argument is ignored if skin_faces
00208      *                  is NULL.
00209      *\param create_faces If true, face equivalent to sides on the skin
00210      *                  that don't already exist will be created.  Note: this
00211      *                  parameter is honored regardless of whether or not skin
00212      *                  faces or vertices are returned.
00213      *\param corners_only If true, only skin vertices that correspond to the
00214      *                  corners of sides will be returned (i.e. no higher-order
00215      *                  nodes.)  This argument is ignored if skin_verts is NULL.
00216      */
00217     ErrorCode find_skin_vertices_3D( const EntityHandle this_set, Tag tag, const Range& entities, Range* skin_verts = 0,
00218                                      Range* skin_faces = 0, Range* reverse_faces = 0, bool create_faces = false,
00219                                      bool corners_only = false );
00220 
00221     ErrorCode create_side( const EntityHandle this_set, EntityHandle element, EntityType side_type,
00222                            const EntityHandle* side_corners, EntityHandle& side_elem_handle_out );
00223 
00224     bool edge_reversed( EntityHandle face, const EntityHandle edge_ends[2] );
00225     bool face_reversed( EntityHandle region, const EntityHandle* face_conn, EntityType face_type );
00226 
00227     //! look for structured box comprising source_entities, and if one is found use
00228     //! structured information to find the skin
00229     ErrorCode find_skin_scd( const Range& source_entities, bool get_vertices, Range& output_handles,
00230                              bool create_skin_elements );
00231 
00232     //! skin a structured box, taking advantage of structured information
00233     ErrorCode skin_box( ScdBox* box, bool get_vertices, Range& output_handles, bool create_skin_elements );
00234 };
00235 
00236 inline ErrorCode Skinner::find_skin( const EntityHandle this_set, const EntityHandle* entities, int num_entities,
00237                                      bool get_vertices, Range& output_handles, Range* output_reverse_handles,
00238                                      bool create_vert_elem_adjs, bool create_skin_elements, bool look_for_scd )
00239 {
00240     Range ents;
00241     std::copy( entities, entities + num_entities, range_inserter( ents ) );
00242     return find_skin( this_set, ents, get_vertices, output_handles, output_reverse_handles, create_vert_elem_adjs,
00243                       create_skin_elements, look_for_scd );
00244 }
00245 
00246 }  // namespace moab
00247 
00248 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines