Loading...
Searching...
No Matches
convertAreaFields.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) 2018-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 finite-area - included by foamToVTK.
15
16 Typedef vtkWriterType_areaMesh is declared in writeAreaFields.H
17
18Note
19 Whereas foamToEnsight creates all mesh accounting up front,
20 and uses a List of PtrList for managing the area regions,
21 foamToVTK handles them every timestep by checking for file contents
22 in the respective area regions.
23 This incurs a penalty with creating the finite-area meshes for each
24 timestep, but increases its flexibility.
25
26\*---------------------------------------------------------------------------*/
27
28//
29// Finite-area mesh and fields - need not exist
30//
31
32// No subsetting!
33if (doFiniteArea && !areaRegionNames.empty())
34{
35 using reportFields = foamToVtkReportFields;
36
37 // The (region) polyMesh being used. No subsetting possible
38 const auto& basePolyMesh = meshProxy.baseMesh();
39
40 for (const word& areaName : areaRegionNames)
41 {
42 const bool isDefaultRegion(polyMesh::regionName(areaName).empty());
43
44 // CAUTION
45 // If we want to have constant access to the HashTable:
46 //
47 // (SEGFAULT)
48 // const auto& faObjs = faObjects.lookup(areaName, IOobjectList());
49 //
50 // Use an empty fallback to avoid binding to a temporary:
51 //
52 // const IOobjectList emptyObjectList;
53 // const auto& faObjs = faObjects.lookup(areaName, emptyObjectList);
54
55 // Since we do not need the area fields afterwards,
56 // just move them out from the HashTable
57
58 IOobjectList faObjs;
59 if (auto iter = faObjects.find(areaName); iter.good())
60 {
61 faObjs = std::move(iter.val());
62 }
63
64 const label nAreaFields = faObjs.count(Foam::fieldTypes::is_area);
65
66 autoPtr<faMesh> faMeshPtr;
67
68 if (nAreaFields || withMeshIds)
69 {
70 faMeshPtr = faMesh::TryNew(areaName, basePolyMesh);
71 }
72
73 if (!faMeshPtr)
74 {
75 if (!isDefaultRegion)
76 {
77 // Report any area region specified but missing
78 // - silently ignore region0
79 Info<< "No area-mesh [" << polyMesh::regionName(areaName)
80 << "] on volume-region ["
81 << basePolyMesh.regionName() << "]" << endl;
82 }
83 continue;
84 }
85 const auto& areaMesh = faMeshPtr();
86
87 Info<< "Using area-mesh [" << polyMesh::regionName(areaName)
88 << "] on volume-region ["
89 << basePolyMesh.regionName() << "]" << endl;
90
91
92 reportFields::area(Info, faObjs);
93
94 const auto& pp = faMeshPtr->patch();
95
96 vtkWriterType_areaMesh writer
97 (
98 pp,
99 writeOpts,
100 (
101 outputDir/regionDir/"finite-area"
102 / (
103 isDefaultRegion
104 ? fileName("finiteArea")
105 : fileName(areaName/areaName)
106 )
107 + timeDesc
108 ),
109 UPstream::parRun()
110 );
111 Info<< " Area : "
112 << args.relativePath(writer.output()) << nl;
113
114 writer.beginFile(areaMesh.name());
115
116 writer.writeTimeValue(timeValue);
117 writer.writeGeometry();
118
119 // Optionally with (cellID, patchID, faceLabels, procID) fields
120 writer.beginCellData
121 (
122 (withMeshIds ? 3 + (writer.parallel() ? 1 : 0) : 0)
123 + nAreaFields
124 );
125
126 if (withMeshIds)
127 {
128 const globalIndex procAddr(areaMesh.nFaces());
129
130 // Use global indexed values for the 'cell' ids
131 writer.writeCellData("cellID", identity(procAddr.range()));
132
133 // The patch ids can also be quite useful
134 const polyBoundaryMesh& pbm = areaMesh.mesh().boundaryMesh();
135
136 labelList patchIds
137 (
138 pbm.patchID(areaMesh.faceLabels())
139 );
140
141 writer.writeCellData("patchID", patchIds);
142
143 // Use proc-local data for faceLabels
144 // (confusing enough already without renumbering)
145 writer.writeCellData("faceLabels", areaMesh.faceLabels());
146
147 writer.writeProcIDs(); // parallel only
148 }
149
150 writeAllAreaFields
151 (
152 writer,
153 areaMesh,
154 faObjs,
155 true // syncPar
156 );
157
158 fileName outputName(writer.output());
159
160 writer.close();
161
162 if (UPstream::master())
163 {
164 // Add to file-series and emit as JSON
165
166 fileName seriesName(vtk::seriesWriter::base(outputName));
167
168 vtk::seriesWriter& series = vtkSeries(seriesName);
169
170 // First time?
171 // Load from file, verify against filesystem,
172 // prune time >= currentTime
173 if (series.empty())
174 {
175 series.load(seriesName, true, timeValue);
176 }
177
178 series.append(timeValue, outputName);
179 series.write(seriesName);
180 }
181 }
182}
183
184
185// ************************************************************************* //
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edgesCentres")))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
const polyBoundaryMesh & pbm
labelList patchIds
word outputName("finiteArea-edges.obj")
const word & regionDir
wordList areaRegionNames
bool is_area(const word &clsName)
Test if the class name appears to be an area field.
Definition areaFields.C:154
Foam::argList args(argc, argv)