Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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 /**\file RangeSeqIntersectIter.hpp 00017 *\author Jason Kraftcheck ([email protected]) 00018 *\date 2006-08-11 00019 *\date 2007-11-06 00020 */ 00021 00022 #ifndef MB_RANGE_SEQ_INTERSECT_ITER_HPP 00023 #define MB_RANGE_SEQ_INTERSECT_ITER_HPP 00024 00025 #include "moab/Types.hpp" 00026 #include "moab/Range.hpp" 00027 00028 namespace moab 00029 { 00030 00031 class SequenceManager; 00032 class EntitySequence; 00033 00034 #define MB_RANGE_SEQ_INTERSECT_ITER_STATS 0 00035 00036 /** \brief Iterate over the blocks of EntityHandles in an Range that 00037 * are in the same EntitySequence. 00038 * 00039 * Iterate over an Range, returning blocks of entities that are the 00040 * largest ranges of contiguous handles that meet one of the following 00041 * conditions: 00042 * - All are valid handles belonging to the same EntitySequence 00043 * - All are invalid handles of the same EntityType 00044 * 00045 * The return type from init() or step() indicates whether or not the 00046 * current range contains valid entities. If the handles are either 00047 * all valid or all holes in an EntitySequence, that sequence can 00048 * be obtained with get_sequence(). get_sequence() will return NULL if 00049 * there is no corresponding EntitySequence for the block of handles. 00050 * 00051 * This class keeps a data related to the 'current' EntitySequence and 00052 * references to the Range pasesd to init(). Changing either of these 00053 * while an instance of this class is in use would be bad. 00054 */ 00055 class RangeSeqIntersectIter 00056 { 00057 public: 00058 RangeSeqIntersectIter( SequenceManager* sequences ) 00059 : mSequenceManager( sequences ), mSequence( 0 ), mStartHandle( 0 ), mEndHandle( 0 ), mLastHandle( 0 ) 00060 { 00061 } 00062 00063 /** Initialize iterator to first valid subset 00064 *\return - MB_SUCCESS : initial position of iterator is valid 00065 * - MB_ENITITY_NOT_FOUND : range contains invalid handle -- can step past by calling 00066 *again 00067 * - MB_FAILURE : No entities (start == end) 00068 */ 00069 ErrorCode init( Range::const_iterator start, Range::const_iterator end ); 00070 00071 /** Step iterator to next range. 00072 *\return - MB_SUCCESS : there is another range, and iter has been changed to it 00073 * - MB_ENITITY_NOT_FOUND : range contains invalid handle -- can step past by calling 00074 *again 00075 * - MB_FAILURE : at end. 00076 */ 00077 ErrorCode step(); 00078 00079 /**\brief Check if next call to step() will return MB_FAILURE. 00080 * 00081 * Check if the iterator cannot be advanced any further. 00082 * If this method returns true, then the *next* call to step() 00083 * will return MB_FAILURE. 00084 */ 00085 bool is_at_end() const 00086 { 00087 return mEndHandle == mLastHandle; 00088 } 00089 00090 /** Get the EntitySequence for the current block. 00091 * May be NULL for invaild handles. 00092 */ 00093 EntitySequence* get_sequence() const 00094 { 00095 return mSequence; 00096 } 00097 00098 /** Get first handle in block */ 00099 EntityHandle get_start_handle() const 00100 { 00101 return mStartHandle; 00102 } 00103 00104 /** Get last handle in block */ 00105 EntityHandle get_end_handle() const 00106 { 00107 return mEndHandle; 00108 } 00109 00110 #if MB_RANGE_SEQ_INTERSECT_ITER_STATS 00111 static double fragmentation() 00112 { 00113 return ( doubleNumCalls + intNumCalls ) / ( doubleEntCount + intEntCount ); 00114 } 00115 #endif 00116 00117 private: 00118 /** Update entity sequence data (mSequence and freeIndex) for current 00119 * mStartHandle. If mEndHandle is past end of sequence, trim it. 00120 * Called by step() and init(). step() handles iterating over the pairs 00121 * in the Range. This method handles iterating over the set of 00122 * EntitySequences that intersect the pair. 00123 */ 00124 ErrorCode update_entity_sequence(); 00125 00126 /** Handle error case where we encountered an EntityHandle w/out 00127 * a corresponding EntitySequence. Trim mEndHandle such that it 00128 * is before the next valid EntityHandle of the same type. 00129 *\return Always returns MB_ENTITY_NOT_FOUND 00130 */ 00131 ErrorCode find_invalid_range(); 00132 00133 SequenceManager* mSequenceManager; //!< THE EntitySequenceManager 00134 EntitySequence* mSequence; //!< EntitySequence corresponding to current location 00135 Range::const_pair_iterator rangeIter; //!< Current position in Range. 00136 EntityHandle mStartHandle, mEndHandle; //!< Subset of current EntitySequence 00137 EntityHandle mLastHandle; //!< The last of the list of all handles in the Range 00138 00139 #if MB_RANGE_SEQ_INTERSECT_ITER_STATS 00140 static double doubleNumCalls, doubleEntCount; 00141 static unsigned long intNumCalls, intEntCount; 00142 static void update_stats( unsigned long num_ents ); 00143 #endif 00144 }; 00145 00146 } // namespace moab 00147 00148 #endif