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