dgfparser/dgfparser.hh

00001 #ifndef DUNE_MACROGRIDPARSER_HH
00002 #define DUNE_MACROGRIDPARSER_HH
00003 
00004 #include <iostream>
00005 #include <fstream>
00006 
00007 #include <sstream>
00008 #include <string>
00009 #include <cstring>
00010 #include <vector>
00011 #include <map>
00012 #include <cassert>
00013 #include <memory>
00014 #include <cmath>
00015 
00016 //- Dune includes 
00017 #include <dune/common/mpihelper.hh>
00018 #include <dune/grid/common/referenceelements.hh>
00019 #include <dune/common/stdstreams.hh>
00020 //- local includes
00021 
00022 namespace Dune {
00024 class DGFException : public IOError {};
00025 };
00026 
00027 #include "entitykey.hh"
00028 #include "dgfparserblocks.hh"
00029 
00030 namespace Dune {
00033 
00034 class DGFPrintInfo;
00035 
00036 class DuneGridFormatParser {
00037  public:
00039   DuneGridFormatParser() :  
00040     dimw(-1),
00041     vtx(0), nofvtx(0), vtxoffset(0),
00042     elements(0) , nofelements(0),
00043     bound(0) , nofbound(0),
00044     facemap(),
00045     element(General),
00046     simplexgrid(false),
00047     cube2simplex(false),
00048     nofvtxparams(0),
00049     nofelparams(0),
00050     vtxParams(),
00051     elParams(),
00052     info(0)
00053   {}
00054 
00055   typedef enum {Simplex,Cube,General} element_t;
00056   typedef enum {counterclockwise=1,clockwise=-1} orientation_t;
00061   inline bool readDuneGrid(std::istream&);
00063   inline void writeTetgenPoly(std::string&,std::string&);
00064   inline void writeTetgenPoly(std::ostream&);
00066   inline void writeAlu(std::ostream&);
00068   inline void writeAlberta(std::ostream&);
00069  protected:
00070   // dimension of world and problem: set through the readDuneGrid() method
00071   int dimw;
00072   // vector of vertex coordinates
00073   std::vector < std::vector <double> > vtx;
00074   int nofvtx;
00075   int vtxoffset;
00076   // vector of elements
00077   std::vector < std::vector <int> > elements;
00078   int nofelements;
00079   // vector of boundary segments + identifier
00080   std::vector < std::vector <int> > bound;
00081   int nofbound;
00082   // map to generate and find boundary segments
00083   typedef std::map<DGFEntityKey<int>,int> facemap_t;
00084   facemap_t facemap;
00085   // set by generator depending on element type wanted
00086   element_t element;
00087   // set by the readDuneGrid method depending 
00088   // on what type the elements were generated
00089   bool simplexgrid;
00090   // true if grid is generated using the intervall Block
00091   bool cube2simplex;
00092   // parameters on elements
00093   int nofvtxparams,nofelparams;
00094   std::vector<std::vector<double> > vtxParams,elParams;
00095   // write information about generation process
00096   DGFPrintInfo* info;
00097   inline void generateBoundaries(std::istream&,bool);
00098   // call to tetgen/triangle
00099   inline void generateSimplexGrid(std::istream&);
00100   inline void readTetgenTriangle(std::string);
00101   // helper methods 
00102   inline void removeCopies();
00103   inline void setOrientation(int use1,int use2,orientation_t orientation=counterclockwise);
00104   inline void setRefinement(int use1,int use2,int is1=-1,int is2=-1);
00105   inline double testTriang(int snr);
00106   inline std::vector<double>& getElParam(int i,std::vector<double>& coord) {
00107     coord.resize(dimw);
00108     for (int j=0;j<dimw;j++) 
00109       coord[j]=0.;
00110     for (int j=0;j<dimw;j++) {
00111       for (size_t k=0;k<elements[i].size();++k) {
00112         coord[j]+=vtx[elements[i][k]][j];
00113       }
00114       coord[j]/=double(elements[i].size());
00115     }
00116     return elParams[i];
00117   }
00118   inline std::vector<double>& getVtxParam(int i,std::vector<double>& coord) {
00119     coord.resize(dimw);
00120     for (int j=0;j<dimw;j++) 
00121       coord[j]=0.;
00122     coord = vtx[i];
00123     return vtxParams[i];
00124   }
00125 };
00126 
00127 class MacroGrid : protected DuneGridFormatParser 
00128 {
00129 public:
00130   typedef MPIHelper::MPICommunicator MPICommunicatorType; 
00131   
00132 protected:  
00134   MacroGrid(const char* filename, MPICommunicatorType MPICOMM = MPIHelper::getCommunicator()) 
00135     : DuneGridFormatParser()
00136     , filename_(filename)
00137     , MPICOMM_(MPICOMM) {}
00138 
00140   MacroGrid() 
00141     : DuneGridFormatParser()
00142     , filename_(0)
00143     , MPICOMM_(MPIHelper::getCommunicator()) {}
00144     
00146   template <class GridType>
00147   inline GridType * createGrid () {
00148     return Impl<GridType>::generate(*this,filename_,MPICOMM_);
00149   }
00150 private:
00153   template <class GT>
00154   class Impl {
00155     typedef MPIHelper::MPICommunicator MPICommunicatorType;
00156   public:
00157     static GT* generate(MacroGrid& mg,const char* filename, MPICommunicatorType MPICOMM = MPIHelper::getCommunicator() );
00158   };
00159   const char* filename_;
00160   MPICommunicatorType MPICOMM_;
00161 };
00162 
00175 template <class GridType>
00176 class GridPtr : public MacroGrid {
00177   // make operator new and delete private, because this class is only a
00178   // pointer 
00179   // void * operator new (size_t); 
00180   // void operator delete (void *);
00181 public:
00182   typedef MPIHelper::MPICommunicator MPICommunicatorType; 
00184   GridPtr(const std::string filename, MPICommunicatorType MPICOMM = MPIHelper::getCommunicator()) : 
00185     MacroGrid(filename.c_str(),MPICOMM),
00186     gridptr_(this->template createGrid<GridType>()),
00187     emptyParam(),
00188     elParam(0), vtxParam(0), nofElParam_(0), nofVtxParam_(0) {
00189     if (nofelparams>0) {
00190       nofElParam_ = nofelparams;
00191       for (size_t i=0;i<elements.size();i++) {
00192         std::vector<double> coord;
00193         DomainType p (0);
00194         std::vector<double>& param = this->getElParam(i,coord);
00195         for (int k=0;k<dimw;k++) 
00196           p[k] = coord[k];
00197         elParam.push_back(make_pair(p,param));
00198       }
00199     }
00200     if (nofvtxparams>0) {
00201       nofVtxParam_ = nofvtxparams;
00202       for (size_t i=0;i<vtx.size();i++) {
00203         std::vector<double> coord;
00204         DomainType p (0);
00205         std::vector<double>& param = getVtxParam(i,coord);
00206         for (int k=0;k<dimw;k++) 
00207           p[k] = coord[k];
00208         vtxParam.push_back(make_pair(p,param));
00209       }
00210     }
00211   }
00212 
00214   GridPtr() : MacroGrid() , gridptr_() ,
00215               emptyParam(), elParam(0), vtxParam(0), 
00216               nofElParam_(0), nofVtxParam_(0) {}
00217 
00219   GridPtr(GridType * grd) : MacroGrid() , gridptr_(grd),
00220                             emptyParam(), elParam(0), vtxParam(0),  
00221                             nofElParam_(0), nofVtxParam_(0) {}
00222 
00224   GridPtr(const GridPtr & org) : gridptr_(org.gridptr_),
00225                                  emptyParam(), 
00226                                  elParam(org.elParam), vtxParam(org.vtxParam), 
00227                                  nofElParam_(org.nofElParam_), 
00228                                  nofVtxParam_(org.nofVtxParam_) {}
00229 
00231   GridType& operator*() {
00232     return *gridptr_;
00233   }
00235   GridType* operator->() {
00236     return gridptr_.operator -> ();
00237   }
00238 
00240   const GridType& operator*() const {
00241     return *gridptr_;
00242   }
00243   
00245   const GridType* operator->() const {
00246     return gridptr_.operator -> ();
00247   }
00248   
00250   GridType* release () {
00251     return gridptr_.release();
00252   }
00253 
00255   GridPtr & operator = (const GridPtr & org)
00256   {
00257     gridptr_ = org.gridptr_;
00258     elParam = org.elParam;
00259     vtxParam = org.vtxParam; 
00260     nofVtxParam_ = org.nofVtxParam_; 
00261     nofElParam_ = org.nofElParam_;
00262     return *this;
00263   }
00264   
00266   GridPtr & operator = (GridType * grd)
00267   {
00268     gridptr_ = std::auto_ptr<GridType>(grd);
00269     return *this;
00270   }
00272   int nofParameters(int cdim) {
00273     switch (cdim) {
00274     case 0: return nofElParam_; break;
00275     case GridType::dimension: return nofVtxParam_; break;
00276     }
00277     return 0;
00278   }
00280   template <class Entity>
00281   std::vector<double>& parameters(const Entity& en) {
00282     if (Entity::codimension==0) {
00283       if (elParam.size()==0) 
00284         return emptyParam;
00285       DomainType coord(0);
00286       typedef typename Entity::Geometry GeometryType;
00287       const GeometryType& geo=en.geometry();
00288       for (int i=0;i<geo.corners();++i) 
00289         coord += geo[i];
00290       coord/=double(geo.corners());
00291       return elementParams(coord);
00292     } else if (int(Entity::codimension) == int(GridType::dimension)) {
00293       if (vtxParam.size()==0) 
00294         return emptyParam;
00295       DomainType coord;
00296       typedef typename Entity::Geometry GeometryType;
00297       const GeometryType& geo=en.geometry();
00298       coord = geo[0];
00299       return vertexParams(coord);
00300     } else {
00301       return emptyParam;
00302     }
00303   }
00304 protected:
00305   typedef FieldVector<typename GridType::ctype,GridType::dimensionworld> DomainType;
00306   inline std::vector<double>& elementParams(DomainType& coord) {
00307     int idx=0;
00308     double min=1e10;
00309     for (size_t i=0;i<elParam.size();++i) {
00310       DomainType p(coord);
00311       p -= elParam[i].first;
00312       double len=p.two_norm();
00313       if (min>len) {
00314         min=len;
00315         idx=i;
00316       }
00317     }
00318     if (idx<0)
00319       return emptyParam;
00320     else
00321       return elParam[idx].second;
00322   }
00323   inline std::vector<double>& vertexParams(DomainType& coord) {
00324     int idx=0;
00325     double min=1e10;
00326     for (size_t i=0;i<vtxParam.size();++i) {
00327       DomainType p(coord);
00328       p -= vtxParam[i].first;
00329       double len=p.two_norm();
00330       if (min>len) {
00331         min=len;
00332         idx=i;
00333       }
00334     }
00335     if (idx<0)
00336       return emptyParam;
00337     else
00338       return vtxParam[idx].second;
00339   }
00340   // grid auto pointer
00341   mutable std::auto_ptr<GridType> gridptr_;
00342   std::vector<double> emptyParam;
00343   // element and vertex parameters
00344   std::vector<std::pair<DomainType,std::vector<double> > > elParam,vtxParam;
00345   int nofElParam_,nofVtxParam_;
00346 }; // end of class GridPtr
00347 }
00348 #include "dgfparser.cc"
00349 
00968 /*
00969       Dune::Alberta with \c dimworld=3: \n
00970         if Tetgen is used to construct a 
00971         tetrahedral grid for Dune::Alberta then the bisection routine does
00972         not necessarily terminate. This problem does not occur
00973         if the grid is constructed using the \b Interval block. 
00974 */
00975 
00976 namespace Dune {
00977 
00980 template <class GridType>
00981 struct DGFGridInfo 
00982 {
00984   static int refineStepsForHalf();
00987   static double refineWeight();
00988 };
00989 
00990 } // end namespace Dune 
00991 #endif

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].