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