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

BoxLayoutData.H

Go to the documentation of this file.
00001 /*   _______              __
00002     / ___/ /  ___  __ _  / /  ___
00003    / /__/ _ \/ _ \/  V \/ _ \/ _ \
00004    \___/_//_/\___/_/_/_/_.__/\___/
00005 */
00006 // CHOMBO Copyright (c) 2000-2004, The Regents of the University of
00007 // California, through Lawrence Berkeley National Laboratory (subject to
00008 // receipt of any required approvals from U.S. Dept. of Energy).  All
00009 // rights reserved.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are met:
00013 //
00014 // (1) Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 // (2) Redistributions in binary form must reproduce the above copyright
00017 // notice, this list of conditions and the following disclaimer in the
00018 // documentation and/or other materials provided with the distribution.
00019 // (3) Neither the name of Lawrence Berkeley National Laboratory, U.S.
00020 // Dept. of Energy nor the names of its contributors may be used to endorse
00021 // or promote products derived from this software without specific prior
00022 // written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00026 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00027 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00028 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00029 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00030 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00031 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00032 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00033 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00034 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035 //
00036 // You are under no obligation whatsoever to provide any bug fixes,
00037 // patches, or upgrades to the features, functionality or performance of
00038 // the source code ("Enhancements") to anyone; however, if you choose to
00039 // make your Enhancements available either publicly, or directly to
00040 // Lawrence Berkeley National Laboratory, without imposing a separate
00041 // written license agreement for such Enhancements, then you hereby grant
00042 // the following license: a non-exclusive, royalty-free perpetual license
00043 // to install, use, modify, prepare derivative works, incorporate into
00044 // other computer software, distribute, and sublicense such Enhancements or
00045 // derivative works thereof, in binary and source code form.
00046 //
00047 // TRADEMARKS. Product and company names mentioned herein may be the
00048 // trademarks of their respective owners.  Any rights not expressly granted
00049 // herein are reserved.
00050 //
00051 
00052 #ifndef _BOXLAYOUTDATA_H_
00053 #define _BOXLAYOUTDATA_H_
00054 
00055 #include "LayoutData.H"
00056 #include "Interval.H"
00057 #include "FArrayBox.H"
00058 
00059 class MotionItem;
00060 
00061 #include "DisjointBoxLayout.H"
00062 #include "Copier.H"
00063 #include "SPMD.H"
00064 #include "memtrack.H"
00065 
00067 template <class T> class DataFactory
00068 {
00069 public:
00070 
00071   virtual ~DataFactory(){;}
00073 
00075   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const=0;
00076 
00077   virtual bool callDelete() const {return true;}
00078 };
00079 
00081 
00095 template <class T> class DefaultDataFactory : public DataFactory<T>
00096 {
00097 public:
00099 
00101   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00102 
00103 };
00104 
00105 class FABAliasDataFactory : public DataFactory<FArrayBox>
00106 {
00107 public:
00108   virtual ~FABAliasDataFactory()
00109   {}
00110 
00111   FABAliasDataFactory(const LayoutData<Real*>& aliases);
00112   void define(const LayoutData<Real*>& aliases);
00114 
00116   virtual FArrayBox* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00117 
00118 protected:
00119   LayoutData<Real*> aliasPtrs;
00120 };
00121 
00122 template<class T> class BoxLayoutData;
00123 
00124 template <class T>
00125 class AliasDataFactory : public DataFactory<T>
00126 {
00127 public:
00128   virtual ~AliasDataFactory()
00129   {}
00130 
00131   AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval);
00132   void define(BoxLayoutData<T>* a_original, const Interval& interval);
00135   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00136 
00137 protected:
00138   BoxLayoutData<T>* m_origPointer;
00139   Interval          m_interval;
00140 };
00141 
00142 template<class T> class LevelData;
00143 
00144 template <class T>
00145 class LDOperator
00146 {
00147 public:
00148   virtual ~LDOperator(){}    //to keep the compiler happy
00149 
00150   virtual int size(const T& arg, const Box& b, const Interval& comps) const
00151   {
00152     return arg.size(b, comps);
00153   }
00154   virtual void linearOut(const T& arg, void* buf, const Box& R,
00155                          const Interval& comps) const
00156   {
00157     arg.linearOut(buf, R, comps);
00158   }
00159   virtual void linearIn(T& arg,  void* buf, const Box& R,
00160                         const Interval& comps)const
00161   {
00162     arg.linearIn(buf, R, comps);
00163   }
00164   virtual void op(T& dest,
00165           const Box& RegionFrom,
00166           const Interval& Cdest,
00167           const Box& RegionTo,
00168           const T& src,
00169           const Interval& Csrc) const
00170   {
00171     dest.copy(RegionFrom, Cdest,RegionTo, src, Csrc);
00172   }
00173 };
00174 
00176 
00210 template<class T>
00211 class BoxLayoutData : public LayoutData<T>
00212 {
00213 public:
00215   BoxLayoutData();
00216 
00217   virtual ~BoxLayoutData();
00219   BoxLayoutData(const BoxLayout& boxes, int comps,
00220                 const DataFactory<T>& factory = DefaultDataFactory<T>());
00221 
00223   virtual void define(const BoxLayout& boxes, int comps,
00224                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00225 
00227   virtual void define(const BoxLayoutData<T>& da,
00228                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00229 
00231 
00234   virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
00235                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00236 
00238   virtual void define(const BoxLayout& boxes);
00239 
00241   int nComp() const { return m_comps;}
00242 
00244   Interval interval() const
00245   {
00246     Interval outint(0, m_comps-1);
00247     return(outint);
00248   }
00249 
00251 
00259   void generalCopyTo(const BoxLayout& a_destGrids,
00260                      LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
00261                      const Interval& a_interval,
00262                      const ProblemDomain& a_domain,
00263                      const DataFactory<T>& factory = DefaultDataFactory<T>()) const ;
00264 
00266   /* User writes a function with the signature:
00267 
00268      <PRE>
00269      void myfunction(const Box& box, int comps, T& t){ your code here;}
00270      </PRE>
00271 
00272      They can then hand this off to LayoutData::apply.  This class
00273      then cycles through all the T objects and invokes this function.  Function
00274      must not be inline. (I'm still trying to figure out a nice way to send
00275      in non-static member functions).
00276      */
00277   virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
00278 
00280   virtual bool isDefined() const;
00281 
00282 
00283 protected:
00284   int             m_comps;
00285   bool            m_isdefined;
00286 
00287   friend class LevelData<T>;
00288 
00289   void setVector(const BoxLayoutData<T>& da,
00290                  const Interval& srcComps,
00291                  const Interval& destComps);
00292 
00293   void allocateGhostVector(const DataFactory<T>& factory,
00294                            const IntVect& ghost = IntVect::Zero);
00295 
00296   void makeItSo(const Interval&     a_srcComps,
00297                 const BoxLayoutData<T>& a_src,
00298                 BoxLayoutData<T>&   a_dest,
00299                 const Interval&     a_destComps,
00300                 const Copier&       a_copier,
00301                 const LDOperator<T>& a_op = LDOperator<T>()) const;
00302 
00303   //========================================================================
00304   //
00305   // data structures used by makeItSo when we have some
00306   // data that needs to be moved (ie. there are entries
00307   // in the 'FROM' or 'TO' CopyIterators)
00308   //
00309   void completePendingSends() const;
00310 
00311   void allocateBuffers(const BoxLayoutData<T>& a_src,
00312                        const Interval& a_srcComps,
00313                        const BoxLayoutData<T>& a_dest,
00314                        const Interval& a_destComps,
00315                        const Copier&   a_copier,
00316                        const LDOperator<T>& a_op) const;
00317 
00318   void writeSendDataFromMeIntoBuffers(const BoxLayoutData<T>& a_src,
00319                                       const Interval& a_srcComps,
00320                                       const LDOperator<T>& a_op) const;
00321 
00322   void postSendsFromMe() const ;
00323 
00324   void postReceivesToMe() const ;
00325 
00326   void unpackReceivesToMe(BoxLayoutData<T>& a_dest,
00327                           const Interval&   a_destComps,
00328                           const LDOperator<T>& a_op) const ;
00329 
00330   void unpackReceivesToMe_append(LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
00331                                  const Interval&   a_destComps,
00332                                  int ncomp,
00333                                  const DataFactory<T>& factory,
00334                                  const LDOperator<T>& a_op) const;
00335 
00338   mutable void*  m_sendbuffer; // pointer member OK here,
00339                                // since LevelData<T> has no copy
00340   mutable size_t m_sendcapacity;
00341   mutable void*  m_recbuffer;  // pointer member OK here,
00342                                // since LevelData<T> has no copy
00343   mutable size_t m_reccapacity;
00344 
00345 #ifdef CH_MPI
00346 
00347 #ifndef DOXYGEN
00348 
00349   struct bufEntry
00350   {
00351     void* bufPtr; // pointer into contiguous m_buffer
00352     size_t size;
00353     const MotionItem* item;
00354     unsigned int procID;
00355     bool operator < (const bufEntry& rhs) const
00356       {
00357         if(procID == rhs.procID)
00358           {
00359             const Box& left = item->toRegion;
00360             const Box& right= rhs.item->toRegion;
00361             if(left.smallEnd() == right.smallEnd())
00362               {
00363                 return left.bigEnd().lexLT(right.bigEnd());
00364               }
00365             else
00366               {
00367                 return item->toRegion < rhs.item->toRegion;
00368               }
00369           }
00370         //else
00371         return procID < rhs.procID;
00372       }
00373   };
00374 
00375 #endif
00376   mutable std::vector<bufEntry> m_fromMe;
00377   mutable std::vector<bufEntry> m_toMe;
00378 
00379   mutable MPI_Request  *m_sendRequests, *m_receiveRequests;
00380   mutable MPI_Status   *m_sendStatus,   *m_receiveStatus;
00381   mutable int numSends, numReceives;
00382 #endif
00383 
00384 };
00385 
00387 
00406 Real norm(const BoxLayoutData<FArrayBox>& A,
00407           const Interval& interval,
00408           const int& p = 2);
00409 
00410 //======================================================================
00411 template < >
00412 BaseFab<int>* DefaultDataFactory<BaseFab<int> >::create(const Box& box,
00413                                                         int ncomps,
00414                                                         const DataIndex& a_datInd) const;
00415 
00416 template < >
00417 FArrayBox* DefaultDataFactory<FArrayBox>::create(const Box& box,
00418                                                  int ncomps,
00419                                                  const DataIndex& a_datInd) const;
00420 
00421 template <class T>
00422 T* DefaultDataFactory<T>::create(const Box& box,
00423                                  int ncomps,
00424                                  const DataIndex& a_datInd) const
00425 {
00426   return new T(box, ncomps);
00427 }
00428 
00429 template<class T>
00430 inline bool BoxLayoutData<T>::isDefined() const
00431 {
00432   return m_isdefined;
00433 }
00434 
00435 template <class T>
00436 inline void BoxLayoutData<T>::setVector(const BoxLayoutData<T>& da,
00437                                         const Interval& srcComps,
00438                                         const Interval& destComps)
00439 {
00440   if(&da != this)
00441     {
00442       for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00443         {
00444           this->m_vector[this->m_boxLayout.index(it())]->copy( this->box(it()), destComps,
00445                                                    this->box(it()), da[it()], srcComps);
00446         }
00447     }
00448 }
00449 
00450 template<class T>
00451 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
00452                                      const DataFactory<T>& factory)
00453 {
00454   if(this == &da){
00455     MayDay::Error("BoxLayoutData<T>::define(const LayoutData<T>& da,.....) called with 'this'");
00456   }
00457  CH_assert(comps.size()>0);
00458  CH_assert(comps.end()<=m_comps);
00459  CH_assert(comps.begin()>=0);
00460   this->m_boxLayout = da.boxLayout();
00461 
00462   this->m_comps = comps.size();
00463 
00464   Interval dest(0, m_comps-1);
00465   allocateGhostVector(factory);
00466   setVector(da, comps, dest);
00467 #ifdef CH_MPI
00468   this->m_fromMe.resize(0);
00469   this->m_toMe.resize(0);
00470 #endif
00471 
00472 }
00473 
00474 template<class T>
00475 inline void BoxLayoutData<T>::define(const BoxLayout& boxes, int comps,
00476                                      const DataFactory<T>& factory)
00477 {
00478  CH_assert(boxes.isClosed());
00479   this->m_boxLayout = boxes;
00480   m_comps = comps;
00481   m_isdefined = true;
00482   allocateGhostVector(factory);
00483 #ifdef CH_MPI
00484   m_fromMe.resize(0);
00485   m_toMe.resize(0);
00486 #endif
00487 }
00488 
00489 template<class T>
00490 inline void BoxLayoutData<T>::define(const BoxLayout& boxes)
00491 {
00492   MayDay::Error("BoxLayoutData<T>::define(const BoxLayout& boxes)...needs comps");
00493 }
00494 
00495 template <class T>
00496 inline   BoxLayoutData<T>::BoxLayoutData():m_comps(0) , m_sendbuffer(NULL),
00497     m_sendcapacity(0),  m_recbuffer(NULL),m_reccapacity(0)
00498 {
00499   m_isdefined = false;
00500 #ifdef CH_MPI
00501   this->numSends = 0;
00502   this->numReceives = 0;
00503 #endif
00504 }
00505 template<class T>
00506 inline BoxLayoutData<T>::BoxLayoutData(const BoxLayout& boxes, int comps,
00507                                        const DataFactory<T>& factory)
00508   :m_comps(comps), m_sendbuffer(NULL),
00509     m_sendcapacity(0),  m_recbuffer(NULL),m_reccapacity(0)
00510 {
00511  CH_assert(boxes.isClosed());
00512   this->m_boxLayout = boxes;
00513   m_isdefined = true;
00514   allocateGhostVector(factory);
00515 #ifdef CH_MPI
00516   m_fromMe.resize(0);
00517   m_toMe.resize(0);
00518   this->numSends = 0;
00519   this->numReceives = 0;
00520 #endif
00521 }
00522 
00523 template<class T>
00524 BoxLayoutData<T>::~BoxLayoutData()
00525 {
00526   completePendingSends();
00527   free(m_sendbuffer);
00528   free(m_recbuffer);
00529 }
00530 
00531 template<class T>
00532 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da,
00533                                      const DataFactory<T>& factory)
00534 {
00535   if(this != &da){
00536     m_isdefined = da.m_isdefined;
00537     this->m_boxLayout = da.boxLayout();
00538     m_comps    = da.nComp();
00539     Interval srcAnddest(0, m_comps-1);
00540     allocateGhostVector(factory);
00541     setVector(da, srcAnddest, srcAnddest);
00542   }
00543 #ifdef CH_MPI
00544   m_fromMe.resize(0);
00545   m_toMe.resize(0);
00546 #endif
00547 }
00548 
00549 template<class T>
00550 inline void BoxLayoutData<T>::allocateGhostVector(const DataFactory<T>& factory, const IntVect& ghost)
00551 {
00552   if(this->m_callDelete == true){
00553   for(unsigned int i=0; i<this->m_vector.size(); ++i)
00554     {
00555       delete this->m_vector[i];
00556       this->m_vector[i] = NULL;
00557     }
00558   }
00559 
00560   this->m_callDelete = factory.callDelete();
00561 
00562   this->m_vector.resize(this->m_boxLayout.size(), NULL);
00563 
00564   for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00565     {
00566       unsigned int index = this->m_boxLayout.index(it());
00567       Box abox = this->box(it());
00568       abox.grow(ghost);
00569       this->m_vector[index] = factory.create(abox, m_comps, it());
00570       if(this->m_vector[index] == NULL)
00571         {
00572           MayDay::Error("OutOfMemory in boxlayoutdata::allocate");
00573         }
00574     }
00575 }
00576 
00577 template<class T>
00578 inline void BoxLayoutData<T>::apply(void (*a_func)(const Box& box, int comps, T& t))
00579 {
00580   for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00581     {
00582       unsigned int index = this->m_boxLayout.index(it());
00583       a_func(this->box(it()), m_comps, *(this->m_vector[index]));
00584     }
00585 }
00586 
00587 //======================================================================
00588 template <class T>
00589 AliasDataFactory<T>::AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval)
00590 {
00591   define(a_original, interval);
00592 }
00593 
00594 template <class T>
00595 void AliasDataFactory<T>::define(BoxLayoutData<T>* a_original, const Interval& interval)
00596 {
00597   m_origPointer = a_original;
00598   m_interval    = interval;
00599 }
00600 
00601 template <class T>
00602 T* AliasDataFactory<T>::create(const Box& a_box, int ncomps, const DataIndex& a_dataInd) const
00603 {
00604   //CH_assert(this->box(a_dataInd) == a_box);
00605  CH_assert(ncomps = m_interval.size());
00606   T* rtn = new T(m_interval, m_origPointer->operator[](a_dataInd));
00607   return rtn;
00608 }
00609 
00610 #include "BoxLayoutDataI.H"
00611 
00612 #endif //BOXLAYOUTDATA

Generated on Wed Oct 5 13:52:08 2005 for Chombo&AMRSelfGravity by  doxygen 1.4.1