1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/**
 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
 * storing and accessing finite element mesh data.
 *
 * Copyright 2004 Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
 * retains certain rights in this software.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 */

#ifndef AENTITY_FACTORY_HPP
#define AENTITY_FACTORY_HPP

#ifndef IS_BUILDING_MB
#error "AEntityFactory.hpp isn't supposed to be included into an application"
#endif

#include "moab/Forward.hpp"
#include <vector>

namespace moab
{

typedef std::vector< EntityHandle > AdjacencyVector;
class Core;

//! class AEntityFactory
class AEntityFactory
{
  public:
    //! require an Interface object in order to access tags on that interface
    AEntityFactory( Core* mdb );

    //! destructor
    ~AEntityFactory();

    //! add an adjacency from from_ent to to_ent; if both_ways is true, add one
    //! in reverse too
    //! NOTE: this function is defined even though we may only be implementing
    //! vertex-based up-adjacencies
    ErrorCode add_adjacency( EntityHandle from_ent, EntityHandle to_ent, const bool both_ways = false );

    //! remove an adjacency from from the base_entity.
    ErrorCode remove_adjacency( EntityHandle base_entity, EntityHandle adjacency_to_remove );

    //! remove all adjacencies from from the base_entity.
    ErrorCode remove_all_adjacencies( EntityHandle base_entity, const bool delete_adj_list = false );

    /**\brief Get adjacencies for a single source entity.
     *
     * Get adjacent entities.
     *
     *\param source_entity    The entity for which to retrieve the adjacencies.
     *\param target_dimension Retrieve adjacent entities of this dimension.  Must
     *                        be in the range [1,3], where 4 is used to indicated entity sets.
     *\param target_entities  Requested adjacent entities will be appended to this list.
     *\param create_if_missing If true, adjacent elements of the specified dimension will
     *                        be created if they do not already exist.  If the target dimension
     *                        is less than the dimension of the input entity and greater than zero,
     *the elements will be created as required to represent the "sides" of the source element.  If
     *the target dimension is greater than that of the source entity and less than 3, then sides of
     *the specified dimension on that are a) of greater dimension and b) adjacent to the input
     *entity will be created. \param create_adjacency_option If create_adjacency_option is >= 0,
     *adjacencies from entities of that dimension to each target_entity are created (this function
     *uses AEntityFactory::get_element for each element)
     */
    ErrorCode get_elements( EntityHandle source_entity,
                            const unsigned int target_dimension,
                            std::vector< EntityHandle >& target_entities,
                            const bool create_if_missing,
                            const int create_adjacency_option = -1 );

    //! get the vertices for a polyhedron (special implementation because for polyhedra
    //! connectivity array stores faces)
    ErrorCode get_polyhedron_vertices( const EntityHandle source_entity, std::vector< EntityHandle >& target_entities );

    //! get the meshsets that are in source_entitiy's adjacency vector
    ErrorCode get_associated_meshsets( EntityHandle source_entity, std::vector< EntityHandle >& target_entities );

    //! get the element defined by the vertices in vertex_list, of the
    //! type target_type, passing back in target_entity; if create_if_missing
    //! is true and no entity is found, one is created; if create_adjacency_option
    //! is >= 0, adjacencies from entities of that dimension to target_entity
    //! are created (only create_adjacency_option=0 is supported right now,
    //! so that never creates other ancillary entities); explicitly require
    //! the vertex_list_size for consistency, even though we could probably get
    //! it from target_type
    ErrorCode get_element( const EntityHandle* vertex_list,
                           const int vertex_list_size,
                           const EntityType target_type,
                           EntityHandle& target_entity,
                           const bool create_if_missing,
                           const EntityHandle source_entity  = 0,
                           const int create_adjacency_option = -1 );

    /**\brief Get adjacent entities
     *
     *\param entity            The source entity for which to retrieve adjacent entities.
     *\param to_dimension      The adjacent entities to retrieve, specified by dimension.
     *\param create_if_missing Create adjacent entities that do not already exist.
     *\param adjacent_entities The resulting adjacent entities are appended to this
     *                         list.
     */
    ErrorCode get_adjacencies( const EntityHandle entity,
                               const unsigned int to_dimension,
                               bool create_if_missing,
                               std::vector< EntityHandle >& adjacent_entities );

    //! return const array * for adjacencies
    ErrorCode get_adjacencies( EntityHandle entity, const EntityHandle*& adjacent_entities, int& num_entities ) const;

    ErrorCode get_adjacencies( EntityHandle entity,
                               std::vector< EntityHandle >*& adj_vec_ptr_out,
                               bool create_if_missing = false );

    //! returns the entities in sorted order
    ErrorCode get_adjacencies( EntityHandle entity, std::vector< EntityHandle >& adjacent_entities ) const;

    //! creates vertex to element adjacency information
    ErrorCode create_vert_elem_adjacencies();

    //! returns whether vertex to element adjacencies are being stored
    bool vert_elem_adjacencies() const
    {
        return mVertElemAdj;
    }

    //! calling code notifying this that an entity is getting deleted
    ErrorCode notify_delete_entity( EntityHandle entity );

    //! calling code notifying this that to update connectivity of 'entity'
    ErrorCode notify_create_entity( const EntityHandle entity, const EntityHandle* node_array, const int number_nodes );

    //! calling code notifying that an entity changed its connectivity
    ErrorCode notify_change_connectivity( EntityHandle entity,
                                          const EntityHandle* old_array,
                                          const EntityHandle* new_array,
                                          int number_nodes );

    //! return true if 2 entities are explicitly adjacent
    bool explicitly_adjacent( const EntityHandle ent1, const EntityHandle ent2 );

    //! in preparation for merging two entities, adjust adjacencies so that
    //! entity_to_keep will be adjacent to the "right" entities after merge
    //! (also checks for potential formation of equivalent entities and
    //! creates explicit adjacencies accordingly)
    ErrorCode merge_adjust_adjacencies( EntityHandle entity_to_keep, EntityHandle entity_to_remove );

    void get_memory_use( unsigned long long& total_entity_storage, unsigned long long& total_storage );
    ErrorCode get_memory_use( const Range& entities,
                              unsigned long long& total_entity_storage,
                              unsigned long long& total_amortized_storage );

  private:
    ErrorCode get_adjacency_ptr( EntityHandle, std::vector< EntityHandle >*& );
    ErrorCode get_adjacency_ptr( EntityHandle, const std::vector< EntityHandle >*& ) const;
    ErrorCode set_adjacency_ptr( EntityHandle, std::vector< EntityHandle >* );

    ErrorCode get_vertices( EntityHandle h,
                            const EntityHandle*& vect_out,
                            int& count_out,
                            std::vector< EntityHandle >& storage );

    //! private constructor to prevent the construction of a default one
    AEntityFactory();

    //! interface associated with this tool
    Core* thisMB;

    //! whether vertex to element adjacencies are begin done
    bool mVertElemAdj;

    //! compare vertex_list to the vertices in this_entity,
    //!  and return true if they contain the same vertices
    bool entities_equivalent( const EntityHandle this_entity,
                              const EntityHandle* vertex_list,
                              const int vertex_list_size,
                              const EntityType target_type );

    ErrorCode get_zero_to_n_elements( EntityHandle source_entity,
                                      const unsigned int target_dimension,
                                      std::vector< EntityHandle >& target_entities,
                                      const bool create_if_missing,
                                      const int create_adjacency_option = -1 );

    ErrorCode get_down_adjacency_elements( EntityHandle source_entity,
                                           const unsigned int target_dimension,
                                           std::vector< EntityHandle >& target_entities,
                                           const bool create_if_missing,
                                           const int create_adjacency_option = -1 );

    ErrorCode get_down_adjacency_elements_poly( EntityHandle source_entity,
                                                const unsigned int target_dimension,
                                                std::vector< EntityHandle >& target_entities,
                                                const bool create_if_missing,
                                                const int create_adjacency_option = -1 );

    ErrorCode get_up_adjacency_elements( EntityHandle source_entity,
                                         const unsigned int target_dimension,
                                         std::vector< EntityHandle >& target_entities,
                                         const bool create_if_missing,
                                         const int create_adjacency_option = -1 );

    //! check for equivalent entities that may be formed when merging two entities, and
    //! create explicit adjacencies accordingly
    ErrorCode check_equiv_entities( EntityHandle entity_to_keep, EntityHandle entity_to_remove );

    //! create explicit adjacencies between this_ent and all adjacent entities of higher
    //! dimension
    ErrorCode create_explicit_adjs( EntityHandle this_ent );
};

}  // namespace moab

#endif