Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
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,
00079                          const Range& entities,
00080                          bool get_vertices,
00081                          Range& output_handles,
00082                          Range* output_reverse_handles = 0,
00083                          bool create_vert_elem_adjs    = false,
00084                          bool create_skin_elements     = true,
00085                          bool look_for_scd             = false );
00086 
00087     /**\brief will accept entities all of one dimension and
00088      *        return entities of n-1 dimension; NOTE: get_vertices argument controls whether
00089      * vertices or entities of n-1 dimension are returned, and only one of these is allowed
00090      * (i.e. this function returns only vertices or (n-1)-dimensional entities, but not both)
00091      * \param entities Pointer to elements for which to find the skin
00092      * \param num_entities Number of entities in vector
00093      * \param get_vertices If true, vertices on the skin are returned
00094      *        in the range, otherwise elements are returned
00095      * \param output_handles Range holding skin entities returned
00096      * \param output_reverse_handles Range holding entities on skin which
00097      *        are reversed wrt entities
00098      * \param create_vert_elem_adjs If true, this function will cause
00099      *        vertex-element adjacencies to be generated
00100      * \param create_skin_elements If true, this function will cause creation
00101      *        of skin entities, otherwise only skin entities already extant
00102      *        will be returned
00103      */
00104     ErrorCode find_skin( const EntityHandle this_set,
00105                          const EntityHandle* entities,
00106                          int num_entities,
00107                          bool get_vertices,
00108                          Range& output_handles,
00109                          Range* output_reverse_handles = 0,
00110                          bool create_vert_elem_adjs    = false,
00111                          bool create_skin_elements     = true,
00112                          bool look_for_scd             = false );
00113 
00114     /**\brief get skin entities of prescribed dimension
00115      * \param entities The elements for which to find the skin
00116      * \param dim Dimension of skin entities requested
00117      * \param skin_entities Range holding skin entities returned
00118      * \param create_vert_elem_adjs If true, this function will cause
00119      *        vertex-element adjacencies to be generated
00120      */
00121     ErrorCode find_skin( const EntityHandle this_set,
00122                          const Range& entities,
00123                          int dim,
00124                          Range& skin_entities,
00125                          bool create_vert_elem_adjs = false,
00126                          bool create_skin_elements  = true );
00127 
00128     ErrorCode classify_2d_boundary( const Range& boundary,
00129                                     const Range& bar_elements,
00130                                     EntityHandle boundary_edges,
00131                                     EntityHandle inferred_edges,
00132                                     EntityHandle non_manifold_edges,
00133                                     EntityHandle other_edges,
00134                                     int& number_boundary_nodes );
00135 
00136     //! given a skin of dimension 2, will classify and return edges
00137     //! as boundary, inferred, and non-manifold, and the rest (other)
00138     ErrorCode classify_2d_boundary( const Range& boundary,
00139                                     const Range& mesh_1d_elements,
00140                                     Range& boundary_edges,
00141                                     Range& inferred_edges,
00142                                     Range& non_manifold_edges,
00143                                     Range& other_edges,
00144                                     int& number_boundary_nodes );
00145 
00146   protected:
00147     ErrorCode initialize();
00148 
00149     ErrorCode deinitialize();
00150 
00151     ErrorCode find_skin_noadj( const Range& source_entities,
00152                                Range& forward_target_entities,
00153                                Range& reverse_target_entities );
00154 
00155     ErrorCode add_adjacency( EntityHandle entity );
00156 
00157     void add_adjacency( EntityHandle entity, const EntityHandle* conn, const int num_nodes );
00158 
00159     ErrorCode remove_adjacency( EntityHandle entity );
00160 
00161     bool entity_deletable( EntityHandle entity );
00162 
00163     void find_match( EntityType type,
00164                      const EntityHandle* conn,
00165                      const int num_nodes,
00166                      EntityHandle& match,
00167                      Skinner::direction& direct );
00168 
00169     bool connectivity_match( const EntityHandle* conn1,
00170                              const EntityHandle* conn2,
00171                              const int num_verts,
00172                              Skinner::direction& direct );
00173 
00174     void find_inferred_edges( Range& skin_boundary,
00175                               Range& candidate_edges,
00176                               Range& inferred_edges,
00177                               double reference_angle_degrees );
00178 
00179     bool has_larger_angle( EntityHandle& entity1, EntityHandle& entity2, double reference_angle_cosine );
00180 
00181     /**\brief Find vertices on the skin of a set of mesh entities.
00182      *\param entities The elements for which to find the skin.  Range
00183      *                may NOT contain vertices, polyhedra, or entity sets.
00184      *                All elements in range must be of the same dimension.
00185      *\param skin_verts Output: the vertices on the skin.
00186      *\param skin_elems Optional output: elements representing sides of entities
00187      *                    that are on the skin
00188      *\param create_if_missing If skin_elemts is non-null and this is true,
00189      *                    create new elements representing the sides of
00190      *                    entities on the skin.  If this is false, skin_elems
00191      *                    will contain only those skin elements that already
00192      *                    exist.
00193      */
00194     ErrorCode find_skin_vertices( const EntityHandle this_set,
00195                                   const Range& entities,
00196                                   Range* skin_verts      = 0,
00197                                   Range* skin_elems      = 0,
00198                                   Range* rev_elems       = 0,
00199                                   bool create_if_missing = true,
00200                                   bool corners_only      = false );
00201 
00202     /**\brief Skin edges
00203      *
00204      * Return any vertices adjacent to exactly one of the input edges.
00205      */
00206     ErrorCode find_skin_vertices_1D( Tag tag, const Range& edges, Range& skin_verts );
00207 
00208     /**\brief Skin faces
00209      *
00210      * For the set of face sides (logical edges), return
00211      * vertices on such sides and/or edges equivalent to such sides.
00212      *\param faces  Set of toplogically 2D entities to skin.
00213      *\param skin_verts If non-NULL, skin vertices will be added to this container.
00214      *\param skin_edges If non-NULL, skin edges will be added to this container
00215      *\param reverse_edges If skin_edges is not NULL and this is not NULL, then
00216      *                  any existing skin edges that are reversed with respect
00217      *                  to the skin side will be placed in this range instead of
00218      *                  skin_edges.  Note: this argument is ignored if skin_edges
00219      *                  is NULL.
00220      *\param create_edges If true, edges equivalent to face sides on the skin
00221      *                  that don't already exist will be created.  Note: this
00222      *                  parameter is honored regardless of whether or not skin
00223      *                  edges or vertices are returned.
00224      *\param corners_only If true, only skin vertices that correspond to the
00225      *                  corners of sides will be returned (i.e. no higher-order
00226      *                  nodes.)  This argument is ignored if skin_verts is NULL.
00227      */
00228     ErrorCode find_skin_vertices_2D( const EntityHandle this_set,
00229                                      Tag tag,
00230                                      const Range& faces,
00231                                      Range* skin_verts    = 0,
00232                                      Range* skin_edges    = 0,
00233                                      Range* reverse_edges = 0,
00234                                      bool create_edges    = false,
00235                                      bool corners_only    = false );
00236 
00237     /**\brief Skin volume mesh
00238      *
00239      * For the set of element sides (logical faces), return
00240      * vertices on such sides and/or faces equivalent to such sides.
00241      *\param entities  Set of toplogically 3D entities to skin.
00242      *\param skin_verts If non-NULL, skin vertices will be added to this container.
00243      *\param skin_faces If non-NULL, skin faces will be added to this container
00244      *\param reverse_faces If skin_faces is not NULL and this is not NULL, then
00245      *                  any existing skin faces that are reversed with respect
00246      *                  to the skin side will be placed in this range instead of
00247      *                  skin_faces.  Note: this argument is ignored if skin_faces
00248      *                  is NULL.
00249      *\param create_faces If true, face equivalent to sides on the skin
00250      *                  that don't already exist will be created.  Note: this
00251      *                  parameter is honored regardless of whether or not skin
00252      *                  faces or vertices are returned.
00253      *\param corners_only If true, only skin vertices that correspond to the
00254      *                  corners of sides will be returned (i.e. no higher-order
00255      *                  nodes.)  This argument is ignored if skin_verts is NULL.
00256      */
00257     ErrorCode find_skin_vertices_3D( const EntityHandle this_set,
00258                                      Tag tag,
00259                                      const Range& entities,
00260                                      Range* skin_verts    = 0,
00261                                      Range* skin_faces    = 0,
00262                                      Range* reverse_faces = 0,
00263                                      bool create_faces    = false,
00264                                      bool corners_only    = false );
00265 
00266     ErrorCode create_side( const EntityHandle this_set,
00267                            EntityHandle element,
00268                            EntityType side_type,
00269                            const EntityHandle* side_corners,
00270                            EntityHandle& side_elem_handle_out );
00271 
00272     bool edge_reversed( EntityHandle face, const EntityHandle edge_ends[2] );
00273     bool face_reversed( EntityHandle region, const EntityHandle* face_conn, EntityType face_type );
00274 
00275     //! look for structured box comprising source_entities, and if one is found use
00276     //! structured information to find the skin
00277     ErrorCode find_skin_scd( const Range& source_entities,
00278                              bool get_vertices,
00279                              Range& output_handles,
00280                              bool create_skin_elements );
00281 
00282     //! skin a structured box, taking advantage of structured information
00283     ErrorCode skin_box( ScdBox* box, bool get_vertices, Range& output_handles, bool create_skin_elements );
00284 };
00285 
00286 inline ErrorCode Skinner::find_skin( const EntityHandle this_set,
00287                                      const EntityHandle* entities,
00288                                      int num_entities,
00289                                      bool get_vertices,
00290                                      Range& output_handles,
00291                                      Range* output_reverse_handles,
00292                                      bool create_vert_elem_adjs,
00293                                      bool create_skin_elements,
00294                                      bool look_for_scd )
00295 {
00296     Range ents;
00297     std::copy( entities, entities + num_entities, range_inserter( ents ) );
00298     return find_skin( this_set, ents, get_vertices, output_handles, output_reverse_handles, create_vert_elem_adjs,
00299                       create_skin_elements, look_for_scd );
00300 }
00301 
00302 }  // namespace moab
00303 
00304 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines