00001 /* _______ __ 00002 / ___/ / ___ __ _ / / ___ 00003 / /__/ _ \/ _ \/ ' \/ _ \/ _ \ 00004 \___/_//_/\___/_/_/_/_.__/\___/ 00005 */ 00006 // 00007 // This software is copyright (C) by the Lawrence Berkeley 00008 // National Laboratory. Permission is granted to reproduce 00009 // this software for non-commercial purposes provided that 00010 // this notice is left intact. 00011 // 00012 // It is acknowledged that the U.S. Government has rights to 00013 // this software under Contract DE-AC03-765F00098 between 00014 // the U.S. Department of Energy and the University of 00015 // California. 00016 // 00017 // This software is provided as a professional and academic 00018 // contribution for joint exchange. Thus it is experimental, 00019 // is provided ``as is'', with no warranties of any kind 00020 // whatsoever, no support, no promise of updates, or printed 00021 // documentation. By using this software, you acknowledge 00022 // that the Lawrence Berkeley National Laboratory and 00023 // Regents of the University of California shall have no 00024 // liability with respect to the infringement of other 00025 // copyrights by any part of this software. 00026 // 00027 00028 //CH_COPYRIGHT_NOTICE 00029 00030 #ifndef CH_BASEFAB_H 00031 #define CH_BASEFAB_H 00032 00033 // 00034 // $Id: BaseFab.H,v 1.7 2002/01/26 01:11:05 dmartin Exp $ 00035 // 00036 00037 #include <cstdlib> 00038 #include <assert.h> 00039 #include <string> 00040 #include <typeinfo> 00041 #include "Box.H" 00042 #include "Arena.H" 00043 #include "Interval.H" 00044 00045 00046 // 00047 //@Man: 00048 //@Memo: A Fortran Array-like Container 00049 /*@Doc: 00050 00051 BaseFab emulates the Fortran array concept. 00052 Useful operations can be performed upon 00053 BaseFab's in C++, and they provide a convenient interface to 00054 Fortran when it is necessary to retreat into that language. 00055 00056 `BaseFab' is a template class. Through use of the 00057 template, a `BaseFab' may be based upon any class. So far at least, 00058 most applications have been based upon simple types like `integer's, 00059 `real's, or `doubleprecision's. Most applications do not use BaseFab's 00060 directly, but utilize specialized classes derived from BaseFab. 00061 00062 It will be easier to use a `BaseFab' if you understand the following 00063 concepts. `BaseFab' objects depend on the dimensionality of space 00064 (indirectly through the DOMAIN `Box' member). It is 00065 typical to define the macro `CH_SPACEDIM' to be 1, 2, or 3 to indicate 00066 the dimension of space. See the discussion of class `Box' for more 00067 information. A `BaseFab' contains a `Box' DOMAIN, which indicates the 00068 integer indexing space over which the array is defined. A `BaseFab' 00069 also has NVAR components. By components, we mean that for each 00070 point in the rectangular indexing space, there are NVAR values 00071 associated with that point. A Fortran array corresponding to a 00072 `BaseFab' would have (CH_SPACEDIM+1) dimensions. 00073 00074 By design, the array layout in a `BaseFab' mirrors that of a 00075 Fortran array. The first index (x direction for example) varies 00076 most rapidly, the next index (y direction), if any, varies next 00077 fastest. The component index varies last, after all the spatial 00078 indices. 00079 00080 It is sometimes convenient to be able to treat a sub-array within an 00081 existing `BaseFab' as a `BaseFab' in its own right. This is often 00082 referred to as 'aliasing' the `BaseFab'. Note that when aliasing is 00083 used, the BaseFab's domain will not, in general, be the same as the 00084 parent BaseFab's domain, nor will the number of components. 00085 BaseFab is a dimension dependent class, so CH_SPACEDIM must be 00086 defined as either 1, 2, or 3 when compiling. 00087 00088 This is NOT a polymorphic class. 00089 00090 It does NOT provide a copy constructor or assignment operator. 00091 00092 T MUST have a default constructor and an assignment operator. 00093 */ 00094 00095 template <class T> 00096 class BaseFab 00097 { 00098 public: 00099 00101 00102 /*@ManDoc: Constructs an invalid `BaseFab'. The domain is invalid, the 00103 number of components is zero, and no actual array memory is 00104 allocated. An invalid `BaseFab' must be resize()d 00105 (see `BaseFab::resize') before use. 00106 */ 00107 BaseFab (); 00108 00110 00113 BaseFab (const Box& bx, 00114 int n); 00115 00117 00120 virtual ~BaseFab (); 00121 00122 /*@ManDoc: This function resizes a `BaseFab' so it covers the `Box' B 00123 with N components. The default action 00124 is that under resize()ing, the memory allocated for the 00125 `BaseFab' only grows and never shrinks. This function is 00126 particularly useful when a `BaseFab' is used as a temporary 00127 space which must be a different size whenever it is used. 00128 Resize()ing a temp will often be faster than re-allocating a 00129 `BaseFab' because memory allocation can often be avoided. 00130 */ 00131 void resize (const Box& b, 00132 int N = 1); 00133 00134 /*@ManDoc: Make BaseFab with desired domain and number of components. 00135 existing data is lost. Data is in uninialized state. 00136 */ 00137 virtual void define(const Box& box, int comps) { resize(box, comps);} 00138 00139 /*@ManDoc: The function returns the `BaseFab' to the invalid state. (See 00140 comments for constructors above.) The memory is freed. 00141 */ 00142 void clear (); 00143 00144 00146 00148 00151 int nComp () const; 00152 00154 00157 const Box& box () const; 00158 00159 /*@ManDoc: Returns a pointer to an array of SpaceDim integers 00160 giving the length of the domain in each direction. 00161 */ 00162 const int* size () const; 00163 00164 /*@ManDoc: Returns the lower corner of the domain. See 00165 class `Box' for analogue. 00166 */ 00167 const IntVect& smallEnd () const; 00168 00169 /*@ManDoc: Returns the upper corner of the domain. See 00170 class `Box' for analogue. 00171 */ 00172 const IntVect& bigEnd () const; 00173 00175 00178 Interval interval() const 00179 { return Interval(0, nvar-1); } 00180 00181 /*@ManDoc: Returns a modifiable lvalue reference to the Nth component value 00182 defined at position p in the domain. This operator may be 00183 inefficient if the C++ compiler is unable to optimize the 00184 C++ code. 00185 */ 00186 T& operator() (const IntVect& p, 00187 int N); 00188 00189 T& operator() (const IntVect& p); 00190 00191 /*@ManDoc: Returns a conatant reference to the Nth component value 00192 defined at position p in the domain. This operator may be 00193 inefficient if the C++ compiler is unable to optimize the 00194 C++ code. 00195 */ 00196 const T& operator() (const IntVect& p, 00197 int N) const; 00198 00199 const T& operator() (const IntVect& p) const; 00200 00201 /*@ManDoc: This function puts numcomp component values, starting at 00202 component N, from position pos in the domain into array data, 00203 that must be allocated by the user. 00204 */ 00205 void getVal (T* data, 00206 const IntVect& pos, 00207 int N, 00208 int numcomp) const; 00209 00210 /*@ManDoc: This function puts all component values, starting at 00211 component 0, from position pos in the domain into array data, 00212 that must be allocated by the user. 00213 */ 00214 void getVal (T* data, 00215 const IntVect& pos) const; 00216 00218 00219 /*@ManDoc: Returns the lower corner of the domain. Instead of 00220 returning them in the form of IntVects, as in smallEnd 00221 and bigEnd, it returns the values as a pointer to an 00222 array of constant integers. This is useful when 00223 interfacing to Fortran subroutines. It should not be 00224 used in any other context!!! 00225 00226 */ 00227 const int* loVect () const; 00228 00229 /*@ManDoc: Returns the upper corner of the domain. Instead of 00230 returning them in the form of IntVects, as in smallEnd 00231 and bigEnd, it returns the values as a pointer to an 00232 array of constant integers. This is useful when 00233 interfacing to Fortran subroutines. It should not be 00234 used in any other context!!! 00235 00236 */ 00237 const int* hiVect () const; 00238 00239 /*@ManDoc: Returns a pointer to an integer that contains the 00240 number of components in the BaseFab. This is useful when 00241 interfacing to Fortran subroutines. It should not be 00242 used in any other context!!! 00243 00244 */ 00245 const int* nCompPtr () const; 00246 00247 /*@ManDoc: Returns a pointer to an object of type T that is the 00248 value of the Nth component associated with the cell at 00249 the low end of the domain. This is commonly used to 00250 get a pointer to data in the array which is then handed 00251 off to a Fortran subroutine. It should not be used in 00252 any other context!!! Remember that data is stored in 00253 Fortran array order, with the component index coming 00254 last. In other words, `dataPtr' returns a pointer to 00255 all the Nth components. 00256 00257 */ 00258 T* dataPtr (int N = 0); 00259 00260 /*@ManDoc: Returns a constant pointer to an object of type T that is 00261 the value of the Nth component associated with the cell 00262 at the low end of the domain. This is commonly used to 00263 get a pointer to data in the array which is then handed 00264 off to a Fortran subroutine. It should not be used in 00265 any other context!!! Remember that data is stored in 00266 Fortran array order, with the component index coming 00267 last. In other words, `dataPtr' returns a pointer to 00268 all the Nth components. 00269 00270 */ 00271 const T* dataPtr (int N = 0) const; 00272 00274 00275 /*@ManDoc: Returns true if the domain of fab is totally contained within 00276 the domain of this `BaseFab'. 00277 */ 00278 bool contains (const BaseFab<T>& fab) const; 00279 00280 /*@ManDoc: Returns true if bx is totally contained 00281 within the domain of this `BaseFab'. 00282 */ 00283 bool contains (const Box& bx) const; 00284 00286 00287 /*@ManDoc: The setVal functions set subregions in the `BaseFab' to a 00288 constant value. This most general form specifies the sub-box, 00289 the starting component number, and the number of components 00290 to be set. 00291 */ 00292 void setVal (T x, 00293 const Box& bx, 00294 int nstart, 00295 int ncomp); 00296 00298 00303 void setVal (T x, 00304 const Box& bx, 00305 int N); 00306 00308 00313 void setVal (T x, 00314 int N); 00315 00317 00322 void setVal (T x); 00323 00324 00325 /*@ManDoc: Modifies this BaseFab by copying the contents of the 00326 argument BaseFab into it. This, the most general form 00327 of copy, specifies the contents of any sub-box srcbox 00328 in `BaseFab' src may be copied into a (possibly 00329 different) destbox in the destination `BaseFab'. Note 00330 that although the srcbox and the destbox may be 00331 disjoint, they must be the same size and shape. If the 00332 sizes differ, the copy is undefined and a runtime error 00333 results. This copy function is the only one of the 00334 copy functions to allow a copy between differing 00335 boxes. The user also specifies how many components are 00336 copied, starting at component srccomp in src and stored 00337 starting at component destcomp. The results are 00338 UNDEFINED if the src and dest BaseFabs are the same and 00339 the srcbox and destbox overlap. 00340 00341 */ 00342 BaseFab<T>& copy (const BaseFab<T>& src, 00343 const Box& srcbox, 00344 int srccomp, 00345 const Box& destbox, 00346 int destcomp, 00347 int numcomp); 00348 00349 /*@ManDoc: Modifies this BaseFab by coping the contents of the 00350 argument BaseFab into it. A copy within the intersecting 00351 region of the domains of the two BaseFabs is performed. 00352 The user specifies how many components are copied, 00353 starting at component srccomp in src and stored starting 00354 at component destcomp. 00355 00356 */ 00357 BaseFab<T>& copy (const BaseFab<T>& src, 00358 int srccomp, 00359 int destcomp, 00360 int numcomp = 1); 00361 00362 /*@ManDoc: Modifies this BaseFab by coping the contents of the 00363 argument BaseFab into it. A copy within the intersecting 00364 region of the domains of the two BaseFabs and the 00365 specified Box destbox is performed. All components are 00366 copied. 00367 00368 */ 00369 BaseFab<T>& copy (const BaseFab<T>& src, 00370 const Box& destbox); 00371 00372 /*@ManDoc: Modifies this BaseFab by coping the contents of the 00373 argument BaseFab into it. A copy within the intersecting 00374 region of the domains of the two BaseFabs is performed. 00375 All components are copied. 00376 00377 */ 00378 BaseFab<T>& copy (const BaseFab<T>& src); 00379 00381 00386 void copy(const Box& RegionFrom, 00387 const Interval& Cdest, 00388 const Box& RegionTo, 00389 const BaseFab<T>& src, 00390 const Interval& Csrc); 00391 00392 00394 00396 00402 BaseFab<T>& shift (const IntVect& v); 00403 00405 00412 BaseFab<T>& shift (int idir, 00413 int n_cell); 00414 00416 00428 BaseFab<T>& shiftHalf (int dir, 00429 int num_halfs); 00430 00432 00438 BaseFab<T>& shiftHalf (const IntVect& num_halfs); 00439 00441 00443 00449 virtual int size(const Box& b, const Interval& comps) const; 00450 00452 00457 virtual void linearOut(void* buf, const Box& R, const Interval& comps) const; 00458 00460 virtual void linearIn(void* buf, const Box& R, const Interval& comps); 00461 00463 static int preAllocatable(){ return 0;} // static preAllocatable 00464 00465 protected: 00466 // 00467 // Allocates memory for the `BaseFab<T>'. 00468 // 00469 void define (); 00470 // 00471 // Deallocates memory for the `BaseFab<T>'. 00472 // 00473 void undefine (); 00474 // 00475 // template class static data member. not sure if this will 00476 // work with all compilers. It has been in the draft standard 00477 // for some time 00478 // 00479 static Arena* s_Arena; 00480 // 00481 // 00482 static std::string name(); 00483 // 00484 // The function called by BaseFab copy operations. 00485 // 00486 virtual void performCopy (const BaseFab<T>& src, 00487 const Box& srcbox, 00488 int srccomp, 00489 const Box& destbox, 00490 int destcomp, 00491 int numcomp); 00492 00493 // 00494 // This function is called by the `BaseFab' setVal operations. 00495 // 00496 void performSetVal (T x, 00497 const Box& bx, 00498 int nstart, 00499 int numcomp); 00500 00501 00502 private: 00503 // 00504 // These functions are made private to prevent use of the default 00505 // functions provided by the C++ compiler. 00506 // 00507 00508 BaseFab<T>& operator= (const BaseFab<T>&); 00509 BaseFab (const BaseFab<T>&); 00510 00511 protected: 00512 00513 Box domain; // My index space. 00514 int nvar; // Number components. 00515 long numpts; // Cached number of points in FAB. 00516 long truesize; // nvar*numpts that was allocated on heap. 00517 T* dptr; // The data pointer. 00518 }; 00519 00520 #include "BaseFabImplem.H" 00521 00522 #endif /*CH_BASEFAB_H*/ 00523