Chaste Release::3.1
PottsMeshReader.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 
00036 #include "PottsMeshReader.hpp"
00037 #include "Exception.hpp"
00038 
00039 #include <sstream>
00040 
00041 template<unsigned SPACE_DIM>
00042 PottsMeshReader<SPACE_DIM>::PottsMeshReader(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 SPACE_DIM>
00056 unsigned PottsMeshReader<SPACE_DIM>::GetNumElements() const
00057 {
00058     return mNumElements;
00059 }
00060 
00061 template<unsigned SPACE_DIM>
00062 unsigned PottsMeshReader<SPACE_DIM>::GetNumNodes() const
00063 {
00064     return mNumNodes;
00065 }
00066 
00067 template<unsigned SPACE_DIM>
00068 unsigned PottsMeshReader<SPACE_DIM>::GetNumElementAttributes() const
00069 {
00070     return mNumElementAttributes;
00071 }
00072 
00073 template<unsigned SPACE_DIM>
00074 ElementData PottsMeshReader<SPACE_DIM>::GetNextFaceData()
00075 {
00077     ElementData ret;
00078     ret.NodeIndices = std::vector<unsigned>();
00079     ret.AttributeValue = 0;
00080     return ret;
00081 }
00082 
00083 template<unsigned SPACE_DIM>
00084 unsigned PottsMeshReader<SPACE_DIM>::GetNumFaces() const
00085 {
00087     return 0;
00088 }
00089 
00090 template<unsigned SPACE_DIM>
00091 void PottsMeshReader<SPACE_DIM>::Reset()
00092 {
00093     CloseFiles();
00094     OpenFiles();
00095     ReadHeaders();
00096 
00097     mNodesRead = 0;
00098     mElementsRead = 0;
00099 }
00100 
00101 template<unsigned SPACE_DIM>
00102 std::vector<double> PottsMeshReader<SPACE_DIM>::GetNextNode()
00103 {
00104     std::vector<double> node_data;
00105 
00106     std::string buffer;
00107     GetNextLineFromStream(mNodesFile, buffer);
00108 
00109     std::stringstream buffer_stream(buffer);
00110 
00111     unsigned index;
00112     buffer_stream >> index;
00113 
00114     unsigned offset = mIndexFromZero ? 0 : 1;
00115     if (index != mNodesRead + offset)
00116     {
00117         EXCEPTION("Data for node " << mNodesRead << " missing");
00118     }
00119 
00120     double node_value;
00121     for (unsigned i=0; i<SPACE_DIM+1; i++)
00122     {
00123         buffer_stream >> node_value;
00124         node_data.push_back(node_value);
00125     }
00126 
00127     mNodesRead++;
00128     return node_data;
00129 }
00130 
00131 template<unsigned SPACE_DIM>
00132 ElementData PottsMeshReader<SPACE_DIM>::GetNextElementData()
00133 {
00134     // Create data structure for this element
00135     ElementData element_data;
00136 
00137     std::string buffer;
00138     GetNextLineFromStream(mElementsFile, buffer);
00139 
00140     std::stringstream buffer_stream(buffer);
00141 
00142     unsigned element_index;
00143     buffer_stream >> element_index;
00144 
00145     unsigned offset = mIndexFromZero ? 0 : 1;
00146     if (element_index != mElementsRead + offset)
00147     {
00148         EXCEPTION("Data for element " << mElementsRead << " missing");
00149     }
00150 
00151     unsigned num_nodes_in_element;
00152     buffer_stream >> num_nodes_in_element;
00153 
00154     // Store node indices owned by this element
00155     unsigned node_index;
00156     for (unsigned i=0; i<num_nodes_in_element; i++)
00157     {
00158         buffer_stream >> node_index;
00159         element_data.NodeIndices.push_back(node_index - offset);
00160     }
00161 
00162     if (mNumElementAttributes > 0)
00163     {
00164         assert(mNumElementAttributes==1);
00165 
00166         unsigned attribute_value;
00167         buffer_stream >> attribute_value;
00168         element_data.AttributeValue = attribute_value;
00169     }
00170     else
00171     {
00172         element_data.AttributeValue = 0;
00173     }
00174 
00175     mElementsRead++;
00176     return element_data;
00177 }
00178 
00179 template<unsigned SPACE_DIM>
00180 void PottsMeshReader<SPACE_DIM>::OpenFiles()
00181 {
00182     OpenNodeFile();
00183     OpenElementsFile();
00184 }
00185 
00186 template<unsigned SPACE_DIM>
00187 void PottsMeshReader<SPACE_DIM>::OpenNodeFile()
00188 {
00189     // Nodes definition
00190     std::string file_name = mFilesBaseName + ".node";
00191     mNodesFile.open(file_name.c_str());
00192     if (!mNodesFile.is_open())
00193     {
00194         EXCEPTION("Could not open data file: " + file_name);
00195     }
00196 }
00197 
00198 template<unsigned SPACE_DIM>
00199 void PottsMeshReader<SPACE_DIM>::OpenElementsFile()
00200 {
00201     // Elements definition
00202     std::string file_name;
00203     file_name = mFilesBaseName + ".cell";
00204 
00205     mElementsFile.open(file_name.c_str());
00206     if (!mElementsFile.is_open())
00207     {
00208         EXCEPTION("Could not open data file: " + file_name);
00209     }
00210 }
00211 
00212 template<unsigned SPACE_DIM>
00213 void PottsMeshReader<SPACE_DIM>::ReadHeaders()
00214 {
00215     std::string buffer;
00216 
00217     GetNextLineFromStream(mNodesFile, buffer);
00218     std::stringstream buffer_stream(buffer);
00219     buffer_stream >> mNumNodes >> mNumNodeAttributes;
00220 
00221     // Get the next line to see if nodes are indexed from zero or not
00222     GetNextLineFromStream(mNodesFile, buffer);
00223     std::stringstream node_buffer_stream(buffer);
00224 
00225     unsigned first_index;
00226     node_buffer_stream >> first_index;
00227     assert(first_index == 0 || first_index == 1);
00228     mIndexFromZero = (first_index == 0);
00229 
00230     // Close, reopen, skip header
00231     mNodesFile.close();
00232     OpenNodeFile();
00233     GetNextLineFromStream(mNodesFile, buffer);
00234 
00235     GetNextLineFromStream(mElementsFile, buffer);
00236     std::stringstream element_buffer_stream(buffer);
00237 
00238     element_buffer_stream >> mNumElements >> mNumElementAttributes;
00239 }
00240 
00241 template<unsigned SPACE_DIM>
00242 void PottsMeshReader<SPACE_DIM>::CloseFiles()
00243 {
00244     mNodesFile.close();
00245     mElementsFile.close();
00246 }
00247 
00248 template<unsigned SPACE_DIM>
00249 void PottsMeshReader<SPACE_DIM>::GetNextLineFromStream(std::ifstream& fileStream, std::string& rawLine)
00250 {
00251     bool line_is_blank;
00252 
00253     do
00254     {
00255         getline(fileStream, rawLine);
00256 
00257         if (fileStream.eof())
00258         {
00259             EXCEPTION("Cannot get the next line from node or element file due to incomplete data");
00260         }
00261 
00262         // Get rid of any comment
00263         rawLine = rawLine.substr(0,rawLine.find('#', 0));
00264 
00265         line_is_blank = (rawLine.find_first_not_of(" \t", 0) == std::string::npos);
00266     }
00267     while (line_is_blank);
00268 }
00269 
00271 // Explicit instantiation
00273 
00274 template class PottsMeshReader<1>;
00275 template class PottsMeshReader<2>;
00276 template class PottsMeshReader<3>;