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 <memory>
00012 #include <map>
00013 #include <assert.h>
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 #include "dgfexception.hh"
00023 #include "entitykey.hh"
00024 #include "dgfparserblocks.hh"
00025
00026 namespace Dune
00027 {
00028
00029 class DGFPrintInfo;
00030
00033 class DuneGridFormatParser
00034 {
00035 public:
00036 typedef enum {Simplex,Cube,General} element_t;
00037 typedef enum {counterclockwise=1,clockwise=-1} orientation_t;
00038
00040 DuneGridFormatParser ();
00041
00046 bool readDuneGrid( std :: istream &, int dimG = -1, int dimW = -1 );
00047
00049 void writeTetgenPoly ( std :: string &, std :: string & );
00050 void writeTetgenPoly ( std::ostream & );
00052 void writeAlu ( std :: ostream & );
00054 void writeAlberta ( std::ostream & );
00055
00056 protected:
00057
00058 int dimw, dimgrid;
00059
00060 std::vector < std::vector <double> > vtx;
00061 int nofvtx;
00062 int vtxoffset;
00063
00064 std :: vector< std :: vector< unsigned int > > elements;
00065 int nofelements;
00066
00067 std::vector < std::vector <int> > bound;
00068 int nofbound;
00069
00070 typedef std :: map< DGFEntityKey< unsigned int >, int > facemap_t;
00071 facemap_t facemap;
00072
00073 element_t element;
00074
00075
00076 bool simplexgrid;
00077
00078 bool cube2simplex;
00079
00080 int nofvtxparams,nofelparams;
00081 std::vector<std::vector<double> > vtxParams,elParams;
00082
00083 DGFPrintInfo* info;
00084
00085 void generateBoundaries ( std::istream &, bool );
00086
00087
00088 void generateSimplexGrid ( std::istream & );
00089 void readTetgenTriangle ( const std :: string & );
00090
00091
00092 void removeCopies ();
00093 void setOrientation ( int use1, int use2,
00094 orientation_t orientation=counterclockwise );
00095 void setRefinement ( int use1, int use2, int is1=-1, int is2=-1 );
00096 double testTriang ( int snr );
00097
00098 std :: vector< double > &getElParam ( int i, std::vector< double > &coord );
00099 std :: vector< double > &getVtxParam ( int i, std::vector< double > &coord );
00100 };
00101
00102
00103 class MacroGrid : protected DuneGridFormatParser
00104 {
00105 public:
00106 typedef MPIHelper::MPICommunicator MPICommunicatorType;
00107
00108 protected:
00110 MacroGrid(const char* filename, MPICommunicatorType MPICOMM = MPIHelper::getCommunicator())
00111 : DuneGridFormatParser()
00112 , filename_(filename)
00113 , MPICOMM_(MPICOMM) {}
00114
00116 MacroGrid()
00117 : DuneGridFormatParser()
00118 , filename_(0)
00119 , MPICOMM_(MPIHelper::getCommunicator()) {}
00120
00122 template <class GridType>
00123 inline GridType * createGrid () {
00124 return Impl<GridType>::generate(*this,filename_,MPICOMM_);
00125 }
00126 private:
00138 template< class GridType >
00139 class Impl;
00140
00141 const char* filename_;
00142 MPICommunicatorType MPICOMM_;
00143 };
00144
00157 template <class GridType>
00158 class GridPtr : public MacroGrid {
00159
00160
00161
00162
00163 public:
00164 typedef MPIHelper::MPICommunicator MPICommunicatorType;
00166 GridPtr(const std::string filename, MPICommunicatorType MPICOMM = MPIHelper::getCommunicator()) :
00167 MacroGrid(filename.c_str(),MPICOMM),
00168 gridptr_(this->template createGrid<GridType>()),
00169 emptyParam(),
00170 elParam(0), vtxParam(0), nofElParam_(0), nofVtxParam_(0) {
00171 if (nofelparams>0) {
00172 nofElParam_ = nofelparams;
00173 for (size_t i=0;i<elements.size();i++) {
00174 std::vector<double> coord;
00175 DomainType p (0);
00176 std::vector<double>& param = this->getElParam(i,coord);
00177 for (int k=0;k<dimw;k++)
00178 p[k] = coord[k];
00179 elParam.push_back(make_pair(p,param));
00180 }
00181 }
00182 if (nofvtxparams>0) {
00183 nofVtxParam_ = nofvtxparams;
00184 for (size_t i=0;i<vtx.size();i++) {
00185 std::vector<double> coord;
00186 DomainType p (0);
00187 std::vector<double>& param = getVtxParam(i,coord);
00188 for (int k=0;k<dimw;k++)
00189 p[k] = coord[k];
00190 vtxParam.push_back(make_pair(p,param));
00191 }
00192 }
00193 }
00194
00196 GridPtr() : MacroGrid() , gridptr_() ,
00197 emptyParam(), elParam(0), vtxParam(0),
00198 nofElParam_(0), nofVtxParam_(0) {}
00199
00201 GridPtr(GridType * grd) : MacroGrid() , gridptr_(grd),
00202 emptyParam(), elParam(0), vtxParam(0),
00203 nofElParam_(0), nofVtxParam_(0) {}
00204
00206 GridPtr(const GridPtr & org) : gridptr_(org.gridptr_),
00207 emptyParam(),
00208 elParam(org.elParam), vtxParam(org.vtxParam),
00209 nofElParam_(org.nofElParam_),
00210 nofVtxParam_(org.nofVtxParam_) {}
00211
00213 GridType& operator*() {
00214 return *gridptr_;
00215 }
00217 GridType* operator->() {
00218 return gridptr_.operator -> ();
00219 }
00220
00222 const GridType& operator*() const {
00223 return *gridptr_;
00224 }
00225
00227 const GridType* operator->() const {
00228 return gridptr_.operator -> ();
00229 }
00230
00232 GridType* release () {
00233 return gridptr_.release();
00234 }
00235
00237 GridPtr & operator = (const GridPtr & org)
00238 {
00239 gridptr_ = org.gridptr_;
00240 elParam = org.elParam;
00241 vtxParam = org.vtxParam;
00242 nofVtxParam_ = org.nofVtxParam_;
00243 nofElParam_ = org.nofElParam_;
00244 return *this;
00245 }
00246
00248 GridPtr & operator = (GridType * grd)
00249 {
00250 gridptr_ = std::auto_ptr<GridType>(grd);
00251 return *this;
00252 }
00254 int nofParameters(int cdim) {
00255 switch (cdim) {
00256 case 0: return nofElParam_; break;
00257 case GridType::dimension: return nofVtxParam_; break;
00258 }
00259 return 0;
00260 }
00262 template <class Entity>
00263 std::vector<double>& parameters(const Entity& en) {
00264 if (Entity::codimension==0) {
00265 if (elParam.size()==0)
00266 return emptyParam;
00267 DomainType coord(0);
00268 typedef typename Entity::Geometry GeometryType;
00269 const GeometryType& geo=en.geometry();
00270 for (int i=0;i<geo.corners();++i)
00271 coord += geo[i];
00272 coord/=double(geo.corners());
00273 return elementParams(coord);
00274 } else if (int(Entity::codimension) == int(GridType::dimension)) {
00275 if (vtxParam.size()==0)
00276 return emptyParam;
00277 DomainType coord;
00278 typedef typename Entity::Geometry GeometryType;
00279 const GeometryType& geo=en.geometry();
00280 coord = geo[0];
00281 return vertexParams(coord);
00282 } else {
00283 return emptyParam;
00284 }
00285 }
00286 protected:
00287 typedef FieldVector<typename GridType::ctype,GridType::dimensionworld> DomainType;
00288 inline std::vector<double>& elementParams(DomainType& coord) {
00289 int idx=0;
00290 double min=1e10;
00291 for (size_t i=0;i<elParam.size();++i) {
00292 DomainType p(coord);
00293 p -= elParam[i].first;
00294 double len=p.two_norm();
00295 if (min>len) {
00296 min=len;
00297 idx=i;
00298 }
00299 }
00300 if (idx<0)
00301 return emptyParam;
00302 else
00303 return elParam[idx].second;
00304 }
00305 inline std::vector<double>& vertexParams(DomainType& coord) {
00306 int idx=0;
00307 double min=1e10;
00308 for (size_t i=0;i<vtxParam.size();++i) {
00309 DomainType p(coord);
00310 p -= vtxParam[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 vtxParam[idx].second;
00321 }
00322
00323 mutable std::auto_ptr<GridType> gridptr_;
00324 std::vector<double> emptyParam;
00325
00326 std::vector<std::pair<DomainType,std::vector<double> > > elParam,vtxParam;
00327 int nofElParam_,nofVtxParam_;
00328 };
00329
00330 }
00331
00950
00951
00952
00953
00954
00955
00956
00957
00958 namespace Dune {
00959
00962 template <class GridType>
00963 struct DGFGridInfo
00964 {
00966 static int refineStepsForHalf();
00969 static double refineWeight();
00970 };
00971
00972 }
00973 #endif