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 "SundanceTriangleMeshReader.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "SundanceGeomUtils.hpp"
00046 #include "PlayaExceptions.hpp"
00047
00048 using namespace Sundance;
00049 using namespace Sundance;
00050
00051 using namespace Teuchos;
00052 using namespace Sundance;
00053
00054
00055 TriangleMeshReader::TriangleMeshReader(const std::string& fname,
00056 const MeshType& meshType,
00057 int verbosity,
00058 const MPIComm& comm)
00059 : MeshReaderBase(fname, meshType, verbosity, comm),
00060 nodeFilename_(filename()),
00061 elemFilename_(filename()),
00062 parFilename_(filename()),
00063 sideFilename_(filename()),
00064 edgeFilename_(filename()),
00065 offset_(0)
00066 {
00067
00068
00069 if (nProc() > 1)
00070 {
00071 std::string suffix = "." + Teuchos::toString(nProc())
00072 + "." + Teuchos::toString(myRank());
00073 nodeFilename_ = nodeFilename_ + suffix;
00074 parFilename_ = parFilename_ + suffix;
00075 elemFilename_ = elemFilename_ + suffix;
00076 sideFilename_ = sideFilename_ + suffix;
00077 edgeFilename_ = edgeFilename_ + suffix;
00078 }
00079 nodeFilename_ = nodeFilename_ + ".node";
00080 elemFilename_ = elemFilename_ + ".ele";
00081 parFilename_ = parFilename_ + ".par";
00082 sideFilename_ = sideFilename_ + ".side";
00083 edgeFilename_ = edgeFilename_ + ".edge";
00084
00085
00086 SUNDANCE_OUT(this->verb() > 1,
00087 "node filename = " << nodeFilename_);
00088
00089 SUNDANCE_OUT(this->verb() > 1,
00090 "elem filename = " << elemFilename_);
00091
00092 }
00093 TriangleMeshReader::TriangleMeshReader(const ParameterList& params)
00094 : MeshReaderBase(params),
00095 nodeFilename_(filename()),
00096 elemFilename_(filename()),
00097 parFilename_(filename()),
00098 sideFilename_(filename()),
00099 edgeFilename_(filename()),
00100 offset_(0)
00101 {
00102
00103
00104 if (nProc() > 1)
00105 {
00106 std::string suffix = "." + Teuchos::toString(nProc())
00107 + "." + Teuchos::toString(myRank());
00108 nodeFilename_ = nodeFilename_ + suffix;
00109 parFilename_ = parFilename_ + suffix;
00110 elemFilename_ = elemFilename_ + suffix;
00111 sideFilename_ = sideFilename_ + suffix;
00112 edgeFilename_ = edgeFilename_ + suffix;
00113 }
00114 nodeFilename_ = nodeFilename_ + ".node";
00115 elemFilename_ = elemFilename_ + ".ele";
00116 sideFilename_ = sideFilename_ + ".side";
00117 edgeFilename_ = edgeFilename_ + ".edge";
00118 parFilename_ = parFilename_ + ".par";
00119
00120 SUNDANCE_OUT(this->verb() > 1,
00121 "node filename = " << nodeFilename_);
00122
00123 SUNDANCE_OUT(this->verb() > 1,
00124 "elem filename = " << elemFilename_);
00125
00126 }
00127
00128
00129 Mesh TriangleMeshReader::fillMesh() const
00130 {
00131 Mesh mesh;
00132
00133 Array<int> ptGID;
00134 Array<int> ptOwner;
00135 Array<int> cellGID;
00136 Array<int> cellOwner;
00137
00138 readParallelInfo(ptGID, ptOwner, cellGID, cellOwner);
00139
00140 mesh = readNodes(ptGID, ptOwner);
00141
00142 readElems(mesh, ptGID, cellGID, cellOwner);
00143
00144 mesh.freezeTopology();
00145
00146 readSides(mesh);
00147
00148 readEdges(mesh);
00149
00150 return mesh;
00151 }
00152
00153 void TriangleMeshReader::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 if (nProc() > 1)
00172 {
00173 RCP<std::ifstream> parStream
00174 = openFile(parFilename_, "parallel info");
00175
00176
00177
00178
00179 getNextLine(*parStream, line, tokens, '#');
00180
00181 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 2, std::runtime_error,
00182 "TriangleMeshReader::getMesh() expects 2 entries "
00183 "on the first line of .par file. In "
00184 << parFilename_ << " I found \n[" << line << "]\n");
00185
00186 int np = atoi(tokens[1]);
00187 int pid = atoi(tokens[0]);
00188
00189
00190
00191
00192 TEUCHOS_TEST_FOR_EXCEPTION(np != nProc(), std::runtime_error,
00193 "TriangleMeshReader::getMesh() found "
00194 "a mismatch between the current number of processors="
00195 << nProc() <<
00196 "and the number of processors=" << np
00197 << "in the file " << parFilename_);
00198
00199 TEUCHOS_TEST_FOR_EXCEPTION(pid != myRank(), std::runtime_error,
00200 "TriangleMeshReader::getMesh() found "
00201 "a mismatch between the current processor rank="
00202 << myRank() << "and the processor rank="
00203 << pid << " in the file " << parFilename_);
00204
00205
00206 getNextLine(*parStream, line, tokens, '#');
00207
00208 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 1, std::runtime_error,
00209 "TriangleMeshReader::getMesh() requires 1 entry "
00210 "on the second line of .par file. Found line \n["
00211 << line << "]\n in file " << parFilename_);
00212
00213 nPoints = StrUtils::atoi(tokens[0]);
00214
00215
00216 ptGID.resize(nPoints);
00217 ptOwner.resize(nPoints);
00218
00219 for (int i=0; i<nPoints; i++)
00220 {
00221 getNextLine(*parStream, line, tokens, '#');
00222
00223 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 3, std::runtime_error,
00224 "TriangleMeshReader::getMesh() requires 3 "
00225 "entries on each line of the point section in "
00226 "the .par file. Found line \n[" << line
00227 << "]\n in file " << parFilename_);
00228
00229 ptGID[i] = StrUtils::atoi(tokens[1]);
00230 ptOwner[i] = StrUtils::atoi(tokens[2]);
00231 }
00232
00233
00234
00235
00236 getNextLine(*parStream, line, tokens, '#');
00237
00238 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 1, std::runtime_error,
00239 "TriangleMeshReader::getMesh() requires 1 entry "
00240 "on the cell count line of .par file. Found line \n["
00241 << line << "]\n in file " << parFilename_);
00242
00243 nElems = StrUtils::atoi(tokens[0]);
00244
00245 SUNDANCE_OUT(this->verb() > 1,
00246 "read nElems = " << nElems);
00247
00248
00249
00250
00251 cellGID.resize(nElems);
00252 cellOwner.resize(nElems);
00253 for (int i=0; i<nElems; i++)
00254 {
00255 getNextLine(*parStream, line, tokens, '#');
00256
00257 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 3, std::runtime_error,
00258 "TriangleMeshReader::getMesh() requires 3 "
00259 "entries on each line of the element section in "
00260 "the .par file. Found line \n[" << line
00261 << "]\n in file " << parFilename_);
00262
00263 cellGID[i] = StrUtils::atoi(tokens[1]);
00264 cellOwner[i] = StrUtils::atoi(tokens[2]);
00265 }
00266 }
00267
00268 nPoints = ptGID.length();
00269 nElems = cellGID.length();
00270 }
00271 catch(std::exception& e)
00272 {
00273 SUNDANCE_TRACE(e);
00274 }
00275 }
00276
00277 Mesh TriangleMeshReader::readNodes(Array<int>& ptGID,
00278 Array<int>& ptOwner) const
00279 {
00280 Mesh mesh;
00281 std::string line;
00282 Array<string> tokens;
00283 int nPoints = -1;
00284
00285
00286
00287 RCP<std::ifstream> nodeStream = openFile(nodeFilename_, "node info");
00288
00289
00290 getNextLine(*nodeStream, line, tokens, '#');
00291 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 4, std::runtime_error,
00292 "TriangleMeshReader::getMesh() requires 4 "
00293 "entries on the header line in "
00294 "the .node file. Found line \n[" << line
00295 << "]\n in file " << nodeFilename_);
00296 string headerLine = line;
00297 SUNDANCE_OUT(this->verb() > 2,
00298 "read point header " << line);
00299
00300
00301 if (nProc()==1)
00302 {
00303 nPoints = atoi(tokens[0]);
00304 ptGID.resize(nPoints);
00305 ptOwner.resize(nPoints);
00306 for (int i=0; i<nPoints; i++)
00307 {
00308 ptGID[i] = i;
00309 ptOwner[i] = 0;
00310 }
00311 }
00312 else
00313 {
00314
00315
00316 nPoints = ptGID.length();
00317 TEUCHOS_TEST_FOR_EXCEPTION(atoi(tokens[0]) != nPoints, std::runtime_error,
00318 "TriangleMeshReader::getMesh() found inconsistent "
00319 "numbers of points in .node file and par file. Node "
00320 "file " << nodeFilename_ << " had nPoints="
00321 << atoi(tokens[0]) << " but .par file "
00322 << parFilename_ << " had nPoints=" << nPoints);
00323 }
00324
00325 SUNDANCE_OUT(this->verb() > 3,
00326 "expecting to read " << nPoints << " points");
00327
00328 int dimension = atoi(tokens[1]);
00329 int nAttributes = atoi(tokens[2]);
00330 int nBdryMarkers = atoi(tokens[3]);
00331
00332
00333 mesh = createMesh(dimension);
00334
00335
00336 Array<int> ptIndices(nPoints);
00337 Array<bool> usedPoint(nPoints);
00338 nodeAttributes()->resize(nAttributes);
00339 for (int i=0; i<nAttributes; i++)
00340 {
00341 (*nodeAttributes())[i].resize(nPoints);
00342 }
00343 offset_=-1;
00344 bool first = true;
00345
00346
00347 for (int count=0; count<nPoints; count++)
00348 {
00349 getNextLine(*nodeStream, line, tokens, '#');
00350
00351 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length()
00352 != (1 + dimension + nAttributes + nBdryMarkers),
00353 std::runtime_error,
00354 "TriangleMeshReader::getMesh() found bad node input "
00355 "line. Expected "
00356 << (1 + dimension + nAttributes + nBdryMarkers)
00357 << " entries but found line \n[" <<
00358 line << "]\n in file " << nodeFilename_);
00359
00360
00361 if (first)
00362 {
00363 offset_ = atoi(tokens[0]);
00364 TEUCHOS_TEST_FOR_EXCEPTION(offset_ < 0 || offset_ > 1, std::runtime_error,
00365 "TriangleMeshReader::getMesh() expected "
00366 "either 0-offset or 1-offset numbering. Found an "
00367 "initial offset of " << offset_ << " in line \n["
00368 << line << "]\n of file " << nodeFilename_);
00369 first = false;
00370 }
00371
00372
00373 double x = atof(tokens[1]);
00374 double y = atof(tokens[2]);
00375 double z = 0.0;
00376 Point pt;
00377 int ptLabel = 0;
00378
00379 if (dimension==3)
00380 {
00381 z = atof(tokens[3]);
00382 pt = Point(x,y,z);
00383 }
00384 else
00385 {
00386 pt = Point(x,y);
00387 }
00388
00389 ptIndices[count]
00390 = mesh.addVertex(ptGID[count], pt, ptOwner[count], ptLabel);
00391
00392 for (int i=0; i<nAttributes; i++)
00393 {
00394 (*nodeAttributes())[i][count] = atof(tokens[dimension+1+i]);
00395 }
00396 }
00397 return mesh;
00398 }
00399
00400 void TriangleMeshReader::readElems(Mesh& mesh,
00401 const Array<int>& ptGID,
00402 Array<int>& elemGID,
00403 Array<int>& elemOwner) const
00404 {
00405 try
00406 {
00407 std::string line;
00408 Array<string> tokens;
00409
00410
00411 RCP<std::ifstream> elemStream = openFile(elemFilename_, "element info");
00412
00413 getNextLine(*elemStream, line, tokens, '#');
00414
00415 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 3, std::runtime_error,
00416 "TriangleMeshReader::getMesh() requires 3 "
00417 "entries on the header line in "
00418 "the .ele file. Found line \n[" << line
00419 << "]\n in file " << elemFilename_);
00420
00421 int nElems = -1;
00422
00423 if (nProc()==1)
00424 {
00425 nElems = atoi(tokens[0]);
00426 elemGID.resize(nElems);
00427 elemOwner.resize(nElems);
00428 for (int i=0; i<nElems; i++)
00429 {
00430 elemGID[i] = i;
00431 elemOwner[i] = 0;
00432 }
00433 }
00434 else
00435 {
00436
00437
00438 nElems = elemGID.length();
00439 TEUCHOS_TEST_FOR_EXCEPTION(atoi(tokens[0]) != nElems, std::runtime_error,
00440 "TriangleMeshReader::readElems() found inconsistent "
00441 "numbers of elements in .ele file and par file. Elem "
00442 "file " << elemFilename_ << " had nElems="
00443 << atoi(tokens[0]) << " but .par file "
00444 << parFilename_ << " had nElems=" << nElems);
00445 }
00446
00447 int ptsPerElem = atoi(tokens[1]);
00448
00449 TEUCHOS_TEST_FOR_EXCEPTION(ptsPerElem != mesh.spatialDim()+1, std::runtime_error,
00450 "TriangleMeshReader::readElems() found inconsistency "
00451 "between number of points per element=" << ptsPerElem
00452 << " and dimension=" << mesh.spatialDim() << ". Number of pts "
00453 "per element should be dimension + 1");
00454
00455 int nAttributes = atoi(tokens[2]);
00456 elemAttributes()->resize(nElems);
00457
00458 int dim = mesh.spatialDim();
00459 Array<int> nodes(dim+1);
00460
00461 for (int count=0; count<nElems; count++)
00462 {
00463 getNextLine(*elemStream, line, tokens, '#');
00464
00465 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length()
00466 != (1 + ptsPerElem + nAttributes),
00467 std::runtime_error,
00468 "TriangleMeshReader::readElems() found bad elem "
00469 "input line. Expected "
00470 << (1 + ptsPerElem + nAttributes)
00471 << " entries but found line \n[" <<
00472 line << "]\n in file " << elemFilename_);
00473
00474 for (int d=0; d<=dim; d++)
00475 {
00476 nodes[d] = ptGID[atoi(tokens[d+1])-offset_];
00477 }
00478
00479 int elemLabel = 0;
00480 try
00481 {
00482 mesh.addElement(elemGID[count], nodes, elemOwner[count], elemLabel);
00483 }
00484 catch(std::exception& ex1)
00485 {
00486 SUNDANCE_TRACE(ex1);
00487 }
00488
00489 (*elemAttributes())[count].resize(nAttributes);
00490 for (int i=0; i<nAttributes; i++)
00491 {
00492 (*elemAttributes())[count][i] = atof(tokens[1+ptsPerElem+i]);
00493 }
00494 }
00495 }
00496 catch(std::exception& ex)
00497 {
00498 SUNDANCE_TRACE(ex);
00499 }
00500 }
00501
00502
00503 void TriangleMeshReader::readSides(Mesh& mesh) const
00504 {
00505 try
00506 {
00507 std::string line;
00508 Array<string> tokens;
00509
00510 RCP<std::ifstream> sideStream;
00511 bool fileOK = false;
00512
00513 try
00514 {
00515 sideStream = openFile(sideFilename_, "side info");
00516 fileOK = true;
00517 }
00518 catch(std::exception& e) {;}
00519
00520
00521
00522 if (!fileOK)
00523 {
00524 SUNDANCE_VERB_LOW("side file [" << sideFilename_ << "] not found");
00525 return;
00526 }
00527
00528 getNextLine(*sideStream, line, tokens, '#');
00529
00530 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 1, std::runtime_error,
00531 "TriangleMeshReader::readSides() requires 1 "
00532 "entry on the header line in "
00533 "the .side file. Found line \n[" << line
00534 << "]\n in file " << sideFilename_);
00535
00536 int nSides = atoi(tokens[0]);
00537
00538 int elemDim = mesh.spatialDim();
00539 int sideDim = elemDim - 1;
00540
00541 for (int i=0; i<nSides; i++)
00542 {
00543 getNextLine(*sideStream, line, tokens, '#');
00544
00545 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 4,
00546 std::runtime_error,
00547 "TriangleMeshReader::readSides() found bad side "
00548 "input line. Expected 4 entries but found line \n["
00549 << line << "]\n in file " << sideFilename_);
00550
00551 int elemGID = atoi(tokens[1]);
00552 int elemFacet = atoi(tokens[2]);
00553 TEUCHOS_TEST_FOR_EXCEPTION(!mesh.hasGID(elemDim, elemGID), std::runtime_error,
00554 "element GID " << elemGID << " not found");
00555 int elemLID = mesh.mapGIDToLID(elemDim, elemGID);
00556 int o=0;
00557 int sideLID = mesh.facetLID(elemDim, elemLID, sideDim,
00558 elemFacet, o);
00559
00560 int sideLabel = atoi(tokens[3]);
00561
00562 mesh.setLabel(sideDim, sideLID, sideLabel);
00563 }
00564 }
00565 catch(std::exception& ex)
00566 {
00567 SUNDANCE_TRACE(ex);
00568 }
00569 }
00570
00571
00572
00573 void TriangleMeshReader::readEdges(Mesh& mesh) const
00574 {
00575 try
00576 {
00577 std::string line;
00578 Array<string> tokens;
00579
00580 RCP<std::ifstream> edgeStream;
00581 bool fileOK = false;
00582
00583 try
00584 {
00585 edgeStream = openFile(edgeFilename_, "edge info");
00586 fileOK = true;
00587 }
00588 catch(std::exception& e) {;}
00589
00590
00591
00592 if (!fileOK)
00593 {
00594 SUNDANCE_VERB_LOW("edge file [" << edgeFilename_ << "] not found");
00595 return;
00596 }
00597
00598 getNextLine(*edgeStream, line, tokens, '#');
00599
00600 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 2, std::runtime_error,
00601 "TriangleMeshReader::readEdges() requires 2 "
00602 "entries on the header line in "
00603 "the .edge file. Found line \n[" << line
00604 << "]\n in file " << edgeFilename_);
00605
00606 int nEdges = atoi(tokens[0]);
00607
00608 for (int i=0; i<nEdges; i++)
00609 {
00610 getNextLine(*edgeStream, line, tokens, '#');
00611
00612 TEUCHOS_TEST_FOR_EXCEPTION(tokens.length() != 4,
00613 std::runtime_error,
00614 "TriangleMeshReader::readEdges() found bad edge "
00615 "input line. Expected 4 entries but found line \n["
00616 << line << "]\n in file " << edgeFilename_);
00617
00618 int v1 = atoi(tokens[1])-offset_;
00619 int v2 = atoi(tokens[2])-offset_;
00620 int label = atoi(tokens[3]);
00621 if (label==0) continue;
00622
00623 int edgeLID = lookupEdgeLIDFromVerts(mesh, v1, v2);
00624
00625 TEUCHOS_TEST_FOR_EXCEPTION(edgeLID < 0, std::runtime_error,
00626 "edge(" << v1 << ", " << v2 <<") not found");
00627 mesh.setLabel(1, edgeLID, label);
00628 }
00629 }
00630 catch(std::exception& ex)
00631 {
00632 SUNDANCE_TRACE(ex);
00633 }
00634 }