MemfemMeshReader.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
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 "MemfemMeshReader.hpp"
00030 #include "Exception.hpp"
00031 
00032 #include <sstream>
00033 
00035 // Implementation
00037 
00038 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00039 MemfemMeshReader<ELEMENT_DIM, SPACE_DIM>::MemfemMeshReader(const std::string& rPathBaseName)
00040 {
00041     // Open node file and store the lines as a vector of strings (minus the comments)
00042     std::string node_file_name = rPathBaseName + ".pts";
00043     this->mNodeRawData = this->GetRawDataFromFile(node_file_name);
00044 
00045     // Read single line header which is the number of nodes */
00046     std::stringstream node_header_stream(this->mNodeRawData[0]);
00047     unsigned num_nodes;
00048     node_header_stream >> num_nodes;
00049 
00050     // All Memfem data is in 3D
00051     if (SPACE_DIM != 3  || ELEMENT_DIM != 3)
00052     {
00053         EXCEPTION("You have asked to read non-3D data. All Memfem data is in 3D.");
00054     }
00055 
00056     // Read the rest of the node data using TokenizeStringsToDoubles method
00057     this->mNodeData = TokenizeStringsToDoubles(this->mNodeRawData);
00058 
00059     // Initialise iterator for public GetNextNode method
00060     this->mpNodeIterator = this->mNodeData.begin();
00061 
00062     // Check that the size of the data matches the information in the header
00063     if (num_nodes != this->mNodeData.size())
00064     {
00065         // ignored from coverage because otherwise would have to create files
00066         // for a bad mesh just to test this line
00067 #define COVERAGE_IGNORE
00068         EXCEPTION("Number of nodes does not match expected number declared in header");
00069 #undef COVERAGE_IGNORE
00070     }
00071 
00072     // Open element file and store the lines as a vector of strings (minus the comments)
00073     std::string element_file_name = rPathBaseName + ".tetras";
00074     this->mElementRawData = this->GetRawDataFromFile(element_file_name);
00075 
00076     // Read single line header which is the number of elements
00077     std::stringstream element_header_stream(this->mElementRawData[0]);
00078     unsigned num_elements;
00079     element_header_stream >> num_elements;
00080 
00081     // Read the rest of the element data using TokenizeStringsToInts method
00082     this->mElementData = TokenizeStringsToInts(this->mElementRawData, SPACE_DIM+1, true);
00083     this->mpElementIterator = this->mElementData.begin();
00084 
00085     // Check that the size of the data matches the information in the header
00086     if (num_elements != this->mElementData.size())
00087     {
00088         // Ignored from coverage because otherwise we would have to create files
00089         // for a bad mesh just to test this line
00090 #define COVERAGE_IGNORE
00091         EXCEPTION("Number of elements does not match expected number declared in header");
00092 #undef COVERAGE_IGNORE
00093     }
00094 
00095     // Open boundary face file and store the lines as a vector of strings (minus the comments)
00096     std::string face_file_name = rPathBaseName + ".tri";
00097     this->mFaceRawData = this->GetRawDataFromFile(face_file_name);
00098 
00099     // There is no header
00100 
00101     // Read the face/edge data using TokenizeStringsToInts method
00102     this->mFaceData = TokenizeStringsToInts(this->mFaceRawData, SPACE_DIM, false);
00103     this->mpFaceIterator = this->mFaceData.begin();
00104 }
00105 
00106 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00107 MemfemMeshReader<ELEMENT_DIM, SPACE_DIM>::~MemfemMeshReader()
00108 {}
00109 
00110 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00111 std::vector<std::vector<double> > MemfemMeshReader<ELEMENT_DIM, SPACE_DIM>::TokenizeStringsToDoubles(
00112     const std::vector<std::string>& rRawData)
00113 {
00114     std::vector<std::vector<double> > tokenized_data; // Output
00115 
00116     // Iterate over the lines of input
00117     std::vector<std::string>::const_iterator the_iterator;
00118     for (the_iterator = rRawData.begin(); the_iterator != rRawData.end(); the_iterator++ )
00119     {
00120         const std::string& line_of_data = *the_iterator;
00121         std::stringstream line_stream(line_of_data);
00122 
00123         if (the_iterator != rRawData.begin()) // Ignore the header string
00124         {
00125             std::vector<double> current_coords;
00126 
00127             // Form the vector which represents the position of this item
00128             for (unsigned i=0; i<SPACE_DIM; i++)
00129             {
00130                 double item_coord;
00131                 line_stream >> item_coord;
00132                 current_coords.push_back(item_coord);
00133             }
00134 
00135             // Put item onto main output vector
00136             tokenized_data.push_back(current_coords);
00137         }
00138     }
00139 
00140     return tokenized_data;
00141 }
00142 
00143 template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00144 std::vector<std::vector<unsigned> > MemfemMeshReader<ELEMENT_DIM, SPACE_DIM>::TokenizeStringsToInts(
00145     const std::vector<std::string>& rRawData,
00146     unsigned dimensionOfObject,
00147     bool readHeader)
00148 {
00149     std::vector<std::vector<unsigned> > tokenized_data;
00150 
00151     std::vector<std::string>::const_iterator the_iterator;
00152     for (the_iterator = rRawData.begin(); the_iterator != rRawData.end(); the_iterator++ )
00153     {
00154         const std::string& line_of_data = *the_iterator;
00155         std::stringstream line_stream(line_of_data);
00156 
00157         if ( readHeader == false || the_iterator != rRawData.begin() )
00158         {
00159             std::vector<unsigned> current_indices;
00160 
00161             for (unsigned i=0; i<dimensionOfObject; i++)
00162             {
00163                 unsigned item_index;
00164                 line_stream >> item_index;
00165                 // The nodes have been indexed from one so we need to shift the indices
00166                 item_index -= 1;
00167                 current_indices.push_back(item_index);
00168             }
00169 
00170             tokenized_data.push_back(current_indices);
00171         }
00172     }
00173 
00174     return tokenized_data;
00175 }
00176 
00178 // Explicit instantiation
00180 
00181 template class MemfemMeshReader<1,1>;
00182 template class MemfemMeshReader<1,2>;
00183 template class MemfemMeshReader<1,3>;
00184 template class MemfemMeshReader<2,2>;
00185 template class MemfemMeshReader<2,3>;
00186 template class MemfemMeshReader<3,3>;
Generated on Thu Dec 22 13:00:16 2011 for Chaste by  doxygen 1.6.3