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