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-2021 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
26Description
27 Code chunk for converting volume fields on processor boundaries,
28 included by foamToVTK.
29
30\*---------------------------------------------------------------------------*/
31
32// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33
34// Generate processor/processorN/procBoundary
35
36{
37 using reportFields = foamToVtkReportFields;
38
39 const label nVolFields =
40 (
41 objects.count(stringListOps::foundOp<word>(fieldTypes::volume))
42 );
43
44 reportFields::volume(Info, objects);
45
46 // Setup for the vtm writer.
47
49 (
50 outputDir/regionDir/vtkName + timeDesc
51 );
52
53 // Naming
54 const auto subDirNaming =
55 [](const label i) -> fileName
56 { return "processor" / ("processor" + Foam::name(i)); };
57
58
59 // Dummy writer.
60 autoPtr<vtk::internalWriter> internalWriter;
61
62 // Setup the patch writers
63 PtrList<vtk::patchWriter> patchWriters;
64
65 const polyBoundaryMesh& patches = mesh.boundaryMesh();
66
67 labelList patchIds =
68 identity
69 (
70 patches.size()-patches.nNonProcessor(),
71 patches.nNonProcessor()
72 );
73
75 {
76 if (!isA<processorPolyPatch>(patches[patchIds[i]]))
77 {
78 patchIds.resize(i);
79 break;
80 }
81 }
82
83 patchWriters.resize(patchIds.size());
84
85 label nPatchWriters = 0;
86
87 List<wordList> procPatchNames(Pstream::nProcs());
88
89 procPatchNames[Pstream::myProcNo()].resize(patchIds.size());
90
91 for (const label patchId : patchIds)
92 {
93 const polyPatch& pp = patches[patchId];
94
95 auto writer = autoPtr<vtk::patchWriter>::New
96 (
97 meshProxy.mesh(),
98 labelList(one{}, pp.index()),
99 writeOpts,
100 nearCellValue,
101 (
103 / subDirNaming(Pstream::myProcNo())
104 / pp.name()
105 ),
106 false // This MUST be non-parallel (serial only)
107 );
108
109 procPatchNames[Pstream::myProcNo()][nPatchWriters] = pp.name();
110
111 writer->writeTimeValue(timeValue);
112 writer->writeGeometry();
113
114 // Transfer writer to list for later use
116 }
118
119
120 Pstream::gatherList(procPatchNames);
121
122 // CellData
123 {
124 for (vtk::patchWriter& writer : patchWriters)
125 {
126 // Optionally with patchID, procID, neighID fields
127 // - use Pstream::parRun() not writer.parallel() !!
128 writer.beginCellData
129 (
130 (withMeshIds ? 1 + (Pstream::parRun() ? 2 : 0) : 0)
131 + nVolFields
132 );
133
134 if (withMeshIds)
135 {
136 writer.writePatchIDs();
137 writer.writeProcIDs(); // parallel only
138 writer.writeNeighIDs(); // parallel only
139 }
140 }
141
143 (
146 meshProxy,
147 objects,
148 true // syncPar
149 );
150
151 // End CellData is implicit
152 }
153
154
155 // Finish writers
157 {
158 internalWriter->close();
159 }
160
161 for (vtk::patchWriter& writer : patchWriters)
162 {
163 writer.close();
164 }
165
167
168
169 // Collective output
170
171 const label nProcPatches = returnReduce(nPatchWriters, sumOp<label>());
172
173 if (Pstream::master() && nProcPatches)
174 {
175 Info<< "Wrote " << nProcPatches << " processor boundaries from "
176 << Pstream::nProcs() << " processes" << nl;
177
178
179 // Collect individual boundaries into a vtm file
180 vtk::vtmWriter vtmBoundaries;
181
182 // Naming for vtm
183 fileName outputName(vtmOutputBase / "processor");
184 outputName.ext(vtmBoundaries.ext());
185
186 vtmBoundaries.setTime(timeValue);
187
188 forAll(procPatchNames, proci)
189 {
190 label n = 0;
191
192 const word blockName("proc" + Foam::name(proci));
193 const fileName dirName = subDirNaming(proci);
194
195 for (const word& patchName : procPatchNames[proci])
196 {
197 if (!n)
198 {
199 vtmBoundaries.beginBlock(blockName);
200 ++n;
201 }
202
203 vtmBoundaries.append_vtp
204 (
205 patchName,
206 dirName/patchName
207 );
208 }
209
210 if (n)
211 {
212 vtmBoundaries.endBlock();
213 }
214 }
215
216
217 // Emit "processor.vtm" with collection of processor boundaries
219 }
220}
221
222
223// ************************************************************************* //
label n
vtk::internalMeshWriter writer(topoMesh, topoCells, vtk::formatType::INLINE_ASCII, runTime.path()/"blockTopology")
labelList patchIds
const label nProcPatches
const label nVolFields
label nPatchWriters
fileName vtmOutputBase(outputDir/regionDir/vtkName+timeDesc)
autoPtr< vtk::internalWriter > internalWriter
PtrList< vtk::patchWriter > patchWriters
const polyBoundaryMesh & patches
List< wordList > procPatchNames(Pstream::nProcs())
const auto subDirNaming
dynamicFvMesh & mesh
word outputName("finiteArea-edges.obj")
const word & regionDir
vtk::vtmWriter vtmBoundaries
label patchId(-1)
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 INVALID.
Definition: exprTraits.C:59
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333