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
00017 #include <dune/common/mpihelper.hh>
00018 #include <dune/grid/common/referenceelements.hh>
00019 #include <dune/common/stdstreams.hh>
00020
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
00071 int dimw;
00072
00073 std::vector < std::vector <double> > vtx;
00074 int nofvtx;
00075 int vtxoffset;
00076
00077 std::vector < std::vector <int> > elements;
00078 int nofelements;
00079
00080 std::vector < std::vector <int> > bound;
00081 int nofbound;
00082
00083 typedef std::map<DGFEntityKey<int>,int> facemap_t;
00084 facemap_t facemap;
00085
00086 element_t element;
00087
00088
00089 bool simplexgrid;
00090
00091 bool cube2simplex;
00092
00093 int nofvtxparams,nofelparams;
00094 std::vector<std::vector<double> > vtxParams,elParams;
00095
00096 DGFPrintInfo* info;
00097 inline void generateBoundaries(std::istream&,bool);
00098
00099 inline void generateSimplexGrid(std::istream&);
00100 inline void readTetgenTriangle(std::string);
00101
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
00178
00179
00180
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
00341 mutable std::auto_ptr<GridType> gridptr_;
00342 std::vector<double> emptyParam;
00343
00344 std::vector<std::pair<DomainType,std::vector<double> > > elParam,vtxParam;
00345 int nofElParam_,nofVtxParam_;
00346 };
00347 }
00348 #include "dgfparser.cc"
00349
00968
00969
00970
00971
00972
00973
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 }
00991 #endif