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 _DISJOINTBOXLAYOUT_H_ 00012 #define _DISJOINTBOXLAYOUT_H_ 00013 00014 #include "Vector.H" 00015 #include "BoxLayout.H" 00016 #include "ProblemDomain.H" 00017 #include "NamespaceHeader.H" 00018 00019 struct SliceSpec; 00020 00021 ///A BoxLayout that has a concept of disjointedness 00022 /** 00023 DisjointBoxLayout is-a BoxLayout that has a concept of disjointedness 00024 of the boxes. DisjointBoxLayout is only different from BoxLayout in 00025 that it has a method isDisjoint(). DisjointBoxLayouts also have 00026 a ProblemDomain member to ensure disjointness in the case of periodic 00027 boundary conditions, among other things. 00028 */ 00029 00030 class DisjointBoxLayout: public BoxLayout 00031 { 00032 00033 public: 00034 00035 friend class Copier; 00036 00037 /** 00038 \name Constructors, destructors, defines 00039 */ 00040 /*@{*/ 00041 00042 /// 00043 /** 00044 Construct BoxLayout with no boxes. 00045 */ 00046 DisjointBoxLayout(); 00047 00048 /// 00049 /** Construct from a Vector of Boxes and optionally a Vector of 00050 processor assignments. If the processor assignment Vector 00051 is present, it must be either zero-length or the same length 00052 as the Box Vector. On exit, the DisjointBoxLayout will be closed. 00053 */ 00054 DisjointBoxLayout(const Vector<Box>& a_boxes, 00055 const Vector<int>& a_procIDs); 00056 00057 /// 00058 /** Construct from a Vector of Boxes and optionally a Vector of 00059 processor assignments. If the processor assignment Vector 00060 is present, it must be either zero-length or the same length 00061 as the Box Vector. On exit, the DisjointBoxLayout will be closed. 00062 */ 00063 DisjointBoxLayout(const Vector<Box>& a_boxes, 00064 const Vector<int>& a_procIDs, 00065 const ProblemDomain& a_physDomain); 00066 00067 /// 00068 /** Construct from a LayoutData<Box>. 00069 On exit, the BoxLayout will be closed. 00070 */ 00071 DisjointBoxLayout(const LayoutData<Box>& a_newLayout); 00072 00073 /// 00074 /** 00075 Ref-counted destruction. Once the last reference to the 00076 implementation of this class is destroyed, the data members 00077 are cleaned up. 00078 */ 00079 virtual 00080 ~DisjointBoxLayout() 00081 {} 00082 00083 // for flop counts 00084 unsigned long long int numPointsThisProc() const; 00085 00086 /// 00087 /** Define this DisjointBoxLayout from a Vector of Boxes. This is a 00088 wrapper for a call to BoxLayout::define, required because 00089 DisjointBoxLayout::define is overloaded and the compiler will not 00090 look into the base class for name resolution. 00091 */ 00092 virtual void 00093 define(const Vector<Box>& a_boxes, 00094 const Vector<int>& a_procIDs); 00095 00096 /// 00097 /** 00098 Like the define() that takes the same two arguments, except this one 00099 also initializes a_procIDs if it's not NULL. In that case, the passed-in 00100 a_procIDs should point to a Vector of size 0. 00101 */ 00102 void 00103 defineAndLoadBalance(const Vector<Box>& a_boxes, 00104 Vector<int>* a_procIDs); 00105 00106 /// 00107 /** 00108 Like the define() that takes the same two arguments, except this one 00109 also initializes a_procIDs if it's not NULL. In that case, the passed-in 00110 a_procIDs should point to a Vector of size 0. 00111 */ 00112 void 00113 defineAndLoadBalance(const Vector<Box>& a_boxes, 00114 Vector<int>* a_procIDs, 00115 const ProblemDomain& a_physDomain); 00116 00117 /// 00118 /** Shallow define. Only way to promote a BoxLayout. If BoxLayout 00119 has been closed, then this method checks isDisjoint and throws an 00120 error if not disjoint. If <i>a_layout</i> is disjoint, then this object 00121 becomes a closed DisjointBoxLayout object. 00122 */ 00123 virtual void 00124 define(const BoxLayout& a_layout); 00125 00126 /// 00127 /** Shallow define. Only way to promote a BoxLayout. If BoxLayout 00128 has been closed, then this method checks isDisjoint and throws an 00129 error if not disjoint. If <i>a_layout</i> is disjoint, then this object 00130 becomes a closed DisjointBoxLayout object. If BoxLayout has been closed, 00131 and is sorted, the neighbour iterator is rebuilt (now with knowledge of 00132 the problem domain). 00133 */ 00134 virtual void 00135 define(const BoxLayout& a_layout, const ProblemDomain& a_physDomain); 00136 00137 /// 00138 /** Define this DisjointBoxLayout from a Vector of Boxes. This is a 00139 wrapper for a call to BoxLayout::define, required because 00140 DisjointBoxLayout::define is overloaded and the compiler will not 00141 look into the base class for name resolution. 00142 */ 00143 virtual void 00144 define(const Vector<Box>& a_boxes, 00145 const Vector<int>& a_procIDs, 00146 const ProblemDomain& a_physDomain); 00147 00148 /// 00149 /** Define this DisjointBoxLayout from a Vector of Boxes. 00150 Same as define. 00151 */ 00152 virtual void 00153 define_pd(const Vector<Box>& a_boxes, 00154 const Vector<int>& a_procIDs, 00155 const ProblemDomain& a_physDomain) 00156 {define(a_boxes, a_procIDs, a_physDomain);} 00157 00158 /*@}*/ 00159 00160 /** 00161 \name Checks 00162 */ 00163 /*@{*/ 00164 00165 /// 00166 /** Returns <tt>true</tt> if this object contains a disjoint 00167 union of Boxes. 00168 00169 The Disjoint testing algorithm assumes that the 00170 boxes are CELL-Centered boxes. We can expand the algorithm 00171 when someone needs it. bvs 00172 */ 00173 bool 00174 isDisjoint() const; 00175 00176 /// 00177 /** Checks to see that problem domains are compatible. 00178 To be compatible: 00179 - <i>a_domain</i> and the ProblemDomain in 00180 this DisjointBoxLayout must have the same periodicity. 00181 - The ProblemDomains must be periodic in the same dimensions. 00182 - In all periodic directions, the period must be the same. 00183 00184 There are no checks in non-periodic directions, since 00185 DisjointBoxLayouts don't care about physical domains 00186 except in the periodic case. 00187 */ 00188 bool checkPeriodic(const ProblemDomain& a_domain) const; 00189 00190 /** Performs problem domain check when we don't have direct 00191 access to a problemDomain. 00192 00193 Returns <tt>true</tt> if this and <i>a_dbl</i> 00194 have compatible ProblemDomains. 00195 */ 00196 bool checkDomains(const DisjointBoxLayout& a_dbl) const; 00197 00198 /*@}*/ 00199 00200 /** 00201 \name Modification functions 00202 */ 00203 /*@{*/ 00204 00205 /// 00206 /** Mark this DisjointBoxLayout as complete and unchangeable. 00207 */ 00208 virtual void 00209 close(); 00210 00211 /// 00212 /** Set ProblemDomain. Useful when using addBox() and trying to use closeNoSort() 00213 */ 00214 void setDomain(const ProblemDomain& a_domain) 00215 { 00216 //if (*m_closed) 00217 // { 00218 // MayDay::Error("attempt to setDomain on closed DisjointBoxLayout"); 00219 // } 00220 m_physDomain = a_domain; 00221 } 00222 00223 /// 00224 /** Create new open DisjointBoxLayout with copied data. 00225 00226 Doesn't check for disjointness, since <i>a_source</i> is already 00227 guaranteed to be disjoint. Also copies problem domain 00228 info. */ 00229 virtual void 00230 deepCopy(const DisjointBoxLayout& a_source); 00231 00232 /// 00233 /** Create new open DisjointBoxLayout with copied data. 00234 00235 Checks that the source BoxLayout isDisjoint, throws an error 00236 if it is not. Otherwise, same as BoxLayout::deepCopy. */ 00237 virtual void 00238 deepCopy(const BoxLayout& a_source); 00239 00240 /// 00241 /** Create new open DisjointBoxLayout with copied data. 00242 00243 Checks that the source BoxLayout isDisjoint, throws an error 00244 if it is not. Otherwise, same as BoxLayout::deepCopy. */ 00245 virtual void 00246 deepCopy(const BoxLayout& a_source, const ProblemDomain& a_physDomain); 00247 00248 /** 00249 Makes a_to a one-cell-thick version of *this -- sliced at a_ss.position 00250 along the a_ss.direction'th axis. 00251 If a_ss.position is outside the range of *this, that's a fatal error. 00252 If a_maintainProcAssign = true, maintain processor assignments in the 00253 process (even if it breaks load balancing) 00254 */ 00255 void degenerate( DisjointBoxLayout& a_to, const SliceSpec& a_ss, 00256 bool a_maintainProcAssign = false) const; 00257 00258 /// 00259 /** 00260 00261 Coarsen a DisjointBoxLayout: 00262 - <i>output</i> must be open 00263 - <i>input</i> must be closed 00264 - <i>refinement</i> must be a positive non-zero integer 00265 - <i>output</i> and <i>input</i> do not share an 00266 implementation. 00267 00268 <i>output</i> is first deepCopy'ed from <i>input</i>, 00269 then coarsen(refinement) is called on each box of <i>output</i>. 00270 00271 <i>output</i> returns from this function closed. 00272 00273 LayoutIterators and DataIterators from <i>input</i> and <i>output</i> 00274 can be used interchangeably. 00275 */ 00276 friend void coarsen(DisjointBoxLayout& output, 00277 const DisjointBoxLayout& input, 00278 int refinement); 00279 00280 /// 00281 /** 00282 Refine a DisjointBoxLayout: 00283 - <i>output</i> must be open 00284 - <i>input</i> must be closed 00285 - <i>refinement</i> must be a positive non-zero integer 00286 - <i>output</i> and <i>input</i> do not share an 00287 implementation. 00288 00289 <i>output</i> is first deepCopy'ed from <i>input</i>, 00290 then refine(refinement) is called on each box of <i>output</i>. 00291 00292 <i>output</i> returns from this function closed. 00293 00294 LayoutIterators and DataIterators from <i>input</i> and <i>output</i> 00295 can be used interchangeably. 00296 */ 00297 friend void refine(DisjointBoxLayout& output, 00298 const DisjointBoxLayout& input, 00299 int refinement); 00300 00301 /*@}*/ 00302 00303 /** 00304 \name Neighbor functions 00305 */ 00306 /*@{*/ 00307 00308 /// 00309 /** Returns the set of boxes which you get from calling Box::adjCellLo 00310 on each box in input. Output must be open, is closed upon exit from 00311 this function. A negative length results in the set of boxes 00312 of width a_len on the low side of, but _inside_ the original boxes. 00313 */ 00314 friend void adjCellLo(DisjointBoxLayout& a_output, 00315 const DisjointBoxLayout& a_input, 00316 int a_dir, int a_len); 00317 00318 /// 00319 /** Returns the set of boxes which result from calling Box::adjCellHi 00320 on each box in input. Output must be open, will be closed upon 00321 exiting this function. A negative length results in the set of boxes 00322 of width a_len on the low side of, but _inside_ the original boxes. 00323 */ 00324 friend void adjCellHi(DisjointBoxLayout& a_output, 00325 const DisjointBoxLayout& a_input, 00326 int a_dir, int a_len); 00327 00328 /*@}*/ 00329 00330 const ProblemDomain& physDomain() const; 00331 00332 virtual void closeNoSort(); // close without sorting; used by AdjCellHi, etc. 00333 00334 protected: 00335 /// 00336 friend class NeighborIterator; 00337 ProblemDomain m_physDomain; 00338 00339 // The "pair" here : the first int is the index of the periodic shift iterator, the second unsigned int is 00340 // the box index. an unshifted box is stored with a -1 shift index. 00341 RefCountedPtr<Vector<Vector<std::pair<int, LayoutIndex> > > > m_neighbors; //what a mouthful 00342 00343 void computeNeighbors(); 00344 virtual void closeN( RefCountedPtr<Vector<Vector<std::pair<int, LayoutIndex> > > > neighbors); 00345 virtual void closeNO(); // close, but don't bother building neighbors 00346 00347 }; 00348 void adjCellLo_dbl(DisjointBoxLayout& a_output, 00349 const DisjointBoxLayout& a_input, 00350 int a_dir, int a_len); 00351 void adjCellHi_dbl(DisjointBoxLayout& a_output, 00352 const DisjointBoxLayout& a_input, 00353 int a_dir, int a_len); 00354 void coarsen_dbl(DisjointBoxLayout& output, 00355 const DisjointBoxLayout& input, 00356 int refinement); 00357 void refine_dbl(DisjointBoxLayout& output, 00358 const DisjointBoxLayout& input, 00359 int refinement); 00360 00361 inline 00362 void adjCellLo_dbl(DisjointBoxLayout& a_output, 00363 const DisjointBoxLayout& a_input, 00364 int a_dir, int a_len) 00365 { 00366 adjCellLo(a_output,a_input,a_dir,a_len); 00367 } 00368 inline 00369 void adjCellHi_dbl(DisjointBoxLayout& a_output, 00370 const DisjointBoxLayout& a_input, 00371 int a_dir, int a_len) 00372 { 00373 adjCellHi(a_output,a_input,a_dir,a_len); 00374 } 00375 inline 00376 void coarsen_dbl(DisjointBoxLayout& output, 00377 const DisjointBoxLayout& input, 00378 int refinement) 00379 { 00380 coarsen(output, input, refinement); 00381 } 00382 inline 00383 void refine_dbl(DisjointBoxLayout& output, 00384 const DisjointBoxLayout& input, 00385 int refinement) 00386 { 00387 refine(output, input, refinement); 00388 } 00389 00390 /// 00391 /** Returns the set of boxes which you get from calling Box::adjCellLo 00392 on each box in input. Output must be open, is closed upon exit from 00393 this function. A negative length results in the set of boxes 00394 of width a_len on the low side of, but _inside_ the original boxes. 00395 */ 00396 void adjCellLo(DisjointBoxLayout& a_output, 00397 const DisjointBoxLayout& a_input, 00398 int a_dir, int a_len=1); 00399 00400 /// 00401 /** Returns the set of boxes which result from calling Box::adjCellHi 00402 on each box in input. Output must be open, will be closed upon 00403 exiting this function. A negative length results in the set of boxes 00404 of width a_len on the low side of, but _inside_ the original boxes. 00405 */ 00406 void adjCellHi(DisjointBoxLayout& a_output, 00407 const DisjointBoxLayout& a_input, 00408 int a_dir, int a_len=1); 00409 00410 /*@}*/ 00411 00412 #include "NamespaceFooter.H" 00413 #endif