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 #include <cassert>
00036 #include <sstream>
00037 #include <iostream>
00038
00039 #include "GmshMeshReader.hpp"
00040 #include "Exception.hpp"
00041
00042 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00043 GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GmshMeshReader(std::string pathBaseName,
00044 unsigned orderOfElements,
00045 unsigned orderOfBoundaryElements) :
00046 mFileName(pathBaseName),
00047 mOrderOfElements(orderOfElements),
00048 mOrderOfBoundaryElements(orderOfBoundaryElements)
00049 {
00050 assert(SPACE_DIM==ELEMENT_DIM);
00051
00052
00053 assert(mOrderOfElements==1 || mOrderOfElements==2);
00054
00055 if (mOrderOfElements==1)
00056 {
00057 mNodesPerElement = ELEMENT_DIM+1;
00058 }
00059 else
00060 {
00061 mNodesPerElement = (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2;
00062 }
00063
00064 if (mOrderOfBoundaryElements==1)
00065 {
00066 mNodesPerBoundaryElement = ELEMENT_DIM;
00067 }
00068 else
00069 {
00070 mNodesPerBoundaryElement = ELEMENT_DIM*(ELEMENT_DIM+1)/2;
00071 }
00072
00073 OpenFiles();
00074 ReadHeaders();
00075 }
00076
00077 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00078 GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::~GmshMeshReader()
00079 {
00080 CloseFiles();
00081 }
00082
00083 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00084 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFiles()
00085 {
00086
00087 mNodeFile.open(mFileName.c_str());
00088 mElementFile.open(mFileName.c_str());
00089 mFaceFile.open(mFileName.c_str());
00090 if (!mNodeFile.is_open() || !mElementFile.is_open() || !mFaceFile.is_open() )
00091 {
00092 EXCEPTION("Could not open data file: " + mFileName);
00093 }
00094 }
00095
00096 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00097 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::CloseFiles()
00098 {
00099 mNodeFile.close();
00100 mElementFile.close();
00101 mFaceFile.close();
00102 }
00103
00104
00105 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00106 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadHeaders()
00107 {
00108
00109
00110
00111 std::string this_line;
00112 getline(mNodeFile, this_line);
00113
00114 assert(this_line == "$MeshFormat");
00115
00116
00117 getline(mNodeFile, this_line);
00118 std::stringstream line(this_line);
00119
00120 line >> mVersionNumber >> mFileType >> mDataSize;
00121
00122 if(mVersionNumber != 2.2)
00123 {
00124 EXCEPTION("Only .msh version 2.2 files are supported.");
00125 }
00126 assert(mFileType == 0);
00127
00128
00129 getline(mNodeFile, this_line);
00130 assert(this_line == "$EndMeshFormat");
00131
00132 ReadNodeHeader();
00133 ReadElementHeader();
00134 ReadFaceHeader();
00135 }
00136
00137
00138 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00139 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadNodeHeader()
00140 {
00141
00142 std::string this_line;
00143 std::stringstream line(this_line);
00144
00145 while(this_line != "$Nodes")
00146 {
00147 getline(mNodeFile, this_line);
00148 }
00149 getline(mNodeFile, this_line);
00150
00151 line.clear();
00152 line.str(this_line);
00153 line >> mNumNodes;
00154 }
00155
00156 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00157 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadElementHeader()
00158 {
00159
00160 std::string this_line;
00161 std::stringstream line(this_line);
00162
00163 getline(mElementFile, this_line);
00164 while(this_line != "$Elements")
00165 {
00166 getline(mElementFile, this_line);
00167 }
00168 getline(mElementFile, this_line);
00169 int ele_start = mElementFile.tellg();
00170
00171 mNumElements = 0u;
00172 getline(mElementFile, this_line);
00173
00174 while(this_line != "$EndElements")
00175 {
00176 line.clear();
00177 line.str(this_line);
00178
00179 unsigned ele_index;
00180 unsigned ele_type;
00181 line >> ele_index >> ele_type;
00182
00183 if(ELEMENT_DIM == 2 && (ele_type == GmshTypes::TRIANGLE || ele_type == GmshTypes::QUADRATIC_TRIANGLE))
00184 {
00185 mNumElements++;
00186 }
00187 else if(ELEMENT_DIM == 3 && (ele_type == GmshTypes::TETRAHEDRON || ele_type == GmshTypes::QUADRATIC_TETRAHEDRON))
00188 {
00189 mNumElements++;
00190 }
00191
00192 getline(mElementFile, this_line);
00193 }
00194
00195 mElementFile.seekg(ele_start);
00196 }
00197
00198 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00199 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadFaceHeader()
00200 {
00201
00202 std::string this_line;
00203 std::stringstream line(this_line);
00204
00205 getline(mFaceFile, this_line);
00206 while(this_line != "$Elements")
00207 {
00208 getline(mFaceFile, this_line);
00209 }
00210 getline(mFaceFile, this_line);
00211 int face_start = mFaceFile.tellg();
00212
00213 mNumFaces = 0u;
00214 getline(mFaceFile, this_line);
00215
00216 while(this_line != "$EndElements")
00217 {
00218 line.clear();
00219 line.str(this_line);
00220
00221 unsigned ele_index;
00222 unsigned ele_type;
00223 line >> ele_index >> ele_type;
00224
00225 if(ELEMENT_DIM == 2 && (ele_type == GmshTypes::LINE || ele_type == GmshTypes::QUADRATIC_LINE))
00226 {
00227 mNumFaces++;
00228 }
00229 else if(ELEMENT_DIM == 3 && (ele_type == GmshTypes::TRIANGLE || ele_type == GmshTypes::QUADRATIC_TRIANGLE))
00230 {
00231 mNumFaces++;
00232 }
00233
00234 getline(mFaceFile, this_line);
00235 }
00236
00237 mFaceFile.seekg(face_start);
00238 }
00239
00240 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00241 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00242 {
00243 return mNumElements;
00244 }
00245
00246 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00247 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00248 {
00249 return mNumNodes;
00250 }
00251
00252 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00253 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaces() const
00254 {
00255 return mNumFaces;
00256 }
00257
00258 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00259 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElements() const
00260 {
00261 NEVER_REACHED;
00262
00263 }
00264
00265 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00266 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetOrderOfElements()
00267 {
00268 return mOrderOfElements;
00269 }
00270
00271 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00272 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetOrderOfBoundaryElements()
00273 {
00274 return mOrderOfBoundaryElements;
00275 }
00276
00277 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00278 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElementAttributes() const
00279 {
00280 return mNumElementAttributes;
00281 }
00282
00283 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00284 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaceAttributes() const
00285 {
00286 return mNumFaceAttributes;
00287 }
00288
00289 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00290 unsigned GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumCableElementAttributes() const
00291 {
00292 NEVER_REACHED;
00293
00294 }
00295
00296
00297 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00298 void GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::Reset()
00299 {
00300 CloseFiles();
00301
00302 OpenFiles();
00303 ReadHeaders();
00304 }
00305
00306 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00307 std::vector<double> GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextNode()
00308 {
00309 std::vector<double> ret_coords(SPACE_DIM);
00310
00311 std::string this_line;
00312 getline(mNodeFile, this_line);
00313
00314 std::stringstream line(this_line);
00315
00316 unsigned node_index;
00317 line >> node_index >> ret_coords[0] >> ret_coords[1];
00318
00319 if(ELEMENT_DIM == 3)
00320 {
00321 line >> ret_coords[2];
00322 }
00323
00324 return ret_coords;
00325 }
00326
00327 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00328 std::vector<double> GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNodeAttributes()
00329 {
00330 return std::vector<double>(0);
00331 }
00332
00333 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00334 ElementData GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextElementData()
00335 {
00336 ElementData element_data;
00337 element_data.NodeIndices.resize(mNodesPerElement);
00338 element_data.AttributeValue = 0.0;
00339
00340 std::string this_line;
00341 std::stringstream line(this_line);
00342
00343 unsigned ele_index;
00344 unsigned ele_type;
00345 unsigned ele_attributes=0;
00346 bool volume_element_found = false;
00347
00348 while(!volume_element_found)
00349 {
00350 getline(mElementFile, this_line);
00351 line.clear();
00352 line.str(this_line);
00353
00354 line >> ele_index >> ele_type >> ele_attributes;
00355
00356 if((ELEMENT_DIM == 2 && (ele_type == GmshTypes::TRIANGLE || ele_type == GmshTypes::QUADRATIC_TRIANGLE) ) ||
00357 (ELEMENT_DIM == 3 && (ele_type == GmshTypes::TETRAHEDRON || ele_type == GmshTypes::QUADRATIC_TETRAHEDRON)))
00358 {
00359 volume_element_found = true;
00360 }
00361 }
00362
00363
00364
00365 if(ele_attributes > 0)
00366 {
00367 mNumElementAttributes = 1u;
00368 line >> element_data.AttributeValue;
00369 }
00370 unsigned unused_attr;
00371 for(unsigned attr_index = 0; attr_index < (ele_attributes-1); ++attr_index)
00372 {
00373 line >> unused_attr;
00374 }
00375
00376
00377 for(unsigned node_index = 0; node_index < mNodesPerElement; ++node_index)
00378 {
00379 line >> element_data.NodeIndices[node_index];
00380
00381 element_data.NodeIndices[node_index]--;
00382 }
00383
00384 return element_data;
00385 }
00386
00387 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00388 ElementData GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextCableElementData()
00389 {
00390 NEVER_REACHED;
00391 }
00392
00393 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00394 ElementData GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextFaceData()
00395 {
00396 ElementData face_data;
00397 face_data.NodeIndices.resize(mNodesPerBoundaryElement);
00398 face_data.AttributeValue = 0.0;
00399
00400 std::string this_line;
00401 std::stringstream line(this_line);
00402
00403 unsigned face_index;
00404 unsigned face_type;
00405 unsigned face_attributes=0;
00406 bool surface_element_found = false;
00407
00408 while(!surface_element_found)
00409 {
00410 getline(mFaceFile, this_line);
00411 line.clear();
00412 line.str(this_line);
00413
00414 line >> face_index >> face_type >> face_attributes;
00415
00416 if((ELEMENT_DIM == 2 && (face_type == GmshTypes::LINE || face_type == GmshTypes::QUADRATIC_LINE) ) ||
00417 (ELEMENT_DIM == 3 && (face_type == GmshTypes::TRIANGLE || face_type == GmshTypes::QUADRATIC_TRIANGLE)))
00418 {
00419 surface_element_found = true;
00420 }
00421 }
00422
00423
00424
00425 if(face_attributes > 0)
00426 {
00427 mNumFaceAttributes = 1u;
00428 line >> face_data.AttributeValue;
00429 }
00430 unsigned unused_attr;
00431 for(unsigned attr_index = 0; attr_index < (face_attributes-1); ++attr_index)
00432 {
00433 line >> unused_attr;
00434 }
00435
00436
00437 for(unsigned node_index = 0; node_index < mNodesPerBoundaryElement; ++node_index)
00438 {
00439 line >> face_data.NodeIndices[node_index];
00440
00441 face_data.NodeIndices[node_index]--;
00442 }
00443
00444 return face_data;
00445 }
00446
00447 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00448 std::vector<double> GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned index)
00449 {
00450 NEVER_REACHED;
00451 }
00452
00453 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00454 ElementData GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementData(unsigned index)
00455 {
00456 NEVER_REACHED;
00457 }
00458
00459 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00460 ElementData GmshMeshReader<ELEMENT_DIM, SPACE_DIM>::GetFaceData(unsigned index)
00461 {
00462 NEVER_REACHED;
00463 }
00464
00466
00468
00469 template class GmshMeshReader<0,1>;
00470 template class GmshMeshReader<1,1>;
00471 template class GmshMeshReader<1,2>;
00472 template class GmshMeshReader<1,3>;
00473 template class GmshMeshReader<2,2>;
00474 template class GmshMeshReader<2,3>;
00475 template class GmshMeshReader<3,3>;