⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boxlayoutdata.h

📁 自适应网格划分通用程序包
💻 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 + -