00001 #ifndef DUNE_MACROGRIDPARSERBLOCKS_HH
00002 #define DUNE_MACROGRIDPARSERBLOCKS_HH
00003
00004 namespace Dune {
00005
00006
00007
00008
00009
00010 namespace {
00011
00012 inline void makeupcase(std::string &s)
00013 {
00014 for (size_t i=0;i<s.size();i++)
00015 s[i]=toupper(s[i]);
00016 }
00017
00018 class BasicBlock {
00019 int pos;
00020 bool active;
00021 bool empty;
00022 std::string identifier;
00023 int linecount;
00024 std::stringstream block;
00025 std::string oneline;
00026
00027 void getblock(std::istream &in) {
00028 std::string id;
00029 getline(in,id);
00030 while (in.good()) {
00031 std::stringstream idstream(id);
00032 std::string upcaseid;
00033 idstream >> upcaseid;
00034 makeupcase(upcaseid);
00035 if (upcaseid==identifier)
00036 {
00037 active=true;
00038 break;
00039 }
00040 getline(in,id);
00041 }
00042 if (active) {
00043 bool blockend=false;
00044 while (in.good()) {
00045 getline(in,oneline);
00046 if (oneline.size()==0)
00047 continue;
00048 std::stringstream onelinestream(oneline);
00049 std::string test;
00050 onelinestream >> test;
00051 if (test[0] == '#') {
00052 blockend=true;
00053 break;
00054 }
00055 empty=false;
00056 block << oneline << "\n";
00057 }
00058 if (!blockend) {
00059 DUNE_THROW(DGFException,
00060 "Error: block must end with a #-line");
00061 }
00062 }
00063 else {
00064
00065 }
00066 }
00067
00068 int countlines() {
00069 if (empty)
00070 return 0;
00071 int ret=0;
00072 while (1) {
00073 getnextline();
00074 if (oneline.size()==0)
00075 break;
00076 ret++;
00077 }
00078 return ret;
00079 }
00080 protected:
00081 std::stringstream line;
00082
00083
00084 void reset() {
00085 pos=-1;
00086 block.clear();
00087 block.seekg(0);
00088 linecount=countlines();
00089 pos=-1;
00090 block.clear();
00091 block.seekg(0);
00092 }
00093
00094 void getnextline() {
00095 line.clear();
00096 oneline.clear();
00097 getline(block,oneline);
00098 if (oneline.size()>0) {
00099 std::size_t comment=oneline.find("%");
00100 if (comment!=std::string::npos) {
00101 oneline.erase(comment);
00102 if (oneline.size()==0) {
00103 getnextline();
00104 return;
00105 }
00106 }
00107 }
00108 line.str(oneline);
00109 pos++;
00110 }
00111
00112 template <class ENTRY>
00113 bool getnextentry(ENTRY &entry) {
00114 line >> entry;
00115 return line;
00116 }
00117 bool gettokenparam(std::string token,std::string& entry) {
00118 makeupcase(token);
00119 std::string ltoken;
00120 reset();
00121 do {
00122 getnextline();
00123 if (oneline.size()==0)
00124 return false;
00125 line >> ltoken;
00126 makeupcase(ltoken);
00127 } while (ltoken!=token);
00128 getline(line,entry);
00129 return true;
00130 }
00131 bool findtoken(std::string token) {
00132 makeupcase(token);
00133 std::string ltoken;
00134 reset();
00135 do {
00136 getnextline();
00137 if (oneline.size()==0)
00138 return false;
00139 line >> ltoken;
00140 makeupcase(ltoken);
00141 } while (ltoken!=token);
00142 return true;
00143 }
00144 public:
00145
00146 BasicBlock(std::istream& in, const char* id) :
00147 pos(-1),
00148 active(false),
00149 empty(true),
00150 identifier(id),
00151 linecount(0)
00152 {
00153 makeupcase(identifier);
00154 in.clear();
00155 in.seekg(0);
00156 if (!in) {
00157 DUNE_THROW(DGFException,
00158 "file not found in BasicBlock::BasicBlock");
00159 }
00160 getblock(in);
00161 if (active && !empty) {
00162 linecount=countlines();
00163 reset();
00164 }
00165 in.clear();
00166 in.seekg(0);
00167 }
00168
00169 bool isactive() {
00170 return active;
00171 }
00172 bool isempty() {
00173 return empty;
00174 }
00175 int& noflines() {
00176 return linecount;
00177 }
00178 int linenumber() {
00179 return pos;
00180 }
00181
00182 friend std::ostream& operator<<(std::ostream& os, const BasicBlock &b) {
00183 return os
00184 << "block " << b.identifier
00185 << " on line " << b.pos << std::endl;
00186 }
00187 };
00188
00189
00190
00191 class VertexBlock : public BasicBlock {
00192 int dimworld;
00193 bool goodline;
00194 std::vector<double> p;
00195 int vtxoffset;
00196 int nofParam;
00197 std::vector<double> vtxparam;
00198 public:
00199 static const char* ID;
00200
00201 VertexBlock(std::istream& in,int &pdimworld) :
00202 BasicBlock(in,ID),
00203 dimworld(pdimworld),
00204 goodline(true),
00205 p(0),
00206 vtxoffset(0),
00207 nofParam(0),
00208 vtxparam(0)
00209 {
00210 if (!isactive())
00211 return;
00212 if (dimworld<0)
00213 dimworld=0;
00214 {
00215 int x;
00216 if (findtoken("firstindex")) {
00217 if (getnextentry(x)) {
00218 vtxoffset=x;
00219 }
00220 }
00221 }
00222 {
00223 int x;
00224 if (findtoken("parameters")) {
00225 if (getnextentry(x)) {
00226 nofParam=x;
00227 vtxparam.resize(nofParam);
00228 }
00229 }
00230 }
00231 dimworld=getDimW();
00232 if (dimworld>0) {
00233 p.resize(dimworld);
00234 } else {
00235 DUNE_THROW(DGFException,
00236 "ERROR in " << *this
00237 << " no line with enough entries found");
00238 }
00239 reset();
00240 next();
00241 pdimworld=dimworld;
00242 }
00243 ~VertexBlock() {
00244 }
00245 int offset() {
00246 return vtxoffset;
00247 }
00248 int get(std::vector<std::vector<double> >& vtx,
00249 std::vector<std::vector<double> >& param,int& nofp) {
00250 nofp=nofParam;
00251 size_t nofvtx;
00252 size_t old_size = vtx.size();
00253
00254 for (nofvtx=old_size;ok();next(),nofvtx++) {
00255 vtx.push_back(p);
00256 if (nofParam>0)
00257 param.push_back(vtxparam);
00258 }
00259 return nofvtx;
00260 }
00261
00262 bool ok() {
00263 return goodline;
00264 }
00265 private:
00266
00267 int getDimW() {
00268 reset();
00269 int dimworld=0;
00270 getnextline();
00271 while (dimworld<1 && linenumber()<noflines()) {
00272 dimworld = 0;
00273 double x;
00274 while (getnextentry(x)) {
00275 dimworld++;
00276 }
00277 dimworld-=nofParam;
00278 getnextline();
00279 }
00280 return dimworld;
00281 }
00282
00283 bool next() {
00284 assert(ok());
00285 int n=0;
00286 getnextline();
00287 if (linenumber()==noflines()) {
00288 goodline=false;
00289 return goodline;
00290 }
00291 double x;
00292 while (getnextentry(x)){
00293 if (n<dimworld)
00294 p[n]=x;
00295 else if (n-dimworld<nofParam) {
00296 vtxparam[n-dimworld]=x;
00297 }
00298 n++;
00299 }
00300 if (n>0 && n!=dimworld+nofParam) {
00301 return next();
00302
00303
00304
00305
00306
00307
00308 }
00309 if (n==0) {
00310 return next();
00311 }
00312 goodline=true;
00313 if (!goodline) {
00314 DUNE_THROW(DGFException,
00315 "ERROR in " << *this
00316 << " wrong number of coordinates: "
00317 << n << " read but expected " << dimworld);
00318 }
00319 return goodline;
00320 }
00321
00322 double operator[](int i) {
00323 assert(ok());
00324 assert(linenumber()>=0);
00325 assert(0<=i && i<dimworld);
00326 return p[i];
00327 }
00328 };
00329 const char *VertexBlock::ID = "Vertex";
00330
00331 class SimplexGenerationBlock : public BasicBlock {
00332 double area_;
00333 double angle_;
00334 bool display_;
00335 std::string path_;
00336 bool haspath_;
00337 std::string filename_;
00338 std::string filetype_;
00339 std::string parameter_;
00340 bool hasfile_;
00341 int dimension_;
00342 public:
00343 const static char* ID;
00344 SimplexGenerationBlock(std::istream& in) :
00345 BasicBlock(in,ID),
00346 area_(-1),
00347 angle_(-1),
00348 display_(false),
00349 haspath_(false),
00350 filetype_(),
00351 parameter_(),
00352 hasfile_(false),
00353 dimension_(-1)
00354 {
00355 double x;
00356 bool b;
00357 int i;
00358 std::string p;
00359 if (findtoken("max-area"))
00360 if (getnextentry(x))
00361 area_=x;
00362 if (findtoken("min-angle"))
00363 if (getnextentry(x))
00364 angle_=x;
00365 if (findtoken("display"))
00366 if (getnextentry(b))
00367 display_=b;
00368 if (findtoken("path"))
00369 if (getnextentry(p)) {
00370 path_=p;
00371 haspath_=true;
00372 }
00373 if (findtoken("file")) {
00374 if (getnextentry(p)) {
00375 filename_=p;
00376 hasfile_=true;
00377 }
00378 if (getnextentry(p)) {
00379 filetype_=p;
00380 }
00381 if (findtoken("dimension"))
00382 if (getnextentry(i)) {
00383 dimension_=i;
00384 }
00385 gettokenparam("parameter",parameter_);
00386 }
00387 }
00388 double maxArea() {
00389 return area_;
00390 }
00391 double minAngle() {
00392 return angle_;
00393 }
00394 bool display() {
00395 return display_;
00396 }
00397 bool haspath() {
00398 return haspath_;
00399 }
00400 std::string path() {
00401 return path_;
00402 }
00403 bool hasfile() {
00404 return hasfile_;
00405 }
00406 std::string filename() {
00407 return filename_;
00408 }
00409 std::string filetype() {
00410 return filetype_;
00411 }
00412 int dimension() {
00413 return dimension_;
00414 }
00415 std::string parameter() {
00416 return parameter_;
00417 }
00418 };
00419 const char* SimplexGenerationBlock::ID = "Simplexgenerator";
00420
00421 class SimplexBlock : public BasicBlock {
00422 int nofvtx;
00423 int vtxoffset;
00424 int dimworld;
00425 bool goodline;
00426 std::vector<int> p;
00427 int nofparams;
00428 std::vector<double> psimpl;
00429 public:
00430 const static char* ID;
00431 SimplexBlock(std::istream& in,int pnofvtx, int pvtxoffset, int adimworld) :
00432 BasicBlock(in,ID),
00433 nofvtx(pnofvtx),
00434 vtxoffset(pvtxoffset),
00435 dimworld(adimworld),
00436 goodline(true),
00437 p(adimworld+1),
00438 nofparams(0),
00439 psimpl(0)
00440 {
00441 if (!isactive()) return;
00442 assert((dimworld+1)>0);
00443 if (findtoken("parameters")) {
00444 int x=0;
00445 if (getnextentry(x)) {
00446 if (x>0) {
00447 nofparams = x;
00448 psimpl.resize(nofparams);
00449 }
00450 }
00451 if (x<=0) {
00452 DUNE_THROW(DGFException,
00453 "ERROR in " << *this
00454 << " parameter key found with no or non-positive value "
00455 << x);
00456 }
00457 }
00458 reset();
00459 next();
00460 }
00461 ~SimplexBlock() {
00462 }
00463 int get(std::vector<std::vector<int> >& simplex,
00464 std::vector<std::vector<double> >¶ms,int& nofp) {
00465 nofp=nofparams;
00466 int nofsimpl;
00467 for (nofsimpl=0; ok(); next(), nofsimpl++) {
00468 simplex.push_back(p);
00469 for (size_t j=0;j<p.size();j++) {
00470 simplex[nofsimpl][j] = p[j];
00471 }
00472 if (nofparams>0) {
00473 params.push_back(psimpl);
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 return nofsimpl;
00489 }
00490
00491 static int cube2simplex(std::vector<std::vector<double> >& vtx,
00492 std::vector<std::vector<int> >& elements,
00493 std::vector<std::vector<double> >& params) {
00494 static int offset3[6][4][3] = {{{0,0,0},{1,1,1},{1,0,0},{1,1,0}},
00495 {{0,0,0},{1,1,1},{1,0,1},{1,0,0}},
00496 {{0,0,0},{1,1,1},{0,0,1},{1,0,1}},
00497 {{0,0,0},{1,1,1},{1,1,0},{0,1,0}},
00498 {{0,0,0},{1,1,1},{0,1,0},{0,1,1}},
00499 {{0,0,0},{1,1,1},{0,1,1},{0,0,1}} };
00500 static int offset2[2][3][2] = {{{0,0},{1,0},{0,1}},
00501 {{1,1},{0,1},{1,0}}};
00502 if (vtx.size()==0)
00503 DUNE_THROW(DGFException, "Converting Cune- to Simplexgrid with no verticies given");
00504 int dimworld = vtx[0].size();
00505 dverb << "generating simplices...";
00506 dverb.flush();
00507 std::vector<std::vector<int> > cubes = elements;
00508 std::vector<std::vector<double> > cubeparams = params;
00509 if(dimworld == 3) {
00510 elements.resize(6*cubes.size());
00511 if (cubeparams.size()>0)
00512 params.resize(6*cubes.size());
00513 for(size_t countsimpl=0;countsimpl < elements.size(); countsimpl++)
00514 elements[countsimpl].resize(4);
00515 for (size_t c=0;c<cubes.size();c++) {
00516 for(int tetra=0; tetra < 6 ; tetra++) {
00517 for (int v=0;v<4;v++) {
00518 elements[c*6+tetra][v]=
00519 cubes[c][offset3[tetra][v][0]+
00520 offset3[tetra][v][1]*2+
00521 offset3[tetra][v][2]*4];
00522 }
00523 if (cubeparams.size()>0)
00524 params[c*6+tetra] = cubeparams[c];
00525 }
00526 }
00527 }
00528 else {
00529 elements.resize(2*cubes.size() );
00530 if (cubeparams.size()>0)
00531 params.resize(2*cubes.size());
00532 for(size_t countsimpl=0;countsimpl < elements.size(); countsimpl++)
00533 elements[countsimpl].resize(3);
00534 for (size_t c=0;c<cubes.size();c++) {
00535 int diag = 0;
00536 double mind = 0;
00537 for (int d=0;d<2;d++) {
00538 double diaglen =
00539 pow(vtx[cubes[c][d]][0]-vtx[cubes[c][2+((d+1)%2)]][0],2) +
00540 pow(vtx[cubes[c][d]][1]-vtx[cubes[c][2+((d+1)%2)]][1],2);
00541 if (diaglen<mind) {
00542 mind=diaglen;
00543 diag = d;
00544 }
00545 }
00546
00547 if (diag == 0) {
00548 int tmp0 = cubes[c][0];
00549 cubes[c][0] = cubes[c][1];
00550 cubes[c][1] = cubes[c][3];
00551 cubes[c][3] = cubes[c][2];
00552 cubes[c][2] = tmp0;
00553 }
00554 for(int tetra=0; tetra < 2 ; tetra++) {
00555 for (int v=0;v<3;v++) {
00556 elements[c*2+tetra][v]=
00557 cubes[c][offset2[tetra][v][0]+
00558 offset2[tetra][v][1]*2];
00559 }
00560 if (cubeparams.size()>0)
00561 params[c*2+tetra] = cubeparams[c];
00562 }
00563 }
00564 }
00565 return elements.size();
00566 }
00567
00568 bool ok() {
00569 return goodline;
00570 }
00571 int nofsimplex() {
00572 return noflines();
00573 }
00574 private:
00575
00576 bool next() {
00577 assert(ok());
00578 int n=0;
00579 getnextline();
00580 if (linenumber()==noflines()) {
00581 goodline=false;
00582 return goodline;
00583 }
00584 double x;
00585 while (getnextentry(x)){
00586 if (n<(int)p.size()) {
00587 p[n]=int(x)-vtxoffset;
00588 if (p[n]<0 || p[n]>=nofvtx) {
00589 DUNE_THROW(DGFException,
00590 "ERROR in " << *this
00591 << " wrong index of vertices: "
00592 << x << " read but expected value between "
00593 << vtxoffset << " and "
00594 << nofvtx+vtxoffset);
00595 }
00596 }
00597 else if (n-int(p.size())<nofparams) {
00598 psimpl[n-p.size()]=x;
00599 }
00600 n++;
00601 }
00602
00603 if (n!=(int)p.size()+nofparams) {
00604 return next();
00605 }
00606
00607 goodline=(n==(int)p.size()+nofparams);
00608 return goodline;
00609 }
00610
00611 int operator[](int i) {
00612 assert(ok());
00613 assert(linenumber()>=0);
00614 assert(0<=i && i<(dimworld+1));
00615 return p[i];
00616 }
00617 };
00618 const char* SimplexBlock::ID = "Simplex";
00620 class CubeBlock : public BasicBlock {
00621 int nofvtx;
00622 int dimworld;
00623 bool goodline;
00624 std::vector<int> p;
00625 std::vector<int> map;
00626 int nofparams;
00627 int vtxoffset;
00628 std::vector<double> psimpl;
00629 public:
00630 static const char* ID;
00631 CubeBlock(std::istream& in,int pnofvtx, int pvtxoffset, int adimworld) :
00632 BasicBlock(in,ID),
00633 nofvtx(pnofvtx),
00634 dimworld(adimworld),
00635 goodline(true),
00636 p(0),
00637 map(0),
00638 nofparams(0),
00639 vtxoffset(pvtxoffset),
00640 psimpl(0)
00641 {
00642 if (!isactive()) return;
00643 assert((dimworld+1)>0);
00644 p.resize(1<<dimworld);
00645 map.resize(1<<dimworld);
00646 int x;
00647 if (findtoken("map")) {
00648 for (size_t i=0;i<map.size();i++) {
00649 if (getnextentry(x)) {
00650 map[i]=x;
00651 } else {
00652 DUNE_THROW(DGFException,
00653 "ERROR in " << *this
00654 << " reference maping not complete "
00655 << i
00656 << " entries read but expected "
00657 << map.size());
00658 }
00659 }
00660 } else {
00661 for (size_t i=0;i<map.size();i++) {
00662 map[i]=i;
00663 }
00664 }
00665 if (findtoken("parameters")) {
00666 int x=0;
00667 if (getnextentry(x)) {
00668 if (x>0) {
00669 nofparams = x;
00670 psimpl.resize(nofparams);
00671 }
00672 }
00673 if (x<=0){
00674 DUNE_THROW(DGFException,
00675 "ERROR in " << *this
00676 << " parameter key found with no or non-positive value "
00677 << x);
00678 }
00679 }
00680 reset();
00681 next();
00682 }
00683 ~CubeBlock() {
00684 }
00685 int get(std::vector<std::vector<int> >& simplex,
00686 std::vector<std::vector<double> >¶ms,int& nofp) {
00687 nofp=nofparams;
00688 int nofsimpl;
00689
00690 for (nofsimpl=0; ok(); next(), nofsimpl++) {
00691 simplex.push_back(p);
00692 for (size_t j=0;j<p.size();j++) {
00693 simplex[nofsimpl][map[j]] = p[j];
00694 }
00695 if (nofparams>0) {
00696 params.push_back(psimpl);
00697 }
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 return nofsimpl;
00713 }
00714
00715 bool ok() {
00716 return goodline;
00717 }
00718 int nofsimplex() {
00719 return noflines();
00720 }
00721 private:
00722
00723 bool next() {
00724 assert(ok());
00725 int n=0;
00726 getnextline();
00727 if (linenumber()==noflines()) {
00728 goodline=false;
00729 return goodline;
00730 }
00731 double x;
00732 while (getnextentry(x))
00733 {
00734 if (n<(int)p.size())
00735 {
00736 p[n]=int(x)-vtxoffset;
00737 if (p[n]<0 || p[n]>=nofvtx)
00738 {
00739 DUNE_THROW(DGFException,
00740 "ERROR in " << *this
00741 << " wrong index of vertices: "
00742 << x << " read but expected value between "
00743 << vtxoffset << " and "
00744 << nofvtx+vtxoffset);
00745 }
00746 } else if (n-int(p.size())<nofparams) {
00747 psimpl[n-p.size()]=x;
00748 }
00749 n++;
00750 }
00751
00752 if (n!=(int)p.size()+nofparams) {
00753 return next();
00754 }
00755 goodline=(n==(int)p.size()+nofparams);
00756 return goodline;
00757 }
00758
00759 int operator[](int i) {
00760 assert(ok());
00761 assert(linenumber()>=0);
00762 assert(0<=i && i< (int)p.size());
00763 return p[i];
00764 }
00765 };
00766 const char* CubeBlock::ID = "Cube";
00767
00768
00769 class BoundaryDomBlock : public BasicBlock {
00770 int dimworld;
00771 bool goodline;
00772 std::vector<double> p1,p2;
00773 int bndid;
00774 bool withdefault;
00775 int defaultvalue;
00776 public:
00777 static const char* ID;
00778
00779 BoundaryDomBlock(std::istream& in,int cdimworld ) :
00780 BasicBlock(in,ID),
00781 dimworld(cdimworld),
00782 goodline(true),
00783 p1(cdimworld),
00784 p2(cdimworld),
00785 bndid(0),
00786 withdefault(false),
00787 defaultvalue(0)
00788 {
00789 if (!isactive())
00790 return;
00791 assert(cdimworld>0);
00792 {
00793 int x;
00794 if (findtoken("default"))
00795 if (getnextentry(x)) {
00796 defaultvalue=x;
00797 if( x <= 0 )
00798 {
00799 DUNE_THROW(DGFException,
00800 "ERROR in " << *this
00801 << " non-positive boundary id (" << x << ") read!");
00802 }
00803
00804 withdefault = true;
00805 }
00806 }
00807 reset();
00808 next();
00809 }
00810 ~BoundaryDomBlock() {
00811 }
00812 bool next() {
00813 assert(ok());
00814 getnextline();
00815 if (linenumber()==noflines()) {
00816 goodline=false;
00817 return goodline;
00818 }
00819 int id;
00820 if (getnextentry(id))
00821 {
00822 if( id <= 0 )
00823 {
00824 DUNE_THROW(DGFException,
00825 "ERROR in " << *this
00826 << " non-positive boundary id (" << id << ") read!");
00827 }
00828 bndid = id;
00829 double x;
00830 int n=0;
00831 while (getnextentry(x)){
00832 if (0<=n && n<dimworld)
00833 p1.at(n)=x;
00834 else if (dimworld<=n && n<2*dimworld) {
00835 p2.at(n-dimworld)=x;
00836 if (p2.at(n-dimworld)<p1.at(n-dimworld)) {
00837 DUNE_THROW(DGFException,
00838 "ERROR in " << *this
00839 << " second coordinate smaller than first coordinate: "
00840 << p2.at(n-dimworld)
00841 << " read but expected value larger or equal to "
00842 << p1.at(n-dimworld));
00843 }
00844 }
00845 n++;
00846 }
00847 goodline=(n==dimworld*2);
00848 if (!goodline) {
00849 DUNE_THROW(DGFException,
00850 "ERROR in " << *this
00851 << " wrong number of coordinates: "
00852 << n << " read but expected " << dimworld);
00853 }
00854 }
00855 else
00856 next();
00857 return goodline;
00858 }
00859 bool inside(const std::vector<double>& v) const {
00860 assert(v.size()==(size_t)dimworld);
00861 for (int i=0;i<dimworld;i++)
00862 if (v[i]<p1[i] || v[i]>p2[i])
00863 return false;
00864 return true;
00865 }
00866 int id() const {
00867 return bndid;
00868 }
00869 bool defaultValueGiven() {
00870 return withdefault;
00871 }
00872 int defaultValue() {
00873 return defaultvalue;
00874 }
00875
00876 bool ok() {
00877 return goodline;
00878 }
00879 int nofdombound() {
00880 return noflines();
00881 }
00882
00883 };
00884 const char *BoundaryDomBlock::ID = "boundarydomain";
00885
00886
00887 class BoundarySegBlock : public BasicBlock {
00888 int dimworld;
00889 bool goodline;
00890 std::vector<int> p;
00891 int bndid;
00892 bool simplexgrid;
00893 public:
00894 static const char* ID;
00895
00896 BoundarySegBlock(std::istream& in,int pnofvtx,
00897 int pdimworld,bool psimplexgrid ) :
00898 BasicBlock(in,ID),
00899 dimworld(pdimworld),
00900 goodline(true),
00901 p(),
00902 bndid(-1),
00903 simplexgrid(psimplexgrid)
00904 {
00905 if (!isactive())
00906 return;
00907 assert(dimworld>0);
00908 next();
00909 }
00910
00911 ~BoundarySegBlock() {
00912 }
00913
00914
00915 int get(std::map<EntityKey<int>,int>& facemap,bool fixedsize,int vtxoffset) {
00916 static int cube2simplex[3][3] = {
00917 {0,1,3},
00918 {0,2,3},
00919 {1,2,3}
00920 };
00921
00922 int lnofbound;
00923 int face = ElementFaceUtil::faceSize(dimworld,simplexgrid);
00924 for (lnofbound=0; ok(); next())
00925 {
00926 for (size_t i=0;i<p.size();i++)
00927 {
00928 p[i] -= vtxoffset;
00929 }
00930
00931 if (fixedsize)
00932 {
00933 if ((dimworld==2 && size()<=2) ||
00934 (dimworld==3 && simplexgrid && size()!=3 && size()!=4) ||
00935 (dimworld==3 && !simplexgrid && size()!=4))
00936 continue;
00937 std::vector<int> bound(face);
00938 for (int j=0;j<face;j++) {
00939 bound[j] = p[j];
00940 }
00941
00942 EntityKey<int> key(bound,false);
00943
00944 facemap[key] = bndid;
00945 ++lnofbound;
00946
00947 if (size()>face)
00948 {
00949 assert(dimworld==2 || face==3);
00950 if (dimworld==3) {
00951 for (int i=0; i<3;i++)
00952 {
00953 for (int j=0;j<face;j++)
00954 {
00955 bound[j] = p[cube2simplex[i][j]];
00956 }
00957
00958 EntityKey<int> key(bound,false);
00959 facemap[key] = bndid;
00960 ++lnofbound;
00961 }
00962 }
00963 else
00964 {
00965 for (int i=2; i<=size();i++)
00966 {
00967 bound[0] = p[i-1];
00968 bound[1] = p[i%size()];
00969 EntityKey<int> key(bound,false);
00970 facemap[key] = bndid;
00971 ++lnofbound;
00972 }
00973 }
00974 }
00975 }
00976 else {
00977 if (dimworld==3) {
00978 EntityKey<int> key(p,false);
00979 facemap[key] = bndid;
00980 ++lnofbound;
00981 } else {
00982 std::vector<int> k(2);
00983 for (size_t i=0;i<p.size()-1;i++) {
00984 k[0]=p[i];
00985 k[1]=p[(i+1)%p.size()];
00986 EntityKey<int> key(k,false);
00987 facemap[key] = bndid;
00988 ++lnofbound;
00989 }
00990 }
00991 }
00992 }
00993 return lnofbound;
00994 }
00995 bool ok() {
00996 return goodline;
00997 }
00998 int nofbound() {
00999 return noflines();
01000 }
01001 private:
01002 bool next() {
01003 assert(ok());
01004 int n=0;
01005 getnextline();
01006 if (linenumber()==noflines()) {
01007 goodline=false;
01008 return goodline;
01009 }
01010 p.clear();
01011 int x;
01012 if (getnextentry(x)) {
01013 bndid = x;
01014 if (bndid<=0) {
01015 DUNE_THROW(DGFException,
01016 "ERROR in " << *this
01017 << " non-positive boundary id read!");
01018 }
01019 while (getnextentry(x))
01020 {
01021 p.push_back(x);
01022 n++;
01023 }
01024
01025 goodline=true;
01026 return goodline;
01027 } else return next();
01028 }
01029
01030 int operator[](int i) {
01031 assert(ok());
01032 assert(linenumber()>=0);
01033 assert(0<=i && i<dimworld+1);
01034 return p[i];
01035 }
01036 int size() {
01037 return p.size();
01038 }
01039 };
01040 const char *BoundarySegBlock::ID = "boundarysegments";
01041
01042 class DimBlock : public BasicBlock {
01043 int _dimworld;
01044 int _dim;
01045 public:
01046 const static char* ID;
01047
01048 DimBlock(std::istream& in) :
01049 BasicBlock(in,ID)
01050 {
01051 if (isempty()) {
01052 DUNE_THROW(DGFException,
01053 "no dimension of world specified!");
01054 } else {
01055 getnextline();
01056 line >> _dim;
01057 if (_dim<1) {
01058 DUNE_THROW(DGFException,
01059 "negative dimension of world specified!");
01060 }
01061 else {
01062 if (noflines()==1)
01063 _dimworld=_dim;
01064 else {
01065 getnextline();
01066 line >> _dimworld;
01067 if (_dimworld < _dim) {
01068 DUNE_THROW(DGFException,
01069 "negative dimension of world smaller than dim!");
01070 }
01071 }
01072 }
01073 }
01074 }
01075
01076 int dim() {
01077 return _dim;
01078 }
01079 int dimworld() {
01080 return _dimworld;
01081 }
01082
01083 bool ok() {
01084 return true;
01085 }
01086 };
01087 const char* DimBlock::ID = "Dimensions";
01088
01089 class IntervalBlock : public BasicBlock {
01090 std::vector<double> p0_,p1_;
01091 std::vector<double> h_;
01092 std::vector<int> nofcells_;
01093 bool good_;
01094 int dimw_;
01095 public:
01096 const static char* ID;
01097 IntervalBlock(std::istream& in) :
01098 BasicBlock(in,ID),
01099 p0_(0),
01100 p1_(0),
01101 h_(0),
01102 nofcells_(0),
01103 good_(false),
01104 dimw_(0)
01105 {
01106 if(isactive()) {
01107 getnextline();
01108 double x;
01109 while (getnextentry(x)) {
01110 dimw_++;
01111 }
01112 if (dimw_==0) {
01113 DUNE_THROW(DGFException,
01114 "Too few coordinates for point p0 in IntervalBlock");
01115 }
01116 p0_.resize(dimw_);
01117 p1_.resize(dimw_);
01118 h_.resize(dimw_);
01119 nofcells_.resize(dimw_);
01120 reset();
01121 next();
01122 }
01123 }
01124 void get(std::vector<std::vector<double> >& vtx,int& nofvtx,
01125 std::vector<std::vector<int> >& simplex,int& nofsimpl) {
01126 do {
01127 int oldvtx = nofvtx;
01128 nofvtx +=getVtx(vtx);
01129 nofsimpl+=getHexa(simplex,oldvtx);
01130 } while (next());
01131 }
01132 void get(std::vector<std::vector<double> >& vtx,int& nofvtx) {
01133 do {
01134
01135 nofvtx +=getVtx(vtx);
01136 } while (next());
01137 }
01138 int getVtx(std::vector<std::vector<double> >& vtx) {
01139 size_t countvtx;
01140 size_t old_size = vtx.size();
01141
01142 dverb << "reading vertices...";
01143 vtx.resize(vtx.size()+nofvtx());
01144 for (countvtx=old_size;countvtx < vtx.size(); countvtx++)
01145 vtx[countvtx].resize(dimw_);
01146 int m = old_size;
01147 if(dimw_ == 3) {
01148 for(int i =0; i < nofcells_[0]+1; i++)
01149 for(int j=0; j < nofcells_[1]+1; j++)
01150 for(int k=0; k < nofcells_[2]+1; k++) {
01151 vtx[m][0] = p0_[0] + i*h_[0];
01152 vtx[m][1] = p0_[1] + j*h_[1];
01153 vtx[m][2] = p0_[2] + k*h_[2];
01154 m++;
01155 }
01156 }
01157 else {
01158 for(int i =0; i < nofcells_[0]+1; i++)
01159 for(int j=0; j < nofcells_[1]+1; j++) {
01160 vtx[m][0] = p0_[0] + i*h_[0];
01161 vtx[m][1] = p0_[1] + j*h_[1];
01162 m++;
01163 }
01164 }
01165 dverb << "done" << std::endl;
01166 return nofvtx();
01167 }
01168 int getHexa(std::vector<std::vector<int> >& simplex,
01169 int offset=0) {
01170 int oldsize=simplex.size();
01171
01172 size_t counthexa;
01173 int verticesPerCube;
01174 int m=oldsize;
01175 if(dimw_ == 3)
01176 verticesPerCube = 8;
01177 else
01178 verticesPerCube = 4;
01179 dverb << "generating hexaeder...";
01180 simplex.resize(oldsize+nofhexa());
01181 for (counthexa=m;counthexa < simplex.size();counthexa++)
01182 simplex[counthexa].resize(verticesPerCube);
01183 if(dimw_ == 3) {
01184 for(int i =0; i < nofcells_[0]; i++)
01185 for(int j=0; j < nofcells_[1]; j++)
01186 for(int k=0; k < nofcells_[2]; k++) {
01187 simplex[m][0] = offset+getIndex(i,j,k);
01188 simplex[m][1] = offset+getIndex(i+1,j,k);
01189 simplex[m][2] = offset+getIndex(i,j+1,k);
01190 simplex[m][3] = offset+getIndex(i+1,j+1,k);
01191 simplex[m][4] = offset+getIndex(i,j,k+1);
01192 simplex[m][5] = offset+getIndex(i+1,j,k+1);
01193 simplex[m][6] = offset+getIndex(i,j+1,k+1);
01194 simplex[m][7] = offset+getIndex(i+1,j+1,k+1);
01195 m++;
01196 }
01197 }
01198 else {
01199 for(int i =0; i < nofcells_[0]; i++)
01200 for(int j=0; j < nofcells_[1]; j++) {
01201 simplex[m][0] = offset+getIndex(i,j);
01202 simplex[m][1] = offset+getIndex(i+1,j);
01203 simplex[m][2] = offset+getIndex(i,j+1);
01204 simplex[m][3] = offset+getIndex(i+1,j+1);
01205 m++;
01206 }
01207 }
01208 dverb << "done" << std::endl;
01209 assert((size_t)m==simplex.size());
01210 return nofhexa();
01211 }
01212
01213 int nofvtx() {
01214 if(dimw_ == 3)
01215 return (nofcells_[0]+1)*(nofcells_[1]+1)*(nofcells_[2]+1);
01216 else
01217 return (nofcells_[0]+1)*(nofcells_[1]+1);
01218 }
01219
01220 int nofhexa() {
01221 if(dimw_ == 3)
01222 return (nofcells_[0])*(nofcells_[1])*(nofcells_[2]);
01223 else
01224 return (nofcells_[0])*(nofcells_[1]);
01225
01226 }
01227
01228 int segments(int i) {
01229 return nofcells_[i];
01230 }
01231
01232 double length(int i) {
01233 return p1_[i]-p0_[i];
01234 }
01235
01236 double start(int i) {
01237 return p0_[i];
01238 }
01239
01240 double end(int i) {
01241 return p1_[i];
01242 }
01243
01244
01245
01246
01247
01248 int dimw() {
01249 return dimw_;
01250 }
01251
01252 int getIndex(int i,int j, int k = 0) {
01253 if(dimw_ == 3)
01254 return i*(nofcells_[1]+1)*(nofcells_[2]+1) + j*(nofcells_[2]+1) + k;
01255 else
01256 return i*(nofcells_[1]+1) + j;
01257 }
01258 private:
01259 bool next() {
01260 if (linenumber()==noflines()-1) {
01261 good_=false;
01262 return good_;
01263 }
01264
01265 getnextline();
01266 double x;
01267 for(int i = 0;i<dimw_;i++)
01268 if(getnextentry(x))
01269 p0_[i] = x;
01270 else {
01271 DUNE_THROW(DGFException,
01272 "ERROR in " << *this
01273 << "Too few coordinates for point p0");
01274 }
01275
01276 getnextline();
01277 for(int i = 0;i<dimw_;i++)
01278 if(getnextentry(x))
01279 p1_[i] = x;
01280 else {
01281 DUNE_THROW(DGFException,
01282 "ERROR in " << *this
01283 << "Too few coordinates for point p1");
01284 }
01285
01286
01287 std::vector<double> p0h(dimw_),p1h(dimw_);
01288 for(int i = 0; i<dimw_;i++) {
01289 p0h[i] = p0_[i] < p1_[i] ? p0_[i] : p1_[i];
01290 p1h[i] = p0_[i] > p1_[i] ? p0_[i] : p1_[i];
01291 }
01292 p0_ = p0h;
01293 p1_ = p1h;
01294
01295 getnextline();
01296 int number;
01297 for(int i = 0;i<dimw_;i++)
01298 if(getnextentry(number))
01299 nofcells_[i] = number;
01300 else {
01301 DUNE_THROW(DGFException,
01302 "ERROR in " << *this
01303 << "Couldn't detect a number of cells for every direction");
01304 }
01305 good_ = true;
01306 for(int i =0; i < dimw_; i++)
01307 h_[i] = (p1_[i] - p0_[i])/double(nofcells_[i]);
01308
01309 dverb << "p0 = (";
01310 for(int i = 0;i<dimw_-1;i++)
01311 dverb << p0_[i] <<",";
01312 dverb << p0_[dimw_-1] <<") \n";
01313 dverb << "p1 = (";
01314 for(int i = 0;i<dimw_-1;i++)
01315 dverb << p1_[i] <<",";
01316 dverb << p1_[dimw_-1] <<") \n";
01317 dverb << "n = (";
01318 for(int i = 0;i<dimw_-1;i++)
01319 dverb << nofcells_[i] <<",";
01320 dverb << nofcells_[dimw_-1] <<") \n";
01321 dverb << std::endl;
01322 return good_;
01323 }
01324 };
01325 const char* IntervalBlock::ID = "Interval";
01326 }
01327 }
01328 #endif