foamToVTK.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Application
25  foamToVTK
26 
27 Description
28  Legacy VTK file format writer.
29 
30  - handles volScalar, volVector, pointScalar, pointVector, surfaceScalar
31  fields.
32  - mesh topo changes.
33  - both ascii and binary.
34  - single time step writing.
35  - write subset only.
36  - automatic decomposition of cells; polygons on boundary undecomposed since
37  handled by vtk.
38 
39 Usage
40 
41  - foamToVTK [OPTION]
42 
43  \param -ascii \n
44  Write VTK data in ASCII format instead of binary.
45 
46  \param -mesh <name>\n
47  Use a different mesh name (instead of -region)
48 
49  \param -fields <fields>\n
50  Convert selected fields only. For example,
51  \verbatim
52  -fields "( p T U )"
53  \endverbatim
54  The quoting is required to avoid shell expansions and to pass the
55  information as a single argument.
56 
57  \param -surfaceFields \n
58  Write surfaceScalarFields (e.g., phi)
59 
60  \param -cellSet <name>\n
61  \param -faceSet <name>\n
62  \param -pointSet <name>\n
63  Restrict conversion to the cellSet, faceSet or pointSet.
64 
65  \param -nearCellValue \n
66  Output cell value on patches instead of patch value itself
67 
68  \param -noInternal \n
69  Do not generate file for mesh, only for patches
70 
71  \param -noPointValues \n
72  No pointFields
73 
74  \param -noFaceZones \n
75  No faceZones
76 
77  \param -noLinks \n
78  (in parallel) do not link processor files to master
79 
80  \param poly \n
81  write polyhedral cells without tet/pyramid decomposition
82 
83  \param -allPatches \n
84  Combine all patches into a single file
85 
86  \param -excludePatches <patchNames>\n
87  Specify patches (wildcards) to exclude. For example,
88  \verbatim
89  -excludePatches '( inlet_1 inlet_2 "proc.*")'
90  \endverbatim
91  The quoting is required to avoid shell expansions and to pass the
92  information as a single argument. The double quotes denote a regular
93  expression.
94 
95  \param -useTimeName \n
96  use the time index in the VTK file name instead of the time index
97 
98 Note
99  mesh subset is handled by vtkMesh. Slight inconsistency in
100  interpolation: on the internal field it interpolates the whole volField
101  to the whole-mesh pointField and then selects only those values it
102  needs for the subMesh (using the fvMeshSubset cellMap(), pointMap()
103  functions). For the patches however it uses the
104  fvMeshSubset.interpolate function to directly interpolate the
105  whole-mesh values onto the subset patch.
106 
107 Note
108  new file format: \n
109  no automatic timestep recognition.
110  However can have .pvd file format which refers to time simulation
111  if XML *.vtu files are available:
112 
113  \verbatim
114  <?xml version="1.0"?>
115  <VTKFile type="Collection"
116  version="0.1"
117  byte_order="LittleEndian"
118  compressor="vtkZLibDataCompressor">
119  <Collection>
120  <DataSet timestep="50" file="pitzDaily_2.vtu"/>
121  <DataSet timestep="100" file="pitzDaily_3.vtu"/>
122  <DataSet timestep="150" file="pitzDaily_4.vtu"/>
123  <DataSet timestep="200" file="pitzDaily_5.vtu"/>
124  <DataSet timestep="250" file="pitzDaily_6.vtu"/>
125  <DataSet timestep="300" file="pitzDaily_7.vtu"/>
126  <DataSet timestep="350" file="pitzDaily_8.vtu"/>
127  <DataSet timestep="400" file="pitzDaily_9.vtu"/>
128  <DataSet timestep="450" file="pitzDaily_10.vtu"/>
129  <DataSet timestep="500" file="pitzDaily_11.vtu"/>
130  </Collection>
131  </VTKFile>
132  \endverbatim
133 
134 \*---------------------------------------------------------------------------*/
135 
136 #include "fvCFD.H"
137 #include "pointMesh.H"
138 #include "volPointInterpolation.H"
139 #include "emptyPolyPatch.H"
140 #include "labelIOField.H"
141 #include "scalarIOField.H"
142 #include "sphericalTensorIOField.H"
143 #include "symmTensorIOField.H"
144 #include "tensorIOField.H"
145 #include "faceZoneMesh.H"
146 #include "Cloud.H"
147 #include "passiveParticle.H"
148 #include "stringListOps.H"
149 
150 #include "vtkMesh.H"
151 #include "readFields.H"
152 #include "writeFuns.H"
153 
154 #include "internalWriter.H"
155 #include "patchWriter.H"
156 #include "lagrangianWriter.H"
157 
158 #include "writeFaceSet.H"
159 #include "writePointSet.H"
160 #include "surfaceMeshWriter.H"
161 #include "writeSurfFields.H"
162 
163 
164 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
165 
166 template<class GeoField>
167 void print(const char* msg, Ostream& os, const PtrList<GeoField>& flds)
168 {
169  if (flds.size())
170  {
171  os << msg;
172  forAll(flds, i)
173  {
174  os << ' ' << flds[i].name();
175  }
176  os << endl;
177  }
178 }
179 
180 
181 void print(Ostream& os, const wordList& flds)
182 {
183  forAll(flds, i)
184  {
185  os << ' ' << flds[i];
186  }
187  os << endl;
188 }
189 
190 
192 (
193  const polyBoundaryMesh& patches,
194  const List<wordRe>& excludePatches //HashSet<word>& excludePatches
195 )
196 {
197  DynamicList<label> patchIDs(patches.size());
198 
199  Info<< "Combining patches:" << endl;
200 
201  forAll(patches, patchI)
202  {
203  const polyPatch& pp = patches[patchI];
204 
205  if
206  (
207  isType<emptyPolyPatch>(pp)
208  || (Pstream::parRun() && isType<processorPolyPatch>(pp))
209  )
210  {
211  Info<< " discarding empty/processor patch " << patchI
212  << " " << pp.name() << endl;
213  }
214  else if (findStrings(excludePatches, pp.name()))
215  {
216  Info<< " excluding patch " << patchI
217  << " " << pp.name() << endl;
218  }
219  else
220  {
221  patchIDs.append(patchI);
222  Info<< " patch " << patchI << " " << pp.name() << endl;
223  }
224  }
225  return patchIDs.shrink();
226 }
227 
228 
229 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
230 
231 int main(int argc, char *argv[])
232 {
233  argList::addNote
234  (
235  "legacy VTK file format writer"
236  );
237  timeSelector::addOptions();
238 
239  #include "addRegionOption.H"
240  argList::addOption
241  (
242  "fields",
243  "wordList",
244  "only convert the specified fields - eg '(p T U)'"
245  );
246  argList::addOption
247  (
248  "cellSet",
249  "name",
250  "convert a mesh subset corresponding to the specified cellSet"
251  );
252  argList::addOption
253  (
254  "faceSet",
255  "name",
256  "restrict conversion to the specified faceSet"
257  );
258  argList::addOption
259  (
260  "pointSet",
261  "name",
262  "restrict conversion to the specified pointSet"
263  );
264  argList::addBoolOption
265  (
266  "ascii",
267  "write in ASCII format instead of binary"
268  );
269  argList::addBoolOption
270  (
271  "poly",
272  "write polyhedral cells without tet/pyramid decomposition"
273  );
274  argList::addBoolOption
275  (
276  "surfaceFields",
277  "write surfaceScalarFields (e.g., phi)"
278  );
279  argList::addBoolOption
280  (
281  "nearCellValue",
282  "use cell value on patches instead of patch value itself"
283  );
284  argList::addBoolOption
285  (
286  "noInternal",
287  "do not generate file for mesh, only for patches"
288  );
289  argList::addBoolOption
290  (
291  "noPointValues",
292  "no pointFields"
293  );
294  argList::addBoolOption
295  (
296  "allPatches",
297  "combine all patches into a single file"
298  );
299  argList::addOption
300  (
301  "excludePatches",
302  "wordReList",
303  "a list of patches to exclude - eg '( inlet \".*Wall\" )' "
304  );
305  argList::addBoolOption
306  (
307  "noFaceZones",
308  "no faceZones"
309  );
310  argList::addBoolOption
311  (
312  "noLinks",
313  "don't link processor VTK files - parallel only"
314  );
315  argList::addBoolOption
316  (
317  "useTimeName",
318  "use the time name instead of the time index when naming the files"
319  );
320 
321  #include "setRootCase.H"
322  #include "createTime.H"
323 
324  const bool doWriteInternal = !args.optionFound("noInternal");
325  const bool doFaceZones = !args.optionFound("noFaceZones");
326  const bool doLinks = !args.optionFound("noLinks");
327  const bool binary = !args.optionFound("ascii");
328  const bool useTimeName = args.optionFound("useTimeName");
329 
330  // decomposition of polyhedral cells into tets/pyramids cells
331  vtkTopo::decomposePoly = !args.optionFound("poly");
332 
333  if (binary && (sizeof(floatScalar) != 4 || sizeof(label) != 4))
334  {
336  << "floatScalar and/or label are not 4 bytes in size" << nl
337  << "Hence cannot use binary VTK format. Please use -ascii"
338  << exit(FatalError);
339  }
340 
341  const bool nearCellValue = args.optionFound("nearCellValue");
342 
343  if (nearCellValue)
344  {
346  << "Using neighbouring cell value instead of patch value"
347  << nl << endl;
348  }
349 
350  const bool noPointValues = args.optionFound("noPointValues");
351 
352  if (noPointValues)
353  {
355  << "Outputting cell values only" << nl << endl;
356  }
357 
358  const bool allPatches = args.optionFound("allPatches");
359 
360  List<wordRe> excludePatches;
361  if (args.optionFound("excludePatches"))
362  {
363  args.optionLookup("excludePatches")() >> excludePatches;
364 
365  Info<< "Not including patches " << excludePatches << nl << endl;
366  }
367 
368  word cellSetName;
369  word faceSetName;
370  word pointSetName;
371  string vtkName = runTime.caseName();
372 
373  if (args.optionReadIfPresent("cellSet", cellSetName))
374  {
375  vtkName = cellSetName;
376  }
377  else if (Pstream::parRun())
378  {
379  // Strip off leading casename, leaving just processor_DDD ending.
380  string::size_type i = vtkName.rfind("processor");
381 
382  if (i != string::npos)
383  {
384  vtkName = vtkName.substr(i);
385  }
386  }
387  args.optionReadIfPresent("faceSet", faceSetName);
388  args.optionReadIfPresent("pointSet", pointSetName);
389 
390 
391 
392  instantList timeDirs = timeSelector::select0(runTime, args);
393 
394  #include "createNamedMesh.H"
395 
396  // VTK/ directory in the case
397  fileName fvPath(runTime.path()/"VTK");
398  // Directory of mesh (region0 gets filtered out)
399  fileName regionPrefix = "";
400 
401  if (regionName != polyMesh::defaultRegion)
402  {
403  fvPath = fvPath/regionName;
404  regionPrefix = regionName;
405  }
406 
407  if (isDir(fvPath))
408  {
409  if
410  (
411  args.optionFound("time")
412  || args.optionFound("latestTime")
413  || cellSetName.size()
414  || faceSetName.size()
415  || pointSetName.size()
416  || regionName != polyMesh::defaultRegion
417  )
418  {
419  Info<< "Keeping old VTK files in " << fvPath << nl << endl;
420  }
421  else
422  {
423  Info<< "Deleting old VTK files in " << fvPath << nl << endl;
424 
425  rmDir(fvPath);
426  }
427  }
428 
429  mkDir(fvPath);
430 
431 
432  // Mesh wrapper; does subsetting and decomposition
433  vtkMesh vMesh(mesh, cellSetName);
434 
435 
436  // Scan for all possible lagrangian clouds
437  HashSet<fileName> allCloudDirs;
438  forAll(timeDirs, timeI)
439  {
440  runTime.setTime(timeDirs[timeI], timeI);
441  fileNameList cloudDirs
442  (
443  readDir
444  (
445  runTime.timePath()/regionPrefix/cloud::prefix,
446  fileName::DIRECTORY
447  )
448  );
449  forAll(cloudDirs, i)
450  {
451  IOobjectList sprayObjs
452  (
453  mesh,
454  runTime.timeName(),
455  cloud::prefix/cloudDirs[i]
456  );
457 
458  IOobject* positionsPtr = sprayObjs.lookup(word("positions"));
459 
460  if (positionsPtr)
461  {
462  if (allCloudDirs.insert(cloudDirs[i]))
463  {
464  Info<< "At time: " << runTime.timeName()
465  << " detected cloud directory : " << cloudDirs[i]
466  << endl;
467  }
468  }
469  }
470  }
471 
472 
473  forAll(timeDirs, timeI)
474  {
475  runTime.setTime(timeDirs[timeI], timeI);
476 
477  Info<< "Time: " << runTime.timeName() << endl;
478 
479  word timeDesc =
480  useTimeName ? runTime.timeName() : Foam::name(runTime.timeIndex());
481 
482  // Check for new polyMesh/ and update mesh, fvMeshSubset and cell
483  // decomposition.
484  polyMesh::readUpdateState meshState = vMesh.readUpdate();
485 
486  const fvMesh& mesh = vMesh.mesh();
487 
488  if
489  (
490  meshState == polyMesh::TOPO_CHANGE
491  || meshState == polyMesh::TOPO_PATCH_CHANGE
492  )
493  {
494  Info<< " Read new mesh" << nl << endl;
495  }
496 
497 
498  // If faceSet: write faceSet only (as polydata)
499  if (faceSetName.size())
500  {
501  // Load the faceSet
502  faceSet set(mesh, faceSetName);
503 
504  // Filename as if patch with same name.
505  mkDir(fvPath/set.name());
506 
507  fileName patchFileName
508  (
509  fvPath/set.name()/set.name()
510  + "_"
511  + timeDesc
512  + ".vtk"
513  );
514 
515  Info<< " FaceSet : " << patchFileName << endl;
516 
517  writeFaceSet(binary, vMesh, set, patchFileName);
518 
519  continue;
520  }
521  // If pointSet: write pointSet only (as polydata)
522  if (pointSetName.size())
523  {
524  // Load the pointSet
525  pointSet set(mesh, pointSetName);
526 
527  // Filename as if patch with same name.
528  mkDir(fvPath/set.name());
529 
530  fileName patchFileName
531  (
532  fvPath/set.name()/set.name()
533  + "_"
534  + timeDesc
535  + ".vtk"
536  );
537 
538  Info<< " pointSet : " << patchFileName << endl;
539 
540  writePointSet(binary, vMesh, set, patchFileName);
541 
542  continue;
543  }
544 
545 
546  // Search for list of objects for this time
547  IOobjectList objects(mesh, runTime.timeName());
548 
549  HashSet<word> selectedFields;
550  bool specifiedFields = args.optionReadIfPresent
551  (
552  "fields",
553  selectedFields
554  );
555 
556  // Construct the vol fields (on the original mesh if subsetted)
557 
558  PtrList<volScalarField> vsf;
559  PtrList<volVectorField> vvf;
560  PtrList<volSphericalTensorField> vSpheretf;
561  PtrList<volSymmTensorField> vSymmtf;
562  PtrList<volTensorField> vtf;
563 
564  if (!specifiedFields || selectedFields.size())
565  {
566  readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vsf);
567  print(" volScalarFields :", Info, vsf);
568 
569  readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vvf);
570  print(" volVectorFields :", Info, vvf);
571 
572  readFields
573  (
574  vMesh,
575  vMesh.baseMesh(),
576  objects,
577  selectedFields,
578  vSpheretf
579  );
580  print(" volSphericalTensorFields :", Info, vSpheretf);
581 
582  readFields
583  (
584  vMesh,
585  vMesh.baseMesh(),
586  objects,
587  selectedFields,
588  vSymmtf
589  );
590  print(" volSymmTensorFields :", Info, vSymmtf);
591 
592  readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vtf);
593  print(" volTensorFields :", Info, vtf);
594  }
595 
596  label nVolFields =
597  vsf.size()
598  + vvf.size()
599  + vSpheretf.size()
600  + vSymmtf.size()
601  + vtf.size();
602 
603 
604  // Construct dimensioned fields
605  PtrList<volScalarField::DimensionedInternalField> dsf;
606  PtrList<volVectorField::DimensionedInternalField> dvf;
607  PtrList<volSphericalTensorField::DimensionedInternalField> dSpheretf;
608  PtrList<volSymmTensorField::DimensionedInternalField> dSymmtf;
609  PtrList<volTensorField::DimensionedInternalField> dtf;
610 
611  if (!specifiedFields || selectedFields.size())
612  {
613  readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dsf);
614  print(" volScalarFields::Internal :", Info, dsf);
615 
616  readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dvf);
617  print(" volVectorFields::Internal :", Info, dvf);
618 
619  readFields
620  (
621  vMesh,
622  vMesh.baseMesh(),
623  objects,
624  selectedFields,
625  dSpheretf
626  );
627  print(" volSphericalTensorFields::Internal :", Info, dSpheretf);
628 
629  readFields
630  (
631  vMesh,
632  vMesh.baseMesh(),
633  objects,
634  selectedFields,
635  dSymmtf
636  );
637  print(" volSymmTensorFields::Internal :", Info, dSymmtf);
638 
639  readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dtf);
640  print(" volTensorFields::Internal :", Info, dtf);
641  }
642 
643  label nDimFields =
644  dsf.size()
645  + dvf.size()
646  + dSpheretf.size()
647  + dSymmtf.size()
648  + dtf.size();
649 
650 
651  // Construct pointMesh only if nessecary since constructs edge
652  // addressing (expensive on polyhedral meshes)
653  if (noPointValues)
654  {
655  Info<< " pointScalarFields : switched off"
656  << " (\"-noPointValues\" (at your option)\n";
657  Info<< " pointVectorFields : switched off"
658  << " (\"-noPointValues\" (at your option)\n";
659  }
660 
661  PtrList<pointScalarField> psf;
662  PtrList<pointVectorField> pvf;
663  PtrList<pointSphericalTensorField> pSpheretf;
664  PtrList<pointSymmTensorField> pSymmtf;
665  PtrList<pointTensorField> ptf;
666 
667  if (!noPointValues && !(specifiedFields && selectedFields.empty()))
668  {
669  readFields
670  (
671  vMesh,
672  pointMesh::New(vMesh.baseMesh()),
673  objects,
674  selectedFields,
675  psf
676  );
677  print(" pointScalarFields :", Info, psf);
678 
679  readFields
680  (
681  vMesh,
682  pointMesh::New(vMesh.baseMesh()),
683  objects,
684  selectedFields,
685  pvf
686  );
687  print(" pointVectorFields :", Info, pvf);
688 
689  readFields
690  (
691  vMesh,
692  pointMesh::New(vMesh.baseMesh()),
693  objects,
694  selectedFields,
695  pSpheretf
696  );
697  print(" pointSphericalTensorFields :", Info, pSpheretf);
698 
699  readFields
700  (
701  vMesh,
702  pointMesh::New(vMesh.baseMesh()),
703  objects,
704  selectedFields,
705  pSymmtf
706  );
707  print(" pointSymmTensorFields :", Info, pSymmtf);
708 
709  readFields
710  (
711  vMesh,
712  pointMesh::New(vMesh.baseMesh()),
713  objects,
714  selectedFields,
715  ptf
716  );
717  print(" pointTensorFields :", Info, ptf);
718  }
719  Info<< endl;
720 
721  label nPointFields =
722  psf.size()
723  + pvf.size()
724  + pSpheretf.size()
725  + pSymmtf.size()
726  + ptf.size();
727 
728  if (doWriteInternal)
729  {
730  //
731  // Create file and write header
732  //
733  fileName vtkFileName
734  (
735  fvPath/vtkName
736  + "_"
737  + timeDesc
738  + ".vtk"
739  );
740 
741  Info<< " Internal : " << vtkFileName << endl;
742 
743  // Write mesh
744  internalWriter writer(vMesh, binary, vtkFileName);
745 
746  // VolFields + cellID
747  writeFuns::writeCellDataHeader
748  (
749  writer.os(),
750  vMesh.nFieldCells(),
751  1 + nVolFields + nDimFields
752  );
753 
754  // Write cellID field
755  writer.writeCellIDs();
756 
757  // Write volFields
758  writer.write(vsf);
759  writer.write(vvf);
760  writer.write(vSpheretf);
761  writer.write(vSymmtf);
762  writer.write(vtf);
763 
764  // Write dimensionedFields
765  writer.write<scalar, volMesh>(dsf);
766  writer.write<vector, volMesh>(dvf);
767  writer.write<sphericalTensor, volMesh>(dSpheretf);
768  writer.write<symmTensor, volMesh>(dSymmtf);
769  writer.write<tensor, volMesh>(dtf);
770 
771  if (!noPointValues)
772  {
773  writeFuns::writePointDataHeader
774  (
775  writer.os(),
776  vMesh.nFieldPoints(),
777  nVolFields + nDimFields + nPointFields
778  );
779 
780  // pointFields
781  writer.write(psf);
782  writer.write(pvf);
783  writer.write(pSpheretf);
784  writer.write(pSymmtf);
785  writer.write(ptf);
786 
787  // Interpolated volFields
788  volPointInterpolation pInterp(mesh);
789  writer.write(pInterp, vsf);
790  writer.write(pInterp, vvf);
791  writer.write(pInterp, vSpheretf);
792  writer.write(pInterp, vSymmtf);
793  writer.write(pInterp, vtf);
794 
795  writer.write<scalar, volMesh>(pInterp, dsf);
796  writer.write<vector, volMesh>(pInterp, dvf);
797  writer.write<sphericalTensor, volMesh>(pInterp, dSpheretf);
798  writer.write<symmTensor, volMesh>(pInterp, dSymmtf);
799  writer.write<tensor, volMesh>(pInterp, dtf);
800  }
801  }
802 
803  //---------------------------------------------------------------------
804  //
805  // Write surface fields
806  //
807  //---------------------------------------------------------------------
808 
809  if (args.optionFound("surfaceFields"))
810  {
811  PtrList<surfaceScalarField> ssf;
812  readFields
813  (
814  vMesh,
815  vMesh.baseMesh(),
816  objects,
817  selectedFields,
818  ssf
819  );
820  print(" surfScalarFields :", Info, ssf);
821 
822  PtrList<surfaceVectorField> svf;
823  readFields
824  (
825  vMesh,
826  vMesh.baseMesh(),
827  objects,
828  selectedFields,
829  svf
830  );
831  print(" surfVectorFields :", Info, svf);
832 
833  if (ssf.size() + svf.size() > 0)
834  {
835  // Rework the scalar fields into vectorfields.
836  label sz = svf.size();
837 
838  svf.setSize(sz+ssf.size());
839 
840  surfaceVectorField n(mesh.Sf()/mesh.magSf());
841 
842  forAll(ssf, i)
843  {
844  svf.set(sz+i, ssf[i]*n);
845  svf[sz+i].rename(ssf[i].name());
846  }
847  ssf.clear();
848 
849  mkDir(fvPath / "surfaceFields");
850 
851  fileName surfFileName
852  (
853  fvPath
854  /"surfaceFields"
855  /"surfaceFields"
856  + "_"
857  + timeDesc
858  + ".vtk"
859  );
860 
862  (
863  binary,
864  vMesh,
865  surfFileName,
866  svf
867  );
868  }
869  }
870 
871 
872  //---------------------------------------------------------------------
873  //
874  // Write patches (POLYDATA file, one for each patch)
875  //
876  //---------------------------------------------------------------------
877 
878  const polyBoundaryMesh& patches = mesh.boundaryMesh();
879 
880  if (allPatches)
881  {
882  mkDir(fvPath/"allPatches");
883 
884  fileName patchFileName;
885 
886  if (vMesh.useSubMesh())
887  {
888  patchFileName =
889  fvPath/"allPatches"/cellSetName
890  + "_"
891  + timeDesc
892  + ".vtk";
893  }
894  else
895  {
896  patchFileName =
897  fvPath/"allPatches"/"allPatches"
898  + "_"
899  + timeDesc
900  + ".vtk";
901  }
902 
903  Info<< " Combined patches : " << patchFileName << endl;
904 
905  patchWriter writer
906  (
907  vMesh,
908  binary,
909  nearCellValue,
910  patchFileName,
911  getSelectedPatches(patches, excludePatches)
912  );
913 
914  // VolFields + patchID
915  writeFuns::writeCellDataHeader
916  (
917  writer.os(),
918  writer.nFaces(),
919  1+nVolFields
920  );
921 
922  // Write patchID field
923  writer.writePatchIDs();
924 
925  // Write volFields
926  writer.write(vsf);
927  writer.write(vvf);
928  writer.write(vSpheretf);
929  writer.write(vSymmtf);
930  writer.write(vtf);
931 
932  if (!noPointValues)
933  {
934  writeFuns::writePointDataHeader
935  (
936  writer.os(),
937  writer.nPoints(),
938  nPointFields
939  );
940 
941  // Write pointFields
942  writer.write(psf);
943  writer.write(pvf);
944  writer.write(pSpheretf);
945  writer.write(pSymmtf);
946  writer.write(ptf);
947 
948  // no interpolated volFields since I cannot be bothered to
949  // create the patchInterpolation for all subpatches.
950  }
951  }
952  else
953  {
954  forAll(patches, patchI)
955  {
956  const polyPatch& pp = patches[patchI];
957 
958  if (!findStrings(excludePatches, pp.name()))
959  {
960  mkDir(fvPath/pp.name());
961 
962  fileName patchFileName;
963 
964  if (vMesh.useSubMesh())
965  {
966  patchFileName =
967  fvPath/pp.name()/cellSetName
968  + "_"
969  + timeDesc
970  + ".vtk";
971  }
972  else
973  {
974  patchFileName =
975  fvPath/pp.name()/pp.name()
976  + "_"
977  + timeDesc
978  + ".vtk";
979  }
980 
981  Info<< " Patch : " << patchFileName << endl;
982 
983  patchWriter writer
984  (
985  vMesh,
986  binary,
987  nearCellValue,
988  patchFileName,
989  labelList(1, patchI)
990  );
991 
992  if (!isA<emptyPolyPatch>(pp))
993  {
994  // VolFields + patchID
995  writeFuns::writeCellDataHeader
996  (
997  writer.os(),
998  writer.nFaces(),
999  1+nVolFields
1000  );
1001 
1002  // Write patchID field
1003  writer.writePatchIDs();
1004 
1005  // Write volFields
1006  writer.write(vsf);
1007  writer.write(vvf);
1008  writer.write(vSpheretf);
1009  writer.write(vSymmtf);
1010  writer.write(vtf);
1011 
1012  if (!noPointValues)
1013  {
1014  writeFuns::writePointDataHeader
1015  (
1016  writer.os(),
1017  writer.nPoints(),
1018  nVolFields
1019  + nPointFields
1020  );
1021 
1022  // Write pointFields
1023  writer.write(psf);
1024  writer.write(pvf);
1025  writer.write(pSpheretf);
1026  writer.write(pSymmtf);
1027  writer.write(ptf);
1028 
1029  PrimitivePatchInterpolation<primitivePatch> pInter
1030  (
1031  pp
1032  );
1033 
1034  // Write interpolated volFields
1035  writer.write(pInter, vsf);
1036  writer.write(pInter, vvf);
1037  writer.write(pInter, vSpheretf);
1038  writer.write(pInter, vSymmtf);
1039  writer.write(pInter, vtf);
1040  }
1041  }
1042  }
1043  }
1044  }
1045 
1046  //---------------------------------------------------------------------
1047  //
1048  // Write faceZones (POLYDATA file, one for each zone)
1049  //
1050  //---------------------------------------------------------------------
1051 
1052  if (doFaceZones)
1053  {
1054  PtrList<surfaceScalarField> ssf;
1055  readFields
1056  (
1057  vMesh,
1058  vMesh.baseMesh(),
1059  objects,
1060  selectedFields,
1061  ssf
1062  );
1063  print(" surfScalarFields :", Info, ssf);
1064 
1065  PtrList<surfaceVectorField> svf;
1066  readFields
1067  (
1068  vMesh,
1069  vMesh.baseMesh(),
1070  objects,
1071  selectedFields,
1072  svf
1073  );
1074  print(" surfVectorFields :", Info, svf);
1075 
1076  const faceZoneMesh& zones = mesh.faceZones();
1077 
1078  forAll(zones, zoneI)
1079  {
1080  const faceZone& fz = zones[zoneI];
1081 
1082  mkDir(fvPath/fz.name());
1083 
1084  fileName patchFileName;
1085 
1086  if (vMesh.useSubMesh())
1087  {
1088  patchFileName =
1089  fvPath/fz.name()/cellSetName
1090  + "_"
1091  + timeDesc
1092  + ".vtk";
1093  }
1094  else
1095  {
1096  patchFileName =
1097  fvPath/fz.name()/fz.name()
1098  + "_"
1099  + timeDesc
1100  + ".vtk";
1101  }
1102 
1103  Info<< " FaceZone : " << patchFileName << endl;
1104 
1106  (
1107  IndirectList<face>(mesh.faces(), fz),
1108  mesh.points()
1109  );
1110 
1111  surfaceMeshWriter writer
1112  (
1113  binary,
1114  pp,
1115  fz.name(),
1116  patchFileName
1117  );
1118 
1119  // Number of fields
1120  writeFuns::writeCellDataHeader
1121  (
1122  writer.os(),
1123  pp.size(),
1124  ssf.size()+svf.size()
1125  );
1126 
1127  writer.write(ssf);
1128  writer.write(svf);
1129  }
1130  }
1131 
1132 
1133 
1134  //---------------------------------------------------------------------
1135  //
1136  // Write lagrangian data
1137  //
1138  //---------------------------------------------------------------------
1139 
1140  forAllConstIter(HashSet<fileName>, allCloudDirs, iter)
1141  {
1142  const fileName& cloudName = iter.key();
1143 
1144  // Always create the cloud directory.
1145  mkDir(fvPath/cloud::prefix/cloudName);
1146 
1147  fileName lagrFileName
1148  (
1149  fvPath/cloud::prefix/cloudName/cloudName
1150  + "_" + timeDesc + ".vtk"
1151  );
1152 
1153  Info<< " Lagrangian: " << lagrFileName << endl;
1154 
1155 
1156  IOobjectList sprayObjs
1157  (
1158  mesh,
1159  runTime.timeName(),
1160  cloud::prefix/cloudName
1161  );
1162 
1163  IOobject* positionsPtr = sprayObjs.lookup(word("positions"));
1164 
1165  if (positionsPtr)
1166  {
1167  wordList labelNames(sprayObjs.names(labelIOField::typeName));
1168  Info<< " labels :";
1169  print(Info, labelNames);
1170 
1171  wordList scalarNames(sprayObjs.names(scalarIOField::typeName));
1172  Info<< " scalars :";
1173  print(Info, scalarNames);
1174 
1175  wordList vectorNames(sprayObjs.names(vectorIOField::typeName));
1176  Info<< " vectors :";
1177  print(Info, vectorNames);
1178 
1179  wordList sphereNames
1180  (
1181  sprayObjs.names
1182  (
1183  sphericalTensorIOField::typeName
1184  )
1185  );
1186  Info<< " spherical tensors :";
1187  print(Info, sphereNames);
1188 
1189  wordList symmNames
1190  (
1191  sprayObjs.names
1192  (
1193  symmTensorIOField::typeName
1194  )
1195  );
1196  Info<< " symm tensors :";
1197  print(Info, symmNames);
1198 
1199  wordList tensorNames(sprayObjs.names(tensorIOField::typeName));
1200  Info<< " tensors :";
1201  print(Info, tensorNames);
1202 
1203  lagrangianWriter writer
1204  (
1205  vMesh,
1206  binary,
1207  lagrFileName,
1208  cloudName,
1209  false
1210  );
1211 
1212  // Write number of fields
1213  writer.writeParcelHeader
1214  (
1215  labelNames.size()
1216  + scalarNames.size()
1217  + vectorNames.size()
1218  + sphereNames.size()
1219  + symmNames.size()
1220  + tensorNames.size()
1221  );
1222 
1223  // Fields
1224  writer.writeIOField<label>(labelNames);
1225  writer.writeIOField<scalar>(scalarNames);
1226  writer.writeIOField<vector>(vectorNames);
1227  writer.writeIOField<sphericalTensor>(sphereNames);
1228  writer.writeIOField<symmTensor>(symmNames);
1229  writer.writeIOField<tensor>(tensorNames);
1230  }
1231  else
1232  {
1233  lagrangianWriter writer
1234  (
1235  vMesh,
1236  binary,
1237  lagrFileName,
1238  cloudName,
1239  true
1240  );
1241 
1242  // Write number of fields
1243  writer.writeParcelHeader(0);
1244  }
1245  }
1246  }
1247 
1248 
1249  //---------------------------------------------------------------------
1250  //
1251  // Link parallel outputs back to undecomposed case for ease of loading
1252  //
1253  //---------------------------------------------------------------------
1254 
1255  if (Pstream::parRun() && doLinks)
1256  {
1257  mkDir(runTime.path()/".."/"VTK");
1258  chDir(runTime.path()/".."/"VTK");
1259 
1260  Info<< "Linking all processor files to " << runTime.path()/".."/"VTK"
1261  << endl;
1262 
1263  // Get list of vtk files
1264  fileName procVTK
1265  (
1266  fileName("..")
1267  /"processor" + name(Pstream::myProcNo())
1268  /"VTK"
1269  );
1270 
1271  fileNameList dirs(readDir(procVTK, fileName::DIRECTORY));
1272  label sz = dirs.size();
1273  dirs.setSize(sz+1);
1274  dirs[sz] = ".";
1275 
1276  forAll(dirs, i)
1277  {
1278  fileNameList subFiles(readDir(procVTK/dirs[i], fileName::FILE));
1279 
1280  forAll(subFiles, j)
1281  {
1282  fileName procFile(procVTK/dirs[i]/subFiles[j]);
1283 
1284  if (exists(procFile))
1285  {
1286  string cmd
1287  (
1288  "ln -s "
1289  + procFile
1290  + " "
1291  + "processor"
1292  + name(Pstream::myProcNo())
1293  + "_"
1294  + procFile.name()
1295  );
1296  if (system(cmd.c_str()) == -1)
1297  {
1299  << "Could not execute command " << cmd << endl;
1300  }
1301  }
1302  }
1303  }
1304  }
1305 
1306  Info<< "End\n" << endl;
1307 
1308  return 0;
1309 }
1310 
1311 
1312 // ************************************************************************* //
Foam::sphericalTensor
SphericalTensor< scalar > sphericalTensor
SphericalTensor of scalars.
Definition: sphericalTensor.H:48
Foam::compressible::New
autoPtr< BasicCompressibleTurbulenceModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const typename BasicCompressibleTurbulenceModel::transportModel &transport, const word &propertiesName)
Definition: turbulentFluidThermoModel.C:36
print
void print(const char *msg, Ostream &os, const PtrList< GeoField > &flds)
Definition: foamToVTK.C:164
Foam::exists
bool exists(const fileName &, const bool checkGzip=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:608
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::floatScalar
float floatScalar
Float precision floating point scalar type.
Definition: floatScalar.H:49
Foam::tensor
Tensor< scalar > tensor
Tensor of scalars.
Definition: tensor.H:51
Foam::indirectPrimitivePatch
PrimitivePatch< face, IndirectList, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
Definition: indirectPrimitivePatch.H:45
Cloud.H
tensorIOField.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
scalarIOField.H
Foam::instantList
List< instant > instantList
List of instants.
Definition: instantList.H:42
Foam::writeFaceSet
void writeFaceSet(const bool binary, const vtkMesh &vMesh, const faceSet &set, const fileName &fileName)
Definition: writeFaceSet.C:33
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:54
Foam::faceZoneMesh
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
Definition: faceZoneMeshFwd.H:41
n
label n
Definition: TABSMDCalcMethod2.H:31
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
passiveParticle.H
addRegionOption.H
Foam::symmTensor
SymmTensor< scalar > symmTensor
SymmTensor of scalars.
Definition: symmTensor.H:48
size_type
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
Foam::FatalError
error FatalError
createNamedMesh.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
faceZoneMesh.H
Foam::faceZoneMesh.
Foam::isDir
bool isDir(const fileName &)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:615
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
emptyPolyPatch.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::writeSurfFields
void writeSurfFields(const bool binary, const vtkMesh &vMesh, const fileName &fileName, const PtrList< surfaceVectorField > &surfVectorFields)
Definition: writeSurfFields.C:41
Foam::fileNameList
List< fileName > fileNameList
A List of fileNames.
Definition: fileNameList.H:50
volPointInterpolation.H
Foam::chDir
bool chDir(const fileName &dir)
Change the current directory to the one given and return true,.
Definition: POSIX.C:264
setRootCase.H
timeDirs
static instantList timeDirs
Definition: globalFoam.H:44
Foam::findStrings
bool findStrings(const wordReListMatcher &matcher, const std::string &str)
Return true if string matches one of the regular expressions.
Definition: stringListOps.H:52
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
readFields
void readFields(const boolList &haveMesh, const fvMesh &mesh, const autoPtr< fvMeshSubset > &subsetterPtr, IOobjectList &allObjects, PtrList< GeoField > &fields)
Definition: redistributePar.C:589
createTime.H
cloudName
const word cloudName(propsDict.lookup("cloudName"))
Foam::argList::optionFound
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:108
symmTensorIOField.H
fvCFD.H
stringListOps.H
Operations on lists of strings.
patches
patches[0]
Definition: createSingleCellMesh.H:36
List
Definition: Test.C:19
main
int main(int argc, char *argv[])
Definition: foamToVTK.C:228
sphericalTensorIOField.H
Foam::readDir
fileNameList readDir(const fileName &, const fileName::Type=fileName::FILE, const bool filtergz=true)
Read a directory and return the entries as a string list.
Definition: POSIX.C:660
Foam::surfaceVectorField
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
Definition: surfaceFieldsFwd.H:55
args
Foam::argList args(argc, argv)
Foam::mkDir
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:419
Foam::argList::optionReadIfPresent
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
Definition: argListI.H:198
getSelectedPatches
labelList getSelectedPatches(const polyBoundaryMesh &patches, const List< wordRe > &excludePatches)
Definition: foamToVTK.C:189
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:259
Foam::system
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1155
Foam::rmDir
bool rmDir(const fileName &)
Remove a dirctory and its contents.
Definition: POSIX.C:974
pointMesh.H
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::writePointSet
void writePointSet(const bool binary, const primitiveMesh &mesh, const topoSet &set, const fileName &fileName)
Write pointSet to vtk polydata file.
labelIOField.H
Foam::argList::optionLookup
IStringStream optionLookup(const word &opt) const
Return an IStringStream from the named option.
Definition: argListI.H:114