VTUGridWriterASCII.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23 \*---------------------------------------------------------------------------*/
24 
25 #include "VTUGridWriterASCII.hpp"
26 
27 namespace mimmo{
28 
33  m_patch = nullptr;
34  m_vtkVertexMap = nullptr;
35 }
36 
41 
47 void VTUFlushStreamerASCII::setTargetPatch(bitpit::PatchKernel & patch, bitpit::PiercedStorage<long, long> & vtkVertexMap){
48  m_patch = &patch;
49  m_vtkVertexMap = &vtkVertexMap;
50 }
51 
60 void VTUFlushStreamerASCII::flushData(std::fstream &stream, const std::string &name, bitpit::VTKFormat format)
61 {
62  assert(format == bitpit::VTKFormat::ASCII && m_patch != nullptr);
63  BITPIT_UNUSED(format);
64 
65  if (name == "Points") {
66  auto &verts = m_patch->getVertices();
67  for (bitpit::PatchKernel::VertexConstIterator itr = m_patch->vertexConstBegin(); itr != m_patch->vertexConstEnd(); ++itr) {
68  std::size_t vertexRawId = itr.getRawIndex();
69  long vertexVTKId = m_vtkVertexMap->rawAt(vertexRawId);
70  if (vertexVTKId != bitpit::Vertex::NULL_ID) {
71  const bitpit::Vertex &vertex = verts.rawAt(vertexRawId);
72  bitpit::genericIO::flushASCII(stream, 3, vertex.getCoords());
73  }
74  }
75  } else if (name == "offsets") {
76  int offset = 0;
77  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
78  offset += cell.getVertexCount();
79  bitpit::genericIO::flushASCII(stream, offset);
80  }
81  } else if (name == "types") {
82  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
83  bitpit::VTKElementType VTKType;
84  switch (cell.getType()) {
85 
86  case bitpit::ElementType::VERTEX:
87  VTKType = bitpit::VTKElementType::VERTEX;
88  break;
89 
90  case bitpit::ElementType::LINE:
91  VTKType = bitpit::VTKElementType::LINE;
92  break;
93 
94  case bitpit::ElementType::TRIANGLE:
95  VTKType = bitpit::VTKElementType::TRIANGLE;
96  break;
97 
98  case bitpit::ElementType::PIXEL:
99  VTKType = bitpit::VTKElementType::PIXEL;
100  break;
101 
102  case bitpit::ElementType::QUAD:
103  VTKType = bitpit::VTKElementType::QUAD;
104  break;
105 
106  case bitpit::ElementType::POLYGON:
107  VTKType = bitpit::VTKElementType::POLYGON;
108  break;
109 
110  case bitpit::ElementType::TETRA:
111  VTKType = bitpit::VTKElementType::TETRA;
112  break;
113 
114  case bitpit::ElementType::VOXEL:
115  VTKType = bitpit::VTKElementType::VOXEL;
116  break;
117 
118  case bitpit::ElementType::HEXAHEDRON:
119  VTKType = bitpit::VTKElementType::HEXAHEDRON;
120  break;
121 
122  case bitpit::ElementType::WEDGE:
123  VTKType = bitpit::VTKElementType::WEDGE;
124  break;
125 
126  case bitpit::ElementType::PYRAMID:
127  VTKType = bitpit::VTKElementType::PYRAMID;
128  break;
129 
130  case bitpit::ElementType::POLYHEDRON:
131  VTKType = bitpit::VTKElementType::POLYHEDRON;
132  break;
133 
134  default:
135  VTKType = bitpit::VTKElementType::UNDEFINED;
136  break;
137 
138  }
139 
140  bitpit::genericIO::flushASCII(stream, (int) VTKType);
141  }
142  } else if (name == "connectivity") {
143  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
144  bitpit::ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
145  const int nCellVertices = cell.getVertexCount();
146  for (int k = 0; k < nCellVertices; ++k) {
147  long vertexId = cellVertexIds[k];
148  long vtkVertexId = m_vtkVertexMap->at(vertexId);
149  bitpit::genericIO::flushASCII(stream, vtkVertexId);
150  }
151  }
152  } else if (name == "faces") {
153  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
154  if (cell.getDimension() <= 2 || cell.hasInfo()) {
155  bitpit::genericIO::flushASCII(stream, (long) 0);
156  } else {
157  std::vector<long> faceStream = cell.getFaceStream();
158  bitpit::Cell::renumberFaceStream(*(m_vtkVertexMap), &faceStream);
159  int faceStreamSize = faceStream.size();
160  for (int k = 0; k < faceStreamSize; ++k) {
161  bitpit::genericIO::flushASCII(stream, faceStream[k]);
162  }
163  }
164  }
165  } else if (name == "faceoffsets") {
166  int offset = 0;
167  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
168  if (cell.getDimension() <= 2 || cell.hasInfo()) {
169  offset += 1;
170  } else {
171  offset += cell.getFaceStreamSize();
172  }
173 
174  bitpit::genericIO::flushASCII(stream, offset);
175  }
176  } else if (name == "cellIndex") {
177  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
178  bitpit::genericIO::flushASCII(stream, cell.getId());
179  }
180  } else if (name == "PID") {
181  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
182  bitpit::genericIO::flushASCII(stream, cell.getPID());
183  }
184  } else if (name == "vertexIndex") {
185  for (bitpit::PatchKernel::VertexConstIterator itr = m_patch->vertexConstBegin(); itr != m_patch->vertexConstEnd(); ++itr) {
186  std::size_t vertexRawId = itr.getRawIndex();
187  long vertexVTKId = m_vtkVertexMap->rawAt(vertexRawId);
188  if (vertexVTKId != bitpit::Vertex::NULL_ID) {
189  std::size_t vertexId = itr.getId();
190  bitpit::genericIO::flushASCII(stream, vertexId);
191  }
192  }
193 
194 
195 #if MIMMO_ENABLE_MPI==1
196  } else if (name == "cellGlobalIndex") {
197  bitpit::PatchNumberingInfo numberingInfo(m_patch);
198  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
199  bitpit::genericIO::flushASCII(stream, numberingInfo.getCellGlobalId(cell.getId()));
200  }
201  } else if (name == "cellRank") {
202  for (const bitpit::Cell &cell : m_patch->getVTKCellWriteRange()) {
203  bitpit::genericIO::flushASCII(stream, m_patch->getCellRank(cell.getId()));
204  }
205  } else if (name == "vertexRank") {
206  for (bitpit::PatchKernel::VertexConstIterator itr = m_patch->vertexConstBegin(); itr != m_patch->vertexConstEnd(); ++itr) {
207  std::size_t vertexRawId = itr.getRawIndex();
208  long vertexVTKId = m_vtkVertexMap->rawAt(vertexRawId);
209  if (vertexVTKId != bitpit::Vertex::NULL_ID) {
210  bitpit::genericIO::flushASCII(stream, m_patch->getVertexRank(itr.getId()));
211  }
212  }
213 #endif
214  }
215 
216 }
217 
218 
226 VTUGridWriterASCII::VTUGridWriterASCII( VTUFlushStreamerASCII & streamer, bitpit::PatchKernel & patch, bitpit::VTKElementType eltype) :
227  VTKUnstructuredGrid(eltype), m_patch(patch), m_streamer(streamer)
228 {
229  for(auto & field : m_geometry){
230  field.enable();
231  field.setStreamer(streamer);
232  }
233 
234  addData<long>("vertexIndex", bitpit::VTKFieldType::SCALAR, bitpit::VTKLocation::POINT, &streamer);
235  addData<long>("cellIndex", bitpit::VTKFieldType::SCALAR, bitpit::VTKLocation::CELL, &streamer);
236  addData<int>("PID", bitpit::VTKFieldType::SCALAR, bitpit::VTKLocation::CELL, &streamer);
237 #if MIMMO_ENABLE_MPI==1
238  addData<long>("cellGlobalIndex", bitpit::VTKFieldType::SCALAR, bitpit::VTKLocation::CELL, &streamer);
239  addData<int>("cellRank", bitpit::VTKFieldType::SCALAR, bitpit::VTKLocation::CELL, &streamer);
240  addData<int>("vertexRank", bitpit::VTKFieldType::SCALAR, bitpit::VTKLocation::POINT, &streamer);
241 #endif
242 
243  // Get VTK cell count
244  long vtkCellCount = 0;
245  if (m_patch.getVTKWriteTarget() == bitpit::PatchKernel::WriteTarget::WRITE_TARGET_CELLS_ALL) {
246  vtkCellCount = m_patch.getCellCount();
247  #if MIMMO_ENABLE_MPI==1
248  } else if (m_patch.getVTKWriteTarget() == bitpit::PatchKernel::WriteTarget::WRITE_TARGET_CELLS_INTERNAL) {
249  vtkCellCount = m_patch.getInternalCellCount();
250  #endif
251  }
252 
253  // Set the dimensinos of the mesh
254  bitpit::PiercedStorage<long, long> vertexWriteFlag(1, &(m_patch.getVertices()));
255  vertexWriteFlag.fill(false);
256 
257  bool vtkFaceStreamNeeded = false;
258  for (const bitpit::Cell &cell : m_patch.getCells()) {
259  if (cell.getDimension() > 2 && !cell.hasInfo()) {
260  vtkFaceStreamNeeded = true;
261  break;
262  }
263  }
264 
265  long vtkConnectSize = 0;
266  long vtkFaceStreamSize = 0;
267  for (const bitpit::Cell &cell : m_patch.getVTKCellWriteRange()) {
268  bitpit::ConstProxyVector<long> cellVertexIds = cell.getVertexIds();
269  const int nCellVertices = cellVertexIds.size();
270  for (int k = 0; k < nCellVertices; ++k) {
271  long vertexId = cellVertexIds[k];
272  vertexWriteFlag.at(vertexId) = true;
273  }
274 
275  vtkConnectSize += nCellVertices;
276  if (vtkFaceStreamNeeded) {
277  if (cell.getDimension() <= 2 || cell.hasInfo()) {
278  vtkFaceStreamSize += 1;
279  } else {
280  vtkFaceStreamSize += cell.getFaceStreamSize();
281  }
282  }
283  }
284 
285  int vtkVertexCount = 0;
286  m_vtkVertexMap.unsetKernel(true);
287  m_vtkVertexMap.setStaticKernel(&(m_patch.getVertices()));
288  for (bitpit::PatchKernel::VertexConstIterator itr = m_patch.vertexConstBegin(); itr != m_patch.vertexConstEnd(); ++itr) {
289  std::size_t vertexRawId = itr.getRawIndex();
290  if (vertexWriteFlag.rawAt(vertexRawId)) {
291  m_vtkVertexMap.rawAt(vertexRawId) = vtkVertexCount++;
292  } else {
293  m_vtkVertexMap.rawAt(vertexRawId) = bitpit::Vertex::NULL_ID;
294  }
295  }
296 
297  setDimensions(vtkCellCount, vtkVertexCount, vtkConnectSize, vtkFaceStreamSize);
298  setCodex(bitpit::VTKFormat::ASCII);
299  m_streamer.setTargetPatch(m_patch, m_vtkVertexMap);
300 
301 #if MIMMO_ENABLE_MPI
302  if (m_patch.getProcessorCount() > 1) {
303  setParallel(m_patch.getProcessorCount(), m_patch.getRank());
304  }
305 #endif
306 
307 }
308 
313 
320 void VTUGridWriterASCII::write(const std::string & dir, const std::string & file, bitpit::VTKWriteMode mode){
321  setDirectory(dir);
322  setName(file);
323  VTKUnstructuredGrid::write(mode);
324 }
325 
326 
327 
328 
329 }
VTUGridWriterASCII(VTUFlushStreamerASCII &streamer, bitpit::PatchKernel &patch, bitpit::VTKElementType eltype=bitpit::VTKElementType::UNDEFINED)
void setTargetPatch(bitpit::PatchKernel &patch, bitpit::PiercedStorage< long, long > &vtkVertexMap)
virtual void flushData(std::fstream &stream, const std::string &name, bitpit::VTKFormat format=bitpit::VTKFormat::ASCII)
Abstract class for custom ASCII writer/flusher of *.vtu mesh external files.
void write(const std::string &dir, const std::string &file, bitpit::VTKWriteMode mode=bitpit::VTKWriteMode::DEFAULT)