Chaste  Release::2017.1
VertexMeshReader.cpp
1 /*
2 
3 Copyright (c) 2005-2017, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 #include "VertexMeshReader.hpp"
36 #include "Exception.hpp"
37 
38 #include <sstream>
39 
40 
41 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
43  : mFilesBaseName(pathBaseName),
44  mIndexFromZero(false), // initially assume that nodes are not numbered from zero
45  mNumNodes(0),
46  mNumElements(0),
47  mNodesRead(0),
48  mElementsRead(0),
49  mNumElementAttributes(0)
50 {
51  OpenFiles();
52  ReadHeaders();
53 }
54 
55 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
57 {
58  return mNumElements;
59 }
60 
61 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
63 {
64  return mNumNodes;
65 }
66 
67 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
69 {
70  return mNumElementAttributes;
71 }
72 
73 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
75 {
77  return 0;
78 }
79 
80 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
82 {
84  ElementData ret;
85  ret.NodeIndices = std::vector<unsigned>();
86  ret.AttributeValue = 0;
87  return ret;
88 }
89 
90 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
92 {
94  return 0;
95 }
96 
97 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
99 {
100  CloseFiles();
101  OpenFiles();
102  ReadHeaders();
103 
104  mNodesRead = 0;
105  mElementsRead = 0;
106 }
107 
108 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
110 {
111  std::vector<double> node_data;
112 
113  std::string buffer;
115 
116  std::stringstream buffer_stream(buffer);
117 
118  unsigned index;
119  buffer_stream >> index;
120 
121  unsigned offset = mIndexFromZero ? 0 : 1;
122  if (index != mNodesRead + offset)
123  {
124  EXCEPTION("Data for node " << mNodesRead << " missing");
125  }
126 
127  double node_value;
128  for (unsigned i=0; i<SPACE_DIM+1; i++)
129  {
130  buffer_stream >> node_value;
131  node_data.push_back(node_value);
132  }
133 
134  mNodesRead++;
135  return node_data;
136 }
137 
138 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
140 {
141  // Create data structure for this element
142  ElementData element_data;
143 
144  std::string buffer;
146 
147  std::stringstream buffer_stream(buffer);
148 
149  unsigned element_index;
150  buffer_stream >> element_index;
151 
152  unsigned offset = mIndexFromZero ? 0 : 1;
153  if (element_index != mElementsRead + offset)
154  {
155  EXCEPTION("Data for element " << mElementsRead << " missing");
156  }
157 
158  unsigned num_nodes_in_element;
159  buffer_stream >> num_nodes_in_element;
160 
161  // Store node indices owned by this element
162  unsigned node_index;
163  for (unsigned i=0; i<num_nodes_in_element; i++)
164  {
165  buffer_stream >> node_index;
166  element_data.NodeIndices.push_back(node_index - offset);
167  }
168 
169  if (mNumElementAttributes > 0)
170  {
171  assert(mNumElementAttributes == 1);
172 
173  buffer_stream >> element_data.AttributeValue;
174  }
175  else
176  {
177  element_data.AttributeValue = 0;
178  }
179 
180  mElementsRead++;
181  return element_data;
182 }
183 
184 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
186 {
187  // Create data structure for this element
188  VertexElementData element_data;
189 
190  std::string buffer;
192 
193  std::stringstream buffer_stream(buffer);
194 
195  unsigned element_index;
196  buffer_stream >> element_index;
197 
198  unsigned offset = mIndexFromZero ? 0 : 1;
199  if (element_index != mElementsRead + offset)
200  {
201  EXCEPTION("Data for element " << mElementsRead << " missing");
202  }
203 
204  // Get number of nodes owned by this element
205  unsigned num_nodes_in_element;
206  buffer_stream >> num_nodes_in_element;
207 
208  // Store node indices owned by this element
209  for (unsigned i=0; i<num_nodes_in_element; i++)
210  {
211  unsigned node_index;
212  buffer_stream >> node_index;
213  element_data.NodeIndices.push_back(node_index - offset);
214  }
215 
216  // Get number of faces owned by this element
217  unsigned num_faces_in_element;
218  buffer_stream >> num_faces_in_element;
219 
220  element_data.Faces.resize(num_faces_in_element);
221  for (unsigned j=0; j<num_faces_in_element; j++)
222  {
223  // Create data structure for this face
224  ElementData face_data;
225 
226  // Get face index
227  unsigned face_index;
228  buffer_stream >> face_index;
229  face_data.AttributeValue = face_index;
230 
231  // Get number of nodes owned by this face
232  unsigned num_nodes_in_face;
233  buffer_stream >> num_nodes_in_face;
234 
235  // Store node indices owned by this face
236  for (unsigned i=0; i<num_nodes_in_face; i++)
237  {
238  unsigned node_index_face;
239  buffer_stream >> node_index_face;
240  face_data.NodeIndices.push_back(node_index_face - offset);
241  }
242 
244 
245  element_data.Faces[j] = face_data;
246  }
247 
248  //For back compatibility (we always store attributes on elements now)
249  element_data.AttributeValue = 0;
250  if (mNumElementAttributes > 0)
251  {
252  assert(mNumElementAttributes==1);
253 
254  buffer_stream >> element_data.AttributeValue;
255  }
256 
257  mElementsRead++;
258  return element_data;
259 }
260 
261 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
263 {
264  OpenNodeFile();
266 }
267 
268 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
270 {
271  // Nodes definition
272  std::string file_name = mFilesBaseName + ".node";
273  mNodesFile.open(file_name.c_str());
274  if (!mNodesFile.is_open())
275  {
276  EXCEPTION("Could not open data file: " + file_name);
277  }
278 }
279 
280 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
282 {
283  // Elements definition
284  std::string file_name;
285  file_name = mFilesBaseName + ".cell";
286 
287  mElementsFile.open(file_name.c_str());
288  if (!mElementsFile.is_open())
289  {
290  EXCEPTION("Could not open data file: " + file_name);
291  }
292 }
293 
294 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
296 {
297  std::string buffer;
298 
300  std::stringstream buffer_stream(buffer);
301  buffer_stream >> mNumNodes >> mNumNodeAttributes;
302 
303  // Get the next line to see if nodes are indexed from zero or not
305  std::stringstream node_buffer_stream(buffer);
306 
307  unsigned first_index;
308  node_buffer_stream >> first_index;
309  assert(first_index == 0 || first_index == 1);
310  mIndexFromZero = (first_index == 0);
311 
312  // Close, reopen, skip header
313  mNodesFile.close();
314  OpenNodeFile();
316 
318  std::stringstream element_buffer_stream(buffer);
319 
320  element_buffer_stream >> mNumElements >> mNumElementAttributes;
321 }
322 
323 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
325 {
326  mNodesFile.close();
327  mElementsFile.close();
328 }
329 
330 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
331 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextLineFromStream(std::ifstream& fileStream, std::string& rawLine)
332 {
333  bool line_is_blank;
334 
335  do
336  {
337  getline(fileStream, rawLine);
338 
339  if (fileStream.eof())
340  {
341  EXCEPTION("Cannot get the next line from node or element file due to incomplete data");
342  }
343 
344  // Get rid of any comment
345  rawLine = rawLine.substr(0,rawLine.find('#', 0));
346 
347  line_is_blank = (rawLine.find_first_not_of(" \t", 0) == std::string::npos);
348  }
349  while (line_is_blank);
350 }
351 
353 
354 template class VertexMeshReader<1,1>;
355 template class VertexMeshReader<1,2>;
356 template class VertexMeshReader<1,3>;
357 template class VertexMeshReader<2,2>;
358 template class VertexMeshReader<2,3>;
359 template class VertexMeshReader<3,3>;
std::ifstream mElementsFile
VertexElementData GetNextElementDataWithFaces()
#define EXCEPTION(message)
Definition: Exception.hpp:143
ElementData GetNextFaceData()
unsigned mNumElementAttributes
unsigned GetNumElementAttributes() const
std::ifstream mNodesFile
std::vector< ElementData > Faces
void GetNextLineFromStream(std::ifstream &fileStream, std::string &rawLine)
std::vector< unsigned > NodeIndices
unsigned GetNumElements() const
VertexMeshReader(std::string pathBaseName)
unsigned GetNumNodes() const
unsigned GetNumEdges() const
ElementData GetNextElementData()
std::string mFilesBaseName
std::vector< double > GetNextNode()
unsigned GetNumFaces() const
std::vector< unsigned > NodeIndices