Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

BoxLayoutData.H

Go to the documentation of this file.
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 #ifndef BOXLAYOUTDATA_H
00029 #define BOXLAYOUTDATA_H
00030 
00031 #include "LayoutData.H"
00032 #include "Interval.H"
00033 #include "FArrayBox.H"
00034 
00035 #include "DisjointBoxLayout.H"
00036 #include "Copier.H"
00037 #include "SPMD.H"
00038 
00040 template <class T> class DataFactory
00041 {
00042 public:
00044 
00046   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const=0;
00047 
00048   virtual bool callDelete() const {return true;}
00049 
00050 
00051 };
00052 
00053 
00055 
00069 template <class T> class DefaultDataFactory : public DataFactory<T>
00070 {
00071 public:
00073 
00075   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00076 
00077 };
00078 
00079 class FABAliasDataFactory : public DataFactory<FArrayBox>
00080 {
00081 public:
00082   virtual ~FABAliasDataFactory(){;}
00083   FABAliasDataFactory(const LayoutData<Real*>& aliases);
00084   void define(const LayoutData<Real*>& aliases);
00086 
00088   virtual FArrayBox* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00089 
00090 protected:
00091   LayoutData<Real*> aliasPtrs;
00092 };
00093 
00094 
00095 template<class T> class BoxLayoutData;
00096 
00097 template <class T>
00098 class AliasDataFactory : public DataFactory<T>
00099 {
00100 public:
00101   virtual ~AliasDataFactory(){;}
00102   AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval);
00103   void define(BoxLayoutData<T>* a_original, const Interval& interval);
00106   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00107 
00108 protected:
00109   BoxLayoutData<T>* m_origPointer;
00110   Interval          m_interval;
00111 };
00112 
00113 
00114 template<class T> class LevelData;
00115 
00116 
00117 
00118 template <class T>
00119 class LDOperator
00120 {
00121 public:
00122   virtual int size(const T& arg, const Box& b, const Interval& comps) const
00123   {
00124         return arg.size(b, comps);
00125   }
00126   virtual void linearOut(const T& arg, void* buf, const Box& R, 
00127                          const Interval& comps) const
00128   {
00129         arg.linearOut(buf, R, comps);
00130   }
00131   virtual void linearIn(T& arg,  void* buf, const Box& R, 
00132                         const Interval& comps)const
00133   {
00134         arg.linearIn(buf, R, comps);
00135   }
00136   virtual void op(T& dest, 
00137                   const Box& RegionFrom, 
00138                   const Interval& Cdest, 
00139                   const Box& RegionTo,
00140                   const T& src, 
00141                   const Interval& Csrc) const
00142   {
00143         dest.copy(RegionFrom, Cdest,RegionTo, src, Csrc);
00144   }
00145 }; 
00146 
00148 
00182 template<class T> 
00183 class BoxLayoutData : public LayoutData<T>
00184 {
00185 public:
00187   BoxLayoutData();
00188 
00189   virtual ~BoxLayoutData();
00191   BoxLayoutData(const BoxLayout& boxes, int comps, 
00192                 const DataFactory<T>& factory = DefaultDataFactory<T>());
00193 
00195   virtual void define(const BoxLayout& boxes, int comps, 
00196                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00197 
00199   virtual void define(const BoxLayoutData<T>& da,
00200                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00201 
00203 
00206   virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
00207                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00208 
00210   virtual void define(const BoxLayout& boxes);
00211 
00213   int nComp() const { return m_comps;}
00214 
00216   Interval interval() const
00217   {
00218     Interval outint(0, m_comps-1);
00219     return(outint);
00220   }
00221 
00223 
00231   void generalCopyTo(const BoxLayout& a_destGrids, 
00232                      LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
00233                      const Interval& a_interval,
00234                      const ProblemDomain& a_domain,
00235                      const DataFactory<T>& factory = DefaultDataFactory<T>()) const ;
00236 
00238   /* User writes a function with the signature:
00239 
00240      <PRE>
00241      void myfunction(const Box& box, int comps, T& t){ your code here;}
00242      </PRE>
00243 
00244      They can then hand this off to LayoutData::apply.  This class
00245      then cycles through all the T objects and invokes this function.  Function
00246      must not be inline. (I'm still trying to figure out a nice way to send
00247      in non-static member functions).
00248      */
00249   virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
00250 
00251 
00253   virtual bool isDefined() const;
00254 protected:
00255 
00256   int             m_comps;
00257   bool            m_isdefined;
00258 
00259   friend class LevelData<T>;
00260   void setVector(const BoxLayoutData<T>& da, 
00261                  const Interval& srcComps,
00262                  const Interval& destComps);
00263   void allocateGhostVector(const DataFactory<T>& factory, 
00264                            const IntVect& ghost = IntVect::TheZeroVector());
00265 
00266 
00267   void makeItSo(const Interval&     a_srcComps,
00268                 const BoxLayoutData<T>& a_src,
00269                 BoxLayoutData<T>&   a_dest,
00270                 const Interval&     a_destComps,
00271                 const Copier&       a_copier,
00272                 const LDOperator<T>& a_op = LDOperator<T>()) const;
00273 
00274   //========================================================================
00275   //
00276   // data structures used by makeItSo when we have some
00277   // data that needs to be moved (ie. there are entries
00278   // in the 'FROM' or 'TO' CopyIterators)
00279   //
00280   void completePendingSends() const;
00281 
00282   void allocateBuffers(const BoxLayoutData<T>& a_src,
00283                        const Interval& a_srcComps,
00284                        const BoxLayoutData<T>& a_dest,
00285                        const Interval& a_destComps,
00286                        const Copier&   a_copier,
00287                        const LDOperator<T>& a_op) const;
00288 
00289   void writeSendDataFromMeIntoBuffers(const BoxLayoutData<T>& a_src,
00290                                       const Interval& a_srcComps,
00291                                       const LDOperator<T>& a_op) const;
00292 
00293   void postSendsFromMe() const ;
00294 
00295   void postReceivesToMe() const ;
00296 
00297   void unpackReceivesToMe(BoxLayoutData<T>& a_dest,
00298                           const Interval&   a_destComps,
00299                           const LDOperator<T>& a_op) const ;
00300 
00301   void unpackReceivesToMe_append(LayoutData<Vector<RefCountedPtr<T> > >& a_dest, 
00302                                  const Interval&   a_destComps,
00303                                  int ncomp,
00304                                  const DataFactory<T>& factory,
00305                                  const LDOperator<T>& a_op) const;
00306 
00309   mutable void*  m_sendbuffer; // pointer member OK here,
00310                                // since LevelData<T> has no copy
00311   mutable size_t m_sendcapacity;
00312   mutable void*  m_recbuffer;  // pointer member OK here,
00313                                // since LevelData<T> has no copy
00314   mutable size_t m_reccapacity;
00315 
00316 #ifdef MPI
00317 
00318 #ifndef DOXYGEN
00319 
00320   struct bufEntry
00321   {
00322     void* bufPtr; // pointer into contiguous m_buffer
00323     size_t size;
00324     const MotionItem* item;
00325     unsigned int procID;
00326     bool operator < (const bufEntry& rhs) const
00327       {
00328         if(procID == rhs.procID)
00329           {
00330             const Box& left = item->toRegion;
00331             const Box& right= rhs.item->toRegion;
00332             if(left.smallEnd() == right.smallEnd())
00333               {
00334                 return left.bigEnd().lexLT(right.bigEnd());
00335               }
00336             else
00337               {
00338                 return item->toRegion < rhs.item->toRegion;
00339               }
00340           }
00341         //else
00342         return procID < rhs.procID;
00343       }
00344   };
00345 
00346 #endif
00347   mutable std::vector<bufEntry> m_fromMe;
00348   mutable std::vector<bufEntry> m_toMe;
00349 
00350   mutable MPI_Request  *m_sendRequests, *m_receiveRequests;
00351   mutable MPI_Status   *m_sendStatus,   *m_receiveStatus;
00352   mutable int numSends, numReceives;
00353 #endif
00354 
00355 };
00356 
00358 
00377 Real norm(const BoxLayoutData<FArrayBox>& A, 
00378           const Interval& interval,
00379           const int& p = 2);
00380 
00381 
00382 //======================================================================
00383 template < >
00384 BaseFab<int>* DefaultDataFactory<BaseFab<int> >::create(const Box& box, 
00385                                                         int ncomps, 
00386                                                         const DataIndex& a_datInd) const;
00387 
00388 template < >
00389 FArrayBox* DefaultDataFactory<FArrayBox>::create(const Box& box, 
00390                                                  int ncomps,
00391                                                  const DataIndex& a_datInd) const;
00392 
00393 template <class T>
00394 T* DefaultDataFactory<T>::create(const Box& box, 
00395                                  int ncomps, 
00396                                  const DataIndex& a_datInd) const
00397 {
00398   return new T(box, ncomps);
00399 }
00400 
00401 
00402 template<class T>
00403 inline bool BoxLayoutData<T>::isDefined() const
00404 {
00405   return m_isdefined;
00406 }
00407 
00408 template <class T>
00409 inline void BoxLayoutData<T>::setVector(const BoxLayoutData<T>& da, 
00410                                         const Interval& srcComps,
00411                                         const Interval& destComps)
00412 {
00413   if(&da != this)
00414     {
00415       for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00416         {
00417           this->m_vector[this->m_boxLayout.index(it())]->copy( this->box(it()), destComps, 
00418                                                    this->box(it()), da[it()], srcComps);
00419         }
00420     }
00421 }
00422 
00423 template<class T>
00424 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
00425                                      const DataFactory<T>& factory)
00426 {
00427   if(this == &da){
00428     MayDay::Error("BoxLayoutData<T>::define(const LayoutData<T>& da,.....) called with 'this'");
00429   }
00430   assert(comps.size()>0);
00431   assert(comps.end()<=m_comps);
00432   assert(comps.begin()>=0);
00433   this->m_boxLayout = da.boxLayout();
00434 
00435   m_comps = comps.size();
00436 
00437   Interval dest(0, m_comps-1);
00438   allocateGhostVector(factory);
00439   setVector(da, comps, dest);
00440 #ifdef MPI  
00441   m_fromMe.resize(0);
00442   m_toMe.resize(0);
00443 #endif
00444 
00445 }
00446 
00447 template<class T>
00448 inline void BoxLayoutData<T>::define(const BoxLayout& boxes, int comps,
00449                                      const DataFactory<T>& factory)
00450 {
00451   assert(boxes.isClosed());
00452   this->m_boxLayout = boxes;
00453   m_comps = comps;
00454   m_isdefined = true;
00455   allocateGhostVector(factory);
00456 #ifdef MPI  
00457   m_fromMe.resize(0);
00458   m_toMe.resize(0);
00459 #endif
00460 }
00461 
00462 template<class T>
00463 inline void BoxLayoutData<T>::define(const BoxLayout& boxes)
00464 {
00465   MayDay::Error("BoxLayoutData<T>::define(const BoxLayout& boxes)...needs comps");
00466 }
00467 
00468 template <class T>
00469 inline   BoxLayoutData<T>::BoxLayoutData():m_comps(0) , m_sendbuffer(NULL),
00470     m_sendcapacity(0),  m_recbuffer(NULL),m_reccapacity(0)
00471 {
00472   m_isdefined = false;
00473 #ifdef MPI
00474   numSends = 0;
00475   numReceives = 0;
00476 #endif
00477 }
00478 template<class T>
00479 inline BoxLayoutData<T>::BoxLayoutData(const BoxLayout& boxes, int comps,
00480                                        const DataFactory<T>& factory)
00481   :m_comps(comps), m_sendbuffer(NULL),
00482     m_sendcapacity(0),  m_recbuffer(NULL),m_reccapacity(0)
00483 {
00484   assert(boxes.isClosed());
00485   this->m_boxLayout = boxes;
00486   m_isdefined = true;
00487   allocateGhostVector(factory);
00488 #ifdef MPI  
00489   m_fromMe.resize(0);
00490   m_toMe.resize(0);
00491 #endif
00492 }
00493 
00494 template<class T> 
00495 BoxLayoutData<T>::~BoxLayoutData()
00496 {
00497   completePendingSends();
00498   free(m_sendbuffer);
00499   free(m_recbuffer);
00500 }
00501 
00502 template<class T>
00503 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da,
00504                                      const DataFactory<T>& factory)
00505 {
00506   if(this != &da){
00507     m_isdefined = da.m_isdefined;
00508     this->m_boxLayout = da.boxLayout();
00509     m_comps    = da.nComp();
00510     Interval srcAnddest(0, m_comps-1);
00511     allocateGhostVector(factory);
00512     setVector(da, srcAnddest, srcAnddest);
00513   }
00514 #ifdef MPI  
00515   m_fromMe.resize(0);
00516   m_toMe.resize(0);
00517 #endif
00518 }
00519 
00520 
00521 template<class T>
00522 inline void BoxLayoutData<T>::allocateGhostVector(const DataFactory<T>& factory, const IntVect& ghost)
00523 {
00524   if(this->m_callDelete == true){
00525   for(unsigned int i=0; i<this->m_vector.size(); ++i)
00526     {
00527       delete this->m_vector[i];
00528       this->m_vector[i] = NULL;
00529     }
00530   }
00531 
00532   this->m_callDelete = factory.callDelete();
00533 
00534   this->m_vector.resize(this->m_boxLayout.size(), NULL);
00535 
00536   for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00537     {
00538       unsigned int index = this->m_boxLayout.index(it());
00539       Box abox = this->box(it());
00540       abox.grow(ghost);
00541       this->m_vector[index] = factory.create(abox, m_comps, it());
00542       if(this->m_vector[index] == NULL)
00543         {
00544           MayDay::Error("OutOfMemory in boxlayoutdata::allocate");
00545         }
00546     }
00547 }
00548 
00549 template<class T>
00550 inline void BoxLayoutData<T>::apply(void (*a_func)(const Box& box, int comps, T& t))
00551 {
00552   for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00553     {
00554       unsigned int index = this->m_boxLayout.index(it());
00555       a_func(this->box(it()), m_comps, *(this->m_vector[index]));
00556     }
00557 }
00558 
00559 
00560 
00561 //======================================================================
00562 template <class T>
00563 AliasDataFactory<T>::AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval)
00564 {
00565   define(a_original, interval);
00566 }
00567 
00568 template <class T>
00569 void AliasDataFactory<T>::define(BoxLayoutData<T>* a_original, const Interval& interval)
00570 {
00571   m_origPointer = a_original;
00572   m_interval    = interval;
00573 }
00574  
00575 template <class T>
00576 T* AliasDataFactory<T>::create(const Box& box, int ncomps, const DataIndex& a_datInd) const
00577 {
00578   assert(this->box() == box);
00579   assert(ncomps = m_interval.size());
00580   T* rtn = new T(m_interval, m_origPointer->operator[](a_datInd));
00581   return rtn;
00582 }
00583 
00584 #include "BoxLayoutDataI.H"
00585 
00586 #endif //BOXLAYOUTDATA

Generated on Fri Jul 2 17:53:42 2004 for Chombo by doxygen 1.3.2