fileOperation.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) 2017-2018 OpenFOAM Foundation
9  Copyright (C) 2019-2021 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 \*---------------------------------------------------------------------------*/
28 
29 #include "fileOperation.H"
31 #include "regIOobject.H"
32 #include "argList.H"
33 #include "HashSet.H"
34 #include "objectRegistry.H"
35 #include "decomposedBlockData.H"
36 #include "polyMesh.H"
37 #include "registerSwitch.H"
38 #include "Time.H"
39 #include "ITstream.H"
40 #include <cerrno>
41 #include <cinttypes>
42 
43 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
44 
45 namespace Foam
46 {
47  defineTypeNameAndDebug(fileOperation, 0);
48  defineRunTimeSelectionTable(fileOperation, word);
49 
51  (
52  debug::optimisationSwitches().getOrAdd<word>
53  (
54  "fileHandler",
55  //Foam::fileOperations::uncollatedFileOperation::typeName,
56  "uncollated",
58  )
59  );
60 }
61 
64 ({
65  { fileOperation::NOTFOUND, "notFound" },
66  { fileOperation::ABSOLUTE, "absolute" },
67  { fileOperation::OBJECT, "objectPath" },
68  { fileOperation::WRITEOBJECT, "writeObject" },
69  { fileOperation::PROCUNCOLLATED, "uncollatedProc" },
70  { fileOperation::PROCBASEOBJECT, "globalProc" },
71  { fileOperation::PROCOBJECT, "localProc" },
72  { fileOperation::PARENTOBJECT, "parentObjectPath" },
73  { fileOperation::FINDINSTANCE, "findInstance" },
74  { fileOperation::PROCUNCOLLATEDINSTANCE, "uncollatedProcInstance" },
75  { fileOperation::PROCBASEINSTANCE, "globalProcInstance" },
76  { fileOperation::PROCINSTANCE, "localProcInstance" }
77 });
78 
79 
81 
83 
84 
85 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
86 
87 namespace
88 {
89 
90 // Need to parse the numbers
91 // from "processors(\d+)" and
92 // from "processors(\d+)_(\d+)-(\d+)"
93 //
94 // Receive the string matching "^(\d+)(?:_(\d+)-(\d+))?/?$"
95 //
96 // \1 = numProcs
97 // \2 = firstProc
98 // \3 = lastProc
99 //
100 // Return true on success and set parameters numProcs and group (size,start)
101 //
102 // Use low-level C-string to integer parsing to drive the sequence.
103 //
104 // For simplicity, also skip INT_MAX checks everywhere but check for
105 // - (errno) for success
106 // - (nptr == endptr) for leading junk
107 // - (*endptr != endChar) for trailing junk
108 // - skip INT_MAX checks as being too pessimistic
109 
110 static bool parseProcsNumRange
111 (
112  const std::string str,
113  int& numProcs,
115 )
116 {
117  const char * nptr = str.c_str();
118  char *endptr = nullptr;
119 
120  // 1. numProcs
121  errno = 0;
122  intmax_t parsed = std::strtoimax(nptr, &endptr, 10);
123  if (errno || nptr == endptr) return false; // bad parse
124 
125  const int nProcs = int(parsed);
126 
127  // End of string? Then no range and we are done.
128  if (*endptr == '\0')
129  {
130  numProcs = nProcs;
131  return true;
132  }
133 
134  // Parse point at start of range ('_' character)?
135  if (*endptr != '_') return false;
136  nptr = ++endptr;
137 
138 
139  // 2. firstProc
140  errno = 0;
141  parsed = std::strtoimax(nptr, &endptr, 10);
142  if (errno || nptr == endptr) return false; // bad parse
143 
144  const int firstProc = int(parsed);
145 
146  // Parse point at range separator ('-' character)?
147  if (*endptr != '-') return false;
148  nptr = ++endptr;
149 
150 
151  // 3. lastProc
152  errno = 0;
153  parsed = std::strtoimax(nptr, &endptr, 10);
154  if (errno || nptr == endptr) return false; // bad parse
155 
156  const int lastProc = int(parsed);
157 
158 
159  if
160  (
161  // Parse point at end of string
162  (*endptr == '\0')
163 
164  // Input plausibility
165  // Accept nProcs == 0 in case that becomes useful in the future
166  && (nProcs >= 0 && firstProc >= 0 && firstProc <= lastProc)
167  )
168  {
169  numProcs = nProcs;
170 
171  // Convert first/last to start/size
172  group.reset(firstProc, lastProc-firstProc+1);
173 
174  return true;
175  }
176 
177  return false;
178 }
179 
180 } // End anonymous namespace
181 
182 
183 #if 0
184 
185 // Sorting of processor directories
186 #include "stringOpsSort.H"
187 namespace
188 {
189 
190 // Sort processor directory names (natural order)
191 // - not strictly necessary
192 void sortProcessorDirs(Foam::UList<Foam::fileOperation::dirIndex>& dirs)
193 {
194  if (dirs.size() > 1)
195  {
196  std::stable_sort
197  (
198  dirs.begin(),
199  dirs.end(),
200  []
201  (
204  ) -> bool
205  {
206  return
208  (
209  a.first(),
210  b.first()
211  ) < 0;
212  }
213  );
214  }
215 }
216 
217 } // End anonymous namespace
218 #endif
219 
220 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
221 
223 {
224  labelList ranks;
225 
226  ITstream is(Foam::getEnv("FOAM_IORANKS"));
227  if (!is.empty())
228  {
229  is >> ranks;
230  }
231 
232  return ranks;
233 }
234 
235 
238 (
239  const fileNameList& dirEntries,
240  const word& constantName
241 )
242 {
243  // Check for "constant"
244  bool haveConstant = false;
245 
246  if (!constantName.empty())
247  {
248  for (const fileName& dirName : dirEntries)
249  {
250  if (dirName == constantName)
251  {
252  haveConstant = true;
253  break;
254  }
255  }
256  }
257 
258  instantList times(dirEntries.size() + 1);
259  label nTimes = 0;
260 
261  if (haveConstant)
262  {
263  times[nTimes].value() = 0;
264  times[nTimes].name() = constantName;
265  ++nTimes;
266  }
267 
268  // Parse directory entries for scalar values
269  for (const fileName& dirName : dirEntries)
270  {
271  if (readScalar(dirName, times[nTimes].value()))
272  {
273  times[nTimes].name() = dirName;
274  ++nTimes;
275  }
276  }
277 
278  times.resize(nTimes);
279 
280  if (haveConstant)
281  {
282  if (nTimes > 2)
283  {
284  std::sort(&times[1], times.end(), instant::less());
285  }
286  }
287  else if (nTimes > 1)
288  {
289  std::sort(times.begin(), times.end(), instant::less());
290  }
291 
292  return times;
293 }
294 
295 
296 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
297 
299 {
300  if (!monitorPtr_)
301  {
302  monitorPtr_.reset
303  (
304  new fileMonitor
305  (
308  )
309  );
310  }
311  return *monitorPtr_;
312 }
313 
314 
316 (
317  const instantList& extraTimes,
318  const word& constantName,
319  instantList& times
320 )
321 {
322  if (extraTimes.size())
323  {
324  const bool haveConstant =
325  (
326  times.size()
327  && times[0].name() == constantName
328  );
329 
330  const bool haveExtraConstant =
331  (
332  extraTimes.size()
333  && extraTimes[0].name() == constantName
334  );
335 
336  // Combine times
337  instantList combinedTimes(times.size()+extraTimes.size());
338  label sz = 0;
339  label extrai = 0;
340  if (haveExtraConstant)
341  {
342  extrai = 1;
343  if (!haveConstant)
344  {
345  combinedTimes[sz++] = extraTimes[0]; // constant
346  }
347  }
348  forAll(times, i)
349  {
350  combinedTimes[sz++] = times[i];
351  }
352  for (; extrai < extraTimes.size(); extrai++)
353  {
354  combinedTimes[sz++] = extraTimes[extrai];
355  }
356  combinedTimes.setSize(sz);
357  times.transfer(combinedTimes);
358 
359  // Sort
360  if (times.size() > 1)
361  {
362  label starti = 0;
363  if (times[0].name() == constantName)
364  {
365  starti = 1;
366  }
367  std::sort(&times[starti], times.end(), instant::less());
368 
369  // Filter out duplicates
370  label newi = starti+1;
371  for (label i = newi; i < times.size(); i++)
372  {
373  if (times[i].value() != times[i-1].value())
374  {
375  if (newi != i)
376  {
377  times[newi] = times[i];
378  }
379  newi++;
380  }
381  }
382 
383  times.setSize(newi);
384  }
385  }
386 }
387 
388 
390 {
391  return (isFile ? Foam::isFile(f) : Foam::isDir(f));
392 }
393 
394 
397 (
398  const fileName& fName,
399  const bool syncPar
400 ) const
401 {
402  // If path is local to a processor (e.g. contains 'processor2')
403  // find the corresponding actual processor directory (e.g. 'processors4')
404  // and index (2)
405 
406  fileName path, pDir, local;
408  label numProcs;
409  const label proci =
410  splitProcessorPath(fName, path, pDir, local, group, numProcs);
411 
412  if (proci != -1)
413  {
414  const fileName procPath(path/pDir);
415 
416  const auto iter = procsDirs_.cfind(procPath);
417 
418  if (iter.found())
419  {
420  return iter.val();
421  }
422 
423  DynamicList<dirIndex> procDirs;
424  fileNameList dirEntries;
425 
426  // Read all directories to see any beginning with processor
427  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
428 
429  // Note: use parallel synchronised reading so cache will be same
430  // order on all processors
431 
432  const bool readDirMasterOnly
433  (
434  Pstream::parRun() && !distributed()
435  &&
436  (
439  )
440  );
441 
442  // The above selection excludes masterUncollated, which uses inotify or
443  // timeStamp but provides its own internals for readDir() anyhow.
444 
445  if (readDirMasterOnly)
446  {
447  // Parallel and non-distributed
448  // Read on master only and send to subProcs
449 
450  if (Pstream::master(comm_))
451  {
452  dirEntries = Foam::readDir(path, fileName::Type::DIRECTORY);
453 
454  DebugInfo
455  << "readDir on master: send " << dirEntries.size()
456  << " names to sub-processes" << endl;
457  }
458 
459  Pstream::scatter(dirEntries, Pstream::msgType(), comm_);
460  }
461  else
462  {
463  // Serial or distributed roots.
464  // Handle readDir() with virtual method
465 
466  if (debug)
467  {
468  Pout<< "readDir without special master/send treatment"
469  << endl;
470  }
471 
472  dirEntries = readDir(path, fileName::Type::DIRECTORY);
473  }
474 
475  // Extract info from processorN or processorsNN
476  // - highest processor number
477  // - directory+offset containing data for proci
478 
479  label nProcs = 0;
480  for (const fileName& dirN : dirEntries)
481  {
482  // Analyse directory name
483  fileName rp, rd, rl;
484  label rNum;
485  const label readProci =
486  splitProcessorPath(dirN, rp, rd, rl, group, rNum);
487 
488  nProcs = max(nProcs, readProci+1);
489 
490  Tuple2<pathType, int> pathTypeIdx(pathType::NOTFOUND, 0);
491 
492  if (proci == readProci)
493  {
494  // Found "processorN"
495  pathTypeIdx.first() = pathType::PROCUNCOLLATED;
496  }
497  else if (rNum != -1)
498  {
499  // "processorsNN" or "processorsNN_start-end"
500  nProcs = max(nProcs, rNum);
501 
502  if (group.empty())
503  {
504  // "processorsNN"
505 
506  if (proci < rNum)
507  {
508  // And it is also in range.
509  // Eg for "processors4": 3 is ok, 10 is not
510 
511  pathTypeIdx.first() = pathType::PROCBASEOBJECT;
512  pathTypeIdx.second() = proci;
513  }
514  }
515  else if (group.found(proci))
516  {
517  // "processorsNN_start-end"
518  // - save the local proc offset
519 
520  pathTypeIdx.first() = pathType::PROCOBJECT;
521  pathTypeIdx.second() = (proci - group.start());
522  }
523  }
524 
525  if (pathTypeIdx.first() != pathType::NOTFOUND)
526  {
527  procDirs.append(dirIndex(dirN, pathTypeIdx));
528  }
529  }
530 
531  // Global check of empty/exists.
532  // 1 : empty directory
533  // 2 : non-empty directory
534  // 3 : mixed empty/non-empty directory (after reduce)
535  // Combines andOp<bool>() and orOp<bool>() in single operation
536 
537  unsigned procDirsStatus = (procDirs.empty() ? 1u : 2u);
538 
539  if (debug)
540  {
541  Pout<< "fileOperation::lookupProcessorsPath " << procPath
542  << " detected:" << procDirs << endl;
543  }
544 
545  if (Pstream::parRun() && (!distributed() || syncPar))
546  {
547  reduce(procDirsStatus, bitOrOp<unsigned>()); // worldComm
548 
549  if (procDirsStatus == 3u)
550  {
551  // Mixed empty/exists for procDirs.
552  // Synthesize missing directory name (consistency in cache
553  // existence).
554  // Cannot reliably synthesize RANK-COLLATED, only COLLATED or
555  // UNCOLLATED.
556  //
557  // RANK-COLLATED should have been read from its corresponding
558  // master anyhow
559 
560  int flavour(pathType::PROCUNCOLLATED);
561  for (const dirIndex& pDir : procDirs)
562  {
563  flavour = max(flavour, int(pDir.second().first()));
564  }
565 
566  reduce(nProcs, maxOp<label>()); // worldComm
567  reduce(flavour, maxOp<int>()); // worldComm
568 
569  if (procDirs.empty())
570  {
571  Tuple2<pathType, int> pathTypeIdx(pathType(flavour), 0);
572 
573  if
574  (
575  pathTypeIdx.first() == pathType::PROCBASEOBJECT
576  && proci < nProcs
577  )
578  {
579  pathTypeIdx.second() = proci;
580 
581  procDirs.append
582  (
583  dirIndex
584  (
585  processorsBaseDir + Foam::name(nProcs),
586  pathTypeIdx
587  )
588  );
589  }
590  else
591  {
592  // - pathType::PROCUNCOLLATED
593  // - poor fallback for pathType::PROCOBJECT
594  // - out-of-range pathType::PROCBASEOBJECT
595 
596  procDirs.append
597  (
598  dirIndex
599  (
600  "processor" + Foam::name(proci),
601  pathTypeIdx
602  )
603  );
604  }
605 
606  if (debug)
607  {
608  Pout<< "fileOperation::lookupProcessorsPath "
609  << procPath
610  << " synthetic:" << procDirs << endl;
611  }
612  }
613  }
614  }
615  else if (!Pstream::parRun())
616  {
617  // Serial: use the number of decompositions (if found)
618  if (nProcs)
619  {
620  const_cast<fileOperation&>(*this).setNProcs(nProcs);
621  }
622  }
623 
624  // Sort processor directory names (natural order)
626 
627  if (procDirsStatus & 2u)
628  {
629  procsDirs_.insert(procPath, procDirs);
630 
631  // Make sure to return a reference
632  return procsDirs_[procPath];
633  }
634  }
635 
636  return refPtr<dirIndexList>::New();
637 }
638 
639 
642 {
643  // Use parallel synchronisation
644  return lookupAndCacheProcessorsPath(fName, true);
645 }
646 
647 
649 {
650  // Generate output filename for object
651  fileName objPath(objectPath(io, word::null));
652 
653  // Test for either directory or a (valid) file & IOobject
654  bool ok;
655  if (io.name().empty())
656  {
657  ok = isDir(objPath);
658  }
659  else
660  {
661  ok =
662  isFile(objPath)
663  && io.typeHeaderOk<IOList<label>>(false);// object with local scope
664  }
665 
666  if (!ok)
667  {
668  // Re-test with searched for objectPath. This is for backwards
669  // compatibility
670  fileName originalPath(filePath(io.objectPath()));
671  if (originalPath != objPath)
672  {
673  // Test for either directory or a (valid) file & IOobject
674  if (io.name().empty())
675  {
676  ok = isDir(originalPath);
677  }
678  else
679  {
680  ok =
681  isFile(originalPath)
682  && io.typeHeaderOk<IOList<label>>(false);
683  }
684  }
685  }
686 
687  return ok;
688 }
689 
690 
691 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
692 
694 (
695  const label comm,
696  const bool distributedRoots
697 )
698 :
699  comm_(comm),
700  distributed_(distributedRoots)
701 {}
702 
703 
706 (
707  const word& handlerType,
708  bool verbose
709 )
710 {
712  << "Constructing fileHandler" << endl;
713 
714  auto* ctorPtr = wordConstructorTable(handlerType);
715 
716  if (!ctorPtr)
717  {
719  (
720  "fileHandler",
721  handlerType,
722  *wordConstructorTablePtr_
723  ) << abort(FatalError);
724  }
725 
726  return autoPtr<fileOperation>(ctorPtr(verbose));
727 }
728 
729 
730 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
731 
732 bool Foam::fileOperation::distributed(bool on) const noexcept
733 {
734  bool old(distributed_);
735  distributed_ = on;
736  return old;
737 }
738 
739 
741 (
742  const IOobject& io,
743  const word& typeName
744 ) const
745 {
746  return io.objectPath();
747 }
748 
749 
751 (
752  const regIOobject& io,
753  IOstreamOption streamOpt,
754  const bool valid
755 ) const
756 {
757  if (valid)
758  {
759  const fileName pathName(io.objectPath());
760 
761  mkDir(pathName.path());
762 
763  autoPtr<OSstream> osPtr(NewOFstream(pathName, streamOpt));
764 
765  if (!osPtr)
766  {
767  return false;
768  }
769 
770  OSstream& os = *osPtr;
771 
772  // Update meta-data for current state
773  const_cast<regIOobject&>(io).updateMetaData();
774 
775  // If any of these fail, return (leave error handling to Ostream class)
776 
777  const bool ok =
778  (
779  os.good()
780  && io.writeHeader(os)
781  && io.writeData(os)
782  );
783 
784  if (ok)
785  {
787  }
788 
789  return ok;
790  }
791  return true;
792 }
793 
794 
796 {
797  if (debug)
798  {
799  Pout<< "fileOperation::filePath :" << " fName:" << fName << endl;
800  }
801 
802  fileName path, pDir, local;
804  label numProcs;
805  label proci =
806  splitProcessorPath(fName, path, pDir, local, group, numProcs);
807 
808  if (numProcs != -1)
809  {
810  WarningInFunction << "Filename is already adapted:" << fName << endl;
811  }
812 
813  // Give preference to processors variant
814  if (proci != -1)
815  {
816  // Get all processor directories
817  refPtr<dirIndexList> procDirs(lookupProcessorsPath(fName));
818  for (const dirIndex& dirIdx : procDirs())
819  {
820  const fileName& procDir = dirIdx.first();
821 
822  fileName collatedName(path/procDir/local);
823  if (exists(collatedName))
824  {
825  if (debug)
826  {
827  Pout<< "fileOperation::filePath : " << collatedName << endl;
828  }
829  return collatedName;
830  }
831  }
832  }
833 
834  if (exists(fName))
835  {
836  if (debug)
837  {
838  Pout<< "fileOperation::filePath : " << fName << endl;
839  }
840  return fName;
841  }
842 
843  if (debug)
844  {
845  Pout<< "fileOperation::filePath : Not found" << endl;
846  }
847  return fileName::null;
848 }
849 
850 
851 Foam::label Foam::fileOperation::addWatch(const fileName& fName) const
852 {
853  return monitor().addWatch(fName);
854 }
855 
856 
857 bool Foam::fileOperation::removeWatch(const label watchIndex) const
858 {
859  return monitor().removeWatch(watchIndex);
860 }
861 
862 
864 (
865  const labelList& watchIndices,
866  const fileName& fName
867 ) const
868 {
869  forAll(watchIndices, i)
870  {
871  if (getFile(watchIndices[i]) == fName)
872  {
873  return i;
874  }
875  }
876  return -1;
877 }
878 
879 
881 (
882  regIOobject& rio,
883  const fileNameList& files
884 ) const
885 {
886  const labelList& watchIndices = rio.watchIndices();
887 
888  DynamicList<label> newWatchIndices;
889  labelHashSet removedWatches(watchIndices);
890 
891  for (const fileName& f : files)
892  {
893  const label index = findWatch(watchIndices, f);
894 
895  if (index == -1)
896  {
897  newWatchIndices.append(addWatch(f));
898  }
899  else
900  {
901  // Existing watch
902  newWatchIndices.append(watchIndices[index]);
903  removedWatches.erase(index);
904  }
905  }
906 
907  // Remove any unused watches
908  for (const label index : removedWatches)
909  {
910  removeWatch(watchIndices[index]);
911  }
912 
913  rio.watchIndices() = newWatchIndices;
914 }
915 
916 
917 Foam::fileName Foam::fileOperation::getFile(const label watchIndex) const
918 {
919  return monitor().getFile(watchIndex);
920 }
921 
922 
924 (
925  const bool masterOnly,
926  const bool syncPar
927 ) const
928 {
929  monitor().updateStates(masterOnly, Pstream::parRun());
930 }
931 
932 
934 (
935  const label watchFd
936 ) const
937 {
938  return monitor().getState(watchFd);
939 }
940 
941 
942 void Foam::fileOperation::setUnmodified(const label watchFd) const
943 {
944  monitor().setUnmodified(watchFd);
945 }
946 
947 
949 (
950  const fileName& directory,
951  const word& constantName
952 ) const
953 {
954  if (debug)
955  {
956  Pout<< "fileOperation::findTimes : Finding times in directory "
957  << directory << endl;
958  }
959 
960  // Note: do NOT use master-only reading here (as per lookupProcessorsPath)
961  // since this routine is called on an individual processorN directory
962 
963  // Read directory entries into a list
964  fileNameList dirEntries(Foam::readDir(directory, fileName::DIRECTORY));
965  instantList times = sortTimes(dirEntries, constantName);
966 
967 
968  // Get all processor directories
969  refPtr<dirIndexList> procDirs(lookupProcessorsPath(directory));
970  for (const dirIndex& dirIdx : procDirs())
971  {
972  const fileName& procDir = dirIdx.first();
973  fileName collDir(processorsPath(directory, procDir));
974  if (!collDir.empty() && collDir != directory)
975  {
976  fileNameList extraEntries
977  (
979  (
980  collDir,
982  )
983  );
984  mergeTimes
985  (
986  sortTimes(extraEntries, constantName),
987  constantName,
988  times
989  );
990  }
991  }
992 
993  if (debug)
994  {
995  Pout<< "fileOperation::findTimes : Found times:" << times << endl;
996  }
997  return times;
998 }
999 
1000 
1003  const IOobject& startIO,
1004  const scalar startValue,
1005  const word& stopInstance
1006 ) const
1007 {
1008  const Time& time = startIO.time();
1009 
1010  IOobject io(startIO);
1011 
1012  // Note: - if name is empty, just check the directory itself
1013  // - check both for isFile and headerOk since the latter does a
1014  // filePath so searches for the file.
1015  // - check for an object with local file scope (so no looking up in
1016  // parent directory in case of parallel)
1017 
1018  if (exists(io))
1019  {
1021  << "Found exact match for \"" << io.name()
1022  << "\" in " << io.instance()/io.local()
1023  << endl;
1024 
1025  return io;
1026  }
1027 
1028  // Search back through the time directories to find the first time
1029  // that is less than or equal to the current time
1030 
1031  instantList ts = time.times();
1032  label instanceI = ts.size()-1;
1033 
1034  for (; instanceI >= 0; --instanceI)
1035  {
1036  if (ts[instanceI].value() <= startValue)
1037  {
1038  break;
1039  }
1040  }
1041 
1042  // Found the time, continue from here
1043  for (; instanceI >= 0; --instanceI)
1044  {
1045  io.instance() = ts[instanceI].name();
1046 
1047  // Shortcut: if actual directory is the timeName we've already tested it
1048  if
1049  (
1050  io.instance() == startIO.instance()
1051  && io.instance() != stopInstance
1052  )
1053  {
1054  continue;
1055  }
1056 
1057  if (exists(io))
1058  {
1060  << "Found exact match for \"" << io.name()
1061  << "\" in " << io.instance()/io.local()
1062  << endl;
1063 
1064  return io;
1065  }
1066 
1067  // Check if hit minimum instance
1068  if (io.instance() == stopInstance)
1069  {
1071  << "Hit stopInstance " << stopInstance << endl;
1072 
1073  if
1074  (
1075  startIO.readOpt() == IOobject::MUST_READ
1077  )
1078  {
1079  if (io.name().empty())
1080  {
1082  << "Cannot find directory "
1083  << io.local() << " in times " << startIO.instance()
1084  << " down to " << stopInstance
1085  << exit(FatalError);
1086  }
1087  else
1088  {
1090  << "Cannot find file \"" << io.name()
1091  << "\" in directory " << io.local()
1092  << " in times " << startIO.instance()
1093  << " down to " << stopInstance
1094  << exit(FatalError);
1095  }
1096  }
1097 
1098  return io;
1099  }
1100  }
1101 
1102  // Times usually already includes 'constant' so would have been checked
1103  // above.
1104  // However, re-test under these conditions:
1105  // - Times is empty.
1106  // Sometimes this can happen (eg, decomposePar with collated)
1107  // - Times[0] is not constant
1108  // - The startValue is negative (eg, kivaTest).
1109  // This plays havoc with the reverse search, causing it to miss 'constant'
1110 
1111  if
1112  (
1113  ts.empty()
1114  || ts.first().name() != time.constant()
1115  || startValue < 0
1116  )
1117  {
1118  io.instance() = time.constant();
1119  if (exists(io))
1120  {
1122  << "Found constant match for \"" << io.name()
1123  << "\" in " << io.instance()/io.local()
1124  << endl;
1125 
1126  return io;
1127  }
1128  }
1129 
1130 
1131  if
1132  (
1133  startIO.readOpt() == IOobject::MUST_READ
1135  )
1136  {
1138  << "Cannot find file \"" << io.name() << "\" in directory "
1139  << io.local() << " in times " << startIO.instance()
1140  << " down to " << time.constant()
1141  << exit(FatalError);
1142  }
1143 
1144  return io;
1145 }
1146 
1147 
1150  const objectRegistry& db,
1151  const fileName& instance,
1152  const fileName& local,
1153  word& newInstance
1154 ) const
1155 {
1156  if (debug)
1157  {
1158  Pout<< "fileOperation::readObjects :"
1159  << " db:" << db.objectPath()
1160  << " instance:" << instance << endl;
1161  }
1162 
1163  fileName path(db.path(instance, db.dbDir()/local));
1164 
1165  newInstance = word::null;
1166  fileNameList objectNames;
1167 
1168  if (Foam::isDir(path))
1169  {
1170  newInstance = instance;
1171  objectNames = Foam::readDir(path, fileName::FILE);
1172  }
1173  else
1174  {
1175  // Get processors equivalent of path
1176  fileName procsPath(filePath(path));
1177 
1178  if (!procsPath.empty())
1179  {
1180  newInstance = instance;
1181  objectNames = Foam::readDir(procsPath, fileName::FILE);
1182  }
1183  }
1184  return objectNames;
1185 }
1186 
1187 
1188 void Foam::fileOperation::setNProcs(const label nProcs)
1189 {}
1190 
1191 
1192 Foam::label Foam::fileOperation::nProcs
1194  const fileName& dir,
1195  const fileName& local
1196 ) const
1197 {
1198  label nProcs = 0;
1199  if (Pstream::master(comm_))
1200  {
1201  fileNameList dirNames(Foam::readDir(dir, fileName::Type::DIRECTORY));
1202 
1203  // Detect any processorsDDD or processorDDD
1204  label maxProc = -1;
1205  for (const fileName& dirN : dirNames)
1206  {
1207  fileName rp, rd, rl;
1209  label rNum;
1210 
1211  const label readProci =
1212  splitProcessorPath(dirN, rp, rd, rl, group, rNum);
1213 
1214  maxProc = max(maxProc, readProci);
1215  if (rNum != -1)
1216  {
1217  // Direct detection of processorsDDD
1218  maxProc = rNum-1;
1219  break;
1220  }
1221  }
1222  nProcs = maxProc+1;
1223 
1224  if (nProcs == 0 && Foam::isDir(dir/processorsBaseDir))
1225  {
1227  << "Defunct collated naming: " << processorsBaseDir << nl
1228  << "Manually rename with the decomposition number. Eg," << nl << nl
1229  << " mv processors processors16" << nl << nl
1230  << "...returning 1" << endl;
1231 
1232  nProcs = 1;
1233  }
1234  }
1235  Pstream::scatter(nProcs, Pstream::msgType(), comm_);
1236  return nProcs;
1237 }
1238 
1239 
1241 {
1242  if (debug)
1243  {
1244  Pout<< "fileOperation::flush : clearing processor directories cache"
1245  << endl;
1246  }
1247  procsDirs_.clear();
1248 }
1249 
1250 
1253  const IOobject& io,
1254  const word& procsDir
1255 ) const
1256 {
1257  return io.rootPath()/io.time().globalCaseName()/procsDir;
1258 }
1259 
1260 
1263  const IOobject& io,
1264  const word& instance,
1265  const word& procsDir
1266 ) const
1267 {
1268  return
1269  processorsCasePath(io, procsDir)
1270  /instance
1271  /io.db().dbDir()
1272  /io.local();
1273 }
1274 
1275 
1278  const fileName& dir,
1279  const word& procsDir
1280 ) const
1281 {
1282  // Check if directory is processorDDD
1283 
1284  const word caseName(dir.name());
1285  if (caseName.starts_with("processor"))
1286  {
1287  // Reject both '^processor$' and '^processors.*$'
1288 
1289  if (!std::isdigit(caseName[9]))
1290  {
1291  WarningInFunction << "Directory " << dir
1292  << " does not end in old-style processorDDD" << endl;
1293  }
1294 
1295  return dir.path()/procsDir;
1296  }
1297 
1298  return fileName::null;
1299 }
1300 
1301 
1304  const fileName& objPath,
1305  fileName& path,
1306  fileName& procDir,
1307  fileName& local,
1308 
1310  label& nProcs
1311 )
1312 {
1313  // Return value
1314  label returnProci = -1;
1315 
1316  // Clear out the return parameters
1317 
1318  path.clear();
1319  procDir.clear();
1320  local.clear();
1321  group.clear();
1322 
1323  // Invalidate detected number of processors
1324  nProcs = -1;
1325 
1326  // The local processor group is read as first/last, but stored as
1327  // start/size. Empty with start=0, size=0 if no range is detected
1328 
1329 
1330  // Start of 'processor..' directory name (the procDir)
1331  size_t pos = 0;
1332 
1333  // The slash starting the trailing (local) directory
1334  size_t slashLocal = string::npos;
1335 
1336 
1337  // Search for processor at start of string or after /processor
1338  //
1339  // 'processor(\d+)'
1340  // 'processors(\d+)'
1341  // 'processors(\d+)_(\d+)-(\d+)'
1342 
1343  for
1344  (
1345  /*nil*/;
1346  (pos = objPath.find("processor", pos)) != string::npos;
1347  pos += 9
1348  )
1349  {
1350  if (pos > 0 && objPath[pos-1] != '/')
1351  {
1352  // Not start of string or after /processor
1353  continue;
1354  }
1355 
1356  // The parse point. One past 'processor'
1357  size_t firstp = pos + 9;
1358 
1359  // normal: 'processor(\d+)'
1360  // plural: 'processors(\d+)'
1361 
1362  const bool plural = (objPath[firstp] == 's');
1363 
1364  if (plural)
1365  {
1366  ++firstp; // Skip over the 's'
1367  }
1368  else if (!std::isdigit(objPath[firstp]))
1369  {
1370  // Non-plural version (uncollated) requires digits only
1371  continue;
1372  }
1373 
1374  // The next slash indicates there is a local directory
1375  slashLocal = objPath.find('/', firstp);
1376 
1377  // The last parse point is the slash, or end of string
1378  const size_t lastp =
1379  (slashLocal == string::npos ? objPath.length() : slashLocal);
1380 
1381  if (!std::isdigit(objPath[lastp-1]))
1382  {
1383  // Must end in a digit!
1384  // This traps entries that are too short or look quite wrong
1385  // and avoid a string to int conversion that will fail anyhow
1386  continue;
1387  }
1388 
1389 
1390  // Match: '^processors(\d+)$' -> nProcs
1391 
1392  // Match: '^processors(\d+)_(\d+)-(\d+)$'
1393  // \1 = nProcs
1394  // \2 = beg processor group
1395  // \3 = end processor group (inclusive)
1396 
1397  if (plural)
1398  {
1399  int nProcsRead = 0;
1400 
1401  if
1402  (
1403  parseProcsNumRange
1404  (
1405  objPath.substr(firstp, lastp-firstp),
1406  nProcsRead,
1407  group
1408  )
1409  )
1410  {
1411  // Total number of processors
1412  nProcs = nProcsRead;
1413 
1414  // We are done!
1415  break;
1416  }
1417  }
1418 
1419  // Single
1420  // Match: '^processor(\d+)$' -> proci
1421 
1422  label proci = 0;
1423  if
1424  (
1425  Foam::read(objPath.substr(firstp, lastp-firstp), proci)
1426  && (proci >= 0)
1427  )
1428  {
1429  // Capture value of an individual processor
1430  returnProci = proci;
1431 
1432  // We are done!
1433  break;
1434  }
1435  }
1436 
1437  if (pos != string::npos)
1438  {
1439  // The split succeeded, extract the components.
1440 
1441  // The leading directory
1442  if (pos > 0)
1443  {
1444  path = objPath.substr(0, pos-1);
1445  }
1446 
1447  // The slash starting the trailing (local) directory
1448  if (slashLocal != string::npos)
1449  {
1450  procDir = objPath.substr(pos, slashLocal-pos);
1451  local = objPath.substr(slashLocal+1);
1452  }
1453  else
1454  {
1455  procDir = objPath.substr(pos);
1456  }
1457  }
1458 
1459  return returnProci;
1460 }
1461 
1462 
1464 {
1465  fileName path, pDir, local;
1467  label nProcs;
1468  return splitProcessorPath(fName, path, pDir, local, group, nProcs);
1469 }
1470 
1471 
1472 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
1473 
1475 {
1476  return autoPtr<fileOperation>
1477  (
1479  );
1480 }
1481 
1482 
1483 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1484 
1486 {
1488  {
1489  word handler(getEnv("FOAM_FILEHANDLER"));
1490 
1491  if (handler.empty())
1492  {
1494  }
1495 
1497  }
1498 
1500 }
1501 
1502 
1505 {
1506  if
1507  (
1508  newHandler
1510  && newHandler->type() == fileOperation::fileHandlerPtr_->type()
1511  )
1512  {
1513  return nullptr; // No change
1514  }
1515 
1517 
1518  fileOperation::fileHandlerPtr_ = std::move(newHandler);
1519 
1520  return old;
1521 }
1522 
1523 
1524 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
regIOobject.H
Foam::refPtr::New
static refPtr< T > New(Args &&... args)
Construct refPtr of T with forwarding arguments.
uncollatedFileOperation.H
Foam::TimePaths::globalCaseName
const fileName & globalCaseName() const
Return global case name.
Definition: TimePathsI.H:56
Foam::maxOp
Definition: ops.H:223
Foam::bitOrOp
Definition: ops.H:230
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
rp
regionProperties rp(runTime)
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
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::fileName::FILE
A file.
Definition: fileName.H:83
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::fileOperation::mergeTimes
static void mergeTimes(const instantList &extraTimes, const word &constantName, instantList &times)
Merge two times.
Definition: fileOperation.C:316
Foam::fileOperation
An encapsulation of filesystem-related operations.
Definition: fileOperation.H:68
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
ITstream.H
Foam::constant::atomic::group
constexpr const char *const group
Group name for atomic constants.
Definition: atomicConstants.H:52
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::UList::end
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:350
Foam::fileOperation::processorsPath
fileName processorsPath(const IOobject &, const word &instance, const word &procDir) const
Generate path (like io.path) with provided instance and any.
Definition: fileOperation.C:1262
Foam::fileOperation::fileHandlerPtr_
static autoPtr< fileOperation > fileHandlerPtr_
Static fileOperation.
Definition: fileOperation.H:181
stringOpsSort.H
Specialized string sorting.
Foam::IOobject::instance
const fileName & instance() const noexcept
Definition: IOobjectI.H:196
Foam::fileOperation::addWatches
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
Definition: fileOperation.C:881
Foam::fileName::path
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:176
Foam::regIOobject::watchIndices
const labelList & watchIndices() const
Return file-monitoring handles.
Definition: regIOobjectI.H:196
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::IntRange
An interval of (signed) integers defined by a start and a size.
Definition: IntRange.H:63
Foam::less
static bool less(const vector &x, const vector &y)
To compare normals.
Definition: meshRefinementRefine.C:57
Foam::IOobject::typeHeaderOk
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (uses typeFilePath to find file) and check its info.
Definition: IOobjectTemplates.C:39
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::IOobject::writeEndDivider
static Ostream & writeEndDivider(Ostream &os)
Write the standard end file divider.
Definition: IOobjectWriteHeader.C:142
Foam::regIOobject::writeData
virtual bool writeData(Ostream &) const =0
Pure virtual writeData function.
Foam::IOobject::rootPath
const fileName & rootPath() const
Definition: IOobject.C:499
Foam::fileName::name
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Definition: fileNameI.H:199
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::IOobject::inotifyMaster
Definition: IOobject.H:204
Foam::fileOperation::NewUncollated
static autoPtr< fileOperation > NewUncollated()
Static construct the commonly used uncollatedFileOperation.
Definition: fileOperation.C:1474
Foam::IOobject::timeStampMaster
Definition: IOobject.H:202
Foam::fileOperation::pathTypeNames_
static const Enum< pathType > pathTypeNames_
Definition: fileOperation.H:95
Foam::fileOperation::flush
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
Definition: fileOperation.C:1240
objectRegistry.H
Foam::IOobject::fileModificationChecking
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:303
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.
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::fileMonitor::fileState
fileState
Enumeration defining the file state.
Definition: fileMonitor.H:73
Foam::isFile
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: MSwindows.C:658
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1485
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::fileOperation::isFileOrDir
static bool isFileOrDir(const bool isFile, const fileName &)
Helper: check for file (isFile) or directory (!isFile)
Definition: fileOperation.C:389
Foam::fileOperation::setNProcs
virtual void setNProcs(const label nProcs)
Set number of processor directories/results. Only used in.
Definition: fileOperation.C:1188
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
polyMesh.H
Foam::HashSet< label, Hash< label > >
Foam::IOobject::time
const Time & time() const
Return Time associated with the objectRegistry.
Definition: IOobject.C:493
Foam::fileOperation::updateStates
virtual void updateStates(const bool masterOnly, const bool syncPar) const
Update state of all files.
Definition: fileOperation.C:924
Foam::IOobject::inotify
Definition: IOobject.H:203
Foam::getEnv
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: MSwindows.C:371
Foam::fileOperation::findTimes
virtual instantList findTimes(const fileName &, const word &) const
Get sorted list of times.
Definition: fileOperation.C:949
Foam::fileOperation::sortTimes
static instantList sortTimes(const fileNameList &dirEntries, const word &constantName="constant")
Sort directory entries according to time value,.
Definition: fileOperation.C:238
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::fileOperation::getFile
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
Definition: fileOperation.C:917
Foam::fileOperation::findInstance
virtual IOobject findInstance(const IOobject &io, const scalar startValue, const word &stopInstance) const
Find instance where IOobject is. Fails if cannot be found.
Definition: fileOperation.C:1002
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::fileOperation::New
static autoPtr< fileOperation > New(const word &handlerType, bool verbose=false)
Select fileHandler-type.
Definition: fileOperation.C:706
Foam::objectRegistry::dbDir
virtual const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
Definition: objectRegistry.H:187
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::UList::begin
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:52
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::IOobject::local
const fileName & local() const noexcept
Definition: IOobjectI.H:208
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
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:1193
argList.H
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:456
Foam::fileMonitor
Checking for changes to files.
Definition: fileMonitor.H:66
Foam::sort
void sort(UList< T > &a)
Definition: UList.C:261
Foam::TimePaths::times
instantList times() const
Search the case for valid time directories.
Definition: TimePaths.C:149
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::fileOperation::writeObject
virtual bool writeObject(const regIOobject &io, IOstreamOption streamOpt=IOstreamOption(), const bool valid=true) const
Writes a regIOobject (so header, contents and divider).
Definition: fileOperation.C:751
Foam::fileOperation::getState
virtual fileMonitor::fileState getState(const label) const
Get current state of file (using handle)
Definition: fileOperation.C:934
Foam::OSstream
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:54
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
HashSet.H
Foam::FatalError
error FatalError
FatalErrorInLookup
#define FatalErrorInLookup(lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalError.
Definition: error.H:457
os
OBJstream os(runTime.globalPath()/outputName)
fileOperation.H
Foam::fileOperation::defaultFileHandler
static word defaultFileHandler
Name of the default fileHandler.
Definition: fileOperation.H:171
Foam::stringOps::natural_sort::compare
static int compare(const std::string &s1, const std::string &s2)
Natural compare for std::string.
Definition: stringOpsSort.H:67
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::fileOperation::objectPath
virtual fileName objectPath(const IOobject &io, const word &typeName) const
Generate disk file name for object. Opposite of filePath.
Definition: fileOperation.C:741
Foam::fileName::null
static const fileName null
An empty fileName.
Definition: fileName.H:101
Foam::fileOperation::addWatch
virtual label addWatch(const fileName &) const
Add watching of a file. Returns handle.
Definition: fileOperation.C:851
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::fileOperation::removeWatch
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
Definition: fileOperation.C:857
Foam::IOobject::readOpt
readOption readOpt() const noexcept
The read option.
Definition: IOobjectI.H:164
Foam::fileOperation::lookupAndCacheProcessorsPath
refPtr< dirIndexList > lookupAndCacheProcessorsPath(const fileName &objectPath, const bool syncPar) const
Lookup name of processorsDDD using cache.
Definition: fileOperation.C:397
Foam::fileOperation::setUnmodified
virtual void setUnmodified(const label) const
Set current state of file (using handle) to unmodified.
Definition: fileOperation.C:942
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
Foam::fileOperation::monitor
fileMonitor & monitor() const
Get or create fileMonitor singleton.
Definition: fileOperation.C:298
Time.H
Foam::autoPtr< Foam::fileOperation >
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:73
Foam::fileOperation::fileOperation
fileOperation(const label comm, const bool distributedRoots=false)
Construct from communicator, optionally with distributed roots.
Definition: fileOperation.C:694
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::UPstream::msgType
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:540
DebugInfo
#define DebugInfo
Report an information message using Foam::Info.
Definition: messageStream.H:382
Foam::nl
constexpr char nl
Definition: Ostream.H:404
f
labelList f(nPoints)
Foam::fileOperations::uncollatedFileOperation
fileOperation that assumes file operations are local.
Definition: uncollatedFileOperation.H:51
decomposedBlockData.H
Foam::fileOperation::exists
bool exists(IOobject &io) const
Definition: fileOperation.C:648
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List< label >
Foam::fileOperation::splitProcessorPath
static label splitProcessorPath(const fileName &objectPath, fileName &path, fileName &procDir, fileName &local, procRangeType &group, label &nProcs)
Split objectPath into part before 'processor' and part after.
Definition: fileOperation.C:1303
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::IOList< label >
Foam::fileOperation::readObjects
virtual fileNameList readObjects(const objectRegistry &db, const fileName &instance, const fileName &local, word &newInstance) const
Search directory for objects. Used in IOobjectList.
Definition: fileOperation.C:1149
Foam::fileName::DIRECTORY
A directory.
Definition: fileName.H:84
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::word::null
static const word null
An empty word.
Definition: word.H:80
Foam::IOobject::MUST_READ_IF_MODIFIED
Definition: IOobject.H:186
Foam::fileOperation::ioRanks
static labelList ioRanks()
Retrieve list of IO ranks from FOAM_IORANKS env variable.
Definition: fileOperation.C:222
Foam::Tuple2::second
const T2 & second() const noexcept
Return second.
Definition: Tuple2.H:130
Foam::fileOperation::findWatch
virtual label findWatch(const labelList &watchIndices, const fileName &) const
Find index (or -1) of file in list of handles.
Definition: fileOperation.C:864
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fileOperation::lookupProcessorsPath
virtual refPtr< dirIndexList > lookupProcessorsPath(const fileName &objectPath) const
Lookup name of processorsDDD using cache.
Definition: fileOperation.C:641
Foam::IOobject::writeHeader
bool writeHeader(Ostream &os) const
Write header with current type()
Definition: IOobjectWriteHeader.C:277
registerSwitch.H
Foam::fileOperation::processorsBaseDir
static word processorsBaseDir
Return the processors directory name (usually "processors")
Definition: fileOperation.H:168
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::keyType::LITERAL
String literal.
Definition: keyType.H:81
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:60
Foam::IOobject::objectPath
fileName objectPath() const
The complete path + object name.
Definition: IOobjectI.H:214
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:96
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
Foam::IOobject::path
fileName path() const
The complete path.
Definition: IOobject.C:511
Foam::debug::optimisationSwitches
dictionary & optimisationSwitches()
The OptimisationSwitches sub-dictionary in the central controlDict(s).
Definition: debug.C:219
Foam::fileOperation::processorsCasePath
fileName processorsCasePath(const IOobject &, const word &procDir) const
Generate path (like io.path) from root+casename with any.
Definition: fileOperation.C:1252
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
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::fileOperation::detectProcessorPath
static label detectProcessorPath(const fileName &objPath)
Detect processor number from '/aa/bb/processorDDD/cc'.
Definition: fileOperation.C:1463
Foam::Tuple2::first
const T1 & first() const noexcept
Return first.
Definition: Tuple2.H:118
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::fileOperation::pathType
pathType
Enumeration for the location of an IOobject.
Definition: fileOperation.H:73
Foam::fileOperation::distributed
bool distributed() const noexcept
Distributed roots (parallel run)
Definition: fileOperation.H:239
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::refPtr
A class for managing references or pointers (no reference counting)
Definition: PtrList.H:60
Foam::IOobject::MUST_READ
Definition: IOobject.H:185
Foam::IOobject::db
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:487
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177