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

Generated on Mon Nov 1 12:35:23 2010 for Chaste by  doxygen 1.5.5