ensightOutput.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) 2020-2022 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 "ensightOutput.H"
29#include "cell.H"
30#include "cellShape.H"
31#include "face.H"
32#include "polyMesh.H"
33#include "ListOps.H"
35
36// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37
38// Sizes
39
41(
42 const UList<face>& faces
43)
44{
45 labelList list(faces.size());
46
47 auto outIter = list.begin();
48
49 for (const face& f : faces)
50 {
51 *outIter = f.size();
52 ++outIter;
53 }
54
55 return list;
56}
57
58
60(
61 const UIndirectList<face>& faces
62)
63{
64 labelList list(faces.size());
65
66 auto outIter = list.begin();
67
68 for (const face& f : faces)
69 {
70 *outIter = f.size();
71 ++outIter;
72 }
73
74 return list;
75}
76
77
79(
80 const polyMesh& mesh,
81 const labelUList& addr
82)
83{
85 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
86
87 labelList list(addr.size());
88
89 auto outIter = list.begin();
90
91 // The number of faces per element
92 for (const label cellId : addr)
93 {
94 *outIter = meshCells[cellId].size();
95 ++outIter;
96 }
97
98 return list;
99}
100
101
103(
104 const polyMesh& mesh,
105 const labelUList& addr
106)
107{
109 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
110 const faceList& meshFaces = mesh.faces();
111
112 // Count the number of faces per element
113
114 label nTotFaces = 0;
115 for (const label cellId : addr)
116 {
117 nTotFaces += meshCells[cellId].size();
118 }
119
120 labelList list(nTotFaces);
121
122 auto outIter = list.begin();
123
124 // The number of points per element face
125 for (const label cellId : addr)
126 {
127 for (const label facei : meshCells[cellId])
128 {
129 *outIter = meshFaces[facei].size();
130 ++outIter;
131 }
132 }
133
134 return list;
135}
136
137
139(
141 const labelUList& offsets,
142 const labelUList& values,
143 const label pointOffset
144)
145{
146 const label off = (pointOffset + 1); // 1-based for Ensight
147
148 const label nLists = (offsets.size() - 1);
149
150 for (label i = 0; i < nLists; ++i)
151 {
152 const labelUList list
153 (
154 values.slice(offsets[i], (offsets[i+i] - offsets[i]))
155 );
156 for (const label pointi : list)
157 {
158 os.write(pointi + off);
159 }
160 os.newline(); // One list (cell/faces) per line (ASCII)
161 }
162}
163
164
166(
168 const UList<face>& faces,
169 const label pointOffset
170)
171{
172 ensightOutput::Detail::writeLabelListList(os, faces, pointOffset);
173}
174
175
177(
179 const UIndirectList<face>& faces,
180 const label pointOffset
181)
182{
183 ensightOutput::Detail::writeLabelListList(os, faces, pointOffset);
184}
185
186
188(
190 const CompactListList<label>& faces,
191 const label pointOffset
192)
193{
194 ensightOutput::Detail::writeLabelListList(os, faces, pointOffset);
195}
196
197
199(
201 const UList<cellShape>& shapes,
202 const label pointOffset
203)
204{
205 ensightOutput::Detail::writeLabelListList(os, shapes, pointOffset);
206}
207
208
211(
212 const polyMesh& mesh,
213 const labelUList& addr,
214 const labelList& pointMap
215)
216{
218 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
219 const faceList& meshFaces = mesh.faces();
220 const labelList& owner = mesh.faceOwner();
221
222
223 // The caller should have already checked for possible overflow,
224 // so can skip that here.
225 // but still need the sizing for allocations
226
227 label nFaces = 0, nPoints = 0;
228 for (const label cellId : addr)
229 {
230 nFaces += meshCells[cellId].size();
231
232 for (const label faceId : meshCells[cellId])
233 {
234 nPoints += meshFaces[faceId].size();
235 }
236 }
237
238
240 labelList& offsets = compact.offsets();
241 labelList& verts = compact.values();
242
243 // Restart counts
244 nFaces = nPoints = 0;
245
246 for (const label cellId : addr)
247 {
248 for (const label faceId : meshCells[cellId])
249 {
250 const face& f = meshFaces[faceId];
251
252 offsets[nFaces++] = nPoints;
253
254 if (faceId < owner.size() && owner[faceId] != cellId)
255 {
256 // The neighbour of an internal face
257 // - handle like face::reverseFace()
258
259 verts[nPoints++] = pointMap[f[0]];
260 for (label pti = f.size()-1; pti > 0; --pti)
261 {
262 verts[nPoints++] = pointMap[f[pti]];
263 }
264 }
265 else
266 {
267 for (const label pointi : f)
268 {
269 verts[nPoints++] = pointMap[pointi];
270 }
271 }
272 }
273 }
274
275 // Finally
276 if (nFaces)
277 {
278 offsets[nFaces] = nPoints;
279 }
280
281 return compact;
282}
283
284
286(
288 const polyMesh& mesh,
289 const labelUList& addr,
290 const labelList& pointMap
291)
292{
294 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
295 const faceList& meshFaces = mesh.faces();
296 const labelList& owner = mesh.faceOwner();
297
298 const label off = (1); // 1-based for Ensight
299
300 for (const label cellId : addr)
301 {
302 for (const label faceId : meshCells[cellId])
303 {
304 const face& f = meshFaces[faceId];
305
306 if (faceId < owner.size() && owner[faceId] != cellId)
307 {
308 // The neighbour of an internal face
309 // - write as face::reverseFace()
310
311 os.write(pointMap[f[0]] + off);
312 for (label pti = f.size()-1; pti > 0; --pti)
313 {
314 os.write(pointMap[f[pti]] + off);
315 }
316 }
317 else
318 {
319 for (const label pointi : f)
320 {
321 os.write(pointMap[pointi] + off);
322 }
323 }
324
325 os.newline(); // One face per line (ASCII)
326 }
327 }
328}
329
330
332(
334 const cellUList& meshCells,
335 const labelUList& addr,
336 const faceUList& meshFaces,
337 const labelUList& owner
338)
339{
340 const label off = (1); // 1-based for Ensight
341
342 for (const label cellId : addr)
343 {
344 for (const label faceId : meshCells[cellId])
345 {
346 const face& f = meshFaces[faceId];
347
348 if (faceId < owner.size() && owner[faceId] != cellId)
349 {
350 // The neighbour of an internal face
351 // - write as face::reverseFace()
352
353 os.write(f[0] + off);
354 for (label pti = f.size()-1; pti > 0; --pti)
355 {
356 os.write(f[pti] + off);
357 }
358 }
359 else
360 {
361 for (const label pointi : f)
362 {
363 os.write(pointi + off);
364 }
365 }
366
367 os.newline(); // One face per line (ASCII)
368 }
369 }
370}
371
372
374(
376 const ensightFaces::elemType etype,
377 const label nTotal,
378 const faceUList& faces,
379 bool parallel
380)
381{
382 if (!nTotal)
383 {
384 return;
385 }
386
387 parallel = parallel && Pstream::parRun();
388
389 const IntRange<int> senders =
390 (
391 parallel
392 ? Pstream::subProcs()
393 : IntRange<int>()
394 );
395
396 if (Pstream::master())
397 {
398 os.writeKeyword(ensightFaces::key(etype));
399 os.write(nTotal);
400 os.newline();
401 }
402
403 if (etype == ensightFaces::NSIDED)
404 {
405 // Face sizes (number of points per face)
406
407 labelList send(ensightOutput::Detail::getFaceSizes(faces));
408
409 if (Pstream::master())
410 {
411 // Main
412 os.writeLabels(send);
413
414 // Others
415 for (const int proci : senders)
416 {
417 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
418 labelList recv(fromOther);
419
420 os.writeLabels(recv);
421 }
422 }
423 else if (senders)
424 {
425 OPstream toMaster
426 (
427 Pstream::commsTypes::scheduled,
428 Pstream::masterNo()
429 );
430
431 toMaster << send;
432 }
433 }
434
435
436 // List of points id for each face
437 if (Pstream::master())
438 {
439 // Main
440 writeFaceList(os, faces);
441
442 // Others
443 for (const int proci : senders)
444 {
445 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
446 List<face> recv(fromOther);
447
448 writeFaceList(os, recv);
449 }
450 }
451 else if (senders)
452 {
453 OPstream toMaster
454 (
455 Pstream::commsTypes::scheduled,
456 Pstream::masterNo()
457 );
458
459 toMaster << faces;
460 }
461}
462
463
465(
467 const ensightFaces::elemType etype,
468 const label nTotal,
469 const UIndirectList<face>& faces,
470 bool parallel
471)
472{
473 if (!nTotal)
474 {
475 return;
476 }
477
478 parallel = parallel && Pstream::parRun();
479
480 const IntRange<int> senders =
481 (
482 parallel
483 ? Pstream::subProcs()
484 : IntRange<int>()
485 );
486
487
488 if (Pstream::master())
489 {
490 os.writeKeyword(ensightFaces::key(etype));
491 os.write(nTotal);
492 os.newline();
493 }
494
495 if (etype == ensightFaces::NSIDED)
496 {
497 // Face sizes (number of points per face)
498
499 labelList send(ensightOutput::Detail::getFaceSizes(faces));
500
501 if (Pstream::master())
502 {
503 // Main
504 os.writeLabels(send);
505
506 // Others
507 for (const int proci : senders)
508 {
509 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
510 labelList recv(fromOther);
511
512 os.writeLabels(recv);
513 }
514 }
515 else if (senders)
516 {
517 OPstream toMaster
518 (
519 Pstream::commsTypes::scheduled,
520 Pstream::masterNo()
521 );
522
523 toMaster << send;
524 }
525 }
526
527
528 // List of points id per face
529
530 if (Pstream::master())
531 {
532 // Main
533 writeFaceList(os, faces);
534
535 // Others
536 for (const int proci : senders)
537 {
538 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
539 List<face> recv(fromOther);
540
541 writeFaceList(os, recv);
542 }
543 }
544 else if (senders)
545 {
546 OPstream toMaster
547 (
548 Pstream::commsTypes::scheduled,
549 Pstream::masterNo()
550 );
551
552 toMaster << faces;
553 }
554}
555
556
558(
560 const ensightFaces& part,
561 const faceUList& faces,
562 bool parallel
563)
564{
565 for (label typei=0; typei < ensightFaces::nTypes; ++typei)
566 {
567 const auto etype = ensightFaces::elemType(typei);
568
570 (
571 os,
572 etype,
573 part.total(etype),
574 UIndirectList<face>(faces, part.faceIds(etype)),
575 parallel
576 );
577 }
578}
579
580
582(
584 const ensightFaces& part,
585 const faceUList& faces,
586 bool parallel
587)
588{
589 for (label typei=0; typei < ensightFaces::nTypes; ++typei)
590 {
591 const auto etype = ensightFaces::elemType(typei);
592
594 (
595 os,
596 etype,
597 part.total(etype),
598 SubList<face>(faces, part.range(etype)),
599 parallel
600 );
601 }
602}
603
604
605// ************************************************************************* //
Various functions to operate on Lists.
A packed storage unstructured matrix of objects of type <T> using an offset table for access.
const List< T > & values() const noexcept
Return the packed matrix of values.
const labelList & offsets() const noexcept
Return the offset table (= size()+1)
Input inter-processor communications stream.
Definition: IPstream.H:57
label size() const noexcept
The number of elements in the list.
An interval of (signed) integers defined by a start and a size.
Definition: IntRange.H:64
Output inter-processor communications stream.
Definition: OPstream.H:57
A List obtained as a section of another List.
Definition: SubList.H:70
A List with indirect addressing. Like IndirectList but does not store addressing.
Definition: IndirectList.H:79
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Sorting/classification of faces (2D) into corresponding ensight types.
Definition: ensightFaces.H:75
labelRange range(const elemType etype) const
Processor-local offset/size of element type.
Definition: ensightFacesI.H:73
const labelList & faceIds() const noexcept
Processor-local face ids of all elements.
Definition: ensightFacesI.H:79
elemType
Supported ensight 'Face' element types.
Definition: ensightFaces.H:83
label total() const
The global size of all element types.
Definition: ensightFaces.C:136
Specialized Ensight output with extra geometry file header.
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
dynamicFvMesh & mesh
OBJstream os(runTime.globalPath()/outputName)
const labelList nFaces(UPstream::listGatherValues< label >(aMesh.nFaces()))
label nPoints
label cellId
label faceId(-1)
labelList getFaceSizes(const UList< face > &faces)
Return sizes of faces in the list.
Definition: ensightOutput.C:41
labelList getPolysNPointsPerFace(const polyMesh &mesh, const labelUList &addr)
The number of points for each face of the poly elements.
labelList getPolysNFaces(const polyMesh &mesh, const labelUList &addr)
The number of faces per poly element.
Definition: ensightOutput.C:79
CompactListList< label > getPolysFacePoints(const polyMesh &mesh, const labelUList &addr, const labelList &pointMap)
Generate 0-based point ids for each poly element face.
void writeLabelListList(ensightGeoFile &os, const labelUList &offsets, const labelUList &values, const label pointOffset)
Write CompactListList<label> by components.
void writePolysPoints(ensightGeoFile &os, const cellUList &meshCells, const labelUList &addr, const faceUList &meshFaces, const labelUList &faceOwner)
Write the point ids per poly element.
void writeFaceConnectivityPresorted(ensightGeoFile &os, const ensightFaces &part, const faceUList &faces, bool parallel)
Write the presorted face connectivity for the part.
void writeFaceConnectivity(ensightGeoFile &os, const ensightFaces::elemType etype, const label nTotal, const UIndirectList< face > &faces, bool parallel)
void writeCellShapes(ensightGeoFile &os, const UList< cellShape > &shapes, const label pointOffset=0)
Write cell connectivity via cell shapes.
void writeFaceList(ensightGeoFile &os, const UList< face > &faces, const label pointOffset=0)
Write list of faces.
labelList f(nPoints)