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 _CODIMBOX_H_ 00012 #define _CODIMBOX_H_ 00013 #include "BaseFab.H" 00014 #include "FArrayBox.H" 00015 #include "BoxLayoutData.H" 00016 #include "NamespaceHeader.H" 00017 00018 /******************************************************************************* 00019 */ 00020 /// An FArrayBox container for storage on the codimensions of a box. 00021 /** 00022 * The orientation of a box is described by specifying the orthogonal 00023 * directions and internally, this is converted to a bit representation. 00024 * Direction 'i' is bit 2^i (or via shifting as 1 << i). Directions can be 00025 * specified in any order. For example, the edges in 3D orthogonal to 00026 * directions i and j may be specified as (0, 1) or (1, 0). Internally, both 00027 * are converted to 0x3. Orientations can be described by sequential indices 00028 * or bit representations. The routines seq2bit and bit2seq can be used to 00029 * switch between the two using lookup tables. 00030 * 00031 * For example, a 3 dimensional space has the following codimensions, bit 00032 * representations, and sequential indices of the orientations: 00033 * \verbatim 00034 * Codim Bit Integer Sequential numOrient totOrient 00035 * Dir zyx 00036 * 0 000 0 0 1 0 00037 * 1 001 1 0 3 1 00038 * 1 010 2 1 00039 * 1 100 4 2 00040 * 2 011 3 0 3 4 00041 * 2 101 5 1 00042 * 2 110 6 2 00043 * 3 111 7 0 1 7 00044 * \endverbatim 00045 * The 'indexFAB' and 'bitOrient' are then defined as follows: 00046 * \verbatim 00047 * indexFAB: 0 0 1 0 2 1 2 0 00048 * bitOrient: 0 1 2 4 3 5 6 7 00049 * \endverbatim 00050 * \note 00051 * <ul> 00052 * <li> CodimBoxFactory is also defined in this file for use with 00053 * BoxLayoutData and similar containers 00054 * <li> A FluxBox is essentially a CodimBox with codimension 1. 00055 * <li> Not much functionality exists in this class beyond creating and 00056 * retrieving the FArrayBoxes. 00057 * <li> Codimension 0 is the original object spanning 'SpaceDim' dimensions. 00058 * Using this is no different from an FArrayBox itself. 00059 * <li> Codimension 'SpaceDim' is a vertex. This is also the same as an 00060 * FArrayBox that surrounds all nodes. 00061 * </ul> 00062 * 00063 ******************************************************************************/ 00064 00065 template <class S >class CodimBox 00066 { 00067 00068 public: 00069 enum 00070 { 00071 numCD = SpaceDim + 1, ///< Number of codimensions 00072 numAI = 1 << SpaceDim ///< Total orientations (array indices) for 00073 ///< all codimensions 00074 }; 00075 00076 /// Default constructor 00077 CodimBox(); 00078 00079 /// Full constructor 00080 CodimBox(const int a_codim, const Box& a_box, const int a_nvar); 00081 00082 /// Destructor 00083 ~CodimBox(); 00084 00085 /// Initialize static lookup tables 00086 static void initialize(); 00087 00088 /// Full define function 00089 void define(const int a_codim, const Box& a_box, const int a_nvar); 00090 00091 /// Define function 00092 void define(const Box& a_box, int a_nvar); 00093 00094 /// Deallocate 00095 void clear(); 00096 00097 /// Return the codimension 00098 int getCodim() const; 00099 00100 /// Number of components 00101 int nComp() const; 00102 00103 /// Number of different orientations of codimensional objects 00104 int getNumOrient() const; 00105 00106 /// Number of different orientations of codimensional objects. Used 00107 /// externally for any codimension. 00108 static int getNumOrient(const int a_codim); 00109 00110 /// Switch from a bit orientation to a sequential index of the 00111 /// orientation 00112 int bit2seq(const unsigned a_bOrient) const; 00113 00114 /// Switch from a sequential index to a bit representation of the 00115 /// orientation 00116 unsigned seq2bit(const int a_iOrient) const; 00117 00118 /// Switch from a sequential index to a bit representation of the orientation 00119 /// for any codimension 00120 static unsigned seq2bit(const int a_codim, const int a_iOrient); 00121 00122 /// Get the 'i'th orthogonal direction of an orientation 00123 int getDirection(const int a_iOrient, int a_i) const; 00124 00125 /// Get all the orthogonal directions of an orientation 00126 void getDirections(const int a_iOrient, int *const a_dir) const; 00127 00128 /// Get all the orthogonal directions of an orientation. Used externally for 00129 /// any codimension. 00130 static void getDirections(const int a_codim, 00131 const int a_iOrient, 00132 int *const a_dir); 00133 00134 /// Returns cell-centered box which defines the CodimBox 00135 const Box& box() const; 00136 00137 /// Returns S in the directions defined by a Box 00138 const S& operator()(const Box &a_box) const; 00139 S& operator()(const Box &a_box); 00140 00141 /// Returns S in the directions defined by an IndexType 00142 const S& operator()(const IndexType &a_ixType) const; 00143 S& operator()(const IndexType &a_ixType); 00144 00145 /// Returns S in the given direction (codimension 0) 00146 const S& operator()() const; 00147 S& operator()(); 00148 00149 /// Returns S in the given direction (codimension 1) 00150 const S& operator()(const int a_dir0) const; 00151 S& operator()(const int a_dir0); 00152 00153 /// Returns S in the given direction (codimension 2) 00154 const S& operator()(const int a_dir0, 00155 const int a_dir1) const; 00156 S& operator()(const int a_dir0, 00157 const int a_dir1); 00158 00159 /// Returns S in the given direction (codimension 3) 00160 const S& operator()(const int a_dir0, 00161 const int a_dir1, 00162 const int a_dir2) const; 00163 S& operator()(const int a_dir0, 00164 const int a_dir1, 00165 const int a_dir2); 00166 00167 /// Returns S in the given direction (codimension 4) 00168 const S& operator()(const int a_dir0, 00169 const int a_dir1, 00170 const int a_dir2, 00171 const int a_dir3) const; 00172 S& operator()(const int a_dir0, 00173 const int a_dir1, 00174 const int a_dir2, 00175 const int a_dir3); 00176 00177 /// Returns S in the given direction (codimension 5) 00178 const S& operator()(const int a_dir0, 00179 const int a_dir1, 00180 const int a_dir2, 00181 const int a_dir3, 00182 const int a_dir4) const; 00183 S& operator()(const int a_dir0, 00184 const int a_dir1, 00185 const int a_dir2, 00186 const int a_dir3, 00187 const int a_dir4); 00188 00189 /// Returns S in the given direction (codimension 6) 00190 const S& operator()(const int a_dir0, 00191 const int a_dir1, 00192 const int a_dir2, 00193 const int a_dir3, 00194 const int a_dir4, 00195 const int a_dir5) const; 00196 S& operator()(const int a_dir0, 00197 const int a_dir1, 00198 const int a_dir2, 00199 const int a_dir3, 00200 const int a_dir4, 00201 const int a_dir5); 00202 00203 /// Returns S from a sequential index 00204 const S& getSequential(const int a_iOrient) const; 00205 S& getSequential(const int a_iOrient); 00206 00207 /// Set all values in all FAB 00208 void setVal(const Real a_x); 00209 00210 /// Orient the stored box in the othogonal directions of the given 00211 /// orientation 00212 Box orientBox(const int a_iOrient) const; 00213 00214 /// Orient a centered box in the othogonal directions of the given 00215 /// orientation 00216 Box orientBox(const int a_iOrient, const Box& a_cbox) const; 00217 00218 /// Orient a centered box in the othogonal directions of the given 00219 /// orientation. Used externally for any codimension. 00220 static Box orientBox(const int a_codim, 00221 const int a_iOrient, 00222 const Box& a_cbox); 00223 00224 /// Copy from another CodimBox 00225 void copy(const Box& a_R, 00226 const Interval& a_Cd, 00227 const CodimBox& a_src, 00228 const Interval& a_Cs); 00229 00230 /// Copy from another CodimBox but to a different region 00231 void copy(const Box& a_Rs, // Beware that the src and dest arguments 00232 const Interval& a_Cd, // are not grouped together 00233 const Box& a_Rd, 00234 const CodimBox& a_src, 00235 const Interval& a_Cs); 00236 00237 /// Report preallocation capability as non-static but symmetric 00238 static int preAllocatable(); 00239 00240 /// Returns size of serialized data 00241 int size(const Box& a_R, const Interval& a_comps) const; 00242 00243 /// Writes a serialized representation of this CodimBox 00244 void linearOut(void* a_buf, const Box& a_R, const Interval& a_comps) const; 00245 00246 /// Reads a serialized representation of this CodimBox 00247 void linearIn(void* a_buf, const Box& a_R, const Interval& a_comps); 00248 00249 protected: 00250 static int numOrient[numCD]; ///< Number of orientations for an object 00251 ///< of a given codimension 00252 static int totOrient[numCD]; ///< Total of number of orientations for 00253 ///< all smaller codimensions 00254 static unsigned bitOrient[CodimBox::numAI]; 00255 ///< A sequential list of bit 00256 ///< representations of possible 00257 ///< orientations for each codimension 00258 static int indexFAB[CodimBox::numAI]; 00259 ///< Returns the index of the S 00260 ///< for a given codimension and 00261 ///< orientation. The input index 00262 ///< expresses the orientation as the sum 00263 ///< of the orthogonal directions. 00264 00265 private: 00266 00267 Box m_box; ///< Cell-centered box over which this 00268 ///< CodimBox is defined 00269 int m_codim; ///< Codimension for which the Ses 00270 ///< are defined 00271 int m_nvar; ///< Number of components in the S 00272 Vector<S*> m_S; ///< The Ses for each orientation 00273 00274 // Copy and assignment not allowed 00275 CodimBox(const CodimBox&); 00276 CodimBox& operator=(const CodimBox&); 00277 00278 /// Check that static arrays are initialized 00279 static bool isInitialized(); 00280 00281 /// Return the FArray box from a bit description of the orientation 00282 S& getS(const unsigned i); 00283 const S& getS(const unsigned i) const; 00284 00285 /// Get all the orthogonal directions of an orientation (general) 00286 static void genGetDirections(const int a_codim, 00287 int a_bOrient, 00288 int *const a_dir); 00289 00290 /// Orient a centered box in the othogonal directions of the given 00291 /// orientation (general) 00292 static Box genOrientBox(int a_bOrient, Box a_cbox); 00293 00294 // Only of use with a register class 00295 // /// Shift all FABs by halves in one direction. 00296 // void shiftHalf(const int a_dir, const int a_numHalfs); 00297 // friend class LevelCodimRegister; 00298 00299 }; 00300 00301 /******************************************************************************* 00302 * 00303 * Class CodimBox: inline member definitions 00304 * 00305 ******************************************************************************/ 00306 00307 /*--------------------------------------------------------------------*/ 00308 /// Return the codimension 00309 /*--------------------------------------------------------------------*/ 00310 00311 template<typename S> int CodimBox<S>::getCodim() const 00312 { 00313 return m_codim; 00314 } 00315 00316 /*--------------------------------------------------------------------*/ 00317 /// Number of components 00318 /*--------------------------------------------------------------------*/ 00319 00320 template<typename S> int CodimBox<S>::nComp() const 00321 { 00322 return m_nvar; 00323 } 00324 00325 /*--------------------------------------------------------------------*/ 00326 /// Number of different orientations of codimensional objects 00327 /*--------------------------------------------------------------------*/ 00328 00329 template<typename S> int CodimBox<S>::getNumOrient() const 00330 { 00331 return numOrient[m_codim]; 00332 } 00333 00334 /*--------------------------------------------------------------------*/ 00335 /// Number of different orientations of codimensional objects. Used 00336 /// externally for any codimension. 00337 /*--------------------------------------------------------------------*/ 00338 00339 template<typename S>int CodimBox<S>::getNumOrient(const int a_codim) 00340 { 00341 CH_assert(CodimBox<S>::isInitialized()); 00342 return numOrient[a_codim]; 00343 } 00344 00345 /*--------------------------------------------------------------------*/ 00346 /// Switch from a bit orientation to a sequential index of the 00347 /// orientation 00348 /*--------------------------------------------------------------------*/ 00349 00350 template<typename S> int CodimBox<S>::bit2seq(const unsigned a_bOrient) const 00351 { 00352 return indexFAB[a_bOrient]; 00353 } 00354 00355 /*--------------------------------------------------------------------*/ 00356 /// Switch from a sequential index to a bit representation of the 00357 /// orientation 00358 /*--------------------------------------------------------------------*/ 00359 00360 template<typename S> unsigned CodimBox<S>::seq2bit(const int a_iOrient) const 00361 { 00362 return bitOrient[totOrient[m_codim] + a_iOrient]; 00363 } 00364 00365 /*--------------------------------------------------------------------*/ 00366 /// Switch from a sequential index to a bit representation of the 00367 /// orientation for any codimension 00368 /*--------------------------------------------------------------------*/ 00369 00370 template<typename S> unsigned CodimBox<S>::seq2bit(const int a_codim, const int a_iOrient) 00371 { 00372 CH_assert(CodimBox<S>::isInitialized()); 00373 return bitOrient[totOrient[a_codim] + a_iOrient]; 00374 } 00375 00376 /*--------------------------------------------------------------------*/ 00377 /// Get all the orthogonal directions of an orientation 00378 /** \param[in] a_iOrient 00379 * The sequential orientation index from which to 00380 * get the directions 00381 * \param[in] a_dir Array with minimum size [m_codim] 00382 * \param[out] a_dir Integers defining the directions 00383 * 0 <= dir[i] < SpaceDim 00384 * \note 00385 * <ul> 00386 * <li> The directions are orderd from smallest to largest. 00387 * </ul> 00388 *//*-----------------------------------------------------------------*/ 00389 00390 template<typename S> void CodimBox<S>::getDirections(const int a_iOrient, int *const a_dir) const 00391 { 00392 genGetDirections(m_codim, seq2bit(a_iOrient), a_dir); 00393 } 00394 00395 /*--------------------------------------------------------------------*/ 00396 /// Get all the orthogonal directions of an orientation. Used 00397 /// externally for any codimension. 00398 /** \param[in] a_codim 00399 * The codimension 00400 * \param[in] a_iOrient 00401 * The sequential orientation index from which to 00402 * get the directions 00403 * \param[in] a_dir Array with minimum size [m_codim] 00404 * \param[out] a_dir Integers defining the directions 00405 * 0 <= dir[i] < SpaceDim 00406 * \note 00407 * <ul> 00408 * <li> The directions are orderd from smallest to largest. 00409 * </ul> 00410 *//*-----------------------------------------------------------------*/ 00411 00412 template<typename S> void CodimBox<S>::getDirections(const int a_codim, 00413 const int a_iOrient, 00414 int *const a_dir) 00415 { 00416 CH_assert(CodimBox<S>::isInitialized()); 00417 genGetDirections(a_codim, seq2bit(a_codim, a_iOrient), a_dir); 00418 } 00419 00420 /*--------------------------------------------------------------------*/ 00421 // Returns cell-centered box which defines the CodimBox 00422 /*--------------------------------------------------------------------*/ 00423 template<typename S> const Box& CodimBox<S>::box() const 00424 { 00425 return m_box; 00426 } 00427 00428 /*--------------------------------------------------------------------*/ 00429 /// Returns S in the directions defined by a Box 00430 /*--------------------------------------------------------------------*/ 00431 00432 template<typename S> S& CodimBox<S>::operator()(const Box &a_box) 00433 { 00434 return this->operator()(a_box.ixType()); 00435 } 00436 00437 /*--------------------------------------------------------------------*/ 00438 /// Returns S from a sequential index 00439 /** \param[in] a_iOrient 00440 * A sequential orientation index. 00441 * \note 00442 * <ul> 00443 * <li> A bit description of the orientation can be obtained from 00444 * \verbatim 00445 * bitOrient[totOrient[a_codim] + a_iOrient] 00446 * \endverbatim 00447 * </ul> 00448 *//*-----------------------------------------------------------------*/ 00449 template<typename S> const S& CodimBox<S>::getSequential(const int a_iOrient) const 00450 { 00451 CH_assert(a_iOrient < numOrient[m_codim]); 00452 return *m_S[a_iOrient]; 00453 } 00454 00455 template<typename S> S& CodimBox<S>::getSequential(const int a_iOrient) 00456 { 00457 CH_assert(a_iOrient < numOrient[m_codim]); 00458 return *m_S[a_iOrient]; 00459 } 00460 00461 /*--------------------------------------------------------------------*/ 00462 /// Orient the stored box in the othogonal directions of the given 00463 /// orientation 00464 /** \param[in] a_bOrient 00465 * A bit orientation index. 00466 *//*-----------------------------------------------------------------*/ 00467 00468 template<typename S> Box CodimBox<S>::orientBox(const int a_bOrient) const 00469 { 00470 return orientBox(a_bOrient, m_box); 00471 } 00472 00473 /*--------------------------------------------------------------------*/ 00474 /// Orient a centered box in the othogonal directions of the given 00475 /// orientation 00476 /** \param[in] a_iOrient 00477 * A sequential orientation index. This is 00478 * converted to a bit orientation for finding the 00479 * orthogonal directions. 00480 * \param[in] a_cbox 00481 * A centered box. 00482 * \return The orientated box 00483 *//*-----------------------------------------------------------------*/ 00484 00485 template<typename S> Box CodimBox<S>::orientBox(const int a_iOrient, const Box& a_cbox) const 00486 { 00487 return genOrientBox(seq2bit(a_iOrient), a_cbox); 00488 } 00489 00490 /*--------------------------------------------------------------------*/ 00491 /// Orient a centered box in the othogonal directions of the given 00492 /// orientation. Used externally for any codimension. 00493 /** \param[in] a_codim 00494 * The codimension of the box 00495 * \param[in] a_iOrient 00496 * A sequential orientation index. This is 00497 * converted to a bit orientation for finding the 00498 * orthogonal directions. 00499 * \param[in] a_cbox 00500 * A centered box. 00501 * \return The orientated box 00502 *//*-----------------------------------------------------------------*/ 00503 00504 template<typename S> Box CodimBox<S>::orientBox(const int a_codim, const int a_iOrient, const Box& a_cbox) 00505 { 00506 CH_assert(CodimBox<S>::isInitialized()); 00507 return genOrientBox(seq2bit(a_codim, a_iOrient), a_cbox); 00508 } 00509 00510 /*--------------------------------------------------------------------*/ 00511 /// Report preallocation capability as non-static but symmetric 00512 /** The size of the class is dependent upon the codimension. See 00513 * BoxLayoutData.H for more info 00514 *//*-----------------------------------------------------------------*/ 00515 00516 template<typename S> int CodimBox<S>::preAllocatable() 00517 { 00518 return 1; 00519 } 00520 00521 /*--------------------------------------------------------------------*/ 00522 /// Check that static arrays are initialized 00523 /** Test assumes static arrays have at least been default 00524 * initialized. 00525 * \return T - Arrays initialized 00526 *//*-----------------------------------------------------------------*/ 00527 00528 template<typename S> bool CodimBox<S>::isInitialized() 00529 { 00530 return (indexFAB[0] != -1); 00531 } 00532 00533 /*--------------------------------------------------------------------*/ 00534 /// Return the FArray box from a bit description of the orientation 00535 /** The appropriate FArray box for this codimension and orientation 00536 * is given by a query to 'indexFAB' 00537 * \param[in] a_bOrient 00538 * Bit description of the orientation 00539 *//*-----------------------------------------------------------------*/ 00540 template<typename S> const S& CodimBox<S>::getS(const unsigned a_bOrient) const 00541 { 00542 return *(m_S[bit2seq(a_bOrient)]); 00543 } 00544 00545 template<typename S> S& CodimBox<S>::getS(const unsigned a_bOrient) 00546 { 00547 return *(m_S[bit2seq(a_bOrient)]); 00548 } 00549 00550 /******************************************************************************* 00551 */ 00552 /// Factory object to create CodimBox(s) for BoxLayoutData and similar 00553 /// containers. 00554 /* 00555 ******************************************************************************/ 00556 template <class S> class CodimBoxFactory : public DataFactory<CodimBox<S> > 00557 { 00558 00559 public: 00560 /// Constructor stores codimension 00561 CodimBoxFactory(int a_codim) 00562 : 00563 m_codim(a_codim) 00564 { } 00565 00566 /// Create a new CodimBox 00567 CodimBox<S>* create(const Box& a_box, 00568 int a_ncomps, 00569 const DataIndex& a_datInd) const 00570 { 00571 return new CodimBox<S>(m_codim, a_box, a_ncomps); 00572 } 00573 00574 private: 00575 int m_codim; ///< Codimension 00576 00577 }; 00578 00579 #include "NamespaceFooter.H" 00580 00581 #include "CodimBoxImplem.H" 00582 00583 #endif