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:
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
00263
00264
00265
00266
00267
00268
00269
00270
00271
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
00302
00303
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;
00335
00336 mutable size_t m_sendcapacity;
00337 mutable void* m_recbuffer;
00338
00339 mutable size_t m_reccapacity;
00340
00341 #ifdef MPI
00342
00343 #ifndef DOXYGEN
00344
00345 struct bufEntry
00346 {
00347 void* bufPtr;
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
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