Loading...
Searching...
No Matches
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#include "debug.H"
37#include "registerSwitch.H"
38
39// * * * * * * * * * * * * * * * * Globals * * * * * * * * * * * * * * * * * //
40
42
44
46(
47 Foam::debug::optimisationSwitch("ensight.maxChunk", 0)
48);
49
51
52
53// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54
55// Sizes
56
58(
59 const UList<face>& faces
60)
61{
62 labelList list(faces.size());
63
64 auto outIter = list.begin();
65
66 for (const face& f : faces)
67 {
68 *outIter = f.size();
69 ++outIter;
70 }
71
72 return list;
73}
74
75
77(
78 const UIndirectList<face>& faces
79)
80{
81 labelList list(faces.size());
82
83 auto outIter = list.begin();
84
85 for (const face& f : faces)
86 {
87 *outIter = f.size();
88 ++outIter;
89 }
90
91 return list;
92}
93
94
96(
97 const polyMesh& mesh,
98 const labelUList& addr
99)
100{
102 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
103
104 labelList list(addr.size());
105
106 auto outIter = list.begin();
107
108 // The number of faces per element
109 for (const label cellId : addr)
110 {
111 *outIter = meshCells[cellId].size();
112 ++outIter;
113 }
114
115 return list;
116}
117
118
120(
121 const polyMesh& mesh,
122 const labelUList& addr
123)
124{
126 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
127 const faceList& meshFaces = mesh.faces();
128
129 // Count the number of faces per element
130
131 label nTotFaces = 0;
132 for (const label cellId : addr)
133 {
134 nTotFaces += meshCells[cellId].size();
135 }
136
137 labelList list(nTotFaces);
138
139 auto outIter = list.begin();
140
141 // The number of points per element face
142 for (const label cellId : addr)
143 {
144 for (const label facei : meshCells[cellId])
145 {
146 *outIter = meshFaces[facei].size();
147 ++outIter;
149 }
150
151 return list;
152}
153
154
156(
157 ensightGeoFile& os,
158 const labelUList& offsets,
159 const labelUList& values,
160 const label pointOffset
161)
162{
163 const label off = (pointOffset + 1); // 1-based for Ensight
164
165 const label nLists = (offsets.size() - 1);
166
167 for (label i = 0; i < nLists; ++i)
168 {
169 const labelUList list
170 (
171 values.slice(offsets[i], (offsets[i+i] - offsets[i]))
172 );
173 for (const label pointi : list)
174 {
175 os.write(pointi + off);
176 }
177 os.newline(); // One list (cell/faces) per line (ASCII)
178 }
179}
180
181
183(
184 ensightGeoFile& os,
185 const UList<face>& faces,
186 const label pointOffset
187)
188{
190}
191
192
194(
196 const UIndirectList<face>& faces,
197 const label pointOffset
198)
199{
201}
202
203
205(
207 const CompactListList<label>& faces,
208 const label pointOffset
209)
210{
212}
213
214
216(
218 const UList<cellShape>& shapes,
219 const label pointOffset
221{
222 ensightOutput::Detail::writeLabelListList(os, shapes, pointOffset);
223}
224
225
228(
229 const polyMesh& mesh,
230 const labelUList& addr,
231 const labelList& pointMap
232)
233{
235 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
236 const faceList& meshFaces = mesh.faces();
237 const labelList& owner = mesh.faceOwner();
238
239
240 // The caller should have already checked for possible overflow,
241 // so can skip that here.
242 // but still need the sizing for allocations
243
244 label nFaces = 0, nPoints = 0;
245 for (const label cellId : addr)
246 {
247 nFaces += meshCells[cellId].size();
248
249 for (const label faceId : meshCells[cellId])
250 {
251 nPoints += meshFaces[faceId].size();
252 }
253 }
254
255
256 CompactListList<label> compact(nFaces, nPoints);
257 labelList& offsets = compact.offsets();
258 labelList& verts = compact.values();
259
260 // Restart counts
261 nFaces = nPoints = 0;
262
263 for (const label cellId : addr)
264 {
265 for (const label faceId : meshCells[cellId])
266 {
267 const face& f = meshFaces[faceId];
268
269 offsets[nFaces++] = nPoints;
270
271 if (faceId < owner.size() && owner[faceId] != cellId)
272 {
273 // The neighbour of an internal face
274 // - handle like face::reverseFace()
275
276 verts[nPoints++] = pointMap[f[0]];
277 for (label pti = f.size()-1; pti > 0; --pti)
278 {
279 verts[nPoints++] = pointMap[f[pti]];
280 }
281 }
282 else
283 {
284 for (const label pointi : f)
285 {
286 verts[nPoints++] = pointMap[pointi];
287 }
288 }
289 }
290 }
291
292 // Finally
293 if (nFaces)
294 {
295 offsets[nFaces] = nPoints;
296 }
297
298 return compact;
299}
300
301
303(
304 ensightGeoFile& os,
305 const polyMesh& mesh,
306 const labelUList& addr,
307 const labelList& pointMap
308)
309{
311 const cellList& meshCells = manifoldCellsMeshObject::New(mesh).cells();
312 const faceList& meshFaces = mesh.faces();
313 const labelList& owner = mesh.faceOwner();
314
315 const label off = (1); // 1-based for Ensight
316
317 for (const label cellId : addr)
318 {
319 for (const label faceId : meshCells[cellId])
320 {
321 const face& f = meshFaces[faceId];
322
323 if (faceId < owner.size() && owner[faceId] != cellId)
324 {
325 // The neighbour of an internal face
326 // - write as face::reverseFace()
327
328 os.write(pointMap[f[0]] + off);
329 for (label pti = f.size()-1; pti > 0; --pti)
330 {
331 os.write(pointMap[f[pti]] + off);
332 }
333 }
334 else
335 {
336 for (const label pointi : f)
337 {
338 os.write(pointMap[pointi] + off);
339 }
340 }
342 os.newline(); // One face per line (ASCII)
343 }
344 }
345}
346
347
349(
350 ensightGeoFile& os,
351 const cellUList& meshCells,
352 const labelUList& addr,
353 const faceUList& meshFaces,
354 const labelUList& owner
355)
356{
357 const label off = (1); // 1-based for Ensight
358
359 for (const label cellId : addr)
360 {
361 for (const label faceId : meshCells[cellId])
362 {
363 const face& f = meshFaces[faceId];
364
365 if (faceId < owner.size() && owner[faceId] != cellId)
366 {
367 // The neighbour of an internal face
368 // - write as face::reverseFace()
369
370 os.write(f[0] + off);
371 for (label pti = f.size()-1; pti > 0; --pti)
372 {
373 os.write(f[pti] + off);
374 }
375 }
376 else
377 {
378 for (const label pointi : f)
379 {
380 os.write(pointi + off);
381 }
382 }
384 os.newline(); // One face per line (ASCII)
385 }
386 }
387}
388
389
391(
392 ensightGeoFile& os,
393 const ensightFaces::elemType etype,
394 const label nTotal,
395 const faceUList& faces,
396 bool parallel
397)
398{
399 if (!nTotal)
400 {
401 return;
402 }
403
404 parallel = parallel && Pstream::parRun();
405
406 const IntRange<int> senders =
407 (
408 parallel
409 ? Pstream::subProcs()
410 : IntRange<int>()
411 );
412
413 if (Pstream::master())
414 {
415 os.writeKeyword(ensightFaces::key(etype));
416 os.write(nTotal);
417 os.newline();
418 }
419
420 if (etype == ensightFaces::elemType::NSIDED)
421 {
422 // Face sizes (number of points per face)
423
424 labelList send(ensightOutput::Detail::getFaceSizes(faces));
425
426 if (Pstream::master())
427 {
428 // Main
429 os.writeLabels(send);
430
431 // Others
432 for (const int proci : senders)
433 {
434 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
435 labelList recv(fromOther);
436
437 os.writeLabels(recv);
438 }
439 }
440 else if (senders)
441 {
442 OPstream toMaster
443 (
444 Pstream::commsTypes::scheduled,
445 Pstream::masterNo()
446 );
447
448 toMaster << send;
449 }
450 }
451
452
453 // List of points id for each face
454 if (Pstream::master())
455 {
456 // Main
457 writeFaceList(os, faces);
458
459 // Others
460 for (const int proci : senders)
461 {
462 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
463 List<face> recv(fromOther);
464
465 writeFaceList(os, recv);
466 }
467 }
468 else if (senders)
469 {
470 OPstream toMaster
471 (
472 Pstream::commsTypes::scheduled,
473 Pstream::masterNo()
474 );
475
476 toMaster << faces;
477 }
478}
479
480
482(
483 ensightGeoFile& os,
484 const ensightFaces::elemType etype,
485 const label nTotal,
486 const UIndirectList<face>& faces,
487 bool parallel
488)
489{
490 if (!nTotal)
491 {
492 return;
493 }
494
495 parallel = parallel && Pstream::parRun();
496
497 const IntRange<int> senders =
498 (
499 parallel
500 ? Pstream::subProcs()
501 : IntRange<int>()
502 );
503
504
505 if (Pstream::master())
506 {
507 os.writeKeyword(ensightFaces::key(etype));
508 os.write(nTotal);
509 os.newline();
510 }
511
512 if (etype == ensightFaces::elemType::NSIDED)
513 {
514 // Face sizes (number of points per face)
515
516 labelList send(ensightOutput::Detail::getFaceSizes(faces));
517
518 if (Pstream::master())
519 {
520 // Main
521 os.writeLabels(send);
522
523 // Others
524 for (const int proci : senders)
525 {
526 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
527 labelList recv(fromOther);
528
529 os.writeLabels(recv);
530 }
531 }
532 else if (senders)
533 {
534 OPstream toMaster
535 (
536 Pstream::commsTypes::scheduled,
537 Pstream::masterNo()
538 );
539
540 toMaster << send;
541 }
542 }
543
544
545 // List of points id per face
546
547 if (Pstream::master())
548 {
549 // Main
550 writeFaceList(os, faces);
551
552 // Others
553 for (const int proci : senders)
554 {
555 IPstream fromOther(Pstream::commsTypes::scheduled, proci);
556 List<face> recv(fromOther);
557
558 writeFaceList(os, recv);
559 }
560 }
561 else if (senders)
562 {
563 OPstream toMaster
564 (
565 Pstream::commsTypes::scheduled,
566 Pstream::masterNo()
567 );
568
569 toMaster << faces;
570 }
571}
572
573
575(
576 ensightGeoFile& os,
577 const ensightFaces& part,
578 const faceUList& faces,
579 bool parallel
580)
581{
582 for (label typei=0; typei < ensightFaces::nTypes; ++typei)
583 {
584 const auto etype = ensightFaces::elemType(typei);
585
586 writeFaceConnectivity
587 (
588 os,
589 etype,
590 part.total(etype),
591 UIndirectList<face>(faces, part.faceIds(etype)),
592 parallel
593 );
594 }
595}
596
597
599(
600 ensightGeoFile& os,
601 const ensightFaces& part,
602 const faceUList& faces,
603 bool parallel
604)
605{
606 for (label typei=0; typei < ensightFaces::nTypes; ++typei)
607 {
608 const auto etype = ensightFaces::elemType(typei);
609
610 writeFaceConnectivity
611 (
612 os,
613 etype,
614 part.total(etype),
615 SubList<face>(faces, part.range(etype)),
616 parallel
617 );
618 }
619}
620
621
622// ************************************************************************* //
Various functions to operate on Lists.
A packed storage of objects of type <T> using an offset table for access.
const labelList & offsets() const noexcept
Return the offset table (= size()+1).
const List< T > & values() const noexcept
Return the packed values.
Input inter-processor communications stream.
Definition IPstream.H:53
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:69
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
static FOAM_NO_DANGLING_REFERENCE const manifoldCellsMeshObject & New(const polyMesh &mesh, Args &&... args)
Output inter-processor communications stream.
Definition OPstream.H:53
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
A List with indirect addressing. Like IndirectList but does not store addressing.
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:89
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
@ scheduled
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
Definition UPstream.H:83
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition UPstream.H:1691
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition UPstream.H:1866
Sorting/classification of faces (2D) into corresponding ensight types.
labelRange range(const elemType etype) const
Processor-local offset/size of element type.
static const char * key(const elemType etype) noexcept
The ensight element name for the specified 'Face' type.
const labelList & faceIds() const noexcept
Processor-local face ids of all elements.
label total() const noexcept
Same as totalSize.
static constexpr int nTypes
Number of 'Face' element types (3).
elemType
Supported ensight 'Face' element types.
A variant of ensightFile (Ensight writing) that includes the extra geometry file header information.
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
dynamicFvMesh & mesh
Macro definitions for debug switches.
#define registerDebugSwitchWithName(Type, Tag, Name)
Define the debug information, lookup as Name.
#define defineDebugSwitchWithName(Type, Name, Value)
Define the debug information, lookup as Name.
OBJstream os(runTime.globalPath()/outputName)
label nPoints
label cellId
label faceId(-1)
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition debug.C:234
labelList getFaceSizes(const UList< face > &faces)
Return sizes of faces in the list.
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.
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.
A collection of functions for writing ensight file content.
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)
Write the regular face connectivity for specified type and and specified faces.
int maxChunk_
Upper limit on number of items for bundled off-processor field transfers. The component-wise transfer...
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.
UList< cell > cellUList
UList of cell.
Definition cellListFwd.H:43
List< label > labelList
A List of labels.
Definition List.H:62
List< face > faceList
List of faces.
Definition faceListFwd.H:41
List< cell > cellList
List of cell.
Definition cellListFwd.H:41
UList< label > labelUList
A UList of labels.
Definition UList.H:75
UList< face > faceUList
UList of faces.
Definition faceListFwd.H:43
labelList f(nPoints)
#define registerOptSwitch(Name, Type, SwitchVar)