Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
MeshSetSequence.cpp
Go to the documentation of this file.
1 /*
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation. Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 /**\file MeshSetSequence.cpp
17  *\author Jason Kraftcheck ([email protected])
18  *\date 2007-04-30
19  */
20 
21 #include "MeshSetSequence.hpp"
22 #include "SequenceManager.hpp"
23 
24 namespace moab
25 {
26 
27 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, SequenceData* dat )
28  : EntitySequence( start, count, dat )
29 {
30  initialize( flags );
31 }
32 
34  : EntitySequence( start, count, dat )
35 {
36  std::vector< unsigned > vect( count, flags );
37  initialize( &vect[0] );
38 }
39 
40 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, EntityID data_size )
41  : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) )
42 {
43  initialize( flags );
44 }
45 
46 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, EntityID data_size )
47  : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) )
48 {
49  std::vector< unsigned > vect( count, flags );
50  initialize( &vect[0] );
51 }
52 
53 void MeshSetSequence::initialize( const unsigned* flags )
54 {
55  if( !data()->get_sequence_data( 0 ) ) data()->create_sequence_data( 0, SET_SIZE );
56 
57  EntityID offset = start_handle() - data()->start_handle();
58  for( EntityID i = 0; i < size(); ++i )
59  allocate_set( flags[i], i + offset );
60 }
61 
63 {
64  EntityID offset = start_handle() - data()->start_handle();
65  EntityID count = size();
66  for( EntityID i = 0; i < count; ++i )
67  deallocate_set( i + offset );
68 }
69 
71 {
72  return new MeshSetSequence( *this, here );
73 }
74 
76 {
77  EntityID offset = end_handle() + 1 - count - data()->start_handle();
78  ErrorCode rval = EntitySequence::pop_back( count );
79  if( MB_SUCCESS == rval )
80  for( EntityID i = 0; i < count; ++i )
81  deallocate_set( i + offset );
82  return rval;
83 }
84 
86 {
87  EntityID offset = start_handle() - data()->start_handle();
88  ErrorCode rval = EntitySequence::pop_front( count );
89  if( MB_SUCCESS == rval )
90  for( EntityID i = 0; i < count; ++i )
91  deallocate_set( i + offset );
92  return rval;
93 }
94 
95 ErrorCode MeshSetSequence::push_back( EntityID count, const unsigned* flags )
96 {
97  EntityID offset = end_handle() + 1 - data()->start_handle();
99  if( MB_SUCCESS == rval )
100  for( EntityID i = 0; i < count; ++i )
101  allocate_set( flags[i], i + offset );
102  return rval;
103 }
104 
105 ErrorCode MeshSetSequence::push_front( EntityID count, const unsigned* flags )
106 {
107  EntityID offset = start_handle() - data()->start_handle() - count;
109  if( MB_SUCCESS == rval )
110  for( EntityID i = 0; i < count; ++i )
111  allocate_set( flags[i], i + offset );
112  return rval;
113 }
114 
115 void MeshSetSequence::get_const_memory_use( unsigned long& per_ent, unsigned long& seq_size ) const
116 {
117  per_ent = SET_SIZE;
118  seq_size = sizeof( *this );
119 }
120 
122 {
123  if( first < start_handle() ) first = start_handle();
124  if( last > end_handle() ) last = end_handle();
125 
126  unsigned long sum = 0;
127  for( EntityHandle h = first; h <= last; ++h )
128  sum += get_set( h )->get_memory_use();
129  return sum;
130 }
131 
133  EntityHandle handle,
134  Range& entities,
135  bool recursive ) const
136 {
137  if( !recursive )
138  {
139  get_set( handle )->get_entities( entities );
140  return MB_SUCCESS;
141  }
142  else
143  {
144  std::vector< const MeshSet* > list;
145  ErrorCode rval = recursive_get_sets( handle, seqman, &list );
146  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
147  ( *i )->get_non_set_entities( entities );
148  return rval;
149  }
150 }
151 
152 ErrorCode MeshSetSequence::get_entities( EntityHandle handle, std::vector< EntityHandle >& entities ) const
153 {
154  get_set( handle )->get_entities( entities );
155  return MB_SUCCESS;
156 }
157 
159  EntityHandle handle,
160  int dimension,
161  std::vector< EntityHandle >& entities,
162  bool recursive ) const
163 {
164  if( !recursive )
165  {
166  get_set( handle )->get_entities_by_dimension( dimension, entities );
167  return MB_SUCCESS;
168  }
169  else
170  {
171  std::vector< const MeshSet* > list;
172  ErrorCode rval = recursive_get_sets( handle, seqman, &list );
173  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
174  ( *i )->get_entities_by_dimension( dimension, entities );
175  return rval;
176  }
177 }
178 
180  EntityHandle handle,
181  int dimension,
182  Range& entities,
183  bool recursive ) const
184 {
185  if( !recursive )
186  {
187  get_set( handle )->get_entities_by_dimension( dimension, entities );
188  return MB_SUCCESS;
189  }
190  else
191  {
192  std::vector< const MeshSet* > list;
193  ErrorCode rval = recursive_get_sets( handle, seqman, &list );
194  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
195  ( *i )->get_entities_by_dimension( dimension, entities );
196  return rval;
197  }
198 }
199 
201  EntityHandle handle,
202  EntityType tp,
203  std::vector< EntityHandle >& entities,
204  bool recursive ) const
205 {
206  if( !recursive )
207  {
208  get_set( handle )->get_entities_by_type( tp, entities );
209  return MB_SUCCESS;
210  }
211  else if( tp == MBENTITYSET )
212  {
213  return recursive_get_sets( handle, seqman, 0, 0, &entities );
214  }
215  else if( tp == MBMAXTYPE )
216  {
217  Range tmp;
218  ErrorCode rval = get_entities( seqman, handle, tmp, recursive );
219  if( MB_SUCCESS == rval )
220  {
221 #ifdef MOAB_NO_VECTOR_TEMPLATE_INSERT
222  std::copy( tmp.begin(), tmp.end(), std::back_inserter( entities ) );
223 #else
224  entities.insert( entities.end(), tmp.begin(), tmp.end() );
225 #endif
226  }
227  return rval;
228  }
229  else
230  {
231  std::vector< const MeshSet* > list;
232  ErrorCode rval = recursive_get_sets( handle, seqman, &list );
233  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
234  ( *i )->get_entities_by_type( tp, entities );
235  return rval;
236  }
237 }
238 
240  EntityHandle handle,
241  EntityType tp,
242  Range& entities,
243  bool recursive ) const
244 {
245  if( !recursive )
246  {
247  get_set( handle )->get_entities_by_type( tp, entities );
248  return MB_SUCCESS;
249  }
250  else if( tp == MBENTITYSET )
251  {
252  return recursive_get_sets( handle, seqman, 0, &entities );
253  }
254  else if( tp == MBMAXTYPE )
255  {
256  std::vector< const MeshSet* > list;
257  ErrorCode rval = recursive_get_sets( handle, seqman, &list );
258  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
259  ( *i )->get_non_set_entities( entities );
260  return rval;
261  }
262  else
263  {
264  std::vector< const MeshSet* > list;
265  ErrorCode rval = recursive_get_sets( handle, seqman, &list );
266  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
267  ( *i )->get_entities_by_type( tp, entities );
268  return rval;
269  }
270 }
271 
273  EntityHandle handle,
274  int& number,
275  bool recursive ) const
276 {
277  if( !recursive )
278  {
279  number = get_set( handle )->num_entities();
280  return MB_SUCCESS;
281  }
282  else
283  {
284  Range range;
285  ErrorCode result = get_entities( seqman, handle, range, true );
286  number = range.size();
287  return result;
288  }
289 }
290 
292  EntityHandle handle,
293  int dimension,
294  int& number,
295  bool recursive ) const
296 {
297  if( !recursive )
298  {
299  number = get_set( handle )->num_entities_by_dimension( dimension );
300  return MB_SUCCESS;
301  }
302  else
303  {
304  Range range;
305  ErrorCode result = get_dimension( seqman, handle, dimension, range, true );
306  number = range.size();
307  return result;
308  }
309 }
310 
312  EntityHandle handle,
313  EntityType tp,
314  int& number,
315  bool recursive ) const
316 {
317  if( !recursive )
318  {
319  number = get_set( handle )->num_entities_by_type( tp );
320  return MB_SUCCESS;
321  }
322  else
323  {
324  Range range;
325  ErrorCode result = get_type( seqman, handle, tp, range, true );
326  number = range.size();
327  return result;
328  }
329 }
330 
332  const SequenceManager* seq_sets,
333  std::vector< const MeshSet* >* sets,
334  Range* set_handles,
335  std::vector< EntityHandle >* set_vector )
336 {
337  std::set< EntityHandle > visited;
338  std::vector< EntityHandle > stack;
339  stack.push_back( start_set );
340  bool remove_start_set = true;
341  while( !stack.empty() )
342  {
343  EntityHandle handle = stack.back();
344  stack.pop_back();
345 
346  if( !visited.insert( handle ).second )
347  {
348  if( handle == start_set ) remove_start_set = false;
349  continue;
350  }
351 
352  const EntitySequence* seq;
353  ErrorCode rval = seq_sets->find( handle, seq );
354  if( MB_SUCCESS != rval ) return rval;
355 
356  const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
357  const MeshSet* ms_ptr = mseq->get_set( handle );
358  if( sets ) sets->push_back( ms_ptr );
359 
360  Range tmp_range;
361  ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range );
362  std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) );
363  }
364 
365  if( set_handles )
366  {
367  if( remove_start_set ) visited.erase( start_set );
368  Range::iterator hint = set_handles->begin();
369  std::set< EntityHandle >::iterator it;
370  for( it = visited.begin(); it != visited.end(); ++it )
371  hint = set_handles->insert( hint, *it, *it );
372  }
373 
374  if( set_vector )
375  {
376  if( remove_start_set ) visited.erase( start_set );
377  std::copy( visited.begin(), visited.end(), std::back_inserter( *set_vector ) );
378  }
379 
380  return MB_SUCCESS;
381 }
382 
384  SequenceManager* seq_sets,
385  std::vector< MeshSet* >& sets )
386 {
387  std::set< EntityHandle > visited;
388  std::vector< EntityHandle > stack;
389  stack.push_back( start_set );
390  while( !stack.empty() )
391  {
392  EntityHandle handle = stack.back();
393  stack.pop_back();
394 
395  if( !visited.insert( handle ).second ) continue;
396 
397  EntitySequence* seq;
398  ErrorCode rval = seq_sets->find( handle, seq );
399  if( MB_SUCCESS != rval ) return rval;
400 
401  MeshSetSequence* mseq = reinterpret_cast< MeshSetSequence* >( seq );
402  MeshSet* ms_ptr = mseq->get_set( handle );
403  sets.push_back( ms_ptr );
404 
405  Range tmp_range;
406  ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range );
407  std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) );
408  }
409 
410  return MB_SUCCESS;
411 }
412 
414  const SequenceManager* seq_sets,
415  std::vector< EntityHandle >& results,
416  int num_hops,
417  SearchType link_type ) const
418 {
419  ErrorCode result = MB_SUCCESS;
420  std::vector< EntityHandle >::iterator i;
421  const EntityHandle *tmp_array = 0, *end;
422  EntityHandle s, e;
423  int count = 0;
424  size_t n;
425 
426  // Skip any meshsets already in input vector (yes, don't
427  // get their children either even if num_hops would indicate
428  // that we should.) There is an exception to that if the
429  // input meshset is in the list, which is handled by the order
430  // of checks in the main loop below.
431  std::set< EntityHandle > visited;
432  for( i = results.begin(); i != results.end(); ++i )
433  visited.insert( *i );
434 
435  // Two lists for breadth-first search
436  std::vector< EntityHandle > lists[2];
437  int index = 0; // which list to read from (write to lists[1-index])
438  lists[index].push_back( meshset ); // begin with input set
439  // loop for num_hops (or until no more sets)
440  for( ; num_hops && !lists[index].empty(); --num_hops )
441  {
442  // for each set at the current num_hops
443  for( i = lists[index].begin(); i != lists[index].end(); ++i )
444  {
445  // get meshset from handle
446  const EntitySequence* seq;
447  ErrorCode rval = seq_sets->find( *i, seq );
448  if( MB_SUCCESS != rval ) return rval;
449  const MeshSet* ms_ptr = reinterpret_cast< const MeshSetSequence* >( seq )->get_set( *i );
450 
451  switch( link_type )
452  {
453  case CONTAINED:
454  tmp_array = ms_ptr->get_contents( n );
455  end = tmp_array + n;
456  if( ms_ptr->vector_based() )
457  {
458  for( ; tmp_array != end; ++tmp_array )
459  if( MBENTITYSET == TYPE_FROM_HANDLE( *tmp_array ) && visited.insert( *tmp_array ).second )
460  lists[1 - index].push_back( *tmp_array );
461  }
462  else
463  {
464  assert( n % 2 == 0 );
465  tmp_array = std::lower_bound( tmp_array, tmp_array + n, FIRST_HANDLE( MBENTITYSET ) );
466  // only part of first block is of type
467  if( ( end - tmp_array ) % 2 )
468  {
469  ++tmp_array;
470  s = FIRST_HANDLE( MBENTITYSET );
471  e = *tmp_array;
472  for( ; s <= e; ++s )
473  if( visited.insert( s ).second ) lists[1 - index].push_back( s );
474  }
475  while( tmp_array < end )
476  {
477  s = *tmp_array++;
478  e = *tmp_array++;
479  for( ; s <= e; ++s )
480  if( visited.insert( s ).second ) lists[1 - index].push_back( s );
481  }
482  }
483  continue;
484  case PARENTS:
485  tmp_array = ms_ptr->get_parents( count );
486  break;
487  case CHILDREN:
488  tmp_array = ms_ptr->get_children( count );
489  break;
490  }
491 
492  // copy any parents/children we haven't visited yet into list
493  for( end = tmp_array + count; tmp_array != end; ++tmp_array )
494  if( visited.insert( *tmp_array ).second ) lists[1 - index].push_back( *tmp_array );
495  }
496 
497  // iterate
498  lists[index].clear();
499  index = 1 - index;
500  // append each level of sets to the output list.
501  // note: to make a more useful search (e.g. get entities 3 hops away,
502  // rather than entities up to and including 3 hops) move this outside
503  // the loop, but then need to handle the get all (num_hops < 0) case
504  // specially.
505  std::copy( lists[index].begin(), lists[index].end(), std::back_inserter( results ) );
506  }
507 
508  return result;
509 }
510 
512  EntityHandle handle,
513  std::vector< EntityHandle >& parents,
514  int num_hops ) const
515 {
516  if( num_hops == 1 )
517  {
518  int count;
519  const EntityHandle* tmp_array = get_set( handle )->get_parents( count );
520  if( parents.empty() )
521  {
522  parents.resize( count );
523  std::copy( tmp_array, tmp_array + count, parents.begin() );
524  return MB_SUCCESS;
525  }
526  else if( !count )
527  {
528  return MB_SUCCESS;
529  }
530  }
531 
532  if( num_hops > 0 )
533  return get_parent_child_meshsets( handle, seqman, parents, num_hops, PARENTS );
534  else
535  return get_parent_child_meshsets( handle, seqman, parents, -1, PARENTS );
536 }
537 
539  EntityHandle handle,
540  std::vector< EntityHandle >& children,
541  int num_hops ) const
542 {
543  if( num_hops == 1 )
544  {
545  int count;
546  const EntityHandle* tmp_array = get_set( handle )->get_children( count );
547  if( children.empty() )
548  {
549  children.resize( count );
550  std::copy( tmp_array, tmp_array + count, children.begin() );
551  return MB_SUCCESS;
552  }
553  else if( !count )
554  {
555  return MB_SUCCESS;
556  }
557  }
558 
559  if( num_hops > 0 )
560  return get_parent_child_meshsets( handle, seqman, children, num_hops, CHILDREN );
561  else
562  return get_parent_child_meshsets( handle, seqman, children, -1, CHILDREN );
563 }
564 
566  EntityHandle handle,
567  std::vector< EntityHandle >& contained,
568  int num_hops ) const
569 {
570  if( num_hops == 1 && contained.empty() )
571  {
572  return get_set( handle )->get_entities_by_type( MBENTITYSET, contained );
573  }
574 
575  if( num_hops > 0 )
576  return get_parent_child_meshsets( handle, seqman, contained, num_hops, CONTAINED );
577  else
578  return get_parent_child_meshsets( handle, seqman, contained, -1, CONTAINED );
579 }
580 
582  EntityHandle handle,
583  int& number,
584  int num_hops ) const
585 {
586  if( num_hops == 1 )
587  {
588  number = get_set( handle )->num_parents();
589  return MB_SUCCESS;
590  }
591 
592  std::vector< EntityHandle > parents;
593  ErrorCode result = get_parents( seqman, handle, parents, num_hops );
594  number = parents.size();
595  return result;
596 }
597 
599  EntityHandle handle,
600  int& number,
601  int num_hops ) const
602 {
603  if( num_hops == 1 )
604  {
605  number = get_set( handle )->num_children();
606  return MB_SUCCESS;
607  }
608 
609  std::vector< EntityHandle > children;
610  ErrorCode result = get_children( seqman, handle, children, num_hops );
611  number = children.size();
612  return result;
613 }
614 
616  EntityHandle handle,
617  int& number,
618  int num_hops ) const
619 {
620  if( num_hops == 1 )
621  {
622  number = get_set( handle )->num_entities_by_type( MBENTITYSET );
623  return MB_SUCCESS;
624  }
625 
626  std::vector< EntityHandle > contained;
627  ErrorCode result = get_contained_sets( seqman, handle, contained, num_hops );
628  number = contained.size();
629  return result;
630 }
631 
632 } // namespace moab