Main Page   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    / /__/ _ \/ _ \/  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:
00071 
00073   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const=0;
00074 
00075   virtual bool callDelete() const {return true;}
00076 };
00077 
00079 
00093 template <class T> class DefaultDataFactory : public DataFactory<T>
00094 {
00095 public:
00097 
00099   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00100 
00101 };
00102 
00103 class FABAliasDataFactory : public DataFactory<FArrayBox>
00104 {
00105 public:
00106   virtual ~FABAliasDataFactory()
00107   {}
00108 
00109   FABAliasDataFactory(const LayoutData<Real*>& aliases);
00110   void define(const LayoutData<Real*>& aliases);
00112 
00114   virtual FArrayBox* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00115 
00116 protected:
00117   LayoutData<Real*> aliasPtrs;
00118 };
00119 
00120 template<class T> class BoxLayoutData;
00121 
00122 template <class T>
00123 class AliasDataFactory : public DataFactory<T>
00124 {
00125 public:
00126   virtual ~AliasDataFactory()
00127   {}
00128 
00129   AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval);
00130   void define(BoxLayoutData<T>* a_original, const Interval& interval);
00133   virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00134 
00135 protected:
00136   BoxLayoutData<T>* m_origPointer;
00137   Interval          m_interval;
00138 };
00139 
00140 template<class T> class LevelData;
00141 
00142 template <class T>
00143 class LDOperator
00144 {
00145 public:
00146   virtual int size(const T& arg, const Box& b, const Interval& comps) const
00147   {
00148     return arg.size(b, comps);
00149   }
00150   virtual void linearOut(const T& arg, void* buf, const Box& R,
00151                          const Interval& comps) const
00152   {
00153     arg.linearOut(buf, R, comps);
00154   }
00155   virtual void linearIn(T& arg,  void* buf, const Box& R,
00156                         const Interval& comps)const
00157   {
00158     arg.linearIn(buf, R, comps);
00159   }
00160   virtual void op(T& dest,
00161           const Box& RegionFrom,
00162           const Interval& Cdest,
00163           const Box& RegionTo,
00164           const T& src,
00165           const Interval& Csrc) const
00166   {
00167     dest.copy(RegionFrom, Cdest,RegionTo, src, Csrc);
00168   }
00169 };
00170 
00172 
00206 template<class T>
00207 class BoxLayoutData : public LayoutData<T>
00208 {
00209 public:
00211   BoxLayoutData();
00212 
00213   virtual ~BoxLayoutData();
00215   BoxLayoutData(const BoxLayout& boxes, int comps,
00216                 const DataFactory<T>& factory = DefaultDataFactory<T>());
00217 
00219   virtual void define(const BoxLayout& boxes, int comps,
00220                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00221 
00223   virtual void define(const BoxLayoutData<T>& da,
00224                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00225 
00227 
00230   virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
00231                       const DataFactory<T>& factory = DefaultDataFactory<T>());
00232 
00234   virtual void define(const BoxLayout& boxes);
00235 
00237   int nComp() const { return m_comps;}
00238 
00240   Interval interval() const
00241   {
00242     Interval outint(0, m_comps-1);
00243     return(outint);
00244   }
00245 
00247 
00255   void generalCopyTo(const BoxLayout& a_destGrids,
00256                      LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
00257                      const Interval& a_interval,
00258                      const ProblemDomain& a_domain,
00259                      const DataFactory<T>& factory = DefaultDataFactory<T>()) const ;
00260 
00262   /* User writes a function with the signature:
00263 
00264      <PRE>
00265      void myfunction(const Box& box, int comps, T& t){ your code here;}
00266      </PRE>
00267 
00268      They can then hand this off to LayoutData::apply.  This class
00269      then cycles through all the T objects and invokes this function.  Function
00270      must not be inline. (I'm still trying to figure out a nice way to send
00271      in non-static member functions).
00272      */
00273   virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
00274 
00276   virtual bool isDefined() const;
00277 
00278 
00279 protected:
00280   int             m_comps;
00281   bool            m_isdefined;
00282 
00283   friend class LevelData<T>;
00284 
00285   void setVector(const BoxLayoutData<T>& da,
00286                  const Interval& srcComps,
00287                  const Interval& destComps);
00288 
00289   void allocateGhostVector(const DataFactory<T>& factory,
00290                            const IntVect& ghost = IntVect::TheZeroVector());
00291 
00292   void makeItSo(const Interval&     a_srcComps,
00293                 const BoxLayoutData<T>& a_src,
00294                 BoxLayoutData<T>&   a_dest,
00295                 const Interval&     a_destComps,
00296                 const Copier&       a_copier,
00297                 const LDOperator<T>& a_op = LDOperator<T>()) const;
00298 
00299   //========================================================================
00300   //
00301   // data structures used by makeItSo when we have some
00302   // data that needs to be moved (ie. there are entries
00303   // in the 'FROM' or 'TO' CopyIterators)
00304   //
00305   void completePendingSends() const;
00306 
00307   void allocateBuffers(const BoxLayoutData<T>& a_src,
00308                        const Interval& a_srcComps,
00309                        const BoxLayoutData<T>& a_dest,
00310                        const Interval& a_destComps,
00311                        const Copier&   a_copier,
00312                        const LDOperator<T>& a_op) const;
00313 
00314   void writeSendDataFromMeIntoBuffers(const BoxLayoutData<T>& a_src,
00315                                       const Interval& a_srcComps,
00316                                       const LDOperator<T>& a_op) const;
00317 
00318   void postSendsFromMe() const ;
00319 
00320   void postReceivesToMe() const ;
00321 
00322   void unpackReceivesToMe(BoxLayoutData<T>& a_dest,
00323                           const Interval&   a_destComps,
00324                           const LDOperator<T>& a_op) const ;
00325 
00326   void unpackReceivesToMe_append(LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
00327                                  const Interval&   a_destComps,
00328                                  int ncomp,
00329                                  const DataFactory<T>& factory,
00330                                  const LDOperator<T>& a_op) const;
00331 
00334   mutable void*  m_sendbuffer; // pointer member OK here,
00335                                // since LevelData<T> has no copy
00336   mutable size_t m_sendcapacity;
00337   mutable void*  m_recbuffer;  // pointer member OK here,
00338                                // since LevelData<T> has no copy
00339   mutable size_t m_reccapacity;
00340 
00341 #ifdef MPI
00342 
00343 #ifndef DOXYGEN
00344 
00345   struct bufEntry
00346   {
00347     void* bufPtr; // pointer into contiguous m_buffer
00348     size_t size;
00349     const MotionItem* item;
00350     unsigned int procID;
00351     bool operator < (const bufEntry& rhs) const
00352       {
00353         if(procID == rhs.procID)
00354           {
00355             const Box& left = item->toRegion;
00356             const Box& right= rhs.item->toRegion;
00357             if(left.smallEnd() == right.smallEnd())
00358               {
00359                 return left.bigEnd().lexLT(right.bigEnd());
00360               }
00361             else
00362               {
00363                 return item->toRegion < rhs.item->toRegion;
00364               }
00365           }
00366         //else
00367         return procID < rhs.procID;
00368       }
00369   };
00370 
00371 #endif
00372   mutable std::vector<bufEntry> m_fromMe;
00373   mutable std::vector<bufEntry> m_toMe;
00374 
00375   mutable MPI_Request  *m_sendRequests, *m_receiveRequests;
00376   mutable MPI_Status   *m_sendStatus,   *m_receiveStatus;
00377   mutable int numSends, numReceives;
00378 #endif
00379 
00380 };
00381 
00383 
00402 Real norm(const BoxLayoutData<FArrayBox>& A,
00403           const Interval& interval,
00404           const int& p = 2);
00405 
00406 //======================================================================
00407 template < >
00408 BaseFab<int>* DefaultDataFactory<BaseFab<int> >::create(const Box& box,
00409                                                         int ncomps,
00410                                                         const DataIndex& a_datInd) const;
00411 
00412 template < >
00413 FArrayBox* DefaultDataFactory<FArrayBox>::create(const Box& box,
00414                                                  int ncomps,
00415                                                  const DataIndex& a_datInd) const;
00416 
00417 template <class T>
00418 T* DefaultDataFactory<T>::create(const Box& box,
00419                                  int ncomps,
00420                                  const DataIndex& a_datInd) const
00421 {
00422   return new T(box, ncomps);
00423 }
00424 
00425 template<class T>
00426 inline bool BoxLayoutData<T>::isDefined() const
00427 {
00428   return m_isdefined;
00429 }
00430 
00431 template <class T>
00432 inline void BoxLayoutData<T>::setVector(const BoxLayoutData<T>& da,
00433                                         const Interval& srcComps,
00434                                         const Interval& destComps)
00435 {
00436   if(&da != this)
00437     {
00438       for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00439         {
00440           this->m_vector[this->m_boxLayout.index(it())]->copy( this->box(it()), destComps,
00441                                                    this->box(it()), da[it()], srcComps);
00442         }
00443     }
00444 }
00445 
00446 template<class T>
00447 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
00448                                      const DataFactory<T>& factory)
00449 {
00450   if(this == &da){
00451     MayDay::Error("BoxLayoutData<T>::define(const LayoutData<T>& da,.....) called with 'this'");
00452   }
00453   assert(comps.size()>0);
00454   assert(comps.end()<=m_comps);
00455   assert(comps.begin()>=0);
00456   this->m_boxLayout = da.boxLayout();
00457 
00458   this->m_comps = comps.size();
00459 
00460   Interval dest(0, m_comps-1);
00461   allocateGhostVector(factory);
00462   setVector(da, comps, dest);
00463 #ifdef MPI
00464   this->m_fromMe.resize(0);
00465   this->m_toMe.resize(0);
00466 #endif
00467 
00468 }
00469 
00470 template<class T>
00471 inline void BoxLayoutData<T>::define(const BoxLayout& boxes, int comps,
00472                                      const DataFactory<T>& factory)
00473 {
00474   assert(boxes.isClosed());
00475   this->m_boxLayout = boxes;
00476   m_comps = comps;
00477   m_isdefined = true;
00478   allocateGhostVector(factory);
00479 #ifdef MPI
00480   m_fromMe.resize(0);
00481   m_toMe.resize(0);
00482 #endif
00483 }
00484 
00485 template<class T>
00486 inline void BoxLayoutData<T>::define(const BoxLayout& boxes)
00487 {
00488   MayDay::Error("BoxLayoutData<T>::define(const BoxLayout& boxes)...needs comps");
00489 }
00490 
00491 template <class T>
00492 inline   BoxLayoutData<T>::BoxLayoutData():m_comps(0) , m_sendbuffer(NULL),
00493     m_sendcapacity(0),  m_recbuffer(NULL),m_reccapacity(0)
00494 {
00495   m_isdefined = false;
00496 #ifdef MPI
00497   this->numSends = 0;
00498   this->numReceives = 0;
00499 #endif
00500 }
00501 template<class T>
00502 inline BoxLayoutData<T>::BoxLayoutData(const BoxLayout& boxes, int comps,
00503                                        const DataFactory<T>& factory)
00504   :m_comps(comps), m_sendbuffer(NULL),
00505     m_sendcapacity(0),  m_recbuffer(NULL),m_reccapacity(0)
00506 {
00507   assert(boxes.isClosed());
00508   this->m_boxLayout = boxes;
00509   m_isdefined = true;
00510   allocateGhostVector(factory);
00511 #ifdef MPI
00512   m_fromMe.resize(0);
00513   m_toMe.resize(0);
00514   this->numSends = 0;
00515   this->numReceives = 0;
00516 #endif
00517 }
00518 
00519 template<class T>
00520 BoxLayoutData<T>::~BoxLayoutData()
00521 {
00522   completePendingSends();
00523   free(m_sendbuffer);
00524   free(m_recbuffer);
00525 }
00526 
00527 template<class T>
00528 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da,
00529                                      const DataFactory<T>& factory)
00530 {
00531   if(this != &da){
00532     m_isdefined = da.m_isdefined;
00533     this->m_boxLayout = da.boxLayout();
00534     m_comps    = da.nComp();
00535     Interval srcAnddest(0, m_comps-1);
00536     allocateGhostVector(factory);
00537     setVector(da, srcAnddest, srcAnddest);
00538   }
00539 #ifdef MPI
00540   m_fromMe.resize(0);
00541   m_toMe.resize(0);
00542 #endif
00543 }
00544 
00545 template<class T>
00546 inline void BoxLayoutData<T>::allocateGhostVector(const DataFactory<T>& factory, const IntVect& ghost)
00547 {
00548   if(this->m_callDelete == true){
00549   for(unsigned int i=0; i<this->m_vector.size(); ++i)
00550     {
00551       delete this->m_vector[i];
00552       this->m_vector[i] = NULL;
00553     }
00554   }
00555 
00556   this->m_callDelete = factory.callDelete();
00557 
00558   this->m_vector.resize(this->m_boxLayout.size(), NULL);
00559 
00560   for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00561     {
00562       unsigned int index = this->m_boxLayout.index(it());
00563       Box abox = this->box(it());
00564       abox.grow(ghost);
00565       this->m_vector[index] = factory.create(abox, m_comps, it());
00566       if(this->m_vector[index] == NULL)
00567         {
00568           MayDay::Error("OutOfMemory in boxlayoutdata::allocate");
00569         }
00570     }
00571 }
00572 
00573 template<class T>
00574 inline void BoxLayoutData<T>::apply(void (*a_func)(const Box& box, int comps, T& t))
00575 {
00576   for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00577     {
00578       unsigned int index = this->m_boxLayout.index(it());
00579       a_func(this->box(it()), m_comps, *(this->m_vector[index]));
00580     }
00581 }
00582 
00583 //======================================================================
00584 template <class T>
00585 AliasDataFactory<T>::AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval)
00586 {
00587   define(a_original, interval);
00588 }
00589 
00590 template <class T>
00591 void AliasDataFactory<T>::define(BoxLayoutData<T>* a_original, const Interval& interval)
00592 {
00593   m_origPointer = a_original;
00594   m_interval    = interval;
00595 }
00596 
00597 template <class T>
00598 T* AliasDataFactory<T>::create(const Box& box, int ncomps, const DataIndex& a_dataInd) const
00599 {
00600   assert(this->box(a_dataInd) == box);
00601   assert(ncomps = m_interval.size());
00602   T* rtn = new T(m_interval, m_origPointer->operator[](a_dataInd));
00603   return rtn;
00604 }
00605 
00606 #include "BoxLayoutDataI.H"
00607 
00608 #endif //BOXLAYOUTDATA

Generated on Wed Jan 19 17:51:23 2005 for Chombo&INSwithParticles by doxygen1.2.16