00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "SundanceBamgMeshReader.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "PlayaExceptions.hpp"
00046 #include "Teuchos_StrUtils.hpp"
00047
00048 using namespace Teuchos;
00049 using namespace Sundance;
00050
00051
00052 BamgMeshReader::BamgMeshReader(const std::string& fname,
00053 const MeshType& meshType, bool bbAttr,
00054 int verbosity,
00055 const MPIComm& comm)
00056 : MeshReaderBase(fname, meshType, verbosity, comm),
00057 nodeFilename_(filename()),
00058 elemFilename_(filename()),
00059 parFilename_(filename()),
00060 meshFilename_(filename()),
00061 bbFilename_(filename()),
00062 bbAttr_(bbAttr)
00063
00064 {
00065
00066
00067 if (nProc() > 1)
00068 {
00069 nodeFilename_ = nodeFilename_ + Teuchos::toString(myRank());
00070 parFilename_ = parFilename_ + Teuchos::toString(myRank());
00071 elemFilename_ = elemFilename_ + Teuchos::toString(myRank());
00072 }
00073
00074
00075 nodeFilename_ = nodeFilename_ + ".node";
00076 elemFilename_ = elemFilename_ + ".ele";
00077 parFilename_ = parFilename_ + ".par";
00078 meshFilename_ = meshFilename_ + ".mesh";
00079 bbFilename_ = bbFilename_ + ".bb";
00080
00081 SUNDANCE_OUT(this->verb() > 1,
00082 "node filename = " << nodeFilename_);
00083
00084 SUNDANCE_OUT(this->verb() > 1,
00085 "elem filename = " << elemFilename_);
00086
00087 SUNDANCE_OUT(this->verb() > 1,
00088 "mesh filename = " << meshFilename_);
00089
00090 SUNDANCE_OUT(this->verb() > 1,
00091 "bb filename = " << bbFilename_);
00092
00093 }
00094 BamgMeshReader::BamgMeshReader(const ParameterList& params)
00095 : MeshReaderBase(params),
00096 nodeFilename_(filename()),
00097 elemFilename_(filename()),
00098 parFilename_(filename()),
00099 meshFilename_(filename())
00100 {
00101
00102
00103 if (nProc() > 1)
00104 {
00105 nodeFilename_ = nodeFilename_ + Teuchos::toString(myRank());
00106 parFilename_ = parFilename_ + Teuchos::toString(myRank());
00107 elemFilename_ = elemFilename_ + Teuchos::toString(myRank());
00108 }
00109
00110
00111 nodeFilename_ = nodeFilename_ + ".node";
00112 elemFilename_ = elemFilename_ + ".ele";
00113 parFilename_ = parFilename_ + ".par";
00114 meshFilename_ = meshFilename_ + ".mesh";
00115
00116 SUNDANCE_OUT(this->verb() > 1,
00117 "node filename = " << nodeFilename_);
00118
00119 SUNDANCE_OUT(this->verb() > 1,
00120 "elem filename = " << elemFilename_);
00121
00122 SUNDANCE_OUT(this->verb() > 1,
00123 "mesh filename = " << meshFilename_);
00124
00125 SUNDANCE_OUT(this->verb() > 1,
00126 "bb filename = " << bbFilename_);
00127
00128 }
00129
00130
00131 Mesh BamgMeshReader::fillMesh() const
00132 {
00133 Mesh mesh;
00134
00135 Array<int> ptGID;
00136 Array<int> ptOwner;
00137 Array<int> cellGID;
00138 Array<int> cellOwner;
00139
00140 readParallelInfo(ptGID, ptOwner, cellGID, cellOwner);
00141
00142
00143
00144
00145
00146 mesh = readMesh(ptGID, ptOwner);
00147
00148
00149
00150 return mesh;
00151 }
00152
00153 void BamgMeshReader::readParallelInfo(Array<int>& ptGID,
00154 Array<int>& ptOwner,
00155 Array<int>& cellGID,
00156 Array<int>& cellOwner) const
00157 {
00158 int nPoints;
00159 int nElems;
00160 std::string line;
00161 Array<string> tokens;
00162 try
00163 {
00164 ptGID.resize(0);
00165 ptOwner.resize(0);
00166 cellGID.resize(0);
00167 cellOwner.resize(0);
00168
00169
00170
00171
00172 if (nProc() > 1)
00173 {
00174 RCP<std::ifstream> parStream
00175 = openFile(parFilename_, "parallel info");
00176
00177
00178
00179
00180 getNextLine(*parStream, line, tokens, '#');
00181
00182 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 2, std::runtime_error,
00183 "TriangleMeshReader::getMesh() expects 2 entries "
00184 "on the first line of .par file. In "
00185 << parFilename_ << " I found \n[" << line << "]\n");
00186
00187 int np = atoi(tokens[1]);
00188 int pid = atoi(tokens[0]);
00189
00190
00191
00192
00193 TEUCHOS_TEST_FOR_EXCEPTION(np != nProc(), std::runtime_error,
00194 "TriangleMeshReader::getMesh() found "
00195 "a mismatch between the current number of processors="
00196 << nProc() <<
00197 "and the number of processors=" << np
00198 << "in the file " << parFilename_);
00199
00200 TEUCHOS_TEST_FOR_EXCEPTION(pid != myRank(), std::runtime_error,
00201 "TriangleMeshReader::getMesh() found "
00202 "a mismatch between the current processor rank="
00203 << myRank() << "and the processor rank="
00204 << pid << " in the file " << parFilename_);
00205
00206
00207 getNextLine(*parStream, line, tokens, '#');
00208
00209 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 1, std::runtime_error,
00210 "TriangleMeshReader::getMesh() requires 1 entry "
00211 "on the second line of .par file. Found line \n["
00212 << line << "]\n in file " << parFilename_);
00213
00214 nPoints = StrUtils::atoi(tokens[0]);
00215
00216
00217 ptGID.resize(nPoints);
00218 ptOwner.resize(nPoints);
00219
00220 for (int i=0; i<nPoints; i++)
00221 {
00222 getNextLine(*parStream, line, tokens, '#');
00223
00224 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 3, std::runtime_error,
00225 "TriangleMeshReader::getMesh() requires 3 "
00226 "entries on each line of the point section in "
00227 "the .par file. Found line \n[" << line
00228 << "]\n in file " << parFilename_);
00229
00230 ptGID[i] = StrUtils::atoi(tokens[1]);
00231 ptOwner[i] = StrUtils::atoi(tokens[2]);
00232 }
00233
00234
00235
00236
00237 getNextLine(*parStream, line, tokens, '#');
00238
00239 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 1, std::runtime_error,
00240 "TriangleMeshReader::getMesh() requires 1 entry "
00241 "on the cell count line of .par file. Found line \n["
00242 << line << "]\n in file " << parFilename_);
00243
00244 nElems = StrUtils::atoi(tokens[0]);
00245
00246 SUNDANCE_OUT(this->verb() > 1,
00247 "read nElems = " << nElems);
00248
00249
00250
00251
00252 cellGID.resize(nElems);
00253 cellOwner.resize(nElems);
00254 for (int i=0; i<nElems; i++)
00255 {
00256 getNextLine(*parStream, line, tokens, '#');
00257
00258 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 3, std::runtime_error,
00259 "TriangleMeshReader::getMesh() requires 3 "
00260 "entries on each line of the element section in "
00261 "the .par file. Found line \n[" << line
00262 << "]\n in file " << parFilename_);
00263
00264 cellGID[i] = StrUtils::atoi(tokens[1]);
00265 cellOwner[i] = StrUtils::atoi(tokens[2]);
00266 }
00267 }
00268
00269
00270 nPoints = ptGID.length();
00271 nElems = cellGID.length();
00272 }
00273 catch(std::exception& e)
00274 {
00275 SUNDANCE_TRACE(e);
00276 }
00277 }
00278
00279
00280
00281
00282 Mesh BamgMeshReader::readMesh(Array<int>& ptGID,
00283 Array<int>& ptOwner) const
00284 {
00285 Mesh mesh;
00286 std::string line;
00287 Array<string> tokens;
00288 int nPoints=0;
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 std::cerr << "starting to read meshFile" << std::endl;
00383
00384 RCP<std::ifstream> meshStream = openFile(meshFilename_,
00385 "node & elem info");
00386
00387 Array<string> liners = StrUtils::readFile(*meshStream, '#');
00388
00389 std::cerr << "defined liners" << std::endl;
00390
00391
00392 SUNDANCE_OUT(this->verb() > 3,
00393 "reading nodes from " + meshFilename_);
00394
00395
00396 int dimension=0;
00397 int dimensionIndex = 0;
00398 int lineIndex = 0;
00399 int verticesIndex = 0;
00400 int edgesIndex = 0;
00401 int triangleIndex = 0;
00402 int nCells=0;
00403 std::cerr << "DimensionIndex = " << dimensionIndex << std::endl;
00404
00405
00406 int linerssize = liners.length();
00407 std::cerr << "number of lines in liners = " << linerssize << std::endl;
00408
00409 for (int i = lineIndex; i < linerssize; i++)
00410 {
00411 tokens = StrUtils::stringTokenizer(liners[i]);
00412 std::cerr << "test: i = " << i << "tokens[0] = " << tokens[0] << std::endl;
00413 if (i < 20)
00414 {
00415 std::cerr << "i = " << i << ": number of tokens = " << tokens.length()
00416 << std::endl;
00417 for(int j = 0; j < tokens.length();j++)
00418 {
00419 std::cerr << " token " << j << " = " << tokens[j] << std::endl;
00420 std::cerr << " length of token[" << j << "] = "
00421 << tokens[j].length() << std::endl;
00422 }
00423 }
00424 if (tokens[0] == "Dimension")
00425 {
00426 dimensionIndex = i;
00427 std::cerr << "token[0] = Dimension" << std::endl;
00428 break;
00429 }
00430 }
00431 std::cerr << "DimensionIndex = " << dimensionIndex << std::endl;
00432 if (dimensionIndex > 0)
00433 {
00434 tokens = StrUtils::stringTokenizer(liners[dimensionIndex + 1]);
00435 dimension = atoi(tokens[0]);
00436 std::cerr << "dimension = " << dimension << std::endl;
00437 lineIndex = dimensionIndex + 2;
00438 }
00439
00440 for (int i = lineIndex; i < liners.size(); i++)
00441 {
00442 tokens = StrUtils::stringTokenizer(liners[i]);
00443 if (tokens[0] == "Vertices") verticesIndex = i;
00444 if (tokens[0] == "Vertices") break;
00445 }
00446 if (verticesIndex > 0)
00447 {
00448 tokens = StrUtils::stringTokenizer(liners[verticesIndex + 1]);
00449 nPoints = atoi(tokens[0]);
00450 std::cerr << "nPoints = " << nPoints << std::endl;
00451 ptGID.resize(nPoints);
00452 ptOwner.resize(nPoints);
00453 for (int i=0; i<nPoints; i++)
00454 {
00455 ptGID[i] = i;
00456 ptOwner[i] = 0;
00457 }
00458 lineIndex = verticesIndex + 2;
00459
00460 }
00461
00462 Array<int> ptIndices(nPoints);
00463 Array<int> rawIndices(nPoints);
00464
00465 Array<double> velVector(2*nPoints);
00466 int numbbAttr = 0;
00467
00468
00469
00470 if (bbAttr_)
00471 {
00472 RCP<std::ifstream> bbStream = openFile(bbFilename_,
00473 "velocity info");
00474 Array<string> bbliners = StrUtils::readFile(*bbStream, '#');
00475
00476
00477
00478
00479 int bbdimension;
00480 int bbnumSolns;
00481 int bbnumPoints=0;
00482 int bbsolnType;
00483 int bbdimensionIndex = 0;
00484 int bblineIndex = 0;
00485
00486 std::cerr << "bbDimensionIndex = " << bbdimensionIndex << std::endl;
00487
00488 int bblinerssize = bbliners.size();
00489 std::cerr << "number of lines in bbliners = " << bblinerssize << std::endl;
00490
00491 for (int i = bblineIndex; i < bblinerssize; i++)
00492 {
00493 Array<string> bbtokens = StrUtils::stringTokenizer(bbliners[i]);
00494 if(bbtokens.length() > 0)
00495 {
00496 if(bbtokens.length() != 4)
00497 {
00498 std::cerr <<
00499 "warning: .bb header line should have 4 tokens, read "
00500 << bbtokens.length() << std::endl;
00501 }
00502 std::cerr << "bbline " << i << ": read bbtokens " << bbtokens[0]
00503 << " " << bbtokens[1] << " " << bbtokens[2] << " "
00504 << bbtokens[3] << std::endl;
00505 bbdimensionIndex = i;
00506 break;
00507 }
00508 }
00509 bblineIndex = bbdimensionIndex + 1;
00510 std::cerr << "bblineIndex = " << bblineIndex << std::endl;
00511 if (bblineIndex > 0)
00512 {
00513 Array<string> bbtokens =
00514 StrUtils::stringTokenizer(bbliners[bbdimensionIndex]);
00515 bbdimension = StrUtils::atoi(bbtokens[0]);
00516 std::cerr << "bbdimension = " << bbdimension << std::endl;
00517 if (bbdimension != 2)
00518 std::cerr << "Error! bbdimension should be 2" << std::endl;
00519 bbnumSolns = StrUtils::atoi(bbtokens[1]);
00520 numbbAttr = bbnumSolns;
00521 std::cerr << "number of solutions per vertex = " << bbnumSolns << std::endl;
00522
00523
00524 bbnumPoints = StrUtils::atoi(bbtokens[2]);
00525 std::cerr << "number of vertices = " << bbnumPoints << std::endl;
00526 if (bbnumPoints != nPoints)
00527 std::cerr << "Error!! number of bb points != nPoints" << std::endl;
00528 bbsolnType = StrUtils::atoi(bbtokens[3]);
00529 std::cerr << "bbsolution type = " << bbsolnType << std::endl;
00530 }
00531
00532
00533
00534 for (int i = bblineIndex; i < bbnumPoints + bblineIndex; i++)
00535 {
00536 Array<string> bbtokens = StrUtils::stringTokenizer(bbliners[i]);
00537 if (bbtokens.length() == 0)
00538 std::cerr << "warning: encountered a blank soln line" << std::endl;
00539 int ii = i - bblineIndex;
00540
00541 velVector[ii] = StrUtils::atof(bbtokens[0]);
00542 velVector[ii+bbnumPoints] = StrUtils::atof(bbtokens[1]);
00543
00544
00545
00546 if( i < 5 || i > bbnumPoints - 5)
00547 {
00548
00549
00550
00551
00552 std::cerr << "vel0[" << ii << "] = " << velVector[ii] << std::endl;
00553 std::cerr << "vel1[" << ii << "] = " << velVector[ii+bbnumPoints]
00554 << std::endl;
00555 }
00556
00557 }
00558 }
00559
00560
00561
00562 int nAttributes = 0;
00563 if (bbAttr_) nAttributes = numbbAttr;
00564 std::cerr << "nAttributes = " << nAttributes << std::endl;
00565
00566
00567
00568
00569 mesh = createMesh(dimension);
00570 int count=0;
00571 int offset=0;
00572
00573 Array<bool> usedPoint(nPoints);
00574
00575
00576 nodeAttributes()->resize(nPoints);
00577
00578
00579
00580
00581 for (int i = lineIndex; i < liners.size(); i++)
00582
00583 {
00584 tokens = StrUtils::stringTokenizer(liners[i]);
00585 if (tokens.length() > 1)
00586 {
00587 double x = atof(tokens[0]);
00588 double y = atof(tokens[1]);
00589 count = i - lineIndex;
00590 rawIndices[count] = count;
00591 if ((i == lineIndex) || (i == lineIndex + 1) ||
00592 (i > lineIndex + nPoints - 2))
00593 {
00594 std::cerr << "i = " << i << "; node = (" << x << "," << y << ")"
00595 << std::endl;
00596 std::cerr << "count = " << count << std::endl;
00597 }
00598
00599 double z = 0.0;
00600 Point pt;
00601 int ptLabel = 0;
00602
00603 if (dimension==3)
00604 {
00605 z = atof(tokens[3]);
00606 pt = Point(x,y,z);
00607 }
00608 else
00609 {
00610 pt = Point(x,y);
00611 }
00612
00613 ptIndices[count]
00614 = mesh.addVertex(ptGID[count], pt, ptOwner[count], ptLabel);
00615
00616 (*nodeAttributes())[count].resize(nAttributes);
00617 for (int i=0; i<nAttributes; i++)
00618 {
00619
00620 if(i == 0) (*nodeAttributes())[count][i] = velVector[count];
00621 if(i == 1) (*nodeAttributes())[count][i] =
00622 velVector[count + nPoints];
00623 }
00624 }
00625
00626 if (tokens[0] == "Edges")
00627 {
00628 edgesIndex = i;
00629 break;
00630 }
00631 }
00632 std::cerr << "edgesIndex = " << edgesIndex << std::endl;
00633 std::cerr << "count = " << count << "; npoints - 1 = " << nPoints - 1 << std::endl;
00634
00635 if (count != nPoints - 1) std::cout << "error: # of nodes != # of vertices"
00636 << std::endl;
00637 else std::cerr << "successfully read node data" << std::endl;
00638 lineIndex = edgesIndex + 1;
00639
00640
00641
00642 std::cerr << "lineIndex = " << lineIndex << "; triangleIndex = "
00643 << triangleIndex << std::endl;
00644 for (int i = lineIndex; i < liners.size(); i++)
00645 {
00646 tokens = StrUtils::stringTokenizer(liners[i]);
00647 if (tokens[0] == "Triangles") {triangleIndex = i; break;}
00648 if (tokens[0] == "CrackedEdges") {triangleIndex = i+2; break;}
00649
00650 }
00651 std::cerr << "lineIndex = " << lineIndex << "; triangleIndex = "
00652 << triangleIndex << std::endl;
00653 std::cerr << "tokens[0] = " << tokens[0] << std::endl;
00654
00655 lineIndex = triangleIndex + 1;
00656
00657 Array<int> elemGID;
00658 Array<int> elemOwner;
00659
00660 if (triangleIndex > 0)
00661 {
00662 tokens = StrUtils::stringTokenizer(liners[lineIndex]);
00663 std::cerr << "lineIndex = " << lineIndex << "; tokens[0] = " << tokens[0]
00664 << std::endl;
00665 nCells = atoi(tokens[0]);
00666 elemGID.resize(nCells);
00667 elemOwner.resize(nCells);
00668 std::cerr << "nCells = " << nCells << std::endl;
00669 for (int i=0; i<nCells; i++)
00670 {
00671 elemGID[i] = i;
00672 elemOwner[i] = 0;
00673 }
00674 lineIndex = lineIndex + 1;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 std::cerr << "# of triangles = " << nCells
00776 << "; starting to read triangle data" << std::endl;
00777 SUNDANCE_OUT(this->verb() > 3,
00778 "done reading nodes, ready to read elements from " + meshFilename_);
00779
00780 int nElems = nCells;
00781 int ptsPerElem = dimension + 1;
00782 elemGID.resize(nElems);
00783 elemOwner.resize(nElems);
00784 offset = 1;
00785
00786 for (int i=0; i<nElems; i++)
00787 {
00788 elemGID[i] = i;
00789 elemOwner[i] = 0;
00790 }
00791 nAttributes = 0;
00792
00793 elemAttributes()->resize(nElems);
00794 count = 0;
00795
00796 int dim = mesh.spatialDim();
00797 Array<int> nodes(dim+1);
00798 if (dim != dimension) std::cerr << "ERROR: dim = " << dim << "!= dimension = "
00799 << dimension << std::endl;
00800
00801 std::cerr << "lineIndex = " << lineIndex << std::endl;
00802 std::cerr << "size of liners = " << liners.size() << std::endl;
00803 std::cerr << "lineIndex+nCells-1 = " << lineIndex+nCells-1 << std::endl;
00804 for (int i = lineIndex; i < liners.size();i++)
00805
00806 {
00807 tokens = StrUtils::stringTokenizer(liners[i]);
00808 if (tokens.length() > 1)
00809 {
00810 if (i < lineIndex + 5) std::cerr << "i = " << i << " first triangles: "
00811 << tokens[0] << " " << tokens[1]
00812 << " " << tokens[2] << std::endl;
00813 if (i == lineIndex+nCells-1) std::cerr << "i = " << i
00814 << " last triangle: " << tokens[0]
00815 << " " << tokens[1] << " "
00816 << tokens[2] << std::endl;
00817
00818 for (int d=0; d<=dim; d++)
00819 {
00820
00821
00822
00823 nodes[d] = ptGID[atoi(tokens[d])-offset];
00824
00825
00826 }
00827
00828 count = i - lineIndex;
00829 int elemLabel = 0;
00830 mesh.addElement(elemGID[count], nodes, elemOwner[count], elemLabel);
00831
00832 (*elemAttributes())[count].resize(nAttributes);
00833 for (int i=0; i<nAttributes; i++)
00834 {
00835
00836
00837
00838 (*elemAttributes())[count][i] = atof(tokens[ptsPerElem+i]);
00839
00840
00841 }
00842 }
00843 if (tokens[0] == "SubDomainFromMesh") break;
00844 }
00845
00846 std::cerr << "# of cells read = " << count + 1 << std::endl;
00847 if (count != nCells - 1) std::cerr << "error: # of cells read != nCells" << std::endl;
00848
00849
00850
00851 return mesh;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949