Chaste Commit::baa90ac2819b962188b7562f2326be23c47859a7
MeshalyzerMeshWriter.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
36#include "MeshalyzerMeshWriter.hpp"
37#include "Version.hpp"
38
39// We need these two includes for the node/element/face iterators to compile
40#include "AbstractTetrahedralMesh.hpp"
41#include "DistributedTetrahedralMesh.hpp"
42
43
45// Implementation
47
48template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
50 const std::string& rBaseName,
51 const bool &rCleanDirectory,
52 const bool &rSetCoolGraphics)
53 : AbstractTetrahedralMeshWriter<ELEMENT_DIM, SPACE_DIM>(rDirectory, rBaseName, rCleanDirectory)
54{
55 /* if (ELEMENT_DIM != SPACE_DIM)
56 {
57 EXCEPTION("ELEMENT_DIM must be equal to SPACE_DIM");
58 }*/
59
60 if (rSetCoolGraphics)
61 {
62 this->mIndexFromZero = false;
63 this->mWriteMetaFile = true;
64 }
65 else
66 {
67 this->mIndexFromZero = true;
68 this->mWriteMetaFile = false;
69 }
70}
71
72template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
74{
75 std::string comment = "# " + ChasteBuildInfo::GetProvenanceString();
76
77 //Write node file
78 out_stream p_node_file = OpenNodeFile();
79
80 //Write the node header
81 unsigned num_nodes = this->GetNumNodes();
82 *p_node_file << num_nodes << "\n";
83
84 // Write each node's data
85 for (unsigned item_num=0; item_num<num_nodes; item_num++)
86 {
87 std::vector<double> current_item = this->GetNextNode(); //this->mNodeData[item_num];
88 for (unsigned i=0; i<SPACE_DIM; i++)
89 {
90 *p_node_file << current_item[i] << "\t";
91 }
92 if (SPACE_DIM==2)
93 {
94 *p_node_file << 0 << "\t";
95 }
96 if (SPACE_DIM==1)
97 {
98 *p_node_file << 0 << "\t" << 0 << "\t";
99 }
100 *p_node_file << "\n";
101
102 }
103 *p_node_file << comment;
104 p_node_file->close();
105
106 // Write element file
107 std::string element_file_name;
108
109 if (ELEMENT_DIM == 3)
110 {
111 element_file_name = this->mBaseName + ".tetras";
112 }
113 else if (ELEMENT_DIM == 2)
114 {
115 element_file_name = this->mBaseName + ".tri";
116 }
117 else //ELEMENT_DIM == 1
118 {
119 element_file_name = this->mBaseName + ".cnnx";
120 }
121
122 out_stream p_element_file = OpenElementFile();
123
124 // Write the element header
125 unsigned num_elements = this->GetNumElements();
126
127 *p_element_file << num_elements << "\n";
128
129 // Write each element's data
130 unsigned nodes_per_element = ELEMENT_DIM+1;
131 for (unsigned item_num=0; item_num<num_elements; item_num++)
132 {
133 ElementData element_data = this->GetNextElement();
134
135 std::vector<unsigned> current_item = element_data.NodeIndices;
136 for (unsigned i=0; i<nodes_per_element; i++)
137 {
138 if (this->mIndexFromZero)
139 {
140 *p_element_file << current_item[i] << "\t";
141 }
142 else
143 {
144 *p_element_file << current_item[i]+1 << "\t";
145 }
146 }
147
148 *p_element_file << element_data.AttributeValue << "\n";
149 }
150 *p_element_file << comment;
151 p_element_file->close();
152
153 if (ELEMENT_DIM==3)
154 {
155 // Write boundary face file
156 out_stream p_face_file = OpenFaceFile();
157
158 // Write the boundary face header
159 unsigned num_faces = this->GetNumBoundaryFaces();
160
161 *p_face_file << num_faces << "\n";
162
163 // Write each face's data
164 double material_property = 0.0;
165 for (unsigned item_num=0; item_num<num_faces; item_num++)
166 {
167 ElementData current_item = this->GetNextBoundaryElement();
168 for (unsigned i=0; i<ELEMENT_DIM; i++)
169 {
170 if (this->mIndexFromZero)
171 {
172 *p_face_file << current_item.NodeIndices[i] << "\t";
173 }
174 else
175 {
176 *p_face_file << current_item.NodeIndices[i]+1 <<"\t";
177 }
178 }
179 *p_face_file << material_property << "\n";
180 }
181 *p_face_file << comment;
182 p_face_file->close();
183
184 WriteMetaFile();
185 }
186}
187
188template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
192
193template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
195{
196 if (this->mWriteMetaFile)
197 {
198 std::string meta_file_name = this->mBaseName + ".cg_in";
199 out_stream p_meta_file = this->mpOutputFileHandler->OpenOutputFile(meta_file_name);
200
201 *p_meta_file << "1\n" << "0\n";
202 std::string face_file_name = this->mBaseName + ".tri";
203 *p_meta_file << face_file_name <<"\n";
204 std::string comment = "# " + ChasteBuildInfo::GetProvenanceString();
205 *p_meta_file << comment;
206 p_meta_file->close();
207 }
208}
209
210template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
212{
213 std::ios_base::openmode mode = std::ios::out;
214 if (append)
215 {
216 mode |= std::ios::app; // Note: bitwise OR operation
217 }
218 else
219 {
220 mode |= std::ios::trunc;
221 }
222 return mode;
223}
224
225template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
227{
228 std::string node_file_name = this->mBaseName + ".pts";
229 return this->mpOutputFileHandler->OpenOutputFile(node_file_name, GetOpenMode(append));
230}
231
232template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
234{
235 std::string element_file_name;
236
237 if (ELEMENT_DIM == 3)
238 {
239 element_file_name = this->mBaseName + ".tetras";
240 }
241 else if (ELEMENT_DIM == 2)
242 {
243 element_file_name = this->mBaseName + ".tri";
244 }
245 else //ELEMENT_DIM == 1
246 {
247 element_file_name = this->mBaseName + ".cnnx";
248 }
249
250 return this->mpOutputFileHandler->OpenOutputFile(element_file_name, GetOpenMode(append));
251}
252
253template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
255{
256 std::string face_file_name = this->mBaseName + ".tri";
257 return this->mpOutputFileHandler->OpenOutputFile(face_file_name, GetOpenMode(append));
258}
259
260template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
262{
263 /*
264 * Node file
265 */
266 out_stream p_node_file = OpenNodeFile();
267
268 //Write the node header
269 unsigned num_nodes = this->GetNumNodes();
270 *p_node_file << num_nodes << "\n";
271
272 p_node_file->close();
273
274 /*
275 * Element file
276 */
277 // Write element file
278 out_stream p_element_file = OpenElementFile();
279
280 // Write the element header
281 unsigned num_elements = this->GetNumElements();
282 *p_element_file << num_elements << "\n";
283
284 p_element_file->close();
285
286 /*
287 * Face file
288 */
289 if (ELEMENT_DIM==3)
290 {
291 // Write boundary face file
292 out_stream p_face_file = OpenFaceFile();
293
294 // Write the boundary face header
295 unsigned num_faces = this->GetNumBoundaryFaces();
296 *p_face_file << num_faces << "\n";
297
298 p_face_file->close();
299
300 WriteMetaFile();
301 }
302
303}
304
305template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
307{
308 out_stream p_node_file = OpenNodeFile(true);
309
310 typedef typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator NodeIterType;
311
312 for (NodeIterType iter = this->mpDistributedMesh->GetNodeIteratorBegin();
313 iter != this->mpDistributedMesh->GetNodeIteratorEnd();
314 ++iter)
315 {
316 const c_vector<double, SPACE_DIM>& r_current_item = iter->rGetLocation();
317 for (unsigned i=0; i<SPACE_DIM; i++)
318 {
319 *p_node_file << r_current_item[i] << "\t";
320 }
321 if (SPACE_DIM==2)
322 {
323 *p_node_file << 0 << "\t";
324 }
325 if (SPACE_DIM==1)
326 {
327 *p_node_file << 0 << "\t" << 0 << "\t";
328 }
329 *p_node_file << "\n";
330 }
331 p_node_file->close();
332
333 out_stream p_element_file = OpenElementFile(true);
334
336
337 for (ElemIterType iter = this->mpDistributedMesh->GetElementIteratorBegin();
338 iter != this->mpDistributedMesh->GetElementIteratorEnd();
339 ++iter)
340 {
341 if (this->mpDistributedMesh->CalculateDesignatedOwnershipOfElement(iter->GetIndex()))
342 {
343 for (unsigned i=0; i<this->mNodesPerElement; i++)
344 {
345 if (this->mIndexFromZero)
346 {
347 *p_element_file << iter->GetNodeGlobalIndex(i) << "\t";
348 }
349 else
350 {
351 *p_element_file << iter->GetNodeGlobalIndex(i)+1 << "\t";
352 }
353 }
354
355 *p_element_file << iter->GetAttribute() << "\n";
356 }
357 }
358 p_element_file->close();
359
360
361 if (ELEMENT_DIM == 3)
362 {
363 out_stream p_face_file = OpenFaceFile(true);
364
366
367 for (BoundaryElemIterType iter = this->mpDistributedMesh->GetBoundaryElementIteratorBegin();
368 iter != this->mpDistributedMesh->GetBoundaryElementIteratorEnd();
369 ++iter)
370 {
371 if (this->mpDistributedMesh->CalculateDesignatedOwnershipOfBoundaryElement((*iter)->GetIndex()))
372 {
373 for (unsigned i=0; i<ELEMENT_DIM; i++)
374 {
375 if (this->mIndexFromZero)
376 {
377 *p_face_file << (*iter)->GetNodeGlobalIndex(i) << "\t";
378 }
379 else
380 {
381 *p_face_file << (*iter)->GetNodeGlobalIndex(i)+1 << "\t";
382 }
383 }
384
385 *p_face_file << (*iter)->GetAttribute() << "\n";
386 }
387 }
388 p_face_file->close();
389 }
390}
391
392template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
394{
395 std::string comment = "# " + ChasteBuildInfo::GetProvenanceString();
396
397 out_stream p_node_file = OpenNodeFile(true);
398 *p_node_file << comment;
399 p_node_file->close();
400
401 out_stream p_element_file = OpenElementFile(true);
402 *p_element_file << comment;
403 p_element_file->close();
404
405 if (ELEMENT_DIM == 3)
406 {
407 out_stream p_face_file = OpenFaceFile(true);
408 *p_face_file << comment;
409 p_face_file->close();
410 }
411}
412
413
414// Explicit instantiation
415template class MeshalyzerMeshWriter<1,1>;
416template class MeshalyzerMeshWriter<1,2>;
417template class MeshalyzerMeshWriter<1,3>;
418template class MeshalyzerMeshWriter<2,2>;
419template class MeshalyzerMeshWriter<2,3>;
420template class MeshalyzerMeshWriter<3,3>;
std::vector< BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > * >::const_iterator BoundaryElementIterator
static std::string GetProvenanceString()
MeshalyzerMeshWriter(const std::string &rDirectory, const std::string &rBaseName, const bool &rCleanDirectory=true, const bool &rSetCoolGraphics=false)
std::ios_base::openmode GetOpenMode(bool append)
out_stream OpenElementFile(bool append=false)
out_stream OpenFaceFile(bool append=false)
out_stream OpenNodeFile(bool append=false)
std::vector< unsigned > NodeIndices