Chaste  Release::3.4
VertexMeshReader.cpp
1 /*
2 
3 Copyright (c) 2005-2016, 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;
114  GetNextLineFromStream(mNodesFile, 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;
145  GetNextLineFromStream(mElementsFile, 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 
185 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
187 {
188  // Create data structure for this element
189  VertexElementData element_data;
190 
191  std::string buffer;
192  GetNextLineFromStream(mElementsFile, buffer);
193 
194  std::stringstream buffer_stream(buffer);
195 
196  unsigned element_index;
197  buffer_stream >> element_index;
198 
199  unsigned offset = mIndexFromZero ? 0 : 1;
200  if (element_index != mElementsRead + offset)
201  {
202  EXCEPTION("Data for element " << mElementsRead << " missing");
203  }
204 
205  // Get number of nodes owned by this element
206  unsigned num_nodes_in_element;
207  buffer_stream >> num_nodes_in_element;
208 
209  // Store node indices owned by this element
210  for (unsigned i=0; i<num_nodes_in_element; i++)
211  {
212  unsigned node_index;
213  buffer_stream >> node_index;
214  element_data.NodeIndices.push_back(node_index - offset);
215  }
216 
217  // Get number of faces owned by this element
218  unsigned num_faces_in_element;
219  buffer_stream >> num_faces_in_element;
220 
221  element_data.Faces.resize(num_faces_in_element);
222  for (unsigned j=0; j<num_faces_in_element; j++)
223  {
224  // Create data structure for this face
225  ElementData face_data;
226 
227  // Get face index
228  unsigned face_index;
229  buffer_stream >> face_index;
230  face_data.AttributeValue = face_index;
231 
232  // Get number of nodes owned by this face
233  unsigned num_nodes_in_face;
234  buffer_stream >> num_nodes_in_face;
235 
236  // Store node indices owned by this face
237  for (unsigned i=0; i<num_nodes_in_face; i++)
238  {
239  unsigned node_index_face;
240  buffer_stream >> node_index_face;
241  face_data.NodeIndices.push_back(node_index_face - offset);
242  }
243 
245 
246  element_data.Faces[j] = face_data;
247  }
248 
249  //For back compatibility (we always store attributes on elements now)
250  element_data.AttributeValue = 0;
251  if (mNumElementAttributes > 0)
252  {
253  assert(mNumElementAttributes==1);
254 
255  buffer_stream >> element_data.AttributeValue;
256  }
257 
258  mElementsRead++;
259  return element_data;
260 }
261 
262 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
264 {
265  OpenNodeFile();
266  OpenElementsFile();
267 }
268 
269 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
271 {
272  // Nodes definition
273  std::string file_name = mFilesBaseName + ".node";
274  mNodesFile.open(file_name.c_str());
275  if (!mNodesFile.is_open())
276  {
277  EXCEPTION("Could not open data file: " + file_name);
278  }
279 }
280 
281 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
283 {
284  // Elements definition
285  std::string file_name;
286  file_name = mFilesBaseName + ".cell";
287 
288  mElementsFile.open(file_name.c_str());
289  if (!mElementsFile.is_open())
290  {
291  EXCEPTION("Could not open data file: " + file_name);
292  }
293 }
294 
295 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
297 {
298  std::string buffer;
299 
300  GetNextLineFromStream(mNodesFile, buffer);
301  std::stringstream buffer_stream(buffer);
302  buffer_stream >> mNumNodes >> mNumNodeAttributes;
303 
304  // Get the next line to see if nodes are indexed from zero or not
305  GetNextLineFromStream(mNodesFile, buffer);
306  std::stringstream node_buffer_stream(buffer);
307 
308  unsigned first_index;
309  node_buffer_stream >> first_index;
310  assert(first_index == 0 || first_index == 1);
311  mIndexFromZero = (first_index == 0);
312 
313  // Close, reopen, skip header
314  mNodesFile.close();
315  OpenNodeFile();
316  GetNextLineFromStream(mNodesFile, buffer);
317 
318  GetNextLineFromStream(mElementsFile, buffer);
319  std::stringstream element_buffer_stream(buffer);
320 
321  element_buffer_stream >> mNumElements >> mNumElementAttributes;
322 }
323 
324 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
326 {
327  mNodesFile.close();
328  mElementsFile.close();
329 }
330 
331 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
332 void VertexMeshReader<ELEMENT_DIM, SPACE_DIM>::GetNextLineFromStream(std::ifstream& fileStream, std::string& rawLine)
333 {
334  bool line_is_blank;
335 
336  do
337  {
338  getline(fileStream, rawLine);
339 
340  if (fileStream.eof())
341  {
342  EXCEPTION("Cannot get the next line from node or element file due to incomplete data");
343  }
344 
345  // Get rid of any comment
346  rawLine = rawLine.substr(0,rawLine.find('#', 0));
347 
348  line_is_blank = (rawLine.find_first_not_of(" \t", 0) == std::string::npos);
349  }
350  while (line_is_blank);
351 }
352 
354 // Explicit instantiation
356 
357 template class VertexMeshReader<1,1>;
358 template class VertexMeshReader<1,2>;
359 template class VertexMeshReader<1,3>;
360 template class VertexMeshReader<2,2>;
361 template class VertexMeshReader<2,3>;
362 template class VertexMeshReader<3,3>;
VertexElementData GetNextElementDataWithFaces()
#define EXCEPTION(message)
Definition: Exception.hpp:143
ElementData GetNextFaceData()
unsigned GetNumElementAttributes() const
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::vector< double > GetNextNode()
unsigned GetNumFaces() const
std::vector< unsigned > NodeIndices