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 #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
00239
00240
00241
00242
00243
00244
00245
00246
00247
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
00277
00278
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;
00310
00311 mutable size_t m_sendcapacity;
00312 mutable void* m_recbuffer;
00313
00314 mutable size_t m_reccapacity;
00315
00316 #ifdef MPI
00317
00318 #ifndef DOXYGEN
00319
00320 struct bufEntry
00321 {
00322 void* bufPtr;
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
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