Chaste Commit::1fd4e48e3990e67db148bc1bc4cf6991a0049d0c
VertexMeshReader.cpp
1/*
2
3Copyright (c) 2005-2024, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF 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
41template<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();
53}
54
55template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
57{
58 return mNumElements;
59}
60
61template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
63{
64 return mNumNodes;
65}
66
67template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
69{
70 return mNumElementAttributes;
71}
72
73template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
75{
77 return 0;
78}
79
80template<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
90template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
92{
94 return 0;
95}
96
97template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
99{
100 CloseFiles();
101 OpenFiles();
102 ReadHeaders();
103
104 mNodesRead = 0;
105 mElementsRead = 0;
106}
107
108template<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
138template<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
184template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
186{
187 // Create data structure for this element
188 VertexElementData element_data;
189
190 std::string buffer;
191 GetNextLineFromStream(mElementsFile, 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
261template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
263{
264 OpenNodeFile();
265 OpenElementsFile();
266}
267
268template<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
280template<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
294template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
296{
297 std::string buffer;
298
299 GetNextLineFromStream(mNodesFile, buffer);
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
304 GetNextLineFromStream(mNodesFile, buffer);
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();
315 GetNextLineFromStream(mNodesFile, buffer);
316
317 GetNextLineFromStream(mElementsFile, buffer);
318 std::stringstream element_buffer_stream(buffer);
319
320 element_buffer_stream >> mNumElements >> mNumElementAttributes;
321}
322
323template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
325{
326 mNodesFile.close();
327 mElementsFile.close();
328}
329
330template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
331void 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
354template class VertexMeshReader<1,1>;
355template class VertexMeshReader<1,2>;
356template class VertexMeshReader<1,3>;
357template class VertexMeshReader<2,2>;
358template class VertexMeshReader<2,3>;
359template class VertexMeshReader<3,3>;
#define EXCEPTION(message)
unsigned GetNumFaces() const
unsigned GetNumElementAttributes() const
VertexMeshReader(std::string pathBaseName)
unsigned GetNumEdges() const
ElementData GetNextElementData()
unsigned GetNumNodes() const
VertexElementData GetNextElementDataWithFaces()
void GetNextLineFromStream(std::ifstream &fileStream, std::string &rawLine)
unsigned GetNumElements() const
std::vector< double > GetNextNode()
ElementData GetNextFaceData()
std::vector< unsigned > NodeIndices
std::vector< ElementData > Faces
std::vector< unsigned > NodeIndices