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
00016 #include <dune/common/mpihelper.hh>
00017 #include <dune/grid/common/referenceelements.hh>
00018 #include <dune/common/stdstreams.hh>
00019
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
00070 int dimw;
00071
00072 std::vector < std::vector <double> > vtx;
00073 int nofvtx;
00074 int vtxoffset;
00075
00076 std::vector < std::vector <int> > elements;
00077 int nofelements;
00078
00079 std::vector < std::vector <int> > bound;
00080 int nofbound;
00081
00082 typedef std::map<EntityKey<int>,int> facemap_t;
00083 facemap_t facemap;
00084
00085 element_t element;
00086
00087
00088 bool simplexgrid;
00089
00090 bool cube2simplex;
00091
00092 int nofvtxparams,nofelparams;
00093 std::vector<std::vector<double> > vtxParams,elParams;
00094
00095 PrintInfo* info;
00096 inline void generateBoundaries(std::istream&,bool);
00097
00098 inline void generateSimplexGrid(std::istream&);
00099 inline void readTetgenTriangle(std::string);
00100
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
00177
00178
00179
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
00340 mutable std::auto_ptr<GridType> gridptr_;
00341 std::vector<double> emptyParam;
00342
00343 std::vector<std::pair<DomainType,std::vector<double> > > elParam,vtxParam;
00344 int nofElParam_,nofVtxParam_;
00345 };
00346 }
00347 #include "dgfparser.cc"
00348
00956
00957
00958
00959
00960
00961
00962
00963
00966 namespace Dune {
00967 template <class GridType>
00968 struct DGFGridInfo {
00970 static int refineStepsForHalf();
00973 static double refineWeight();
00974 };
00975
00976 }
00977 #endif