masterUncollatedFileOperation.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2017-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "Time.H"
28 #include "masterOFstream.H"
29 #include "decomposedBlockData.H"
30 #include "dummyISstream.H"
31 #include "SubList.H"
32 #include "PackedBoolList.H"
33 #include "gzstream.h"
35 
36 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
37 
38 namespace Foam
39 {
40 namespace fileOperations
41 {
44  (
47  word
48  );
49 
51  (
52  Foam::debug::floatOptimisationSwitch("maxMasterFileBufferSize", 1e9)
53  );
54 
55  // Mark as not needing threaded mpi
57  (
60  word,
61  masterUncollated
62  );
63 }
64 }
65 
66 
67 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
68 
70 (
71  const label n
72 )
73 {
74  string ioRanksString(getEnv("FOAM_IORANKS"));
75  if (ioRanksString.empty())
76  {
77  return identityMap(n);
78  }
79  else
80  {
82 
83  IStringStream is(ioRanksString);
84  labelList ioRanks(is);
85 
86  if (findIndex(ioRanks, 0) == -1)
87  {
89  << "Rank 0 (master) should be in the IO ranks. Currently "
90  << ioRanks << exit(FatalError);
91  }
92 
93  // The lowest numbered rank is the IO rank
94  PackedBoolList isIOrank(n);
95  isIOrank.set(ioRanks);
96 
97  for (label proci = Pstream::myProcNo(); proci >= 0; --proci)
98  {
99  if (isIOrank[proci])
100  {
101  // Found my master. Collect all processors with same master
102  subRanks.append(proci);
103  for
104  (
105  label rank = proci+1;
106  rank < n && !isIOrank[rank];
107  ++rank
108  )
109  {
110  subRanks.append(rank);
111  }
112  break;
113  }
114  }
115 
116  return subRanks;
117  }
118 }
119 
120 
123 (
124  const instantList& timeDirs,
125  const instant& t
126 )
127 {
128  // Note:
129  // - times will include constant (with value 0) as first element.
130  // For backwards compatibility make sure to find 0 in preference
131  // to constant.
132  // - list is sorted so could use binary search
133 
135  {
136  if (t.equal(timeDirs[i].value()))
137  {
138  return timeDirs[i].name();
139  }
140  }
141 
142  return word::null;
143 }
144 
145 
148 (
149  const bool globalFile,
150  const bool isFile,
151  const IOobject& io,
152  pathType& searchType,
153  word& procsDir,
154  word& newInstancePath
155 ) const
156 {
157  procsDir = word::null;
158  newInstancePath = word::null;
159 
160  if (io.instance().isAbsolute())
161  {
162  fileName objPath = io.instance()/io.name();
163 
164  if (isFileOrDir(isFile, objPath))
165  {
166  searchType = fileOperation::ABSOLUTE;
167  return objPath;
168  }
169  else
170  {
171  searchType = fileOperation::NOTFOUND;
172  return fileName::null;
173  }
174  }
175  else
176  {
177  // 1. Check the writing fileName
178  fileName writePath(objectPath(io, io.headerClassName()));
179 
180  if (isFileOrDir(isFile, writePath))
181  {
182  searchType = fileOperation::WRITEOBJECT;
183  return writePath;
184  }
185 
186  // 2. Check processors/
187  if (io.time().processorCase())
188  {
190  (
191  lookupProcessorsPath(io.objectPath(globalFile))
192  );
193  forAll(pDirs(), i)
194  {
195  const fileName& pDir = pDirs()[i].first();
196  fileName objPath =
197  processorsPath(io, io.instance(), pDir)
198  /io.name();
199  if (objPath != writePath && isFileOrDir(isFile, objPath))
200  {
201  searchType = pDirs()[i].second().first();
202  procsDir = pDir;
203  return objPath;
204  }
205  }
206  }
207  {
208  // 3. Check local
209  fileName localPath = io.objectPath(globalFile);
210 
211  if
212  (
213  localPath != writePath
214  && isFileOrDir(isFile, localPath)
215  )
216  {
217  searchType = fileOperation::OBJECT;
218  return localPath;
219  }
220  }
221 
222 
223 
224  // Any global checks
225  if
226  (
227  globalFile
228  && io.time().processorCase()
229  && (
230  io.instance() == io.time().system()
231  || io.instance() == io.time().constant()
232  )
233  )
234  {
235  fileName parentPath =
236  io.rootPath()/io.time().globalCaseName()
237  /io.instance()/io.db().dbDir()/io.local()/io.name();
238 
239  if (isFileOrDir(isFile, parentPath))
240  {
241  searchType = fileOperation::PARENTOBJECT;
242  return parentPath;
243  }
244  }
245 
246  // Check for approximately same time. E.g. if time = 1e-2 and
247  // directory is 0.01 (due to different time formats)
249  (
250  times_.find
251  (
252  io.time().path()
253  )
254  );
255  if (pathFnd != times_.end())
256  {
257  newInstancePath = findInstancePath
258  (
259  *pathFnd(),
260  instant(io.instance())
261  );
262 
263  if (newInstancePath.size() && newInstancePath != io.instance())
264  {
265  // 1. Try processors equivalent
267  (
268  lookupProcessorsPath(io.objectPath(globalFile))
269  );
270  forAll(pDirs(), i)
271  {
272  const fileName& pDir = pDirs()[i].first();
273 
274  fileName fName
275  (
276  processorsPath(io, newInstancePath, pDir)
277  /io.name()
278  );
279  if (isFileOrDir(isFile, fName))
280  {
281  switch (pDirs()[i].second().first())
282  {
284  {
285  searchType =
287  }
288  break;
290  {
291  searchType = fileOperation::PROCBASEINSTANCE;
292  }
293  break;
295  {
296  searchType = fileOperation::PROCINSTANCE;
297  }
298  break;
299  default:
300  break;
301  }
302  procsDir = pDir;
303  return fName;
304  }
305  }
306 
307 
308  // 2. Check local
309  fileName fName
310  (
311  io.rootPath()/io.caseName(false)
312  /newInstancePath/io.db().dbDir()/io.local()/io.name()
313  );
314  if (isFileOrDir(isFile, fName))
315  {
316  searchType = fileOperation::FINDINSTANCE;
317  return fName;
318  }
319  }
320  }
321 
322  searchType = fileOperation::NOTFOUND;
323  return fileName::null;
324  }
325 }
326 
327 
330 (
331  const IOobject& io,
332  const pathType& searchType,
333  const word& procDir,
334  const word& instancePath
335 ) const
336 {
337  // Replacement for IOobject::objectPath()
338 
339  switch (searchType)
340  {
342  {
343  return io.instance()/io.name();
344  }
345  break;
346 
348  {
349  return io.path(false)/io.name();
350  }
351  break;
352 
354  {
355  return objectPath(io, io.headerClassName());
356  }
357  break;
358 
360  {
361  // Uncollated type, e.g. processor1
362  const word procName
363  (
364  "processor"
366  );
367  return
368  processorsPath
369  (
370  io,
371  io.instance(),
372  (
374  ? procName
375  : procDir
376  )
377  )
378  /io.name();
379  }
380  break;
381 
383  {
384  // Collated, e.g. processors4
385  return
386  processorsPath(io, io.instance(), procDir)
387  /io.name();
388  }
389  break;
390 
392  {
393  // Processors directory locally provided by the fileHandler itself
394  return
395  processorsPath(io, io.instance(), processorsDir(io))
396  /io.name();
397  }
398  break;
399 
401  {
402  return
403  io.rootPath()/io.time().globalCaseName()
404  /io.instance()/io.db().dbDir()/io.local()/io.name();
405  }
406  break;
407 
409  {
410  return
411  io.rootPath()/io.caseName(false)
412  /instancePath/io.db().dbDir()/io.local()/io.name();
413  }
414  break;
415 
417  {
418  // Uncollated type, e.g. processor1
419  const word procName
420  (
421  "processor"
423  );
424  return
425  processorsPath
426  (
427  io,
428  instancePath,
429  (
431  ? procName
432  : procDir
433  )
434  )
435  /io.name();
436  }
437  break;
438 
440  {
441  // Collated, e.g. processors4
442  return
443  processorsPath(io, instancePath, procDir)
444  /io.name();
445  }
446  break;
447 
449  {
450  // Processors directory locally provided by the fileHandler itself
451  return
452  processorsPath(io, instancePath, processorsDir(io))
453  /io.name();
454  }
455  break;
456 
458  {
459  return fileName::null;
460  }
461  break;
462 
463  default:
464  {
466  return fileName::null;
467  }
468  }
469 }
470 
471 
473 (
474  const fileNameList& filePaths
475 )
476 {
477  const fileName& object0 = filePaths[0];
478 
479  for (label i = 1; i < filePaths.size(); i++)
480  {
481  if (filePaths[i] != object0)
482  {
483  return false;
484  }
485  }
486  return true;
487 }
488 
489 
491 (
492  const fileName& filePath,
493  const labelUList& procs,
494  PstreamBuffers& pBufs
495 )
496 {
497  if (debug)
498  {
499  Pout<< FUNCTION_NAME << ": Opening " << filePath << endl;
500  }
501 
502  IFstream is(filePath, IOstream::streamFormat::BINARY);
503 
504  if (!is.good())
505  {
506  FatalIOErrorInFunction(filePath) << "Cannot open file " << filePath
507  << exit(FatalIOError);
508  }
509 
510  if (isA<igzstream>(is.stdStream()))
511  {
512  if (debug)
513  {
514  Pout<< FUNCTION_NAME << ": Reading compressed" << endl;
515  }
516 
517  std::ostringstream stringStr;
518  stringStr << is.stdStream().rdbuf();
519  string buf(stringStr.str());
520 
521  forAll(procs, i)
522  {
523  UOPstream os(procs[i], pBufs);
524  os.write(&buf[0], buf.size());
525  }
526  }
527  else
528  {
529  off_t count(Foam::fileSize(filePath));
530 
531  if (debug)
532  {
533  Pout<< FUNCTION_NAME << " : Reading " << count << " bytes " << endl;
534  }
535 
536  List<char> buf(static_cast<label>(count));
537  is.stdStream().read(buf.begin(), count);
538 
539  forAll(procs, i)
540  {
541  UOPstream os(procs[i], pBufs);
542  os.write(buf.begin(), count);
543  }
544  }
545 }
546 
547 
550 (
551  IOobject& io,
552  const label comm,
553  const bool uniform, // on comms master only
554  const fileNameList& filePaths, // on comms master only
555  const boolList& read // on comms master only
556 )
557 {
558  autoPtr<ISstream> isPtr;
559 
560  // const bool uniform = uniformFile(filePaths);
561 
562  PstreamBuffers pBufs
563  (
566  comm
567  );
568 
569  if (Pstream::master(comm))
570  {
571  if (uniform)
572  {
573  if (read[0])
574  {
575  if (filePaths[0].empty())
576  {
577  FatalIOErrorInFunction(filePaths[0])
578  << "cannot find file for object " << io.name()
579  << exit(FatalIOError);
580  }
581 
582  DynamicList<label> validProcs(Pstream::nProcs(comm));
583  for
584  (
585  label proci = 0;
586  proci < Pstream::nProcs(comm);
587  proci++
588  )
589  {
590  if (read[proci])
591  {
592  validProcs.append(proci);
593  }
594  }
595 
596  // Read on master and send to all processors (including
597  // master for simplicity)
598  if (debug)
599  {
600  Pout<< "masterUncollatedFileOperation::readStream :"
601  << " For uniform file " << filePaths[0]
602  << " sending to " << validProcs
603  << " in comm:" << comm << endl;
604  }
605  readAndSend(filePaths[0], validProcs, pBufs);
606  }
607  }
608  else
609  {
610  if (read[0])
611  {
612  if (filePaths[0].empty())
613  {
614  FatalIOErrorInFunction(filePaths[0])
615  << "cannot find file for object " << io.name()
616  << exit(FatalIOError);
617  }
618 
619  autoPtr<IFstream> ifsPtr(new IFstream(filePaths[0]));
620 
621  // Read header
622  if (!io.readHeader(ifsPtr()))
623  {
624  FatalIOErrorInFunction(ifsPtr())
625  << "problem while reading header for object "
626  << io.name() << exit(FatalIOError);
627  }
628 
629  // Open master (steal from ifsPtr)
630  isPtr.reset(ifsPtr.ptr());
631  }
632 
633  // Read slave files
634  for
635  (
636  label proci = 1;
637  proci < Pstream::nProcs(comm);
638  proci++
639  )
640  {
641  if (debug)
642  {
643  Pout<< "masterUncollatedFileOperation::readStream :"
644  << " For processor " << proci
645  << " opening " << filePaths[proci] << endl;
646  }
647 
648  const fileName& fPath = filePaths[proci];
649 
650  if (read[proci] && !fPath.empty())
651  {
652  // Note: handle compression ourselves since size cannot
653  // be determined without actually uncompressing
654  readAndSend(fPath, labelList(1, proci), pBufs);
655  }
656  }
657  }
658  }
659 
660  labelList recvSizes;
661  pBufs.finishedSends(recvSizes);
662 
663  // isPtr will be valid on master and will be the unbuffered
664  // IFstream. Else the information is in the PstreamBuffers (and
665  // the special case of a uniform file)
666 
667  if (read[Pstream::myProcNo(comm)])
668  {
669  // This processor needs to return something
670 
671  if (!isPtr.valid())
672  {
673  UIPstream is(Pstream::masterNo(), pBufs);
674  string buf(recvSizes[Pstream::masterNo()], '\0');
675  if (recvSizes[Pstream::masterNo()] > 0)
676  {
677  is.read(&buf[0], recvSizes[Pstream::masterNo()]);
678  }
679 
680  if (debug)
681  {
682  Pout<< "masterUncollatedFileOperation::readStream :"
683  << " Done reading " << buf.size() << " bytes" << endl;
684  }
685  const fileName& fName = filePaths[Pstream::myProcNo(comm)];
686  isPtr.reset(new IStringStream(fName, buf, IOstream::BINARY));
687 
688  if (!io.readHeader(isPtr()))
689  {
690  FatalIOErrorInFunction(isPtr())
691  << "problem while reading header for object "
692  << io.name() << exit(FatalIOError);
693  }
694  }
695  }
696  else
697  {
698  isPtr.reset(new dummyISstream());
699  }
700 
701  return isPtr;
702 }
703 
704 
705 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
706 
709 (
710  const bool verbose
711 )
712 :
714  (
715  UPstream::allocateCommunicator
716  (
717  UPstream::worldComm,
718  subRanks(Pstream::nProcs())
719  )
720  ),
721  myComm_(comm_)
722 {
723  if (verbose)
724  {
725  InfoHeader
726  << "I/O : " << typeName
727  << " (maxMasterFileBufferSize " << maxMasterFileBufferSize << ')'
728  << endl;
729  }
730 
732  {
733  if (verbose)
734  {
736  << "Resetting fileModificationChecking to timeStamp" << endl;
737  }
739  }
740  else if
741  (
744  )
745  {
746  if (verbose)
747  {
749  << "Resetting fileModificationChecking to inotify"
750  << endl;
751  }
753  }
754 }
755 
756 
759 (
760  const label comm,
761  const bool verbose
762 )
763 :
764  fileOperation(comm),
765  myComm_(-1)
766 {
767  if (verbose)
768  {
769  InfoHeader
770  << "I/O : " << typeName
771  << " (maxMasterFileBufferSize " << maxMasterFileBufferSize << ')'
772  << endl;
773  }
774 
776  {
777  if (verbose)
778  {
780  << "Resetting fileModificationChecking to timeStamp" << endl;
781  }
783  }
784  else if
785  (
788  )
789  {
790  if (verbose)
791  {
793  << "Resetting fileModificationChecking to inotify"
794  << endl;
795  }
797  }
798 }
799 
800 
802 masterUncollatedFileOperationInitialise(int& argc, char**& argv)
803 :
804  unthreadedInitialise(argc, argv)
805 {
806  // Filter out any of my arguments
807  const string s("-ioRanks");
808 
809  int index = -1;
810  for (int i=1; i<argc-1; i++)
811  {
812  if (argv[i] == s)
813  {
814  index = i;
815  setEnv("FOAM_IORANKS", argv[i+1], true);
816  break;
817  }
818  }
819 
820  if (index != -1)
821  {
822  for (int i=index+2; i<argc; i++)
823  {
824  argv[i-2] = argv[i];
825  }
826  argc -= 2;
827  }
828 }
829 
830 
831 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
832 
835 {
836  if (myComm_ != -1)
837  {
839  }
840 }
841 
842 
843 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
844 
846 (
847  const fileName& dir,
848  mode_t mode
849 ) const
850 {
851  return masterOp<mode_t, mkDirOp>
852  (
853  dir,
854  mkDirOp(mode),
856  comm_
857  );
858 }
859 
860 
862 (
863  const fileName& fName,
864  mode_t mode
865 ) const
866 {
867  return masterOp<mode_t, chModOp>
868  (
869  fName,
870  chModOp(mode),
872  comm_
873  );
874 }
875 
876 
878 (
879  const fileName& fName,
880  const bool checkVariants,
881  const bool followLink
882 ) const
883 {
884  return masterOp<mode_t, modeOp>
885  (
886  fName,
887  modeOp(checkVariants, followLink),
889  comm_
890  );
891 }
892 
893 
895 (
896  const fileName& fName,
897  const bool checkVariants,
898  const bool followLink
899 ) const
900 {
901  return fileType
902  (
903  masterOp<label, typeOp>
904  (
905  fName,
906  typeOp(checkVariants, followLink),
908  comm_
909  )
910  );
911 }
912 
913 
915 (
916  const fileName& fName,
917  const bool checkVariants,
918  const bool followLink
919 ) const
920 {
921  return masterOp<bool, existsOp>
922  (
923  fName,
924  existsOp(checkVariants, followLink),
926  comm_
927  );
928 }
929 
930 
932 (
933  const fileName& fName,
934  const bool followLink
935 ) const
936 {
937  return masterOp<bool, isDirOp>
938  (
939  fName,
940  isDirOp(followLink),
942  comm_
943  );
944 }
945 
946 
948 (
949  const fileName& fName,
950  const bool checkVariants,
951  const bool followLink
952 ) const
953 {
954  return masterOp<bool, isFileOp>
955  (
956  fName,
957  isFileOp(checkVariants, followLink),
959  comm_
960  );
961 }
962 
963 
965 (
966  const fileName& fName,
967  const bool checkVariants,
968  const bool followLink
969 ) const
970 {
971  return masterOp<off_t, fileSizeOp>
972  (
973  fName,
974  fileSizeOp(checkVariants, followLink),
976  comm_
977  );
978 }
979 
980 
982 (
983  const fileName& fName,
984  const bool checkVariants,
985  const bool followLink
986 ) const
987 {
988  return masterOp<time_t, lastModifiedOp>
989  (
990  fName,
991  lastModifiedOp(checkVariants, followLink),
993  comm_
994  );
995 }
996 
997 
999 (
1000  const fileName& fName,
1001  const bool checkVariants,
1002  const bool followLink
1003 ) const
1004 {
1005  return masterOp<double, lastModifiedHROp>
1006  (
1007  fName,
1008  lastModifiedHROp(checkVariants, followLink),
1009  Pstream::msgType(),
1010  comm_
1011  );
1012 }
1013 
1014 
1016 (
1017  const fileName& fName,
1018  const std::string& ext
1019 ) const
1020 {
1021  return masterOp<bool, mvBakOp>
1022  (
1023  fName,
1024  mvBakOp(ext),
1025  Pstream::msgType(),
1026  comm_
1027  );
1028 }
1029 
1030 
1032 (
1033  const fileName& fName
1034 ) const
1035 {
1036  return masterOp<bool, rmOp>
1037  (
1038  fName,
1039  rmOp(),
1040  Pstream::msgType(),
1041  comm_
1042  );
1043 }
1044 
1045 
1047 (
1048  const fileName& dir
1049 ) const
1050 {
1051  return masterOp<bool, rmDirOp>
1052  (
1053  dir,
1054  rmDirOp(),
1055  Pstream::msgType(),
1056  comm_
1057  );
1058 }
1059 
1060 
1062 (
1063  const fileName& dir,
1064  const fileType type,
1065  const bool filtergz,
1066  const bool followLink
1067 ) const
1068 {
1069  return masterOp<fileNameList, readDirOp>
1070  (
1071  dir,
1072  readDirOp(type, filtergz, followLink),
1073  Pstream::msgType(),
1074  comm_
1075  );
1076 }
1077 
1078 
1080 (
1081  const fileName& src,
1082  const fileName& dst,
1083  const bool followLink
1084 ) const
1085 {
1086  return masterOp<bool, cpOp>
1087  (
1088  src,
1089  dst,
1090  cpOp(followLink),
1091  Pstream::msgType(),
1092  comm_
1093  );
1094 }
1095 
1096 
1098 (
1099  const fileName& src,
1100  const fileName& dst
1101 ) const
1102 {
1103  return masterOp<bool, lnOp>
1104  (
1105  src,
1106  dst,
1107  lnOp(),
1108  Pstream::msgType(),
1109  comm_
1110  );
1111 }
1112 
1113 
1115 (
1116  const fileName& src,
1117  const fileName& dst,
1118  const bool followLink
1119 ) const
1120 {
1121  return masterOp<bool, mvOp>
1122  (
1123  src,
1124  dst,
1125  mvOp(followLink),
1126  Pstream::msgType(),
1127  comm_
1128  );
1129 }
1130 
1131 
1133 (
1134  const bool globalFile,
1135  const IOobject& io,
1136  const word& typeName
1137 ) const
1138 {
1139  if (debug)
1140  {
1141  Pout<< "masterUncollatedFileOperation::filePath :"
1142  << " objectPath:" << io.objectPath(globalFile)
1143  << " globalFile:" << globalFile << endl;
1144  }
1145 
1146  // Now that we have an IOobject path use it to detect & cache
1147  // processor directory naming
1148  (void)lookupProcessorsPath(io.objectPath(globalFile));
1149 
1150  // Trigger caching of times
1151  (void)findTimes(io.time().path(), io.time().constant());
1152 
1153 
1154  // Determine master filePath and scatter
1155 
1156  fileName objPath;
1157  pathType searchType = NOTFOUND;
1158  word procsDir;
1159  word newInstancePath;
1160 
1161  if (Pstream::master(comm_))
1162  {
1163  // All masters search locally. Note that global objects might
1164  // fail (except on master). This gets handled later on (in PARENTOBJECT)
1165  objPath = filePathInfo
1166  (
1167  globalFile,
1168  true,
1169  io,
1170  searchType,
1171  procsDir,
1172  newInstancePath
1173  );
1174 
1175  if (debug)
1176  {
1177  Pout<< "masterUncollatedFileOperation::filePath :"
1178  << " master objPath:" << objPath
1179  << " searchType:" << fileOperation::pathTypeNames_[searchType]
1180  << " procsDir:" << procsDir << " instance:" << newInstancePath
1181  << endl;
1182  }
1183 
1184  }
1185 
1186  // Scatter the information about where the master found the object
1187  // Note: use the worldComm to make sure all processors decide
1188  // the same type. Only procsDir is allowed to differ; searchType
1189  // and instance have to be same
1190  {
1191  label masterType(searchType);
1192  Pstream::scatter(masterType);
1193  searchType = pathType(masterType);
1194  }
1195  Pstream::scatter(newInstancePath);
1196 
1197  if
1198  (
1199  globalFile
1200  || searchType == fileOperation::PARENTOBJECT
1201  || searchType == fileOperation::PROCBASEOBJECT
1202  || searchType == fileOperation::PROCBASEINSTANCE
1203  || io.local() == "uniform"
1204  )
1205  {
1206  // Distribute master path. This makes sure it is seen as uniform
1207  // and only gets read from the master.
1208  Pstream::scatter(objPath);
1209  Pstream::scatter(procsDir);
1210  }
1211  else
1212  {
1213  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1214 
1215  // Use the master type to determine if additional information is
1216  // needed to construct the local equivalent
1217  switch (searchType)
1218  {
1222  {
1223  // Already handled above
1224  }
1225  break;
1226 
1234  {
1235  // Construct equivalent local path
1236  objPath = relativeObjectPath
1237  (
1238  io,
1239  searchType,
1240  procsDir,
1241  newInstancePath
1242  );
1243  }
1244  break;
1245 
1246  case fileOperation::OBJECT:
1248  {
1249  // Retest all processors separately since some processors might
1250  // have the file and some not (e.g. lagrangian data)
1251 
1252  objPath = masterOp<fileName, fileOrNullOp>
1253  (
1254  io.objectPath(globalFile),
1255  fileOrNullOp(true),
1256  Pstream::msgType(),
1257  comm_
1258  );
1259  }
1260  break;
1261  }
1262  }
1263 
1264  if (debug)
1265  {
1266  Pout<< "masterUncollatedFileOperation::filePath :"
1267  << " Returning from file searching:" << endl
1268  << " objectPath:" << io.objectPath(globalFile) << endl
1269  << " filePath :" << objPath << endl << endl;
1270  }
1271  return objPath;
1272 }
1273 
1274 
1276 (
1277  const bool globalFile,
1278  const IOobject& io
1279 ) const
1280 {
1281  if (debug)
1282  {
1283  Pout<< "masterUncollatedFileOperation::dirPath :"
1284  << " objectPath:" << io.objectPath(globalFile)
1285  << " globalFile:" << globalFile << endl;
1286  }
1287 
1288  // Now that we have an IOobject path use it to detect & cache
1289  // processor directory naming
1290  (void)lookupProcessorsPath(io.objectPath(globalFile));
1291 
1292  // Determine master dirPath and scatter
1293 
1294  fileName objPath;
1295  pathType searchType = NOTFOUND;
1296  word procsDir;
1297  word newInstancePath;
1298 
1299  if (Pstream::master(comm_))
1300  {
1301  objPath = filePathInfo
1302  (
1303  globalFile,
1304  false,
1305  io,
1306  searchType,
1307  procsDir,
1308  newInstancePath
1309  );
1310  }
1311 
1312  {
1313  label masterType(searchType);
1314  Pstream::scatter(masterType); //, Pstream::msgType(), comm_);
1315  searchType = pathType(masterType);
1316  }
1317  Pstream::scatter(newInstancePath); //, Pstream::msgType(), comm_);
1318 
1319  if
1320  (
1321  globalFile
1322  || searchType == fileOperation::PARENTOBJECT
1323  || searchType == fileOperation::PROCBASEOBJECT
1324  || searchType == fileOperation::PROCBASEINSTANCE
1325  || io.local() == "uniform"
1326  )
1327  {
1328  // Distribute master path. This makes sure it is seen as uniform
1329  // and only gets read from the master.
1330  Pstream::scatter(objPath);
1331  Pstream::scatter(procsDir);
1332  }
1333  else
1334  {
1335  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1336 
1337  // Use the master type to determine if additional information is
1338  // needed to construct the local equivalent
1339  switch (searchType)
1340  {
1344  {
1345  // Already handled above
1346  }
1347  break;
1348 
1356  {
1357  // Construct equivalent local path
1358  objPath = relativeObjectPath
1359  (
1360  io,
1361  searchType,
1362  procsDir,
1363  newInstancePath
1364  );
1365  }
1366  break;
1367 
1368  case fileOperation::OBJECT:
1370  {
1371  // Retest all processors separately since some processors might
1372  // have the file and some not (e.g. lagrangian data)
1373  objPath = masterOp<fileName, fileOrNullOp>
1374  (
1375  io.objectPath(globalFile),
1376  fileOrNullOp(false),
1377  Pstream::msgType(),
1378  comm_
1379  );
1380  }
1381  break;
1382  }
1383  }
1384 
1385  if (debug)
1386  {
1387  Pout<< "masterUncollatedFileOperation::dirPath :"
1388  << " Returning from file searching:" << endl
1389  << " objectPath:" << io.objectPath(globalFile) << endl
1390  << " filePath :" << objPath << endl << endl;
1391  }
1392  return objPath;
1393 }
1394 
1395 
1397 (
1398  const dirIndexList& pDirs,
1399  IOobject& io
1400 ) const
1401 {
1402  // Cut-down version of filePathInfo that does not look for
1403  // different instance or parent directory
1404 
1405  const bool isFile = !io.name().empty();
1406 
1407  // Generate output filename for object
1408  const fileName writePath(objectPath(io, word::null));
1409 
1410  // 1. Test writing name for either directory or a (valid) file
1411  if (isFileOrDir(isFile, writePath))
1412  {
1413  return true;
1414  }
1415 
1416  // 2. Check processors/
1417  if (io.time().processorCase())
1418  {
1419  forAll(pDirs, i)
1420  {
1421  const fileName& pDir = pDirs[i].first();
1422  fileName procPath =
1423  processorsPath(io, io.instance(), pDir)
1424  /io.name();
1425  if (procPath != writePath && isFileOrDir(isFile, procPath))
1426  {
1427  return true;
1428  }
1429  }
1430  }
1431 
1432  // 3. Check local
1433  fileName localPath = io.objectPath(false);
1434 
1435  if (localPath != writePath && isFileOrDir(isFile, localPath))
1436  {
1437  return true;
1438  }
1439 
1440  return false;
1441 }
1442 
1443 
1446 (
1447  const IOobject& startIO,
1448  const scalar startValue,
1449  const word& stopInstance
1450 ) const
1451 {
1452  if (debug)
1453  {
1454  Pout<< "masterUncollatedFileOperation::findInstance :"
1455  << " Starting searching for name:" << startIO.name()
1456  << " local:" << startIO.local()
1457  << " from instance:" << startIO.instance()
1458  << endl;
1459  }
1460 
1461 
1462  const Time& time = startIO.time();
1463 
1464  IOobject io(startIO);
1465 
1466  // Note: - if name is empty, just check the directory itself
1467  // - check both for isFile and headerOk since the latter does a
1468  // filePath so searches for the file.
1469  // - check for an object with local file scope (so no looking up in
1470  // parent directory in case of parallel)
1471 
1472 
1473  tmpNrc<dirIndexList> pDirs(lookupProcessorsPath(io.objectPath(false)));
1474 
1475  word foundInstance;
1476 
1477  // if (Pstream::master(comm_))
1479  {
1480  if (exists(pDirs, io))
1481  {
1482  foundInstance = io.instance();
1483  }
1484  }
1485 
1486  // Do parallel early exit to avoid calling time.times()
1487  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1489  if (!foundInstance.empty())
1490  {
1491  io.instance() = foundInstance;
1492  if (debug)
1493  {
1494  Pout<< "masterUncollatedFileOperation::findInstance :"
1495  << " for name:" << io.name() << " local:" << io.local()
1496  << " found starting instance:" << io.instance() << endl;
1497  }
1498  return io;
1499  }
1500 
1501 
1502  // Search back through the time directories to find the time
1503  // closest to and lower than current time
1504 
1505  instantList ts = time.times();
1506  // if (Pstream::master(comm_))
1508  {
1509  label instanceI;
1510 
1511  for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
1512  {
1513  if (ts[instanceI].value() <= startValue)
1514  {
1515  break;
1516  }
1517  }
1518 
1519  // continue searching from here
1520  for (; instanceI >= 0; --instanceI)
1521  {
1522  // Shortcut: if actual directory is the timeName we've
1523  // already tested it
1524  if (ts[instanceI].name() == time.name())
1525  {
1526  continue;
1527  }
1528 
1529  io.instance() = ts[instanceI].name();
1530  if (exists(pDirs, io))
1531  {
1532  foundInstance = io.instance();
1533  if (debug)
1534  {
1535  Pout<< "masterUncollatedFileOperation::findInstance :"
1536  << " for name:" << io.name() << " local:" << io.local()
1537  << " found at:" << io.instance()
1538  << endl;
1539  }
1540  break;
1541  }
1542 
1543  // Check if hit minimum instance
1544  if (ts[instanceI].name() == stopInstance)
1545  {
1546  if
1547  (
1548  startIO.readOpt() == IOobject::MUST_READ
1550  )
1551  {
1552  if (io.name().empty())
1553  {
1555  << "Cannot find directory "
1556  << io.local() << " in times " << time.name()
1557  << " down to " << stopInstance
1558  << exit(FatalError);
1559  }
1560  else
1561  {
1563  << "Cannot find file \"" << io.name()
1564  << "\" in directory " << io.local()
1565  << " in times " << time.name()
1566  << " down to " << stopInstance
1567  << exit(FatalError);
1568  }
1569  }
1570  foundInstance = io.instance();
1571  if (debug)
1572  {
1573  Pout<< "masterUncollatedFileOperation::findInstance :"
1574  << " name:" << io.name() << " local:" << io.local()
1575  << " found at stopinstance:" << io.instance() << endl;
1576  }
1577  break;
1578  }
1579  }
1580 
1581 
1582  if (foundInstance.empty())
1583  {
1584  // times() usually already includes the constant() so would
1585  // have been checked above. Re-test if
1586  // - times() is empty. Sometimes this can happen (e.g. decomposePar
1587  // with collated)
1588  // - times()[0] is not constant
1589  if (!ts.size() || ts[0].name() != time.constant())
1590  {
1591  // Note. This needs to be a hard-coded constant, rather than the
1592  // constant function of the time, because the latter points to
1593  // the case constant directory in parallel cases
1594 
1595  io.instance() = time.constant();
1596  if (exists(pDirs, io))
1597  {
1598  if (debug)
1599  {
1600  Pout<< "masterUncollatedFileOperation::findInstance :"
1601  << " name:" << io.name()
1602  << " local:" << io.local()
1603  << " found at:" << io.instance() << endl;
1604  }
1605  foundInstance = io.instance();
1606  }
1607  }
1608  }
1609 
1610  if (foundInstance.empty())
1611  {
1612  if
1613  (
1614  startIO.readOpt() == IOobject::MUST_READ
1616  )
1617  {
1619  << "Cannot find file \"" << io.name() << "\" in directory "
1620  << io.local() << " in times " << startIO.instance()
1621  << " down to " << time.constant()
1622  << exit(FatalError);
1623  }
1624  else
1625  {
1626  foundInstance = time.constant();
1627  }
1628  }
1629  }
1630 
1631  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1633  io.instance() = foundInstance;
1634  if (debug)
1635  {
1636  Pout<< "masterUncollatedFileOperation::findInstance :"
1637  << " name:" << io.name() << " local:" << io.local()
1638  << " returning instance:" << io.instance() << endl;
1639  }
1640  return io;
1641 }
1642 
1643 
1646 (
1647  const objectRegistry& db,
1648  const fileName& instance,
1649  const fileName& local,
1650  word& newInstance
1651 ) const
1652 {
1653  if (debug)
1654  {
1655  Pout<< "masterUncollatedFileOperation::readObjects :"
1656  << " db:" << db.objectPath()
1657  << " local:" << local << " instance:" << instance << endl;
1658  }
1659 
1660  fileNameList objectNames;
1661  newInstance = word::null;
1662 
1663  // Note: readObjects uses WORLD to make sure order of objects is the
1664  // same everywhere
1665 
1666  if (Pstream::master()) // comm_))
1667  {
1668  // Avoid fileOperation::readObjects from triggering parallel ops
1669  // (through call to filePath which triggers parallel )
1670  bool oldParRun = UPstream::parRun();
1671  UPstream::parRun() = false;
1672 
1673  //- Use non-time searching version
1674  objectNames = fileOperation::readObjects
1675  (
1676  db,
1677  instance,
1678  local,
1679  newInstance
1680  );
1681 
1682  if (newInstance.empty())
1683  {
1684  // Find similar time
1685 
1686  // Copy of Time::findInstancePath. We want to avoid the
1687  // parallel call to findTimes. Alternative is to have
1688  // version of findInstancePath that takes instantList ...
1689  const instantList timeDirs
1690  (
1692  (
1693  db.time().path(),
1694  db.time().constant()
1695  )
1696  );
1697 
1698  const instant t(instance);
1700  {
1701  if (t.equal(timeDirs[i].value()))
1702  {
1703  objectNames = fileOperation::readObjects
1704  (
1705  db,
1706  timeDirs[i].name(), // newly found time
1707  local,
1708  newInstance
1709  );
1710  break;
1711  }
1712  }
1713  }
1714 
1715  UPstream::parRun() = oldParRun;
1716  }
1717 
1718  Pstream::scatter(newInstance); //, Pstream::msgType(), comm_);
1719  Pstream::scatter(objectNames); //, Pstream::msgType(), comm_);
1720 
1721  if (debug)
1722  {
1723  Pout<< "masterUncollatedFileOperation::readObjects :"
1724  << " newInstance:" << newInstance
1725  << " objectNames:" << objectNames << endl;
1726  }
1727 
1728  return objectNames;
1729 }
1730 
1731 
1733 (
1734  IOobject& io,
1735  const fileName& fName,
1736  const word& typeName
1737 ) const
1738 {
1739  bool ok = false;
1740 
1741  if (debug)
1742  {
1743  Pout<< "masterUncollatedFileOperation::readHeader :" << nl
1744  << " object :" << io.name() << nl
1745  << " fName :" << fName << endl;
1746  }
1747 
1748  // Get filePaths on world master
1750  filePaths[Pstream::myProcNo(Pstream::worldComm)] = fName;
1752  bool uniform = uniformFile(filePaths);
1754 
1755  if (uniform)
1756  {
1758  {
1759  if (!fName.empty())
1760  {
1761  IFstream is(fName);
1762 
1763  if (is.good())
1764  {
1765  ok = io.readHeader(is);
1766  if (io.headerClassName() == decomposedBlockData::typeName)
1767  {
1768  // Read the header inside the container (master data)
1770  }
1771  }
1772  }
1773  }
1776  (
1777  io.headerClassName(),
1778  Pstream::msgType(),
1780  );
1782  }
1783  else
1784  {
1786  {
1787  // Re-gather file paths on local master
1788  filePaths.setSize(Pstream::nProcs(comm_));
1789  filePaths[Pstream::myProcNo(comm_)] = fName;
1790  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
1791  }
1792 
1793  boolList result(Pstream::nProcs(comm_), false);
1794  wordList headerClassName(Pstream::nProcs(comm_));
1795  stringList note(Pstream::nProcs(comm_));
1796  if (Pstream::master(comm_))
1797  {
1798  forAll(filePaths, proci)
1799  {
1800  if (!filePaths[proci].empty())
1801  {
1802  if (proci > 0 && filePaths[proci] == filePaths[proci-1])
1803  {
1804  result[proci] = result[proci-1];
1805  headerClassName[proci] = headerClassName[proci-1];
1806  note[proci] = note[proci-1];
1807  }
1808  else
1809  {
1810  IFstream is(filePaths[proci]);
1811 
1812  if (is.good())
1813  {
1814  result[proci] = io.readHeader(is);
1815  if
1816  (
1817  io.headerClassName()
1818  == decomposedBlockData::typeName
1819  )
1820  {
1821  // Read the header inside the container (master
1822  // data)
1823  result[proci] = decomposedBlockData::
1825  (
1826  io,
1827  is
1828  );
1829  }
1830  headerClassName[proci] = io.headerClassName();
1831  note[proci] = io.note();
1832  }
1833  }
1834  }
1835  }
1836  }
1837  ok = scatterList(result, Pstream::msgType(), comm_);
1838  io.headerClassName() = scatterList
1839  (
1840  headerClassName,
1841  Pstream::msgType(),
1842  comm_
1843  );
1844  io.note() = scatterList(note, Pstream::msgType(), comm_);
1845  }
1846 
1847  if (debug)
1848  {
1849  Pout<< "masterUncollatedFileOperation::readHeader :" << " ok:" << ok
1850  << " class:" << io.headerClassName() << endl;
1851  }
1852  return ok;
1853 }
1854 
1855 
1858 (
1859  regIOobject& io,
1860  const fileName& fName,
1861  const word& typeName,
1862  const bool read
1863 ) const
1864 {
1865  if (debug)
1866  {
1867  Pout<< "masterUncollatedFileOperation::readStream :"
1868  << " object : " << io.name()
1869  << " global : " << io.global()
1870  << " fName : " << fName << " read:" << read << endl;
1871  }
1872 
1873 
1874  autoPtr<ISstream> isPtr;
1875  bool isCollated = false;
1876  IOobject headerIO(io);
1877 
1878  // Detect collated format. This could be done on the local communicator
1879  // but we do it on the master node only for now.
1880  if (UPstream::master()) // comm_))
1881  {
1882  if (!fName.empty())
1883  {
1884  // This can happen in lagrangian field reading some processors
1885  // have no file to read from. This will only happen when using
1886  // normal writing since then the fName for the valid processors is
1887  // processorDDD/<instance>/.. . In case of collocated writing
1888  // the fName is already rewritten to processors/.
1889 
1890  isPtr.reset(new IFstream(fName));
1891 
1892  if (isPtr().good())
1893  {
1894  // Read header data (on copy)
1895  headerIO.readHeader(isPtr());
1896 
1897  if (headerIO.headerClassName() == decomposedBlockData::typeName)
1898  {
1899  isCollated = true;
1900  }
1901  else if (!Pstream::parRun())
1902  {
1903  // Short circuit: non-collated format. No parallel bits.
1904  // Copy header and return.
1905  if (debug)
1906  {
1907  Pout<< "masterUncollatedFileOperation::readStream :"
1908  << " For object : " << io.name()
1909  << " doing straight IFstream input from "
1910  << fName << endl;
1911  }
1912  io = headerIO;
1913  return isPtr;
1914  }
1915  }
1916 
1917  if (!isCollated)
1918  {
1919  // Close file. Reopened below.
1920  isPtr.clear();
1921  }
1922  }
1923  }
1924 
1925  Pstream::scatter(isCollated); //, Pstream::msgType(), comm_);
1926 
1927  if (isCollated)
1928  {
1929  if (debug)
1930  {
1931  Pout<< "masterUncollatedFileOperation::readStream :"
1932  << " For object : " << io.name()
1933  << " starting collating input from " << fName << endl;
1934  }
1935 
1936 
1937  // Analyse the file path (on (co)master) to see the processors type
1938  fileName path, procDir, local;
1939  label groupStart, groupSize, nProcs;
1940  splitProcessorPath
1941  (
1942  fName,
1943  path,
1944  procDir,
1945  local,
1946  groupStart,
1947  groupSize,
1948  nProcs
1949  );
1950 
1951 
1952  List<char> data;
1953  if (!Pstream::parRun())
1954  {
1955  // Analyse the objectpath to find out the processor we're trying
1956  // to access
1957  label proci = detectProcessorPath(io.objectPath());
1958 
1959  if (proci == -1)
1960  {
1961  FatalIOErrorInFunction(isPtr())
1962  << "Could not detect processor number"
1963  << " from objectPath:" << io.objectPath()
1964  << exit(FatalIOError);
1965  }
1966 
1967  // Analyse the fileName for any processor subset. Note: this
1968  // should really be part of filePath() which should return
1969  // both file and index in file.
1970  if (groupStart != -1 && groupSize > 0)
1971  {
1972  proci = proci-groupStart;
1973  }
1974 
1975  if (debug)
1976  {
1977  Pout<< "masterUncollatedFileOperation::readStream :"
1978  << " For object : " << io.name()
1979  << " starting input from block " << proci
1980  << " of " << isPtr().name() << endl;
1981  }
1982 
1983  return decomposedBlockData::readBlock(proci, isPtr(), io);
1984  }
1985  else
1986  {
1987  // Scatter master header info
1988  string versionString;
1989  string formatString;
1990  if (isPtr.valid())
1991  {
1992  versionString = isPtr().version().str();
1993  OStringStream os;
1994  os << isPtr().format();
1995  formatString = (os.str());
1996  }
1997 
1998  Pstream::scatter(versionString); //, Pstream::msgType(), comm);
1999  Pstream::scatter(formatString); //, Pstream::msgType(), comm);
2000 
2001  // Get size of file
2002  off_t sz = Foam::fileSize(fName);
2003  bool bigSize = sz > off_t(maxMasterFileBufferSize);
2004  Pstream::scatter(bigSize);
2005 
2006  // Are we reading from single-master file ('processors256') or
2007  // from multi-master files ('processors256_0-9')
2008  label readComm = -1;
2009  if (groupStart != -1 && groupSize > 0)
2010  {
2011  readComm = comm_;
2012  if (UPstream::master(comm_) && !isPtr.valid() && !fName.empty())
2013  {
2014  // In multi-master mode also open the file on the other
2015  // masters
2016  isPtr.reset(new IFstream(fName));
2017 
2018  if (isPtr().good())
2019  {
2020  // Read header data (on copy)
2021  IOobject headerIO(io);
2022  headerIO.readHeader(isPtr());
2023  }
2024  }
2025  }
2026  else
2027  {
2028  // Single master so read on world
2029  readComm = Pstream::worldComm;
2030  }
2031 
2032  // Read my data
2034  (
2035  readComm,
2036  fName,
2037  isPtr,
2038  io,
2039  (
2040  bigSize
2043  )
2044  );
2045  }
2046  }
2047  else
2048  {
2049  if (debug)
2050  {
2051  Pout<< "masterUncollatedFileOperation::readStream :"
2052  << " For object : " << io.name()
2053  << " starting separated input from " << fName << endl;
2054  }
2055 
2056  if (io.global())
2057  {
2058  // Use worldComm. Note: should not really need to gather filePaths
2059  // since we enforce sending from master anyway ...
2060  fileNameList filePaths(Pstream::nProcs());
2061  filePaths[Pstream::myProcNo()] = fName;
2062  Pstream::gatherList(filePaths);
2063  boolList procValid(Pstream::nProcs());
2064  procValid[Pstream::myProcNo()] = read;
2065  Pstream::gatherList(procValid);
2066 
2067  return this->read
2068  (
2069  io,
2071  true,
2072  filePaths,
2073  procValid
2074  );
2075  }
2076  else
2077  {
2078  // Use local communicator
2079  fileNameList filePaths(Pstream::nProcs(comm_));
2080  filePaths[Pstream::myProcNo(comm_)] = fName;
2081  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
2082  boolList procValid(Pstream::nProcs(comm_));
2083  procValid[Pstream::myProcNo(comm_)] = read;
2084  Pstream::gatherList(procValid, Pstream::msgType(), comm_);
2085 
2086  // Uniform in local comm
2087  bool uniform = uniformFile(filePaths);
2088 
2089  return this->read
2090  (
2091  io,
2092  comm_,
2093  uniform,
2094  filePaths,
2095  procValid
2096  );
2097  }
2098  }
2099 }
2100 
2101 
2103 (
2104  regIOobject& io,
2105  const bool masterOnly,
2106  const IOstream::streamFormat defaultFormat,
2107  const word& typeName
2108 ) const
2109 {
2110  bool ok = true;
2111 
2112  // Initialise format to the defaultFormat
2113  // but reset to ASCII if defaultFormat and file format are ASCII
2114  IOstream::streamFormat format = defaultFormat;
2115 
2116  if (io.global())
2117  {
2118  if (debug)
2119  {
2120  Pout<< "masterUncollatedFileOperation::read :"
2121  << " Reading global object " << io.name() << endl;
2122  }
2123 
2124  // Now that we have an IOobject path use it to detect & cache
2125  // processor directory naming
2126  (void)lookupProcessorsPath(io.objectPath());
2127 
2128  // Trigger caching of times
2129  (void)findTimes(io.time().path(), io.time().constant());
2130 
2131  bool ok = false;
2132  if (Pstream::master()) // comm_))
2133  {
2134  // Do master-only reading always.
2135  bool oldParRun = UPstream::parRun();
2136  UPstream::parRun() = false;
2137 
2138  // Open file and read header
2139  Istream& is = io.readStream(typeName);
2140 
2141  // Set format to ASCII if defaultFormat and file format are ASCII
2142  if (defaultFormat == IOstream::ASCII)
2143  {
2144  format = is.format();
2145  }
2146 
2147  // Read the data from the file
2148  ok = io.readData(is);
2149 
2150  // Close the file
2151  io.close();
2152 
2153  UPstream::parRun() = oldParRun;
2154  }
2155 
2156  Pstream::scatter(ok);
2158  Pstream::scatter(io.note());
2159 
2160  if (defaultFormat == IOstream::ASCII)
2161  {
2162  std::underlying_type_t<IOstream::streamFormat> formatValue(format);
2163  Pstream::scatter(formatValue);
2164  format = IOstream::streamFormat(formatValue);
2165  }
2166 
2167  // scatter operation for regIOobjects
2168 
2169  // Get my communication order
2170  const List<Pstream::commsStruct>& comms =
2171  (
2175  );
2176  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
2177 
2178  // Receive from up
2179  if (myComm.above() != -1)
2180  {
2181  IPstream fromAbove
2182  (
2184  myComm.above(),
2185  0,
2186  Pstream::msgType(),
2188  format
2189  );
2190  ok = io.readData(fromAbove);
2191  }
2192 
2193  // Send to my downstairs neighbours
2194  forAll(myComm.below(), belowI)
2195  {
2196  OPstream toBelow
2197  (
2199  myComm.below()[belowI],
2200  0,
2201  Pstream::msgType(),
2203  format
2204  );
2205  bool okWrite = io.writeData(toBelow);
2206  ok = ok && okWrite;
2207  }
2208  }
2209  else
2210  {
2211  if (debug)
2212  {
2213  Pout<< "masterUncollatedFileOperation::read :"
2214  << " Reading local object " << io.name() << endl;
2215  }
2216 
2217  ok = io.readData(io.readStream(typeName));
2218  io.close();
2219  }
2220 
2221  return ok;
2222 }
2223 
2224 
2226 (
2227  const regIOobject& io,
2231  const bool write
2232 ) const
2233 {
2234  fileName filePath(io.objectPath());
2235 
2236  if (debug)
2237  {
2238  Pout<< "masterUncollatedFileOperation::writeObject :"
2239  << " io:" << filePath << " write:" << write << endl;
2240  }
2241 
2242  // Make sure to pick up any new times
2243  setTime(io.time());
2244 
2245  autoPtr<Ostream> osPtr
2246  (
2247  NewOFstream
2248  (
2249  filePath,
2250  fmt,
2251  ver,
2252  cmp,
2253  write
2254  )
2255  );
2256  Ostream& os = osPtr();
2257 
2258  // If any of these fail, return (leave error handling to Ostream class)
2259  if (!os.good())
2260  {
2261  return false;
2262  }
2263 
2264  if (!io.writeHeader(os))
2265  {
2266  return false;
2267  }
2268 
2269  // Write the data to the Ostream
2270  if (!io.writeData(os))
2271  {
2272  return false;
2273  }
2274 
2276 
2277  return true;
2278 }
2279 
2280 
2282 (
2283  const fileName& directory,
2284  const word& constantName
2285 ) const
2286 {
2288  if (iter != times_.end())
2289  {
2290  if (debug)
2291  {
2292  Pout<< "masterUncollatedFileOperation::findTimes :"
2293  << " Found " << iter()->size() << " cached times" << endl;
2294  }
2295  return *iter();
2296  }
2297  else
2298  {
2299  instantList times;
2300  if (Pstream::master()) // comm_))
2301  {
2302  // Do master-only reading always.
2303  bool oldParRun = UPstream::parRun();
2304  UPstream::parRun() = false;
2305  times = fileOperation::findTimes(directory, constantName);
2306  UPstream::parRun() = oldParRun;
2307  }
2308  Pstream::scatter(times); //, Pstream::msgType(), comm_);
2309 
2310  // Note: do we also cache if no times have been found since it might
2311  // indicate a directory that is being filled later on ...
2312 
2313  instantList* tPtr = new instantList(move(times));
2314 
2315  times_.insert(directory, tPtr);
2316 
2317  if (debug)
2318  {
2319  Pout<< "masterUncollatedFileOperation::findTimes :"
2320  << " Caching times:" << *tPtr << nl
2321  << " for directory:" << directory << endl;
2322  }
2323  return *tPtr;
2324  }
2325 }
2326 
2327 
2329 (
2330  const Time& tm
2331 ) const
2332 {
2333  if (tm.subCycling())
2334  {
2335  return;
2336  }
2337 
2338  HashPtrTable<instantList>::const_iterator iter = times_.find(tm.path());
2339  if (iter != times_.end())
2340  {
2341  instantList& times = *iter();
2342 
2343  const instant timeNow(tm.value(), tm.name());
2344 
2345  if (times.size() > 0 && times[0].name() == tm.constant())
2346  {
2347  // Exclude constant
2348  SubList<instant> realTimes(times, times.size()-1, 1);
2349  if
2350  (
2352  (
2353  SubList<instant>(times, times.size()-1, 1),
2354  timeNow
2355  )
2356  == -1
2357  )
2358  {
2359  if (debug)
2360  {
2361  Pout<< "masterUncollatedFileOperation::setTime :"
2362  << " Caching time " << tm.name()
2363  << " for case:" << tm.path() << endl;
2364  }
2365 
2366  times.append(timeNow);
2367  SubList<instant> realTimes(times, times.size()-1, 1);
2368  Foam::stableSort(realTimes);
2369  }
2370  }
2371  else
2372  {
2373  if (findSortedIndex(times, timeNow) == -1)
2374  {
2375  if (debug)
2376  {
2377  Pout<< "masterUncollatedFileOperation::setTime :"
2378  << " Caching time " << tm.name()
2379  << " for case:" << tm.path() << endl;
2380  }
2381 
2382  times.append(timeNow);
2383  Foam::stableSort(times);
2384  }
2385  }
2386  }
2388 }
2389 
2390 
2393 (
2394  const fileName& filePath,
2396  IOstream::versionNumber version
2397 ) const
2398 {
2399  if (Pstream::parRun())
2400  {
2401  // Insert logic of filePath. We assume that if a file is absolute
2402  // on the master it is absolute also on the slaves etc.
2403 
2405  filePaths[Pstream::myProcNo(Pstream::worldComm)] = filePath;
2407 
2408  PstreamBuffers pBufs
2409  (
2411  Pstream::msgType(),
2413  );
2414 
2416  {
2417  const bool uniform = uniformFile(filePaths);
2418 
2419  if (uniform)
2420  {
2421  if (debug)
2422  {
2423  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2424  << " Opening global file " << filePath << endl;
2425  }
2426 
2428  for
2429  (
2430  label proci = 1;
2432  proci++
2433  )
2434  {
2435  procs[proci-1] = proci;
2436  }
2437 
2438  readAndSend(filePath, procs, pBufs);
2439  }
2440  else
2441  {
2442  for
2443  (
2444  label proci = 1;
2446  proci++
2447  )
2448  {
2449  readAndSend(filePaths[proci], labelList(1, proci), pBufs);
2450  }
2451  }
2452  }
2453 
2454 
2455  labelList recvSizes;
2456  pBufs.finishedSends(recvSizes);
2457 
2459  {
2460  // Read myself
2461  return autoPtr<ISstream>
2462  (
2463  new IFstream(filePaths[Pstream::masterNo()], format, version)
2464  );
2465  }
2466  else
2467  {
2468  if (debug)
2469  {
2470  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2471  << " Reading " << filePath
2472  << " from processor " << Pstream::masterNo() << endl;
2473  }
2474 
2475  UIPstream is(Pstream::masterNo(), pBufs);
2476  string buf(recvSizes[Pstream::masterNo()], '\0');
2477  is.read(&buf[0], recvSizes[Pstream::masterNo()]);
2478 
2479  if (debug)
2480  {
2481  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2482  << " Done reading " << buf.size() << " bytes" << endl;
2483  }
2484 
2485  // Note: IPstream is not an IStream so use a IStringStream to
2486  // convert the buffer. Note that we construct with a string
2487  // so it holds a copy of the buffer.
2488  return autoPtr<ISstream>
2489  (
2490  new IStringStream(filePath, buf, IOstream::BINARY)
2491  );
2492  }
2493  }
2494  else
2495  {
2496  // Read myself
2497  return autoPtr<ISstream>(new IFstream(filePath, format, version));
2498  }
2499 }
2500 
2501 
2504 (
2505  const fileName& filePath,
2507  IOstream::versionNumber version,
2508  IOstream::compressionType compression,
2509  const bool write
2510 ) const
2511 {
2512  return autoPtr<Ostream>
2513  (
2514  new masterOFstream
2515  (
2516  filePath,
2517  format,
2518  version,
2519  compression,
2520  false, // append
2521  write
2522  )
2523  );
2524 }
2525 
2526 
2528 {
2530  times_.clear();
2531 }
2532 
2533 
2535 (
2536  const fileName& fName
2537 ) const
2538 {
2539  label watchFd;
2540  if (Pstream::master()) // comm_))
2541  {
2542  watchFd = monitor().addWatch(fName);
2543  }
2544  Pstream::scatter(watchFd); //, Pstream::msgType(), comm_);
2545  return watchFd;
2546 }
2547 
2548 
2550 (
2551  const label watchIndex
2552 ) const
2553 {
2554  bool ok;
2555  if (Pstream::master()) // comm_))
2556  {
2557  ok = monitor().removeWatch(watchIndex);
2558  }
2559  Pstream::scatter(ok); //, Pstream::msgType(), comm_);
2560  return ok;
2561 }
2562 
2563 
2565 (
2566  const labelList& watchIndices,
2567  const fileName& fName
2568 ) const
2569 {
2570  label index = -1;
2571 
2572  if (Pstream::master()) // comm_))
2573  {
2574  forAll(watchIndices, i)
2575  {
2576  if (monitor().getFile(watchIndices[i]) == fName)
2577  {
2578  index = i;
2579  break;
2580  }
2581  }
2582  }
2583  Pstream::scatter(index); //, Pstream::msgType(), comm_);
2584  return index;
2585 }
2586 
2587 
2589 (
2590  regIOobject& rio,
2591  const fileNameList& files
2592 ) const
2593 {
2594  const labelList& watchIndices = rio.watchIndices();
2595 
2596  DynamicList<label> newWatchIndices;
2597  labelHashSet removedWatches(watchIndices);
2598 
2599  forAll(files, i)
2600  {
2601  const fileName& f = files[i];
2602  label index = findWatch(watchIndices, f);
2603 
2604  if (index == -1)
2605  {
2606  newWatchIndices.append(addWatch(f));
2607  }
2608  else
2609  {
2610  // Existing watch
2611  newWatchIndices.append(watchIndices[index]);
2612  removedWatches.erase(index);
2613  }
2614  }
2615 
2616  // Remove any unused watches
2617  forAllConstIter(labelHashSet, removedWatches, iter)
2618  {
2619  removeWatch(watchIndices[iter.key()]);
2620  }
2621 
2622  rio.watchIndices() = newWatchIndices;
2623 }
2624 
2625 
2627 (
2628  const label watchIndex
2629 ) const
2630 {
2631  fileName fName;
2632  if (Pstream::master()) // comm_))
2633  {
2634  fName = monitor().getFile(watchIndex);
2635  }
2636  Pstream::scatter(fName); //, Pstream::msgType(), comm_);
2637  return fName;
2638 }
2639 
2640 
2642 (
2643  const bool masterOnly,
2644  const bool syncPar
2645 ) const
2646 {
2647  if (Pstream::master()) // comm_))
2648  {
2649  monitor().updateStates(true, false);
2650  }
2651 }
2652 
2653 
2656 (
2657  const label watchFd
2658 ) const
2659 {
2660  unsigned int state = fileMonitor::UNMODIFIED;
2661  if (Pstream::master()) // comm_))
2662  {
2663  state = monitor().getState(watchFd);
2664  }
2665  Pstream::scatter(state); //, Pstream::msgType(), comm_);
2666  return fileMonitor::fileState(state);
2667 }
2668 
2669 
2671 (
2672  const label watchFd
2673 ) const
2674 {
2675  if (Pstream::master()) // comm_))
2676  {
2677  monitor().setUnmodified(watchFd);
2678  }
2679 }
2680 
2681 
2682 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
Macros for easy insertion into run-time selection tables.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
An STL-conforming const_iterator.
Definition: HashTable.H:498
bool erase(const iterator &)
Erase a hashedEntry specified by given iterator.
Definition: HashTable.C:445
Input from file stream.
Definition: IFstream.H:85
virtual istream & stdStream()
Access to underlying std::istream.
Definition: IFstream.C:141
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const fileName & local() const
Definition: IOobject.H:400
const fileName & caseName(const bool global) const
Definition: IOobject.C:342
const Time & time() const
Return time.
Definition: IOobject.C:318
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:119
static Stream & writeEndDivider(Stream &os)
Write the standard end file divider.
Definition: IOobjectI.H:103
fileName & instance() const
Return the instance directory, constant, system, <time> etc.
Definition: IOobject.C:355
const objectRegistry & db() const
Return the local objectRegistry.
Definition: IOobject.C:312
string & note()
Return non-constant access to the optional note.
Definition: IOobject.H:328
readOption readOpt() const
Definition: IOobject.H:360
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:316
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:226
bool readHeader(Istream &)
Read header.
const word & name() const
Return name.
Definition: IOobject.H:310
const fileName & rootPath() const
Definition: IOobject.C:336
bool writeHeader(Ostream &) const
Write header.
fileName objectPath(const bool global) const
Return complete path + object name including the processor.
Definition: IOobject.H:411
fileName path(const bool global) const
Return complete path including the processor sub-directory.
Definition: IOobject.C:380
Version number type.
Definition: IOstream.H:97
streamFormat format() const
Return current stream format.
Definition: IOstream.H:374
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:330
Input inter-processor communications stream.
Definition: IPstream.H:54
Input from memory buffer stream.
Definition: IStringStream.H:52
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
Output inter-processor communications stream.
Definition: OPstream.H:54
Output to memory buffer stream.
Definition: OStringStream.H:52
string str() const
Return the string.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A bit-packed bool list.
void set(const PackedList< 1 > &)
Set specified bits.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
Inter-processor communications stream.
Definition: Pstream.H:56
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
A List obtained as a section of another List.
Definition: SubList.H:56
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
static const word & system()
Return system name.
Definition: TimePaths.H:112
bool processorCase() const
Return true if this is a processor case.
Definition: TimePaths.H:88
const fileName & globalCaseName() const
Return global case name.
Definition: TimePaths.H:100
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
instantList times() const
Search the case for valid time directories.
Definition: Time.C:651
fileName path() const
Explicitly inherit path from TimePaths to disambiguate from.
Definition: TimePaths.H:138
bool subCycling() const
Return true if time currently being sub-cycled, otherwise false.
Definition: Time.H:438
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:57
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Read into given buffer from given processor and return the.
Definition: UIPread.C:79
T & first()
Return the first element of the list.
Definition: UListI.H:114
iterator begin()
Return an iterator to begin traversing the UList.
Definition: UListI.H:216
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:58
static bool write(const commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Write given buffer to given processor.
Definition: UOPwrite.C:34
Structure for communicating between processors.
Definition: UPstream.H:77
const labelList & below() const
Definition: UPstream.H:130
Inter-processor communications stream.
Definition: UPstream.H:59
static int masterNo()
Process index of the master.
Definition: UPstream.H:417
static void freeCommunicator(const label communicator, const bool doPstream=true)
Free a previously allocated communicator.
Definition: UPstream.C:314
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:278
static int nProcsSimpleSum
Number of processors at which the sum algorithm changes from linear.
Definition: UPstream.H:269
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:411
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
static const List< commsStruct > & linearCommunication(const label communicator=0)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.H:459
static const List< commsStruct > & treeCommunication(const label communicator=0)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.H:468
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
T * ptr()
Return object pointer for reuse.
Definition: autoPtrI.H:90
void clear()
Delete object (if the pointer is valid) and set pointer to.
Definition: autoPtrI.H:126
void reset(T *=nullptr)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
static bool readMasterHeader(IOobject &, Istream &)
Read header. Call only on master.
static bool readBlocks(const label comm, autoPtr< ISstream > &isPtr, List< char > &data, const UPstream::commsTypes commsType)
Read data into *this. ISstream is only valid on master.
static autoPtr< ISstream > readBlock(const label blocki, Istream &is, IOobject &headerIO)
Read selected block (non-seeking) + header information.
const Type & value() const
Return const reference to value.
const word & name() const
Return const reference to name.
Dummy stream for input. Aborts at any attempt to read from it.
Definition: dummyISstream.H:50
fileState
Enumeration defining the file state.
Definition: fileMonitor.H:70
A class for handling file names.
Definition: fileName.H:82
bool isAbsolute() const
Return true if file name is absolute.
Definition: fileName.C:73
static const fileName null
An empty fileName.
Definition: fileName.H:97
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
virtual fileNameList readObjects(const objectRegistry &db, const fileName &instance, const fileName &local, word &newInstance) const
Search directory for objects. Used in IOobjectList.
pathType
Enumeration for the location of an IOobject.
Definition: fileOperation.H:62
static const NamedEnum< pathType, 12 > pathTypeNames_
Definition: fileOperation.H:79
virtual void setTime(const Time &) const
Callback for time change.
virtual instantList findTimes(const fileName &, const word &) const
Get sorted list of times.
fileOperations that performs all file operations on the master processor. Requires the calls to be pa...
masterUncollatedFileOperationInitialise(int &argc, char **&argv)
Construct from components.
virtual bool writeObject(const regIOobject &, IOstream::streamFormat format=IOstream::ASCII, IOstream::versionNumber version=IOstream::currentVersion, IOstream::compressionType compression=IOstream::UNCOMPRESSED, const bool write=true) const
Writes a regIOobject (so header, contents and divider).
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
static word findInstancePath(const instantList &timeDirs, const instant &t)
Equivalent of Time::findInstance.
virtual autoPtr< ISstream > NewIFstream(const fileName &filePath, IOstream::streamFormat format=IOstream::ASCII, IOstream::versionNumber version=IOstream::currentVersion) const
Generate an ISstream that reads a file.
virtual double highResLastModified(const fileName &, const bool checkVariants=true, const bool followLink=true) const
Return time of last file modification.
virtual fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true) const
Return the file type: directory, file or link.
virtual bool isFile(const fileName &, const bool checkVariants=true, const bool followLink=true) const
Does the name exist as a file in the file system?
virtual label addWatch(const fileName &) const
Add watching of a file. Returns handle.
static labelList subRanks(const label n)
Get the list of processors that are part of this communicator.
static void readAndSend(const fileName &fName, const labelUList &procs, PstreamBuffers &pBufs)
Detect file (possibly compressed), read file contents and send.
virtual void setTime(const Time &) const
Callback for time change.
virtual off_t fileSize(const fileName &, const bool checkVariants=true, const bool followLink=true) const
Return size of file.
virtual time_t lastModified(const fileName &, const bool checkVariants=true, const bool followLink=true) const
Return time of last file modification.
virtual fileName filePath(const bool globalFile, const IOobject &, const word &typeName) const
Search for an object. globalFile : also check undecomposed case.
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
static float maxMasterFileBufferSize
Max size of parallel communications. Switches from non-blocking.
virtual fileNameList readDir(const fileName &, const fileType=fileType::file, const bool filterVariants=true, const bool followLink=true) const
Read a directory and return the entries as a string list.
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
virtual bool readHeader(IOobject &, const fileName &, const word &typeName) const
Read object header from supplied file.
virtual bool mvBak(const fileName &, const std::string &ext="bak") const
Rename to a corresponding backup file.
virtual fileNameList readObjects(const objectRegistry &db, const fileName &instance, const fileName &local, word &newInstance) const
Search directory for objects. Used in IOobjectList.
virtual bool rmDir(const fileName &) const
Remove a directory and its contents.
virtual label findWatch(const labelList &watchIndices, const fileName &) const
Find index (or -1) of file in list of handles.
virtual bool cp(const fileName &src, const fileName &dst, const bool followLink=true) const
Copy, recursively if necessary, the source to the destination.
virtual bool chMod(const fileName &, const mode_t) const
Set the file mode.
virtual IOobject findInstance(const IOobject &io, const scalar startValue, const word &stopInstance) const
Find instance where IOobject is. Fails if cannot be found.
bool exists(const dirIndexList &, IOobject &io) const
Helper: check IO for local existence. Like filePathInfo but.
virtual autoPtr< Ostream > NewOFstream(const fileName &filePath, IOstream::streamFormat format=IOstream::ASCII, IOstream::versionNumber version=IOstream::currentVersion, IOstream::compressionType compression=IOstream::UNCOMPRESSED, const bool write=true) const
Generate an Ostream that writes a file.
virtual autoPtr< ISstream > readStream(regIOobject &, const fileName &, const word &typeName, const bool read=true) const
Reads header for regIOobject and returns an ISstream.
virtual bool rm(const fileName &) const
Remove a file, returning true if successful otherwise false.
virtual bool isDir(const fileName &, const bool followLink=true) const
Does the name exist as a directory in the file system?
fileName relativeObjectPath(const IOobject &, const pathType &searchType, const word &processorsDir, const word &instancePath) const
Construct filePath.
static autoPtr< ISstream > read(IOobject &io, const label comm, const bool uniform, const fileNameList &filePaths, const boolList &read)
Read files on comms master.
virtual fileMonitor::fileState getState(const label) const
Get current state of file (using handle)
virtual void setUnmodified(const label) const
Set current state of file (using handle) to unmodified.
virtual void updateStates(const bool masterOnly, const bool syncPar) const
Update state of all files.
virtual mode_t mode(const fileName &, const bool checkVariants=true, const bool followLink=true) const
Return the file mode.
static bool uniformFile(const fileNameList &)
Same file?
virtual bool mkDir(const fileName &, mode_t=0777) const
Make directory.
virtual fileName dirPath(const bool globalFile, const IOobject &) const
Search for a directory. globalFile : also check undecomposed.
virtual instantList findTimes(const fileName &, const word &) const
Get sorted list of times.
virtual fileName filePathInfo(const bool globalFile, const bool isFile, const IOobject &, pathType &searchType, word &processorsDir, word &instance) const
Search (locally!) for object; return info on how it was found.
virtual bool mv(const fileName &src, const fileName &dst, const bool followLink=false) const
Rename src to dst.
virtual bool ln(const fileName &src, const fileName &dst) const
Create a softlink. dst should not exist. Returns true if.
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
An instant of time. Contains the time value and name.
Definition: instant.H:67
bool equal(const scalar) const
Comparison used for instants to be equal.
Definition: instant.C:59
Master-only drop-in replacement for OFstream.
Registry of regIOobjects.
const Time & time() const
Return time.
virtual const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
const labelList & watchIndices() const
Return file-monitoring handles.
Definition: regIOobjectI.H:100
fileName objectPath() const
Return complete path + object name.
Definition: regIOobject.H:158
virtual bool writeData(Ostream &) const =0
Pure virtual writaData function.
virtual bool global() const
Return true if object is global, i.e. same for all processors.
Definition: regIOobject.C:181
void close()
Close Istream.
virtual bool readData(Istream &)
Virtual readData function.
A class for managing temporary objects without reference counting.
Definition: tmpNrc.H:53
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:381
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
static instantList timeDirs
Definition: globalFoam.H:44
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
runTimeSource setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex)
#define WarningInFunction
Report a warning using Foam::Warning.
#define FUNCTION_NAME
#define InfoHeader
Report write to Foam::Info if the local log switch is true.
float floatOptimisationSwitch(const char *name, const float defaultValue=0)
Lookup optimisation switch or add default value.
Definition: debug.C:278
addToRunTimeSelectionTable(fileOperation, collatedFileOperation, word)
defineTypeNameAndDebug(collatedFileOperation, 0)
addNamedToRunTimeSelectionTable(fileOperationInitialise, collatedFileOperationInitialise, word, collated)
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
bool isFile(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist as a file in the file system?
Definition: POSIX.C:555
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
off_t fileSize(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return size of file.
Definition: POSIX.C:576
mode_t mode(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file mode.
Definition: POSIX.C:461
bool read(const char *, int32_t &)
Definition: int32IO.C:85
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
bool exists(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist (as directory or file) in the file system?
Definition: POSIX.C:520
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
List< instant > instantList
List of instants.
Definition: instantList.H:42
label findSortedIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element in sorted list and return index,.
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
IOerror FatalIOError
fileType
Enumeration of file types.
Definition: fileName.H:67
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
void stableSort(UList< T > &)
Definition: UList.C:129
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
static const char nl
Definition: Ostream.H:266
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
word format(conversionProperties.lookup("format"))
labelList f(nPoints)