1 #ifndef SEQUENCE_MANAGER_HPP
2 #define SEQUENCE_MANAGER_HPP
3 
4 #include "TypeSequenceManager.hpp"
5 #include "TagInfo.hpp"
6 #include <vector>
7 
8 namespace moab {
9 
10 class HomCoord;
11 class Error;
12 
13 class SequenceManager
14 {
15   public:
16 
SequenceManager(double default_seq_multiplier=1.0)17     SequenceManager(double default_seq_multiplier = 1.0) : sequence_multiplier(default_seq_multiplier)
18     { }
19 
20     ~SequenceManager();
21 
22       /** Delete all contained data */
23     void clear();
24 
25       /** Find entity sequence containing specified handle.
26        *\return MB_SUCCESS or MB_ENTITY_NOT_FOUND
27        */
find(EntityHandle handle,EntitySequence * & sequence_out)28     ErrorCode find( EntityHandle handle, EntitySequence*& sequence_out )
29       {
30         return typeData[TYPE_FROM_HANDLE(handle)].find( handle, sequence_out );
31       }
32 
33       /** Find entity sequence containing specified handle.
34        *\return MB_SUCCESS or MB_ENTITY_NOT_FOUND
35        */
find(EntityHandle handle,const EntitySequence * & sequence_out) const36     ErrorCode find( EntityHandle handle, const EntitySequence*& sequence_out ) const
37       {
38         return typeData[TYPE_FROM_HANDLE(handle)].find( handle, sequence_out );
39       }
40 
41       /** Get all entities of a given EntityType, return all entities
42        *  if type == MBMAXTYPE */
get_entities(EntityType type,Range & entities_out) const43     void get_entities( EntityType type, Range& entities_out ) const
44       {
45         if (type == MBMAXTYPE)
46           get_entities( entities_out );
47         else
48           typeData[type].get_entities( entities_out );
49       }
50 
51     void get_entities( Range& entities_out ) const;
52 
53       /** Get all entities of a given EntityType, return all entities
54        *  if type == MBMAXTYPE */
get_entities(EntityType type,std::vector<EntityHandle> & entities_out) const55     void get_entities( EntityType type, std::vector<EntityHandle>& entities_out ) const
56       {
57         if (type == MBMAXTYPE)
58           get_entities( entities_out );
59         else
60           typeData[type].get_entities( entities_out );
61       }
62 
63     void get_entities( std::vector<EntityHandle>& entities_out ) const;
64 
65       /** Count entities of a given EntityType */
get_number_entities(EntityType type) const66     EntityID get_number_entities( EntityType type ) const
67       { return type == MBMAXTYPE ? get_number_entities() : typeData[type].get_number_entities(); }
68 
69       /** Count entities of a given EntityType */
70     EntityID get_number_entities( ) const;
71 
72       /** Get most recently accessed sequence for a given type */
get_last_accessed_sequence(EntityType type) const73     const EntitySequence* get_last_accessed_sequence( EntityType type ) const
74       { return typeData[type].get_last_accessed(); }
75 
76       /**\brief Replace subset of existing sequence with new
77        *        sequence (splits existing sequence)
78        *
79        * Used for converting number of nodes for fixed-connectivity-length
80        * elements.  Input sequence must be a non-strict subset of an existing
81        * sequence.  Existing sequence will be removed, modified, or split
82        * into two prevent it from overlapping the new sequence.
83        */
84     ErrorCode replace_subsequence( EntitySequence* new_seq );
85 
86       /** Check if passed entity handles are valid */
87     ErrorCode check_valid_entities( Error* error_handler,
88                                     const Range& entities ) const;
89 
90       /** Check if passed entity handles are valid
91        *\param root_set_okay  If true, do not returnan error if the passed
92        *                      array contains one or more zero-valued handles
93        */
94     ErrorCode check_valid_entities( Error* error_handler,
95                                     const EntityHandle entities[],
96                                     size_t num_entities,
97                                     bool root_set_okay = false ) const;
98 
99       /** Delete an entity.  Deletes sequence if only contained entity. */
100     ErrorCode delete_entity( Error* error_handler, EntityHandle entity );
101 
102       /** Delete entities */
103     ErrorCode delete_entities( Error* error_handler, const Range& entities );
104 
105       /** Allocate a vertex (possibly in an existing sequence) and
106        *  assign it the passed coordinate values.
107        */
108     ErrorCode create_vertex( const double coords[3],
109                                EntityHandle& handle_out );
110 
111       /** Allocate a element (possibly in an existing sequence) and
112        *  assign it the passed connectivity.
113        */
114     ErrorCode create_element( EntityType type,
115                                 const EntityHandle* conn_array,
116                                 unsigned num_vertices,
117                                 EntityHandle& handle_out );
118 
119       /** Allocate an entity set (possibly in an existing sequence) */
120     ErrorCode create_mesh_set( unsigned flags,
121                                  EntityHandle& handle_out );
122       /** Allocate an entity set with the specified handle.
123        *\return MB_ALREADY_ALLOCATED if handle is in use, MB_SUCCESS otherwise.
124        */
125     ErrorCode allocate_mesh_set( EntityHandle at_this_handle,
126                                    unsigned flags );
127 
128       /**\brief Allocate a block of consecutive entity handles
129        *
130        * Allocate a block of consecutive entity handles.  Handles
131        * may be appended or prepended to an existing entity sequence.
132        *\param type The type of of entity for which to allocate handles
133        *\param num_entities Number of entities to allocate
134        *\param nodes_per_entity Number of nodes in connectivity for elements,
135        *                    ignored MBVERTEX, MBPOLYGON, MBPOLYHEDRON, and
136        *                    MBENTITYSET types.
137        *\param start_id_hint Preferred ID portion for first handle.
138        *                    May be ignored if not available.
139        *\param first_handle_out First allocated handle.  Allocated handles
140        *                    are [first_handle_out, first_handle_out+num_entities-1].
141        *\param sequence_out The sequence in which the entities were allocated.
142        *                    NOTE: first_handle_out may not be first handle in
143        *                    sequence.
144        *\param sequence_size If specified, allocate this sequence size instead of DEFAULT_***_SEQUENCE_SIZE
145        */
146     ErrorCode create_entity_sequence( EntityType type,
147                                       EntityID num_entities,
148                                       int nodes_per_entity,
149                                       EntityID start_id_hint,
150                                       EntityHandle& first_handle_out,
151                                       EntitySequence*& sequence_out,
152                                       int sequence_size);
153 
154        /**\brief Allocate a block of consecutive mesh sets
155        *
156        * Allocate a block of consecutive entity handles.  Handles
157        * may be appended or prepended to an existing entity sequence.
158        *\param type The type of of entity for which to allocate handles
159        *\param num_sets     Number of entities to allocate
160        *\param start_id_hint Preferred ID portion for first handle.
161        *                    May be ignored if not available.
162        *\param processor_id Processor ID to embed in handles
163        *\param flags        Array of length 'num_sets' containing entity set
164        *                    creating flags.
165        *\param first_handle_out First allocated handle.  Allocated handles
166        *                    are [first_handle_out, first_handle_out+num_entities-1].
167        *\param sequence_out The sequence in which the entities were allocated.
168        *                    NOTE: first_handle_out may not be first handle in
169        *                    sequence.
170        */
171     ErrorCode create_meshset_sequence( EntityID num_sets,
172                                          EntityID start_id_hint,
173                                          const unsigned* flags,
174                                          EntityHandle& first_handle_out,
175                                          EntitySequence*& sequence_out );
176 
177       /**\brief Allocate a block of consecutive mesh sets
178        *
179        * Alternate form that creates all mesh sets with same flags.
180        */
181     ErrorCode create_meshset_sequence( EntityID num_sets,
182                                          EntityID start_id_hint,
183                                          unsigned flags,
184                                          EntityHandle& first_handle_out,
185                                          EntitySequence*& sequence_out );
186 
187       /** Create structured mesh */
188     ErrorCode create_scd_sequence( int imin, int jmin, int kmin,
189                                      int imax, int jmax, int kmax,
190                                      EntityType type,
191                                      EntityID start_id_hint,
192                                      EntityHandle& first_handle_out,
193                                    EntitySequence*& sequence_out,
194                                    int *is_periodic = NULL);
195 
196       /** Create structured mesh */
197     ErrorCode create_scd_sequence( const HomCoord& coord_min,
198                                      const HomCoord& coord_max,
199                                      EntityType type,
200                                      EntityID start_id_hint,
201                                      EntityHandle& first_handle_out,
202                                      EntitySequence*& sequence_out,
203                                    int *is_periodic = NULL);
204 
205       /** Create swept mesh */
206     ErrorCode create_sweep_sequence( int imin, int jmin, int kmin,
207 				       int imax, int jmax, int kmax,
208 				       int* Cq,
209 				       EntityType type,
210 				       EntityID start_id_hint,
211 				       EntityHandle& first_handle_out,
212 				       EntitySequence*& sequence_out );
213 
214       /** Create swept mesh */
215     ErrorCode create_sweep_sequence( const HomCoord& coord_min,
216 				       const HomCoord& coord_max,
217 				       int* Cq,
218 				       EntityType type,
219 				       EntityID start_id_hint,
220 				       EntityHandle& first_handle_out,
221 				       EntitySequence*& sequence_out );
222 
223     /** Add a structured vertex sequence to this structured element sequence;
224      * see comments in ScdElementData */
225   ErrorCode add_vsequence(EntitySequence *vert_seq,
226                             EntitySequence *elem_seq,
227                             const HomCoord &p1, const HomCoord &q1,
228                             const HomCoord &p2, const HomCoord &q2,
229                             const HomCoord &p3, const HomCoord &q3,
230                             bool bb_input = false,
231                             const HomCoord *bb_min = NULL,
232                             const HomCoord *bb_max = NULL);
233 
234       /** Get data for a specific EntityType */
entity_map(EntityType type)235     TypeSequenceManager& entity_map( EntityType type )
236       { return typeData[type]; }
237 
238       /** Get data for a specific EntityType */
entity_map(EntityType type) const239     const TypeSequenceManager& entity_map( EntityType type ) const
240       { return typeData[type]; }
241 
242     void get_memory_use( unsigned long long& total_entity_storage,
243                          unsigned long long& total_storage ) const;
244 
245     void get_memory_use( EntityType type,
246                          unsigned long long& total_entity_storage,
247                          unsigned long long& total_storage ) const;
248 
249     void get_memory_use( const Range& entities,
250                          unsigned long long& total_entity_storage,
251                          unsigned long long& total_amortized_storage ) const;
252 
253 
254 
255     /* Dense Tag Functions */
256 
257       /** Allocate a tag ID
258        *\param tag_size The size of the tag value for each entity
259        */
260     ErrorCode reserve_tag_array( Error* error_handler, int tag_size, int& array_id_out );
261 
262       /** Release any storage assocociated with a tag ID, and optionally,
263        *  release the reserved tag ID. */
264     ErrorCode release_tag_array( Error* error_handler, int id, bool release_id );
265 
266       /**\brief Get default size of POLYGON and POLYHEDRON SequenceData */
267     static EntityID default_poly_sequence_size( int entity_connectivity_length );
268 
269       /**\brief Size to allocate for new SquenceData
270        * THIS FUNCTION SHOULD ONLY BE CALLED WHEN ALLOCATING FROM ReadUtil IN BULK
271        * (since it will allocate lesser of requested_size and default_size)
272        * If sequence_size != -1, will try to allocate that, unless there isn't available
273        * space
274        */
275     EntityID new_sequence_size( EntityHandle start_handle,
276                                 EntityID requested_size,
277                                 int sequence_size) const;
278 
279     /** \brief Interface to control memory allocation for sequences
280      * Provide a factor that controls the size of the sequence that gets allocated.
281      * This is typically useful in the parallel setting when a-priori, the number of ghost entities
282      * and the memory required for them within the same sequence as the owned entities are unknown.
283      * The default factor is 1.0 but this can be appropriately updated at runtime so that we do not
284      * have broken sequences.
285      */
get_sequence_multiplier() const286     double get_sequence_multiplier() const
287     { return sequence_multiplier; }
288 
289     /** \brief Interface to control memory allocation for sequences
290      * Provide a factor that controls the size of the sequence that gets allocated.
291      * This is typically useful in the parallel setting when a-priori, the number of ghost entities
292      * and the memory required for them within the same sequence as the owned entities are unknown.
293      * The default factor is 1.0 but this can be appropriately updated at runtime so that we do not
294      * have broken sequences.
295      *
296      * \param meshset User specified multiplier (should be greater than 1.0)
297      */
set_sequence_multiplier(double factor)298     void set_sequence_multiplier(double factor)
299     { sequence_multiplier = factor; }
300 
301     /**\brief Default allocation size for vertices */
302   static const EntityID DEFAULT_VERTEX_SEQUENCE_SIZE;
303 
304     /**\brief Default allocation size for elements */
305   static const EntityID DEFAULT_ELEMENT_SEQUENCE_SIZE;
306 
307     /**\brief Default allocation size for poly's */
308   static const EntityID DEFAULT_POLY_SEQUENCE_SIZE;
309 
310     /**\brief Default allocation size for meshsets */
311   static const EntityID DEFAULT_MESHSET_SEQUENCE_SIZE;
312 
313   private:
314 
315     /**\brief Utility function for allocate_mesh_set (and similar)
316      *
317      * Given a block of available handles, determine the non-strict
318      * subset at which to create a new EntitySequence.
319      */
320     void trim_sequence_block( EntityHandle start_handle,
321                               EntityHandle& end_handle_in_out,
322                               unsigned maximum_sequence_size );
323 
324 
325       /**\brief Get range of handles in which to create an entity sequence
326        *
327        * Get range of handles in whcih to place a new entity sequence.
328        *\param type              The EntityType for the contents of the sequence
329        *\param entity_count      The number of entities in the range
330        *\param values_per_entity Vertices per element, zero for other types
331        *\param start_id_hint     Preferred id of first handle
332        *\param processor_rank    MPI processor ID
333        *\param data_out  Output: Either NULL or an existing SequenceData
334        *                         with a sufficiently large block to accomodate
335        *                         the handle range.
336        *\return zero if no available handle range, start handle otherwise.
337        */
338     EntityHandle sequence_start_handle( EntityType type,
339                                           EntityID entity_count,
340                                           int values_per_entity,
341                                           EntityID start_id_hint,
342                                           SequenceData*& data_out,
343                                           EntityID &data_size );
344 
345     TypeSequenceManager typeData[MBMAXTYPE];
346 
347     std::vector<int> tagSizes;
348 
349      /**\brief The over-allocation factor for entities in a sequence (strictly >= 1.0) */
350     double sequence_multiplier;
351 
352 };
353 
354 } // namespace moab
355 
356 #endif
357