foamFormatConvert.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 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  foamFormatConvert
26 
27 Description
28  Converts all IOobjects associated with a case into the format specified
29  in the controlDict.
30 
31  Mainly used to convert binary mesh/field files to ASCII.
32 
33  Problem: any zero-size List written binary gets written as '0'. When
34  reading the file as a dictionary this is interpreted as a label. This
35  is (usually) not a problem when doing patch fields since these get the
36  'uniform', 'nonuniform' prefix. However zone contents are labelLists
37  not labelFields and these go wrong. For now hacked a solution where
38  we detect the keywords in zones and redo the dictionary entries
39  to be labelLists.
40 
41 \*---------------------------------------------------------------------------*/
42 
43 #include "argList.H"
44 #include "timeSelector.H"
45 #include "Time.H"
46 #include "volFields.H"
47 #include "surfaceFields.H"
48 #include "pointFields.H"
49 #include "cellIOList.H"
50 #include "IOobjectList.H"
51 #include "IOPtrList.H"
52 #include "cloud.H"
53 #include "labelIOField.H"
54 #include "scalarIOField.H"
55 #include "sphericalTensorIOField.H"
56 #include "symmTensorIOField.H"
57 #include "tensorIOField.H"
58 #include "labelFieldIOField.H"
59 #include "vectorFieldIOField.H"
60 #include "Cloud.H"
61 #include "passiveParticle.H"
62 #include "fieldDictionary.H"
63 
64 #include "writeMeshObject.H"
65 
66 using namespace Foam;
67 
68 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
69 
70 namespace Foam
71 {
73 }
74 
75 
76 // Hack to do zones which have Lists in them. See above.
77 bool writeZones(const word& name, const fileName& meshDir, Time& runTime)
78 {
79  IOobject io
80  (
81  name,
82  runTime.name(),
83  meshDir,
84  runTime,
87  false
88  );
89 
90  bool writeOk = false;
91 
92  if (io.headerOk())
93  {
94  Info<< " Reading " << io.headerClassName()
95  << " : " << name << endl;
96 
97  // Switch off type checking (for reading e.g. faceZones as
98  // generic list of dictionaries).
99  const word oldTypeName = IOPtrList<entry>::typeName;
101 
102  IOPtrList<entry> meshObject(io);
103 
104  forAll(meshObject, i)
105  {
106  if (meshObject[i].isDict())
107  {
108  dictionary& d = meshObject[i].dict();
109 
110  if (d.found("faceLabels"))
111  {
112  d.set("faceLabels", labelList(d.lookup("faceLabels")));
113  }
114 
115  if (d.found("flipMap"))
116  {
117  d.set("flipMap", boolList(d.lookup("flipMap")));
118  }
119 
120  if (d.found("cellLabels"))
121  {
122  d.set("cellLabels", labelList(d.lookup("cellLabels")));
123  }
124 
125  if (d.found("pointLabels"))
126  {
127  d.set("pointLabels", labelList(d.lookup("pointLabels")));
128  }
129  }
130  }
131 
132  const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
133  // Fake type back to what was in field
134  const_cast<word&>(meshObject.type()) = io.headerClassName();
135 
136  Info<< " Writing " << name << endl;
137 
138  // Force writing as ascii
139  writeOk = meshObject.regIOobject::writeObject
140  (
143  runTime.writeCompression(),
144  true
145  );
146  }
147 
148  return writeOk;
149 }
150 
151 
152 // Reduction for non-empty strings
153 class uniqueEqOp
154 {
155  public:
156  void operator()(stringList& x, const stringList& y) const
157  {
158  stringList newX(x.size()+y.size());
159  label n = 0;
160  forAll(x, i)
161  {
162  if (!x[i].empty())
163  {
164  newX[n++] = x[i];
165  }
166  }
167  forAll(y, i)
168  {
169  if (!y[i].empty() && findIndex(x, y[i]) == -1)
170  {
171  newX[n++] = y[i];
172  }
173  }
174  newX.setSize(n);
175  x.transfer(newX);
176  }
177 };
178 
179 
180 template<class T>
181 bool writeOptionalMeshObject
182 (
183  const word& name,
184  const fileName& meshDir,
185  Time& runTime,
186  const bool write
187 )
188 {
189  IOobject io
190  (
191  name,
192  runTime.name(),
193  meshDir,
194  runTime,
197  false
198  );
199 
200  bool writeOk = false;
201 
202  bool haveFile = io.headerOk();
203 
204  // Make sure all know if there is a valid class name
205  stringList classNames(1, io.headerClassName());
206  combineReduce(classNames, uniqueEqOp());
207 
208  // Check for correct type
209  if (classNames[0] == T::typeName)
210  {
211  Info<< " Reading " << classNames[0]
212  << " : " << name << endl;
213  T meshObject(io, write && haveFile);
214 
215  Info<< " Writing " << name << endl;
216  writeOk = meshObject.regIOobject::write(write && haveFile);
217  }
218 
219  return writeOk;
220 }
221 
222 
223 int main(int argc, char *argv[])
224 {
227  (
228  "noConstant",
229  "exclude the 'constant/' dir in the times list"
230  );
231 
232  #include "addRegionOption.H"
233  #include "setRootCase.H"
234 
235  // enable noConstant by switching
236  if (!args.optionFound("noConstant"))
237  {
238  args.setOption("constant", "");
239  }
240  else
241  {
242  args.unsetOption("constant");
243  Info<< "Excluding the constant directory." << nl << endl;
244  }
245 
246 
247  #include "createTime.H"
248  // Optional mesh (used to read Clouds)
250 
251 
252  // Make sure we do not use the master-only reading since we read
253  // fields (different per processor) as dictionaries.
255 
256 
257  fileName meshDir = polyMesh::meshSubDir;
258  fileName regionPrefix = "";
260  if (args.optionReadIfPresent("region", regionName))
261  {
262  Info<< "Using region " << regionName << nl << endl;
263  regionPrefix = regionName;
265  }
266 
268 
269  forAll(timeDirs, timeI)
270  {
271  runTime.setTime(timeDirs[timeI], timeI);
272  Info<< "Time = " << runTime.userTimeName() << endl;
273 
274  // Convert all the standard mesh files
275  writeMeshObject<cellCompactIOList, cellIOList>
276  (
277  "cells",
278  meshDir,
279  runTime
280  );
281  writeMeshObject<labelIOList>("owner", meshDir, runTime);
282  writeMeshObject<labelIOList>("neighbour", meshDir, runTime);
283  writeMeshObject<faceCompactIOList, faceIOList>
284  (
285  "faces",
286  meshDir,
287  runTime
288  );
289  writeMeshObject<pointIOField>("points", meshDir, runTime);
290  // Write boundary in ascii. This is only needed for fileHandler to
291  // kick in. Should not give problems since always writing ascii.
292  writeZones("boundary", meshDir, runTime);
293  writeMeshObject<labelIOList>("pointProcAddressing", meshDir, runTime);
294  writeMeshObject<labelIOList>("faceProcAddressing", meshDir, runTime);
295  writeMeshObject<labelIOList>("cellProcAddressing", meshDir, runTime);
296 
297  if (runTime.writeFormat() == IOstream::ASCII)
298  {
299  // Only do zones when converting from binary to ascii
300  // The other way gives problems since working on dictionary level.
301  writeZones("cellZones", meshDir, runTime);
302  writeZones("faceZones", meshDir, runTime);
303  writeZones("pointZones", meshDir, runTime);
304  }
305 
306  // Get list of objects from the database
307  IOobjectList objects(runTime, runTime.name(), regionPrefix);
308 
310  {
311  const word& headerClassName = iter()->headerClassName();
312 
313  if
314  (
315  headerClassName == volScalarField::typeName
316  || headerClassName == volVectorField::typeName
317  || headerClassName == volSphericalTensorField::typeName
318  || headerClassName == volSymmTensorField::typeName
319  || headerClassName == volTensorField::typeName
320 
321  || headerClassName == surfaceScalarField::typeName
322  || headerClassName == surfaceVectorField::typeName
323  || headerClassName == surfaceSphericalTensorField::typeName
324  || headerClassName == surfaceSymmTensorField::typeName
325  || headerClassName == surfaceTensorField::typeName
326 
327  || headerClassName == pointScalarField::typeName
328  || headerClassName == pointVectorField::typeName
329  || headerClassName == pointSphericalTensorField::typeName
330  || headerClassName == pointSymmTensorField::typeName
331  || headerClassName == pointTensorField::typeName
332 
333  || headerClassName == volScalarField::Internal::typeName
334  || headerClassName == volVectorField::Internal::typeName
335  || headerClassName == volSphericalTensorField::Internal::typeName
336  || headerClassName == volSymmTensorField::Internal::typeName
337  || headerClassName == volTensorField::Internal::typeName
338  )
339  {
340  Info<< " Reading " << headerClassName
341  << " : " << iter()->name() << endl;
342 
343  fieldDictionary fDict(*iter(), headerClassName);
344 
345  Info<< " Writing " << iter()->name() << endl;
346  fDict.regIOobject::write();
347  }
348  }
349 
350 
351 
352  // Check for lagrangian
353  const fileName lagrangianDir
354  (
355  fileHandler().filePath
356  (
357  runTime.timePath()
358  / regionPrefix
359  / cloud::prefix
360  )
361  );
362  stringList lagrangianDirs
363  (
364  lagrangianDir == fileName::null ? 0 : 1,
365  lagrangianDir
366  );
367 
368  combineReduce(lagrangianDirs, uniqueEqOp());
369 
370  if (!lagrangianDirs.empty())
371  {
372  if (meshPtr.valid())
373  {
374  meshPtr().readUpdate();
375  }
376  else
377  {
378  Info<< " Create polyMesh for time = "
379  << runTime.name() << endl;
380 
381  meshPtr.reset
382  (
383  new polyMesh
384  (
385  IOobject
386  (
387  regionName,
388  runTime.name(),
389  runTime,
391  )
392  )
393  );
394  }
395 
396  stringList cloudDirs
397  (
399  (
400  lagrangianDirs[0],
402  )
403  );
404 
405  combineReduce(cloudDirs, uniqueEqOp());
406 
407  forAll(cloudDirs, i)
408  {
409  fileName dir(cloud::prefix/cloudDirs[i]);
410 
411  Cloud<passiveParticle> parcels(meshPtr(), cloudDirs[i], false);
412 
413  parcels.writeObject
414  (
415  runTime.writeFormat(),
417  runTime.writeCompression(),
418  parcels.size()
419  );
420 
421 
422  // Do local scan for valid cloud objects
423  IOobjectList sprayObjs(runTime, runTime.name(), dir);
424 
425  // Combine with all other cloud objects
426  stringList sprayFields(sprayObjs.sortedToc());
427  combineReduce(sprayFields, uniqueEqOp());
428 
429  forAll(sprayFields, fieldi)
430  {
431  const word& name = sprayFields[fieldi];
432 
433  // Note: try the various field types. Make sure to
434  // exit once successful conversion to avoid re-read
435  // converted file.
436 
437  if
438  (
439  name == "positions"
440  || name == "origProcId"
441  || name == "origId"
442  )
443  {
444  continue;
445  }
446 
447  bool writeOk = writeOptionalMeshObject<labelIOField>
448  (
449  name,
450  dir,
451  runTime,
452  parcels.size() > 0
453  );
454  if (writeOk) continue;
455 
456  writeOk = writeOptionalMeshObject<scalarIOField>
457  (
458  name,
459  dir,
460  runTime,
461  parcels.size() > 0
462  );
463  if (writeOk) continue;
464 
465  writeOk = writeOptionalMeshObject<vectorIOField>
466  (
467  name,
468  dir,
469  runTime,
470  parcels.size() > 0
471  );
472  if (writeOk) continue;
473 
474  writeOk = writeOptionalMeshObject<sphericalTensorIOField>
475  (
476  name,
477  dir,
478  runTime,
479  parcels.size() > 0
480  );
481  if (writeOk) continue;
482 
483  writeOk = writeOptionalMeshObject<symmTensorIOField>
484  (
485  name,
486  dir,
487  runTime,
488  parcels.size() > 0
489  );
490  if (writeOk) continue;
491 
492  writeOk = writeOptionalMeshObject<tensorIOField>
493  (
494  name,
495  dir,
496  runTime,
497  parcels.size() > 0
498  );
499  if (writeOk) continue;
500 
501  writeOk = writeOptionalMeshObject<labelFieldIOField>
502  (
503  name,
504  dir,
505  runTime,
506  parcels.size() > 0
507  );
508  if (writeOk) continue;
509 
510  writeOk = writeOptionalMeshObject<vectorFieldIOField>
511  (
512  name,
513  dir,
514  runTime,
515  parcels.size() > 0
516  );
517 
518  if (!writeOk)
519  {
520  Info<< " Failed converting " << name << endl;
521  }
522  }
523  }
524  }
525 
526  Info<< endl;
527  }
528 
529  Info<< "End\n" << endl;
530 
531  return 0;
532 }
533 
534 
535 // ************************************************************************* //
scalar y
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
static const char *const typeName
Definition: Field.H:105
A PtrList of objects of type <Type> with automated input and output.
Definition: IOPtrList.H:53
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:53
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:226
static const versionNumber currentVersion
Current version number.
Definition: IOstream.H:203
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
virtual void setTime(const Time &)
Reset the time and time-index to those of the given time.
Definition: Time.C:939
word userTimeName() const
Return current user time name with units.
Definition: Time.C:836
IOstream::streamFormat writeFormat() const
Default write format.
Definition: Time.H:283
IOstream::compressionType writeCompression() const
Default write compression.
Definition: Time.H:295
fileName timePath() const
Return current time path.
Definition: Time.H:277
bool setOption(const word &opt, const string &param="")
Set option directly (use with caution)
Definition: argList.C:1112
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
Definition: argList.C:118
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:114
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
Definition: argListI.H:204
bool unsetOption(const word &opt)
Unset option directly (use with caution)
Definition: argList.C:1188
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
static const word prefix
The prefix to local: lagrangian.
Definition: cloud.H:63
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:860
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:1307
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:659
const word & name() const
Return const reference to name.
Read field as dictionary (without mesh).
A class for handling file names.
Definition: fileName.H:82
static const fileName null
An empty fileName.
Definition: fileName.H:97
readUpdateState readUpdate(const stitchType stitch=stitchType::geometric)
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:808
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:268
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:271
void reset(const label nPoints, const label nInternalFaces, const label nFaces, const label nCells)
Reset this primitiveMesh given the primitive array sizes.
static void addOptions(const bool constant=true, const bool withZero=false)
Add the options handled by timeSelector to argList::validOptions.
Definition: timeSelector.C:114
static instantList select0(Time &runTime, const argList &args)
Return the set of times selected based on the argList options.
Definition: timeSelector.C:252
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
Foam::word regionName
int main(int argc, char *argv[])
Definition: financialFoam.C:44
static instantList timeDirs
Definition: globalFoam.H:44
static fvMesh * meshPtr
Definition: globalFoam.H:52
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
List< label > labelList
A List of labels.
Definition: labelList.H:56
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
messageStream Info
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
defineTemplateTypeNameAndDebug(IOPtrList< ensightPart >, 0)
static const char nl
Definition: Ostream.H:260
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
fileNameList readDir(const fileName &, const fileType=fileType::file, const bool filterVariants=true, const bool followLink=true)
Read a directory and return the entries as a string list.
Definition: POSIX.C:662
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
objects
Foam::argList args(argc, argv)
Foam::surfaceFields.
Write a mesh object in the format specified in controlDict.