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 #include "TrianglesMeshReader.hpp"
00030 #include "Exception.hpp"
00031 #include <cassert>
00032 #include <sstream>
00033
00034 const static char* NODES_FILE_EXTENSION = ".node";
00035 const static char* ELEMENTS_FILE_EXTENSION = ".ele";
00036 const static char* FACES_FILE_EXTENSION = ".face";
00037 const static char* EDGES_FILE_EXTENSION = ".edge";
00038
00040
00042
00043 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00044 TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::TrianglesMeshReader(std::string pathBaseName, unsigned orderOfElements, unsigned orderOfBoundaryElements)
00045 : mFilesBaseName(pathBaseName),
00046 mNumNodes(0),
00047 mNumElements(0),
00048 mNumFaces(0),
00049 mNodesRead(0),
00050 mElementsRead(0),
00051 mFacesRead(0),
00052 mBoundaryFacesRead(0),
00053 mNumElementAttributes(0),
00054 mNumFaceAttributes(0),
00055 mOrderOfElements(orderOfElements),
00056 mOrderOfBoundaryElements(orderOfBoundaryElements)
00057 {
00058
00059 assert(orderOfElements==1 || orderOfElements==2);
00060 if (mOrderOfElements==1)
00061 {
00062 mNodesPerElement = ELEMENT_DIM+1;
00063 }
00064 else
00065 {
00066 #define COVERAGE_IGNORE
00067 assert(SPACE_DIM==ELEMENT_DIM);
00068 #undef COVERAGE_IGNORE
00069 mNodesPerElement = (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2;
00070 }
00071
00072 if (mOrderOfBoundaryElements==1)
00073 {
00074 mNodesPerBoundaryElement = ELEMENT_DIM;
00075 }
00076 else
00077 {
00078 #define COVERAGE_IGNORE
00079 assert(SPACE_DIM==ELEMENT_DIM);
00080 #undef COVERAGE_IGNORE
00081 mNodesPerBoundaryElement = ELEMENT_DIM*(ELEMENT_DIM+1)/2;
00082 }
00083
00084 mIndexFromZero = false;
00085
00086 OpenFiles();
00087 ReadHeaders();
00088 }
00089
00090 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00091 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00092 {
00093 return mNumElements;
00094 }
00095
00096 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00097 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00098 {
00099 return mNumNodes;
00100 }
00101
00102 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00103 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaces() const
00104 {
00105 return mNumFaces;
00106 }
00107
00108 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00109 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumEdges() const
00110 {
00111 return mNumFaces;
00112 }
00113
00114 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00115 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElementAttributes() const
00116 {
00117 return mNumElementAttributes;
00118 }
00119
00120 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00121 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaceAttributes() const
00122 {
00123 return mNumFaceAttributes;
00124 }
00125
00126 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00127 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::Reset()
00128 {
00129 CloseFiles();
00130 OpenFiles();
00131 ReadHeaders();
00132
00133 mNodesRead = 0;
00134 mElementsRead = 0;
00135 mFacesRead = 0;
00136 mBoundaryFacesRead = 0;
00137 }
00138
00139 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00140 std::vector<double> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextNode()
00141 {
00142 std::vector<double> ret_coords;
00143
00144 std::string buffer;
00145 GetNextLineFromStream(mNodesFile, buffer);
00146
00147 std::stringstream buffer_stream(buffer);
00148
00149 unsigned index;
00150 buffer_stream >> index;
00151
00152 unsigned offset = mIndexFromZero ? 0 : 1;
00153 if (index != mNodesRead+offset)
00154 {
00155 std::stringstream error;
00156 error << "Data for node " << mNodesRead << " missing";
00157 EXCEPTION(error.str());
00158 }
00159
00160 double coord;
00161
00162 for (unsigned i=0; i<SPACE_DIM; i++)
00163 {
00164 buffer_stream >> coord;
00165 ret_coords.push_back(coord);
00166 }
00167
00168 mNodesRead++;
00169
00170 return ret_coords;
00171 }
00172
00173 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00174 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextElementData()
00175 {
00176 ElementData element_data;
00177
00178 std::string buffer;
00179 GetNextLineFromStream(mElementsFile, buffer);
00180
00181 std::stringstream buffer_stream(buffer);
00182
00183 unsigned element_index;
00184 buffer_stream >> element_index;
00185
00186 unsigned offset = mIndexFromZero ? 0 : 1;
00187 if (element_index != mElementsRead+offset)
00188 {
00189 std::stringstream error;
00190 error << "Data for element " << mElementsRead << " missing";
00191 EXCEPTION(error.str());
00192 }
00193
00194 unsigned node_index;
00195 for (unsigned i=0; i<mNodesPerElement; i++)
00196 {
00197 buffer_stream >> node_index;
00198 element_data.NodeIndices.push_back(node_index - offset);
00199 }
00200
00201 if (mNumElementAttributes > 0)
00202 {
00203 assert(mNumElementAttributes==1);
00204
00205 unsigned attribute_value;
00206 buffer_stream >> attribute_value;
00207 element_data.AttributeValue = attribute_value;
00208 }
00209 else
00210 {
00211 element_data.AttributeValue = 0;
00212 }
00213
00214 mElementsRead++;
00215 return element_data;
00216 }
00217
00218 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00219 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextFaceData()
00220 {
00221 ElementData face_data;
00222 std::vector<unsigned> ret_indices;
00223
00224
00225 if (SPACE_DIM == 1)
00226 {
00227 ret_indices.push_back(mBoundaryFacesRead);
00228 }
00229 else if (SPACE_DIM == 2 && ELEMENT_DIM == 1)
00230 {
00231 ret_indices.push_back(mBoundaryFacesRead);
00232 }
00233 else if (SPACE_DIM == 3 && ELEMENT_DIM == 1)
00234 {
00235 ret_indices.push_back(mBoundaryFacesRead);
00236 }
00237 else
00238 {
00239 unsigned offset = mIndexFromZero ? 0 : 1;
00240
00241 assert(ELEMENT_DIM != 0);
00242 do
00243 {
00244 ret_indices.clear();
00245
00246 std::string buffer;
00247 GetNextLineFromStream(mFacesFile, buffer);
00248
00249 std::stringstream buffer_stream(buffer);
00250
00251 unsigned face_index;
00252 buffer_stream >> face_index;
00253
00254 if (face_index != mFacesRead+offset)
00255 {
00256 std::stringstream error;
00257 error << "Data for face " << mFacesRead << " missing";
00258 EXCEPTION(error.str());
00259 }
00260
00261 unsigned node_index;
00262 for (unsigned i=0; i<mNodesPerBoundaryElement; i++)
00263 {
00264 buffer_stream >> node_index;
00265 ret_indices.push_back(node_index-offset);
00266 }
00267
00268 if (mNumFaceAttributes>0)
00269 {
00270 assert(mNumFaceAttributes==1);
00271
00272 unsigned attribute_value;
00273 buffer_stream >> attribute_value;
00274 face_data.AttributeValue = attribute_value;
00275 }
00276 else
00277 {
00278 face_data.AttributeValue = 0u;
00279 }
00280
00281 mFacesRead++;
00282 }
00283 while ((mNumFaceAttributes==1) && (face_data.AttributeValue==0));
00284 }
00285
00286 mBoundaryFacesRead++;
00287 face_data.NodeIndices = ret_indices;
00288 return face_data;
00289 }
00290
00291 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00292 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextEdgeData()
00293 {
00294 return GetNextFaceData();
00295 }
00296
00297 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00298 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFiles()
00299 {
00300 OpenNodeFile();
00301 OpenElementsFile();
00302 OpenFacesFile();
00303 }
00304
00305 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00306 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenNodeFile()
00307 {
00308
00309 std::string file_name = mFilesBaseName + NODES_FILE_EXTENSION;
00310 mNodesFile.open(file_name.c_str());
00311 if (!mNodesFile.is_open())
00312 {
00313 EXCEPTION("Could not open data file: " + file_name);
00314 }
00315 }
00316
00317 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00318 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenElementsFile()
00319 {
00320
00321 std::string file_name;
00322 if (ELEMENT_DIM == SPACE_DIM)
00323 {
00324 file_name = mFilesBaseName + ELEMENTS_FILE_EXTENSION;
00325 }
00326 else
00327 {
00328 if (SPACE_DIM == 2 && ELEMENT_DIM == 1)
00329 {
00330 file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00331 }
00332 else if (SPACE_DIM == 3 && ELEMENT_DIM == 1)
00333 {
00334 file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00335 }
00336 else if (SPACE_DIM == 3 && ELEMENT_DIM == 2)
00337 {
00338 file_name = mFilesBaseName + FACES_FILE_EXTENSION;
00339 }
00340 else
00341 {
00342 EXCEPTION("Can't have a zero-dimensional mesh in a one-dimensional space");
00343 }
00344 }
00345
00346 mElementsFile.open(file_name.c_str());
00347 if (!mElementsFile.is_open())
00348 {
00349 EXCEPTION("Could not open data file: " + file_name);
00350 }
00351 }
00352
00353 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00354 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFacesFile()
00355 {
00356
00357 std::string file_name;
00358 if (SPACE_DIM == 3)
00359 {
00360 if (SPACE_DIM == ELEMENT_DIM)
00361 {
00362 file_name = mFilesBaseName + FACES_FILE_EXTENSION;
00363 }
00364 else
00365 {
00366 file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00367 }
00368 }
00369 else if (SPACE_DIM == 2)
00370 {
00371 file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00372 }
00373 else if (SPACE_DIM == 1)
00374 {
00375
00376 return;
00377 }
00378
00379 mFacesFile.open(file_name.c_str());
00380 if (!mFacesFile.is_open())
00381 {
00382 EXCEPTION("Could not open data file: " + file_name);
00383 }
00384 }
00385
00386 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00387 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadHeaders()
00388 {
00389 std::string buffer;
00390
00391 GetNextLineFromStream(mNodesFile, buffer);
00392 std::stringstream buffer_stream(buffer);
00393 unsigned dimension;
00394 buffer_stream >> mNumNodes >> dimension >> mNumNodeAttributes >> mMaxNodeBdyMarker;
00395 if (SPACE_DIM != dimension)
00396 {
00397 EXCEPTION("SPACE_DIM != dimension read from file ");
00398 }
00399
00400
00401 GetNextLineFromStream(mNodesFile, buffer);
00402 std::stringstream buffer_stream_ii(buffer);
00403
00404 unsigned first_index;
00405 buffer_stream_ii >> first_index;
00406 assert(first_index == 0 || first_index == 1);
00407 mIndexFromZero = (first_index == 0);
00408
00409
00410 mNodesFile.close();
00411 OpenNodeFile();
00412 GetNextLineFromStream(mNodesFile, buffer);
00413
00415 GetNextLineFromStream(mElementsFile, buffer);
00416 std::stringstream buffer_stream2(buffer);
00417
00418 if (ELEMENT_DIM == SPACE_DIM)
00419 {
00420 buffer_stream2 >> mNumElements >> mNumElementNodes >> mNumElementAttributes;
00421
00422 if ( mNumElementNodes != mNodesPerElement )
00423 {
00424 std::stringstream error;
00425 error << "Number of nodes per elem, " << mNumElementNodes << ", does not match "
00426 << "expected number, " << mNodesPerElement << " (which is calculated given "
00427 << "the order of elements chosen, " << mOrderOfElements << " (1=linear, 2=quadratics)";
00428 EXCEPTION(error.str());
00429 }
00430 }
00431 else
00432 {
00433 buffer_stream2 >> mNumElements >> mNumFaceAttributes;
00434
00435 mNodesPerElement = ELEMENT_DIM+1;
00436 }
00437
00438 if (SPACE_DIM == 1)
00439 {
00440 mNumFaces = mNumNodes;
00441 }
00442 else if (SPACE_DIM == 2 && ELEMENT_DIM == 1)
00443 {
00444 mNumFaces = mNumNodes;
00445 }
00446 else if (SPACE_DIM == 3 && ELEMENT_DIM == 1)
00447 {
00448 mNumFaces = mNumNodes;
00449 }
00450 else
00451 {
00452 GetNextLineFromStream(mFacesFile, buffer);
00453 std::stringstream buffer_stream3(buffer);
00454
00455 buffer_stream3 >> mNumFaces >> mNumFaceAttributes;
00456 assert(mNumFaceAttributes==0 || mNumFaceAttributes==1);
00457
00458
00459
00460 if ((mNumFaceAttributes==1) && (SPACE_DIM!=1))
00461 {
00462 unsigned num_boundary_faces = 0;
00463 bool end_of_file=false;
00464 while (!end_of_file)
00465 {
00466 try
00467 {
00468 GetNextFaceData();
00469 num_boundary_faces++;
00470 }
00471 catch(Exception& e)
00472 {
00473 end_of_file = true;
00474 }
00475 }
00476 mNumFaces = num_boundary_faces;
00477
00478
00479 mFacesFile.close();
00480 mFacesFile.clear();
00481 OpenFacesFile();
00482 GetNextLineFromStream(mFacesFile, buffer);
00483 mFacesRead = 0;
00484 mBoundaryFacesRead = 0;
00485 }
00486 }
00487 }
00488
00489 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00490 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::CloseFiles()
00491 {
00492 mNodesFile.close();
00493 mElementsFile.close();
00494 mFacesFile.close();
00495 }
00496
00497 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00498 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextLineFromStream(std::ifstream& fileStream, std::string& rRawLine)
00499 {
00500 bool line_is_blank;
00501
00502 do
00503 {
00504 getline(fileStream, rRawLine);
00505
00506 if (fileStream.eof())
00507 {
00509 EXCEPTION("File contains incomplete data");
00510 }
00511
00512
00513 rRawLine = rRawLine.substr(0, rRawLine.find('#',0));
00514
00515 line_is_blank = (rRawLine.find_first_not_of(" \t",0) == std::string::npos);
00516 }
00517 while (line_is_blank);
00518 }
00519
00520 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00521 std::string TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetMeshFileBaseName()
00522 {
00523 return mFilesBaseName;
00524 }
00525
00526
00528
00530
00531 template class TrianglesMeshReader<0,1>;
00532 template class TrianglesMeshReader<1,1>;
00533 template class TrianglesMeshReader<1,2>;
00534 template class TrianglesMeshReader<1,3>;
00535 template class TrianglesMeshReader<2,2>;
00536 template class TrianglesMeshReader<2,3>;
00537 template class TrianglesMeshReader<3,3>;