decomposePar.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2016-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Application
28  decomposePar
29 
30 Group
31  grpParallelUtilities
32 
33 Description
34  Automatically decomposes a mesh and fields of a case for parallel
35  execution of OpenFOAM.
36 
37 Usage
38  \b decomposePar [OPTIONS]
39 
40  Options:
41  - \par -allRegions
42  Decompose all regions in regionProperties. Does not check for
43  existence of processor*.
44 
45  - \par -case <dir>
46  Specify case directory to use (instead of the cwd).
47 
48  - \par -cellDist
49  Write the cell distribution as a labelList, for use with 'manual'
50  decomposition method and as a volScalarField for visualization.
51 
52  - \par -constant
53  Include the 'constant/' dir in the times list.
54 
55  - \par -copyUniform
56  Copy any \a uniform directories too.
57 
58  - \par -copyZero
59  Copy \a 0 directory to processor* rather than decompose the fields.
60 
61  - \par -debug-switch <name=val>
62  Specify the value of a registered debug switch. Default is 1
63  if the value is omitted. (Can be used multiple times)
64 
65  - \par -decomposeParDict <file>
66  Use specified file for decomposePar dictionary.
67 
68  - \par -dry-run
69  Test without writing the decomposition. Changes -cellDist to
70  only write volScalarField.
71 
72  - \par -fields
73  Use existing geometry decomposition and convert fields only.
74 
75  - \par fileHandler <handler>
76  Override the file handler type.
77 
78  - \par -force
79  Remove any existing \a processor subdirectories before decomposing the
80  geometry.
81 
82  - \par -ifRequired
83  Only decompose the geometry if the number of domains has changed from a
84  previous decomposition. No \a processor subdirectories will be removed
85  unless the \a -force option is also specified. This option can be used
86  to avoid redundant geometry decomposition (eg, in scripts), but should
87  be used with caution when the underlying (serial) geometry or the
88  decomposition method etc. have been changed between decompositions.
89 
90  - \par -info-switch <name=val>
91  Specify the value of a registered info switch. Default is 1
92  if the value is omitted. (Can be used multiple times)
93 
94  - \par -latestTime
95  Select the latest time.
96 
97  - \par -lib <name>
98  Additional library or library list to load (can be used multiple times).
99 
100  - \par -noFunctionObjects
101  Do not execute function objects.
102 
103  - \par -noSets
104  Skip decomposing cellSets, faceSets, pointSets.
105 
106  - \par -noZero
107  Exclude the \a 0 dir from the times list.
108 
109  - \par -opt-switch <name=val>
110  Specify the value of a registered optimisation switch (int/bool).
111  Default is 1 if the value is omitted. (Can be used multiple times)
112 
113  - \par -region <regionName>
114  Decompose named region. Does not check for existence of processor*.
115 
116  - \par -time <ranges>
117  Override controlDict settings and decompose selected times. Does not
118  re-decompose the mesh i.e. does not handle moving mesh or changing
119  mesh cases. Eg, ':10,20 40:70 1000:', 'none', etc.
120 
121  - \par -verbose
122  Additional verbosity.
123 
124  - \par -doc
125  Display documentation in browser.
126 
127  - \par -doc-source
128  Display source code in browser.
129 
130  - \par -help
131  Display short help and exit.
132 
133  - \par -help-man
134  Display full help (manpage format) and exit.
135 
136  - \par -help-notes
137  Display help notes (description) and exit.
138 
139  - \par -help-full
140  Display full help and exit.
141 
142 \*---------------------------------------------------------------------------*/
143 
144 #include "OSspecific.H"
145 #include "fvCFD.H"
146 #include "IOobjectList.H"
147 #include "domainDecomposition.H"
149 #include "labelIOField.H"
150 #include "labelFieldIOField.H"
151 #include "scalarIOField.H"
152 #include "scalarFieldIOField.H"
153 #include "vectorIOField.H"
154 #include "vectorFieldIOField.H"
155 #include "sphericalTensorIOField.H"
157 #include "symmTensorIOField.H"
158 #include "symmTensorFieldIOField.H"
159 #include "tensorIOField.H"
160 #include "tensorFieldIOField.H"
161 #include "pointFields.H"
162 #include "regionProperties.H"
163 
164 #include "readFields.H"
165 #include "dimFieldDecomposer.H"
166 #include "fvFieldDecomposer.H"
167 #include "pointFieldDecomposer.H"
169 #include "decompositionModel.H"
170 
171 #include "faCFD.H"
172 #include "emptyFaPatch.H"
173 #include "faMeshDecomposition.H"
174 #include "faFieldDecomposer.H"
175 
176 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
177 
178 namespace Foam
179 {
180 
181 const labelIOList& procAddressing
182 (
183  const PtrList<fvMesh>& procMeshList,
184  const label proci,
185  const word& name,
186  PtrList<labelIOList>& procAddressingList
187 )
188 {
189  const fvMesh& procMesh = procMeshList[proci];
190 
191  if (!procAddressingList.set(proci))
192  {
193  procAddressingList.set
194  (
195  proci,
196  new labelIOList
197  (
198  IOobject
199  (
200  name,
201  procMesh.facesInstance(),
202  procMesh.meshSubDir,
203  procMesh,
206  false
207  )
208  )
209  );
210  }
211  return procAddressingList[proci];
212 }
213 
214 
215 void decomposeUniform
216 (
217  const bool copyUniform,
218  const domainDecomposition& mesh,
219  const Time& processorDb,
220  const word& regionDir = word::null
221 )
222 {
223  const Time& runTime = mesh.time();
224 
225  // Any uniform data to copy/link?
226  const fileName uniformDir(regionDir/"uniform");
227 
228  if (fileHandler().isDir(runTime.timePath()/uniformDir))
229  {
230  Info<< "Detected additional non-decomposed files in "
231  << runTime.timePath()/uniformDir
232  << endl;
233 
234  const fileName timePath =
235  fileHandler().filePath(processorDb.timePath());
236 
237  // If no fields have been decomposed the destination
238  // directory will not have been created so make sure.
239  mkDir(timePath);
240 
241  if (copyUniform || mesh.distributed())
242  {
243  if (!fileHandler().exists(timePath/uniformDir))
244  {
245  fileHandler().cp
246  (
247  runTime.timePath()/uniformDir,
248  timePath/uniformDir
249  );
250  }
251  }
252  else
253  {
254  // Link with relative paths
255  string parentPath = string("..")/"..";
256 
257  if (regionDir != word::null)
258  {
259  parentPath = parentPath/"..";
260  }
261 
262  fileName currentDir(cwd());
263  chDir(timePath);
264 
265  if (!fileHandler().exists(uniformDir))
266  {
267  fileHandler().ln
268  (
269  parentPath/runTime.timeName()/uniformDir,
270  uniformDir
271  );
272  }
273  chDir(currentDir);
274  }
275  }
276 }
277 
278 }
279 
280 
281 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
282 
283 int main(int argc, char *argv[])
284 {
285  argList::addNote
286  (
287  "Decompose a mesh and fields of a case for parallel execution"
288  );
289 
290  argList::noParallel();
291  argList::addOption
292  (
293  "decomposeParDict",
294  "file",
295  "Use specified file for decomposePar dictionary"
296  );
297  #include "addRegionOption.H"
298  argList::addBoolOption
299  (
300  "allRegions",
301  "Operate on all regions in regionProperties"
302  );
303  argList::addBoolOption
304  (
305  "dry-run",
306  "Test without writing the decomposition. "
307  "Changes -cellDist to only write volScalarField."
308  );
309  argList::addBoolOption
310  (
311  "verbose",
312  "Additional verbosity"
313  );
314  argList::addBoolOption
315  (
316  "cellDist",
317  "Write cell distribution as a labelList - for use with 'manual' "
318  "decomposition method and as a volScalarField for visualization."
319  );
320  argList::addBoolOption
321  (
322  "copyZero",
323  "Copy 0/ directory to processor*/ rather than decompose the fields"
324  );
325  argList::addBoolOption
326  (
327  "copyUniform",
328  "Copy any uniform/ directories too"
329  );
330  argList::addBoolOption
331  (
332  "fields",
333  "Use existing geometry decomposition and convert fields only"
334  );
335  argList::addBoolOption
336  (
337  "noSets",
338  "Skip decomposing cellSets, faceSets, pointSets"
339  );
340  argList::addBoolOption
341  (
342  "force",
343  "Remove existing processor*/ subdirs before decomposing the geometry"
344  );
345  argList::addBoolOption
346  (
347  "ifRequired",
348  "Only decompose geometry if the number of domains has changed"
349  );
350 
351  // Allow explicit -constant, have zero from time range
352  timeSelector::addOptions(true, false); // constant(true), zero(false)
353 
354  #include "setRootCase.H"
355 
356  const bool dryrun = args.found("dry-run");
357  const bool optRegion = args.found("region");
358  const bool allRegions = args.found("allRegions");
359  const bool writeCellDist = args.found("cellDist");
360  const bool verbose = args.found("verbose");
361 
362  // Most of these are ignored for dry-run (not triggered anywhere)
363  const bool copyZero = args.found("copyZero");
364  const bool copyUniform = args.found("copyUniform");
365  const bool decomposeSets = !args.found("noSets");
366  const bool decomposeIfRequired = args.found("ifRequired");
367 
368  bool decomposeFieldsOnly = args.found("fields");
369  bool forceOverwrite = args.found("force");
370 
371 
372  // Set time from database
373  #include "createTime.H"
374 
375  // Allow override of time (unless dry-run)
376  instantList times;
377  if (dryrun)
378  {
379  Info<< "\ndry-run: ignoring -copy*, -fields, -force, time selection"
380  << nl;
381  }
382  else
383  {
384  times = timeSelector::selectIfPresent(runTime, args);
385  }
386 
387  // Allow override of decomposeParDict location
388  fileName decompDictFile(args.get<fileName>("decomposeParDict", ""));
389  if (!decompDictFile.empty() && !decompDictFile.isAbsolute())
390  {
391  decompDictFile = runTime.globalPath()/decompDictFile;
392  }
393 
394  // Get all region names
395  wordList regionNames;
396  if (allRegions)
397  {
398  regionNames = regionProperties(runTime).names();
399 
400  Info<< "Decomposing all regions in regionProperties" << nl
401  << " " << flatOutput(regionNames) << nl << endl;
402  }
403  else
404  {
405  regionNames.resize(1);
406  regionNames.first() =
407  args.getOrDefault<word>("region", fvMesh::defaultRegion);
408  }
409 
410  forAll(regionNames, regioni)
411  {
412  const word& regionName = regionNames[regioni];
413  const word& regionDir =
414  (regionName == fvMesh::defaultRegion ? word::null : regionName);
415 
416  if (dryrun)
417  {
418  Info<< "dry-run: decomposing mesh " << regionName << nl << nl
419  << "Create mesh..." << flush;
420 
421  domainDecompositionDryRun decompTest
422  (
423  IOobject
424  (
425  regionName,
426  runTime.timeName(),
427  runTime,
428  IOobject::MUST_READ,
429  IOobject::NO_WRITE,
430  false
431  ),
432  decompDictFile
433  );
434 
435  decompTest.execute(writeCellDist, verbose);
436  continue;
437  }
438 
439  Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
440 
441  // Determine the existing processor count directly
442  label nProcs = fileHandler().nProcs(runTime.path(), regionDir);
443 
444  // Get requested numberOfSubdomains directly from the dictionary.
445  // Note: have no mesh yet so cannot use decompositionModel::New
446  const label nDomains = decompositionMethod::nDomains
447  (
448  IOdictionary
449  (
450  IOobject::selectIO
451  (
452  IOobject
453  (
454  decompositionModel::canonicalName,
455  runTime.time().system(),
456  regionDir, // region (if non-default)
457  runTime,
458  IOobject::MUST_READ,
459  IOobject::NO_WRITE,
460  false
461  ),
462  decompDictFile
463  )
464  )
465  );
466 
467  // Give file handler a chance to determine the output directory
468  const_cast<fileOperation&>(fileHandler()).setNProcs(nDomains);
469 
470  if (decomposeFieldsOnly)
471  {
472  // Sanity check on previously decomposed case
473  if (nProcs != nDomains)
474  {
476  << "Specified -fields, but the case was decomposed with "
477  << nProcs << " domains"
478  << nl
479  << "instead of " << nDomains
480  << " domains as specified in decomposeParDict" << nl
481  << exit(FatalError);
482  }
483  }
484  else if (nProcs)
485  {
486  bool procDirsProblem = true;
487 
488  if (decomposeIfRequired && nProcs == nDomains)
489  {
490  // We can reuse the decomposition
491  decomposeFieldsOnly = true;
492  procDirsProblem = false;
493  forceOverwrite = false;
494 
495  Info<< "Using existing processor directories" << nl;
496  }
497 
498  if (allRegions || optRegion)
499  {
500  procDirsProblem = false;
501  forceOverwrite = false;
502  }
503 
504  if (forceOverwrite)
505  {
506  Info<< "Removing " << nProcs
507  << " existing processor directories" << endl;
508 
509  // Remove existing processors directory
510  fileNameList dirs
511  (
513  (
514  runTime.path(),
515  fileName::Type::DIRECTORY
516  )
517  );
518  forAllReverse(dirs, diri)
519  {
520  const fileName& d = dirs[diri];
521 
522  // Starts with 'processors'
523  if (d.find("processors") == 0)
524  {
525  if (fileHandler().exists(d))
526  {
527  fileHandler().rmDir(d);
528  }
529  }
530 
531  // Starts with 'processor'
532  if (d.find("processor") == 0)
533  {
534  // Check that integer after processor
535  fileName num(d.substr(9));
536  label proci = -1;
537  if (Foam::read(num.c_str(), proci))
538  {
539  if (fileHandler().exists(d))
540  {
541  fileHandler().rmDir(d);
542  }
543  }
544  }
545  }
546 
547  procDirsProblem = false;
548  }
549 
550  if (procDirsProblem)
551  {
553  << "Case is already decomposed with " << nProcs
554  << " domains, use the -force option or manually" << nl
555  << "remove processor directories before decomposing. e.g.,"
556  << nl
557  << " rm -rf " << runTime.path().c_str() << "/processor*"
558  << nl
559  << exit(FatalError);
560  }
561  }
562 
563  Info<< "Create mesh" << endl;
564  domainDecomposition mesh
565  (
566  IOobject
567  (
568  regionName,
569  runTime.timeName(),
570  runTime,
571  IOobject::NO_READ,
572  IOobject::NO_WRITE,
573  false
574  ),
575  decompDictFile
576  );
577 
578  // Decompose the mesh
579  if (!decomposeFieldsOnly)
580  {
581  mesh.decomposeMesh();
582 
583  mesh.writeDecomposition(decomposeSets);
584 
585  if (writeCellDist)
586  {
587  const labelList& procIds = mesh.cellToProc();
588 
589  // Write decomposition as volScalarField for visualization
590  volScalarField cellDist
591  (
592  IOobject
593  (
594  "cellDist",
595  runTime.timeName(),
596  mesh,
597  IOobject::NO_READ,
598  IOobject::AUTO_WRITE
599  ),
600  mesh,
601  dimensionedScalar("cellDist", dimless, -1),
602  zeroGradientFvPatchScalarField::typeName
603  );
604 
605  forAll(procIds, celli)
606  {
607  cellDist[celli] = procIds[celli];
608  }
609 
610  cellDist.correctBoundaryConditions();
611  cellDist.write();
612 
613  Info<< nl << "Wrote decomposition as volScalarField to "
614  << cellDist.name() << " for visualization."
615  << endl;
616 
617  // Write decomposition as labelList for use with 'manual'
618  // decomposition method.
619  labelIOList cellDecomposition
620  (
621  IOobject
622  (
623  "cellDecomposition",
624  mesh.facesInstance(),
625  mesh,
626  IOobject::NO_READ,
627  IOobject::NO_WRITE,
628  false
629  ),
630  procIds
631  );
632  cellDecomposition.write();
633 
634  Info<< nl << "Wrote decomposition to "
635  << cellDecomposition.objectPath()
636  << " for use in manual decomposition." << endl;
637  }
638 
639  fileHandler().flush();
640  }
641 
642 
643  if (copyZero)
644  {
645  // Copy the 0 directory into each of the processor directories
646  fileName prevTimePath;
647  for (label proci = 0; proci < mesh.nProcs(); ++proci)
648  {
649  Time processorDb
650  (
651  Time::controlDictName,
652  args.rootPath(),
653  args.caseName()/("processor" + Foam::name(proci))
654  );
655  processorDb.setTime(runTime);
656 
657  if (fileHandler().isDir(runTime.timePath()))
658  {
659  // Get corresponding directory name (to handle processors/)
660  const fileName timePath
661  (
662  fileHandler().objectPath
663  (
664  IOobject
665  (
666  "",
667  processorDb.timeName(),
668  processorDb
669  ),
670  word::null
671  )
672  );
673 
674  if (timePath != prevTimePath)
675  {
676  Info<< "Processor " << proci
677  << ": copying " << runTime.timePath() << nl
678  << " to " << timePath << endl;
679  fileHandler().cp(runTime.timePath(), timePath);
680 
681  prevTimePath = timePath;
682  }
683  }
684  }
685  }
686  else
687  {
688  // Decompose the field files
689 
690  // Cached processor meshes and maps. These are only preserved if
691  // running with multiple times.
692  PtrList<Time> processorDbList(mesh.nProcs());
693  PtrList<fvMesh> procMeshList(mesh.nProcs());
694  PtrList<labelIOList> faceProcAddressingList(mesh.nProcs());
695  PtrList<labelIOList> cellProcAddressingList(mesh.nProcs());
696  PtrList<labelIOList> boundaryProcAddressingList(mesh.nProcs());
697  PtrList<fvFieldDecomposer> fieldDecomposerList(mesh.nProcs());
698  PtrList<dimFieldDecomposer> dimFieldDecomposerList(mesh.nProcs());
699  PtrList<labelIOList> pointProcAddressingList(mesh.nProcs());
700  PtrList<pointFieldDecomposer> pointFieldDecomposerList
701  (
702  mesh.nProcs()
703  );
704 
705 
706  // Loop over all times
707  forAll(times, timeI)
708  {
709  runTime.setTime(times[timeI], timeI);
710 
711  Info<< "Time = " << runTime.timeName() << endl;
712 
713  // Search for list of objects for this time
714  IOobjectList objects(mesh, runTime.timeName());
715 
716 
717  // Construct the vol fields
718  // ~~~~~~~~~~~~~~~~~~~~~~~~
719  PtrList<volScalarField> volScalarFields;
720  readFields(mesh, objects, volScalarFields, false);
721  PtrList<volVectorField> volVectorFields;
722  readFields(mesh, objects, volVectorFields, false);
723  PtrList<volSphericalTensorField> volSphericalTensorFields;
724  readFields(mesh, objects, volSphericalTensorFields, false);
725  PtrList<volSymmTensorField> volSymmTensorFields;
726  readFields(mesh, objects, volSymmTensorFields, false);
727  PtrList<volTensorField> volTensorFields;
728  readFields(mesh, objects, volTensorFields, false);
729 
730 
731  // Construct the dimensioned fields
732  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
733  PtrList<DimensionedField<scalar, volMesh>> dimScalarFields;
734  readFields(mesh, objects, dimScalarFields);
735  PtrList<DimensionedField<vector, volMesh>> dimVectorFields;
736  readFields(mesh, objects, dimVectorFields);
737  PtrList<DimensionedField<sphericalTensor, volMesh>>
738  dimSphericalTensorFields;
739  readFields(mesh, objects, dimSphericalTensorFields);
740  PtrList<DimensionedField<symmTensor, volMesh>>
741  dimSymmTensorFields;
742  readFields(mesh, objects, dimSymmTensorFields);
743  PtrList<DimensionedField<tensor, volMesh>> dimTensorFields;
744  readFields(mesh, objects, dimTensorFields);
745 
746 
747  // Construct the surface fields
748  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
749  PtrList<surfaceScalarField> surfaceScalarFields;
750  readFields(mesh, objects, surfaceScalarFields, false);
751  PtrList<surfaceVectorField> surfaceVectorFields;
752  readFields(mesh, objects, surfaceVectorFields, false);
753  PtrList<surfaceSphericalTensorField>
754  surfaceSphericalTensorFields;
755  readFields(mesh, objects, surfaceSphericalTensorFields, false);
756  PtrList<surfaceSymmTensorField> surfaceSymmTensorFields;
757  readFields(mesh, objects, surfaceSymmTensorFields, false);
758  PtrList<surfaceTensorField> surfaceTensorFields;
759  readFields(mesh, objects, surfaceTensorFields, false);
760 
761 
762  // Construct the point fields
763  // ~~~~~~~~~~~~~~~~~~~~~~~~~~
764  const pointMesh& pMesh = pointMesh::New(mesh);
765 
766  PtrList<pointScalarField> pointScalarFields;
767  readFields(pMesh, objects, pointScalarFields, false);
768  PtrList<pointVectorField> pointVectorFields;
769  readFields(pMesh, objects, pointVectorFields, false);
770  PtrList<pointSphericalTensorField> pointSphericalTensorFields;
771  readFields(pMesh, objects, pointSphericalTensorFields, false);
772  PtrList<pointSymmTensorField> pointSymmTensorFields;
773  readFields(pMesh, objects, pointSymmTensorFields, false);
774  PtrList<pointTensorField> pointTensorFields;
775  readFields(pMesh, objects, pointTensorFields, false);
776 
777 
778  // Construct the Lagrangian fields
779  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
780 
781  fileNameList cloudDirs
782  (
784  (
785  runTime.timePath()/cloud::prefix,
786  fileName::DIRECTORY
787  )
788  );
789 
790  // Particles
791  PtrList<Cloud<indexedParticle>> lagrangianPositions
792  (
793  cloudDirs.size()
794  );
795  // Particles per cell
796  PtrList<List<SLList<indexedParticle*>*>> cellParticles
797  (
798  cloudDirs.size()
799  );
800 
801  PtrList<PtrList<labelIOField>> lagrangianLabelFields
802  (
803  cloudDirs.size()
804  );
805  PtrList<PtrList<labelFieldCompactIOField>>
806  lagrangianLabelFieldFields
807  (
808  cloudDirs.size()
809  );
810  PtrList<PtrList<scalarIOField>> lagrangianScalarFields
811  (
812  cloudDirs.size()
813  );
814  PtrList<PtrList<scalarFieldCompactIOField>>
815  lagrangianScalarFieldFields
816  (
817  cloudDirs.size()
818  );
819  PtrList<PtrList<vectorIOField>> lagrangianVectorFields
820  (
821  cloudDirs.size()
822  );
823  PtrList<PtrList<vectorFieldCompactIOField>>
824  lagrangianVectorFieldFields
825  (
826  cloudDirs.size()
827  );
828  PtrList<PtrList<sphericalTensorIOField>>
829  lagrangianSphericalTensorFields
830  (
831  cloudDirs.size()
832  );
833  PtrList<PtrList<sphericalTensorFieldCompactIOField>>
834  lagrangianSphericalTensorFieldFields(cloudDirs.size());
835  PtrList<PtrList<symmTensorIOField>> lagrangianSymmTensorFields
836  (
837  cloudDirs.size()
838  );
839  PtrList<PtrList<symmTensorFieldCompactIOField>>
840  lagrangianSymmTensorFieldFields
841  (
842  cloudDirs.size()
843  );
844  PtrList<PtrList<tensorIOField>> lagrangianTensorFields
845  (
846  cloudDirs.size()
847  );
848  PtrList<PtrList<tensorFieldCompactIOField>>
849  lagrangianTensorFieldFields
850  (
851  cloudDirs.size()
852  );
853 
854  label cloudI = 0;
855 
856  for (const fileName& cloudDir : cloudDirs)
857  {
858  IOobjectList cloudObjects
859  (
860  mesh,
861  runTime.timeName(),
862  cloud::prefix/cloudDir,
863  IOobject::MUST_READ,
864  IOobject::NO_WRITE,
865  false
866  );
867 
868  // Note: look up "positions" for backwards compatibility
869  if
870  (
871  cloudObjects.found("coordinates")
872  || cloudObjects.found("positions")
873  )
874  {
875  // Read lagrangian particles
876  // ~~~~~~~~~~~~~~~~~~~~~~~~~
877 
878  Info<< "Identified lagrangian data set: "
879  << cloudDir << endl;
880 
881  lagrangianPositions.set
882  (
883  cloudI,
884  new Cloud<indexedParticle>
885  (
886  mesh,
887  cloudDir,
888  false
889  )
890  );
891 
892 
893  // Sort particles per cell
894  // ~~~~~~~~~~~~~~~~~~~~~~~
895 
896  cellParticles.set
897  (
898  cloudI,
899  new List<SLList<indexedParticle*>*>
900  (
901  mesh.nCells(),
902  static_cast<SLList<indexedParticle*>*>(nullptr)
903  )
904  );
905 
906  label i = 0;
907 
908  for (indexedParticle& p : lagrangianPositions[cloudI])
909  {
910  p.index() = i++;
911 
912  label celli = p.cell();
913 
914  // Check
915  if (celli < 0 || celli >= mesh.nCells())
916  {
918  << "Illegal cell number " << celli
919  << " for particle with index "
920  << p.index()
921  << " at position "
922  << p.position() << nl
923  << "Cell number should be between 0 and "
924  << mesh.nCells()-1 << nl
925  << "On this mesh the particle should"
926  << " be in cell "
927  << mesh.findCell(p.position())
928  << exit(FatalError);
929  }
930 
931  if (!cellParticles[cloudI][celli])
932  {
933  cellParticles[cloudI][celli] =
934  new SLList<indexedParticle*>();
935  }
936 
937  cellParticles[cloudI][celli]->append(&p);
938  }
939 
940  // Read fields
941  // ~~~~~~~~~~~
942 
943  IOobjectList lagrangianObjects
944  (
945  mesh,
946  runTime.timeName(),
947  cloud::prefix/cloudDirs[cloudI],
948  IOobject::MUST_READ,
949  IOobject::NO_WRITE,
950  false
951  );
952 
954  (
955  cloudI,
956  lagrangianObjects,
957  lagrangianLabelFields
958  );
959 
960  lagrangianFieldDecomposer::readFieldFields
961  (
962  cloudI,
963  lagrangianObjects,
964  lagrangianLabelFieldFields
965  );
966 
968  (
969  cloudI,
970  lagrangianObjects,
971  lagrangianScalarFields
972  );
973 
974  lagrangianFieldDecomposer::readFieldFields
975  (
976  cloudI,
977  lagrangianObjects,
978  lagrangianScalarFieldFields
979  );
980 
982  (
983  cloudI,
984  lagrangianObjects,
985  lagrangianVectorFields
986  );
987 
988  lagrangianFieldDecomposer::readFieldFields
989  (
990  cloudI,
991  lagrangianObjects,
992  lagrangianVectorFieldFields
993  );
994 
996  (
997  cloudI,
998  lagrangianObjects,
999  lagrangianSphericalTensorFields
1000  );
1001 
1002  lagrangianFieldDecomposer::readFieldFields
1003  (
1004  cloudI,
1005  lagrangianObjects,
1006  lagrangianSphericalTensorFieldFields
1007  );
1008 
1010  (
1011  cloudI,
1012  lagrangianObjects,
1013  lagrangianSymmTensorFields
1014  );
1015 
1016  lagrangianFieldDecomposer::readFieldFields
1017  (
1018  cloudI,
1019  lagrangianObjects,
1020  lagrangianSymmTensorFieldFields
1021  );
1022 
1024  (
1025  cloudI,
1026  lagrangianObjects,
1027  lagrangianTensorFields
1028  );
1029 
1030  lagrangianFieldDecomposer::readFieldFields
1031  (
1032  cloudI,
1033  lagrangianObjects,
1034  lagrangianTensorFieldFields
1035  );
1036 
1037  cloudI++;
1038  }
1039  }
1040 
1041  lagrangianPositions.setSize(cloudI);
1042  cellParticles.setSize(cloudI);
1043  lagrangianLabelFields.setSize(cloudI);
1044  lagrangianLabelFieldFields.setSize(cloudI);
1045  lagrangianScalarFields.setSize(cloudI);
1046  lagrangianScalarFieldFields.setSize(cloudI);
1047  lagrangianVectorFields.setSize(cloudI);
1048  lagrangianVectorFieldFields.setSize(cloudI);
1049  lagrangianSphericalTensorFields.setSize(cloudI);
1050  lagrangianSphericalTensorFieldFields.setSize(cloudI);
1051  lagrangianSymmTensorFields.setSize(cloudI);
1052  lagrangianSymmTensorFieldFields.setSize(cloudI);
1053  lagrangianTensorFields.setSize(cloudI);
1054  lagrangianTensorFieldFields.setSize(cloudI);
1055 
1056  Info<< endl;
1057 
1058  // split the fields over processors
1059  for (label proci = 0; proci < mesh.nProcs(); ++proci)
1060  {
1061  Info<< "Processor " << proci << ": field transfer" << endl;
1062 
1063 
1064  // open the database
1065  if (!processorDbList.set(proci))
1066  {
1067  processorDbList.set
1068  (
1069  proci,
1070  new Time
1071  (
1072  Time::controlDictName,
1073  args.rootPath(),
1074  args.caseName()
1075  / ("processor" + Foam::name(proci))
1076  )
1077  );
1078  }
1079  Time& processorDb = processorDbList[proci];
1080 
1081 
1082  processorDb.setTime(runTime);
1083 
1084  // read the mesh
1085  if (!procMeshList.set(proci))
1086  {
1087  procMeshList.set
1088  (
1089  proci,
1090  new fvMesh
1091  (
1092  IOobject
1093  (
1094  regionName,
1095  processorDb.timeName(),
1096  processorDb
1097  )
1098  )
1099  );
1100  }
1101  const fvMesh& procMesh = procMeshList[proci];
1102 
1103  const labelIOList& faceProcAddressing = procAddressing
1104  (
1105  procMeshList,
1106  proci,
1107  "faceProcAddressing",
1108  faceProcAddressingList
1109  );
1110 
1111  const labelIOList& cellProcAddressing = procAddressing
1112  (
1113  procMeshList,
1114  proci,
1115  "cellProcAddressing",
1116  cellProcAddressingList
1117  );
1118 
1119  const labelIOList& boundaryProcAddressing = procAddressing
1120  (
1121  procMeshList,
1122  proci,
1123  "boundaryProcAddressing",
1124  boundaryProcAddressingList
1125  );
1126 
1127 
1128  // FV fields
1129  {
1130  if (!fieldDecomposerList.set(proci))
1131  {
1132  fieldDecomposerList.set
1133  (
1134  proci,
1135  new fvFieldDecomposer
1136  (
1137  mesh,
1138  procMesh,
1140  cellProcAddressing,
1141  boundaryProcAddressing
1142  )
1143  );
1144  }
1145  const fvFieldDecomposer& fieldDecomposer =
1146  fieldDecomposerList[proci];
1147 
1148  fieldDecomposer.decomposeFields(volScalarFields);
1149  fieldDecomposer.decomposeFields(volVectorFields);
1150  fieldDecomposer.decomposeFields
1151  (
1152  volSphericalTensorFields
1153  );
1154  fieldDecomposer.decomposeFields(volSymmTensorFields);
1155  fieldDecomposer.decomposeFields(volTensorFields);
1156 
1157  fieldDecomposer.decomposeFields(surfaceScalarFields);
1158  fieldDecomposer.decomposeFields(surfaceVectorFields);
1159  fieldDecomposer.decomposeFields
1160  (
1161  surfaceSphericalTensorFields
1162  );
1163  fieldDecomposer.decomposeFields
1164  (
1165  surfaceSymmTensorFields
1166  );
1167  fieldDecomposer.decomposeFields(surfaceTensorFields);
1168 
1169  if (times.size() == 1)
1170  {
1171  // Clear cached decomposer
1172  fieldDecomposerList.set(proci, nullptr);
1173  }
1174  }
1175 
1176  // Dimensioned fields
1177  {
1178  if (!dimFieldDecomposerList.set(proci))
1179  {
1180  dimFieldDecomposerList.set
1181  (
1182  proci,
1183  new dimFieldDecomposer
1184  (
1185  mesh,
1186  procMesh,
1188  cellProcAddressing
1189  )
1190  );
1191  }
1192  const dimFieldDecomposer& dimDecomposer =
1193  dimFieldDecomposerList[proci];
1194 
1195  dimDecomposer.decomposeFields(dimScalarFields);
1196  dimDecomposer.decomposeFields(dimVectorFields);
1197  dimDecomposer.decomposeFields(dimSphericalTensorFields);
1198  dimDecomposer.decomposeFields(dimSymmTensorFields);
1199  dimDecomposer.decomposeFields(dimTensorFields);
1200 
1201  if (times.size() == 1)
1202  {
1203  dimFieldDecomposerList.set(proci, nullptr);
1204  }
1205  }
1206 
1207 
1208  // Point fields
1209  if
1210  (
1211  pointScalarFields.size()
1212  || pointVectorFields.size()
1213  || pointSphericalTensorFields.size()
1214  || pointSymmTensorFields.size()
1215  || pointTensorFields.size()
1216  )
1217  {
1218  const labelIOList& pointProcAddressing = procAddressing
1219  (
1220  procMeshList,
1221  proci,
1222  "pointProcAddressing",
1223  pointProcAddressingList
1224  );
1225 
1226  const pointMesh& procPMesh = pointMesh::New(procMesh);
1227 
1228  if (!pointFieldDecomposerList.set(proci))
1229  {
1230  pointFieldDecomposerList.set
1231  (
1232  proci,
1233  new pointFieldDecomposer
1234  (
1235  pMesh,
1236  procPMesh,
1237  pointProcAddressing,
1238  boundaryProcAddressing
1239  )
1240  );
1241  }
1242  const pointFieldDecomposer& pointDecomposer =
1243  pointFieldDecomposerList[proci];
1244 
1245  pointDecomposer.decomposeFields(pointScalarFields);
1246  pointDecomposer.decomposeFields(pointVectorFields);
1247  pointDecomposer.decomposeFields
1248  (
1249  pointSphericalTensorFields
1250  );
1251  pointDecomposer.decomposeFields(pointSymmTensorFields);
1252  pointDecomposer.decomposeFields(pointTensorFields);
1253 
1254 
1255  if (times.size() == 1)
1256  {
1257  pointProcAddressingList.set(proci, nullptr);
1258  pointFieldDecomposerList.set(proci, nullptr);
1259  }
1260  }
1261 
1262 
1263  // If there is lagrangian data write it out
1264  forAll(lagrangianPositions, cloudI)
1265  {
1266  if (lagrangianPositions[cloudI].size())
1267  {
1268  lagrangianFieldDecomposer fieldDecomposer
1269  (
1270  mesh,
1271  procMesh,
1273  cellProcAddressing,
1274  cloudDirs[cloudI],
1275  lagrangianPositions[cloudI],
1276  cellParticles[cloudI]
1277  );
1278 
1279  // Lagrangian fields
1280  {
1281  fieldDecomposer.decomposeFields
1282  (
1283  cloudDirs[cloudI],
1284  lagrangianLabelFields[cloudI]
1285  );
1286  fieldDecomposer.decomposeFieldFields
1287  (
1288  cloudDirs[cloudI],
1289  lagrangianLabelFieldFields[cloudI]
1290  );
1291  fieldDecomposer.decomposeFields
1292  (
1293  cloudDirs[cloudI],
1294  lagrangianScalarFields[cloudI]
1295  );
1296  fieldDecomposer.decomposeFieldFields
1297  (
1298  cloudDirs[cloudI],
1299  lagrangianScalarFieldFields[cloudI]
1300  );
1301  fieldDecomposer.decomposeFields
1302  (
1303  cloudDirs[cloudI],
1304  lagrangianVectorFields[cloudI]
1305  );
1306  fieldDecomposer.decomposeFieldFields
1307  (
1308  cloudDirs[cloudI],
1309  lagrangianVectorFieldFields[cloudI]
1310  );
1311  fieldDecomposer.decomposeFields
1312  (
1313  cloudDirs[cloudI],
1314  lagrangianSphericalTensorFields[cloudI]
1315  );
1316  fieldDecomposer.decomposeFieldFields
1317  (
1318  cloudDirs[cloudI],
1319  lagrangianSphericalTensorFieldFields[cloudI]
1320  );
1321  fieldDecomposer.decomposeFields
1322  (
1323  cloudDirs[cloudI],
1324  lagrangianSymmTensorFields[cloudI]
1325  );
1326  fieldDecomposer.decomposeFieldFields
1327  (
1328  cloudDirs[cloudI],
1329  lagrangianSymmTensorFieldFields[cloudI]
1330  );
1331  fieldDecomposer.decomposeFields
1332  (
1333  cloudDirs[cloudI],
1334  lagrangianTensorFields[cloudI]
1335  );
1336  fieldDecomposer.decomposeFieldFields
1337  (
1338  cloudDirs[cloudI],
1339  lagrangianTensorFieldFields[cloudI]
1340  );
1341  }
1342  }
1343  }
1344 
1345  // Decompose the "uniform" directory in the time region
1346  // directory
1347  decomposeUniform(copyUniform, mesh, processorDb, regionDir);
1348 
1349  // For a multi-region case, also decompose the "uniform"
1350  // directory in the time directory
1351  if (regionNames.size() > 1 && regioni == 0)
1352  {
1353  decomposeUniform(copyUniform, mesh, processorDb);
1354  }
1355 
1356  // We have cached all the constant mesh data for the current
1357  // processor. This is only important if running with
1358  // multiple times, otherwise it is just extra storage.
1359  if (times.size() == 1)
1360  {
1361  boundaryProcAddressingList.set(proci, nullptr);
1362  cellProcAddressingList.set(proci, nullptr);
1363  faceProcAddressingList.set(proci, nullptr);
1364  procMeshList.set(proci, nullptr);
1365  processorDbList.set(proci, nullptr);
1366  }
1367  }
1368 
1369  // Finite area mesh and field decomposition
1370 
1371  IOobject faMeshBoundaryIOobj
1372  (
1373  "faBoundary",
1374  mesh.time().findInstance
1375  (
1376  mesh.dbDir()/polyMesh::meshSubDir,
1377  "boundary"
1378  ),
1379  faMesh::meshSubDir,
1380  mesh,
1381  IOobject::READ_IF_PRESENT,
1382  IOobject::NO_WRITE
1383  );
1384 
1385 
1386  if (faMeshBoundaryIOobj.typeHeaderOk<faBoundaryMesh>(true))
1387  {
1388  Info << "\nFinite area mesh decomposition" << endl;
1389 
1390  faMeshDecomposition aMesh(mesh);
1391 
1392  aMesh.decomposeMesh();
1393 
1394  aMesh.writeDecomposition();
1395 
1396 
1397  // Construct the area fields
1398  // ~~~~~~~~~~~~~~~~~~~~~~~~
1399  PtrList<areaScalarField> areaScalarFields;
1400  readFields(aMesh, objects, areaScalarFields);
1401 
1402  PtrList<areaVectorField> areaVectorFields;
1403  readFields(aMesh, objects, areaVectorFields);
1404 
1405  PtrList<areaSphericalTensorField> areaSphericalTensorFields;
1406  readFields(aMesh, objects, areaSphericalTensorFields);
1407 
1408  PtrList<areaSymmTensorField> areaSymmTensorFields;
1409  readFields(aMesh, objects, areaSymmTensorFields);
1410 
1411  PtrList<areaTensorField> areaTensorFields;
1412  readFields(aMesh, objects, areaTensorFields);
1413 
1414 
1415  // Construct the edge fields
1416  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1417  PtrList<edgeScalarField> edgeScalarFields;
1418  readFields(aMesh, objects, edgeScalarFields);
1419 
1420  Info << endl;
1421 
1422  // Split the fields over processors
1423  for (label procI = 0; procI < mesh.nProcs(); procI++)
1424  {
1425  Info<< "Processor " << procI
1426  << ": finite area field transfer" << endl;
1427 
1428  // open the database
1429  Time processorDb
1430  (
1431  Time::controlDictName,
1432  args.rootPath(),
1433  args.caseName()
1434  / ("processor" + Foam::name(procI))
1435  );
1436 
1437  processorDb.setTime(runTime);
1438 
1439  // Read the mesh
1440  fvMesh procFvMesh
1441  (
1442  IOobject
1443  (
1444  regionName,
1445  processorDb.timeName(),
1446  processorDb
1447  )
1448  );
1449 
1450  faMesh procMesh(procFvMesh);
1451 
1452  // // Does not work. HJ, 15/Aug/2017
1453  // const labelIOList& faceProcAddressing =
1454  // procAddressing
1455  // (
1456  // procMeshList,
1457  // procI,
1458  // "faceProcAddressing",
1459  // faceProcAddressingList
1460  // );
1461 
1462  // const labelIOList& boundaryProcAddressing =
1463  // procAddressing
1464  // (
1465  // procMeshList,
1466  // procI,
1467  // "boundaryProcAddressing",
1468  // boundaryProcAddressingList
1469  // );
1470 
1472  (
1473  IOobject
1474  (
1475  "faceProcAddressing",
1476  "constant",
1477  procMesh.meshSubDir,
1478  procFvMesh,
1479  IOobject::MUST_READ,
1480  IOobject::NO_WRITE
1481  )
1482  );
1483 
1484  labelIOList boundaryProcAddressing
1485  (
1486  IOobject
1487  (
1488  "boundaryProcAddressing",
1489  "constant",
1490  procMesh.meshSubDir,
1491  procFvMesh,
1492  IOobject::MUST_READ,
1493  IOobject::NO_WRITE
1494  )
1495  );
1496 
1497  // FA fields
1498  if
1499  (
1500  areaScalarFields.size()
1501  || areaVectorFields.size()
1502  || areaSphericalTensorFields.size()
1503  || areaSymmTensorFields.size()
1504  || areaTensorFields.size()
1505  || edgeScalarFields.size()
1506  )
1507  {
1508  labelIOList edgeProcAddressing
1509  (
1510  IOobject
1511  (
1512  "edgeProcAddressing",
1513  "constant",
1514  procMesh.meshSubDir,
1515  procFvMesh,
1516  IOobject::MUST_READ,
1517  IOobject::NO_WRITE
1518  )
1519  );
1520 
1521  faFieldDecomposer fieldDecomposer
1522  (
1523  aMesh,
1524  procMesh,
1525  edgeProcAddressing,
1527  boundaryProcAddressing
1528  );
1529 
1530  fieldDecomposer.decomposeFields(areaScalarFields);
1531  fieldDecomposer.decomposeFields(areaVectorFields);
1532  fieldDecomposer.decomposeFields
1533  (
1534  areaSphericalTensorFields
1535  );
1536  fieldDecomposer.decomposeFields
1537  (
1538  areaSymmTensorFields
1539  );
1540  fieldDecomposer.decomposeFields(areaTensorFields);
1541 
1542  fieldDecomposer.decomposeFields(edgeScalarFields);
1543  }
1544  }
1545  }
1546  }
1547  }
1548  }
1549 
1550  Info<< "\nEnd\n" << endl;
1551 
1552  return 0;
1553 }
1554 
1555 
1556 // ************************************************************************* //
Foam::IOobject::NO_WRITE
Definition: IOobject.H:130
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
runTime
engineTime & runTime
Definition: createEngineTime.H:13
faceProcAddressing
PtrList< labelIOList > & faceProcAddressing
Definition: checkFaceAddressingComp.H:9
OSspecific.H
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Dimensionless.
Definition: dimensionSets.H:50
Foam::exists
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: MSwindows.C:625
faCFD.H
regionProperties.H
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:107
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:785
Foam::fileOperation::flush
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
Definition: fileOperation.C:977
Foam::fileOperation::filePath
virtual fileName filePath(const bool checkGlobal, const IOobject &, const word &typeName, const bool search=true) const =0
Search for an object. checkGlobal : also check undecomposed case.
tensorIOField.H
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1170
IOobjectList.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
scalarIOField.H
Foam::labelIOList
IOList< label > labelIOList
Label container classes.
Definition: labelIOList.H:44
Foam::instantList
List< instant > instantList
List of instants.
Definition: instantList.H:44
Foam::argList::get
T get(const label index) const
Get a value from the argument at index.
Definition: argListI.H:257
Foam::argList::rootPath
const fileName & rootPath() const
Return root path.
Definition: argListI.H:63
domainDecomposition.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
tensorFieldIOField.H
scalarFieldIOField.H
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:59
aMesh
faMesh aMesh(mesh)
Foam::flush
Ostream & flush(Ostream &os)
Flush stream.
Definition: Ostream.H:342
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
domainDecompositionDryRun.H
faMeshDecomposition.H
vectorFieldIOField.H
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
dimFieldDecomposer.H
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::Time::timePath
fileName timePath() const
Return current time path.
Definition: Time.H:375
Foam::fileOperation::nProcs
virtual label nProcs(const fileName &dir, const fileName &local="") const
Get number of processor directories/results. Used for e.g.
Definition: fileOperation.C:915
addRegionOption.H
Foam::dimensionedScalar
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
Definition: dimensionedScalarFwd.H:43
Foam::volScalarField
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:57
Foam::fileOperation::rmDir
virtual bool rmDir(const fileName &dir, const bool silent=false) const =0
Remove a directory and its contents.
labelFieldIOField.H
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
fvFieldDecomposer.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::readFields
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject * > &storedObjects)
Read the selected GeometricFields of the templated type.
Definition: ReadFieldsTemplates.C:312
Foam::fileOperation::ln
virtual bool ln(const fileName &src, const fileName &dst) const =0
Create a softlink. dst should not exist. Returns true if.
Foam::fileNameList
List< fileName > fileNameList
A List of fileNames.
Definition: fileNameList.H:58
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
vectorIOField.H
Foam::chDir
bool chDir(const fileName &dir)
Change current directory to the one specified and return true on success.
Definition: MSwindows.C:500
setRootCase.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::flatOutput
FlatOutput< Container > flatOutput(const Container &obj, label len=0)
Global flatOutput function.
Definition: FlatOutput.H:85
symmTensorFieldIOField.H
Foam::fileOperation::exists
bool exists(IOobject &io) const
Does ioobject exist. Is either a directory (empty name()) or.
Definition: fileOperation.C:376
pointFieldDecomposer.H
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
createTime.H
Foam::List::set
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:325
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:309
symmTensorIOField.H
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:248
Foam::fileOperation::cp
virtual bool cp(const fileName &src, const fileName &dst, const bool followLink=true) const =0
Copy, recursively if necessary, the source to the destination.
Foam::cwd
fileName cwd()
The physical or logical current working directory path name.
Definition: MSwindows.C:468
fvCFD.H
decompositionModel.H
Foam::argList::caseName
const fileName & caseName() const
Return case name (parallel run) or global case (serial run)
Definition: argListI.H:69
sphericalTensorIOField.H
args
Foam::argList args(argc, argv)
Foam::mkDir
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:507
sphericalTensorFieldIOField.H
emptyFaPatch.H
Foam::readDir
fileNameList readDir(const fileName &directory, const fileName::Type type=fileName::FILE, const bool filtergz=true, const bool followLink=true)
Read a directory and return the entries as a fileName List.
Definition: MSwindows.C:707
lagrangianFieldDecomposer.H
pointFields.H
labelIOField.H
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157
Foam::IOobject::MUST_READ
Definition: IOobject.H:120
faFieldDecomposer.H