src/Region/NDRegion.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef NDREGION_H
00012 #define NDREGION_H
00013 
00014 /***********************************************************************
00015  * NDRegion is a simple container of N PRegion objects.  It is templated
00016  * on the type of data (T) and the number of PRegions (Dim).  It can also
00017  * be templated on the Mesh type, in order to provide a mesh for converting
00018  * an NDIndex into an NDRegion.
00019  ***********************************************************************/
00020 
00021 // include files
00022 #include "Region/PRegion.h"
00023 #include "Utility/PAssert.h"
00024 
00025 #ifdef IPPL_USE_STANDARD_HEADERS
00026 #include <iostream>
00027 using namespace std;
00028 #else
00029 #include <iostream.h>
00030 #endif
00031 
00032 // forward declarations
00033 class Message;
00034 template < class T, unsigned Dim > class NDRegion;
00035 template <class T, unsigned Dim>
00036 NDRegion<T,Dim> operator+(const NDRegion<T,Dim>&, T);
00037 template <class T, unsigned Dim>
00038 NDRegion<T,Dim> operator+(T, const NDRegion<T,Dim>&);
00039 template <class T, unsigned Dim>
00040 NDRegion<T,Dim> operator-(const NDRegion<T,Dim>&, T);
00041 template <class T, unsigned Dim>
00042 NDRegion<T,Dim> operator-(T, const NDRegion<T,Dim>&);
00043 template <class T, unsigned Dim>
00044 NDRegion<T,Dim> operator-(const NDRegion<T,Dim>&);
00045 template <class T, unsigned Dim>
00046 NDRegion<T,Dim> operator*(const NDRegion<T,Dim>&, T);
00047 template <class T, unsigned Dim>
00048 NDRegion<T,Dim> operator*(T, const NDRegion<T,Dim>&);
00049 template <class T, unsigned Dim>
00050 NDRegion<T,Dim> operator/(const NDRegion<T,Dim>&, T);
00051 template <class T, unsigned Dim>
00052 bool operator<(const NDRegion<T,Dim>&, const NDRegion<T,Dim>&);
00053 template <class T, unsigned Dim>
00054 bool operator==(const NDRegion<T,Dim>&, const NDRegion<T,Dim>&);
00055 template <class T, unsigned Dim>
00056 bool operator!=(const NDRegion<T,Dim>&, const NDRegion<T,Dim>&);
00057 template < class T, unsigned Dim >
00058 ostream& operator<<(ostream&, const NDRegion<T,Dim>&);
00059 
00060 template < class T, unsigned Dim >
00061 class NDRegion {
00062 
00063 public: 
00064   // Null ctor does nothing.
00065   NDRegion() {}
00066 
00067   // Construct from a simple array of PRegions
00068   NDRegion(PRegion<T>* idx) {
00069     for (int i=0; i < Dim; i++)
00070       p[i] = idx[i];
00071   }
00072 
00073   // Construct from individual PRegions, for 1D thru 6D cases.
00074   NDRegion(const PRegion<T>& r1) {
00075     PInsist(Dim==1, "Number of arguments does not match NDRegion dimension!!");
00076     p[0] = r1;
00077   }
00078   NDRegion(const PRegion<T>& r1, const PRegion<T>& r2) {
00079     PInsist(Dim==2, "Number of arguments does not match NDRegion dimension!!");
00080     p[0] = r1;
00081     p[1] = r2;
00082   }
00083   NDRegion(const PRegion<T>& r1, const PRegion<T>& r2, const PRegion<T>& r3) {
00084     PInsist(Dim==3, "Number of arguments does not match NDRegion dimension!!");
00085     p[0] = r1;
00086     p[1] = r2;
00087     p[2] = r3;
00088   }
00089   NDRegion(const PRegion<T>& r1, const PRegion<T>& r2, const PRegion<T>& r3,
00090            const PRegion<T>& r4) {
00091     PInsist(Dim==4, "Number of arguments does not match NDRegion dimension!!");
00092     p[0] = r1;
00093     p[1] = r2;
00094     p[2] = r3;
00095     p[3] = r4;
00096   }
00097   NDRegion(const PRegion<T>& r1, const PRegion<T>& r2, const PRegion<T>& r3,
00098            const PRegion<T>& r4, const PRegion<T>& r5) {
00099     PInsist(Dim==5, "Number of arguments does not match NDRegion dimension!!");
00100     p[0] = r1;
00101     p[1] = r2;
00102     p[2] = r3;
00103     p[3] = r4;
00104     p[4] = r5;
00105   }
00106   NDRegion(const PRegion<T>& r1, const PRegion<T>& r2, const PRegion<T>& r3,
00107            const PRegion<T>& r4, const PRegion<T>& r5, const PRegion<T>& r6) {
00108     PInsist(Dim==6, "Number of arguments does not match NDRegion dimension!!");
00109     p[0] = r1;
00110     p[1] = r2;
00111     p[2] = r3;
00112     p[3] = r4;
00113     p[4] = r5;
00114     p[5] = r6;
00115   }
00116 
00117   // copy constructor
00118   NDRegion(const NDRegion<T,Dim>& nr) {
00119     for (int i=0; i < Dim; i++)
00120       p[i] = nr.p[i];
00121   }
00122 
00123   // operator= definitions
00124   NDRegion<T,Dim>& operator=(const NDRegion<T,Dim>& nr) {
00125     for (int i=0; i < Dim; i++)
00126       p[i] = nr.p[i];
00127     return *this;
00128   }
00129 
00130   // Return a reference to any of the PRegion<T> objects.
00131   const PRegion<T>& operator[](unsigned d) const { return p[d]; }
00132   PRegion<T>& operator[](unsigned d) { return p[d]; }
00133 
00134   // return the volume of this region
00135   T volume() const {
00136     T v = p[0].length();
00137     for (int i=1; i < Dim; i++)
00138       v *= p[i].length();
00139     return v;
00140   }
00141 
00142   // compute-assign operators
00143   NDRegion<T,Dim>& operator+=(const T t) {
00144     for (int i=0; i < Dim; i++)
00145       p[i] += t;
00146     return *this;
00147   }
00148   NDRegion<T,Dim>& operator-=(const T t) {
00149     for (int i=0; i < Dim; i++)
00150       p[i] -= t;
00151     return *this;
00152   }
00153   NDRegion<T,Dim>& operator*=(const T t) {
00154     for (int i=0; i < Dim; i++)
00155       p[i] *= t;
00156     return *this;
00157   }
00158   NDRegion<T,Dim>& operator/=(const T t) {
00159     if (t != 0) {
00160       for (int i=0; i < Dim; i++) p[i] /= t;
00161     }
00162     return *this;
00163   }
00164 
00165   bool empty() const {
00166     for (int i=0; i < Dim; i++)
00167       if ( ! p[i].empty() )
00168         return false;
00169     return true;
00170   }
00171 
00172   // useful functions with DomainMap.
00173   NDRegion<T,Dim> intersect(const NDRegion<T,Dim>& nr) const {
00174     NDRegion<T,Dim> retval;
00175     for (int i=0; i < Dim; i++)
00176       retval.p[i] = p[i].intersect(nr.p[i]);
00177     return retval;
00178   }
00179 
00180   bool touches(const NDRegion<T,Dim>& nr) const {
00181     for (int i=0; i < Dim; i++)
00182       if ( ! (p[i].touches(nr.p[i])) )
00183         return false;
00184     return true;
00185   }
00186 
00187   bool contains(const NDRegion<T,Dim>& nr) const {
00188     for (int i=0; i < Dim; i++)
00189       if ( ! (p[i].contains(nr.p[i])) )
00190         return false;
00191     return true;
00192   }
00193 
00194   // Split on dimension d, or the longest dimension.
00195   bool split(NDRegion<T,Dim>& l, NDRegion<T,Dim>& r,
00196              unsigned d) const {
00197     for (int i=0; i < Dim; i++) {
00198       if (i == d) {
00199         p[i].split(l.p[i], r.p[i]);
00200       }
00201       else {
00202         l.p[i] = p[i];
00203         r.p[i] = p[i];
00204       }
00205     }
00206     return true;
00207   }
00208 
00209   bool split(NDRegion<T,Dim>& l, NDRegion<T,Dim>& r) const {
00210     // find longest dimension
00211     unsigned d = 0;
00212     T maxlen = p[0].length();
00213     for (unsigned i=1; i < Dim; i++) {
00214       if (p[i].length() > maxlen) {
00215         maxlen = p[i].length();
00216         d = i;
00217       }
00218     }
00219     // split on this dimension
00220     return split(l, r, d);
00221   }
00222 
00223   // put data into a message to send to another node
00224   Message& putMessage(Message& m) {
00225     for ( unsigned d = 0 ; d < Dim ; ++d )
00226       p[d].putMessage(m);
00227     return m;
00228   }
00229 
00230   // get data out from a message
00231   Message& getMessage(Message& m) {
00232     for ( unsigned d = 0 ; d < Dim ; ++d )
00233       p[d].getMessage(m);
00234     return m;
00235   }
00236 
00237 private:
00238   PRegion<T> p[Dim];                    // Array of PRegions
00239 
00240 };
00241 
00242 
00243 // Additive operations.
00244 template <class T, unsigned Dim>
00245 inline
00246 NDRegion<T,Dim> operator+(const NDRegion<T,Dim>& nr, T t) {
00247   NDRegion<T,Dim> retval(nr);
00248   retval += t;
00249   return retval;
00250 }
00251 template <class T, unsigned Dim>
00252 inline
00253 NDRegion<T,Dim> operator+(T t, const NDRegion<T,Dim>& nr) {
00254   return (nr + t);
00255 }
00256 template <class T, unsigned Dim>
00257 inline
00258 NDRegion<T,Dim> operator-(const NDRegion<T,Dim>& nr, T t) {
00259   return (nr + (-t));
00260 }
00261 template <class T, unsigned Dim>
00262 inline
00263 NDRegion<T,Dim> operator-(T t, const NDRegion<T,Dim>& nr) {
00264   return (-nr + t);
00265 }
00266 
00267 // Multipplicative operations.
00268 template <class T, unsigned Dim>
00269 inline
00270 NDRegion<T,Dim> operator-(const NDRegion<T,Dim>& nr) {
00271   NDRegion<T,Dim> retval;
00272   for (int i=0; i < Dim; i++)
00273     retval[i] = -nr[i];
00274   return retval;
00275 }
00276 template <class T, unsigned Dim>
00277 inline
00278 NDRegion<T,Dim> operator*(const NDRegion<T,Dim>& nr, T t) {
00279   NDRegion<T,Dim> retval(nr);
00280   retval *= t;
00281   return retval;
00282 }
00283 template <class T, unsigned Dim>
00284 inline
00285 NDRegion<T,Dim> operator*(T t, const NDRegion<T,Dim>& nr) {
00286   return (nr * t);
00287 }
00288 template <class T, unsigned Dim>
00289 inline
00290 NDRegion<T,Dim> operator/(const NDRegion<T,Dim>& nr, T t) {
00291   return (t != 0 ? (nr * (1/t)) : nr);
00292 }
00293 
00294 // Comparison operators so we can use a map container
00295 // Just compare the PRegions in turn.
00296 template <class T, unsigned Dim>
00297 inline
00298 bool operator<(const NDRegion<T,Dim>& A, const NDRegion<T,Dim>& B) {
00299   for (int i=0; i < Dim; i++)
00300     if ( !(A[i] < B[i]) ) return false;
00301   return true;
00302 }
00303 template <class T, unsigned Dim>
00304 inline
00305 bool operator==(const NDRegion<T,Dim>& A, const NDRegion<T,Dim>& B) {
00306   for (int i=0; i < Dim; i++)
00307     if ( !(A[i] == B[i]) ) return false;
00308   return true;
00309 }
00310 template <class T, unsigned Dim>
00311 inline
00312 bool operator!=(const NDRegion<T,Dim>& A, const NDRegion<T,Dim>& B) {
00313   return !(A == B);
00314 }
00315 
00316 // write NDRegion out to the given stream
00317 template <class T, unsigned Dim>
00318 inline
00319 ostream& operator<<(ostream& out, const NDRegion<T,Dim>& idx) {
00320   out << '{';
00321   for (unsigned d = 0; d < Dim; ++d) 
00322     out << idx[d] << ((d==Dim-1) ? '}' : ',');
00323   return out;
00324 }
00325 
00326 
00328 
00329 // Build some helper objects for use in DomainMap
00330 template < class T, unsigned Dim >
00331 class TouchesRegion {
00332 public:
00333   TouchesRegion() {}
00334   static bool test(const NDRegion<T,Dim>& a,
00335                    const NDRegion<T,Dim>& b) {
00336     return a.touches(b);
00337   }
00338 };
00339 
00340 template < class T, unsigned Dim >
00341 class ContainsRegion {
00342 public:
00343   ContainsRegion() {}
00344   static bool test(const NDRegion<T,Dim>& a,
00345                    const NDRegion<T,Dim>& b) {
00346     return a.contains(b);
00347   }
00348 };
00349 
00350 template < class T, unsigned Dim >
00351 class SplitRegion {
00352 public:
00353   SplitRegion() {}
00354   static bool test(NDRegion<T,Dim>& l, NDRegion<T,Dim>& r,
00355                    const NDRegion<T,Dim>& a) {
00356     return a.split(l,r);
00357   }
00358 };
00359 
00360 
00361 #endif // NDREGION_H
00362 
00363 /***************************************************************************
00364  * $RCSfile: NDRegion.h,v $   $Author: adelmann $
00365  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:32 $
00366  * IPPL_VERSION_ID: $Id: NDRegion.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $ 
00367  ***************************************************************************/

Generated on Mon Jan 16 13:23:55 2006 for IPPL by  doxygen 1.4.6