masterUncollatedFileOperation.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 
31 #include "Pstream.H"
32 #include "Time.H"
33 #include "instant.H"
34 #include "IFstream.H"
35 #include "IListStream.H"
36 #include "masterOFstream.H"
37 #include "decomposedBlockData.H"
38 #include "registerSwitch.H"
39 #include "dummyISstream.H"
40 #include "SubList.H"
41 #include "unthreadedInitialise.H"
42 #include "bitSet.H"
43 
44 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
45 
46 namespace Foam
47 {
48 namespace fileOperations
49 {
50  defineTypeNameAndDebug(masterUncollatedFileOperation, 0);
52  (
53  fileOperation,
54  masterUncollatedFileOperation,
55  word
56  );
57 
59  (
60  Foam::debug::floatOptimisationSwitch("maxMasterFileBufferSize", 1e9)
61  );
63  (
64  "maxMasterFileBufferSize",
65  float,
67  );
68 
69  // Mark as not needing threaded mpi
71  (
73  masterUncollatedFileOperationInitialise,
74  word,
75  masterUncollated
76  );
77 }
78 }
79 
80 
81 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
82 
84 (
85  const label n
86 )
87 {
88  labelList mainRanks(fileOperation::ioRanks());
89 
90  if (mainRanks.empty())
91  {
92  return identity(n);
93  }
94  else
95  {
96  DynamicList<label> subRanks(n);
97 
98  if (!mainRanks.found(0))
99  {
101  << "Rank 0 (master) should be in the IO ranks. Currently "
102  << mainRanks << nl
103  << exit(FatalError);
104  }
105 
106  // The lowest numbered rank is the IO rank
107  const bitSet isIOrank(n, mainRanks);
108 
109  for (label proci = Pstream::myProcNo(); proci >= 0; --proci)
110  {
111  if (isIOrank[proci])
112  {
113  // Found my master. Collect all processors with same master
114  subRanks.append(proci);
115  for
116  (
117  label rank = proci+1;
118  rank < n && !isIOrank[rank];
119  ++rank
120  )
121  {
122  subRanks.append(rank);
123  }
124  break;
125  }
126  }
127  return subRanks;
128  }
129 }
130 
131 
134 (
135  const instantList& timeDirs,
136  const instant& t
137 )
138 {
139  // Note:
140  // - times will include constant (with value 0) as first element.
141  // For backwards compatibility make sure to find 0 in preference
142  // to constant.
143  // - list is sorted so could use binary search
144 
145  forAllReverse(timeDirs, i)
146  {
147  if (t.equal(timeDirs[i].value()))
148  {
149  return timeDirs[i].name();
150  }
151  }
152 
153  return word::null;
154 }
155 
156 
159 (
160  const bool checkGlobal,
161  const bool isFile,
162  const IOobject& io,
163  const bool search,
164  pathType& searchType,
165  word& procsDir,
166  word& newInstancePath
167 ) const
168 {
169  procsDir = word::null;
170  newInstancePath = word::null;
171 
172  if (io.instance().isAbsolute())
173  {
174  fileName objPath = io.instance()/io.name();
175 
176  if (isFileOrDir(isFile, objPath))
177  {
178  searchType = fileOperation::ABSOLUTE;
179  return objPath;
180  }
181  else
182  {
183  searchType = fileOperation::NOTFOUND;
184  return fileName::null;
185  }
186  }
187  else
188  {
189  // 1. Check the writing fileName
190  fileName writePath(objectPath(io, io.headerClassName()));
191 
192  if (isFileOrDir(isFile, writePath))
193  {
194  searchType = fileOperation::WRITEOBJECT;
195  return writePath;
196  }
197 
198  // 2. Check processors/
199  if (io.time().processorCase())
200  {
201  refPtr<dirIndexList> pDirs(lookupProcessorsPath(io.objectPath()));
202 
203  for (const dirIndex& dirIdx : pDirs())
204  {
205  const fileName& pDir = dirIdx.first();
206  fileName objPath =
207  processorsPath(io, io.instance(), pDir)
208  /io.name();
209  if (objPath != writePath && isFileOrDir(isFile, objPath))
210  {
211  searchType = dirIdx.second().first();
212  procsDir = pDir;
213  return objPath;
214  }
215  }
216  }
217  {
218  // 3. Check local
219  fileName localPath = io.objectPath();
220 
221  if
222  (
223  localPath != writePath
224  && isFileOrDir(isFile, localPath)
225  )
226  {
227  searchType = fileOperation::OBJECT;
228  return localPath;
229  }
230  }
231 
232 
233 
234  // Any global checks
235  if
236  (
237  checkGlobal
238  && io.time().processorCase()
239  && (
240  io.instance() == io.time().system()
241  || io.instance() == io.time().constant()
242  )
243  )
244  {
245  fileName parentPath =
246  io.rootPath()/io.time().globalCaseName()
247  /io.instance()/io.db().dbDir()/io.local()/io.name();
248 
249  if (isFileOrDir(isFile, parentPath))
250  {
251  searchType = fileOperation::PARENTOBJECT;
252  return parentPath;
253  }
254  }
255 
256  // Check for approximately same time. E.g. if time = 1e-2 and
257  // directory is 0.01 (due to different time formats)
258  const auto pathFnd = times_.cfind(io.time().path());
259 
260  if (search && pathFnd.found())
261  {
262  newInstancePath = findInstancePath
263  (
264  *pathFnd(),
265  instant(io.instance())
266  );
267 
268  if (newInstancePath.size() && newInstancePath != io.instance())
269  {
270  // 1. Try processors equivalent
272  (
273  lookupProcessorsPath(io.objectPath())
274  );
275 
276  for (const dirIndex& dirIdx : pDirs())
277  {
278  const fileName& pDir = dirIdx.first();
279 
280  fileName fName
281  (
282  processorsPath(io, newInstancePath, pDir)
283  /io.name()
284  );
285  if (isFileOrDir(isFile, fName))
286  {
287  switch (dirIdx.second().first())
288  {
289  case fileOperation::PROCUNCOLLATED:
290  {
291  searchType =
292  fileOperation::PROCUNCOLLATEDINSTANCE;
293  }
294  break;
295  case fileOperation::PROCBASEOBJECT:
296  {
297  searchType = fileOperation::PROCBASEINSTANCE;
298  }
299  break;
300  case fileOperation::PROCOBJECT:
301  {
302  searchType = fileOperation::PROCINSTANCE;
303  }
304  break;
305  default:
306  break;
307  }
308  procsDir = pDir;
309  return fName;
310  }
311  }
312 
313 
314  // 2. Check local
315  fileName fName
316  (
317  io.rootPath()/io.caseName()
318  /newInstancePath/io.db().dbDir()/io.local()/io.name()
319  );
320  if (isFileOrDir(isFile, fName))
321  {
322  searchType = fileOperation::FINDINSTANCE;
323  return fName;
324  }
325  }
326  }
327 
328  searchType = fileOperation::NOTFOUND;
329  return fileName::null;
330  }
331 }
332 
333 
336 (
337  const IOobject& io,
338  const pathType& searchType,
339  const word& procDir,
340  const word& instancePath
341 ) const
342 {
343  // Replacement for IOobject::objectPath()
344 
345  switch (searchType)
346  {
347  case fileOperation::ABSOLUTE:
348  {
349  return io.instance()/io.name();
350  }
351  break;
352 
353  case fileOperation::OBJECT:
354  {
355  return io.path()/io.name();
356  }
357  break;
358 
359  case fileOperation::WRITEOBJECT:
360  {
361  return objectPath(io, io.headerClassName());
362  }
363  break;
364 
365  case fileOperation::PROCUNCOLLATED:
366  {
367  // Uncollated type, e.g. processor1
368  const word procName
369  (
370  "processor" + Foam::name(Pstream::myProcNo(Pstream::worldComm))
371  );
372  return
373  processorsPath
374  (
375  io,
376  io.instance(),
377  (
378  Pstream::parRun()
379  ? procName
380  : procDir
381  )
382  )
383  /io.name();
384  }
385  break;
386 
387  case fileOperation::PROCBASEOBJECT:
388  {
389  // Collated, e.g. processors4
390  return
391  processorsPath(io, io.instance(), procDir)
392  /io.name();
393  }
394  break;
395 
396  case fileOperation::PROCOBJECT:
397  {
398  // Processors directory locally provided by the fileHandler itself
399  return
400  processorsPath(io, io.instance(), processorsDir(io))
401  /io.name();
402  }
403  break;
404 
405  case fileOperation::PARENTOBJECT:
406  {
407  return
408  io.rootPath()/io.time().globalCaseName()
409  /io.instance()/io.db().dbDir()/io.local()/io.name();
410  }
411  break;
412 
413  case fileOperation::FINDINSTANCE:
414  {
415  return
416  io.rootPath()/io.caseName()
417  /instancePath/io.db().dbDir()/io.local()/io.name();
418  }
419  break;
420 
421  case fileOperation::PROCUNCOLLATEDINSTANCE:
422  {
423  // Uncollated type, e.g. processor1
424  const word procName
425  (
426  "processor"
427  +Foam::name(Pstream::myProcNo(Pstream::worldComm))
428  );
429  return
430  processorsPath
431  (
432  io,
433  instancePath,
434  (
435  Pstream::parRun()
436  ? procName
437  : procDir
438  )
439  )
440  /io.name();
441  }
442  break;
443 
444  case fileOperation::PROCBASEINSTANCE:
445  {
446  // Collated, e.g. processors4
447  return
448  processorsPath(io, instancePath, procDir)
449  /io.name();
450  }
451  break;
452 
453  case fileOperation::PROCINSTANCE:
454  {
455  // Processors directory locally provided by the fileHandler itself
456  return
457  processorsPath(io, instancePath, processorsDir(io))
458  /io.name();
459  }
460  break;
461 
462  case fileOperation::NOTFOUND:
463  {
464  return fileName::null;
465  }
466  break;
467 
468  default:
469  {
471  return fileName::null;
472  }
473  }
474 }
475 
476 
478 (
479  const fileNameList& filePaths
480 )
481 {
482  const fileName& object0 = filePaths[0];
483 
484  for (label i = 1; i < filePaths.size(); i++)
485  {
486  if (filePaths[i] != object0)
487  {
488  return false;
489  }
490  }
491  return true;
492 }
493 
494 
496 (
497  const fileName& filePath,
498  const labelUList& procs,
499  PstreamBuffers& pBufs
500 )
501 {
502  IFstream ifs(filePath, IOstreamOption::BINARY);
503 
504  if (!ifs.good())
505  {
506  FatalIOErrorInFunction(filePath)
507  << "Cannot open file " << filePath
508  << exit(FatalIOError);
509  }
510 
511  if (debug)
512  {
513  Pout<< "masterUncollatedFileOperation::readAndSend :"
514  << " compressed:" << bool(ifs.compression()) << " "
515  << filePath << endl;
516  }
517 
518  if (ifs.compression() == IOstreamOption::COMPRESSED)
519  {
520  // Could use Foam::fileSize, estimate uncompressed size (eg, 2x)
521  // and then string reserve followed by string assign...
522 
523  // Uncompress and read file contents into a character buffer
524  const std::string buf
525  (
526  std::istreambuf_iterator<char>(ifs.stdStream()),
527  std::istreambuf_iterator<char>()
528  );
529 
530  for (const label proci : procs)
531  {
532  UOPstream os(proci, pBufs);
533  os.write(buf.data(), buf.length());
534  }
535 
536  if (debug)
537  {
538  Pout<< "masterUncollatedFileOperation::readStream :"
539  << " From " << filePath << " sent " << buf.size()
540  << " bytes" << endl;
541  }
542  }
543  else
544  {
545  const off_t count(Foam::fileSize(filePath));
546 
547  // Read file contents into a character buffer
548  List<char> buf(static_cast<label>(count));
549  ifs.stdStream().read(buf.data(), count);
550 
551  for (const label proci : procs)
552  {
553  UOPstream os(proci, pBufs);
554  os.write(buf.cdata(), count);
555  }
556 
557  if (debug)
558  {
559  Pout<< "masterUncollatedFileOperation::readStream :"
560  << " From " << filePath << " sent " << buf.size()
561  << " bytes" << endl;
562  }
563  }
564 }
565 
566 
569 (
570  IOobject& io,
571  const label comm,
572  const bool uniform, // on comms master only
573  const fileNameList& filePaths, // on comms master only
574  const boolList& procValid // on comms master only
575 )
576 {
577  autoPtr<ISstream> isPtr;
578 
579  // const bool uniform = uniformFile(filePaths);
580 
581  PstreamBuffers pBufs
582  (
583  Pstream::commsTypes::nonBlocking,
584  Pstream::msgType(),
585  comm
586  );
587 
588  if (Pstream::master(comm))
589  {
590  if (uniform)
591  {
592  if (procValid[0])
593  {
594  if (filePaths[0].empty())
595  {
596  FatalIOErrorInFunction(filePaths[0])
597  << "cannot find file " << io.objectPath()
598  << exit(FatalIOError);
599  }
600 
601  DynamicList<label> validProcs(Pstream::nProcs(comm));
602  for (const int proci : Pstream::allProcs(comm))
603  {
604  if (procValid[proci])
605  {
606  validProcs.append(proci);
607  }
608  }
609 
610  // Read on master and send to all processors (including
611  // master for simplicity)
612  if (debug)
613  {
614  Pout<< "masterUncollatedFileOperation::readStream :"
615  << " For uniform file " << filePaths[0]
616  << " sending to " << validProcs
617  << " in comm:" << comm << endl;
618  }
619  readAndSend(filePaths[0], validProcs, pBufs);
620  }
621  }
622  else
623  {
624  if (procValid[0])
625  {
626  if (filePaths[0].empty())
627  {
628  FatalIOErrorInFunction(filePaths[0])
629  << "cannot find file " << io.objectPath()
630  << exit(FatalIOError);
631  }
632 
633  // Open master
634  isPtr.reset(new IFstream(filePaths[0]));
635 
636  // Read header
637  if (!io.readHeader(*isPtr))
638  {
639  FatalIOErrorInFunction(*isPtr)
640  << "problem while reading header for object "
641  << io.name() << exit(FatalIOError);
642  }
643  }
644 
645  // Read slave files
646  for (const int proci : Pstream::subProcs(comm))
647  {
648  if (debug)
649  {
650  Pout<< "masterUncollatedFileOperation::readStream :"
651  << " For processor " << proci
652  << " opening " << filePaths[proci] << endl;
653  }
654 
655  const fileName& fPath = filePaths[proci];
656 
657  if (procValid[proci] && !fPath.empty())
658  {
659  // Note: handle compression ourselves since size cannot
660  // be determined without actually uncompressing
661  readAndSend(fPath, labelList(one{}, proci), pBufs);
662  }
663  }
664  }
665  }
666 
667  labelList recvSizes;
668  pBufs.finishedSends(recvSizes);
669 
670  // isPtr will be valid on master and will be the unbuffered
671  // IFstream. Else the information is in the PstreamBuffers (and
672  // the special case of a uniform file)
673 
674  if (procValid[Pstream::myProcNo(comm)])
675  {
676  // This processor needs to return something
677 
678  if (!isPtr)
679  {
680  UIPstream is(Pstream::masterNo(), pBufs);
681 
682  List<char> buf(recvSizes[Pstream::masterNo()]);
683  if (recvSizes[Pstream::masterNo()] > 0)
684  {
685  is.read(buf.data(), recvSizes[Pstream::masterNo()]);
686  }
687 
688  if (debug)
689  {
690  Pout<< "masterUncollatedFileOperation::readStream :"
691  << " Done reading " << buf.size() << " bytes" << endl;
692  }
693 
694  // A local character buffer copy of the Pstream contents.
695  // Construct with same parameters (ASCII, current version)
696  // as the IFstream so that it has the same characteristics.
697 
698  isPtr.reset(new IListStream(std::move(buf)));
699 
700  // With the proper file name
701  isPtr->name() = filePaths[Pstream::myProcNo(comm)];
702 
703  if (!io.readHeader(*isPtr))
704  {
705  FatalIOErrorInFunction(*isPtr)
706  << "problem while reading header for object "
707  << io.name() << exit(FatalIOError);
708  }
709  }
710  }
711  else
712  {
713  isPtr.reset(new dummyISstream());
714  }
715 
716  return isPtr;
717 }
718 
719 
720 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
721 
724 (
725  bool verbose
726 )
727 :
729  (
730  UPstream::allocateCommunicator
731  (
732  UPstream::worldComm,
733  subRanks(Pstream::nProcs())
734  )
735  ),
736  myComm_(comm_)
737 {
738  verbose = (verbose && Foam::infoDetailLevel > 0);
739 
740  if (verbose)
741  {
742  DetailInfo
743  << "I/O : " << typeName
744  << " (maxMasterFileBufferSize " << maxMasterFileBufferSize << ')'
745  << endl;
746  }
747 
748  if (IOobject::fileModificationChecking == IOobject::timeStampMaster)
749  {
750  if (verbose)
751  {
753  << "Resetting fileModificationChecking to timeStamp" << endl;
754  }
755  IOobject::fileModificationChecking = IOobject::timeStamp;
756  }
757  else if (IOobject::fileModificationChecking == IOobject::inotifyMaster)
758  {
759  if (verbose)
760  {
762  << "Resetting fileModificationChecking to inotify"
763  << endl;
764  }
765  IOobject::fileModificationChecking = IOobject::inotify;
766  }
767 }
768 
769 
772 (
773  const label comm,
774  bool verbose
775 )
776 :
777  fileOperation(comm),
778  myComm_(-1)
779 {
780  verbose = (verbose && Foam::infoDetailLevel > 0);
781 
782  if (verbose)
783  {
784  DetailInfo
785  << "I/O : " << typeName
786  << " (maxMasterFileBufferSize " << maxMasterFileBufferSize << ')'
787  << endl;
788  }
789 
790  if (IOobject::fileModificationChecking == IOobject::timeStampMaster)
791  {
792  if (verbose)
793  {
795  << "Resetting fileModificationChecking to timeStamp" << endl;
796  }
797  IOobject::fileModificationChecking = IOobject::timeStamp;
798  }
799  else if (IOobject::fileModificationChecking == IOobject::inotifyMaster)
800  {
801  if (verbose)
802  {
804  << "Resetting fileModificationChecking to inotify"
805  << endl;
806  }
807  IOobject::fileModificationChecking = IOobject::inotify;
808  }
809 }
810 
811 
812 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
813 
816 {
817  if (myComm_ != -1 && myComm_ != UPstream::worldComm)
818  {
820  }
821 }
822 
823 
824 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
825 
827 (
828  const fileName& dir,
829  mode_t mode
830 ) const
831 {
832  return masterOp<mode_t, mkDirOp>
833  (
834  dir,
835  mkDirOp(mode),
837  comm_
838  );
839 }
840 
841 
843 (
844  const fileName& fName,
845  mode_t mode
846 ) const
847 {
848  return masterOp<mode_t, chModOp>
849  (
850  fName,
851  chModOp(mode),
853  comm_
854  );
855 }
856 
857 
859 (
860  const fileName& fName,
861  const bool followLink
862 ) const
863 {
864  return masterOp<mode_t, modeOp>
865  (
866  fName,
867  modeOp(followLink),
869  comm_
870  );
871 }
872 
873 
875 (
876  const fileName& fName,
877  const bool followLink
878 ) const
879 {
880  return fileName::Type
881  (
882  masterOp<label, typeOp>
883  (
884  fName,
885  typeOp(followLink),
887  comm_
888  )
889  );
890 }
891 
892 
894 (
895  const fileName& fName,
896  const bool checkGzip,
897  const bool followLink
898 ) const
899 {
900  return masterOp<bool, existsOp>
901  (
902  fName,
903  existsOp(checkGzip, followLink),
905  comm_
906  );
907 }
908 
909 
911 (
912  const fileName& fName,
913  const bool followLink
914 ) const
915 {
916  return masterOp<bool, isDirOp>
917  (
918  fName,
919  isDirOp(followLink),
921  comm_
922  );
923 }
924 
925 
927 (
928  const fileName& fName,
929  const bool checkGzip,
930  const bool followLink
931 ) const
932 {
933  return masterOp<bool, isFileOp>
934  (
935  fName,
936  isFileOp(checkGzip, followLink),
938  comm_
939  );
940 }
941 
942 
944 (
945  const fileName& fName,
946  const bool followLink
947 ) const
948 {
949  return masterOp<off_t, fileSizeOp>
950  (
951  fName,
952  fileSizeOp(followLink),
954  comm_
955  );
956 }
957 
958 
960 (
961  const fileName& fName,
962  const bool followLink
963 ) const
964 {
965  return masterOp<time_t, lastModifiedOp>
966  (
967  fName,
968  lastModifiedOp(followLink),
970  comm_
971  );
972 }
973 
974 
976 (
977  const fileName& fName,
978  const bool followLink
979 ) const
980 {
981  return masterOp<double, lastModifiedHROp>
982  (
983  fName,
984  lastModifiedHROp(followLink),
986  comm_
987  );
988 }
989 
990 
992 (
993  const fileName& fName,
994  const std::string& ext
995 ) const
996 {
997  return masterOp<bool, mvBakOp>
998  (
999  fName,
1000  mvBakOp(ext),
1001  Pstream::msgType(),
1002  comm_
1003  );
1004 }
1005 
1006 
1009  const fileName& fName
1010 ) const
1011 {
1012  return masterOp<bool, rmOp>
1013  (
1014  fName,
1015  rmOp(),
1016  Pstream::msgType(),
1017  comm_
1018  );
1019 }
1020 
1021 
1024  const fileName& dir,
1025  const bool silent
1026 ) const
1027 {
1028  return masterOp<bool, rmDirOp>
1029  (
1030  dir,
1031  rmDirOp(silent),
1032  Pstream::msgType(),
1033  comm_
1034  );
1035 }
1036 
1037 
1040  const fileName& dir,
1041  const fileName::Type type,
1042  const bool filtergz,
1043  const bool followLink
1044 ) const
1045 {
1046  return masterOp<fileNameList, readDirOp>
1047  (
1048  dir,
1049  readDirOp(type, filtergz, followLink),
1050  Pstream::msgType(),
1051  comm_
1052  );
1053 }
1054 
1055 
1058  const fileName& src,
1059  const fileName& dst,
1060  const bool followLink
1061 ) const
1062 {
1063  return masterOp<bool, cpOp>
1064  (
1065  src,
1066  dst,
1067  cpOp(followLink),
1068  Pstream::msgType(),
1069  comm_
1070  );
1071 }
1072 
1073 
1076  const fileName& src,
1077  const fileName& dst
1078 ) const
1079 {
1080  return masterOp<bool, lnOp>
1081  (
1082  src,
1083  dst,
1084  lnOp(),
1085  Pstream::msgType(),
1086  comm_
1087  );
1088 }
1089 
1090 
1093  const fileName& src,
1094  const fileName& dst,
1095  const bool followLink
1096 ) const
1097 {
1098  return masterOp<bool, mvOp>
1099  (
1100  src,
1101  dst,
1102  mvOp(followLink),
1103  Pstream::msgType(),
1104  comm_
1105  );
1106 }
1107 
1108 
1111  const bool checkGlobal,
1112  const IOobject& io,
1113  const word& typeName,
1114  const bool search
1115 ) const
1116 {
1117  if (debug)
1118  {
1119  Pout<< "masterUncollatedFileOperation::filePath :"
1120  << " objectPath:" << io.objectPath()
1121  << " checkGlobal:" << checkGlobal << endl;
1122  }
1123 
1124  // Now that we have an IOobject path use it to detect & cache
1125  // processor directory naming
1126  (void)lookupProcessorsPath(io.objectPath());
1127 
1128  // Trigger caching of times
1129  (void)findTimes(io.time().path(), io.time().constant());
1130 
1131 
1132  // Determine master filePath and scatter
1133 
1134  fileName objPath;
1135  pathType searchType = NOTFOUND;
1136  word procsDir;
1137  word newInstancePath;
1138 
1139  if (Pstream::master(comm_))
1140  {
1141  const bool oldParRun(Pstream::parRun(false));
1142 
1143  // All masters search locally. Note that global objects might
1144  // fail (except on master). This gets handled later on (in PARENTOBJECT)
1145  objPath =
1146  filePathInfo
1147  (
1148  checkGlobal,
1149  true,
1150  io,
1151  search,
1152  searchType,
1153  procsDir,
1154  newInstancePath
1155  );
1156 
1157  Pstream::parRun(oldParRun);
1158 
1159  if (debug)
1160  {
1161  Pout<< "masterUncollatedFileOperation::filePath :"
1162  << " master objPath:" << objPath
1163  << " searchType:" << fileOperation::pathTypeNames_[searchType]
1164  << " procsDir:" << procsDir << " instance:" << newInstancePath
1165  << endl;
1166  }
1167  }
1168 
1169  // Scatter the information about where the master found the object
1170  // Note: use the worldComm to make sure all processors decide
1171  // the same type. Only procsDir is allowed to differ; searchType
1172  // and instance have to be same
1173  {
1174  label masterType(searchType);
1175  Pstream::scatter(masterType);
1176  searchType = pathType(masterType);
1177  }
1178  Pstream::scatter(newInstancePath);
1179 
1180  if
1181  (
1182  checkGlobal
1183  || searchType == fileOperation::PARENTOBJECT
1184  || searchType == fileOperation::PROCBASEOBJECT
1185  || searchType == fileOperation::PROCBASEINSTANCE
1186  || io.local() == "uniform"
1187  )
1188  {
1189  // Distribute master path. This makes sure it is seen as uniform
1190  // and only gets read from the master.
1191  Pstream::scatter(objPath);
1192  Pstream::scatter(procsDir);
1193  }
1194  else
1195  {
1196  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1197 
1198  // Use the master type to determine if additional information is
1199  // needed to construct the local equivalent
1200  switch (searchType)
1201  {
1205  {
1206  // Already handled above
1207  }
1208  break;
1209 
1217  {
1218  // Construct equivalent local path
1219  objPath = localObjectPath
1220  (
1221  io,
1222  searchType,
1223  procsDir,
1224  newInstancePath
1225  );
1226  }
1227  break;
1228 
1229  case fileOperation::OBJECT:
1231  {
1232  // Retest all processors separately since some processors might
1233  // have the file and some not (e.g. lagrangian data)
1234 
1235  objPath = masterOp<fileName, fileOrNullOp>
1236  (
1237  io.objectPath(),
1238  fileOrNullOp(true),
1239  Pstream::msgType(),
1240  comm_
1241  );
1242  }
1243  break;
1244  }
1245  }
1246 
1247  if (debug)
1248  {
1249  Pout<< "masterUncollatedFileOperation::filePath :"
1250  << " Returning from file searching:" << endl
1251  << " objectPath:" << io.objectPath() << endl
1252  << " filePath :" << objPath << endl << endl;
1253  }
1254  return objPath;
1255 }
1256 
1257 
1260  const bool checkGlobal,
1261  const IOobject& io,
1262  const bool search
1263 ) const
1264 {
1265  if (debug)
1266  {
1267  Pout<< "masterUncollatedFileOperation::dirPath :"
1268  << " objectPath:" << io.objectPath()
1269  << " checkGlobal:" << checkGlobal << endl;
1270  }
1271 
1272  // Now that we have an IOobject path use it to detect & cache
1273  // processor directory naming
1274  (void)lookupProcessorsPath(io.objectPath());
1275 
1276  // Determine master dirPath and scatter
1277 
1278  fileName objPath;
1279  pathType searchType = NOTFOUND;
1280  word procsDir;
1281  word newInstancePath;
1282 
1283  if (Pstream::master(comm_))
1284  {
1285  const bool oldParRun(Pstream::parRun(false));
1286 
1287  objPath = filePathInfo
1288  (
1289  checkGlobal,
1290  false,
1291  io,
1292  search,
1293  searchType,
1294  procsDir,
1295  newInstancePath
1296  );
1297 
1298  Pstream::parRun(oldParRun);
1299  }
1300 
1301  {
1302  label masterType(searchType);
1303  Pstream::scatter(masterType); //, Pstream::msgType(), comm_);
1304  searchType = pathType(masterType);
1305  }
1306  Pstream::scatter(newInstancePath); //, Pstream::msgType(), comm_);
1307 
1308  if
1309  (
1310  checkGlobal
1311  || searchType == fileOperation::PARENTOBJECT
1312  || searchType == fileOperation::PROCBASEOBJECT
1313  || searchType == fileOperation::PROCBASEINSTANCE
1314  || io.local() == "uniform"
1315  )
1316  {
1317  // Distribute master path. This makes sure it is seen as uniform
1318  // and only gets read from the master.
1319  Pstream::scatter(objPath);
1320  Pstream::scatter(procsDir);
1321  }
1322  else
1323  {
1324  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1325 
1326  // Use the master type to determine if additional information is
1327  // needed to construct the local equivalent
1328  switch (searchType)
1329  {
1333  {
1334  // Already handled above
1335  }
1336  break;
1337 
1345  {
1346  // Construct equivalent local path
1347  objPath = localObjectPath
1348  (
1349  io,
1350  searchType,
1351  procsDir,
1352  newInstancePath
1353  );
1354  }
1355  break;
1356 
1357  case fileOperation::OBJECT:
1359  {
1360  // Retest all processors separately since some processors might
1361  // have the file and some not (e.g. lagrangian data)
1362 
1363  objPath = masterOp<fileName, fileOrNullOp>
1364  (
1365  io.objectPath(),
1366  fileOrNullOp(false),
1367  Pstream::msgType(),
1368  comm_
1369  );
1370  }
1371  break;
1372  }
1373  }
1374 
1375  if (debug)
1376  {
1377  Pout<< "masterUncollatedFileOperation::dirPath :"
1378  << " Returning from file searching:" << endl
1379  << " objectPath:" << io.objectPath() << endl
1380  << " filePath :" << objPath << endl << endl;
1381  }
1382  return objPath;
1383 }
1384 
1385 
1388  const dirIndexList& pDirs,
1389  IOobject& io
1390 ) const
1391 {
1392  // Cut-down version of filePathInfo that does not look for
1393  // different instance or parent directory
1394 
1395  const bool isFile = !io.name().empty();
1396 
1397  // Generate output filename for object
1398  const fileName writePath(objectPath(io, word::null));
1399 
1400  // 1. Test writing name for either directory or a (valid) file
1401  if (isFileOrDir(isFile, writePath))
1402  {
1403  return true;
1404  }
1405 
1406  // 2. Check processors/
1407  if (io.time().processorCase())
1408  {
1409  for (const dirIndex& dirIdx : pDirs)
1410  {
1411  const fileName& pDir = dirIdx.first();
1412  fileName procPath =
1413  processorsPath(io, io.instance(), pDir)
1414  /io.name();
1415  if (procPath != writePath && isFileOrDir(isFile, procPath))
1416  {
1417  return true;
1418  }
1419  }
1420  }
1421 
1422  // 3. Check local
1423  fileName localPath = io.objectPath();
1424 
1425  if (localPath != writePath && isFileOrDir(isFile, localPath))
1426  {
1427  return true;
1428  }
1429 
1430  return false;
1431 }
1432 
1433 
1437  const IOobject& startIO,
1438  const scalar startValue,
1439  const word& stopInstance
1440 ) const
1441 {
1442  if (debug)
1443  {
1444  Pout<< "masterUncollatedFileOperation::findInstance :"
1445  << " Starting searching for name:" << startIO.name()
1446  << " local:" << startIO.local()
1447  << " from instance:" << startIO.instance()
1448  << endl;
1449  }
1450 
1451 
1452  const Time& time = startIO.time();
1453 
1454  IOobject io(startIO);
1455 
1456  // Note: - if name is empty, just check the directory itself
1457  // - check both for isFile and headerOk since the latter does a
1458  // filePath so searches for the file.
1459  // - check for an object with local file scope (so no looking up in
1460  // parent directory in case of parallel)
1461 
1462 
1463  refPtr<dirIndexList> pDirs(lookupProcessorsPath(io.objectPath()));
1464 
1465  word foundInstance;
1466 
1467  // if (Pstream::master(comm_))
1469  {
1470  const bool oldParRun(Pstream::parRun(false));
1471  if (exists(pDirs, io))
1472  {
1473  foundInstance = io.instance();
1474  }
1475  Pstream::parRun(oldParRun);
1476  }
1477 
1478  // Do parallel early exit to avoid calling time.times()
1479  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1481  if (!foundInstance.empty())
1482  {
1483  io.instance() = foundInstance;
1484  if (debug)
1485  {
1486  Pout<< "masterUncollatedFileOperation::findInstance :"
1487  << " for name:" << io.name() << " local:" << io.local()
1488  << " found starting instance:" << io.instance() << endl;
1489  }
1490  return io;
1491  }
1492 
1493 
1494  // Search back through the time directories to find the time
1495  // closest to and lower than current time
1496 
1497  instantList ts = time.times();
1498  // if (Pstream::master(comm_))
1500  {
1501  const bool oldParRun(Pstream::parRun(false));
1502 
1503  label instanceI;
1504 
1505  for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
1506  {
1507  if (ts[instanceI].value() <= startValue)
1508  {
1509  break;
1510  }
1511  }
1512 
1513  // continue searching from here
1514  for (; instanceI >= 0; --instanceI)
1515  {
1516  // Shortcut: if actual directory is the timeName we've
1517  // already tested it
1518  if (ts[instanceI].name() == time.timeName())
1519  {
1520  continue;
1521  }
1522 
1523  io.instance() = ts[instanceI].name();
1524  if (exists(pDirs, io))
1525  {
1526  foundInstance = io.instance();
1527  if (debug)
1528  {
1529  Pout<< "masterUncollatedFileOperation::findInstance :"
1530  << " for name:" << io.name() << " local:" << io.local()
1531  << " found at:" << io.instance()
1532  << endl;
1533  }
1534  break;
1535  }
1536 
1537  // Check if hit minimum instance
1538  if (ts[instanceI].name() == stopInstance)
1539  {
1540  if
1541  (
1542  startIO.readOpt() == IOobject::MUST_READ
1544  )
1545  {
1546  if (io.name().empty())
1547  {
1549  << "Cannot find directory "
1550  << io.local() << " in times " << time.timeName()
1551  << " down to " << stopInstance
1552  << exit(FatalError);
1553  }
1554  else
1555  {
1557  << "Cannot find file \"" << io.name()
1558  << "\" in directory " << io.local()
1559  << " in times " << time.timeName()
1560  << " down to " << stopInstance
1561  << exit(FatalError);
1562  }
1563  }
1564  foundInstance = io.instance();
1565  if (debug)
1566  {
1567  Pout<< "masterUncollatedFileOperation::findInstance :"
1568  << " name:" << io.name() << " local:" << io.local()
1569  << " found at stopinstance:" << io.instance() << endl;
1570  }
1571  break;
1572  }
1573  }
1574 
1575 
1576  if (foundInstance.empty())
1577  {
1578  // times() usually already includes the constant() so would
1579  // have been checked above. Re-test if
1580  // - times() is empty. Sometimes this can happen (e.g. decomposePar
1581  // with collated)
1582  // - times()[0] is not constant
1583  if (!ts.size() || ts[0].name() != time.constant())
1584  {
1585  // Note. This needs to be a hard-coded constant, rather than the
1586  // constant function of the time, because the latter points to
1587  // the case constant directory in parallel cases
1588 
1589  io.instance() = time.constant();
1590  if (exists(pDirs, io))
1591  {
1592  if (debug)
1593  {
1594  Pout<< "masterUncollatedFileOperation::findInstance :"
1595  << " name:" << io.name()
1596  << " local:" << io.local()
1597  << " found at:" << io.instance() << endl;
1598  }
1599  foundInstance = io.instance();
1600  }
1601  }
1602  }
1603 
1604  if (foundInstance.empty())
1605  {
1606  if
1607  (
1608  startIO.readOpt() == IOobject::MUST_READ
1610  )
1611  {
1613  << "Cannot find file \"" << io.name() << "\" in directory "
1614  << io.local() << " in times " << startIO.instance()
1615  << " down to " << time.constant()
1616  << exit(FatalError);
1617  }
1618  else
1619  {
1620  foundInstance = time.constant();
1621  }
1622  }
1623  Pstream::parRun(oldParRun);
1624  }
1625 
1626  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1628  io.instance() = foundInstance;
1629  if (debug)
1630  {
1631  Pout<< "masterUncollatedFileOperation::findInstance :"
1632  << " name:" << io.name() << " local:" << io.local()
1633  << " returning instance:" << io.instance() << endl;
1634  }
1635  return io;
1636 }
1637 
1638 
1642  const objectRegistry& db,
1643  const fileName& instance,
1644  const fileName& local,
1645  word& newInstance
1646 ) const
1647 {
1648  if (debug)
1649  {
1650  Pout<< "masterUncollatedFileOperation::readObjects :"
1651  << " db:" << db.objectPath()
1652  << " local:" << local << " instance:" << instance << endl;
1653  }
1654 
1655  fileNameList objectNames;
1656  newInstance = word::null;
1657 
1658  // Note: readObjects uses WORLD to make sure order of objects is the
1659  // same everywhere
1660 
1661  if (Pstream::master()) // comm_))
1662  {
1663  // Avoid fileOperation::readObjects from triggering parallel ops
1664  // (through call to filePath which triggers parallel )
1665  const bool oldParRun = UPstream::parRun(false);
1666 
1667  //- Use non-time searching version
1668  objectNames = fileOperation::readObjects
1669  (
1670  db,
1671  instance,
1672  local,
1673  newInstance
1674  );
1675 
1676  if (newInstance.empty())
1677  {
1678  // Find similar time
1679 
1680  // Copy of Time::findInstancePath. We want to avoid the
1681  // parallel call to findTimes. Alternative is to have
1682  // version of findInstancePath that takes instantList ...
1683  const instantList timeDirs
1684  (
1686  (
1687  db.time().path(),
1688  db.time().constant()
1689  )
1690  );
1691 
1692  const instant t(instance);
1693  forAllReverse(timeDirs, i)
1694  {
1695  if (t.equal(timeDirs[i].value()))
1696  {
1697  objectNames = fileOperation::readObjects
1698  (
1699  db,
1700  timeDirs[i].name(), // newly found time
1701  local,
1702  newInstance
1703  );
1704  break;
1705  }
1706  }
1707  }
1708 
1709  UPstream::parRun(oldParRun); // Restore parallel state
1710  }
1711 
1712  Pstream::scatter(newInstance); //, Pstream::msgType(), comm_);
1713  Pstream::scatter(objectNames); //, Pstream::msgType(), comm_);
1714 
1715  if (debug)
1716  {
1717  Pout<< "masterUncollatedFileOperation::readObjects :"
1718  << " newInstance:" << newInstance
1719  << " objectNames:" << objectNames << endl;
1720  }
1721 
1722  return objectNames;
1723 }
1724 
1725 
1728  IOobject& io,
1729  const fileName& fName,
1730  const word& typeName
1731 ) const
1732 {
1733  bool ok = false;
1734 
1735  if (debug)
1736  {
1737  Pout<< "masterUncollatedFileOperation::readHeader :" << endl
1738  << " objectPath:" << io.objectPath() << endl
1739  << " filePath :" << fName << endl;
1740  }
1741 
1742  // Get filePaths on world master
1744  filePaths[Pstream::myProcNo(Pstream::worldComm)] = fName;
1746  bool uniform = uniformFile(filePaths);
1748 
1749  if (uniform)
1750  {
1752  {
1753  if (!fName.empty())
1754  {
1755  IFstream is(fName);
1756 
1757  if (is.good())
1758  {
1759  // Regular header or from decomposed data
1760  ok = decomposedBlockData::readHeader(io, is);
1761  }
1762  }
1763  }
1766  (
1767  io.headerClassName(),
1768  Pstream::msgType(),
1770  );
1772  }
1773  else
1774  {
1776  {
1777  // Re-gather file paths on local master
1778  filePaths.setSize(Pstream::nProcs(comm_));
1779  filePaths[Pstream::myProcNo(comm_)] = fName;
1780  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
1781  }
1782 
1783  boolList result(Pstream::nProcs(comm_), false);
1784  wordList headerClassName(Pstream::nProcs(comm_));
1785  stringList note(Pstream::nProcs(comm_));
1786  if (Pstream::master(comm_))
1787  {
1788  forAll(filePaths, proci)
1789  {
1790  if (!filePaths[proci].empty())
1791  {
1792  if (proci > 0 && filePaths[proci] == filePaths[proci-1])
1793  {
1794  result[proci] = result[proci-1];
1795  headerClassName[proci] = headerClassName[proci-1];
1796  note[proci] = note[proci-1];
1797  }
1798  else
1799  {
1800  IFstream is(filePaths[proci]);
1801 
1802  if (is.good())
1803  {
1804  result[proci] =
1806  headerClassName[proci] = io.headerClassName();
1807  note[proci] = io.note();
1808  }
1809  }
1810  }
1811  }
1812  }
1813  ok = scatterList(result, Pstream::msgType(), comm_);
1814  io.headerClassName() = scatterList
1815  (
1816  headerClassName,
1817  Pstream::msgType(),
1818  comm_
1819  );
1820  io.note() = scatterList(note, Pstream::msgType(), comm_);
1821  }
1822 
1823  if (debug)
1824  {
1825  Pout<< "masterUncollatedFileOperation::readHeader :" << " ok:" << ok
1826  << " class:" << io.headerClassName() << endl;
1827  }
1828  return ok;
1829 }
1830 
1831 
1835  regIOobject& io,
1836  const fileName& fName,
1837  const word& typeName,
1838  const bool valid
1839 ) const
1840 {
1841  if (debug)
1842  {
1843  Pout<< "masterUncollatedFileOperation::readStream :"
1844  << " object : " << io.name()
1845  << " global : " << io.global()
1846  << " fName : " << fName << " valid:" << valid << endl;
1847  }
1848 
1849 
1850  autoPtr<ISstream> isPtr;
1851  bool isCollated = false;
1852  IOobject headerIO(io);
1853 
1854  // Detect collated format. This could be done on the local communicator
1855  // but we do it on the master node only for now.
1856  if (UPstream::master()) // comm_))
1857  {
1858  if (!fName.empty())
1859  {
1860  // This can happen in lagrangian field reading some processors
1861  // have no file to read from. This will only happen when using
1862  // normal writing since then the fName for the valid processors is
1863  // processorDDD/<instance>/.. . In case of collocated writing
1864  // the fName is already rewritten to processorsNN/.
1865 
1866  isPtr.reset(new IFstream(fName));
1867 
1868  if (isPtr->good())
1869  {
1870  // Read header data (on copy)
1871  headerIO.readHeader(*isPtr);
1872 
1873  isCollated = decomposedBlockData::isCollatedType(headerIO);
1874 
1875  if (!isCollated && !Pstream::parRun())
1876  {
1877  // Short circuit: non-collated format. No parallel bits.
1878  // Copy header and return.
1879  if (debug)
1880  {
1881  Pout<< "masterUncollatedFileOperation::readStream :"
1882  << " For object : " << io.name()
1883  << " doing straight IFstream input from "
1884  << fName << endl;
1885  }
1886  io = headerIO;
1887  return isPtr;
1888  }
1889  }
1890 
1891  if (!isCollated)
1892  {
1893  // Close file. Reopened below.
1894  isPtr.clear();
1895  }
1896  }
1897  }
1898 
1899  Pstream::scatter(isCollated); //, Pstream::msgType(), comm_);
1900 
1901  if (isCollated)
1902  {
1903  if (debug)
1904  {
1905  Pout<< "masterUncollatedFileOperation::readStream :"
1906  << " For object : " << io.name()
1907  << " starting collating input from " << fName << endl;
1908  }
1909 
1910 
1911  // Analyse the file path (on (co)master) to see the processors type
1912  // Note: this should really be part of filePath() which should return
1913  // both file and index in file.
1914 
1915  fileName path, procDir, local;
1917  label nProcs;
1918  splitProcessorPath(fName, path, procDir, local, group, nProcs);
1919 
1920 
1921  if (!Pstream::parRun())
1922  {
1923  // Analyse the objectpath to find out the processor we're trying
1924  // to access
1925  label proci = detectProcessorPath(io.objectPath());
1926 
1927  if (proci == -1)
1928  {
1929  FatalIOErrorInFunction(*isPtr)
1930  << "Could not detect processor number"
1931  << " from objectPath:" << io.objectPath()
1932  << exit(FatalIOError);
1933  }
1934 
1935  // The local rank (offset)
1936  if (!group.empty())
1937  {
1938  proci = proci - group.start();
1939  }
1940 
1941  if (debug)
1942  {
1943  Pout<< "masterUncollatedFileOperation::readStream :"
1944  << " For object : " << io.name()
1945  << " starting input from block " << proci
1946  << " of " << isPtr->name() << endl;
1947  }
1948 
1949  return decomposedBlockData::readBlock(proci, *isPtr, io);
1950  }
1951  else
1952  {
1953  // Get size of file
1954  off_t sz = Foam::fileSize(fName);
1955  bool bigSize = sz > off_t(maxMasterFileBufferSize);
1956  Pstream::scatter(bigSize);
1957 
1958  // Are we reading from single-master file ('processors256') or
1959  // from multi-master files ('processors256_0-9')
1960  label readComm = -1;
1961  if (!group.empty())
1962  {
1963  readComm = comm_;
1964  if (UPstream::master(comm_) && !isPtr && !fName.empty())
1965  {
1966  // In multi-master mode also open the file on the other
1967  // masters
1968  isPtr.reset(new IFstream(fName));
1969 
1970  if (isPtr->good())
1971  {
1972  // Read header data (on copy)
1973  IOobject headerIO(io);
1974  headerIO.readHeader(*isPtr);
1975  }
1976  }
1977  }
1978  else
1979  {
1980  // Single master so read on world
1981  readComm = Pstream::worldComm;
1982  }
1983 
1984  // Read my data
1986  (
1987  readComm,
1988  fName,
1989  isPtr,
1990  io,
1991  (
1992  bigSize
1995  )
1996  );
1997  }
1998  }
1999  else
2000  {
2001  if (debug)
2002  {
2003  Pout<< "masterUncollatedFileOperation::readStream :"
2004  << " For object : " << io.name()
2005  << " starting separated input from " << fName << endl;
2006  }
2007 
2008  if (io.global())
2009  {
2010  // Use worldComm. Note: should not really need to gather filePaths
2011  // since we enforce sending from master anyway ...
2012  fileNameList filePaths(Pstream::nProcs());
2013  filePaths[Pstream::myProcNo()] = fName;
2014  Pstream::gatherList(filePaths);
2015  boolList procValid(Pstream::nProcs());
2016  procValid[Pstream::myProcNo()] = valid;
2017  Pstream::gatherList(procValid);
2018 
2019  return read(io, Pstream::worldComm, true, filePaths, procValid);
2020  }
2021  else
2022  {
2023  // Use local communicator
2024  fileNameList filePaths(Pstream::nProcs(comm_));
2025  filePaths[Pstream::myProcNo(comm_)] = fName;
2026  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
2027  boolList procValid(Pstream::nProcs(comm_));
2028  procValid[Pstream::myProcNo(comm_)] = valid;
2029  Pstream::gatherList(procValid, Pstream::msgType(), comm_);
2030 
2031  // Uniform in local comm
2032  const bool uniform = uniformFile(filePaths);
2033 
2034  return read(io, comm_, uniform, filePaths, procValid);
2035  }
2036  }
2037 }
2038 
2039 
2042  regIOobject& io,
2043  const bool masterOnly,
2045  const word& typeName
2046 ) const
2047 {
2048  bool ok = true;
2049 
2050  if (io.globalObject())
2051  {
2052  if (debug)
2053  {
2054  Pout<< "masterUncollatedFileOperation::read :"
2055  << " Reading global object " << io.name() << endl;
2056  }
2057 
2058  bool ok = false;
2059  if (Pstream::master()) // comm_))
2060  {
2061  // Do master-only reading always.
2062  const bool oldParRun = UPstream::parRun(false);
2063 
2064  ok = io.readData(io.readStream(typeName));
2065  io.close();
2066 
2067  UPstream::parRun(oldParRun); // Restore parallel state
2068  }
2069 
2070  Pstream::scatter(ok); //, Pstream::msgType(), comm_);
2071  Pstream::scatter(io.headerClassName()); //, Pstream::msgType(), comm_);
2072  Pstream::scatter(io.note()); //, Pstream::msgType(), comm_);
2073 
2074 
2075  // scatter operation for regIOobjects
2076 
2077  // Get my communication order
2078  // const List<Pstream::commsStruct>& comms =
2079  //(
2080  // (Pstream::nProcs(comm_) < Pstream::nProcsSimpleSum)
2081  // ? Pstream::linearCommunication(comm_)
2082  // : Pstream::treeCommunication(comm_)
2083  //);
2084  // const Pstream::commsStruct& myComm = comms[Pstream::myProcNo(comm_)];
2085  const List<Pstream::commsStruct>& comms =
2086  (
2090  );
2091  const Pstream::commsStruct& myComm =
2093 
2094  // Receive from up
2095  if (myComm.above() != -1)
2096  {
2097  IPstream fromAbove
2098  (
2100  myComm.above(),
2101  0,
2102  Pstream::msgType(),
2103  Pstream::worldComm, // comm_,
2104  format
2105  );
2106  ok = io.readData(fromAbove);
2107  }
2108 
2109  // Send to my downstairs neighbours
2110  forAll(myComm.below(), belowI)
2111  {
2112  OPstream toBelow
2113  (
2115  myComm.below()[belowI],
2116  0,
2117  Pstream::msgType(),
2118  Pstream::worldComm, // comm_,
2119  format
2120  );
2121  bool okWrite = io.writeData(toBelow);
2122  ok = ok && okWrite;
2123  }
2124  }
2125  else
2126  {
2127  if (debug)
2128  {
2129  Pout<< "masterUncollatedFileOperation::read :"
2130  << " Reading local object " << io.name() << endl;
2131  }
2132 
2133  ok = io.readData(io.readStream(typeName));
2134  io.close();
2135  }
2136 
2137  return ok;
2138 }
2139 
2140 
2143  const regIOobject& io,
2144  IOstreamOption streamOpt,
2145  const bool valid
2146 ) const
2147 {
2148  fileName pathName(io.objectPath());
2149 
2150  if (debug)
2151  {
2152  Pout<< "masterUncollatedFileOperation::writeObject :"
2153  << " io:" << pathName << " valid:" << valid << endl;
2154  }
2155 
2156  // Make sure to pick up any new times
2157  setTime(io.time());
2158 
2159  // Update meta-data for current state
2160  const_cast<regIOobject&>(io).updateMetaData();
2161 
2162  autoPtr<OSstream> osPtr(NewOFstream(pathName, streamOpt, valid));
2163  OSstream& os = *osPtr;
2164 
2165  // If any of these fail, return (leave error handling to Ostream class)
2166 
2167  const bool ok =
2168  (
2169  os.good()
2170  && io.writeHeader(os)
2171  && io.writeData(os)
2172  );
2173 
2174  if (ok)
2175  {
2177  }
2178 
2179  return ok;
2180 }
2181 
2182 
2185  const fileName& directory,
2186  const word& constantName
2187 ) const
2188 {
2189  const auto iter = times_.cfind(directory);
2190  if (iter.found())
2191  {
2192  if (debug)
2193  {
2194  Pout<< "masterUncollatedFileOperation::findTimes :"
2195  << " Found " << iter()->size() << " cached times" << endl;
2196  }
2197  return *iter();
2198  }
2199  else
2200  {
2201  instantList times;
2202  if (Pstream::master()) // comm_))
2203  {
2204  // Do master-only reading always.
2205  const bool oldParRun = UPstream::parRun(false);
2206 
2207  times = fileOperation::findTimes(directory, constantName);
2208 
2209  UPstream::parRun(oldParRun); // Restore parallel state
2210  }
2211  Pstream::scatter(times); //, Pstream::msgType(), comm_);
2212 
2213  // Note: do we also cache if no times have been found since it might
2214  // indicate a directory that is being filled later on ...
2215 
2216  instantList* tPtr = new instantList(std::move(times));
2217 
2218  times_.set(directory, tPtr);
2219 
2220  if (debug)
2221  {
2222  Pout<< "masterUncollatedFileOperation::findTimes :"
2223  << " Caching times:" << *tPtr << nl
2224  << " for directory:" << directory << endl;
2225  }
2226  return *tPtr;
2227  }
2228 }
2229 
2230 
2233  const Time& tm
2234 ) const
2235 {
2236  if (tm.subCycling())
2237  {
2238  return;
2239  }
2240 
2241  // Mutable access to instantList for modification and sorting
2242  // - cannot use auto type deduction here
2243 
2244  HashPtrTable<instantList>::iterator iter = times_.find(tm.path());
2245 
2246  if (iter.found())
2247  {
2248  instantList& times = *iter();
2249 
2250  const instant timeNow(tm.value(), tm.timeName());
2251 
2252  // Exclude constant when checking and sorting
2253  const label skipConst =
2254  (
2255  (!times.empty() && times[0].name() == tm.constant())
2256  ? 1
2257  : 0
2258  );
2259 
2260  if
2261  (
2263  (
2264  SubList<instant>(times, times.size()-skipConst, skipConst),
2265  timeNow
2266  )
2267  == -1
2268  )
2269  {
2270  if (debug)
2271  {
2272  Pout<< "masterUncollatedFileOperation::setTime :"
2273  << " Caching time " << tm.timeName()
2274  << " for case:" << tm.path() << endl;
2275  }
2276 
2277  times.append(timeNow);
2278  SubList<instant> realTimes
2279  (
2280  times, times.size()-skipConst, skipConst
2281  );
2282  Foam::stableSort(realTimes);
2283  }
2284  }
2285 
2287 }
2288 
2289 
2293  const fileName& filePath
2294 ) const
2295 {
2296  autoPtr<ISstream> isPtr;
2297 
2298  if (Pstream::parRun())
2299  {
2300  // Insert logic of filePath. We assume that if a file is absolute
2301  // on the master it is absolute also on the slaves etc.
2302 
2304  filePaths[Pstream::myProcNo(Pstream::worldComm)] = filePath;
2306 
2307  PstreamBuffers pBufs
2308  (
2310  Pstream::msgType(),
2312  );
2313 
2315  {
2316  const bool uniform = uniformFile(filePaths);
2317 
2318  if (uniform)
2319  {
2320  if (debug)
2321  {
2322  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2323  << " Opening global file " << filePath << endl;
2324  }
2325 
2326  readAndSend
2327  (
2328  filePath,
2330  pBufs
2331  );
2332  }
2333  else
2334  {
2335  for (const int proci : Pstream::subProcs(Pstream::worldComm))
2336  {
2337  readAndSend
2338  (
2339  filePaths[proci],
2340  labelList(one{}, proci),
2341  pBufs
2342  );
2343  }
2344  }
2345  }
2346 
2347 
2348  labelList recvSizes;
2349  pBufs.finishedSends(recvSizes);
2350 
2352  {
2353  // Read myself
2354  isPtr.reset(new IFstream(filePaths[Pstream::masterNo()]));
2355  }
2356  else
2357  {
2358  if (debug)
2359  {
2360  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2361  << " Reading " << filePath
2362  << " from processor " << Pstream::masterNo() << endl;
2363  }
2364 
2365  UIPstream is(Pstream::masterNo(), pBufs);
2366 
2367  List<char> buf(recvSizes[Pstream::masterNo()]);
2368  is.read(buf.data(), buf.size());
2369 
2370  if (debug)
2371  {
2372  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2373  << " Done reading " << buf.size() << " bytes" << endl;
2374  }
2375 
2376  // A local character buffer copy of the Pstream contents.
2377  // Construct with same parameters (ASCII, current version)
2378  // as the IFstream so that it has the same characteristics.
2379 
2380  isPtr.reset(new IListStream(std::move(buf)));
2381 
2382  // With the proper file name
2383  isPtr->name() = filePath;
2384  }
2385  }
2386  else
2387  {
2388  // Read myself
2389  isPtr.reset(new IFstream(filePath));
2390  }
2391 
2392  return isPtr;
2393 }
2394 
2395 
2399  const fileName& pathName,
2400  IOstreamOption streamOpt,
2401  const bool valid
2402 ) const
2403 {
2404  return autoPtr<OSstream>
2405  (
2406  new masterOFstream
2407  (
2408  pathName,
2409  streamOpt,
2410  false, // append=false
2411  valid
2412  )
2413  );
2414 }
2415 
2416 
2418 {
2420  times_.clear();
2421 }
2422 
2423 
2426  const fileName& fName
2427 ) const
2428 {
2429  label watchFd = -1;
2430  if (Pstream::master()) // comm_))
2431  {
2432  watchFd = monitor().addWatch(fName);
2433  }
2434  Pstream::scatter(watchFd); //, Pstream::msgType(), comm_);
2435  return watchFd;
2436 }
2437 
2438 
2441  const label watchIndex
2442 ) const
2443 {
2444  bool ok = false;
2445  if (Pstream::master()) // comm_))
2446  {
2447  ok = monitor().removeWatch(watchIndex);
2448  }
2449  Pstream::scatter(ok); //, Pstream::msgType(), comm_);
2450  return ok;
2451 }
2452 
2453 
2456  const labelList& watchIndices,
2457  const fileName& fName
2458 ) const
2459 {
2460  label index = -1;
2461 
2462  if (Pstream::master()) // comm_))
2463  {
2464  forAll(watchIndices, i)
2465  {
2466  if (monitor().getFile(watchIndices[i]) == fName)
2467  {
2468  index = i;
2469  break;
2470  }
2471  }
2472  }
2473  Pstream::scatter(index); //, Pstream::msgType(), comm_);
2474  return index;
2475 }
2476 
2477 
2480  regIOobject& rio,
2481  const fileNameList& files
2482 ) const
2483 {
2484  const labelList& watchIndices = rio.watchIndices();
2485 
2486  DynamicList<label> newWatchIndices;
2487  labelHashSet removedWatches(watchIndices);
2488 
2489  for (const fileName& f : files)
2490  {
2491  const label index = findWatch(watchIndices, f);
2492 
2493  if (index == -1)
2494  {
2495  newWatchIndices.append(addWatch(f));
2496  }
2497  else
2498  {
2499  // Existing watch
2500  newWatchIndices.append(watchIndices[index]);
2501  removedWatches.erase(index);
2502  }
2503  }
2504 
2505  // Remove any unused watches
2506  for (const label index : removedWatches)
2507  {
2508  removeWatch(watchIndices[index]);
2509  }
2510 
2511  rio.watchIndices() = newWatchIndices;
2512 }
2513 
2514 
2517  const label watchIndex
2518 ) const
2519 {
2520  fileName fName;
2521  if (Pstream::master()) // comm_))
2522  {
2523  fName = monitor().getFile(watchIndex);
2524  }
2525  Pstream::scatter(fName); //, Pstream::msgType(), comm_);
2526  return fName;
2527 }
2528 
2529 
2532  const bool masterOnly,
2533  const bool syncPar
2534 ) const
2535 {
2536  if (Pstream::master()) // comm_))
2537  {
2538  monitor().updateStates(true, false);
2539  }
2540 }
2541 
2542 
2546  const label watchFd
2547 ) const
2548 {
2549  unsigned int state = fileMonitor::UNMODIFIED;
2550  if (Pstream::master()) // comm_))
2551  {
2552  state = monitor().getState(watchFd);
2553  }
2554  Pstream::scatter(state); //, Pstream::msgType(), comm_);
2555  return fileMonitor::fileState(state);
2556 }
2557 
2558 
2561  const label watchFd
2562 ) const
2563 {
2564  if (Pstream::master()) // comm_))
2565  {
2566  monitor().setUnmodified(watchFd);
2567  }
2568 }
2569 
2570 
2571 // ************************************************************************* //
Foam::fileOperations::masterUncollatedFileOperation::setUnmodified
virtual void setUnmodified(const label) const
Set current state of file (using handle) to unmodified.
Definition: masterUncollatedFileOperation.C:2560
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::fileOperations::masterUncollatedFileOperation::type
virtual fileName::Type type(const fileName &, const bool followLink=true) const
Return the file type: DIRECTORY, FILE or LINK.
Definition: masterUncollatedFileOperation.C:875
Foam::fileOperations::masterUncollatedFileOperation::getFile
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
Definition: masterUncollatedFileOperation.C:2516
Foam::UPstream::linearCommunication
static const List< commsStruct > & linearCommunication(const label communicator=worldComm)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.H:523
Foam::fileOperation::WRITEOBJECT
write path exists
Definition: fileOperation.H:78
Foam::TimePaths::globalCaseName
const fileName & globalCaseName() const
Return global case name.
Definition: TimePathsI.H:56
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::fileOperations::masterUncollatedFileOperation::cp
virtual bool cp(const fileName &src, const fileName &dst, const bool followLink=true) const
Copy, recursively if necessary, the source to the destination.
Definition: masterUncollatedFileOperation.C:1057
Foam::fileOperations::masterUncollatedFileOperation::setTime
virtual void setTime(const Time &) const
Callback for time change.
Definition: masterUncollatedFileOperation.C:2232
Foam::fileOperations::masterUncollatedFileOperation::readAndSend
static void readAndSend(const fileName &filePath, const labelUList &procs, PstreamBuffers &pBufs)
Read file contents and send to processors.
Definition: masterUncollatedFileOperation.C:496
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
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
SubList.H
Foam::fileOperations::masterUncollatedFileOperation::dirPath
virtual fileName dirPath(const bool checkGlobal, const IOobject &io, const bool search) const
Search for a directory. checkGlobal : also check undecomposed.
Definition: masterUncollatedFileOperation.C:1259
Foam::fileOperations::masterUncollatedFileOperation::lastModifiedOp
Definition: masterUncollatedFileOperation.H:227
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::fileOperation
An encapsulation of filesystem-related operations.
Definition: fileOperation.H:68
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:57
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::fileMonitor::UNMODIFIED
Definition: fileMonitor.H:75
Foam::fileOperations::masterUncollatedFileOperation::mvBakOp
Definition: masterUncollatedFileOperation.H:259
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:63
Foam::fileOperations::masterUncollatedFileOperation::uniformFile
static bool uniformFile(const fileNameList &)
Same file?
Definition: masterUncollatedFileOperation.C:478
Foam::fileOperations::masterUncollatedFileOperation::readDir
virtual fileNameList readDir(const fileName &, const fileName::Type=fileName::FILE, const bool filtergz=true, const bool followLink=true) const
Read a directory and return the entries as a string list.
Definition: masterUncollatedFileOperation.C:1039
Foam::constant::atomic::group
constexpr const char *const group
Group name for atomic constants.
Definition: atomicConstants.H:52
Foam::fileOperation::PARENTOBJECT
parent of object path
Definition: fileOperation.H:89
Foam::IOobject::instance
const fileName & instance() const noexcept
Definition: IOobjectI.H:196
Foam::fileOperations::masterUncollatedFileOperation::rmDirOp
Definition: masterUncollatedFileOperation.H:283
Foam::fileOperations::masterUncollatedFileOperation::lastModifiedHROp
Definition: masterUncollatedFileOperation.H:243
Foam::regIOobject::watchIndices
const labelList & watchIndices() const
Return file-monitoring handles.
Definition: regIOobjectI.H:196
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:53
Foam::DynamicList< label >
Foam::IntRange
An interval of (signed) integers defined by a start and a size.
Definition: IntRange.H:63
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
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::dummyISstream
Dummy input stream, which can be used as a placeholder for interfaces taking an Istream or ISstream....
Definition: dummyISstream.H:56
masterOFstream.H
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
Foam::IOobject::rootPath
const fileName & rootPath() const
Definition: IOobject.C:499
Foam::fileOperations::masterUncollatedFileOperation::mode
virtual mode_t mode(const fileName &, const bool followLink=true) const
Return the file mode.
Definition: masterUncollatedFileOperation.C:859
Foam::TimePaths::processorCase
bool processorCase() const noexcept
Return true if this is a processor case.
Definition: TimePathsI.H:36
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:88
Foam::fileOperations::masterUncollatedFileOperation::isFile
virtual bool isFile(const fileName &, const bool checkGzip=true, const bool followLink=true) const
Does the name exist as a FILE in the file system?
Definition: masterUncollatedFileOperation.C:927
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::fileOperation::OBJECT
io.objectPath() exists
Definition: fileOperation.H:77
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
Foam::fileOperations::masterUncollatedFileOperation::fileSize
virtual off_t fileSize(const fileName &, const bool followLink=true) const
Return size of file.
Definition: masterUncollatedFileOperation.C:944
Foam::fileName::Type
Type
Enumerations to handle directory entry types.
Definition: fileName.H:80
Foam::one
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:61
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::regIOobject::global
virtual bool global() const
Is object global.
Definition: regIOobject.H:354
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::IListStream
An ISstream with internal List storage. Always UNCOMPRESSED.
Definition: IListStream.H:132
Foam::fileOperations::addNamedToRunTimeSelectionTable
addNamedToRunTimeSelectionTable(fileOperationInitialise, collatedFileOperationInitialise, word, collated)
Foam::List::append
void append(const T &val)
Append an element at the end of the list.
Definition: ListI.H:175
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
instant.H
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
Foam::Instant::equal
bool equal(scalar val) const
True if values are equal (includes SMALL for rounding)
Definition: Instant.C:59
Foam::fileOperations::masterUncollatedFileOperation::mv
virtual bool mv(const fileName &src, const fileName &dst, const bool followLink=false) const
Rename src to dst.
Definition: masterUncollatedFileOperation.C:1092
Foam::IOobject::headerClassName
const word & headerClassName() const noexcept
Return name of the class name read from header.
Definition: IOobjectI.H:83
Foam::fileOperations::masterUncollatedFileOperation::maxMasterFileBufferSize
static float maxMasterFileBufferSize
Max size of parallel communications. Switches from non-blocking.
Definition: masterUncollatedFileOperation.H:484
Foam::fileOperations::masterUncollatedFileOperation::chMod
virtual bool chMod(const fileName &, const mode_t) const
Set the file mode.
Definition: masterUncollatedFileOperation.C:843
Foam::fileOperation::ABSOLUTE
instance is absolute directory
Definition: fileOperation.H:76
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::UPstream::commsStruct::below
const labelList & below() const noexcept
Definition: UPstream.H:135
Foam::HashSet< label, Hash< label > >
bitSet.H
Foam::IOobject::time
const Time & time() const
Return Time associated with the objectRegistry.
Definition: IOobject.C:493
Foam::instantList
List< instant > instantList
List of instants.
Definition: instantList.H:44
setTime
runTimeSource setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex)
Foam::UIPstream::read
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=UPstream::worldComm)
Read into given buffer from given processor.
Definition: UIPread.C:81
Foam::fileOperation::FINDINSTANCE
file found in time directory
Definition: fileOperation.H:90
Foam::fileOperations::masterUncollatedFileOperation::isDirOp
Definition: masterUncollatedFileOperation.H:178
Foam::fileOperation::findTimes
virtual instantList findTimes(const fileName &, const word &) const
Get sorted list of times.
Definition: fileOperation.C:949
Foam::fileOperations::masterUncollatedFileOperation::~masterUncollatedFileOperation
virtual ~masterUncollatedFileOperation()
Destructor.
Definition: masterUncollatedFileOperation.C:815
Foam::fileOperations::masterUncollatedFileOperation::fileOrNullOp
Definition: masterUncollatedFileOperation.H:342
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::stableSort
void stableSort(UList< T > &a)
Definition: UList.C:275
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::fileOperations::masterUncollatedFileOperation::typeOp
Definition: masterUncollatedFileOperation.H:146
Foam::IOobject::readHeader
bool readHeader(Istream &is)
Definition: IOobjectReadHeader.C:165
dummyISstream.H
Foam::fileOperations::registerOptSwitch
registerOptSwitch("maxThreadFileBufferSize", float, collatedFileOperation::maxThreadFileBufferSize)
Foam::fileOperation::NOTFOUND
Not found.
Definition: fileOperation.H:75
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::mode
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Definition: MSwindows.C:564
Foam::Time::subCycling
label subCycling() const
Definition: Time.H:515
Foam::fileOperations::masterUncollatedFileOperation::readStream
virtual autoPtr< ISstream > readStream(regIOobject &, const fileName &, const word &typeName, const bool valid=true) const
Reads header for regIOobject and returns an ISstream.
Definition: masterUncollatedFileOperation.C:1834
Foam::fileOperations::masterUncollatedFileOperation::modeOp
Definition: masterUncollatedFileOperation.H:131
Foam::uniform
Definition: uniform.H:50
n
label n
Definition: TABSMDCalcMethod2.H:31
format
word format(conversionProperties.get< word >("format"))
Foam::fileOperations::masterUncollatedFileOperation::read
static autoPtr< ISstream > read(IOobject &io, const label comm, const bool uniform, const fileNameList &filePaths, const boolList &procValid)
Read files on comms master.
Definition: masterUncollatedFileOperation.C:569
NotImplemented
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:517
Foam::objectRegistry::dbDir
virtual const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
Definition: objectRegistry.H:187
Foam::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:515
Foam::fileSize
off_t fileSize(const fileName &name, const bool followLink=true)
Return size of file or -1 on failure (normally follows symbolic links).
Definition: MSwindows.C:676
Foam::fileOperations::masterUncollatedFileOperation::filePath
virtual fileName filePath(const bool checkGlobal, const IOobject &io, const word &typeName, const bool search) const
Search for an object. checkGlobal : also check undecomposed case.
Definition: masterUncollatedFileOperation.C:1110
Foam::fileOperations::masterUncollatedFileOperation::myComm_
const label myComm_
Any communicator allocated by me.
Definition: masterUncollatedFileOperation.H:93
Foam::fileOperations::masterUncollatedFileOperation::fileSizeOp
Definition: masterUncollatedFileOperation.H:211
Foam::fileOperations::masterUncollatedFileOperation::rmOp
Definition: masterUncollatedFileOperation.H:274
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::fileOperation::setTime
virtual void setTime(const Time &) const
Callback for time change.
Definition: fileOperation.H:548
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::decomposedBlockData::readBlocks
static bool readBlocks(const label comm, autoPtr< ISstream > &isPtr, List< char > &contentChars, const UPstream::commsTypes commsType)
Read data into *this. ISstream is only valid on master.
Definition: decomposedBlockData.C:305
Foam::fileOperations::masterUncollatedFileOperation::lastModified
virtual time_t lastModified(const fileName &, const bool followLink=true) const
Return time of last file modification.
Definition: masterUncollatedFileOperation.C:960
Foam::fileOperations::masterUncollatedFileOperation::writeObject
virtual bool writeObject(const regIOobject &io, IOstreamOption streamOpt=IOstreamOption(), const bool valid=true) const
Writes a regIOobject (so header, contents and divider).
Definition: masterUncollatedFileOperation.C:2142
Foam::IOobject::caseName
const fileName & caseName() const
Definition: IOobject.C:505
Foam::fileOperations::addToRunTimeSelectionTable
addToRunTimeSelectionTable(fileOperation, collatedFileOperation, word)
Foam::IOobject::globalObject
bool globalObject() const noexcept
Is object same for all processors?
Definition: IOobjectI.H:121
Foam::fileOperations::masterUncollatedFileOperation::findWatch
virtual label findWatch(const labelList &watchIndices, const fileName &) const
Find index (or -1) of file in list of handles.
Definition: masterUncollatedFileOperation.C:2455
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::PROCBASEOBJECT
objectPath exists in 'processorsNN'
Definition: fileOperation.H:84
Foam::fileOperations::masterUncollatedFileOperation::exists
bool exists(const dirIndexList &, IOobject &io) const
Helper: check IO for local existence. Like filePathInfo but.
Definition: masterUncollatedFileOperation.C:1387
Foam::autoPtr::good
bool good() const noexcept
True if the managed pointer is non-null.
Definition: autoPtr.H:145
Foam::OSstream
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:54
Foam::fileOperations::masterUncollatedFileOperation::existsOp
Definition: masterUncollatedFileOperation.H:161
Foam::fileOperations::masterUncollatedFileOperation::cpOp
Definition: masterUncollatedFileOperation.H:301
Foam::findSortedIndex
label findSortedIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
Foam::UPstream::freeCommunicator
static void freeCommunicator(const label communicator, const bool doPstream=true)
Free a previously allocated communicator.
Definition: UPstream.C:174
Foam::fileOperations::masterUncollatedFileOperation::highResLastModified
virtual double highResLastModified(const fileName &, const bool followLink=true) const
Return time of last file modification.
Definition: masterUncollatedFileOperation.C:976
Foam::fileOperations::masterUncollatedFileOperation::removeWatch
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
Definition: masterUncollatedFileOperation.C:2440
DetailInfo
#define DetailInfo
Definition: evalEntry.C:37
IFstream.H
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done.
Definition: PstreamBuffers.C:73
Foam::fileOperations::masterUncollatedFileOperation::masterUncollatedFileOperation
masterUncollatedFileOperation(bool verbose)
Default construct.
Definition: masterUncollatedFileOperation.C:724
Foam::IOstreamOption::streamFormat
streamFormat
Data format (ascii | binary)
Definition: IOstreamOption.H:70
Foam::FatalError
error FatalError
Foam::fileOperations::masterUncollatedFileOperation::updateStates
virtual void updateStates(const bool masterOnly, const bool syncPar) const
Update state of all files.
Definition: masterUncollatedFileOperation.C:2531
Foam::fileOperation::PROCUNCOLLATEDINSTANCE
as PROCUNCOLLATED but with instance
Definition: fileOperation.H:91
Foam::decomposedBlockData::isCollatedType
static bool isCollatedType(const word &objectType)
True if object type is a known collated type.
Definition: decomposedBlockData.C:54
os
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::fileOperations::masterUncollatedFileOperation::isFileOp
Definition: masterUncollatedFileOperation.H:194
Pstream.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::fileOperations::masterUncollatedFileOperation::rmDir
virtual bool rmDir(const fileName &dir, const bool silent=false) const
Remove a directory and its contents.
Definition: masterUncollatedFileOperation.C:1023
Foam::fileOperations::masterUncollatedFileOperation::mvBak
virtual bool mvBak(const fileName &, const std::string &ext="bak") const
Rename to a corresponding backup file.
Definition: masterUncollatedFileOperation.C:992
fileOperationInitialise
General fileOperation initialiser. Handles -ioRanks option, using it to set the FOAM_IORANKS environm...
Foam::fileOperations::masterUncollatedFileOperation::readObjects
virtual fileNameList readObjects(const objectRegistry &db, const fileName &instance, const fileName &local, word &newInstance) const
Search directory for objects. Used in IOobjectList.
Definition: masterUncollatedFileOperation.C:1641
Foam::infoDetailLevel
int infoDetailLevel
Global for selective suppression of Info output.
Foam::UPstream::commsStruct
Structure for communicating between processors.
Definition: UPstream.H:83
Foam::fileOperations::masterUncollatedFileOperation::filePathInfo
virtual fileName filePathInfo(const bool checkGlobal, const bool isFile, const IOobject &, const bool search, pathType &searchType, word &processorsDir, word &instance) const
Search (locally!) for object; return info on how it was found.
Definition: masterUncollatedFileOperation.C:159
Foam::fileOperations::masterUncollatedFileOperation::findInstancePath
static word findInstancePath(const instantList &timeDirs, const instant &t)
Equivalent of Time::findInstance.
Definition: masterUncollatedFileOperation.C:134
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::IOobject::readOpt
readOption readOpt() const noexcept
The read option.
Definition: IOobjectI.H:164
Foam::fileOperations::masterUncollatedFileOperation::mkDir
virtual bool mkDir(const fileName &, mode_t=0777) const
Make directory.
Definition: masterUncollatedFileOperation.C:827
Foam::fileOperations::masterUncollatedFileOperation::getState
virtual fileMonitor::fileState getState(const label) const
Get current state of file (using handle)
Definition: masterUncollatedFileOperation.C:2545
IListStream.H
Foam::UPstream::nProcsSimpleSum
static int nProcsSimpleSum
Definition: UPstream.H:278
Foam::fileOperation::PROCUNCOLLATED
objectPath exists in 'processorN'
Definition: fileOperation.H:82
Foam::IFstream::stdStream
virtual std::istream & stdStream()
Access to underlying std::istream.
Definition: IFstream.C:94
unthreadedInitialise.H
Foam::autoPtr::reset
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
Time.H
Foam::autoPtr< Foam::ISstream >
Foam::fileOperations::masterUncollatedFileOperation::chModOp
Definition: masterUncollatedFileOperation.H:116
Foam::IOobject::note
const string & note() const noexcept
Return the optional note.
Definition: IOobjectI.H:95
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:73
Foam::fileOperations::masterUncollatedFileOperation::flush
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
Definition: masterUncollatedFileOperation.C:2417
masterUncollatedFileOperation.H
Foam::TimePaths::system
const word & system() const
Return system name.
Definition: TimePathsI.H:102
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::Pstream::gatherList
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
Definition: gatherScatterList.C:52
Foam::debug::floatOptimisationSwitch
float floatOptimisationSwitch(const char *name, const float deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:243
Foam::UPstream::commsTypes::nonBlocking
Foam::UPstream::msgType
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:540
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Time::path
fileName path() const
Return path.
Definition: Time.H:358
Foam::fileOperations::masterUncollatedFileOperation::addWatch
virtual label addWatch(const fileName &) const
Add watching of a file. Returns handle.
Definition: masterUncollatedFileOperation.C:2425
Foam::fileOperation::PROCINSTANCE
as PROCOBJECT but with instance
Definition: fileOperation.H:93
Foam::UPstream::commsTypes::scheduled
Foam::fileOperations::masterUncollatedFileOperation::rm
virtual bool rm(const fileName &) const
Remove a file, returning true if successful otherwise false.
Definition: masterUncollatedFileOperation.C:1008
f
labelList f(nPoints)
Foam::regIOobject::close
void close()
Close Istream.
Definition: regIOobjectRead.C:171
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
decomposedBlockData.H
Foam::UPstream::worldComm
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:293
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::fileOperations::masterUncollatedFileOperation::NewIFstream
virtual autoPtr< ISstream > NewIFstream(const fileName &) const
Generate an ISstream that reads a file.
Definition: masterUncollatedFileOperation.C:2292
Foam::UList< label >
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::decomposedBlockData::readBlock
static autoPtr< ISstream > readBlock(const label blocki, ISstream &is, IOobject &headerIO)
Read selected block (non-seeking) + header information.
Definition: decomposedBlockData.C:227
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
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
bool
bool
Definition: EEqn.H:20
Foam::search
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:571
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::fileOperations::masterUncollatedFileOperation::readHeader
virtual bool readHeader(IOobject &, const fileName &, const word &typeName) const
Read object header from supplied file.
Definition: masterUncollatedFileOperation.C:1727
Foam::fileOperations::masterUncollatedFileOperation::isDir
virtual bool isDir(const fileName &, const bool followLink=true) const
Does the name exist as a DIRECTORY in the file system?
Definition: masterUncollatedFileOperation.C:911
Foam::fileOperation::PROCOBJECT
objectPath exists in 'processorsNN_first-last'
Definition: fileOperation.H:86
Foam::autoPtr::clear
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:176
Foam::fileOperations::masterUncollatedFileOperation::lnOp
Definition: masterUncollatedFileOperation.H:317
Foam::UPstream::commsStruct::above
label above() const noexcept
Definition: UPstream.H:130
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:309
Foam::fileOperations::masterUncollatedFileOperation::localObjectPath
fileName localObjectPath(const IOobject &, const pathType &searchType, const word &processorsDir, const word &instancePath) const
Construct filePath.
Definition: masterUncollatedFileOperation.C:336
Foam::regIOobject::readData
virtual bool readData(Istream &)
Virtual readData function.
Definition: regIOobjectRead.C:185
Foam::fileOperations::masterUncollatedFileOperation::readDirOp
Definition: masterUncollatedFileOperation.H:363
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
Foam::IOobject::writeHeader
bool writeHeader(Ostream &os) const
Write header with current type()
Definition: IOobjectWriteHeader.C:277
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
registerSwitch.H
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::UPstream::treeCommunication
static const List< commsStruct > & treeCommunication(const label communicator=worldComm)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.H:532
Foam::fileOperations::masterUncollatedFileOperation::NewOFstream
virtual autoPtr< OSstream > NewOFstream(const fileName &pathname, IOstreamOption streamOpt=IOstreamOption(), const bool valid=true) const
Generate an OSstream that writes a file.
Definition: masterUncollatedFileOperation.C:2398
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:56
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::fileOperations::masterUncollatedFileOperation::findTimes
virtual instantList findTimes(const fileName &, const word &) const
Get sorted list of times.
Definition: masterUncollatedFileOperation.C:2184
Foam::IOobject::objectPath
fileName objectPath() const
The complete path + object name.
Definition: IOobjectI.H:214
Foam::IOstreamOption::compression
compressionType compression() const noexcept
Get the stream compression.
Definition: IOstreamOption.H:312
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:96
Foam::fileOperations::masterUncollatedFileOperation::ln
virtual bool ln(const fileName &src, const fileName &dst) const
Create a softlink. dst should not exist. Returns true if.
Definition: masterUncollatedFileOperation.C:1075
Foam::fileOperation::PROCBASEINSTANCE
as PROCBASEOBJECT but with instance
Definition: fileOperation.H:92
Foam::HashPtrTable::iterator
typename parent_type::iterator iterator
Definition: HashPtrTable.H:88
Foam::IOobject::path
fileName path() const
The complete path.
Definition: IOobject.C:511
Foam::fileOperations::masterUncollatedFileOperation::addWatches
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
Definition: masterUncollatedFileOperation.C:2479
Foam::fileOperations::masterUncollatedFileOperation::mkDirOp
Definition: masterUncollatedFileOperation.H:101
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::fileOperations::masterUncollatedFileOperation::subRanks
static labelList subRanks(const label n)
Get the list of processors that are part of this communicator.
Definition: masterUncollatedFileOperation.C:84
Foam::fileOperation::pathType
pathType
Enumeration for the location of an IOobject.
Definition: fileOperation.H:73
Foam::fileName::isAbsolute
static bool isAbsolute(const std::string &str)
Definition: fileNameI.H:136
Foam::masterOFstream
Master-only drop-in replacement for OFstream.
Definition: masterOFstream.H:51
Foam::objectRegistry::time
const Time & time() const noexcept
Return time registry.
Definition: objectRegistry.H:178
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445
Foam::fileOperations::defineTypeNameAndDebug
defineTypeNameAndDebug(collatedFileOperation, 0)
Foam::fileOperations::masterUncollatedFileOperation::mvOp
Definition: masterUncollatedFileOperation.H:326
Foam::refPtr
A class for managing references or pointers (no reference counting)
Definition: PtrList.H:60
Foam::decomposedBlockData::readHeader
static bool readHeader(IOobject &io, Istream &is)
Definition: decomposedBlockDataHeader.C:105
Foam::IOobject::MUST_READ
Definition: IOobject.H:185
Foam::fileOperations::masterUncollatedFileOperation::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: masterUncollatedFileOperation.C:1436
Foam::IOobject::db
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:487