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