Chaste Release::3.1
VertexMeshReader.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 #include "VertexMeshReader.hpp"
00036 #include "Exception.hpp"
00037 
00038 #include <sstream>
00039 
00040 
00041 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00042 VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::VertexMeshReader(std::string pathBaseName)
00043     : mFilesBaseName(pathBaseName),
00044       mIndexFromZero(false), // initially assume that nodes are not numbered from zero
00045       mNumNodes(0),
00046       mNumElements(0),
00047       mNodesRead(0),
00048       mElementsRead(0),
00049       mNumElementAttributes(0)
00050 {
00051     OpenFiles();
00052     ReadHeaders();
00053 }
00054 
00055 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00056 unsigned VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElements() const
00057 {
00058     return mNumElements;
00059 }
00060 
00061 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00062 unsigned VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumNodes() const
00063 {
00064     return mNumNodes;
00065 }
00066 
00067 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00068 unsigned VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumElementAttributes() const
00069 {
00070     return mNumElementAttributes;
00071 }
00072 
00073 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00074 unsigned VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumFaces() const
00075 {
00077     return 0;
00078 }
00079 
00080 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00081 ElementData VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextFaceData()
00082 {
00084     ElementData ret;
00085     ret.NodeIndices = std::vector<unsigned>();
00086     ret.AttributeValue = 0;
00087     return ret;
00088 }
00089 
00090 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00091 unsigned VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNumEdges() const
00092 {
00094     return 0;
00095 }
00096 
00097 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00098 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::Reset()
00099 {
00100     CloseFiles();
00101     OpenFiles();
00102     ReadHeaders();
00103 
00104     mNodesRead = 0;
00105     mElementsRead = 0;
00106 }
00107 
00108 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00109 std::vector<double> VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextNode()
00110 {
00111     std::vector<double> node_data;
00112 
00113     std::string buffer;
00114     GetNextLineFromStream(mNodesFile, buffer);
00115 
00116     std::stringstream buffer_stream(buffer);
00117 
00118     unsigned index;
00119     buffer_stream >> index;
00120 
00121     unsigned offset = mIndexFromZero ? 0 : 1;
00122     if (index != mNodesRead + offset)
00123     {
00124         EXCEPTION("Data for node " << mNodesRead << " missing");
00125     }
00126 
00127     double node_value;
00128     for (unsigned i=0; i<SPACE_DIM+1; i++)
00129     {
00130         buffer_stream >> node_value;
00131         node_data.push_back(node_value);
00132     }
00133 
00134     mNodesRead++;
00135     return node_data;
00136 }
00137 
00138 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00139 ElementData VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextElementData()
00140 {
00141     // Create data structure for this element
00142     ElementData element_data;
00143 
00144     std::string buffer;
00145     GetNextLineFromStream(mElementsFile, buffer);
00146 
00147     std::stringstream buffer_stream(buffer);
00148 
00149     unsigned element_index;
00150     buffer_stream >> element_index;
00151 
00152     unsigned offset = mIndexFromZero ? 0 : 1;
00153     if (element_index != mElementsRead + offset)
00154     {
00155         EXCEPTION("Data for element " << mElementsRead << " missing");
00156     }
00157 
00158     unsigned num_nodes_in_element;
00159     buffer_stream >> num_nodes_in_element;
00160 
00161     // Store node indices owned by this element
00162     unsigned node_index;
00163     for (unsigned i=0; i<num_nodes_in_element; i++)
00164     {
00165         buffer_stream >> node_index;
00166         element_data.NodeIndices.push_back(node_index - offset);
00167     }
00168 
00169     if (mNumElementAttributes > 0)
00170     {
00171         assert(mNumElementAttributes == 1);
00172 
00173         unsigned attribute_value;
00174         buffer_stream >> attribute_value;
00175         element_data.AttributeValue = attribute_value;
00176     }
00177     else
00178     {
00179         element_data.AttributeValue = 0;
00180     }
00181 
00182     mElementsRead++;
00183     return element_data;
00184 }
00185 
00186 
00187 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00188 VertexElementData VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextElementDataWithFaces()
00189 {
00190     // Create data structure for this element
00191     VertexElementData element_data;
00192 
00193     std::string buffer;
00194     GetNextLineFromStream(mElementsFile, buffer);
00195 
00196     std::stringstream buffer_stream(buffer);
00197 
00198     unsigned element_index;
00199     buffer_stream >> element_index;
00200 
00201     unsigned offset = mIndexFromZero ? 0 : 1;
00202     if (element_index != mElementsRead + offset)
00203     {
00204         EXCEPTION("Data for element " << mElementsRead << " missing");
00205     }
00206 
00207     // Get number of nodes owned by this element
00208     unsigned num_nodes_in_element;
00209     buffer_stream >> num_nodes_in_element;
00210 
00211     // Store node indices owned by this element
00212     unsigned node_index;
00213     for (unsigned i=0; i<num_nodes_in_element; i++)
00214     {
00215         buffer_stream >> node_index;
00216         element_data.NodeIndices.push_back(node_index - offset);
00217     }
00218 
00219     // Get number of faces owned by this element
00220     unsigned num_faces_in_element;
00221     buffer_stream >> num_faces_in_element;
00222 
00223     element_data.Faces.resize(num_faces_in_element);
00224     for (unsigned j=0; j<num_faces_in_element; j++)
00225     {
00226         // Create data structure for this face
00227         ElementData face_data;
00228 
00229         // Get face index
00230         unsigned face_index;
00231         buffer_stream >> face_index;
00232         face_data.AttributeValue = face_index;
00233 
00234         // Get number of nodes owned by this face
00235         unsigned num_nodes_in_face;
00236         buffer_stream >> num_nodes_in_face;
00237 
00238         // Store node indices owned by this face
00239         unsigned node_index;
00240         for (unsigned i=0; i<num_nodes_in_face; i++)
00241         {
00242             buffer_stream >> node_index;
00243             face_data.NodeIndices.push_back(node_index - offset);
00244         }
00245 
00247 
00248         element_data.Faces[j] = face_data;
00249     }
00250 
00251     if (mNumElementAttributes > 0)
00252     {
00253         assert(mNumElementAttributes==1);
00254 
00255         unsigned attribute_value;
00256         buffer_stream >> attribute_value;
00257         element_data.AttributeValue = attribute_value;
00258     }
00259     else
00260     {
00261         element_data.AttributeValue = 0;
00262     }
00263 
00264     mElementsRead++;
00265     return element_data;
00266 }
00267 
00268 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00269 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenFiles()
00270 {
00271     OpenNodeFile();
00272     OpenElementsFile();
00273 }
00274 
00275 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00276 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenNodeFile()
00277 {
00278     // Nodes definition
00279     std::string file_name = mFilesBaseName + ".node";
00280     mNodesFile.open(file_name.c_str());
00281     if (!mNodesFile.is_open())
00282     {
00283         EXCEPTION("Could not open data file: " + file_name);
00284     }
00285 }
00286 
00287 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00288 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::OpenElementsFile()
00289 {
00290     // Elements definition
00291     std::string file_name;
00292     file_name = mFilesBaseName + ".cell";
00293 
00294     mElementsFile.open(file_name.c_str());
00295     if (!mElementsFile.is_open())
00296     {
00297         EXCEPTION("Could not open data file: " + file_name);
00298     }
00299 }
00300 
00301 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00302 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::ReadHeaders()
00303 {
00304     std::string buffer;
00305 
00306     GetNextLineFromStream(mNodesFile, buffer);
00307     std::stringstream buffer_stream(buffer);
00308     buffer_stream >> mNumNodes >> mNumNodeAttributes;
00309 
00310     // Get the next line to see if nodes are indexed from zero or not
00311     GetNextLineFromStream(mNodesFile, buffer);
00312     std::stringstream node_buffer_stream(buffer);
00313 
00314     unsigned first_index;
00315     node_buffer_stream >> first_index;
00316     assert(first_index == 0 || first_index == 1);
00317     mIndexFromZero = (first_index == 0);
00318 
00319     // Close, reopen, skip header
00320     mNodesFile.close();
00321     OpenNodeFile();
00322     GetNextLineFromStream(mNodesFile, buffer);
00323 
00324     GetNextLineFromStream(mElementsFile, buffer);
00325     std::stringstream element_buffer_stream(buffer);
00326 
00327     element_buffer_stream >> mNumElements >> mNumElementAttributes;
00328 }
00329 
00330 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00331 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::CloseFiles()
00332 {
00333     mNodesFile.close();
00334     mElementsFile.close();
00335 }
00336 
00337 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00338 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextLineFromStream(std::ifstream& fileStream, std::string& rawLine)
00339 {
00340     bool line_is_blank;
00341 
00342     do
00343     {
00344         getline(fileStream, rawLine);
00345 
00346         if (fileStream.eof())
00347         {
00348             EXCEPTION("Cannot get the next line from node or element file due to incomplete data");
00349         }
00350 
00351         // Get rid of any comment
00352         rawLine = rawLine.substr(0,rawLine.find('#', 0));
00353 
00354         line_is_blank = (rawLine.find_first_not_of(" \t", 0) == std::string::npos);
00355     }
00356     while (line_is_blank);
00357 }
00358 
00360 // Explicit instantiation
00362 
00363 template class VertexMeshReader<1,1>;
00364 template class VertexMeshReader<1,2>;
00365 template class VertexMeshReader<1,3>;
00366 template class VertexMeshReader<2,2>;
00367 template class VertexMeshReader<2,3>;
00368 template class VertexMeshReader<3,3>;