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-2020 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 {
42  defineTypeNameAndDebug(masterUncollatedFileOperation, 0);
44  (
45  fileOperation,
46  masterUncollatedFileOperation,
47  word
48  );
49 
51  (
52  Foam::debug::floatOptimisationSwitch("maxMasterFileBufferSize", 1e9)
53  );
54 
55  // Mark as not needing threaded mpi
57  (
58  fileOperationInitialise,
59  masterUncollatedFileOperationInitialise,
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 identity(n);
78  }
79  else
80  {
81  DynamicList<label> subRanks(n);
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  return move(subRanks);
116  }
117 }
118 
119 
122 (
123  const instantList& timeDirs,
124  const instant& t
125 )
126 {
127  // Note:
128  // - times will include constant (with value 0) as first element.
129  // For backwards compatibility make sure to find 0 in preference
130  // to constant.
131  // - list is sorted so could use binary search
132 
133  forAllReverse(timeDirs, i)
134  {
135  if (t.equal(timeDirs[i].value()))
136  {
137  return timeDirs[i].name();
138  }
139  }
140 
141  return word::null;
142 }
143 
144 
147 (
148  const bool checkGlobal,
149  const bool isFile,
150  const IOobject& io,
151  pathType& searchType,
152  word& procsDir,
153  word& newInstancePath
154 ) const
155 {
156  procsDir = word::null;
157  newInstancePath = word::null;
158 
159  if (io.instance().isAbsolute())
160  {
161  fileName objPath = io.instance()/io.name();
162 
163  if (isFileOrDir(isFile, objPath))
164  {
165  searchType = fileOperation::ABSOLUTE;
166  return objPath;
167  }
168  else
169  {
170  searchType = fileOperation::NOTFOUND;
171  return fileName::null;
172  }
173  }
174  else
175  {
176  // 1. Check the writing fileName
177  fileName writePath(objectPath(io, io.headerClassName()));
178 
179  if (isFileOrDir(isFile, writePath))
180  {
181  searchType = fileOperation::WRITEOBJECT;
182  return writePath;
183  }
184 
185  // 2. Check processors/
186  if (io.time().processorCase())
187  {
188  tmpNrc<dirIndexList> pDirs(lookupProcessorsPath(io.objectPath()));
189  forAll(pDirs(), i)
190  {
191  const fileName& pDir = pDirs()[i].first();
192  fileName objPath =
193  processorsPath(io, io.instance(), pDir)
194  /io.name();
195  if (objPath != writePath && isFileOrDir(isFile, objPath))
196  {
197  searchType = pDirs()[i].second().first();
198  procsDir = pDir;
199  return objPath;
200  }
201  }
202  }
203  {
204  // 3. Check local
205  fileName localPath = io.objectPath();
206 
207  if
208  (
209  localPath != writePath
210  && isFileOrDir(isFile, localPath)
211  )
212  {
213  searchType = fileOperation::OBJECT;
214  return localPath;
215  }
216  }
217 
218 
219 
220  // Any global checks
221  if
222  (
223  checkGlobal
224  && io.time().processorCase()
225  && (
226  io.instance() == io.time().system()
227  || io.instance() == io.time().constant()
228  )
229  )
230  {
231  fileName parentPath =
232  io.rootPath()/io.time().globalCaseName()
233  /io.instance()/io.db().dbDir()/io.local()/io.name();
234 
235  if (isFileOrDir(isFile, parentPath))
236  {
237  searchType = fileOperation::PARENTOBJECT;
238  return parentPath;
239  }
240  }
241 
242  // Check for approximately same time. E.g. if time = 1e-2 and
243  // directory is 0.01 (due to different time formats)
245  (
246  times_.find
247  (
248  io.time().path()
249  )
250  );
251  if (pathFnd != times_.end())
252  {
253  newInstancePath = findInstancePath
254  (
255  *pathFnd(),
256  instant(io.instance())
257  );
258 
259  if (newInstancePath.size() && newInstancePath != io.instance())
260  {
261  // 1. Try processors equivalent
263  (
264  lookupProcessorsPath(io.objectPath())
265  );
266  forAll(pDirs(), i)
267  {
268  const fileName& pDir = pDirs()[i].first();
269 
270  fileName fName
271  (
272  processorsPath(io, newInstancePath, pDir)
273  /io.name()
274  );
275  if (isFileOrDir(isFile, fName))
276  {
277  switch (pDirs()[i].second().first())
278  {
280  {
281  searchType =
283  }
284  break;
286  {
287  searchType = fileOperation::PROCBASEINSTANCE;
288  }
289  break;
291  {
292  searchType = fileOperation::PROCINSTANCE;
293  }
294  break;
295  default:
296  break;
297  }
298  procsDir = pDir;
299  return fName;
300  }
301  }
302 
303 
304  // 2. Check local
305  fileName fName
306  (
307  io.rootPath()/io.caseName()
308  /newInstancePath/io.db().dbDir()/io.local()/io.name()
309  );
310  if (isFileOrDir(isFile, fName))
311  {
312  searchType = fileOperation::FINDINSTANCE;
313  return fName;
314  }
315  }
316  }
317 
318  searchType = fileOperation::NOTFOUND;
319  return fileName::null;
320  }
321 }
322 
323 
326 (
327  const IOobject& io,
328  const pathType& searchType,
329  const word& procDir,
330  const word& instancePath
331 ) const
332 {
333  // Replacement for IOobject::objectPath()
334 
335  switch (searchType)
336  {
338  {
339  return io.instance()/io.name();
340  }
341  break;
342 
344  {
345  return io.path()/io.name();
346  }
347  break;
348 
350  {
351  return objectPath(io, io.headerClassName());
352  }
353  break;
354 
356  {
357  // Uncollated type, e.g. processor1
358  const word procName
359  (
360  "processor"
362  );
363  return
364  processorsPath
365  (
366  io,
367  io.instance(),
368  (
370  ? procName
371  : procDir
372  )
373  )
374  /io.name();
375  }
376  break;
377 
379  {
380  // Collated, e.g. processors4
381  return
382  processorsPath(io, io.instance(), procDir)
383  /io.name();
384  }
385  break;
386 
388  {
389  // Processors directory locally provided by the fileHandler itself
390  return
391  processorsPath(io, io.instance(), processorsDir(io))
392  /io.name();
393  }
394  break;
395 
397  {
398  return
399  io.rootPath()/io.time().globalCaseName()
400  /io.instance()/io.db().dbDir()/io.local()/io.name();
401  }
402  break;
403 
405  {
406  return
407  io.rootPath()/io.caseName()
408  /instancePath/io.db().dbDir()/io.local()/io.name();
409  }
410  break;
411 
413  {
414  // Uncollated type, e.g. processor1
415  const word procName
416  (
417  "processor"
419  );
420  return
421  processorsPath
422  (
423  io,
424  instancePath,
425  (
427  ? procName
428  : procDir
429  )
430  )
431  /io.name();
432  }
433  break;
434 
436  {
437  // Collated, e.g. processors4
438  return
439  processorsPath(io, instancePath, procDir)
440  /io.name();
441  }
442  break;
443 
445  {
446  // Processors directory locally provided by the fileHandler itself
447  return
448  processorsPath(io, instancePath, processorsDir(io))
449  /io.name();
450  }
451  break;
452 
454  {
455  return fileName::null;
456  }
457  break;
458 
459  default:
460  {
462  return fileName::null;
463  }
464  }
465 }
466 
467 
469 (
470  const fileNameList& filePaths
471 )
472 {
473  const fileName& object0 = filePaths[0];
474 
475  for (label i = 1; i < filePaths.size(); i++)
476  {
477  if (filePaths[i] != object0)
478  {
479  return false;
480  }
481  }
482  return true;
483 }
484 
485 
487 (
488  const fileName& filePath,
489  const labelUList& procs,
490  PstreamBuffers& pBufs
491 )
492 {
493  if (debug)
494  {
495  Pout<< FUNCTION_NAME << ": Opening " << filePath << endl;
496  }
497 
498  IFstream is(filePath, IOstream::streamFormat::BINARY);
499 
500  if (!is.good())
501  {
502  FatalIOErrorInFunction(filePath) << "Cannot open file " << filePath
503  << exit(FatalIOError);
504  }
505 
506  if (isA<igzstream>(is.stdStream()))
507  {
508  if (debug)
509  {
510  Pout<< FUNCTION_NAME << ": Reading compressed" << endl;
511  }
512 
513  std::ostringstream stringStr;
514  stringStr << is.stdStream().rdbuf();
515  string buf(stringStr.str());
516 
517  forAll(procs, i)
518  {
519  UOPstream os(procs[i], pBufs);
520  os.write(&buf[0], buf.size());
521  }
522  }
523  else
524  {
525  off_t count(Foam::fileSize(filePath));
526 
527  if (debug)
528  {
529  Pout<< FUNCTION_NAME << " : Reading " << count << " bytes " << endl;
530  }
531 
532  List<char> buf(static_cast<label>(count));
533  is.stdStream().read(buf.begin(), count);
534 
535  forAll(procs, i)
536  {
537  UOPstream os(procs[i], pBufs);
538  os.write(buf.begin(), count);
539  }
540  }
541 }
542 
543 
546 (
547  IOobject& io,
548  const label comm,
549  const bool uniform, // on comms master only
550  const fileNameList& filePaths, // on comms master only
551  const boolList& read // on comms master only
552 )
553 {
554  autoPtr<ISstream> isPtr;
555 
556  // const bool uniform = uniformFile(filePaths);
557 
558  PstreamBuffers pBufs
559  (
562  comm
563  );
564 
565  if (Pstream::master(comm))
566  {
567  if (uniform)
568  {
569  if (read[0])
570  {
571  if (filePaths[0].empty())
572  {
573  FatalIOErrorInFunction(filePaths[0])
574  << "cannot find file " << io.objectPath()
575  << exit(FatalIOError);
576  }
577 
578  DynamicList<label> validProcs(Pstream::nProcs(comm));
579  for
580  (
581  label proci = 0;
582  proci < Pstream::nProcs(comm);
583  proci++
584  )
585  {
586  if (read[proci])
587  {
588  validProcs.append(proci);
589  }
590  }
591 
592  // Read on master and send to all processors (including
593  // master for simplicity)
594  if (debug)
595  {
596  Pout<< "masterUncollatedFileOperation::readStream :"
597  << " For uniform file " << filePaths[0]
598  << " sending to " << validProcs
599  << " in comm:" << comm << endl;
600  }
601  readAndSend(filePaths[0], validProcs, pBufs);
602  }
603  }
604  else
605  {
606  if (read[0])
607  {
608  if (filePaths[0].empty())
609  {
610  FatalIOErrorInFunction(filePaths[0])
611  << "cannot find file " << io.objectPath()
612  << exit(FatalIOError);
613  }
614 
615  autoPtr<IFstream> ifsPtr(new IFstream(filePaths[0]));
616 
617  // Read header
618  if (!io.readHeader(ifsPtr()))
619  {
620  FatalIOErrorInFunction(ifsPtr())
621  << "problem while reading header for object "
622  << io.name() << exit(FatalIOError);
623  }
624 
625  // Open master (steal from ifsPtr)
626  isPtr.reset(ifsPtr.ptr());
627  }
628 
629  // Read slave files
630  for
631  (
632  label proci = 1;
633  proci < Pstream::nProcs(comm);
634  proci++
635  )
636  {
637  if (debug)
638  {
639  Pout<< "masterUncollatedFileOperation::readStream :"
640  << " For processor " << proci
641  << " opening " << filePaths[proci] << endl;
642  }
643 
644  const fileName& fPath = filePaths[proci];
645 
646  if (read[proci] && !fPath.empty())
647  {
648  // Note: handle compression ourselves since size cannot
649  // be determined without actually uncompressing
650  readAndSend(fPath, labelList(1, proci), pBufs);
651  }
652  }
653  }
654  }
655 
656  labelList recvSizes;
657  pBufs.finishedSends(recvSizes);
658 
659  // isPtr will be valid on master and will be the unbuffered
660  // IFstream. Else the information is in the PstreamBuffers (and
661  // the special case of a uniform file)
662 
663  if (read[Pstream::myProcNo(comm)])
664  {
665  // This processor needs to return something
666 
667  if (!isPtr.valid())
668  {
669  UIPstream is(Pstream::masterNo(), pBufs);
670  string buf(recvSizes[Pstream::masterNo()], '\0');
671  if (recvSizes[Pstream::masterNo()] > 0)
672  {
673  is.read(&buf[0], recvSizes[Pstream::masterNo()]);
674  }
675 
676  if (debug)
677  {
678  Pout<< "masterUncollatedFileOperation::readStream :"
679  << " Done reading " << buf.size() << " bytes" << endl;
680  }
681  const fileName& fName = filePaths[Pstream::myProcNo(comm)];
682  isPtr.reset(new IStringStream(fName, buf, IOstream::BINARY));
683 
684  if (!io.readHeader(isPtr()))
685  {
686  FatalIOErrorInFunction(isPtr())
687  << "problem while reading header for object "
688  << io.name() << exit(FatalIOError);
689  }
690  }
691  }
692  else
693  {
694  isPtr.reset(new dummyISstream());
695  }
696 
697  return isPtr;
698 }
699 
700 
701 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
702 
705 (
706  const bool verbose
707 )
708 :
710  (
712  (
714  subRanks(Pstream::nProcs())
715  )
716  ),
717  myComm_(comm_)
718 {
719  if (verbose)
720  {
721  InfoHeader
722  << "I/O : " << typeName
723  << " (maxMasterFileBufferSize " << maxMasterFileBufferSize << ')'
724  << endl;
725  }
726 
728  {
729  if (verbose)
730  {
732  << "Resetting fileModificationChecking to timeStamp" << endl;
733  }
735  }
736  else if
737  (
740  )
741  {
742  if (verbose)
743  {
745  << "Resetting fileModificationChecking to inotify"
746  << endl;
747  }
749  }
750 }
751 
752 
755 (
756  const label comm,
757  const bool verbose
758 )
759 :
760  fileOperation(comm),
761  myComm_(-1)
762 {
763  if (verbose)
764  {
765  InfoHeader
766  << "I/O : " << typeName
767  << " (maxMasterFileBufferSize " << maxMasterFileBufferSize << ')'
768  << endl;
769  }
770 
772  {
773  if (verbose)
774  {
776  << "Resetting fileModificationChecking to timeStamp" << endl;
777  }
779  }
780  else if
781  (
784  )
785  {
786  if (verbose)
787  {
789  << "Resetting fileModificationChecking to inotify"
790  << endl;
791  }
793  }
794 }
795 
796 
799 :
800  unthreadedInitialise(argc, argv)
801 {
802  // Filter out any of my arguments
803  const string s("-ioRanks");
804 
805  int index = -1;
806  for (int i=1; i<argc-1; i++)
807  {
808  if (argv[i] == s)
809  {
810  index = i;
811  setEnv("FOAM_IORANKS", argv[i+1], true);
812  break;
813  }
814  }
815 
816  if (index != -1)
817  {
818  for (int i=index+2; i<argc; i++)
819  {
820  argv[i-2] = argv[i];
821  }
822  argc -= 2;
823  }
824 }
825 
826 
827 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
828 
831 {
832  if (myComm_ != -1)
833  {
835  }
836 }
837 
838 
839 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
840 
842 (
843  const fileName& dir,
844  mode_t mode
845 ) const
846 {
847  return masterOp<mode_t, mkDirOp>
848  (
849  dir,
850  mkDirOp(mode),
852  comm_
853  );
854 }
855 
856 
858 (
859  const fileName& fName,
860  mode_t mode
861 ) const
862 {
863  return masterOp<mode_t, chModOp>
864  (
865  fName,
866  chModOp(mode),
868  comm_
869  );
870 }
871 
872 
874 (
875  const fileName& fName,
876  const bool checkVariants,
877  const bool followLink
878 ) const
879 {
880  return masterOp<mode_t, modeOp>
881  (
882  fName,
883  modeOp(checkVariants, followLink),
885  comm_
886  );
887 }
888 
889 
891 (
892  const fileName& fName,
893  const bool checkVariants,
894  const bool followLink
895 ) const
896 {
897  return fileType
898  (
899  masterOp<label, typeOp>
900  (
901  fName,
902  typeOp(checkVariants, followLink),
904  comm_
905  )
906  );
907 }
908 
909 
911 (
912  const fileName& fName,
913  const bool checkVariants,
914  const bool followLink
915 ) const
916 {
917  return masterOp<bool, existsOp>
918  (
919  fName,
920  existsOp(checkVariants, followLink),
922  comm_
923  );
924 }
925 
926 
928 (
929  const fileName& fName,
930  const bool followLink
931 ) const
932 {
933  return masterOp<bool, isDirOp>
934  (
935  fName,
936  isDirOp(followLink),
938  comm_
939  );
940 }
941 
942 
944 (
945  const fileName& fName,
946  const bool checkVariants,
947  const bool followLink
948 ) const
949 {
950  return masterOp<bool, isFileOp>
951  (
952  fName,
953  isFileOp(checkVariants, followLink),
955  comm_
956  );
957 }
958 
959 
961 (
962  const fileName& fName,
963  const bool checkVariants,
964  const bool followLink
965 ) const
966 {
967  return masterOp<off_t, fileSizeOp>
968  (
969  fName,
970  fileSizeOp(checkVariants, followLink),
972  comm_
973  );
974 }
975 
976 
978 (
979  const fileName& fName,
980  const bool checkVariants,
981  const bool followLink
982 ) const
983 {
984  return masterOp<time_t, lastModifiedOp>
985  (
986  fName,
987  lastModifiedOp(checkVariants, followLink),
989  comm_
990  );
991 }
992 
993 
995 (
996  const fileName& fName,
997  const bool checkVariants,
998  const bool followLink
999 ) const
1000 {
1001  return masterOp<double, lastModifiedHROp>
1002  (
1003  fName,
1004  lastModifiedHROp(checkVariants, followLink),
1005  Pstream::msgType(),
1006  comm_
1007  );
1008 }
1009 
1010 
1013  const fileName& fName,
1014  const std::string& ext
1015 ) const
1016 {
1017  return masterOp<bool, mvBakOp>
1018  (
1019  fName,
1020  mvBakOp(ext),
1021  Pstream::msgType(),
1022  comm_
1023  );
1024 }
1025 
1026 
1029  const fileName& fName
1030 ) const
1031 {
1032  return masterOp<bool, rmOp>
1033  (
1034  fName,
1035  rmOp(),
1036  Pstream::msgType(),
1037  comm_
1038  );
1039 }
1040 
1041 
1044  const fileName& dir
1045 ) const
1046 {
1047  return masterOp<bool, rmDirOp>
1048  (
1049  dir,
1050  rmDirOp(),
1051  Pstream::msgType(),
1052  comm_
1053  );
1054 }
1055 
1056 
1059  const fileName& dir,
1060  const fileType type,
1061  const bool filtergz,
1062  const bool followLink
1063 ) const
1064 {
1065  return masterOp<fileNameList, readDirOp>
1066  (
1067  dir,
1068  readDirOp(type, filtergz, followLink),
1069  Pstream::msgType(),
1070  comm_
1071  );
1072 }
1073 
1074 
1077  const fileName& src,
1078  const fileName& dst,
1079  const bool followLink
1080 ) const
1081 {
1082  return masterOp<bool, cpOp>
1083  (
1084  src,
1085  dst,
1086  cpOp(followLink),
1087  Pstream::msgType(),
1088  comm_
1089  );
1090 }
1091 
1092 
1095  const fileName& src,
1096  const fileName& dst
1097 ) const
1098 {
1099  return masterOp<bool, lnOp>
1100  (
1101  src,
1102  dst,
1103  lnOp(),
1104  Pstream::msgType(),
1105  comm_
1106  );
1107 }
1108 
1109 
1112  const fileName& src,
1113  const fileName& dst,
1114  const bool followLink
1115 ) const
1116 {
1117  return masterOp<bool, mvOp>
1118  (
1119  src,
1120  dst,
1121  mvOp(followLink),
1122  Pstream::msgType(),
1123  comm_
1124  );
1125 }
1126 
1127 
1130  const bool checkGlobal,
1131  const IOobject& io,
1132  const word& typeName
1133 ) const
1134 {
1135  if (debug)
1136  {
1137  Pout<< "masterUncollatedFileOperation::filePath :"
1138  << " objectPath:" << io.objectPath()
1139  << " checkGlobal:" << checkGlobal << endl;
1140  }
1141 
1142  // Now that we have an IOobject path use it to detect & cache
1143  // processor directory naming
1144  (void)lookupProcessorsPath(io.objectPath());
1145 
1146  // Trigger caching of times
1147  (void)findTimes(io.time().path(), io.time().constant());
1148 
1149 
1150  // Determine master filePath and scatter
1151 
1152  fileName objPath;
1153  pathType searchType = NOTFOUND;
1154  word procsDir;
1155  word newInstancePath;
1156 
1157  if (Pstream::master(comm_))
1158  {
1159  // All masters search locally. Note that global objects might
1160  // fail (except on master). This gets handled later on (in PARENTOBJECT)
1161  objPath = filePathInfo
1162  (
1163  checkGlobal,
1164  true,
1165  io,
1166  searchType,
1167  procsDir,
1168  newInstancePath
1169  );
1170 
1171  if (debug)
1172  {
1173  Pout<< "masterUncollatedFileOperation::filePath :"
1174  << " master objPath:" << objPath
1175  << " searchType:" << fileOperation::pathTypeNames_[searchType]
1176  << " procsDir:" << procsDir << " instance:" << newInstancePath
1177  << endl;
1178  }
1179 
1180  }
1181 
1182  // Scatter the information about where the master found the object
1183  // Note: use the worldComm to make sure all processors decide
1184  // the same type. Only procsDir is allowed to differ; searchType
1185  // and instance have to be same
1186  {
1187  label masterType(searchType);
1188  Pstream::scatter(masterType);
1189  searchType = pathType(masterType);
1190  }
1191  Pstream::scatter(newInstancePath);
1192 
1193  if
1194  (
1195  checkGlobal
1196  || searchType == fileOperation::PARENTOBJECT
1197  || searchType == fileOperation::PROCBASEOBJECT
1198  || searchType == fileOperation::PROCBASEINSTANCE
1199  || io.local() == "uniform"
1200  )
1201  {
1202  // Distribute master path. This makes sure it is seen as uniform
1203  // and only gets read from the master.
1204  Pstream::scatter(objPath);
1205  Pstream::scatter(procsDir);
1206  }
1207  else
1208  {
1209  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1210 
1211  // Use the master type to determine if additional information is
1212  // needed to construct the local equivalent
1213  switch (searchType)
1214  {
1218  {
1219  // Already handled above
1220  }
1221  break;
1222 
1230  {
1231  // Construct equivalent local path
1232  objPath = localObjectPath
1233  (
1234  io,
1235  searchType,
1236  procsDir,
1237  newInstancePath
1238  );
1239  }
1240  break;
1241 
1242  case fileOperation::OBJECT:
1244  {
1245  // Retest all processors separately since some processors might
1246  // have the file and some not (e.g. lagrangian data)
1247 
1248  objPath = masterOp<fileName, fileOrNullOp>
1249  (
1250  io.objectPath(),
1251  fileOrNullOp(true),
1252  Pstream::msgType(),
1253  comm_
1254  );
1255  }
1256  break;
1257  }
1258  }
1259 
1260  if (debug)
1261  {
1262  Pout<< "masterUncollatedFileOperation::filePath :"
1263  << " Returning from file searching:" << endl
1264  << " objectPath:" << io.objectPath() << endl
1265  << " filePath :" << objPath << endl << endl;
1266  }
1267  return objPath;
1268 }
1269 
1270 
1273  const bool checkGlobal,
1274  const IOobject& io
1275 ) const
1276 {
1277  if (debug)
1278  {
1279  Pout<< "masterUncollatedFileOperation::dirPath :"
1280  << " objectPath:" << io.objectPath()
1281  << " checkGlobal:" << checkGlobal << endl;
1282  }
1283 
1284  // Now that we have an IOobject path use it to detect & cache
1285  // processor directory naming
1286  (void)lookupProcessorsPath(io.objectPath());
1287 
1288  // Determine master dirPath and scatter
1289 
1290  fileName objPath;
1291  pathType searchType = NOTFOUND;
1292  word procsDir;
1293  word newInstancePath;
1294 
1295  if (Pstream::master(comm_))
1296  {
1297  objPath = filePathInfo
1298  (
1299  checkGlobal,
1300  false,
1301  io,
1302  searchType,
1303  procsDir,
1304  newInstancePath
1305  );
1306  }
1307 
1308  {
1309  label masterType(searchType);
1310  Pstream::scatter(masterType); //, Pstream::msgType(), comm_);
1311  searchType = pathType(masterType);
1312  }
1313  Pstream::scatter(newInstancePath); //, Pstream::msgType(), comm_);
1314 
1315  if
1316  (
1317  checkGlobal
1318  || searchType == fileOperation::PARENTOBJECT
1319  || searchType == fileOperation::PROCBASEOBJECT
1320  || searchType == fileOperation::PROCBASEINSTANCE
1321  || io.local() == "uniform"
1322  )
1323  {
1324  // Distribute master path. This makes sure it is seen as uniform
1325  // and only gets read from the master.
1326  Pstream::scatter(objPath);
1327  Pstream::scatter(procsDir);
1328  }
1329  else
1330  {
1331  Pstream::scatter(procsDir, Pstream::msgType(), comm_);
1332 
1333  // Use the master type to determine if additional information is
1334  // needed to construct the local equivalent
1335  switch (searchType)
1336  {
1340  {
1341  // Already handled above
1342  }
1343  break;
1344 
1352  {
1353  // Construct equivalent local path
1354  objPath = localObjectPath
1355  (
1356  io,
1357  searchType,
1358  procsDir,
1359  newInstancePath
1360  );
1361  }
1362  break;
1363 
1364  case fileOperation::OBJECT:
1366  {
1367  // Retest all processors separately since some processors might
1368  // have the file and some not (e.g. lagrangian data)
1369  objPath = masterOp<fileName, fileOrNullOp>
1370  (
1371  io.objectPath(),
1372  fileOrNullOp(false),
1373  Pstream::msgType(),
1374  comm_
1375  );
1376  }
1377  break;
1378  }
1379  }
1380 
1381  if (debug)
1382  {
1383  Pout<< "masterUncollatedFileOperation::dirPath :"
1384  << " Returning from file searching:" << endl
1385  << " objectPath:" << io.objectPath() << endl
1386  << " filePath :" << objPath << endl << endl;
1387  }
1388  return objPath;
1389 }
1390 
1391 
1394  const dirIndexList& pDirs,
1395  IOobject& io
1396 ) const
1397 {
1398  // Cut-down version of filePathInfo that does not look for
1399  // different instance or parent directory
1400 
1401  const bool isFile = !io.name().empty();
1402 
1403  // Generate output filename for object
1404  const fileName writePath(objectPath(io, word::null));
1405 
1406  // 1. Test writing name for either directory or a (valid) file
1407  if (isFileOrDir(isFile, writePath))
1408  {
1409  return true;
1410  }
1411 
1412  // 2. Check processors/
1413  if (io.time().processorCase())
1414  {
1415  forAll(pDirs, i)
1416  {
1417  const fileName& pDir = pDirs[i].first();
1418  fileName procPath =
1419  processorsPath(io, io.instance(), pDir)
1420  /io.name();
1421  if (procPath != writePath && isFileOrDir(isFile, procPath))
1422  {
1423  return true;
1424  }
1425  }
1426  }
1427 
1428  // 3. Check local
1429  fileName localPath = io.objectPath();
1430 
1431  if (localPath != writePath && isFileOrDir(isFile, localPath))
1432  {
1433  return true;
1434  }
1435 
1436  return false;
1437 }
1438 
1439 
1443  const IOobject& startIO,
1444  const scalar startValue,
1445  const word& stopInstance
1446 ) const
1447 {
1448  if (debug)
1449  {
1450  Pout<< "masterUncollatedFileOperation::findInstance :"
1451  << " Starting searching for name:" << startIO.name()
1452  << " local:" << startIO.local()
1453  << " from instance:" << startIO.instance()
1454  << endl;
1455  }
1456 
1457 
1458  const Time& time = startIO.time();
1459 
1460  IOobject io(startIO);
1461 
1462  // Note: - if name is empty, just check the directory itself
1463  // - check both for isFile and headerOk since the latter does a
1464  // filePath so searches for the file.
1465  // - check for an object with local file scope (so no looking up in
1466  // parent directory in case of parallel)
1467 
1468 
1469  tmpNrc<dirIndexList> pDirs(lookupProcessorsPath(io.objectPath()));
1470 
1471  word foundInstance;
1472 
1473  // if (Pstream::master(comm_))
1475  {
1476  if (exists(pDirs, io))
1477  {
1478  foundInstance = io.instance();
1479  }
1480  }
1481 
1482  // Do parallel early exit to avoid calling time.times()
1483  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1485  if (!foundInstance.empty())
1486  {
1487  io.instance() = foundInstance;
1488  if (debug)
1489  {
1490  Pout<< "masterUncollatedFileOperation::findInstance :"
1491  << " for name:" << io.name() << " local:" << io.local()
1492  << " found starting instance:" << io.instance() << endl;
1493  }
1494  return io;
1495  }
1496 
1497 
1498  // Search back through the time directories to find the time
1499  // closest to and lower than current time
1500 
1501  instantList ts = time.times();
1502  // if (Pstream::master(comm_))
1504  {
1505  label instanceI;
1506 
1507  for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
1508  {
1509  if (ts[instanceI].value() <= startValue)
1510  {
1511  break;
1512  }
1513  }
1514 
1515  // continue searching from here
1516  for (; instanceI >= 0; --instanceI)
1517  {
1518  // Shortcut: if actual directory is the timeName we've
1519  // already tested it
1520  if (ts[instanceI].name() == time.timeName())
1521  {
1522  continue;
1523  }
1524 
1525  io.instance() = ts[instanceI].name();
1526  if (exists(pDirs, io))
1527  {
1528  foundInstance = io.instance();
1529  if (debug)
1530  {
1531  Pout<< "masterUncollatedFileOperation::findInstance :"
1532  << " for name:" << io.name() << " local:" << io.local()
1533  << " found at:" << io.instance()
1534  << endl;
1535  }
1536  break;
1537  }
1538 
1539  // Check if hit minimum instance
1540  if (ts[instanceI].name() == stopInstance)
1541  {
1542  if
1543  (
1544  startIO.readOpt() == IOobject::MUST_READ
1546  )
1547  {
1548  if (io.name().empty())
1549  {
1551  << "Cannot find directory "
1552  << io.local() << " in times " << time.timeName()
1553  << " down to " << stopInstance
1554  << exit(FatalError);
1555  }
1556  else
1557  {
1559  << "Cannot find file \"" << io.name()
1560  << "\" in directory " << io.local()
1561  << " in times " << time.timeName()
1562  << " down to " << stopInstance
1563  << exit(FatalError);
1564  }
1565  }
1566  foundInstance = io.instance();
1567  if (debug)
1568  {
1569  Pout<< "masterUncollatedFileOperation::findInstance :"
1570  << " name:" << io.name() << " local:" << io.local()
1571  << " found at stopinstance:" << io.instance() << endl;
1572  }
1573  break;
1574  }
1575  }
1576 
1577 
1578  if (foundInstance.empty())
1579  {
1580  // times() usually already includes the constant() so would
1581  // have been checked above. Re-test if
1582  // - times() is empty. Sometimes this can happen (e.g. decomposePar
1583  // with collated)
1584  // - times()[0] is not constant
1585  if (!ts.size() || ts[0].name() != time.constant())
1586  {
1587  // Note. This needs to be a hard-coded constant, rather than the
1588  // constant function of the time, because the latter points to
1589  // the case constant directory in parallel cases
1590 
1591  io.instance() = time.constant();
1592  if (exists(pDirs, io))
1593  {
1594  if (debug)
1595  {
1596  Pout<< "masterUncollatedFileOperation::findInstance :"
1597  << " name:" << io.name()
1598  << " local:" << io.local()
1599  << " found at:" << io.instance() << endl;
1600  }
1601  foundInstance = io.instance();
1602  }
1603  }
1604  }
1605 
1606  if (foundInstance.empty())
1607  {
1608  if
1609  (
1610  startIO.readOpt() == IOobject::MUST_READ
1612  )
1613  {
1615  << "Cannot find file \"" << io.name() << "\" in directory "
1616  << io.local() << " in times " << startIO.instance()
1617  << " down to " << time.constant()
1618  << exit(FatalError);
1619  }
1620  else
1621  {
1622  foundInstance = time.constant();
1623  }
1624  }
1625  }
1626 
1627  // Pstream::scatter(foundInstance, Pstream::msgType(), comm_);
1629  io.instance() = foundInstance;
1630  if (debug)
1631  {
1632  Pout<< "masterUncollatedFileOperation::findInstance :"
1633  << " name:" << io.name() << " local:" << io.local()
1634  << " returning instance:" << io.instance() << endl;
1635  }
1636  return io;
1637 }
1638 
1639 
1643  const objectRegistry& db,
1644  const fileName& instance,
1645  const fileName& local,
1646  word& newInstance
1647 ) const
1648 {
1649  if (debug)
1650  {
1651  Pout<< "masterUncollatedFileOperation::readObjects :"
1652  << " db:" << db.objectPath()
1653  << " local:" << local << " instance:" << instance << endl;
1654  }
1655 
1656  fileNameList objectNames;
1657  newInstance = word::null;
1658 
1659  // Note: readObjects uses WORLD to make sure order of objects is the
1660  // same everywhere
1661 
1662  if (Pstream::master()) // comm_))
1663  {
1664  // Avoid fileOperation::readObjects from triggering parallel ops
1665  // (through call to filePath which triggers parallel )
1666  bool oldParRun = UPstream::parRun();
1667  UPstream::parRun() = false;
1668 
1669  //- Use non-time searching version
1670  objectNames = fileOperation::readObjects
1671  (
1672  db,
1673  instance,
1674  local,
1675  newInstance
1676  );
1677 
1678  if (newInstance.empty())
1679  {
1680  // Find similar time
1681 
1682  // Copy of Time::findInstancePath. We want to avoid the
1683  // parallel call to findTimes. Alternative is to have
1684  // version of findInstancePath that takes instantList ...
1685  const instantList timeDirs
1686  (
1688  (
1689  db.time().path(),
1690  db.time().constant()
1691  )
1692  );
1693 
1694  const instant t(instance);
1695  forAllReverse(timeDirs, i)
1696  {
1697  if (t.equal(timeDirs[i].value()))
1698  {
1699  objectNames = fileOperation::readObjects
1700  (
1701  db,
1702  timeDirs[i].name(), // newly found time
1703  local,
1704  newInstance
1705  );
1706  break;
1707  }
1708  }
1709  }
1710 
1711  UPstream::parRun() = oldParRun;
1712  }
1713 
1714  Pstream::scatter(newInstance); //, Pstream::msgType(), comm_);
1715  Pstream::scatter(objectNames); //, Pstream::msgType(), comm_);
1716 
1717  if (debug)
1718  {
1719  Pout<< "masterUncollatedFileOperation::readObjects :"
1720  << " newInstance:" << newInstance
1721  << " objectNames:" << objectNames << endl;
1722  }
1723 
1724  return objectNames;
1725 }
1726 
1727 
1730  IOobject& io,
1731  const fileName& fName,
1732  const word& typeName
1733 ) const
1734 {
1735  bool ok = false;
1736 
1737  if (debug)
1738  {
1739  Pout<< "masterUncollatedFileOperation::readHeader :" << endl
1740  << " objectPath:" << io.objectPath() << endl
1741  << " fName :" << fName << endl;
1742  }
1743 
1744  // Get filePaths on world master
1746  filePaths[Pstream::myProcNo(Pstream::worldComm)] = fName;
1748  bool uniform = uniformFile(filePaths);
1750 
1751  if (uniform)
1752  {
1754  {
1755  if (!fName.empty())
1756  {
1757  IFstream is(fName);
1758 
1759  if (is.good())
1760  {
1761  ok = io.readHeader(is);
1762  if (io.headerClassName() == decomposedBlockData::typeName)
1763  {
1764  // Read the header inside the container (master data)
1766  }
1767  }
1768  }
1769  }
1772  (
1773  io.headerClassName(),
1774  Pstream::msgType(),
1776  );
1778  }
1779  else
1780  {
1782  {
1783  // Re-gather file paths on local master
1784  filePaths.setSize(Pstream::nProcs(comm_));
1785  filePaths[Pstream::myProcNo(comm_)] = fName;
1786  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
1787  }
1788 
1789  boolList result(Pstream::nProcs(comm_), false);
1790  wordList headerClassName(Pstream::nProcs(comm_));
1791  stringList note(Pstream::nProcs(comm_));
1792  if (Pstream::master(comm_))
1793  {
1794  forAll(filePaths, proci)
1795  {
1796  if (!filePaths[proci].empty())
1797  {
1798  if (proci > 0 && filePaths[proci] == filePaths[proci-1])
1799  {
1800  result[proci] = result[proci-1];
1801  headerClassName[proci] = headerClassName[proci-1];
1802  note[proci] = note[proci-1];
1803  }
1804  else
1805  {
1806  IFstream is(filePaths[proci]);
1807 
1808  if (is.good())
1809  {
1810  result[proci] = io.readHeader(is);
1811  if
1812  (
1813  io.headerClassName()
1814  == decomposedBlockData::typeName
1815  )
1816  {
1817  // Read the header inside the container (master
1818  // data)
1819  result[proci] = decomposedBlockData::
1821  (
1822  io,
1823  is
1824  );
1825  }
1826  headerClassName[proci] = io.headerClassName();
1827  note[proci] = io.note();
1828  }
1829  }
1830  }
1831  }
1832  }
1833  ok = scatterList(result, Pstream::msgType(), comm_);
1834  io.headerClassName() = scatterList
1835  (
1836  headerClassName,
1837  Pstream::msgType(),
1838  comm_
1839  );
1840  io.note() = scatterList(note, Pstream::msgType(), comm_);
1841  }
1842 
1843  if (debug)
1844  {
1845  Pout<< "masterUncollatedFileOperation::readHeader :" << " ok:" << ok
1846  << " class:" << io.headerClassName() << endl;
1847  }
1848  return ok;
1849 }
1850 
1851 
1855  regIOobject& io,
1856  const fileName& fName,
1857  const word& typeName,
1858  const bool read
1859 ) const
1860 {
1861  if (debug)
1862  {
1863  Pout<< "masterUncollatedFileOperation::readStream :"
1864  << " object : " << io.name()
1865  << " global : " << io.global()
1866  << " fName : " << fName << " read:" << read << endl;
1867  }
1868 
1869 
1870  autoPtr<ISstream> isPtr;
1871  bool isCollated = false;
1872  IOobject headerIO(io);
1873 
1874  // Detect collated format. This could be done on the local communicator
1875  // but we do it on the master node only for now.
1876  if (UPstream::master()) // comm_))
1877  {
1878  if (!fName.empty())
1879  {
1880  // This can happen in lagrangian field reading some processors
1881  // have no file to read from. This will only happen when using
1882  // normal writing since then the fName for the valid processors is
1883  // processorDDD/<instance>/.. . In case of collocated writing
1884  // the fName is already rewritten to processors/.
1885 
1886  isPtr.reset(new IFstream(fName));
1887 
1888  if (isPtr().good())
1889  {
1890  // Read header data (on copy)
1891  headerIO.readHeader(isPtr());
1892 
1893  if (headerIO.headerClassName() == decomposedBlockData::typeName)
1894  {
1895  isCollated = true;
1896  }
1897  else if (!Pstream::parRun())
1898  {
1899  // Short circuit: non-collated format. No parallel bits.
1900  // Copy header and return.
1901  if (debug)
1902  {
1903  Pout<< "masterUncollatedFileOperation::readStream :"
1904  << " For object : " << io.name()
1905  << " doing straight IFstream input from "
1906  << fName << endl;
1907  }
1908  io = headerIO;
1909  return isPtr;
1910  }
1911  }
1912 
1913  if (!isCollated)
1914  {
1915  // Close file. Reopened below.
1916  isPtr.clear();
1917  }
1918  }
1919  }
1920 
1921  Pstream::scatter(isCollated); //, Pstream::msgType(), comm_);
1922 
1923  if (isCollated)
1924  {
1925  if (debug)
1926  {
1927  Pout<< "masterUncollatedFileOperation::readStream :"
1928  << " For object : " << io.name()
1929  << " starting collating input from " << fName << endl;
1930  }
1931 
1932 
1933  // Analyse the file path (on (co)master) to see the processors type
1934  fileName path, procDir, local;
1935  label groupStart, groupSize, nProcs;
1936  splitProcessorPath
1937  (
1938  fName,
1939  path,
1940  procDir,
1941  local,
1942  groupStart,
1943  groupSize,
1944  nProcs
1945  );
1946 
1947 
1948  List<char> data;
1949  if (!Pstream::parRun())
1950  {
1951  // Analyse the objectpath to find out the processor we're trying
1952  // to access
1953  label proci = detectProcessorPath(io.objectPath());
1954 
1955  if (proci == -1)
1956  {
1957  FatalIOErrorInFunction(isPtr())
1958  << "Could not detect processor number"
1959  << " from objectPath:" << io.objectPath()
1960  << exit(FatalIOError);
1961  }
1962 
1963  // Analyse the fileName for any processor subset. Note: this
1964  // should really be part of filePath() which should return
1965  // both file and index in file.
1966  if (groupStart != -1 && groupSize > 0)
1967  {
1968  proci = proci-groupStart;
1969  }
1970 
1971  if (debug)
1972  {
1973  Pout<< "masterUncollatedFileOperation::readStream :"
1974  << " For object : " << io.name()
1975  << " starting input from block " << proci
1976  << " of " << isPtr().name() << endl;
1977  }
1978 
1979  return decomposedBlockData::readBlock(proci, isPtr(), io);
1980  }
1981  else
1982  {
1983  // Scatter master header info
1984  string versionString;
1985  string formatString;
1986  if (isPtr.valid())
1987  {
1988  versionString = isPtr().version().str();
1989  OStringStream os;
1990  os << isPtr().format();
1991  formatString = (os.str());
1992  }
1993 
1994  Pstream::scatter(versionString); //, Pstream::msgType(), comm);
1995  Pstream::scatter(formatString); //, Pstream::msgType(), comm);
1996 
1997  // Get size of file
1998  off_t sz = Foam::fileSize(fName);
1999  bool bigSize = sz > off_t(maxMasterFileBufferSize);
2000  Pstream::scatter(bigSize);
2001 
2002  // Are we reading from single-master file ('processors256') or
2003  // from multi-master files ('processors256_0-9')
2004  label readComm = -1;
2005  if (groupStart != -1 && groupSize > 0)
2006  {
2007  readComm = comm_;
2008  if (UPstream::master(comm_) && !isPtr.valid() && !fName.empty())
2009  {
2010  // In multi-master mode also open the file on the other
2011  // masters
2012  isPtr.reset(new IFstream(fName));
2013 
2014  if (isPtr().good())
2015  {
2016  // Read header data (on copy)
2017  IOobject headerIO(io);
2018  headerIO.readHeader(isPtr());
2019  }
2020  }
2021  }
2022  else
2023  {
2024  // Single master so read on world
2025  readComm = Pstream::worldComm;
2026  }
2027 
2028  // Read my data
2030  (
2031  readComm,
2032  fName,
2033  isPtr,
2034  io,
2035  (
2036  bigSize
2039  )
2040  );
2041  }
2042  }
2043  else
2044  {
2045  if (debug)
2046  {
2047  Pout<< "masterUncollatedFileOperation::readStream :"
2048  << " For object : " << io.name()
2049  << " starting separated input from " << fName << endl;
2050  }
2051 
2052  if (io.global())
2053  {
2054  // Use worldComm. Note: should not really need to gather filePaths
2055  // since we enforce sending from master anyway ...
2056  fileNameList filePaths(Pstream::nProcs());
2057  filePaths[Pstream::myProcNo()] = fName;
2058  Pstream::gatherList(filePaths);
2059  boolList procValid(Pstream::nProcs());
2060  procValid[Pstream::myProcNo()] = read;
2061  Pstream::gatherList(procValid);
2062 
2063  return this->read
2064  (
2065  io,
2067  true,
2068  filePaths,
2069  procValid
2070  );
2071  }
2072  else
2073  {
2074  // Use local communicator
2075  fileNameList filePaths(Pstream::nProcs(comm_));
2076  filePaths[Pstream::myProcNo(comm_)] = fName;
2077  Pstream::gatherList(filePaths, Pstream::msgType(), comm_);
2078  boolList procValid(Pstream::nProcs(comm_));
2079  procValid[Pstream::myProcNo(comm_)] = read;
2080  Pstream::gatherList(procValid, Pstream::msgType(), comm_);
2081 
2082  // Uniform in local comm
2083  bool uniform = uniformFile(filePaths);
2084 
2085  return this->read
2086  (
2087  io,
2088  comm_,
2089  uniform,
2090  filePaths,
2091  procValid
2092  );
2093  }
2094  }
2095 }
2096 
2097 
2100  regIOobject& io,
2101  const bool masterOnly,
2102  const IOstream::streamFormat defaultFormat,
2103  const word& typeName
2104 ) const
2105 {
2106  bool ok = true;
2107 
2108  // Initialise format to the defaultFormat
2109  // but reset to ASCII if defaultFormat and file format are ASCII
2110  IOstream::streamFormat format = defaultFormat;
2111 
2112  if (io.global())
2113  {
2114  if (debug)
2115  {
2116  Pout<< "masterUncollatedFileOperation::read :"
2117  << " Reading global object " << io.name() << endl;
2118  }
2119 
2120  // Now that we have an IOobject path use it to detect & cache
2121  // processor directory naming
2122  (void)lookupProcessorsPath(io.objectPath());
2123 
2124  // Trigger caching of times
2125  (void)findTimes(io.time().path(), io.time().constant());
2126 
2127  bool ok = false;
2128  if (Pstream::master()) // comm_))
2129  {
2130  // Do master-only reading always.
2131  bool oldParRun = UPstream::parRun();
2132  UPstream::parRun() = false;
2133 
2134  // Open file and read header
2135  Istream& is = io.readStream(typeName);
2136 
2137  // Set format to ASCII if defaultFormat and file format are ASCII
2138  if (defaultFormat == IOstream::ASCII)
2139  {
2140  format = is.format();
2141  }
2142 
2143  // Read the data from the file
2144  ok = io.readData(is);
2145 
2146  // Close the file
2147  io.close();
2148 
2149  UPstream::parRun() = oldParRun;
2150  }
2151 
2152  Pstream::scatter(ok);
2154  Pstream::scatter(io.note());
2155 
2156  if (defaultFormat == IOstream::ASCII)
2157  {
2158  std::underlying_type_t<IOstream::streamFormat> formatValue(format);
2159  Pstream::scatter(formatValue);
2160  format = IOstream::streamFormat(formatValue);
2161  }
2162 
2163  // scatter operation for regIOobjects
2164 
2165  // Get my communication order
2166  const List<Pstream::commsStruct>& comms =
2167  (
2171  );
2172  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
2173 
2174  // Receive from up
2175  if (myComm.above() != -1)
2176  {
2177  IPstream fromAbove
2178  (
2180  myComm.above(),
2181  0,
2182  Pstream::msgType(),
2184  format
2185  );
2186  ok = io.readData(fromAbove);
2187  }
2188 
2189  // Send to my downstairs neighbours
2190  forAll(myComm.below(), belowI)
2191  {
2192  OPstream toBelow
2193  (
2195  myComm.below()[belowI],
2196  0,
2197  Pstream::msgType(),
2199  format
2200  );
2201  bool okWrite = io.writeData(toBelow);
2202  ok = ok && okWrite;
2203  }
2204  }
2205  else
2206  {
2207  if (debug)
2208  {
2209  Pout<< "masterUncollatedFileOperation::read :"
2210  << " Reading local object " << io.name() << endl;
2211  }
2212 
2213  ok = io.readData(io.readStream(typeName));
2214  io.close();
2215  }
2216 
2217  return ok;
2218 }
2219 
2220 
2223  const regIOobject& io,
2227  const bool write
2228 ) const
2229 {
2230  fileName filePath(io.objectPath());
2231 
2232  if (debug)
2233  {
2234  Pout<< "masterUncollatedFileOperation::writeObject :"
2235  << " io:" << filePath << " write:" << write << endl;
2236  }
2237 
2238  // Make sure to pick up any new times
2239  setTime(io.time());
2240 
2241  autoPtr<Ostream> osPtr
2242  (
2243  NewOFstream
2244  (
2245  filePath,
2246  fmt,
2247  ver,
2248  cmp,
2249  write
2250  )
2251  );
2252  Ostream& os = osPtr();
2253 
2254  // If any of these fail, return (leave error handling to Ostream class)
2255  if (!os.good())
2256  {
2257  return false;
2258  }
2259 
2260  if (!io.writeHeader(os))
2261  {
2262  return false;
2263  }
2264 
2265  // Write the data to the Ostream
2266  if (!io.writeData(os))
2267  {
2268  return false;
2269  }
2270 
2272 
2273  return true;
2274 }
2275 
2276 
2279  const fileName& directory,
2280  const word& constantName
2281 ) const
2282 {
2283  HashPtrTable<instantList>::const_iterator iter = times_.find(directory);
2284  if (iter != times_.end())
2285  {
2286  if (debug)
2287  {
2288  Pout<< "masterUncollatedFileOperation::findTimes :"
2289  << " Found " << iter()->size() << " cached times" << endl;
2290  }
2291  return *iter();
2292  }
2293  else
2294  {
2295  instantList times;
2296  if (Pstream::master()) // comm_))
2297  {
2298  // Do master-only reading always.
2299  bool oldParRun = UPstream::parRun();
2300  UPstream::parRun() = false;
2301  times = fileOperation::findTimes(directory, constantName);
2302  UPstream::parRun() = oldParRun;
2303  }
2304  Pstream::scatter(times); //, Pstream::msgType(), comm_);
2305 
2306  // Note: do we also cache if no times have been found since it might
2307  // indicate a directory that is being filled later on ...
2308 
2309  instantList* tPtr = new instantList(move(times));
2310 
2311  times_.insert(directory, tPtr);
2312 
2313  if (debug)
2314  {
2315  Pout<< "masterUncollatedFileOperation::findTimes :"
2316  << " Caching times:" << *tPtr << nl
2317  << " for directory:" << directory << endl;
2318  }
2319  return *tPtr;
2320  }
2321 }
2322 
2323 
2326  const Time& tm
2327 ) const
2328 {
2329  if (tm.subCycling())
2330  {
2331  return;
2332  }
2333 
2334  HashPtrTable<instantList>::const_iterator iter = times_.find(tm.path());
2335  if (iter != times_.end())
2336  {
2337  instantList& times = *iter();
2338 
2339  const instant timeNow(tm.value(), tm.timeName());
2340 
2341  if (times.size() > 0 && times[0].name() == tm.constant())
2342  {
2343  // Exclude constant
2344  SubList<instant> realTimes(times, times.size()-1, 1);
2345  if
2346  (
2348  (
2349  SubList<instant>(times, times.size()-1, 1),
2350  timeNow
2351  )
2352  == -1
2353  )
2354  {
2355  if (debug)
2356  {
2357  Pout<< "masterUncollatedFileOperation::setTime :"
2358  << " Caching time " << tm.timeName()
2359  << " for case:" << tm.path() << endl;
2360  }
2361 
2362  times.append(timeNow);
2363  SubList<instant> realTimes(times, times.size()-1, 1);
2364  Foam::stableSort(realTimes);
2365  }
2366  }
2367  else
2368  {
2369  if (findSortedIndex(times, timeNow) == -1)
2370  {
2371  if (debug)
2372  {
2373  Pout<< "masterUncollatedFileOperation::setTime :"
2374  << " Caching time " << tm.timeName()
2375  << " for case:" << tm.path() << endl;
2376  }
2377 
2378  times.append(timeNow);
2379  Foam::stableSort(times);
2380  }
2381  }
2382  }
2384 }
2385 
2386 
2390  const fileName& filePath,
2391  IOstream::streamFormat format,
2392  IOstream::versionNumber version
2393 ) const
2394 {
2395  if (Pstream::parRun())
2396  {
2397  // Insert logic of filePath. We assume that if a file is absolute
2398  // on the master it is absolute also on the slaves etc.
2399 
2401  filePaths[Pstream::myProcNo(Pstream::worldComm)] = filePath;
2403 
2404  PstreamBuffers pBufs
2405  (
2407  Pstream::msgType(),
2409  );
2410 
2412  {
2413  const bool uniform = uniformFile(filePaths);
2414 
2415  if (uniform)
2416  {
2417  if (debug)
2418  {
2419  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2420  << " Opening global file " << filePath << endl;
2421  }
2422 
2424  for
2425  (
2426  label proci = 1;
2428  proci++
2429  )
2430  {
2431  procs[proci-1] = proci;
2432  }
2433 
2434  readAndSend(filePath, procs, pBufs);
2435  }
2436  else
2437  {
2438  for
2439  (
2440  label proci = 1;
2442  proci++
2443  )
2444  {
2445  readAndSend(filePaths[proci], labelList(1, proci), pBufs);
2446  }
2447  }
2448  }
2449 
2450 
2451  labelList recvSizes;
2452  pBufs.finishedSends(recvSizes);
2453 
2455  {
2456  // Read myself
2457  return autoPtr<ISstream>
2458  (
2459  new IFstream(filePaths[Pstream::masterNo()], format, version)
2460  );
2461  }
2462  else
2463  {
2464  if (debug)
2465  {
2466  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2467  << " Reading " << filePath
2468  << " from processor " << Pstream::masterNo() << endl;
2469  }
2470 
2471  UIPstream is(Pstream::masterNo(), pBufs);
2472  string buf(recvSizes[Pstream::masterNo()], '\0');
2473  is.read(&buf[0], recvSizes[Pstream::masterNo()]);
2474 
2475  if (debug)
2476  {
2477  Pout<< "masterUncollatedFileOperation::NewIFstream :"
2478  << " Done reading " << buf.size() << " bytes" << endl;
2479  }
2480 
2481  // Note: IPstream is not an IStream so use a IStringStream to
2482  // convert the buffer. Note that we construct with a string
2483  // so it holds a copy of the buffer.
2484  return autoPtr<ISstream>
2485  (
2486  new IStringStream(filePath, buf, IOstream::BINARY)
2487  );
2488  }
2489  }
2490  else
2491  {
2492  // Read myself
2493  return autoPtr<ISstream>(new IFstream(filePath, format, version));
2494  }
2495 }
2496 
2497 
2501  const fileName& filePath,
2502  IOstream::streamFormat format,
2503  IOstream::versionNumber version,
2504  IOstream::compressionType compression,
2505  const bool write
2506 ) const
2507 {
2508  return autoPtr<Ostream>
2509  (
2510  new masterOFstream
2511  (
2512  filePath,
2513  format,
2514  version,
2515  compression,
2516  false, // append
2517  write
2518  )
2519  );
2520 }
2521 
2522 
2524 {
2526  times_.clear();
2527 }
2528 
2529 
2532  const fileName& fName
2533 ) const
2534 {
2535  label watchFd;
2536  if (Pstream::master()) // comm_))
2537  {
2538  watchFd = monitor().addWatch(fName);
2539  }
2540  Pstream::scatter(watchFd); //, Pstream::msgType(), comm_);
2541  return watchFd;
2542 }
2543 
2544 
2547  const label watchIndex
2548 ) const
2549 {
2550  bool ok;
2551  if (Pstream::master()) // comm_))
2552  {
2553  ok = monitor().removeWatch(watchIndex);
2554  }
2555  Pstream::scatter(ok); //, Pstream::msgType(), comm_);
2556  return ok;
2557 }
2558 
2559 
2562  const labelList& watchIndices,
2563  const fileName& fName
2564 ) const
2565 {
2566  label index = -1;
2567 
2568  if (Pstream::master()) // comm_))
2569  {
2570  forAll(watchIndices, i)
2571  {
2572  if (monitor().getFile(watchIndices[i]) == fName)
2573  {
2574  index = i;
2575  break;
2576  }
2577  }
2578  }
2579  Pstream::scatter(index); //, Pstream::msgType(), comm_);
2580  return index;
2581 }
2582 
2583 
2586  regIOobject& rio,
2587  const fileNameList& files
2588 ) const
2589 {
2590  const labelList& watchIndices = rio.watchIndices();
2591 
2592  DynamicList<label> newWatchIndices;
2593  labelHashSet removedWatches(watchIndices);
2594 
2595  forAll(files, i)
2596  {
2597  const fileName& f = files[i];
2598  label index = findWatch(watchIndices, f);
2599 
2600  if (index == -1)
2601  {
2602  newWatchIndices.append(addWatch(f));
2603  }
2604  else
2605  {
2606  // Existing watch
2607  newWatchIndices.append(watchIndices[index]);
2608  removedWatches.erase(index);
2609  }
2610  }
2611 
2612  // Remove any unused watches
2613  forAllConstIter(labelHashSet, removedWatches, iter)
2614  {
2615  removeWatch(watchIndices[iter.key()]);
2616  }
2617 
2618  rio.watchIndices() = newWatchIndices;
2619 }
2620 
2621 
2624  const label watchIndex
2625 ) const
2626 {
2627  fileName fName;
2628  if (Pstream::master()) // comm_))
2629  {
2630  fName = monitor().getFile(watchIndex);
2631  }
2632  Pstream::scatter(fName); //, Pstream::msgType(), comm_);
2633  return fName;
2634 }
2635 
2636 
2639  const bool masterOnly,
2640  const bool syncPar
2641 ) const
2642 {
2643  if (Pstream::master()) // comm_))
2644  {
2645  monitor().updateStates(true, false);
2646  }
2647 }
2648 
2649 
2653  const label watchFd
2654 ) const
2655 {
2656  unsigned int state = fileMonitor::UNMODIFIED;
2657  if (Pstream::master()) // comm_))
2658  {
2659  state = monitor().getState(watchFd);
2660  }
2661  Pstream::scatter(state); //, Pstream::msgType(), comm_);
2662  return fileMonitor::fileState(state);
2663 }
2664 
2665 
2668  const label watchFd
2669 ) const
2670 {
2671  if (Pstream::master()) // comm_))
2672  {
2673  monitor().setUnmodified(watchFd);
2674  }
2675 }
2676 
2677 
2678 // ************************************************************************* //
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:89
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:303
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:278
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:323
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.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
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:422
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:251
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
label count(const ListType &l, typename ListType::const_reference x)
Count the number of occurrences of a value in a list.
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:636
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:330
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:348
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
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:321
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:73
A class for handling words, derived from string.
Definition: word.H:59
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.
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:178
virtual void addWatches(regIOobject &, const fileNameList &) const
Helper: add watches for list of regIOobjects.
const fileName & local() const
Definition: IOobject.H:400
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:123
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
streamFormat format() const
Return current stream format.
Definition: IOstream.H:374
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:113
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:54
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:101
static const char nl
Definition: Ostream.H:260
#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:219
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:342
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:390
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:123
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:335
const Time & time() const
Return time.
Definition: IOobject.C:318
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:652
string str() const
Return the string.
virtual bool global() const
Is object same for all processors.
Definition: regIOobject.C:418
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:52
bool writeHeader(Ostream &) const
Write header.
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 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:248
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:312
virtual void setTime(const Time &) const
Callback for time change.
void stableSort(UList< T > &)
Definition: UList.C:129
readOption readOpt() const
Definition: IOobject.H:353
virtual fileName dirPath(const bool checkGlobal, const IOobject &) const
Search for a directory. checkGlobal : also check undecomposed.
fileName path() const
Return path.
Definition: TimePaths.H:139
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:370
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:309
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:324
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:419
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:314
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