convertVolumeFields.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-2020 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 converting volume and dimensioned fields
28  included by foamToVTK.
29 
30 \*---------------------------------------------------------------------------*/
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 {
35  using reportFields = foamToVtkReportFields;
36 
37  const label nVolFields =
38  (
39  (doInternal || doBoundary)
40  ? objects.count(stringListOps::foundOp<word>(fieldTypes::volume))
41  : 0
42  );
43 
44  const label nDimFields =
45  (
46  (doInternal || doBoundary)
47  ? objects.count(stringListOps::foundOp<word>(fieldTypes::internal))
48  : 0
49  );
50 
51  const label nPointFields =
52  (
53  doPointValues
54  ? objects.count(stringListOps::foundOp<word>(fieldTypes::point))
55  : 0
56  );
57 
58 
59  reportFields::volume(Info, objects);
60  reportFields::internal(Info, objects);
61 
62 
63  // Setup for the vtm writer.
64  // For legacy format, the information added is simply ignored.
65 
66  fileName vtmOutputBase
67  (
68  outputDir/regionPrefix/vtkName + timeDesc
69  );
70 
71  // Combined internal + boundary in a vtm file
73 
74  // Collect individual boundaries into a vtm file
76 
77  // Setup the internal writer
78  autoPtr<vtk::internalWriter> internalWriter;
79 
80  // Interpolator for volume and dimensioned fields
81  autoPtr<volPointInterpolation> pInterp;
82 
83  if (doInternal)
84  {
85  if (doPointValues)
86  {
87  pInterp.reset(new volPointInterpolation(mesh));
88  }
89 
90  if (vtuMeshCells.empty())
91  {
92  // Use the appropriate mesh (baseMesh or subMesh)
93  vtuMeshCells.reset(meshProxy.mesh());
94  }
95 
97  (
98  meshProxy.mesh(),
99  vtuMeshCells,
100  writeOpts,
101  // The output base name for internal
102  (
103  writeOpts.legacy()
104  ? vtmOutputBase
105  : (vtmOutputBase / "internal")
106  ),
107  Pstream::parRun()
108  );
109 
110  // No sub-block for internal
111  vtmWriter.append_vtu
112  (
113  "internal",
114  vtmOutputBase.name()/"internal"
115  );
116 
117  Info<< " Internal : "
118  << args.relativePath(internalWriter->output()) << nl;
119 
120  internalWriter->writeTimeValue(mesh.time().value());
121  internalWriter->writeGeometry();
122  }
123 
124 
125  // Setup the patch writers
126 
127  const polyBoundaryMesh& patches = mesh.boundaryMesh();
128 
129  PtrList<vtk::patchWriter> patchWriters;
130  PtrList<PrimitivePatchInterpolation<primitivePatch>> patchInterps;
131 
133  if (doBoundary)
134  {
135  patchIds = getSelectedPatches(patches, includePatches, excludePatches);
136  }
137 
138  if (oneBoundary && patchIds.size())
139  {
141  (
142  meshProxy.mesh(),
143  patchIds,
144  writeOpts,
145  nearCellValue,
146  // Output one patch: "boundary"
147  (
148  writeOpts.legacy()
149  ?
150  (
151  outputDir/regionPrefix/"boundary"
152  / (meshProxy.useSubMesh() ? meshProxy.name() : "boundary")
153  + timeDesc
154  )
155  : (vtmOutputBase / "boundary")
156  ),
157  Pstream::parRun()
158  );
159 
160  // No sub-block for one-patch
161  vtmWriter.append_vtp
162  (
163  "boundary",
164  vtmOutputBase.name()/"boundary"
165  );
166 
167  Info<< " Boundaries: "
168  << args.relativePath(writer->output()) << nl;
169 
170  writer->writeTimeValue(timeValue);
171  writer->writeGeometry();
172 
173  // Transfer writer to list for later use
174  patchWriters.resize(1);
175  patchWriters.set(0, writer);
176 
177  // Avoid patchInterpolation for each sub-patch
178  patchInterps.resize(1); // == nullptr
179  }
180  else if (patchIds.size())
181  {
182  patchWriters.resize(patchIds.size());
183  if (doPointValues)
184  {
185  patchInterps.resize(patchIds.size());
186  }
187 
188  label nPatchWriters = 0;
189  label nPatchInterps = 0;
190 
191  for (const label patchId : patchIds)
192  {
193  const polyPatch& pp = patches[patchId];
194 
196  (
197  meshProxy.mesh(),
198  labelList(one{}, pp.index()),
199  writeOpts,
200  nearCellValue,
201  // Output patch: "boundary"/name
202  (
203  writeOpts.legacy()
204  ?
205  (
206  outputDir/regionPrefix/pp.name()
207  / (meshProxy.useSubMesh() ? meshProxy.name() : pp.name())
208  + timeDesc
209  )
210  : (vtmOutputBase / "boundary" / pp.name())
211  ),
212  Pstream::parRun()
213  );
214 
215  if (!nPatchWriters)
216  {
217  vtmWriter.beginBlock("boundary");
218  vtmBoundaries.beginBlock("boundary");
219  }
220 
221  vtmWriter.append_vtp
222  (
223  pp.name(),
224  vtmOutputBase.name()/"boundary"/pp.name()
225  );
226 
227  vtmBoundaries.append_vtp
228  (
229  pp.name(),
230  "boundary"/pp.name()
231  );
232 
233  Info<< " Boundary : "
234  << args.relativePath(writer->output()) << nl;
235 
236  writer->writeTimeValue(timeValue);
237  writer->writeGeometry();
238 
239  // Transfer writer to list for later use
241 
242  if (patchInterps.size())
243  {
244  patchInterps.set
245  (
246  nPatchInterps++,
247  new PrimitivePatchInterpolation<primitivePatch>(pp)
248  );
249  }
250  }
251 
252  if (nPatchWriters)
253  {
254  vtmWriter.endBlock("boundary");
255  }
256 
257  patchWriters.resize(nPatchWriters);
258  patchInterps.resize(nPatchInterps);
259  }
260 
261 
262  // CellData
263  {
264  // Begin CellData
265  if (internalWriter)
266  {
267  // Optionally with cellID and procID fields
268  internalWriter->beginCellData
269  (
270  (withMeshIds ? 1 + (internalWriter->parallel() ? 1 : 0) : 0)
272  );
273 
274  if (withMeshIds)
275  {
276  internalWriter->writeCellIDs();
277  internalWriter->writeProcIDs(); // parallel only
278  }
279  }
280 
281  if (nVolFields)
282  {
283  for (vtk::patchWriter& writer : patchWriters)
284  {
285  // Optionally with patchID field
286  writer.beginCellData
287  (
288  (withMeshIds ? 1 : 0)
289  + nVolFields
290  );
291 
292  if (withMeshIds)
293  {
294  writer.writePatchIDs();
295  }
296  }
297  }
298 
300  (
302  patchWriters,
303  meshProxy,
304  objects,
305  true // syncPar
306  );
307 
309  (
311  meshProxy,
312  objects,
313  true // syncPar
314  );
315 
316  // End CellData is implicit
317  }
318 
319 
320  // PointData
321  // - only construct pointMesh on request since it constructs
322  // edge addressing
323  if (doPointValues)
324  {
325  // Begin PointData
326  if (internalWriter)
327  {
328  internalWriter->beginPointData
329  (
331  + (withPointIds ? 1 : 0)
332  );
333 
334  if (withPointIds)
335  {
336  internalWriter->writePointIDs();
337  }
338  }
339 
340  forAll(patchWriters, writeri)
341  {
342  const label nPatchFields =
343  (
344  (
345  writeri < patchInterps.size() && patchInterps.set(writeri)
346  ? nVolFields
347  : 0
348  )
349  + nPointFields
350  );
351 
352  if (nPatchFields)
353  {
354  patchWriters[writeri].beginPointData(nPatchFields);
355  }
356  }
357 
359  (
362  meshProxy,
363  objects,
364  true // syncPar
365  );
366 
368  (
370  meshProxy,
371  objects,
372  true // syncPar
373  );
374 
376  (
378  patchWriters,
379  meshProxy,
380  objects,
381  true // syncPar
382  );
383 
384  // End PointData is implicit
385  }
386 
387 
388  // Finish writers
390  {
391  internalWriter->close();
392  }
393 
394  for (vtk::patchWriter& writer : patchWriters)
395  {
396  writer.close();
397  }
398 
399  pInterp.clear();
400  patchWriters.clear();
401  patchInterps.clear();
402 
403 
404  // Collective output
405 
406  if (Pstream::master())
407  {
408  // Naming for vtm, file series etc.
409  fileName outputName(vtmOutputBase);
410 
411  if (writeOpts.legacy())
412  {
413  if (doInternal)
414  {
415  // Add to file-series and emit as JSON
416 
417  outputName.ext(vtk::legacy::fileExtension);
418 
419  fileName seriesName(vtk::seriesWriter::base(outputName));
420 
421  vtk::seriesWriter& series = vtkSeries(seriesName);
422 
423  // First time?
424  // Load from file, verify against filesystem,
425  // prune time >= currentTime
426  if (series.empty())
427  {
428  series.load(seriesName, true, timeValue);
429  }
430 
431  series.append(timeValue, timeDesc);
432  series.write(seriesName);
433  }
434  }
435  else
436  {
437  if (vtmWriter.size())
438  {
439  // Emit ".vtm"
440 
441  outputName.ext(vtmWriter.ext());
442 
443  fileName seriesName(vtk::seriesWriter::base(outputName));
444 
445  vtmWriter.setTime(timeValue);
446  vtmWriter.write(outputName);
447 
448  // Add to file-series and emit as JSON
449 
450  vtk::seriesWriter& series = vtkSeries(seriesName);
451 
452  // First time?
453  // Load from file, verify against filesystem,
454  // prune time >= currentTime
455  if (series.empty())
456  {
457  series.load(seriesName, true, timeValue);
458  }
459 
460  series.append(timeValue, outputName);
461  series.write(seriesName);
462 
463  // Add to multi-region vtm
464  vtmMultiRegion.add(regionName, regionPrefix, vtmWriter);
465  }
466 
467  if (vtmBoundaries.size())
468  {
469  // Emit "boundary.vtm" with collection of boundaries
470 
471  // Naming for vtm
472  fileName outputName(vtmOutputBase / "boundary");
473  outputName.ext(vtmBoundaries.ext());
474 
475  vtmBoundaries.setTime(timeValue);
476  vtmBoundaries.write(outputName);
477  }
478  }
479  }
480 }
481 
482 
483 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
vtmWriter
vtk::vtmWriter vtmWriter
Definition: convertVolumeFields.H:72
writeAllDimFields
writeAllDimFields(ensCase, ensMesh, objects)
Foam::vtk::fileExtension
const Foam::Enum< fileTag > fileExtension
File extension (without ".") for some vtk XML file content types.
patchIds
labelList patchIds
Definition: convertVolumeFields.H:132
vtmOutputBase
fileName vtmOutputBase(outputDir/regionPrefix/vtkName+timeDesc)
vtmBoundaries
vtk::vtmWriter vtmBoundaries
Definition: convertVolumeFields.H:75
Foam::fieldTypes::volume
const wordList volume
Standard volume field types (scalar, vector, tensor, etc)
Foam::fieldTypes::internal
const wordList internal
Standard dimensioned field types (scalar, vector, tensor, etc)
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
writeAllVolFields
writeAllVolFields(ensCase, ensMesh, objects, nearCellValue)
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
writer
vtk::internalMeshWriter writer(topoMesh, topoCells, writeOpts, runTime.path()/"blockTopology")
patches
const polyBoundaryMesh & patches
Definition: convertVolumeFields.H:127
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
internalWriter
autoPtr< vtk::internalWriter > internalWriter
Definition: convertVolumeFields.H:78
nDimFields
const label nDimFields
Definition: convertVolumeFields.H:44
nPointFields
const label nPointFields
Definition: convertVolumeFields.H:51
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
nPatchWriters
label nPatchWriters
Definition: convertProcessorPatches.H:85
Foam::nl
constexpr char nl
Definition: Ostream.H:385
patchWriters
PtrList< vtk::patchWriter > patchWriters
Definition: convertVolumeFields.H:129
patchId
label patchId(-1)
Foam::point
vector point
Point is a vector.
Definition: point.H:43
args
Foam::argList args(argc, argv)
patchInterps
PtrList< PrimitivePatchInterpolation< primitivePatch > > patchInterps
Definition: convertVolumeFields.H:130
Foam::argList::relativePath
fileName relativePath(const fileName &input, const bool caseTag=false) const
Definition: argListI.H:94
pInterp
autoPtr< volPointInterpolation > pInterp
Definition: convertVolumeFields.H:81
Foam::writeAllPointFields
label writeAllPointFields(ensightCase &ensCase, const ensightMesh &ensMesh, const IOobjectList &objects)
Definition: writePointFields.H:115
nVolFields
const label nVolFields
Definition: convertVolumeFields.H:37