TrianglesMeshReader.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "TrianglesMeshReader.hpp"
00030 #include "Exception.hpp"
00031 #include <cassert>
00032 #include <sstream>
00033 #include <iostream>
00034 
00035 const static char* NODES_FILE_EXTENSION = ".node";
00036 const static char* ELEMENTS_FILE_EXTENSION = ".ele";
00037 const static char* FACES_FILE_EXTENSION = ".face";
00038 const static char* EDGES_FILE_EXTENSION = ".edge";
00039 
00041 // Implementation
00043 
00044 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00045 TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::TrianglesMeshReader(std::string pathBaseName,
00046                                                                  unsigned orderOfElements,
00047                                                                  unsigned orderOfBoundaryElements,
00048                                                                  bool readContainingElementForBoundaryElements)
00049     : mFilesBaseName(pathBaseName),
00050       mNodeItemWidth(0),
00051       mElementItemWidth(0),
00052       mFaceItemWidth(0),
00053       mNumNodes(0),
00054       mNumElements(0),
00055       mNumFaces(0),
00056       mNodesRead(0),
00057       mElementsRead(0),
00058       mFacesRead(0),
00059       mBoundaryFacesRead(0),
00060       mNumElementAttributes(0),
00061       mNumFaceAttributes(0),
00062       mOrderOfElements(orderOfElements),
00063       mOrderOfBoundaryElements(orderOfBoundaryElements),
00064       mEofException(false),
00065       mReadContainingElementOfBoundaryElement(readContainingElementForBoundaryElements),
00066       mFilesAreBinary(false),
00067       mMeshIsHexahedral(false)
00068 {
00069     // Only linear and quadratic elements
00070     assert(orderOfElements==1 || orderOfElements==2);
00071     if ( mOrderOfBoundaryElements == 2 &&  mReadContainingElementOfBoundaryElement)
00072     {
00073         EXCEPTION("Boundary element file should not have containing element info if it is quadratic");
00074     }
00075     if (mOrderOfElements==1)
00076     {
00077         mNodesPerElement = ELEMENT_DIM+1;
00078     }
00079     else
00080     {
00081         #define COVERAGE_IGNORE
00082         assert(SPACE_DIM==ELEMENT_DIM);
00083         #undef COVERAGE_IGNORE
00084         mNodesPerElement = (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2;
00085     }
00086 
00087     if (mOrderOfBoundaryElements==1)
00088     {
00089         mNodesPerBoundaryElement = ELEMENT_DIM;
00090     }
00091     else
00092     {
00093         #define COVERAGE_IGNORE
00094         assert(SPACE_DIM==ELEMENT_DIM);
00095         #undef COVERAGE_IGNORE
00096         mNodesPerBoundaryElement = ELEMENT_DIM*(ELEMENT_DIM+1)/2;
00097     }
00098 
00099     mIndexFromZero = false; // Initially assume that nodes are not numbered from zero
00100 
00101     OpenFiles();
00102     ReadHeaders();
00103 }
00104 
00105 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00106 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00107 {
00108     return mNumElements;
00109 }
00110 
00111 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00112 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00113 {
00114     return mNumNodes;
00115 }
00116 
00117 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00118 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaces() const
00119 {
00120     return mNumFaces;
00121 }
00122 
00123 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00124 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumEdges() const
00125 {
00126     return mNumFaces;
00127 }
00128 
00129 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00130 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElementAttributes() const
00131 {
00132     return mNumElementAttributes;
00133 }
00134 
00135 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00136 unsigned TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaceAttributes() const
00137 {
00138     return mNumFaceAttributes;
00139 }
00140 
00141 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00142 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::Reset()
00143 {
00144     CloseFiles();
00145 
00146     mNodesRead = 0;
00147     mElementsRead = 0;
00148     mFacesRead = 0;
00149     mBoundaryFacesRead = 0;
00150     mEofException = false;
00151 
00152     OpenFiles();
00153     ReadHeaders();
00154 }
00155 
00156 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00157 std::vector<double> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextNode()
00158 {
00159     std::vector<double> ret_coords(SPACE_DIM);
00160 
00161     // There are no attributes to read with node coordinates
00162     const unsigned num_attributes = 0u;
00163     unsigned empty = 0u;
00164     GetNextItemFromStream(mNodesFile, mNodesRead, ret_coords, num_attributes, empty);
00165 
00166     mNodesRead++;
00167     return ret_coords;
00168 }
00169 
00170 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00171 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextElementData()
00172 {
00173     ElementData element_data;
00174     element_data.NodeIndices.resize(mNodesPerElement);
00175     element_data.AttributeValue = 0; // If an attribute is not read this stays as zero, otherwise overwritten.
00176     GetNextItemFromStream(mElementsFile, mElementsRead, element_data.NodeIndices, mNumElementAttributes,
00177                           element_data.AttributeValue);
00178 
00179     EnsureIndexingFromZero(element_data.NodeIndices);
00180 
00181     mElementsRead++;
00182     return element_data;
00183 }
00184 
00185 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00186 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextFaceData()
00187 {
00188     ElementData face_data;
00189     std::vector<unsigned> ret_indices;
00190 
00191     // In the first case there's no file, all the nodes are set as faces
00192     if (ELEMENT_DIM == 1)
00193     {
00194         ret_indices.push_back( mOneDimBoundary[mBoundaryFacesRead] );
00195     }
00196     else
00197     {
00198         ret_indices.resize(mNodesPerBoundaryElement);
00199 
00200         assert(ELEMENT_DIM != 0); //Covered in earlier exception, but needed in loop guard here.
00201         do
00202         {
00203             face_data.AttributeValue = 1u; // If an attribute is not read this stays as one, otherwise overwritten.
00204 
00205 
00206             if (mReadContainingElementOfBoundaryElement)
00207             {
00208                 assert(mNumFaceAttributes == 0);
00209                 GetNextItemFromStream(mFacesFile, mFacesRead, ret_indices, 1,
00210                                       face_data.ContainingElement);
00211             }
00212             else
00213             {
00214                 GetNextItemFromStream(mFacesFile, mFacesRead, ret_indices, mNumFaceAttributes,
00215                                       face_data.AttributeValue);
00216             }
00217 
00218             EnsureIndexingFromZero(ret_indices);
00219 
00220             mFacesRead++;
00221         }
00222         while (ELEMENT_DIM==2 && face_data.AttributeValue==0); //In triangles format we ignore internal edges (which are marked with attribute 0)
00223     }
00224 
00225     mBoundaryFacesRead++;
00226     face_data.NodeIndices = ret_indices;
00227     return face_data;
00228 }
00229 
00230 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00231 std::vector<double> TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNode(unsigned index)
00232 {
00233     if (!mFilesAreBinary)
00234     {
00235         EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00236     }
00237     if (index >= mNumNodes)
00238     {
00239         EXCEPTION("Node does not exist - not enough nodes.");
00240     }
00241     // Put the file stream pointer to the right location
00242     mNodesFile.seekg(mNodeFileDataStart + mNodeItemWidth*index, std::ios_base::beg);
00243     // Read the next item.
00244     return GetNextNode();
00245 }
00246 
00247 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00248 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetElementData(unsigned index)
00249 {
00250     if (!mFilesAreBinary)
00251     {
00252         EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00253     }
00254     if (index >=mNumElements)
00255     {
00256         EXCEPTION("Element does not exist - not enough elements.");
00257     }
00258 
00259     // Put the file stream pointer to the right location
00260     mElementsFile.seekg(mElementFileDataStart + mElementItemWidth*index, std::ios_base::beg);
00261     // Read the next item.
00262     return GetNextElementData();
00263 }
00264 
00265 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00266 ElementData TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetFaceData(unsigned index)
00267 {
00268     if (!mFilesAreBinary)
00269     {
00270         EXCEPTION("Random access is only implemented in mesh readers for binary mesh files.");
00271     }
00272     if (index >=mNumFaces)
00273     {
00274         EXCEPTION("Face does not exist - not enough faces.");
00275     }
00276     // Put the file stream pointer to the right location
00277     mFacesFile.seekg(mFaceFileDataStart + mFaceItemWidth*index, std::ios_base::beg);
00278     // Read the next item.
00279     return GetNextFaceData();
00280 }
00281 
00282 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00283 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFiles()
00284 {
00285     OpenNodeFile();
00286     OpenElementsFile();
00287     OpenFacesFile();
00288 }
00289 
00290 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00291 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenNodeFile()
00292 {
00293     // Nodes definition
00294     std::string file_name = mFilesBaseName + NODES_FILE_EXTENSION;
00295     mNodesFile.open(file_name.c_str());
00296     if (!mNodesFile.is_open())
00297     {
00298         EXCEPTION("Could not open data file: " + file_name);
00299     }
00300 }
00301 
00302 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00303 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenElementsFile()
00304 {
00305     // Elements definition
00306     std::string file_name;
00307     if (ELEMENT_DIM == SPACE_DIM)
00308     {
00309         file_name = mFilesBaseName + ELEMENTS_FILE_EXTENSION;
00310     }
00311     else
00312     {
00313         if (ELEMENT_DIM == 1)
00314         {
00315             file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00316         }
00317         else if (ELEMENT_DIM == 2)
00318         {
00319             file_name = mFilesBaseName + FACES_FILE_EXTENSION;
00320         }
00321         else
00322         {
00323             EXCEPTION("Can't have a zero-dimensional mesh in a one-dimensional space");
00324         }
00325     }
00326 
00327     mElementsFile.open(file_name.c_str());
00328     if (!mElementsFile.is_open())
00329     {
00330         EXCEPTION("Could not open data file: " + file_name);
00331     }
00332 }
00333 
00334 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00335 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFacesFile()
00336 {
00337     // Faces/edges definition
00338     std::string file_name;
00339     if (ELEMENT_DIM == 3)
00340     {
00341         file_name = mFilesBaseName + FACES_FILE_EXTENSION;
00342     }
00343     else if (ELEMENT_DIM == 2)
00344     {
00345         file_name = mFilesBaseName + EDGES_FILE_EXTENSION;
00346     }
00347     else //if (ELEMENT_DIM == 1)
00348     {
00349         // There is no file, data will be read from the node file (with boundaries marked)
00350         return;
00351     }
00352 
00353     mFacesFile.open(file_name.c_str());
00354     if (!mFacesFile.is_open())
00355     {
00356         EXCEPTION("Could not open data file: " + file_name);
00357     }
00358 }
00359 
00360 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00361 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadHeaders()
00362 {
00363     /*
00364      *  Reading node file header
00365      */
00366     std::string buffer;
00367     GetNextLineFromStream(mNodesFile, buffer);
00368     std::stringstream node_header_line(buffer);
00369     unsigned dimension;
00370     node_header_line >> mNumNodes >> dimension >> mNumNodeAttributes >> mMaxNodeBdyMarker;
00371     if (SPACE_DIM != dimension)
00372     {
00373         EXCEPTION("SPACE_DIM  != dimension read from file ");
00374     }
00375     //Is there anything else on the header line?
00376     std::string extras;
00377     node_header_line >> extras;
00378     if (extras == "BIN")
00379     {
00380         mFilesAreBinary = true;
00381         mNodeFileDataStart = mNodesFile.tellg(); // Record the position of the first byte after the header.
00382         mNodeItemWidth = SPACE_DIM * sizeof(double);
00383         //We enforce that all binary files (written by Chaste) are indexed from zero
00384         mIndexFromZero = true;
00385     }
00386     else
00387     {
00388         // Get the next line to see if it is indexed from zero or not
00389         GetNextLineFromStream(mNodesFile, buffer);
00390         std::stringstream node_first_line(buffer);
00391         unsigned first_index;
00392         node_first_line >> first_index;
00393         assert(first_index == 0 || first_index == 1);
00394         mIndexFromZero = (first_index == 0);
00395         // Close, reopen, skip header
00396         mNodesFile.close();
00397         OpenNodeFile();
00398         GetNextLineFromStream(mNodesFile, buffer);
00399     }
00400 
00401     /*
00402      *  Reading element file header
00403      */
00404     GetNextLineFromStream(mElementsFile, buffer);
00405     std::stringstream element_header_line(buffer);
00406 
00407     unsigned extra_attributes = 0;
00408 
00409     if (ELEMENT_DIM == SPACE_DIM)
00410     {
00411         element_header_line >> mNumElements >> mNumElementNodes >> mNumElementAttributes;
00412 
00413         extra_attributes = mNumElementAttributes;
00414 
00415         //Is there anything else on the header line?
00416         std::string element_extras;
00417         element_header_line >> element_extras;
00418         if (element_extras == "BIN")
00419         {
00420             //Double check for binaryness
00421             assert (mFilesAreBinary);
00422         }
00423         else if (element_extras == "HEX")
00424         {
00425             mMeshIsHexahedral = true;
00426             if ( ELEMENT_DIM == 2 )
00427             {
00428                 mNodesPerElement = 4;
00429                 mNodesPerBoundaryElement = 2;
00430             }
00431             if ( ELEMENT_DIM == 3 )
00432             {
00433                 mNodesPerElement = 8;
00434                 mNodesPerBoundaryElement = 4;
00435             }
00436         }
00437         else
00438         {
00439             assert (element_extras == "");
00440         }
00441 
00442         if ( mNumElementNodes != mNodesPerElement )
00443         {
00444             std::stringstream error;
00445             error << "Number of nodes per elem, " << mNumElementNodes << ", does not match "
00446                   << "expected number, " << mNodesPerElement << " (which is calculated given "
00447                   << "the order of elements chosen, " << mOrderOfElements << " (1=linear, 2=quadratics)";
00448             EXCEPTION(error.str());
00449         }
00450     }
00451     else
00452     {
00453         element_header_line >> mNumElements >> mNumFaceAttributes;
00454 
00455         extra_attributes = mNumFaceAttributes;
00456 
00457         //Is there anything else on the header line?
00458         std::string element_extras;
00459         element_header_line >> element_extras;
00460         if (element_extras == "BIN")
00461         {
00462             //Double check for binaryness
00463             assert (mFilesAreBinary);
00464         }
00465 
00466         mNodesPerElement = ELEMENT_DIM+1;
00467     }
00468 
00469 
00470     if (mFilesAreBinary)
00471     {
00472         mElementFileDataStart = mElementsFile.tellg(); // Record the position of the first byte after the header.
00473         mElementItemWidth = (mNodesPerElement + extra_attributes) * sizeof(unsigned);
00474     }
00475 
00476     /*
00477      *  Reading face/edge file header
00478      */
00479     if (ELEMENT_DIM == 1)
00480     {
00481        GetOneDimBoundary();
00482        mNumFaces = mOneDimBoundary.size();
00483     }
00484     else
00485     {
00486         GetNextLineFromStream(mFacesFile, buffer);
00487         std::stringstream face_header_line(buffer);
00488 
00489         face_header_line >> mNumFaces >> mNumFaceAttributes;
00490         assert(mNumFaceAttributes==0 || mNumFaceAttributes==1);
00491         // if mNumFaceAttributes=1 then loop over and set mNumFaces to be
00492         // the number of faces which are marked as boundary faces
00493         //Double check for binaryness
00494         std::string face_extras;
00495         face_header_line >> face_extras;
00496         assert (mFilesAreBinary == (face_extras == "BIN"));
00497         if ((mNumFaceAttributes==1))
00498         {
00499             unsigned num_boundary_faces = 0;
00500             bool end_of_file=false;
00501             while (!end_of_file)
00502             {
00503                 try
00504                 {
00505                     GetNextFaceData();
00506                     num_boundary_faces++;
00507                 }
00508                 catch(Exception& e)
00509                 {
00510                     if(mEofException)
00511                     {
00512                         end_of_file = true;
00513                     }
00514                     else
00515                     {
00516                         throw e;
00517                     }
00518                 }
00519             }
00520             mNumFaces = num_boundary_faces;
00521 
00524 //            if(mNumFaces==0)
00525 //            {
00526 //                EXCEPTION("No boundary elements found. NOTE: elements in face/edge file with an attribute value of 0 are considered to be internal (non-boundary) elements");
00527 //            }
00528 
00529             // close the file, reopen, and skip the header again
00530             mFacesFile.close();
00531             mFacesFile.clear(); // Older versions of gcc don't explicitly reset "fail" and "eof" flags in std::ifstream after calling close()
00532             OpenFacesFile();
00533             GetNextLineFromStream(mFacesFile, buffer);
00534             mFacesRead = 0;
00535             mBoundaryFacesRead = 0;
00536         }
00537     }
00538 
00539     if (mFilesAreBinary)
00540     {
00541         mFaceFileDataStart = mFacesFile.tellg(); // Record the position of the first byte after the header.
00542         mFaceItemWidth = (ELEMENT_DIM + mNumFaceAttributes) * sizeof(unsigned);
00543     }
00544 }
00545 
00546 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00547 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::CloseFiles()
00548 {
00549     mNodesFile.close();
00550     mElementsFile.close();
00551     mFacesFile.close();
00552 }
00553 
00554 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00555 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextLineFromStream(std::ifstream& rFileStream, std::string& rRawLine)
00556 {
00557     bool line_is_blank;
00558     mEofException = false;
00559     do
00560     {
00561         getline(rFileStream, rRawLine);
00562         if (rFileStream.eof())
00563         {
00564             mEofException = true;
00565             EXCEPTION("File contains incomplete data: unexpected end of file.");
00566         }
00567 
00568         // Get rid of any comment
00569         rRawLine = rRawLine.substr(0, rRawLine.find('#',0));
00570 
00571         line_is_blank = (rRawLine.find_first_not_of(" \t",0) == std::string::npos);
00572     }
00573     while (line_is_blank);
00574 }
00575 
00576 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00577 template<class T>
00578 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextItemFromStream(std::ifstream& rFileStream, unsigned expectedItemNumber,
00579                                std::vector<T>& rDataPacket, const unsigned& rNumAttributes, unsigned& rAttribute)
00580 {
00581     if (mFilesAreBinary)
00582     {
00583         rFileStream.read((char*)&rDataPacket[0], rDataPacket.size()*sizeof(T));
00584         if (rNumAttributes>0)
00585         {
00586             assert(rNumAttributes == 1);
00587             rFileStream.read((char*) &rAttribute, sizeof(unsigned));
00588         }
00589     }
00590     else
00591     {
00592         std::string buffer;
00593         GetNextLineFromStream(rFileStream,buffer);
00594         std::stringstream buffer_stream(buffer);
00595 
00596         unsigned item_index;
00597         buffer_stream >> item_index;
00598 
00599         // If we are indexing from zero our expected item number is one larger.
00600         expectedItemNumber += mIndexFromZero ? 0 : 1;
00601 
00602         if (item_index != expectedItemNumber)
00603         {
00604             std::stringstream error;
00605             if (!mIndexFromZero)
00606             { // To fix the exception message to agree with file format.
00607                 expectedItemNumber--;
00608             }
00609             error << "Data for item " << expectedItemNumber << " missing";
00610             EXCEPTION(error.str());
00611         }
00612 
00613         for (unsigned i=0; i<rDataPacket.size(); i++)
00614         {
00615             buffer_stream >> rDataPacket[i];
00616         }
00617 
00618         if (rNumAttributes>0)
00619         {
00620             assert(rNumAttributes == 1);
00621             buffer_stream >> rAttribute;
00622         }
00623     }
00624 }
00625 
00626 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00627 std::string TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetMeshFileBaseName()
00628 {
00629     return mFilesBaseName;
00630 }
00631 
00632 
00633 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00634 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::GetOneDimBoundary()
00635 {
00636     assert(ELEMENT_DIM == 1);
00637     if (!mOneDimBoundary.empty())
00638     {
00639         //We have already read this and have reset the reader (probably from the mesh class)...
00640         return;
00641     }
00642 
00643     std::vector<unsigned> node_indices(2);
00644     unsigned dummy_attribute;
00645     //Count how many times we see each node
00646     std::vector<unsigned> node_count(mNumNodes);//Covers the case if it's indexed from 1
00647     for (unsigned element_index=0; element_index<mNumElements;element_index++)
00648     {
00649         GetNextItemFromStream(mElementsFile, element_index, node_indices, mNumElementAttributes, dummy_attribute);
00650         if (!mIndexFromZero)
00651         {
00652             //Adjust so we are indexing from zero
00653             node_indices[0]--;
00654             node_indices[1]--;
00655         }
00656         node_count[node_indices[0]]++;
00657         node_count[node_indices[1]]++;
00658     }
00659     //Find the ones which are terminals (only one mention)
00660     for (unsigned node_index=0; node_index<mNumNodes;node_index++)
00661     {
00662         if (node_count[node_index] == 1u)
00663         {
00664             mOneDimBoundary.push_back(node_index);
00665         }
00666     }
00667 
00668     // close the file, reopen, and skip the header again
00669     mElementsFile.close();
00670     mElementsFile.clear(); // Older versions of gcc don't explicitly reset "fail" and "eof" flags in std::ifstream after calling close()
00671     OpenElementsFile();
00672     std::string buffer;
00673     GetNextLineFromStream(mElementsFile, buffer);
00674 }
00675 
00676 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00677 void TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::EnsureIndexingFromZero(std::vector<unsigned>& rNodeIndices)
00678 {
00679 
00680     if (!mIndexFromZero) // If node indices do not start at zero move them all down one so they do
00681     {
00682         for (unsigned i=0; i<rNodeIndices.size(); i++)
00683         {
00684             rNodeIndices[i]--;
00685         }
00686     }
00687 
00688 }
00689 
00690 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00691 bool TrianglesMeshReader<ELEMENT_DIM, SPACE_DIM>::IsFileFormatBinary()
00692 {
00693     return mFilesAreBinary;
00694 }
00695 
00697 // Explicit instantiation
00699 
00700 template class TrianglesMeshReader<0,1>;
00701 template class TrianglesMeshReader<1,1>;
00702 template class TrianglesMeshReader<1,2>;
00703 template class TrianglesMeshReader<1,3>;
00704 template class TrianglesMeshReader<2,2>;
00705 template class TrianglesMeshReader<2,3>;
00706 template class TrianglesMeshReader<3,3>;
00707 
00708 
00713 template void TrianglesMeshReader<0,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00714 template void TrianglesMeshReader<0,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);
00715 template void TrianglesMeshReader<1,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00716 template void TrianglesMeshReader<1,1>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);
00717 template void TrianglesMeshReader<1,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00718 template void TrianglesMeshReader<1,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);
00719 template void TrianglesMeshReader<1,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00720 template void TrianglesMeshReader<1,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);
00721 template void TrianglesMeshReader<2,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00722 template void TrianglesMeshReader<2,2>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);
00723 template void TrianglesMeshReader<2,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00724 template void TrianglesMeshReader<2,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);
00725 template void TrianglesMeshReader<3,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<unsigned>&, const unsigned&, unsigned&);
00726 template void TrianglesMeshReader<3,3>::GetNextItemFromStream(std::ifstream&, unsigned, std::vector<double>  &, const unsigned&, unsigned&);

Generated by  doxygen 1.6.2