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

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)