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-------------------------------------------------------------------------------
10License
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,
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 (
79 );
80
81 // 'points'
82 {
83 const uint64_t payLoad = vtk::sizeofData<float, 3>(nPoints);
84
85 format()
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>
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>
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>
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
381 .endVTKFile();
382}
383
384
385// ************************************************************************* //
Output to file stream, using an OSstream.
Definition: OFstream.H:57
virtual std::ostream & stdStream()
Access to underlying std::ostream.
Definition: OFstream.C:102
Vector< Cmpt > cx() const
Extract vector for column 0.
Definition: TensorI.H:300
Vector< Cmpt > cy() const
Extract vector for column 1.
Definition: TensorI.H:307
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
A class for handling file names.
Definition: fileName.H:76
const tensorField & rotations() const
The local-to-global transformation for each point.
static scalar visLength
The length for visualization triangles.
void writeVTP(const fileName &outputFile, const labelListList &lines=labelListList(), const labelList &pointIds=labelList::null()) const
Output points/rotations as VTK file for debugging/visualization.
A traits class, which is primarily used for primitives.
Definition: pTraits.H:59
A set of labels defined by a start, a length and a stride.
Definition: sliceRange.H:59
splitCell * master() const
Definition: splitCell.H:113
OBJstream os(runTime.globalPath()/outputName)
label nPoints
@ NUMBER_OF_POLYS
"NumberOfPolys"
@ NUMBER_OF_LINES
"NumberOfLines"
@ NUMBER_OF_VERTS
"NumberOfVerts"
@ NUMBER_OF_POINTS
"NumberOfPoints"
void writeIdentity(vtk::formatter &fmt, const label len, label start=0)
Write an identity list of labels.
Definition: foamVtkOutput.C:96
@ CONNECTIVITY
"connectivity"
@ POLY_DATA
"PolyData"
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
@ INLINE_ASCII
XML inline ASCII, asciiFormatter.
autoPtr< vtk::formatter > newFormatter(std::ostream &os, unsigned prec=IOstream::defaultPrecision())
Return a default asciiFormatter.
Definition: foamVtkOutput.C:48
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
word format(conversionProperties.get< word >("format"))
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333