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
00036 template <class T> class DataFactory
00037 {
00038 public:
00040
00042 virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const=0;
00043
00044 virtual bool callDelete() const {return true;}
00045
00046
00047 };
00048
00049
00051
00065 template <class T> class DefaultDataFactory : public DataFactory<T>
00066 {
00067 public:
00069
00071 virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00072
00073 };
00074
00075 class FABAliasDataFactory : public DataFactory<FArrayBox>
00076 {
00077 public:
00078 virtual ~FABAliasDataFactory(){;}
00079 FABAliasDataFactory(const LayoutData<Real*>& aliases);
00080 void define(const LayoutData<Real*>& aliases);
00082
00084 virtual FArrayBox* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00085
00086 protected:
00087 LayoutData<Real*> aliasPtrs;
00088 };
00089
00090 template<class T> class BoxLayoutData;
00091
00092 template <class T>
00093 class AliasDataFactory : public DataFactory<T>
00094 {
00095 public:
00096 virtual ~AliasDataFactory(){;}
00097 AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval);
00098 void define(BoxLayoutData<T>* a_original, const Interval& interval);
00101 virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
00102
00103 protected:
00104 BoxLayoutData<T>* m_origPointer;
00105 Interval m_interval;
00106 };
00107
00108
00109 template<class T> class LevelData;
00110
00111
00113
00147 template<class T>
00148 class BoxLayoutData : public LayoutData<T>
00149 {
00150 public:
00152 BoxLayoutData():m_comps(0) {m_isdefined = false;}
00153
00154 virtual ~BoxLayoutData(){;}
00156 BoxLayoutData(const BoxLayout& boxes, int comps,
00157 const DataFactory<T>& factory = DefaultDataFactory<T>());
00158
00160 virtual void define(const BoxLayout& boxes, int comps,
00161 const DataFactory<T>& factory = DefaultDataFactory<T>());
00162
00164 virtual void define(const BoxLayoutData<T>& da,
00165 const DataFactory<T>& factory = DefaultDataFactory<T>());
00166
00168
00171 virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
00172 const DataFactory<T>& factory = DefaultDataFactory<T>());
00173
00175 virtual void define(const BoxLayout& boxes);
00176
00178 int nComp() const { return m_comps;}
00179
00181 Interval interval() const
00182 {
00183 Interval outint(0, m_comps-1);
00184 return(outint);
00185 }
00186
00187
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
00201
00202
00204 virtual bool isDefined() const;
00205 protected:
00206
00207 int m_comps;
00208 bool m_isdefined;
00209
00210 friend class LevelData<T>;
00211 void setVector(const BoxLayoutData<T>& da,
00212 const Interval& srcComps,
00213 const Interval& destComps);
00214 void allocateGhostVector(const DataFactory<T>& factory,
00215 const IntVect& ghost = IntVect::TheZeroVector());
00216 };
00217
00219
00238 Real norm(const BoxLayoutData<FArrayBox>& A,
00239 const Interval& interval,
00240 const int& p = 2);
00241
00242
00243
00244 template < >
00245 BaseFab<int>* DefaultDataFactory<BaseFab<int> >::create(const Box& box,
00246 int ncomps,
00247 const DataIndex& a_datInd) const;
00248
00249 template < >
00250 FArrayBox* DefaultDataFactory<FArrayBox>::create(const Box& box,
00251 int ncomps,
00252 const DataIndex& a_datInd) const;
00253
00254 template <class T>
00255 T* DefaultDataFactory<T>::create(const Box& box,
00256 int ncomps,
00257 const DataIndex& a_datInd) const
00258 {
00259 return new T(box, ncomps);
00260 }
00261
00262
00263 template<class T>
00264 inline bool BoxLayoutData<T>::isDefined() const
00265 {
00266 return m_isdefined;
00267 }
00268
00269 template <class T>
00270 inline void BoxLayoutData<T>::setVector(const BoxLayoutData<T>& da,
00271 const Interval& srcComps,
00272 const Interval& destComps)
00273 {
00274 if(&da != this)
00275 {
00276 for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00277 {
00278 this->m_vector[this->m_boxLayout.index(it())]->copy( this->box(it()), destComps,
00279 this->box(it()), da[it()], srcComps);
00280 }
00281 }
00282 }
00283
00284 template<class T>
00285 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
00286 const DataFactory<T>& factory)
00287 {
00288 if(this == &da){
00289 MayDay::Error("BoxLayoutData<T>::define(const LayoutData<T>& da,.....) called with 'this'");
00290 }
00291 assert(comps.size()>0);
00292 assert(comps.end()<=m_comps);
00293 assert(comps.begin()>=0);
00294 this->m_boxLayout = da.boxLayout();
00295
00296 m_comps = comps.size();
00297
00298 Interval dest(0, m_comps-1);
00299 allocateGhostVector(factory);
00300 setVector(da, comps, dest);
00301
00302 }
00303
00304 template<class T>
00305 inline void BoxLayoutData<T>::define(const BoxLayout& boxes, int comps,
00306 const DataFactory<T>& factory)
00307 {
00308 assert(boxes.isClosed());
00309 this->m_boxLayout = boxes;
00310 m_comps = comps;
00311 m_isdefined = true;
00312 allocateGhostVector(factory);
00313 }
00314
00315 template<class T>
00316 inline void BoxLayoutData<T>::define(const BoxLayout& boxes)
00317 {
00318 MayDay::Error("BoxLayoutData<T>::define(const BoxLayout& boxes)...needs comps");
00319 }
00320
00321 template<class T>
00322 inline BoxLayoutData<T>::BoxLayoutData(const BoxLayout& boxes, int comps,
00323 const DataFactory<T>& factory)
00324 :m_comps(comps)
00325 {
00326 assert(boxes.isClosed());
00327 this->m_boxLayout = boxes;
00328 m_isdefined = true;
00329 allocateGhostVector(factory);
00330 }
00331
00332 template<class T>
00333 inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da,
00334 const DataFactory<T>& factory)
00335 {
00336 if(this != &da){
00337 m_isdefined = da.m_isdefined;
00338 this->m_boxLayout = da.boxLayout();
00339 m_comps = da.nComp();
00340 Interval srcAnddest(0, m_comps-1);
00341 allocateGhostVector(factory);
00342 setVector(da, srcAnddest, srcAnddest);
00343 }
00344 }
00345
00346
00347 template<class T>
00348 inline void BoxLayoutData<T>::allocateGhostVector(const DataFactory<T>& factory, const IntVect& ghost)
00349 {
00350 if(this->m_callDelete == true){
00351 for(unsigned int i=0; i<this->m_vector.size(); ++i)
00352 {
00353 delete this->m_vector[i];
00354 this->m_vector[i] = NULL;
00355 }
00356 }
00357
00358 this->m_callDelete = factory.callDelete();
00359
00360 this->m_vector.resize(this->m_boxLayout.size(), NULL);
00361
00362 for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00363 {
00364 unsigned int index = this->m_boxLayout.index(it());
00365 Box abox = this->box(it());
00366 abox.grow(ghost);
00367 this->m_vector[index] = factory.create(abox, m_comps, it());
00368 if(this->m_vector[index] == NULL)
00369 {
00370 MayDay::Error("OutOfMemory in boxlayoutdata::allocate");
00371 }
00372 }
00373 }
00374
00375 template<class T>
00376 inline void BoxLayoutData<T>::apply(void (*a_func)(const Box& box, int comps, T& t))
00377 {
00378 for(DataIterator it(this->dataIterator()); it.ok(); ++it)
00379 {
00380 unsigned int index = this->m_boxLayout.index(it());
00381 a_func(this->box(it()), m_comps, *(this->m_vector[index]));
00382 }
00383 }
00384
00385
00386
00387
00388 template <class T>
00389 AliasDataFactory<T>::AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval)
00390 {
00391 define(a_original, interval);
00392 }
00393
00394 template <class T>
00395 void AliasDataFactory<T>::define(BoxLayoutData<T>* a_original, const Interval& interval)
00396 {
00397 m_origPointer = a_original;
00398 m_interval = interval;
00399 }
00400
00401 template <class T>
00402 T* AliasDataFactory<T>::create(const Box& box, int ncomps, const DataIndex& a_datInd) const
00403 {
00404 assert(this->box() == box);
00405 assert(ncomps = m_interval.size());
00406 T* rtn = new T(m_interval, m_origPointer->operator[](a_datInd));
00407 return rtn;
00408 }
00409
00410 #endif // BOXLAYOUTDATA_H