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 
28 #include "lumpedPointState.H"
29 #include "OFstream.H"
30 #include "sliceRange.H"
31 #include "foamVtkOutput.H"
32 
33 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
34 
36 (
37  const fileName& outputFile,
38  const labelListList& lines,
39  const labelList& pointIds
40 ) const
41 {
42  if (!Pstream::master())
43  {
44  // No extra information available from slaves, write on master only.
45  return;
46  }
47 
48  // local-to-global transformation tensors
49  const tensorField& localToGlobal = rotations();
50 
51  OFstream fos(outputFile);
52  std::ostream& os = fos.stdStream();
53 
55  (
56  os,
57  vtk::formatType::INLINE_ASCII
58  );
59 
60  format().xmlHeader()
61  .beginVTKFile<vtk::fileTag::POLY_DATA>();
62 
63  //
64  // Lumped mass points and connections,
65  // with triangles to visualize location/rotation
66  //
67  {
68  const label nPoints = 3*points_.size(); // 3 points per triangle
69  const label nPolys = points_.size();
70 
71  format()
72  .tag
73  (
74  vtk::fileTag::PIECE,
75  vtk::fileAttr::NUMBER_OF_POINTS, nPoints,
76  vtk::fileAttr::NUMBER_OF_VERTS, points_.size(),
77  vtk::fileAttr::NUMBER_OF_LINES, lines.size(),
78  vtk::fileAttr::NUMBER_OF_POLYS, nPolys
79  );
80 
81  // 'points'
82  {
83  const uint64_t payLoad = vtk::sizeofData<float, 3>(nPoints);
84 
85  format()
86  .tag(vtk::fileTag::POINTS)
87  .beginDataArray<float, 3>(vtk::dataArrayAttr::POINTS);
88 
89  format().writeSize(payLoad);
90 
91  // The lumped points first
92  vtk::writeList(format(), points_);
93 
94  // Other points (for the triangles) next
95  forAll(points_, posi)
96  {
97  const point& origin = points_[posi];
98  const tensor& rotTensor =
99  (
100  posi < localToGlobal.size()
101  ? localToGlobal[posi]
103  );
104 
105  // Local-to-global rotation and translation
106  vtk::write(format(), 2*visLength*rotTensor.cx() + origin);
107  vtk::write(format(), 1*visLength*rotTensor.cy() + origin);
108  }
109 
110  format().flush();
111 
112  format()
113  .endDataArray()
114  .endTag(vtk::fileTag::POINTS);
115  }
116 
117  // <Verts>
118  format().tag(vtk::fileTag::VERTS);
119 
120  //
121  // 'connectivity'
122  //
123  {
124  const uint64_t payLoad = vtk::sizeofData<label>(points_.size());
125 
126  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
127  format().writeSize(payLoad);
128 
129  vtk::writeIdentity(format(), points_.size());
130 
131  format().flush();
132 
133  format().endDataArray();
134  }
135 
136  //
137  // 'offsets' (connectivity offsets)
138  // = linear mapping onto points (with 1 offset)
139  //
140  {
141  const uint64_t payLoad = vtk::sizeofData<label>(points_.size());
142 
143  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
144  format().writeSize(payLoad);
145 
146  vtk::writeIdentity(format(), points_.size(), 1);
147 
148  format().flush();
149 
150  format().endDataArray();
151  }
152 
153  format().endTag(vtk::fileTag::VERTS);
154  // </Verts>
155 
156 
157  // <Lines>
158  format().tag(vtk::fileTag::LINES);
159 
160  label nLinePoints = 0;
161  for (const labelList& linePoints : lines)
162  {
163  nLinePoints += linePoints.size();
164  }
165 
166  //
167  // 'connectivity'
168  //
169  {
170  const uint64_t payLoad = vtk::sizeofData<label>(nLinePoints);
171 
172  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
173  format().writeSize(payLoad);
174 
175  for (const labelList& linePoints : lines)
176  {
177  vtk::writeList(format(), linePoints);
178  }
179 
180  format().flush();
181 
182  format().endDataArray();
183  }
184 
185  //
186  // 'offsets' (connectivity offsets)
187  // = N lines
188  //
189  {
190  const uint64_t payLoad = vtk::sizeofData<label>(lines.size());
191 
192  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
193  format().writeSize(payLoad);
194 
195  nLinePoints = 0;
196  for (const labelList& linePoints : lines)
197  {
198  nLinePoints += linePoints.size();
199  format().write(nLinePoints);
200  }
201 
202  format().flush();
203 
204  format().endDataArray();
205  }
206 
207  format().endTag(vtk::fileTag::LINES);
208  // </Lines>
209 
210 
211  // <Polys>
212  format().tag(vtk::fileTag::POLYS);
213 
214  //
215  // 'connectivity' - 3 points (ie, tri)
216  // origins appear first, followed by a point pair for each triangle
217  // Eg,
218  // - tri 0: (0 N N+1)
219  // - tri 1: (1 N+2 N+3)
220  //
221  {
222  const uint64_t payLoad = vtk::sizeofData<label>(3*nPolys);
223 
224  format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
225  format().writeSize(payLoad);
226 
227  for (label pointi=0, nei=nPolys; pointi < nPolys; ++pointi)
228  {
229  format().write(pointi);
230  format().write(nei); ++nei;
231  format().write(nei); ++nei;
232  }
233 
234  format().flush();
235 
236  format().endDataArray();
237  }
238 
239  //
240  // 'offsets' (connectivity offsets)
241  // = single tri
242  //
243  {
244  const uint64_t payLoad = vtk::sizeofData<label>(nPolys);
245 
246  format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
247  format().writeSize(payLoad);
248 
249  for (const label off : sliceRange(3, nPolys, 3))
250  {
251  format().write(off);
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 
380  format().endTag(vtk::fileTag::POLY_DATA)
381  .endVTKFile();
382 }
383 
384 
385 // ************************************************************************* //
Foam::Tensor< scalar >
foamVtkOutput.H
sliceRange.H
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::vtk::writeIdentity
void writeIdentity(vtk::formatter &fmt, const label len, label start=0)
Write an identity list of labels.
Definition: foamVtkOutput.C:96
Foam::Tensor::cy
Vector< Cmpt > cy() const
Extract vector for column 1.
Definition: TensorI.H:306
lumpedPointState.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
OFstream.H
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
format
word format(conversionProperties.get< word >("format"))
Foam::Field< tensor >
Foam::vtk::writeList
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
Definition: foamVtkOutput.C:112
Foam::lumpedPointState::writeVTP
void writeVTP(const fileName &outputFile, const labelListList &lines=labelListList(), const labelList &pointIds=labelList::null()) const
Output points/rotations as VTK file for debugging/visualization.
Definition: lumpedPointStateWriter.C:36
os
OBJstream os(runTime.globalPath()/outputName)
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::sliceRange
A set of labels defined by a start, a length and a stride.
Definition: sliceRange.H:58
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::OFstream::stdStream
virtual std::ostream & stdStream()
Access to underlying std::ostream.
Definition: OFstream.C:102
Foam::Tensor::cx
Vector< Cmpt > cx() const
Extract vector for column 0.
Definition: TensorI.H:299
Foam::Vector< scalar >
Foam::List< labelList >
Foam::pTraits
A traits class, which is primarily used for primitives.
Definition: pTraits.H:56
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::vtk::newFormatter
autoPtr< vtk::formatter > newFormatter(std::ostream &os, unsigned prec=IOstream::defaultPrecision())
Return a default asciiFormatter.
Definition: foamVtkOutput.C:48