00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
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(){}
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
00267
00268
00269
00270
00271
00272
00273
00274
00275
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
00306
00307
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;
00339
00340 mutable size_t m_sendcapacity;
00341 mutable void* m_recbuffer;
00342
00343 mutable size_t m_reccapacity;
00344
00345 #ifdef CH_MPI
00346
00347 #ifndef DOXYGEN
00348
00349 struct bufEntry
00350 {
00351 void* bufPtr;
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
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
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