lumpedPointStateWriter.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
29 #include "OFstream.H"
30 #include "foamVtkOutput.H"
31 
32 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
33 
35 (
36  const fileName& outputFile,
37  const labelListList& lines,
38  const labelList& pointIds
39 ) const
40 {
41  if (!Pstream::master())
42  {
43  // No extra information available from slaves, write on master only.
44  return;
45  }
46 
47  // local-to-global transformation tensors
48  const tensorField& localToGlobal = rotations();
49 
50  OFstream fos(outputFile);
51  std::ostream& os = fos.stdStream();
52 
54  (
55  os,
57  );
58 
59  format().xmlHeader()
60  .beginVTKFile<vtk::fileTag::POLY_DATA>();
61 
62  //
63  // Lumped mass points and connections,
64  // with triangles to visualize location/rotation
65  //
66  {
67  const label nPoints = 3*points_.size(); // 3 points per triangle
68  const label nPolys = points_.size();
69 
70  format()
71  .tag
72  (
78  );
79 
80  // 'points'
81  {
82  const uint64_t payLoad = vtk::sizeofData<float, 3>(nPoints);
83 
84  format()
86  .beginDataArray<float, 3>(vtk::dataArrayAttr::POINTS);
87 
88  format().writeSize(payLoad);
89 
90  // The lumped points first
91  vtk::writeList(format(), points_);
92 
93  // Other points (for the triangles) next
94  forAll(points_, posi)
95  {
96  const point& origin = points_[posi];
97  const tensor& rotTensor =
98  (
99  posi < localToGlobal.size()
100  ? localToGlobal[posi]
102  );
103 
104  // Local-to-global rotation and translation
105  vtk::write(format(), 2*visLength*rotTensor.cx() + origin);
106  vtk::write(format(), 1*visLength*rotTensor.cy() + origin);
107  }
108 
109  format().flush();
110 
111  format()
112  .endDataArray()
113  .endTag(vtk::fileTag::POINTS);
114  }
115 
116  // <Verts>
118 
119  //
120  // 'connectivity'
121  //
122  {
123  const uint64_t payLoad = vtk::sizeofData<label>(points_.size());
124 
125  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
126  format().writeSize(payLoad);
127 
128  vtk::writeIdentity(format(), points_.size());
129 
130  format().flush();
131 
132  format().endDataArray();
133  }
134 
135  //
136  // 'offsets' (connectivity offsets)
137  // = linear mapping onto points (with 1 offset)
138  //
139  {
140  const uint64_t payLoad = vtk::sizeofData<label>(points_.size());
141 
142  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
143  format().writeSize(payLoad);
144 
145  vtk::writeIdentity(format(), points_.size(), 1);
146 
147  format().flush();
148 
149  format().endDataArray();
150  }
151 
152  format().endTag(vtk::fileTag::VERTS);
153  // </Verts>
154 
155 
156  // <Lines>
158 
159  label nLinePoints = 0;
160  for (const labelList& linePoints : lines)
161  {
162  nLinePoints += linePoints.size();
163  }
164 
165  //
166  // 'connectivity'
167  //
168  {
169  const uint64_t payLoad = vtk::sizeofData<label>(nLinePoints);
170 
171  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
172  format().writeSize(payLoad);
173 
174  for (const labelList& linePoints : lines)
175  {
177  }
178 
179  format().flush();
180 
181  format().endDataArray();
182  }
183 
184  //
185  // 'offsets' (connectivity offsets)
186  // = N lines
187  //
188  {
189  const uint64_t payLoad = vtk::sizeofData<label>(lines.size());
190 
191  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
192  format().writeSize(payLoad);
193 
194  nLinePoints = 0;
195  for (const labelList& linePoints : lines)
196  {
197  nLinePoints += linePoints.size();
198  format().write(nLinePoints);
199  }
200 
201  format().flush();
202 
203  format().endDataArray();
204  }
205 
206  format().endTag(vtk::fileTag::LINES);
207  // </Lines>
208 
209 
210  // <Polys>
212 
213  //
214  // 'connectivity' - 3 points (ie, tri)
215  // origins appear first, followed by a point pair for each triangle
216  // Eg,
217  // - tri 0: (0 N N+1)
218  // - tri 1: (1 N+2 N+3)
219  //
220  {
221  const uint64_t payLoad = vtk::sizeofData<label>(3*nPolys);
222 
223  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
224  format().writeSize(payLoad);
225 
226  for (label pointi=0, nei=nPolys; pointi < nPolys; ++pointi)
227  {
228  format().write(pointi);
229  format().write(nei); ++nei;
230  format().write(nei); ++nei;
231  }
232 
233  format().flush();
234 
235  format().endDataArray();
236  }
237 
238  //
239  // 'offsets' (connectivity offsets)
240  // = single tri
241  //
242  {
243  const uint64_t payLoad = vtk::sizeofData<label>(nPolys);
244 
245  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
246  format().writeSize(payLoad);
247 
248  for (label trii = 1; trii <= nPolys; ++trii)
249  {
250  // Connectivity end offset for each triangle
251  format().write(label(3*trii));
252  }
253  format().flush();
254 
255  format().endDataArray();
256  }
257 
258  format().endTag(vtk::fileTag::POLYS);
259  // </Polys>
260 
261 
262  // CELL_DATA
263  format().beginCellData();
264 
265  // point id
266  {
267  const uint64_t payLoad =
268  vtk::sizeofData<label>(points_.size() + lines.size());
269 
270  format().beginDataArray<label>("pointId");
271  format().writeSize(payLoad);
272 
273  // <Verts>
274  vtk::writeIdentity(format(), points_.size());
275 
276  // <Lines>
277  vtk::write(format(), label(-1), lines.size());
278 
279  // <Poly>
280  vtk::writeIdentity(format(), nPolys);
281 
282  format().flush();
283 
284  format().endDataArray();
285  }
286 
287  // original id
288  if (pointIds.size() == points_.size())
289  {
290  const uint64_t payLoad =
291  vtk::sizeofData<label>(points_.size() + lines.size());
292 
293  format().beginDataArray<label>("originalId");
294  format().writeSize(payLoad);
295 
296  // <Verts>
297  vtk::writeList(format(), pointIds);
298 
299  // <Lines>
300  vtk::write(format(), label(-1), lines.size());
301 
302  // <Poly>
303  vtk::writeList(format(), pointIds);
304 
305  format().flush();
306 
307  format().endDataArray();
308  }
309 
310  // line id
311  {
312  const uint64_t payLoad =
313  vtk::sizeofData<label>(points_.size() + lines.size());
314 
315  format().beginDataArray<label>("lineId");
316  format().writeSize(payLoad);
317 
318  // <Verts>
319  vtk::write(format(), label(-1), points_.size());
320 
321  // <Lines>
322  vtk::writeIdentity(format(), lines.size());
323 
324  // <Poly>
325  vtk::write(format(), label(-1), nPolys);
326 
327  format().flush();
328 
329  format().endDataArray();
330  }
331 
332  format().endCellData();
333 
334 
335  // POINT_DATA
336  format().beginPointData();
337 
338  // point id
339  {
340  const uint64_t payLoad = vtk::sizeofData<label>(nPoints);
341 
342  format().beginDataArray<label>("pointId");
343  format().writeSize(payLoad);
344 
345  // The lumped points first
346  vtk::writeIdentity(format(), points_.size());
347 
348  // Tag other (triangle) points as -1
349  vtk::write(format(), label(-1), 2*points_.size());
350 
351  format().flush();
352 
353  format().endDataArray();
354  }
355 
356  // original id
357  if (pointIds.size() == points_.size())
358  {
359  const uint64_t payLoad = vtk::sizeofData<label>(nPoints);
360 
361  format().beginDataArray<label>("originalId");
362  format().writeSize(payLoad);
363 
364  // The lumped points first
365  vtk::writeList(format(), pointIds);
366 
367  // Tag other (triangle) points as -1
368  vtk::write(format(), label(-1), 2*points_.size());
369 
370  format().flush();
371 
372  format().endDataArray();
373  }
374 
375  format().endPointData();
376 
377  format().endPiece();
378  }
379 
381  .endVTKFile();
382 }
383 
384 
385 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:119
void writeIdentity(vtk::formatter &fmt, const label len, label start=0)
Write an identity list of labels.
A class for handling file names.
Definition: fileName.H:72
static scalar visLength
The length for visualization triangles.
Output to file stream as an OSstream, normally using std::ofstream for the actual output...
Definition: OFstream.H:71
A traits class, which is primarily used for primitives and vector-space.
Definition: pTraits.H:63
XML inline ASCII, asciiFormatter.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:400
virtual const std::ostream & stdStream() const override
Const access to underlying std::ostream.
Definition: OFstream.C:125
autoPtr< vtk::formatter > newFormatter(std::ostream &os, unsigned prec=IOstream::defaultPrecision())
Return a default asciiFormatter.
static constexpr label size() noexcept
Return the number of elements in the FixedList.
Definition: FixedList.H:624
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
label nPoints
Line point storage. Default constructable (line is not)
Definition: line.H:76
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
word format(conversionProperties.get< word >("format"))
const tensorField & rotations() const
The local-to-global transformation for each point.
static bool master(label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1807
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Tensor of scalars, i.e. Tensor<scalar>.
void writeVTP(const fileName &outputFile, const labelListList &lines=labelListList(), const labelList &pointIds=labelList::null()) const
Output points/rotations as VTK file for debugging/visualization.