Loading...
Searching...
No Matches
convertProcessorPatches.H
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) 2019-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
12
13Description
14 Code chunk for converting volume fields on processor boundaries,
15 included by foamToVTK.
16
17\*---------------------------------------------------------------------------*/
18
19// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
20
21// Generate processor/processorN/procBoundary
22
23{
24 using reportFields = foamToVtkReportFields;
25
26 const label nVolFields = objects.count(Foam::fieldTypes::is_volume);
27
28 reportFields::volume(Info, objects);
29
30 // Setup for the vtm writer.
31
32 fileName vtmOutputBase
33 (
34 outputDir/regionDir/vtkName + timeDesc
35 );
36
37 // Naming
38 const auto subDirNaming =
39 [](const label i) -> fileName
40 { return "processor" / ("processor" + Foam::name(i)); };
41
42
43 // Dummy writer.
44 autoPtr<vtk::internalWriter> internalWriter;
45
46 // Setup the patch writers
47 PtrList<vtk::patchWriter> patchWriters;
48
49 const polyBoundaryMesh& patches = mesh.boundaryMesh();
50
51 labelList patchIds =
52 identity
53 (
54 patches.size()-patches.nNonProcessor(),
55 patches.nNonProcessor()
56 );
57
59 {
60 if (!isA<processorPolyPatch>(patches[patchIds[i]]))
61 {
62 patchIds.resize(i);
63 break;
64 }
65 }
66
67 patchWriters.resize(patchIds.size());
68
69 label nPatchWriters = 0;
70
71 List<wordList> procPatchNames(UPstream::nProcs());
72 procPatchNames[UPstream::myProcNo()].resize(patchIds.size());
74 labelList selectedPatchId(1);
75
76 for (const label patchId : patchIds)
77 {
78 const polyPatch& pp = patches[patchId];
79 selectedPatchId[0] = pp.index();
80
81 auto writer = autoPtr<vtk::patchWriter>::New
82 (
83 meshProxy.mesh(),
85 writeOpts,
86 (
88 / subDirNaming(UPstream::myProcNo())
89 / pp.name()
90 ),
91 false // This MUST be non-parallel (serial only)
92 );
93
94 if (nearCellValue)
95 {
96 writer->useCellValue(nearCellValue);
97 }
98
99 procPatchNames[UPstream::myProcNo()][nPatchWriters] = pp.name();
100
101 writer->writeTimeValue(timeValue);
102 writer->writeGeometry();
103
104 // Transfer writer to list for later use
106 }
108
110 Pstream::gatherList(procPatchNames);
111
112 // CellData
113 {
114 for (auto& writer : patchWriters)
115 {
116 // Optionally with patchID, procID, neighID fields
117 // - use UPstream::parRun() not writer.parallel() !!
118 writer.beginCellData
119 (
120 (withMeshIds ? 1 + (UPstream::parRun() ? 2 : 0) : 0)
121 + nVolFields
122 );
123
124 if (withMeshIds)
125 {
126 writer.writePatchIDs();
127 writer.writeProcIDs(); // parallel only
128 writer.writeNeighIDs(); // parallel only
129 }
130 }
131
133 (
136 meshProxy,
137 objects,
138 true, // syncPar
139 nullptr // no field cache (object registry)
140 );
141
142 // End CellData is implicit
143 }
144
145
146 // Finish writers
147 if (internalWriter)
148 {
150 }
151
152 for (auto& writer : patchWriters)
153 {
154 writer.close();
155 }
156
157 patchWriters.clear();
158
160 // Collective output
161
162 const label nProcPatches = returnReduce(nPatchWriters, sumOp<label>());
163
164 if (UPstream::master() && nProcPatches)
165 {
166 Info<< "Wrote " << nProcPatches << " processor boundaries from "
167 << UPstream::nProcs() << " processes" << nl;
168
169
170 // Collect individual boundaries into a vtm file
171 vtk::vtmWriter vtmBoundaries;
172
173 // Naming for vtm
174 fileName outputName(vtmOutputBase / "processor");
175 outputName.ext(vtmBoundaries.ext());
176
177 vtmBoundaries.setTime(timeValue);
178
179 forAll(procPatchNames, proci)
180 {
181 label n = 0;
182
183 const word blockName("proc" + Foam::name(proci));
184 const fileName dirName = subDirNaming(proci);
185
186 for (const word& patchName : procPatchNames[proci])
187 {
188 if (!n)
189 {
190 vtmBoundaries.beginBlock(blockName);
191 ++n;
192 }
193
194 vtmBoundaries.append_poly
195 (
196 patchName,
197 dirName/patchName
198 );
199 }
200
201 if (n)
202 {
203 vtmBoundaries.endBlock();
204 }
205 }
206
207
208 // Emit "processor.vtm" with collection of processor boundaries
210 }
211}
212
213
214// ************************************************************************* //
label n
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edgesCentres")))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
labelList patchIds
const label nProcPatches
const label nVolFields
label nPatchWriters
fileName vtmOutputBase(outputDir/regionDir/vtkName+timeDesc)
labelList selectedPatchId(1)
autoPtr< vtk::internalWriter > internalWriter
List< wordList > procPatchNames(UPstream::nProcs())
PtrList< vtk::patchWriter > patchWriters
const polyBoundaryMesh & patches
const auto subDirNaming
dynamicFvMesh & mesh
word outputName("finiteArea-edges.obj")
const word & regionDir
vtk::vtmWriter vtmBoundaries
label patchId(-1)
return returnReduce(nRefine-oldNRefine, sumOp< label >())
bool is_volume(const word &clsName)
Test if the class name appears to be a volume field.
Definition volFields.C:165
label writeAllVolFields(ensightCase &ensCase, const ensightMesh &ensMesh, const IOobjectList &objects, const bool nearCellValue=false)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299