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-2025 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));
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);
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
1137 {
1138  if (debug)
1139  {
1140  Pout<< "masterUncollatedFileOperation::filePath :"
1141  << " objectPath:" << io.objectPath(globalFile)
1142  << " globalFile:" << globalFile << endl;
1143  }
1144 
1145  // Now that we have an IOobject path use it to detect & cache
1146  // processor directory naming
1147  (void)lookupProcessorsPath(io.objectPath(globalFile));
1148 
1149  // Trigger caching of times
1150  (void)findTimes(io.time(), io.time().path(), io.time().constant());
1151 
1152 
1153  // Determine master filePath and scatter
1154 
1155  fileName objPath;
1156  pathType searchType = NOTFOUND;
1157  word procsDir;
1158  word newInstancePath;
1159 
1160  if (Pstream::master(comm_))
1161  {
1162  // All masters search locally. Note that global objects might
1163  // fail (except on master). This gets handled later on (in PARENTOBJECT)
1164  objPath = filePathInfo
1165  (
1166  globalFile,
1167  true,
1168  io,
1169  searchType,
1170  procsDir,
1171  newInstancePath
1172  );
1173 
1174  if (debug)
1175  {
1176  Pout<< "masterUncollatedFileOperation::filePath :"
1177  << " master objPath:" << objPath
1178  << " searchType:" << fileOperation::pathTypeNames_[searchType]
1179  << " procsDir:" << procsDir << " instance:" << newInstancePath
1180  << endl;
1181  }
1182 
1183  }
1184 
1185  // Scatter the information about where the master found the object
1186  // Note: use the worldComm to make sure all processors decide
1187  // the same type. Only procsDir is allowed to differ; searchType
1188  // and instance have to be same
1189  {
1190  label masterType(searchType);
1191  Pstream::scatter(masterType);
1192  searchType = pathType(masterType);
1193  }
1194  Pstream::scatter(newInstancePath);
1195 
1196  if
1197  (
1198  globalFile
1199  || searchType == fileOperation::PARENTOBJECT
1200  || searchType == fileOperation::PROCBASEOBJECT
1201  || searchType == fileOperation::PROCBASEINSTANCE
1202  || io.local() == "uniform"
1203  )
1204  {
1205  // Distribute master path. This makes sure it is seen as uniform
1206  // and only gets read from the master.
1207  Pstream::scatter(objPath);
1208  Pstream::scatter(procsDir);
1209  }
1210  else
1211  {
1212  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1213 
1214  // Use the master type to determine if additional information is
1215  // needed to construct the local equivalent
1216  switch (searchType)
1217  {
1221  {
1222  // Already handled above
1223  }
1224  break;
1225 
1233  {
1234  // Construct equivalent local path
1235  objPath = relativeObjectPath
1236  (
1237  io,
1238  searchType,
1239  procsDir,
1240  newInstancePath
1241  );
1242  }
1243  break;
1244 
1245  case fileOperation::OBJECT:
1247  {
1248  // Retest all processors separately since some processors might
1249  // have the file and some not (e.g. lagrangian data)
1250 
1251  objPath = masterOp<fileName, fileOrNullOp>
1252  (
1253  io.objectPath(globalFile),
1254  fileOrNullOp(true),
1255  Pstream::msgType(),
1256  comm_
1257  );
1258  }
1259  break;
1260  }
1261  }
1262 
1263  if (debug)
1264  {
1265  Pout<< "masterUncollatedFileOperation::filePath :"
1266  << " Returning from file searching:" << endl
1267  << " objectPath:" << io.objectPath(globalFile) << endl
1268  << " filePath :" << objPath << endl << endl;
1269  }
1270  return objPath;
1271 }
1272 
1273 
1275 (
1276  const bool globalFile,
1277  const IOobject& io
1278 ) const
1279 {
1280  if (debug)
1281  {
1282  Pout<< "masterUncollatedFileOperation::dirPath :"
1283  << " objectPath:" << io.objectPath(globalFile)
1284  << " globalFile:" << globalFile << endl;
1285  }
1286 
1287  // Now that we have an IOobject path use it to detect & cache
1288  // processor directory naming
1289  (void)lookupProcessorsPath(io.objectPath(globalFile));
1290 
1291  // Determine master dirPath and scatter
1292 
1293  fileName objPath;
1294  pathType searchType = NOTFOUND;
1295  word procsDir;
1296  word newInstancePath;
1297 
1298  if (Pstream::master(comm_))
1299  {
1300  objPath = filePathInfo
1301  (
1302  globalFile,
1303  false,
1304  io,
1305  searchType,
1306  procsDir,
1307  newInstancePath
1308  );
1309  }
1310 
1311  {
1312  label masterType(searchType);
1313  Pstream::scatter(masterType); //, Pstream::msgType(), comm_);
1314  searchType = pathType(masterType);
1315  }
1316  Pstream::scatter(newInstancePath); //, Pstream::msgType(), comm_);
1317 
1318  if
1319  (
1320  globalFile
1321  || searchType == fileOperation::PARENTOBJECT
1322  || searchType == fileOperation::PROCBASEOBJECT
1323  || searchType == fileOperation::PROCBASEINSTANCE
1324  || io.local() == "uniform"
1325  )
1326  {
1327  // Distribute master path. This makes sure it is seen as uniform
1328  // and only gets read from the master.
1329  Pstream::scatter(objPath);
1330  Pstream::scatter(procsDir);
1331  }
1332  else
1333  {
1334  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1335 
1336  // Use the master type to determine if additional information is
1337  // needed to construct the local equivalent
1338  switch (searchType)
1339  {
1343  {
1344  // Already handled above
1345  }
1346  break;
1347 
1355  {
1356  // Construct equivalent local path
1357  objPath = relativeObjectPath
1358  (
1359  io,
1360  searchType,
1361  procsDir,
1362  newInstancePath
1363  );
1364  }
1365  break;
1366 
1367  case fileOperation::OBJECT:
1369  {
1370  // Retest all processors separately since some processors might
1371  // have the file and some not (e.g. lagrangian data)
1372  objPath = masterOp<fileName, fileOrNullOp>
1373  (
1374  io.objectPath(globalFile),
1375  fileOrNullOp(false),
1376  Pstream::msgType(),
1377  comm_
1378  );
1379  }
1380  break;
1381  }
1382  }
1383 
1384  if (debug)
1385  {
1386  Pout<< "masterUncollatedFileOperation::dirPath :"
1387  << " Returning from file searching:" << endl
1388  << " objectPath:" << io.objectPath(globalFile) << endl
1389  << " filePath :" << objPath << endl << endl;
1390  }
1391  return objPath;
1392 }
1393 
1394 
1396 (
1397  const dirIndexList& pDirs,
1398  IOobject& io
1399 ) const
1400 {
1401  // Cut-down version of filePathInfo that does not look for
1402  // different instance or parent directory
1403 
1404  const bool isFile = !io.name().empty();
1405 
1406  // Generate output filename for object
1407  const fileName writePath(objectPath(io));
1408 
1409  // 1. Test writing name for either directory or a (valid) file
1410  if (isFileOrDir(isFile, writePath))
1411  {
1412  return true;
1413  }
1414 
1415  // 2. Check processors/
1416  if (io.time().processorCase())
1417  {
1418  forAll(pDirs, i)
1419  {
1420  const fileName& pDir = pDirs[i].first();
1421  fileName procPath =
1422  processorsPath(io, io.instance(), pDir)
1423  /io.name();
1424  if (procPath != writePath && isFileOrDir(isFile, procPath))
1425  {
1426  return true;
1427  }
1428  }
1429  }
1430 
1431  // 3. Check local
1432  fileName localPath = io.objectPath(false);
1433 
1434  if (localPath != writePath && isFileOrDir(isFile, localPath))
1435  {
1436  return true;
1437  }
1438 
1439  return false;
1440 }
1441 
1442 
1445 (
1446  const IOobject& startIO,
1447  const scalar startValue,
1448  const word& stopInstance
1449 ) const
1450 {
1451  if (debug)
1452  {
1453  Pout<< "masterUncollatedFileOperation::findInstance :"
1454  << " Starting searching for name:" << startIO.name()
1455  << " local:" << startIO.local()
1456  << " from instance:" << startIO.instance()
1457  << endl;
1458  }
1459 
1460 
1461  const Time& time = startIO.time();
1462 
1463  IOobject io(startIO);
1464 
1465  // Note: - if name is empty, just check the directory itself
1466  // - check both for isFile and headerOk since the latter does a
1467  // filePath so searches for the file.
1468  // - check for an object with local file scope (so no looking up in
1469  // parent directory in case of parallel)
1470 
1471 
1472  tmpNrc<dirIndexList> pDirs(lookupProcessorsPath(io.objectPath(false)));
1473 
1474  word foundInstance;
1475 
1476  // if (Pstream::master(comm_))
1478  {
1479  if (exists(pDirs, io))
1480  {
1481  foundInstance = io.instance();
1482  }
1483  }
1484 
1485  // Do parallel early exit to avoid calling time.times()
1486  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1488  if (!foundInstance.empty())
1489  {
1490  io.instance() = foundInstance;
1491  if (debug)
1492  {
1493  Pout<< "masterUncollatedFileOperation::findInstance :"
1494  << " for name:" << io.name() << " local:" << io.local()
1495  << " found starting instance:" << io.instance() << endl;
1496  }
1497  return io;
1498  }
1499 
1500 
1501  // Search back through the time directories to find the time
1502  // closest to and lower than current time
1503 
1504  instantList ts = time.times();
1505  // if (Pstream::master(comm_))
1507  {
1508  label instanceI;
1509 
1510  for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
1511  {
1512  if (ts[instanceI].value() <= startValue)
1513  {
1514  break;
1515  }
1516  }
1517 
1518  // continue searching from here
1519  for (; instanceI >= 0; --instanceI)
1520  {
1521  // Shortcut: if actual directory is the timeName we've
1522  // already tested it
1523  if (ts[instanceI].name() == time.name())
1524  {
1525  continue;
1526  }
1527 
1528  io.instance() = ts[instanceI].name();
1529  if (exists(pDirs, io))
1530  {
1531  foundInstance = io.instance();
1532  if (debug)
1533  {
1534  Pout<< "masterUncollatedFileOperation::findInstance :"
1535  << " for name:" << io.name() << " local:" << io.local()
1536  << " found at:" << io.instance()
1537  << endl;
1538  }
1539  break;
1540  }
1541 
1542  // Check if hit minimum instance
1543  if (ts[instanceI].name() == stopInstance)
1544  {
1545  if
1546  (
1547  startIO.readOpt() == IOobject::MUST_READ
1549  )
1550  {
1551  if (io.name().empty())
1552  {
1554  << "Cannot find directory "
1555  << io.local() << " in times " << time.name()
1556  << " down to " << stopInstance
1557  << exit(FatalError);
1558  }
1559  else
1560  {
1562  << "Cannot find file \"" << io.name()
1563  << "\" in directory " << io.local()
1564  << " in times " << time.name()
1565  << " down to " << stopInstance
1566  << exit(FatalError);
1567  }
1568  }
1569  foundInstance = io.instance();
1570  if (debug)
1571  {
1572  Pout<< "masterUncollatedFileOperation::findInstance :"
1573  << " name:" << io.name() << " local:" << io.local()
1574  << " found at stopinstance:" << io.instance() << endl;
1575  }
1576  break;
1577  }
1578  }
1579 
1580 
1581  if (foundInstance.empty())
1582  {
1583  // times() usually already includes the constant() so would
1584  // have been checked above. Re-test if
1585  // - times() is empty. Sometimes this can happen (e.g. decomposePar
1586  // with collated)
1587  // - times()[0] is not constant
1588  if (!ts.size() || ts[0].name() != time.constant())
1589  {
1590  // Note. This needs to be a hard-coded constant, rather than the
1591  // constant function of the time, because the latter points to
1592  // the case constant directory in parallel cases
1593 
1594  io.instance() = time.constant();
1595  if (exists(pDirs, io))
1596  {
1597  if (debug)
1598  {
1599  Pout<< "masterUncollatedFileOperation::findInstance :"
1600  << " name:" << io.name()
1601  << " local:" << io.local()
1602  << " found at:" << io.instance() << endl;
1603  }
1604  foundInstance = io.instance();
1605  }
1606  }
1607  }
1608 
1609  if (foundInstance.empty())
1610  {
1611  if
1612  (
1613  startIO.readOpt() == IOobject::MUST_READ
1615  )
1616  {
1618  << "Cannot find file \"" << io.name() << "\" in directory "
1619  << io.local() << " in times " << startIO.instance()
1620  << " down to " << time.constant()
1621  << exit(FatalError);
1622  }
1623  else
1624  {
1625  foundInstance = time.constant();
1626  }
1627  }
1628  }
1629 
1630  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1632  io.instance() = foundInstance;
1633  if (debug)
1634  {
1635  Pout<< "masterUncollatedFileOperation::findInstance :"
1636  << " name:" << io.name() << " local:" << io.local()
1637  << " returning instance:" << io.instance() << endl;
1638  }
1639  return io;
1640 }
1641 
1642 
1645 (
1646  const objectRegistry& db,
1647  const fileName& instance,
1648  const fileName& local,
1649  word& newInstance
1650 ) const
1651 {
1652  if (debug)
1653  {
1654  Pout<< "masterUncollatedFileOperation::readObjects :"
1655  << " db:" << db.objectPath()
1656  << " local:" << local << " instance:" << instance << endl;
1657  }
1658 
1659  fileNameList objectNames;
1660  newInstance = word::null;
1661 
1662  // Note: readObjects uses WORLD to make sure order of objects is the
1663  // same everywhere
1664 
1665  if (Pstream::master()) // comm_))
1666  {
1667  // Avoid fileOperation::readObjects from triggering parallel ops
1668  // (through call to filePath which triggers parallel )
1669  bool oldParRun = UPstream::parRun();
1670  UPstream::parRun() = false;
1671 
1672  //- Use non-time searching version
1673  objectNames = fileOperation::readObjects
1674  (
1675  db,
1676  instance,
1677  local,
1678  newInstance
1679  );
1680 
1681  if (newInstance.empty())
1682  {
1683  // Find similar time
1684 
1685  // Copy of Time::findInstancePath. We want to avoid the
1686  // parallel call to findTimes. Alternative is to have
1687  // version of findInstancePath that takes instantList ...
1688  const instantList timeDirs
1689  (
1691  (
1692  db.time(),
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  autoPtr<ISstream> isPtr;
1874  bool isCollated = false;
1875  IOobject headerIO(io);
1876 
1877  // Detect collated format. This could be done on the local communicator
1878  // but we do it on the master node only for now.
1879  if (UPstream::master()) // comm_))
1880  {
1881  if (!fName.empty())
1882  {
1883  // This can happen in lagrangian field reading some processors
1884  // have no file to read from. This will only happen when using
1885  // normal writing since then the fName for the valid processors is
1886  // processorDDD/<instance>/.. . In case of collocated writing
1887  // the fName is already rewritten to processors/.
1888 
1889  isPtr.reset(new IFstream(fName));
1890  isPtr->global() = io.global();
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.close();
1913  io.IOobject::operator=(headerIO);
1914  return isPtr;
1915  }
1916  }
1917 
1918  if (!isCollated)
1919  {
1920  // Close file. Reopened below.
1921  isPtr.clear();
1922  }
1923  }
1924  }
1925 
1926  Pstream::scatter(isCollated); //, Pstream::msgType(), comm_);
1927 
1928  if (isCollated)
1929  {
1930  if (debug)
1931  {
1932  Pout<< "masterUncollatedFileOperation::readStream :"
1933  << " For object : " << io.name()
1934  << " starting collating input from " << fName << endl;
1935  }
1936 
1937 
1938  // Analyse the file path (on (co)master) to see the processors type
1939  fileName path, procDir, local;
1940  label groupStart, groupSize, nProcs;
1941  splitProcessorPath
1942  (
1943  fName,
1944  path,
1945  procDir,
1946  local,
1947  groupStart,
1948  groupSize,
1949  nProcs
1950  );
1951 
1952 
1953  List<char> data;
1954  if (!Pstream::parRun())
1955  {
1956  // Analyse the objectpath to find out the processor we're trying
1957  // to access
1958  label proci = detectProcessorPath(io.objectPath());
1959 
1960  if (proci == -1)
1961  {
1962  FatalIOErrorInFunction(isPtr())
1963  << "Could not detect processor number"
1964  << " from objectPath:" << io.objectPath()
1965  << exit(FatalIOError);
1966  }
1967 
1968  // Analyse the fileName for any processor subset. Note: this
1969  // should really be part of filePath() which should return
1970  // both file and index in file.
1971  if (groupStart != -1 && groupSize > 0)
1972  {
1973  proci = proci-groupStart;
1974  }
1975 
1976  if (debug)
1977  {
1978  Pout<< "masterUncollatedFileOperation::readStream :"
1979  << " For object : " << io.name()
1980  << " starting input from block " << proci
1981  << " of " << isPtr().name() << endl;
1982  }
1983 
1984  return decomposedBlockData::readBlock(proci, isPtr(), io);
1985  }
1986  else
1987  {
1988  // Scatter master header info
1989  string versionString;
1990  string formatString;
1991  if (isPtr.valid())
1992  {
1993  versionString = isPtr().version().str();
1994  OStringStream os;
1995  os << isPtr().format();
1996  formatString = (os.str());
1997  }
1998 
1999  Pstream::scatter(versionString); //, Pstream::msgType(), comm);
2000  Pstream::scatter(formatString); //, Pstream::msgType(), comm);
2001 
2002  // Get size of file
2003  off_t sz = Foam::fileSize(fName);
2004  bool bigSize = sz > off_t(maxMasterFileBufferSize);
2005  Pstream::scatter(bigSize);
2006 
2007  // Are we reading from single-master file ('processors256') or
2008  // from multi-master files ('processors256_0-9')
2009  label readComm = -1;
2010  if (groupStart != -1 && groupSize > 0)
2011  {
2012  readComm = comm_;
2013  if (UPstream::master(comm_) && !isPtr.valid() && !fName.empty())
2014  {
2015  // In multi-master mode also open the file on the other
2016  // masters
2017  isPtr.reset(new IFstream(fName));
2018 
2019  if (isPtr().good())
2020  {
2021  // Read header data (on copy)
2022  IOobject headerIO(io);
2023  headerIO.readHeader(isPtr());
2024  }
2025  }
2026  }
2027  else
2028  {
2029  // Single master so read on world
2030  readComm = Pstream::worldComm;
2031  }
2032 
2033  // Read my data
2035  (
2036  readComm,
2037  fName,
2038  isPtr,
2039  io,
2040  (
2041  bigSize
2044  )
2045  );
2046  }
2047  }
2048  else
2049  {
2050  if (debug)
2051  {
2052  Pout<< "masterUncollatedFileOperation::readStream :"
2053  << " For object : " << io.name()
2054  << " starting separated input from " << fName << endl;
2055  }
2056 
2057  if (io.global())
2058  {
2059  // Use worldComm. Note: should not really need to gather filePaths
2060  // since we enforce sending from master anyway ...
2061  fileNameList filePaths(Pstream::nProcs());
2062  filePaths[Pstream::myProcNo()] = fName;
2063  Pstream::gatherList(filePaths);
2064  boolList procValid(Pstream::nProcs());
2065  procValid[Pstream::myProcNo()] = read;
2066  Pstream::gatherList(procValid);
2067 
2068  return this->read
2069  (
2070  io,
2072  true,
2073  filePaths,
2074  procValid
2075  );
2076  }
2077  else
2078  {
2079  // Use local communicator
2080  fileNameList filePaths(Pstream::nProcs(comm_));
2081  filePaths[Pstream::myProcNo(comm_)] = fName;
2082  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
2083  boolList procValid(Pstream::nProcs(comm_));
2084  procValid[Pstream::myProcNo(comm_)] = read;
2085  Pstream::gatherList(procValid, Pstream::msgType(), comm_);
2086 
2087  // Uniform in local comm
2088  bool uniform = uniformFile(filePaths);
2089 
2090  return this->read
2091  (
2092  io,
2093  comm_,
2094  uniform,
2095  filePaths,
2096  procValid
2097  );
2098  }
2099  }
2100 }
2101 
2102 
2104 (
2105  regIOobject& io,
2106  const bool masterOnly,
2107  const IOstream::streamFormat defaultFormat,
2108  const word& typeName
2109 ) const
2110 {
2111  bool ok = true;
2112 
2113  // Initialise format to the defaultFormat
2114  // but reset to ASCII if defaultFormat and file format are ASCII
2115  IOstream::streamFormat format = defaultFormat;
2116 
2117  if (io.global())
2118  {
2119  if (debug)
2120  {
2121  Pout<< "masterUncollatedFileOperation::read :"
2122  << " Reading global object " << io.name() << endl;
2123  }
2124 
2125  // Now that we have an IOobject path use it to detect & cache
2126  // processor directory naming
2127  (void)lookupProcessorsPath(io.objectPath());
2128 
2129  // Trigger caching of times
2130  (void)findTimes(io.time(), io.time().path(), io.time().constant());
2131 
2132  bool ok = false;
2133  if (Pstream::master()) // comm_))
2134  {
2135  // Do master-only reading always.
2136  bool oldParRun = UPstream::parRun();
2137  UPstream::parRun() = false;
2138 
2139  // Open file and read header
2140  Istream& is = io.readStream(typeName);
2141 
2142  // Set format to ASCII if defaultFormat and file format are ASCII
2143  if (defaultFormat == IOstream::ASCII)
2144  {
2145  format = is.format();
2146  }
2147 
2148  // Read the data from the file
2149  ok = io.readData(is);
2150 
2151  // Close the file
2152  io.close();
2153 
2154  UPstream::parRun() = oldParRun;
2155  }
2156 
2157  Pstream::scatter(ok);
2159  Pstream::scatter(io.note());
2160 
2161  if (defaultFormat == IOstream::ASCII)
2162  {
2163  std::underlying_type_t<IOstream::streamFormat> formatValue(format);
2164  Pstream::scatter(formatValue);
2165  format = IOstream::streamFormat(formatValue);
2166  }
2167 
2168  // scatter operation for regIOobjects
2169 
2170  // Get my communication order
2171  const List<Pstream::commsStruct>& comms =
2172  (
2176  );
2177  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
2178 
2179  // Receive from up
2180  if (myComm.above() != -1)
2181  {
2182  IPstream fromAbove
2183  (
2185  myComm.above(),
2186  0,
2187  Pstream::msgType(),
2189  format,
2191  io.global()
2192  );
2193 
2194  ok = io.readData(fromAbove);
2195  }
2196 
2197  // Send to my downstairs neighbours
2198  forAll(myComm.below(), belowI)
2199  {
2200  OPstream toBelow
2201  (
2203  myComm.below()[belowI],
2204  0,
2205  Pstream::msgType(),
2207  format,
2209  io.global()
2210  );
2211 
2212  bool okWrite = io.writeData(toBelow);
2213  ok = ok && okWrite;
2214  }
2215  }
2216  else
2217  {
2218  if (debug)
2219  {
2220  Pout<< "masterUncollatedFileOperation::read :"
2221  << " Reading local object " << io.name() << endl;
2222  }
2223 
2224  ok = io.readData(io.readStream(typeName));
2225  io.close();
2226  }
2227 
2228  return ok;
2229 }
2230 
2231 
2233 (
2234  const regIOobject& io,
2238  const bool write
2239 ) const
2240 {
2241  fileName filePath(io.objectPath());
2242 
2243  if (debug)
2244  {
2245  Pout<< "masterUncollatedFileOperation::writeObject :"
2246  << " io:" << filePath << " write:" << write << endl;
2247  }
2248 
2249  // Make sure to pick up any new times
2250  setTime(io.time());
2251 
2252  autoPtr<Ostream> osPtr
2253  (
2254  NewOFstream
2255  (
2256  filePath,
2257  fmt,
2258  ver,
2259  cmp,
2260  write
2261  )
2262  );
2263  Ostream& os = osPtr();
2264 
2265  // If any of these fail, return (leave error handling to Ostream class)
2266  if (!os.good())
2267  {
2268  return false;
2269  }
2270 
2271  if (!io.writeHeader(os))
2272  {
2273  return false;
2274  }
2275 
2276  // Write the data to the Ostream
2277  if (!io.writeData(os))
2278  {
2279  return false;
2280  }
2281 
2283 
2284  return true;
2285 }
2286 
2287 
2289 (
2290  const Time& time,
2291  const fileName& directory,
2292  const word& constantName
2293 ) const
2294 {
2295  if (!time.processorCase())
2296  {
2297  return fileOperation::findTimes(time, directory, constantName);
2298  }
2299  else
2300  {
2302  if (iter != times_.end())
2303  {
2304  if (debug)
2305  {
2306  Pout<< "masterUncollatedFileOperation::findTimes :"
2307  << " Found " << iter()->size() << " cached times" << endl;
2308  }
2309  return *iter();
2310  }
2311  else
2312  {
2313  instantList times;
2314  if (Pstream::master()) // comm_))
2315  {
2316  // Do master-only reading always.
2317  bool oldParRun = UPstream::parRun();
2318  UPstream::parRun() = false;
2319  times = fileOperation::findTimes(time, directory, constantName);
2320  UPstream::parRun() = oldParRun;
2321  }
2322  Pstream::scatter(times); //, Pstream::msgType(), comm_);
2323 
2324  // Note: do we also cache if no times have been found since it might
2325  // indicate a directory that is being filled later on ...
2326 
2327  instantList* tPtr = new instantList(move(times));
2328 
2329  times_.insert(directory, tPtr);
2330 
2331  if (debug)
2332  {
2333  Pout<< "masterUncollatedFileOperation::findTimes :"
2334  << " Caching times:" << *tPtr << nl
2335  << " for directory:" << directory << endl;
2336  }
2337  return *tPtr;
2338  }
2339  }
2340 }
2341 
2342 
2344 (
2345  const Time& tm
2346 ) const
2347 {
2348  if (tm.subCycling())
2349  {
2350  return;
2351  }
2352 
2353  HashPtrTable<instantList>::const_iterator iter = times_.find(tm.path());
2354  if (iter != times_.end())
2355  {
2356  instantList& times = *iter();
2357 
2358  const instant timeNow(tm.value(), tm.name());
2359 
2360  if (times.size() > 0 && times[0].name() == tm.constant())
2361  {
2362  // Exclude constant
2363  SubList<instant> realTimes(times, times.size()-1, 1);
2364  if
2365  (
2367  (
2368  SubList<instant>(times, times.size()-1, 1),
2369  timeNow
2370  )
2371  == -1
2372  )
2373  {
2374  if (debug)
2375  {
2376  Pout<< "masterUncollatedFileOperation::setTime :"
2377  << " Caching time " << tm.name()
2378  << " for case:" << tm.path() << endl;
2379  }
2380 
2381  times.append(timeNow);
2382  SubList<instant> realTimes(times, times.size()-1, 1);
2383  Foam::stableSort(realTimes);
2384  }
2385  }
2386  else
2387  {
2388  if (findSortedIndex(times, timeNow) == -1)
2389  {
2390  if (debug)
2391  {
2392  Pout<< "masterUncollatedFileOperation::setTime :"
2393  << " Caching time " << tm.name()
2394  << " for case:" << tm.path() << endl;
2395  }
2396 
2397  times.append(timeNow);
2398  Foam::stableSort(times);
2399  }
2400  }
2401  }
2403 }
2404 
2405 
2408 (
2409  const fileName& filePath,
2411  IOstream::versionNumber version
2412 ) const
2413 {
2414  if (Pstream::parRun())
2415  {
2416  // Insert logic of filePath. We assume that if a file is absolute
2417  // on the master it is absolute also on the slaves etc.
2418 
2420  filePaths[Pstream::myProcNo(Pstream::worldComm)] = filePath;
2422 
2423  PstreamBuffers pBufs
2424  (
2426  Pstream::msgType(),
2428  );
2429 
2431  {
2432  const bool uniform = uniformFile(filePaths);
2433 
2434  if (uniform)
2435  {
2436  if (debug)
2437  {
2438  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2439  << " Opening global file " << filePath << endl;
2440  }
2441 
2443  for
2444  (
2445  label proci = 1;
2447  proci++
2448  )
2449  {
2450  procs[proci-1] = proci;
2451  }
2452 
2453  readAndSend(filePath, procs, pBufs);
2454  }
2455  else
2456  {
2457  for
2458  (
2459  label proci = 1;
2461  proci++
2462  )
2463  {
2464  readAndSend(filePaths[proci], labelList(1, proci), pBufs);
2465  }
2466  }
2467  }
2468 
2469 
2470  labelList recvSizes;
2471  pBufs.finishedSends(recvSizes);
2472 
2474  {
2475  // Read myself
2476  return autoPtr<ISstream>
2477  (
2478  new IFstream(filePaths[Pstream::masterNo()], format, version)
2479  );
2480  }
2481  else
2482  {
2483  if (debug)
2484  {
2485  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2486  << " Reading " << filePath
2487  << " from processor " << Pstream::masterNo() << endl;
2488  }
2489 
2490  UIPstream is(Pstream::masterNo(), pBufs);
2491  string buf(recvSizes[Pstream::masterNo()], '\0');
2492  is.read(&buf[0], recvSizes[Pstream::masterNo()]);
2493 
2494  if (debug)
2495  {
2496  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2497  << " Done reading " << buf.size() << " bytes" << endl;
2498  }
2499 
2500  // Note: IPstream is not an IStream so use a IStringStream to
2501  // convert the buffer. Note that we construct with a string
2502  // so it holds a copy of the buffer.
2503  return autoPtr<ISstream>
2504  (
2505  new IStringStream(filePath, buf, IOstream::BINARY)
2506  );
2507  }
2508  }
2509  else
2510  {
2511  // Read myself
2512  return autoPtr<ISstream>(new IFstream(filePath, format, version));
2513  }
2514 }
2515 
2516 
2519 (
2520  const fileName& filePath,
2522  IOstream::versionNumber version,
2523  IOstream::compressionType compression,
2524  const bool write
2525 ) const
2526 {
2527  return autoPtr<Ostream>
2528  (
2529  new masterOFstream
2530  (
2531  filePath,
2532  format,
2533  version,
2534  compression,
2535  false, // append
2536  write
2537  )
2538  );
2539 }
2540 
2541 
2543 {
2545  times_.clear();
2546 }
2547 
2548 
2550 (
2551  const fileName& fName
2552 ) const
2553 {
2554  label watchFd;
2555  if (Pstream::master()) // comm_))
2556  {
2557  watchFd = monitor().addWatch(fName);
2558  }
2559  Pstream::scatter(watchFd); //, Pstream::msgType(), comm_);
2560  return watchFd;
2561 }
2562 
2563 
2565 (
2566  const label watchIndex
2567 ) const
2568 {
2569  bool ok;
2570  if (Pstream::master()) // comm_))
2571  {
2572  ok = monitor().removeWatch(watchIndex);
2573  }
2574  Pstream::scatter(ok); //, Pstream::msgType(), comm_);
2575  return ok;
2576 }
2577 
2578 
2580 (
2581  const labelList& watchIndices,
2582  const fileName& fName
2583 ) const
2584 {
2585  label index = -1;
2586 
2587  if (Pstream::master()) // comm_))
2588  {
2589  forAll(watchIndices, i)
2590  {
2591  if (monitor().getFile(watchIndices[i]) == fName)
2592  {
2593  index = i;
2594  break;
2595  }
2596  }
2597  }
2598  Pstream::scatter(index); //, Pstream::msgType(), comm_);
2599  return index;
2600 }
2601 
2602 
2604 (
2605  regIOobject& rio,
2606  const fileNameList& files
2607 ) const
2608 {
2609  const labelList& watchIndices = rio.watchIndices();
2610 
2611  DynamicList<label> newWatchIndices;
2612  labelHashSet removedWatches(watchIndices);
2613 
2614  forAll(files, i)
2615  {
2616  const fileName& f = files[i];
2617  label index = findWatch(watchIndices, f);
2618 
2619  if (index == -1)
2620  {
2621  newWatchIndices.append(addWatch(f));
2622  }
2623  else
2624  {
2625  // Existing watch
2626  newWatchIndices.append(watchIndices[index]);
2627  removedWatches.erase(index);
2628  }
2629  }
2630 
2631  // Remove any unused watches
2632  forAllConstIter(labelHashSet, removedWatches, iter)
2633  {
2634  removeWatch(watchIndices[iter.key()]);
2635  }
2636 
2637  rio.watchIndices() = newWatchIndices;
2638 }
2639 
2640 
2642 (
2643  const label watchIndex
2644 ) const
2645 {
2646  fileName fName;
2647  if (Pstream::master()) // comm_))
2648  {
2649  fName = monitor().getFile(watchIndex);
2650  }
2651  Pstream::scatter(fName); //, Pstream::msgType(), comm_);
2652  return fName;
2653 }
2654 
2655 
2657 (
2658  const bool masterOnly,
2659  const bool syncPar
2660 ) const
2661 {
2662  if (Pstream::master()) // comm_))
2663  {
2664  monitor().updateStates(true, false);
2665  }
2666 }
2667 
2668 
2671 (
2672  const label watchFd
2673 ) const
2674 {
2675  unsigned int state = fileMonitor::UNMODIFIED;
2676  if (Pstream::master()) // comm_))
2677  {
2678  state = monitor().getState(watchFd);
2679  }
2680  Pstream::scatter(state); //, Pstream::msgType(), comm_);
2681  return fileMonitor::fileState(state);
2682 }
2683 
2684 
2686 (
2687  const label watchFd
2688 ) const
2689 {
2690  if (Pstream::master()) // comm_))
2691  {
2692  monitor().setUnmodified(watchFd);
2693  }
2694 }
2695 
2696 
2697 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:445
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:476
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:339
const Time & time() const
Return time.
Definition: IOobject.C:315
@ 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:352
const objectRegistry & db() const
Return the local objectRegistry.
Definition: IOobject.C:309
string & note()
Return non-constant access to the optional note.
Definition: IOobject.H:325
readOption readOpt() const
Definition: IOobject.H:357
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:313
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:223
bool readHeader(Istream &)
Read header.
const word & name() const
Return name.
Definition: IOobject.H:307
const fileName & rootPath() const
Definition: IOobject.C:333
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:383
Version number type.
Definition: IOstream.H:97
static const versionNumber currentVersion
Current version number.
Definition: IOstream.H:203
streamFormat format() const
Return current stream format.
Definition: IOstream.H:377
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:333
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:640
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:432
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:80
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:311
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
static const NamedEnum< pathType, 12 > pathTypeNames_
Definition: fileOperation.H:79
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
virtual void setTime(const Time &) const
Callback for time change.
virtual instantList findTimes(const Time &, 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 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 fileName filePath(const bool globalFile, const IOobject &) const
Search for an object. globalFile : also check undecomposed case.
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 Time &, 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.
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(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::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:269
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:258
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
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
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:267
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)