convertSurfaceFields.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-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
12 
13 Description
14  Code chunk for post-processing surface fields to VTK PolyData
15 
16 \*---------------------------------------------------------------------------*/
17 
18 {
19  using reportFields = foamToVtkReportFields;
20 
21  // Load only once when possible
22  label nSurfaceScalarField = -1;
23  label nSurfaceVectorField = -1;
24 
25  PtrList<const surfaceScalarField> sScalars;
26  PtrList<const surfaceVectorField> sVectors;
27 
28  // Surface Fields
29  if (doSurfaceFields)
30  {
31  if (nSurfaceScalarField == -1)
32  {
33  sScalars = readFields<surfaceScalarField>(meshProxy, objects);
34 
35  reportFields::print(" surfScalar :", Info, sScalars);
37  }
38  else
39  {
40  sScalars.resize(nSurfaceScalarField); // Consistent sizing
41  }
42 
43  if (nSurfaceVectorField == -1)
44  {
45  sVectors = readFields<surfaceVectorField>(meshProxy, objects);
46 
47  reportFields::print(" surfVector :", Info, sVectors);
49  }
50  else
51  {
52  sVectors.resize(nSurfaceVectorField); // Consistent sizing
53  }
54 
55  if (sScalars.size())
56  {
57  // Change scalar fields into vector fields, but leave
58  // the count of vector fields unchanged. This allows us to
59  // easily delete these synthetic fields later.
60 
61  surfaceVectorField unitNorm(mesh.Sf()/mesh.magSf());
62 
64 
65  label nExtra = 0;
66  for (const auto& ssf : sScalars)
67  {
68  surfaceVectorField* tsvfPtr = (ssf * unitNorm).ptr();
69  tsvfPtr->rename(ssf.name());
70  sVectors.set(nSurfaceVectorField + nExtra, tsvfPtr);
71  ++nExtra;
72  }
73  }
74 
75  if (sVectors.size())
76  {
77  vtk::surfaceFieldWriter writer
78  (
79  meshProxy.mesh(),
80  writeOpts,
81  (
82  outputDir/regionDir
83  / "surface-fields"/"surfaceFields" + timeDesc
84  ),
85  UPstream::parRun()
86  );
87 
88  Info<< " Surface : "
89  << args.relativePath(writer.output()) << nl;
90 
91 
92  writer.writeTimeValue(timeValue);
93  writer.writeGeometry();
94 
95  writer.beginPointData(sVectors.size());
96 
97  for (const auto& fld : sVectors)
98  {
99  writer.write(fld);
100  }
101 
102  fileName outputName(writer.output());
103 
104  writer.close();
105 
106  if (UPstream::master())
107  {
108  // Add to file-series and emit as JSON
109 
110  fileName seriesName(vtk::seriesWriter::base(outputName));
111 
112  vtk::seriesWriter& series = vtkSeries(seriesName);
113 
114  // First time?
115  // Load from file, verify against filesystem,
116  // prune time >= currentTime
117  if (series.empty())
118  {
119  series.load(seriesName, true, timeValue);
120  }
121 
122  series.append(timeValue, outputName);
123  series.write(seriesName);
124  }
125  }
126  }
127 
128 
129  // Write faceZones (POLYDATA file, one for each zone)
130 
131  if (!selectedFaceZones.empty() && !mesh.faceZones().empty())
132  {
133  if (nSurfaceScalarField == -1)
134  {
135  sScalars = readFields<surfaceScalarField>(meshProxy, objects);
136  nSurfaceScalarField = sScalars.size();
137 
138  reportFields::print(" surfScalar :", Info, sScalars);
139  }
140  else
141  {
142  sScalars.resize(nSurfaceScalarField); // Consistent sizing
143  }
144 
145  if (nSurfaceVectorField == -1)
146  {
147  sVectors = readFields<surfaceVectorField>(meshProxy, objects);
148  nSurfaceVectorField = sVectors.size();
149 
150  reportFields::print(" surfVector :", Info, sVectors);
151  }
152  else
153  {
154  sVectors.resize(nSurfaceVectorField); // Consistent sizing
155  }
156 
157  for (const faceZone& fz : mesh.faceZones())
158  {
159  if (!selectedFaceZones.match(fz.name()))
160  {
161  continue;
162  }
163 
164  // Retrieve as primitiveFacePatch with faces properly flipped
165  const primitiveFacePatch& pp = fz();
166 
168  (
169  pp,
170  writeOpts,
171  (
172  outputDir/regionDir/fz.name()
173  / (meshProxy.useSubMesh() ? meshProxy.name() : fz.name())
174  + timeDesc
175  ),
176  UPstream::parRun()
177  );
178 
179  Info<< " FaceZone : "
180  << args.relativePath(writer.output()) << nl;
181 
182 
183  writer.beginFile(fz.name());
184  writer.writeTimeValue(timeValue);
185  writer.writeGeometry();
186 
187  writer.beginCellData(sScalars.size() + sVectors.size());
188 
189  for (const auto& fld : sScalars)
190  {
191  writer.write(fld, fz.addressing());
192  }
193  for (const auto& fld : sVectors)
194  {
195  writer.write(fld, fz.addressing());
196  }
197 
198  fileName outputName(writer.output());
199 
200  writer.close();
201 
202  if (UPstream::master())
203  {
204  // Add to file-series and emit as JSON
205 
206  fileName seriesName(vtk::seriesWriter::base(outputName));
207 
208  vtk::seriesWriter& series = vtkSeries(seriesName);
209 
210  // First time?
211  // Load from file, verify against filesystem,
212  // prune time >= currentTime
213  if (series.empty())
214  {
215  series.load(seriesName, true, timeValue);
216  }
217 
218  series.append(timeValue, outputName);
219  series.write(seriesName);
220  }
221  }
222  }
223 }
224 
225 
226 // ************************************************************************* //
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/"finiteArea-edgesCentres"))
Ostream & print(Ostream &os, UIntType value, char off='0', char on='1')
Print 0/1 bits in the (unsigned) integral type.
Definition: BitOps.H:323
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
PtrList< const surfaceVectorField > sVectors
word outputName("finiteArea-edges.obj")
dynamicFvMesh & mesh
label nSurfaceScalarField
label nSurfaceVectorField
fileName relativePath(const fileName &input, const bool caseTag=false) const
Return the input relative to the globalPath by stripping off a leading value of the globalPath...
Definition: argListI.H:87
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:484
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
PtrList< const surfaceScalarField > sScalars
const word & regionDir
messageStream Info
Information stream (stdout output on master, null elsewhere)
vtk::GenericPatchGeoFieldsWriter< primitiveFacePatch > vtkWriterType_faceZone
Foam::argList args(argc, argv)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())