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.
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 Description
27  Code chunk for post-processing surface fields to VTK PolyData
28 
29 \*---------------------------------------------------------------------------*/
30 
31 {
32  using reportFields = foamToVtkReportFields;
33 
34  // Load only once when possible
35  label nSurfaceScalarField = -1;
36  label nSurfaceVectorField = -1;
37 
38  PtrList<const surfaceScalarField> sScalars;
39  PtrList<const surfaceVectorField> sVectors;
40 
41  // Surface Fields
42  if (doSurfaceFields)
43  {
44  if (nSurfaceScalarField == -1)
45  {
46  sScalars = readFields<surfaceScalarField>(meshProxy, objects);
47 
48  reportFields::print(" surfScalar :", Info, sScalars);
50  }
51  else
52  {
53  sScalars.resize(nSurfaceScalarField); // Consistent sizing
54  }
55 
56  if (nSurfaceVectorField == -1)
57  {
58  sVectors = readFields<surfaceVectorField>(meshProxy, objects);
59 
60  reportFields::print(" surfVector :", Info, sVectors);
62  }
63  else
64  {
65  sVectors.resize(nSurfaceVectorField); // Consistent sizing
66  }
67 
68  if (sScalars.size())
69  {
70  // Change scalar fields into vector fields, but leave
71  // the count of vector fields unchanged. This allows us to
72  // easily delete these synthetic fields later.
73 
74  surfaceVectorField unitNorm(mesh.Sf()/mesh.magSf());
75 
77 
78  label nExtra = 0;
79  for (const auto& ssf : sScalars)
80  {
81  surfaceVectorField* tsvfPtr = (ssf * unitNorm).ptr();
82  tsvfPtr->rename(ssf.name());
83  sVectors.set(nSurfaceVectorField + nExtra, tsvfPtr);
84  ++nExtra;
85  }
86  }
87 
88  if (sVectors.size())
89  {
90  vtk::surfaceFieldWriter writer
91  (
92  meshProxy.mesh(),
93  writeOpts,
94  (
95  outputDir/regionDir
96  / "surface-fields"/"surfaceFields" + timeDesc
97  ),
98  Pstream::parRun()
99  );
100 
101  Info<< " Surface : "
102  << args.relativePath(writer.output()) << nl;
103 
104 
105  writer.writeTimeValue(timeValue);
106  writer.writeGeometry();
107 
108  writer.beginPointData(sVectors.size());
109 
110  for (const auto& fld : sVectors)
111  {
112  writer.write(fld);
113  }
114 
115  fileName outputName(writer.output());
116 
117  writer.close();
118 
119  if (Pstream::master())
120  {
121  // Add to file-series and emit as JSON
122 
123  fileName seriesName(vtk::seriesWriter::base(outputName));
124 
125  vtk::seriesWriter& series = vtkSeries(seriesName);
126 
127  // First time?
128  // Load from file, verify against filesystem,
129  // prune time >= currentTime
130  if (series.empty())
131  {
132  series.load(seriesName, true, timeValue);
133  }
134 
135  series.append(timeValue, outputName);
136  series.write(seriesName);
137  }
138  }
139  }
140 
141 
142  // Write faceZones (POLYDATA file, one for each zone)
143 
144  if (!selectedFaceZones.empty() && !mesh.faceZones().empty())
145  {
146  if (nSurfaceScalarField == -1)
147  {
148  sScalars = readFields<surfaceScalarField>(meshProxy, objects);
149  nSurfaceScalarField = sScalars.size();
150 
151  reportFields::print(" surfScalar :", Info, sScalars);
152  }
153  else
154  {
155  sScalars.resize(nSurfaceScalarField); // Consistent sizing
156  }
157 
158  if (nSurfaceVectorField == -1)
159  {
160  sVectors = readFields<surfaceVectorField>(meshProxy, objects);
161  nSurfaceVectorField = sVectors.size();
162 
163  reportFields::print(" surfVector :", Info, sVectors);
164  }
165  else
166  {
167  sVectors.resize(nSurfaceVectorField); // Consistent sizing
168  }
169 
170  for (const faceZone& fz : mesh.faceZones())
171  {
172  if (!selectedFaceZones.match(fz.name()))
173  {
174  continue;
175  }
176 
177  // Retrieve as primitiveFacePatch with faces properly flipped
178  const primitiveFacePatch& pp = fz();
179 
181  (
182  pp,
183  writeOpts,
184  (
185  outputDir/regionDir/fz.name()
186  / (meshProxy.useSubMesh() ? meshProxy.name() : fz.name())
187  + timeDesc
188  ),
189  Pstream::parRun()
190  );
191 
192  Info<< " FaceZone : "
193  << args.relativePath(writer.output()) << nl;
194 
195 
196  writer.beginFile(fz.name());
197  writer.writeTimeValue(timeValue);
198  writer.writeGeometry();
199 
200  writer.beginCellData(sScalars.size() + sVectors.size());
201 
202  for (const auto& fld : sScalars)
203  {
204  writer.write(fld, fz.addressing());
205  }
206  for (const auto& fld : sVectors)
207  {
208  writer.write(fld, fz.addressing());
209  }
210 
211  fileName outputName(writer.output());
212 
213  writer.close();
214 
215  if (Pstream::master())
216  {
217  // Add to file-series and emit as JSON
218 
219  fileName seriesName(vtk::seriesWriter::base(outputName));
220 
221  vtk::seriesWriter& series = vtkSeries(seriesName);
222 
223  // First time?
224  // Load from file, verify against filesystem,
225  // prune time >= currentTime
226  if (series.empty())
227  {
228  series.load(seriesName, true, timeValue);
229  }
230 
231  series.append(timeValue, outputName);
232  series.write(seriesName);
233  }
234  }
235  }
236 }
237 
238 
239 // ************************************************************************* //
Ostream & print(Ostream &os, UIntType value, char off='0', char on='1')
Print 0/1 bits in the (unsigned) integral type.
Definition: BitOps.H:289
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
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
vtk::internalMeshWriter writer(topoMesh, topoCells, vtk::formatType::INLINE_ASCII, runTime.path()/"blockTopology")
virtual void rename(const word &newName)
Rename.
Definition: regIOobject.C:413
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)