![]() |
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 (kraftche@cae.wisc.edu)
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