00001 #ifdef CH_LANG_CC 00002 /* 00003 * _______ __ 00004 * / ___/ / ___ __ _ / / ___ 00005 * / /__/ _ \/ _ \/ V \/ _ \/ _ \ 00006 * \___/_//_/\___/_/_/_/_.__/\___/ 00007 * Please refer to Copyright.txt, in Chombo's root directory. 00008 */ 00009 #endif 00010 00011 #ifndef _BOXITERATOR_H_ 00012 #define _BOXITERATOR_H_ 00013 00014 #include <cstdlib> 00015 00016 #include "Box.H" 00017 #include "REAL.H" 00018 #include "SPACE.H" 00019 #include "IntVect.H" 00020 #include "NamespaceHeader.H" 00021 00022 ///iterates through the IntVects of a Box 00023 /** 00024 BoxIterator iterates through the IntVects of a box. The actual 00025 sqeuence of IntVects is implementation-specific. 00026 Typical usage: 00027 00028 Box b; 00029 ... 00030 BoxIterator bit (b); 00031 for (bit.begin(); bit.ok(); ++bit) 00032 { 00033 IntVect iv = bit(); 00034 (do operations involving iv) 00035 } 00036 */ 00037 class BoxIterator 00038 { 00039 public: 00040 /// 00041 /** 00042 Default constructor. This constructs an invalid iterator. 00043 The user must call define before using. 00044 */ 00045 BoxIterator(); 00046 00047 /// 00048 /** 00049 Constructs a BoxIterator and associates it with a Box. 00050 Arguments: 00051 a_bx (not modified) the Box to iterate over. 00052 */ 00053 BoxIterator(const Box& a_bx); 00054 00055 void setBox(const Box& a_bx); 00056 00057 /// 00058 /** 00059 Associates a Box with this BoxIterator. 00060 Arguments: 00061 a_bx (not modified) the Box to iterate over. 00062 */ 00063 void define(const Box& a_bx); 00064 00065 /// 00066 /** 00067 Copy constructor. 00068 Arguments: 00069 a_iterIn (not modified) the BoxIterator to copy. 00070 */ 00071 BoxIterator(const BoxIterator& a_iterIn); 00072 00073 /// 00074 ~BoxIterator () 00075 { 00076 } 00077 00078 /// 00079 /** 00080 Sets this BoxIterator to the first IntVect in its Box. The 00081 definition of the "first" IntVect is 00082 implementation-dependent. 00083 */ 00084 void begin(); 00085 00086 /// 00087 /** 00088 Sets this BoxIterator to the first IntVect in its Box. The 00089 definition of the "first" IntVect is 00090 implementation-dependent. 00091 */ 00092 void reset(); 00093 00094 /// 00095 /** 00096 Modifies this BoxIterator to set it to the next location in its 00097 Box. The definition of the "next location" of a Box is 00098 implementation-dependent. 00099 */ 00100 void operator ++ (); 00101 00102 void next(); 00103 00104 /// 00105 /** 00106 Returns the value of the InVect for the current location of this 00107 BoxIterator. 00108 */ 00109 const IntVect& operator () () const; 00110 00111 /// 00112 /** 00113 Returns true if this BoxIterator's location is within its Box. 00114 */ 00115 bool ok(); 00116 00117 unsigned long long size() const; 00118 00119 IntVect at(unsigned long long pt) const; 00120 00121 protected: 00122 IntVect m_current; 00123 IntVect m_boxLo; 00124 IntVect m_boxHi; 00125 }; 00126 00127 inline 00128 BoxIterator::BoxIterator() 00129 { 00130 m_current = IntVect::Unit; 00131 m_boxLo = IntVect::Unit; 00132 m_boxHi = IntVect::Zero; 00133 } 00134 00135 inline 00136 BoxIterator::BoxIterator(const Box& a_bx) 00137 { 00138 define(a_bx); 00139 } 00140 00141 inline 00142 BoxIterator::BoxIterator(const BoxIterator& a_iterIn) 00143 { 00144 m_current = a_iterIn.m_current; 00145 m_boxLo = a_iterIn.m_boxLo; 00146 m_boxHi = a_iterIn.m_boxHi; 00147 } 00148 00149 inline 00150 void BoxIterator::begin() 00151 { 00152 if (m_boxLo <= m_boxHi) m_current = m_boxLo; 00153 } 00154 00155 inline 00156 void BoxIterator::reset() 00157 { 00158 begin(); 00159 } 00160 00161 inline 00162 void BoxIterator::operator ++ () 00163 { 00164 next(); 00165 } 00166 00167 inline 00168 void BoxIterator::next() 00169 { 00170 m_current[0]++; 00171 #if CH_SPACEDIM >= 2 00172 if (m_current[0] > m_boxHi[0]) 00173 { 00174 m_current[0] = m_boxLo[0]; 00175 m_current[1]++; 00176 #if CH_SPACEDIM >= 3 00177 if (m_current[1] > m_boxHi[1]) 00178 { 00179 m_current[1] = m_boxLo[1]; 00180 m_current[2]++; 00181 #if CH_SPACEDIM >= 4 00182 if (m_current[2] > m_boxHi[2]) 00183 { 00184 m_current[2] = m_boxLo[2]; 00185 m_current[3]++; 00186 #if CH_SPACEDIM >= 5 00187 if (m_current[3] > m_boxHi[3]) 00188 { 00189 m_current[3] = m_boxLo[3]; 00190 m_current[4]++; 00191 #if CH_SPACEDIM == 6 00192 if (m_current[4] > m_boxHi[4]) 00193 { 00194 m_current[4] = m_boxLo[4]; 00195 m_current[5]++; 00196 } 00197 #elif CH_SPACEDIM > 6 00198 SPACEDIM > 6 undefined!; 00199 #endif 00200 } 00201 #endif 00202 } 00203 #endif 00204 } 00205 #endif 00206 } 00207 #endif 00208 } 00209 00210 inline 00211 unsigned long long BoxIterator::size() const 00212 { 00213 unsigned long long rtn = (m_boxHi[0]-m_boxLo[0]+1); 00214 #if CH_SPACEDIM >= 2 00215 rtn *= (m_boxHi[1]-m_boxLo[1]+1); 00216 #if CH_SPACEDIM >= 3 00217 rtn *= (m_boxHi[2]-m_boxLo[2]+1); 00218 #if CH_SPACEDIM >= 4 00219 rtn *= (m_boxHi[3]-m_boxLo[3]+1); 00220 #if CH_SPACEDIM >= 5 00221 rtn *= (m_boxHi[4]-m_boxLo[4]+1); 00222 #if CH_SPACEDIM == 6 00223 rtn *= (m_boxHi[5]-m_boxLo[5]+1); 00224 #elif CH_SPACEDIM > 6 00225 SPACEDIM > 6 undefined!; 00226 #endif 00227 00228 #endif 00229 00230 #endif 00231 00232 #endif 00233 00234 #endif 00235 return rtn; 00236 } 00237 00238 inline 00239 IntVect BoxIterator::at(unsigned long long int pt) const 00240 { 00241 IntVect rtn; 00242 rtn[0]=m_boxLo[0]+ pt%(m_boxHi[0]-m_boxLo[0]+1); 00243 #if CH_SPACEDIM >= 2 00244 pt/=(m_boxHi[0]-m_boxLo[0]+1); 00245 rtn[1]=m_boxLo[1]+ pt%(m_boxHi[1]-m_boxLo[1]+1); 00246 #if CH_SPACEDIM >= 3 00247 pt/=(m_boxHi[1]-m_boxLo[1]+1); 00248 rtn[2]=m_boxLo[2]+ pt%(m_boxHi[2]-m_boxLo[2]+1); 00249 #if CH_SPACEDIM >= 4 00250 pt/=(m_boxHi[2]-m_boxLo[2]+1); 00251 rtn[3]=m_boxLo[3]+ pt%(m_boxHi[3]-m_boxLo[3]+1); 00252 #if CH_SPACEDIM >= 5 00253 pt/=(m_boxHi[3]-m_boxLo[3]+1); 00254 rtn[4]=m_boxLo[4]+ pt%(m_boxHi[4]-m_boxLo[4]+1); 00255 #if CH_SPACEDIM == 6 00256 pt/=(m_boxHi[4]-m_boxLo[4]+1); 00257 rtn[5]=m_boxLo[5]+ pt%(m_boxHi[5]-m_boxLo[5]+1); 00258 #elif CH_SPACEDIM > 6 00259 SPACEDIM > 6 undefined!; 00260 #endif 00261 00262 #endif 00263 00264 #endif 00265 00266 #endif 00267 00268 #endif 00269 return rtn; 00270 } 00271 00272 inline 00273 const IntVect& BoxIterator::operator () () const 00274 { 00275 CH_assert(m_current <= m_boxHi); 00276 CH_assert(m_current >= m_boxLo); 00277 return m_current; 00278 } 00279 00280 inline 00281 bool BoxIterator::ok() 00282 { 00283 return (m_current <= m_boxHi); 00284 } 00285 00286 #include "NamespaceFooter.H" 00287 #endif