00001 #include "SundanceTriangleMeshReader.hpp"
00002 #include "SundanceOut.hpp"
00003 #include "SundanceExceptions.hpp"
00004
00005 using namespace Sundance;
00006 using namespace Sundance;
00007
00008 using namespace Teuchos;
00009 using namespace Sundance;
00010
00011
00012 TriangleMeshReader::TriangleMeshReader(const std::string& fname,
00013 const MeshType& meshType,
00014 const MPIComm& comm)
00015 : MeshReaderBase(fname, meshType, comm),
00016 nodeFilename_(filename()),
00017 elemFilename_(filename()),
00018 parFilename_(filename()),
00019 sideFilename_(filename()),
00020 offset_(0)
00021 {
00022
00023
00024 if (nProc() > 1)
00025 {
00026 std::string suffix = "." + Teuchos::toString(nProc())
00027 + "." + Teuchos::toString(myRank());
00028 nodeFilename_ = nodeFilename_ + suffix;
00029 parFilename_ = parFilename_ + suffix;
00030 elemFilename_ = elemFilename_ + suffix;
00031 sideFilename_ = sideFilename_ + suffix;
00032 }
00033 nodeFilename_ = nodeFilename_ + ".node";
00034 elemFilename_ = elemFilename_ + ".ele";
00035 parFilename_ = parFilename_ + ".par";
00036 sideFilename_ = sideFilename_ + ".side";
00037
00038 setVerbosity (classVerbosity() );
00039
00040 SUNDANCE_OUT(this->verb() > 1,
00041 "node filename = " << nodeFilename_);
00042
00043 SUNDANCE_OUT(this->verb() > 1,
00044 "elem filename = " << elemFilename_);
00045
00046 }
00047 TriangleMeshReader::TriangleMeshReader(const ParameterList& params)
00048 : MeshReaderBase(params),
00049 nodeFilename_(filename()),
00050 elemFilename_(filename()),
00051 parFilename_(filename())
00052 {
00053
00054
00055 if (nProc() > 1)
00056 {
00057 std::string suffix = "." + Teuchos::toString(nProc())
00058 + "." + Teuchos::toString(myRank());
00059 nodeFilename_ = nodeFilename_ + suffix;
00060 parFilename_ = parFilename_ + suffix;
00061 elemFilename_ = elemFilename_ + suffix;
00062 }
00063 nodeFilename_ = nodeFilename_ + ".node";
00064 elemFilename_ = elemFilename_ + ".ele";
00065 parFilename_ = parFilename_ + ".par";
00066
00067 setVerbosity( classVerbosity() );
00068 SUNDANCE_OUT(this->verb() > 1,
00069 "node filename = " << nodeFilename_);
00070
00071 SUNDANCE_OUT(this->verb() > 1,
00072 "elem filename = " << elemFilename_);
00073
00074 }
00075
00076
00077 Mesh TriangleMeshReader::fillMesh() const
00078 {
00079 Mesh mesh;
00080
00081 Array<int> ptGID;
00082 Array<int> ptOwner;
00083 Array<int> cellGID;
00084 Array<int> cellOwner;
00085
00086 readParallelInfo(ptGID, ptOwner, cellGID, cellOwner);
00087
00088 mesh = readNodes(ptGID, ptOwner);
00089
00090 readElems(mesh, ptGID, cellGID, cellOwner);
00091
00092 readSides(mesh);
00093
00094
00095
00096 return mesh;
00097 }
00098
00099 void TriangleMeshReader::readParallelInfo(Array<int>& ptGID,
00100 Array<int>& ptOwner,
00101 Array<int>& cellGID,
00102 Array<int>& cellOwner) const
00103 {
00104 int nPoints;
00105 int nElems;
00106 std::string line;
00107 Array<string> tokens;
00108 try
00109 {
00110 ptGID.resize(0);
00111 ptOwner.resize(0);
00112 cellGID.resize(0);
00113 cellOwner.resize(0);
00114
00115
00116
00117 if (nProc() > 1)
00118 {
00119 RCP<std::ifstream> parStream
00120 = openFile(parFilename_, "parallel info");
00121
00122
00123
00124
00125 getNextLine(*parStream, line, tokens, '#');
00126
00127 TEST_FOR_EXCEPTION(tokens.length() != 2, RuntimeError,
00128 "TriangleMeshReader::getMesh() expects 2 entries "
00129 "on the first line of .par file. In "
00130 << parFilename_ << " I found \n[" << line << "]\n");
00131
00132 int np = atoi(tokens[1]);
00133 int pid = atoi(tokens[0]);
00134
00135
00136
00137
00138 TEST_FOR_EXCEPTION(np != nProc(), RuntimeError,
00139 "TriangleMeshReader::getMesh() found "
00140 "a mismatch between the current number of processors="
00141 << nProc() <<
00142 "and the number of processors=" << np
00143 << "in the file " << parFilename_);
00144
00145 TEST_FOR_EXCEPTION(pid != myRank(), RuntimeError,
00146 "TriangleMeshReader::getMesh() found "
00147 "a mismatch between the current processor rank="
00148 << myRank() << "and the processor rank="
00149 << pid << " in the file " << parFilename_);
00150
00151
00152 getNextLine(*parStream, line, tokens, '#');
00153
00154 TEST_FOR_EXCEPTION(tokens.length() != 1, RuntimeError,
00155 "TriangleMeshReader::getMesh() requires 1 entry "
00156 "on the second line of .par file. Found line \n["
00157 << line << "]\n in file " << parFilename_);
00158
00159 nPoints = StrUtils::atoi(tokens[0]);
00160
00161
00162 ptGID.resize(nPoints);
00163 ptOwner.resize(nPoints);
00164
00165 for (int i=0; i<nPoints; i++)
00166 {
00167 getNextLine(*parStream, line, tokens, '#');
00168
00169 TEST_FOR_EXCEPTION(tokens.length() != 3, RuntimeError,
00170 "TriangleMeshReader::getMesh() requires 3 "
00171 "entries on each line of the point section in "
00172 "the .par file. Found line \n[" << line
00173 << "]\n in file " << parFilename_);
00174
00175 ptGID[i] = StrUtils::atoi(tokens[1]);
00176 ptOwner[i] = StrUtils::atoi(tokens[2]);
00177 }
00178
00179
00180
00181
00182 getNextLine(*parStream, line, tokens, '#');
00183
00184 TEST_FOR_EXCEPTION(tokens.length() != 1, RuntimeError,
00185 "TriangleMeshReader::getMesh() requires 1 entry "
00186 "on the cell count line of .par file. Found line \n["
00187 << line << "]\n in file " << parFilename_);
00188
00189 nElems = StrUtils::atoi(tokens[0]);
00190
00191 SUNDANCE_OUT(this->verb() > 1,
00192 "read nElems = " << nElems);
00193
00194
00195
00196
00197 cellGID.resize(nElems);
00198 cellOwner.resize(nElems);
00199 for (int i=0; i<nElems; i++)
00200 {
00201 getNextLine(*parStream, line, tokens, '#');
00202
00203 TEST_FOR_EXCEPTION(tokens.length() != 3, RuntimeError,
00204 "TriangleMeshReader::getMesh() requires 3 "
00205 "entries on each line of the element section in "
00206 "the .par file. Found line \n[" << line
00207 << "]\n in file " << parFilename_);
00208
00209 cellGID[i] = StrUtils::atoi(tokens[1]);
00210 cellOwner[i] = StrUtils::atoi(tokens[2]);
00211 }
00212 }
00213
00214 nPoints = ptGID.length();
00215 nElems = cellGID.length();
00216 }
00217 catch(std::exception& e)
00218 {
00219 SUNDANCE_TRACE(e);
00220 }
00221 }
00222
00223 Mesh TriangleMeshReader::readNodes(Array<int>& ptGID,
00224 Array<int>& ptOwner) const
00225 {
00226 Mesh mesh;
00227 std::string line;
00228 Array<string> tokens;
00229 int nPoints = -1;
00230
00231
00232
00233 RCP<std::ifstream> nodeStream = openFile(nodeFilename_, "node info");
00234
00235
00236 getNextLine(*nodeStream, line, tokens, '#');
00237 TEST_FOR_EXCEPTION(tokens.length() != 4, RuntimeError,
00238 "TriangleMeshReader::getMesh() requires 4 "
00239 "entries on the header line in "
00240 "the .node file. Found line \n[" << line
00241 << "]\n in file " << nodeFilename_);
00242 string headerLine = line;
00243 SUNDANCE_OUT(this->verb() > 2,
00244 "read point header " << line);
00245
00246
00247 if (nProc()==1)
00248 {
00249 nPoints = atoi(tokens[0]);
00250 ptGID.resize(nPoints);
00251 ptOwner.resize(nPoints);
00252 for (int i=0; i<nPoints; i++)
00253 {
00254 ptGID[i] = i;
00255 ptOwner[i] = 0;
00256 }
00257 }
00258 else
00259 {
00260
00261
00262 nPoints = ptGID.length();
00263 TEST_FOR_EXCEPTION(atoi(tokens[0]) != nPoints, RuntimeError,
00264 "TriangleMeshReader::getMesh() found inconsistent "
00265 "numbers of points in .node file and par file. Node "
00266 "file " << nodeFilename_ << " had nPoints="
00267 << atoi(tokens[0]) << " but .par file "
00268 << parFilename_ << " had nPoints=" << nPoints);
00269 }
00270
00271 SUNDANCE_OUT(this->verb() > 3,
00272 "expecting to read " << nPoints << " points");
00273
00274 int dimension = atoi(tokens[1]);
00275 int nAttributes = atoi(tokens[2]);
00276 int nBdryMarkers = atoi(tokens[3]);
00277
00278
00279 mesh = createMesh(dimension);
00280
00281
00282 Array<int> ptIndices(nPoints);
00283 Array<bool> usedPoint(nPoints);
00284 nodeAttributes()->resize(nAttributes);
00285 for (int i=0; i<nAttributes; i++)
00286 {
00287 (*nodeAttributes())[i].resize(nPoints);
00288 }
00289 offset_=-1;
00290 bool first = true;
00291
00292
00293 for (int count=0; count<nPoints; count++)
00294 {
00295 getNextLine(*nodeStream, line, tokens, '#');
00296
00297 TEST_FOR_EXCEPTION(tokens.length()
00298 != (1 + dimension + nAttributes + nBdryMarkers),
00299 RuntimeError,
00300 "TriangleMeshReader::getMesh() found bad node input "
00301 "line. Expected "
00302 << (1 + dimension + nAttributes + nBdryMarkers)
00303 << " entries but found line \n[" <<
00304 line << "]\n in file " << nodeFilename_);
00305
00306
00307 if (first)
00308 {
00309 offset_ = atoi(tokens[0]);
00310 TEST_FOR_EXCEPTION(offset_ < 0 || offset_ > 1, RuntimeError,
00311 "TriangleMeshReader::getMesh() expected "
00312 "either 0-offset or 1-offset numbering. Found an "
00313 "initial offset of " << offset_ << " in line \n["
00314 << line << "]\n of file " << nodeFilename_);
00315 first = false;
00316 }
00317
00318
00319 double x = atof(tokens[1]);
00320 double y = atof(tokens[2]);
00321 double z = 0.0;
00322 Point pt;
00323 int ptLabel = 0;
00324
00325 if (dimension==3)
00326 {
00327 z = atof(tokens[3]);
00328 pt = Point(x,y,z);
00329 }
00330 else
00331 {
00332 pt = Point(x,y);
00333 }
00334
00335 ptIndices[count]
00336 = mesh.addVertex(ptGID[count], pt, ptOwner[count], ptLabel);
00337
00338 for (int i=0; i<nAttributes; i++)
00339 {
00340 (*nodeAttributes())[i][count] = atof(tokens[dimension+1+i]);
00341 }
00342 }
00343 return mesh;
00344 }
00345
00346 void TriangleMeshReader::readElems(Mesh& mesh,
00347 const Array<int>& ptGID,
00348 Array<int>& elemGID,
00349 Array<int>& elemOwner) const
00350 {
00351 try
00352 {
00353 std::string line;
00354 Array<string> tokens;
00355
00356
00357 RCP<std::ifstream> elemStream = openFile(elemFilename_, "element info");
00358
00359 getNextLine(*elemStream, line, tokens, '#');
00360
00361 TEST_FOR_EXCEPTION(tokens.length() != 3, RuntimeError,
00362 "TriangleMeshReader::getMesh() requires 3 "
00363 "entries on the header line in "
00364 "the .ele file. Found line \n[" << line
00365 << "]\n in file " << elemFilename_);
00366
00367 int nElems = -1;
00368
00369 if (nProc()==1)
00370 {
00371 nElems = atoi(tokens[0]);
00372 elemGID.resize(nElems);
00373 elemOwner.resize(nElems);
00374 for (int i=0; i<nElems; i++)
00375 {
00376 elemGID[i] = i;
00377 elemOwner[i] = 0;
00378 }
00379 }
00380 else
00381 {
00382
00383
00384 nElems = elemGID.length();
00385 TEST_FOR_EXCEPTION(atoi(tokens[0]) != nElems, RuntimeError,
00386 "TriangleMeshReader::readElems() found inconsistent "
00387 "numbers of elements in .ele file and par file. Elem "
00388 "file " << elemFilename_ << " had nElems="
00389 << atoi(tokens[0]) << " but .par file "
00390 << parFilename_ << " had nElems=" << nElems);
00391 }
00392
00393 int ptsPerElem = atoi(tokens[1]);
00394
00395 TEST_FOR_EXCEPTION(ptsPerElem != mesh.spatialDim()+1, RuntimeError,
00396 "TriangleMeshReader::readElems() found inconsistency "
00397 "between number of points per element=" << ptsPerElem
00398 << " and dimension=" << mesh.spatialDim() << ". Number of pts "
00399 "per element should be dimension + 1");
00400
00401 int nAttributes = atoi(tokens[2]);
00402 elemAttributes()->resize(nElems);
00403
00404 int dim = mesh.spatialDim();
00405 Array<int> nodes(dim+1);
00406
00407 for (int count=0; count<nElems; count++)
00408 {
00409 getNextLine(*elemStream, line, tokens, '#');
00410
00411 TEST_FOR_EXCEPTION(tokens.length()
00412 != (1 + ptsPerElem + nAttributes),
00413 RuntimeError,
00414 "TriangleMeshReader::readElems() found bad elem "
00415 "input line. Expected "
00416 << (1 + ptsPerElem + nAttributes)
00417 << " entries but found line \n[" <<
00418 line << "]\n in file " << elemFilename_);
00419
00420 for (int d=0; d<=dim; d++)
00421 {
00422 nodes[d] = ptGID[atoi(tokens[d+1])-offset_];
00423 }
00424
00425 int elemLabel = 0;
00426 try
00427 {
00428 mesh.addElement(elemGID[count], nodes, elemOwner[count], elemLabel);
00429 }
00430 catch(std::exception& ex1)
00431 {
00432 SUNDANCE_TRACE(ex1);
00433 }
00434
00435 (*elemAttributes())[count].resize(nAttributes);
00436 for (int i=0; i<nAttributes; i++)
00437 {
00438 (*elemAttributes())[count][i] = atof(tokens[1+ptsPerElem+i]);
00439 }
00440 }
00441 }
00442 catch(std::exception& ex)
00443 {
00444 SUNDANCE_TRACE(ex);
00445 }
00446 }
00447
00448
00449 void TriangleMeshReader::readSides(Mesh& mesh) const
00450 {
00451 try
00452 {
00453 std::string line;
00454 Array<string> tokens;
00455
00456 RCP<std::ifstream> sideStream;
00457 bool fileOK = false;
00458
00459 try
00460 {
00461 sideStream = openFile(sideFilename_, "side info");
00462 fileOK = true;
00463 }
00464 catch(std::exception& e) {;}
00465
00466
00467
00468 if (!fileOK)
00469 {
00470 SUNDANCE_VERB_LOW("side file [" << sideFilename_ << "] not found");
00471 return;
00472 }
00473
00474 getNextLine(*sideStream, line, tokens, '#');
00475
00476 TEST_FOR_EXCEPTION(tokens.length() != 1, RuntimeError,
00477 "TriangleMeshReader::readSides() requires 1 "
00478 "entry on the header line in "
00479 "the .side file. Found line \n[" << line
00480 << "]\n in file " << sideFilename_);
00481
00482 int nSides = atoi(tokens[0]);
00483
00484 int elemDim = mesh.spatialDim();
00485 int sideDim = elemDim - 1;
00486
00487 for (int i=0; i<nSides; i++)
00488 {
00489 getNextLine(*sideStream, line, tokens, '#');
00490
00491 TEST_FOR_EXCEPTION(tokens.length() != 4,
00492 RuntimeError,
00493 "TriangleMeshReader::readSides() found bad side "
00494 "input line. Expected 4 entries but found line \n["
00495 << line << "]\n in file " << sideFilename_);
00496
00497 int elemGID = atoi(tokens[1]);
00498 int elemFacet = atoi(tokens[2]);
00499 TEST_FOR_EXCEPTION(!mesh.hasGID(elemDim, elemGID), RuntimeError,
00500 "element GID " << elemGID << " not found");
00501 int elemLID = mesh.mapGIDToLID(elemDim, elemGID);
00502 int o=0;
00503 int sideLID = mesh.facetLID(elemDim, elemLID, sideDim, elemFacet, o);
00504
00505 int sideLabel = atoi(tokens[3]);
00506
00507 mesh.setLabel(sideDim, sideLID, sideLabel);
00508 }
00509 }
00510 catch(std::exception& ex)
00511 {
00512 SUNDANCE_TRACE(ex);
00513 }
00514 }