📄 boxlayoutdata.h
字号:
// This software is copyright (C) by the Lawrence Berkeley
// National Laboratory. Permission is granted to reproduce
// this software for non-commercial purposes provided that
// this notice is left intact.
//
// It is acknowledged that the U.S. Government has rights to
// this software under Contract DE-AC03-765F00098 between
// the U.S. Department of Energy and the University of
// California.
//
// This software is provided as a professional and academic
// contribution for joint exchange. Thus it is experimental,
// is provided ``as is'', with no warranties of any kind
// whatsoever, no support, no promise of updates, or printed
// documentation. By using this software, you acknowledge
// that the Lawrence Berkeley National Laboratory and
// Regents of the University of California shall have no
// liability with respect to the infringement of other
// copyrights by any part of this software.
//
#ifndef BOXLAYOUTDATA_H
#define BOXLAYOUTDATA_H
#include "LayoutData.H"
#include "Interval.H"
#include "FArrayBox.H"
template <class T> class DataFactory
{
public:
virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const=0;
};
template <class T> class DefaultDataFactory : public DataFactory<T>
{
public:
virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
};
class FABAliasDataFactory : public DataFactory<FArrayBox>
{
public:
virtual ~FABAliasDataFactory(){;}
FABAliasDataFactory(const LayoutData<Real*>& aliases);
void define(const LayoutData<Real*>& aliases);
virtual FArrayBox* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
protected:
LayoutData<Real*> aliasPtrs;
};
template<class T> class BoxLayoutData;
template <class T>
class AliasDataFactory : public DataFactory<T>
{
public:
virtual ~AliasDataFactory(){;}
AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval);
void define(BoxLayoutData<T>* a_original, const Interval& interval);
virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
protected:
BoxLayoutData<T>* m_origPointer;
Interval m_interval;
};
template<class T> class LevelData;
template<class T>
class BoxLayoutData : public LayoutData<T>
{
public:
BoxLayoutData():m_comps(0) {m_isdefined = false;}
virtual ~BoxLayoutData(){;}
BoxLayoutData(const BoxLayout& boxes, int comps,
const DataFactory<T>& factory = DefaultDataFactory<T>());
virtual void define(const BoxLayout& boxes, int comps,
const DataFactory<T>& factory = DefaultDataFactory<T>());
virtual void define(const BoxLayoutData<T>& da,
const DataFactory<T>& factory = DefaultDataFactory<T>());
virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
const DataFactory<T>& factory = DefaultDataFactory<T>());
virtual void define(const BoxLayout& boxes);
int nComp() const { return m_comps;}
Interval interval() const
{
Interval outint(0, m_comps-1);
return(outint);
}
/* User writes a function with the signature:
<PRE>
void myfunction(const Box& box, int comps, T& t){ your code here;}
</PRE>
They can then hand this off to LayoutData::apply. This class
then cycles through all the T objects and invokes this function. Function
must not be inline. (I'm still trying to figure out a nice way to send
in non-static member functions).
*/
virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
virtual bool isDefined() const;
protected:
int m_comps;
bool m_isdefined;
friend class LevelData<T>;
void setVector(const BoxLayoutData<T>& da,
const Interval& srcComps,
const Interval& destComps);
void allocateGhostVector(const DataFactory<T>& factory,
const IntVect& ghost = IntVect::TheZeroVector());
};
Real norm(const BoxLayoutData<FArrayBox>& A,
const Interval& interval,
const int& p = 2);
//======================================================================
template < >
BaseFab<int>* DefaultDataFactory<BaseFab<int> >::create(const Box& box,
int ncomps,
const DataIndex& a_datInd) const;
template < >
FArrayBox* DefaultDataFactory<FArrayBox>::create(const Box& box,
int ncomps,
const DataIndex& a_datInd) const;
template <class T>
T* DefaultDataFactory<T>::create(const Box& box,
int ncomps,
const DataIndex& a_datInd) const
{
return new T(box, ncomps);
}
template<class T>
inline bool BoxLayoutData<T>::isDefined() const
{
return m_isdefined;
}
template <class T>
inline void BoxLayoutData<T>::setVector(const BoxLayoutData<T>& da,
const Interval& srcComps,
const Interval& destComps)
{
if(&da != this)
{
for(DataIterator it(this->dataIterator()); it.ok(); ++it)
{
this->m_vector[this->m_boxLayout.index(it())]->copy( this->box(it()), destComps,
this->box(it()), da[it()], srcComps);
}
}
}
template<class T>
inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
const DataFactory<T>& factory)
{
if(this == &da){
MayDay::Error("BoxLayoutData<T>::define(const LayoutData<T>& da,.....) called with 'this'");
}
assert(comps.size()>0);
assert(comps.end()<=m_comps);
assert(comps.begin()>=0);
this->m_boxLayout = da.boxLayout();
m_comps = comps.size();
Interval dest(0, m_comps-1);
allocateGhostVector(factory);
setVector(da, comps, dest);
}
template<class T>
inline void BoxLayoutData<T>::define(const BoxLayout& boxes, int comps,
const DataFactory<T>& factory)
{
assert(boxes.isClosed());
this->m_boxLayout = boxes;
m_comps = comps;
m_isdefined = true;
allocateGhostVector(factory);
}
template<class T>
inline void BoxLayoutData<T>::define(const BoxLayout& boxes)
{
MayDay::Error("BoxLayoutData<T>::define(const BoxLayout& boxes)...needs comps");
}
template<class T>
inline BoxLayoutData<T>::BoxLayoutData(const BoxLayout& boxes, int comps,
const DataFactory<T>& factory)
:m_comps(comps)
{
assert(boxes.isClosed());
this->m_boxLayout = boxes;
m_isdefined = true;
allocateGhostVector(factory);
}
template<class T>
inline void BoxLayoutData<T>::define(const BoxLayoutData<T>& da,
const DataFactory<T>& factory)
{
if(this != &da){
m_isdefined = da.m_isdefined;
this->m_boxLayout = da.boxLayout();
m_comps = da.nComp();
Interval srcAnddest(0, m_comps-1);
allocateGhostVector(factory);
setVector(da, srcAnddest, srcAnddest);
}
}
template<class T>
inline void BoxLayoutData<T>::allocateGhostVector(const DataFactory<T>& factory, const IntVect& ghost)
{
for(unsigned int i=0; i<this->m_vector.size(); ++i)
{
delete this->m_vector[i];
this->m_vector[i] = NULL;
}
this->m_vector.resize(this->m_boxLayout.size(), NULL);
for(DataIterator it(this->dataIterator()); it.ok(); ++it)
{
unsigned int index = this->m_boxLayout.index(it());
Box abox = this->box(it());
abox.grow(ghost);
this->m_vector[index] = factory.create(abox, m_comps, it());
if(this->m_vector[index] == NULL)
{
MayDay::Error("OutOfMemory in boxlayoutdata::allocate");
}
}
}
template<class T>
inline void BoxLayoutData<T>::apply(void (*a_func)(const Box& box, int comps, T& t))
{
for(DataIterator it(this->dataIterator()); it.ok(); ++it)
{
unsigned int index = this->m_boxLayout.index(it());
a_func(this->box(it()), m_comps, *(this->m_vector[index]));
}
}
//======================================================================
template <class T>
AliasDataFactory<T>::AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval)
{
define(a_original, interval);
}
template <class T>
void AliasDataFactory<T>::define(BoxLayoutData<T>* a_original, const Interval& interval)
{
m_origPointer = a_original;
m_interval = interval;
}
template <class T>
T* AliasDataFactory<T>::create(const Box& box, int ncomps, const DataIndex& a_datInd) const
{
assert(this->box() == box);
assert(ncomps = m_interval.size());
T* rtn = new T(m_interval, m_origPointer->operator[](a_datInd));
return rtn;
}
#endif // BOXLAYOUTDATA_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -