decomposedBlockData.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-2022 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 
26 #include "decomposedBlockData.H"
27 #include "OPstream.H"
28 #include "IPstream.H"
29 #include "PstreamBuffers.H"
30 #include "OFstream.H"
31 #include "IFstream.H"
32 #include "IStringStream.H"
33 #include "dictionary.H"
34 #include "objectRegistry.H"
35 #include "SubList.H"
36 #include "labelPair.H"
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
44 }
45 
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
47 
49 (
50  const label comm,
51  const IOobject& io,
52  const UPstream::commsTypes commsType
53 )
54 :
55  regIOobject(io),
56  commsType_(commsType),
57  comm_(comm)
58 {
59  // Temporary warning
61  {
63  << "decomposedBlockData " << name()
64  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
65  " but decomposedBlockData does not support automatic rereading."
66  << endl;
67  }
68  if
69  (
70  (
73  )
75  )
76  {
77  read();
78  }
79 }
80 
81 
83 (
84  const label comm,
85  const IOobject& io,
86  const UList<char>& list,
87  const UPstream::commsTypes commsType
88 )
89 :
90  regIOobject(io),
91  commsType_(commsType),
92  comm_(comm)
93 {
94  // Temporary warning
96  {
98  << "decomposedBlockData " << name()
99  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
100  " but decomposedBlockData does not support automatic rereading."
101  << endl;
102  }
103 
104  if
105  (
106  (
109  )
110  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
111  )
112  {
113  read();
114  }
115  else
116  {
117  List<char>::operator=(list);
118  }
119 }
120 
121 
123 (
124  const label comm,
125  const IOobject& io,
126  List<char>&& list,
127  const UPstream::commsTypes commsType
128 )
129 :
130  regIOobject(io),
131  List<char>(move(list)),
132  commsType_(commsType),
133  comm_(comm)
134 {
135  // Temporary warning
137  {
139  << "decomposedBlockData " << name()
140  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
141  " but decomposedBlockData does not support automatic rereading."
142  << endl;
143  }
144 
145  if
146  (
147  (
150  )
151  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
152  )
153  {
154  read();
155  }
156 }
157 
158 
159 // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
160 
162 {}
163 
164 
165 // * * * * * * * * * * * * * * * Members Functions * * * * * * * * * * * * * //
166 
168 {
169  if (debug)
170  {
171  Pout<< "decomposedBlockData::readMasterHeader:"
172  << " stream:" << is.name() << endl;
173  }
174 
175  // Master-only reading of header
176  is.fatalCheck("read(Istream&)");
177 
178  List<char> data(is);
179  is.fatalCheck("read(Istream&) : reading entry");
180  string buf(data.begin(), data.size());
181  IStringStream str(is.name(), buf);
182 
183  return io.readHeader(str);
184 }
185 
186 
188 (
189  Ostream& os,
190  const IOstream::versionNumber version,
192  const word& type,
193  const string& note,
194  const fileName& location,
195  const word& name
196 )
197 {
198  IOobject::writeBanner(os) << IOobject::foamFile << "\n{\n";
199 
200  if (version != IOstream::currentVersion)
201  {
202  os << " version " << version << ";\n";
203  }
204 
205  os << " format " << format << ";\n"
206  << " class " << type << ";\n";
207 
208  if (note.size())
209  {
210  os << " note " << note << ";\n";
211  }
212 
213  if (location.size())
214  {
215  os << " location " << location << ";\n";
216  }
217 
218  os << " object " << name << ";\n"
219  << "}" << nl;
220 
221  IOobject::writeDivider(os) << nl;
222 }
223 
224 
226 (
227  const label blocki,
228  Istream& is,
229  IOobject& headerIO
230 )
231 {
232  if (debug)
233  {
234  Pout<< "decomposedBlockData::readBlock:"
235  << " stream:" << is.name() << " attempt to read block " << blocki
236  << endl;
237  }
238 
239  is.fatalCheck("read(Istream&)");
240 
241  List<char> data;
242  autoPtr<ISstream> realIsPtr;
243 
244  if (blocki == 0)
245  {
246  is >> data;
247  is.fatalCheck("read(Istream&) : reading entry");
248 
249  string buf(data.begin(), data.size());
250  realIsPtr = new IStringStream(is.name(), buf);
251 
252  // Read header
253  if (!headerIO.readHeader(realIsPtr()))
254  {
255  FatalIOErrorInFunction(realIsPtr())
256  << "problem while reading header for object "
257  << is.name() << exit(FatalIOError);
258  }
259  }
260  else
261  {
262  // Read master for header
263  is >> data;
264  is.fatalCheck("read(Istream&) : reading entry");
265 
268  {
269  string buf(data.begin(), data.size());
270  IStringStream headerStream(is.name(), buf);
271 
272  // Read header
273  if (!headerIO.readHeader(headerStream))
274  {
275  FatalIOErrorInFunction(headerStream)
276  << "problem while reading header for object "
277  << is.name() << exit(FatalIOError);
278  }
279  ver = headerStream.version();
280  fmt = headerStream.format();
281  }
282 
283  for (label i = 1; i < blocki+1; i++)
284  {
285  // Read data, override old data
286  is >> data;
287  is.fatalCheck("read(Istream&) : reading entry");
288  }
289  string buf(data.begin(), data.size());
290  realIsPtr = new IStringStream(is.name(), buf);
291 
292  // Apply master stream settings to realIsPtr
293  realIsPtr().format(fmt);
294  realIsPtr().version(ver);
295  }
296  return realIsPtr;
297 }
298 
299 
301 (
302  const label comm,
303  autoPtr<ISstream>& isPtr,
304  List<char>& data,
305  const UPstream::commsTypes commsType
306 )
307 {
308  if (debug)
309  {
310  Pout<< "decomposedBlockData::readBlocks:"
311  << " stream:" << (isPtr.valid() ? isPtr().name() : "invalid")
312  << " commsType:" << Pstream::commsTypeNames[commsType]
313  << " comm:" << comm << endl;
314  }
315 
316  bool ok = false;
317 
318  if (commsType == UPstream::commsTypes::scheduled)
319  {
320  if (UPstream::master(comm))
321  {
322  Istream& is = isPtr();
323  is.fatalCheck("read(Istream&)");
324 
325  // Read master data
326  {
327  is >> data;
328  is.fatalCheck("read(Istream&) : reading entry");
329  }
330 
331  // Read slave data
332  for
333  (
334  label proci = 1;
335  proci < UPstream::nProcs(comm);
336  proci++
337  )
338  {
339  List<char> elems(is);
340  is.fatalCheck("read(Istream&) : reading entry");
341 
342  OPstream os
343  (
345  proci,
346  0,
348  comm
349  );
350  os << elems;
351  }
352 
353  ok = is.good();
354  }
355  else
356  {
357  IPstream is
358  (
361  0,
363  comm
364  );
365  is >> data;
366  }
367  }
368  else
369  {
370  PstreamBuffers pBufs
371  (
374  comm
375  );
376 
377  if (UPstream::master(comm))
378  {
379  Istream& is = isPtr();
380  is.fatalCheck("read(Istream&)");
381 
382  // Read master data
383  {
384  is >> data;
385  is.fatalCheck("read(Istream&) : reading entry");
386  }
387 
388  // Read slave data
389  for
390  (
391  label proci = 1;
392  proci < UPstream::nProcs(comm);
393  proci++
394  )
395  {
396  List<char> elems(is);
397  is.fatalCheck("read(Istream&) : reading entry");
398 
399  UOPstream os(proci, pBufs);
400  os << elems;
401  }
402  }
403 
404  labelList recvSizes;
405  pBufs.finishedSends(recvSizes);
406 
407  if (!UPstream::master(comm))
408  {
409  UIPstream is(UPstream::masterNo(), pBufs);
410  is >> data;
411  }
412  }
413 
414  Pstream::scatter(ok, Pstream::msgType(), comm);
415 
416  return ok;
417 }
418 
419 
421 (
422  const label comm,
423  const fileName& fName,
424  autoPtr<ISstream>& isPtr,
425  IOobject& headerIO,
426  const UPstream::commsTypes commsType
427 )
428 {
429  if (debug)
430  {
431  Pout<< "decomposedBlockData::readBlocks:"
432  << " stream:" << (isPtr.valid() ? isPtr().name() : "invalid")
433  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
434  }
435 
436  bool ok = false;
437 
438  List<char> data;
439  autoPtr<ISstream> realIsPtr;
440 
441  if (commsType == UPstream::commsTypes::scheduled)
442  {
443  if (UPstream::master(comm))
444  {
445  Istream& is = isPtr();
446  is.fatalCheck("read(Istream&)");
447 
448  // Read master data
449  {
450  is >> data;
451  is.fatalCheck("read(Istream&) : reading entry");
452 
453  string buf(data.begin(), data.size());
454  realIsPtr = new IStringStream(fName, buf);
455 
456  // Read header
457  if (!headerIO.readHeader(realIsPtr()))
458  {
459  FatalIOErrorInFunction(realIsPtr())
460  << "problem while reading header for object "
461  << is.name() << exit(FatalIOError);
462  }
463  }
464 
465  // Read slave data
466  for
467  (
468  label proci = 1;
469  proci < UPstream::nProcs(comm);
470  proci++
471  )
472  {
473  is >> data;
474  is.fatalCheck("read(Istream&) : reading entry");
475 
476  OPstream os
477  (
479  proci,
480  0,
482  comm
483  );
484  os << data;
485  }
486 
487  ok = is.good();
488  }
489  else
490  {
491  IPstream is
492  (
495  0,
497  comm
498  );
499  is >> data;
500 
501  string buf(data.begin(), data.size());
502  realIsPtr = new IStringStream(fName, buf);
503  }
504  }
505  else
506  {
507  PstreamBuffers pBufs
508  (
511  comm
512  );
513 
514  if (UPstream::master(comm))
515  {
516  Istream& is = isPtr();
517  is.fatalCheck("read(Istream&)");
518 
519  // Read master data
520  {
521  is >> data;
522  is.fatalCheck("read(Istream&) : reading entry");
523 
524  string buf(data.begin(), data.size());
525  realIsPtr = new IStringStream(fName, buf);
526 
527  // Read header
528  if (!headerIO.readHeader(realIsPtr()))
529  {
530  FatalIOErrorInFunction(realIsPtr())
531  << "problem while reading header for object "
532  << is.name() << exit(FatalIOError);
533  }
534  }
535 
536  // Read slave data
537  for
538  (
539  label proci = 1;
540  proci < UPstream::nProcs(comm);
541  proci++
542  )
543  {
544  List<char> elems(is);
545  is.fatalCheck("read(Istream&) : reading entry");
546 
547  UOPstream os(proci, pBufs);
548  os << elems;
549  }
550 
551  ok = is.good();
552  }
553 
554  labelList recvSizes;
555  pBufs.finishedSends(recvSizes);
556 
557  if (!UPstream::master(comm))
558  {
559  UIPstream is(UPstream::masterNo(), pBufs);
560  is >> data;
561 
562  string buf(data.begin(), data.size());
563  realIsPtr = new IStringStream(fName, buf);
564  }
565  }
566 
567  Pstream::scatter(ok, Pstream::msgType(), comm);
568 
569  // version
570  string versionString(realIsPtr().version().str());
571  Pstream::scatter(versionString, Pstream::msgType(), comm);
572  realIsPtr().version(IStringStream(versionString)());
573 
574  // stream
575  {
576  OStringStream os;
577  os << realIsPtr().format();
578  string formatString(os.str());
579  Pstream::scatter(formatString, Pstream::msgType(), comm);
580  realIsPtr().format(formatString);
581  }
582 
583  word name(headerIO.name());
585  headerIO.rename(name);
587  Pstream::scatter(headerIO.note(), Pstream::msgType(), comm);
588  // Pstream::scatter(headerIO.instance(), Pstream::msgType(), comm);
589  // Pstream::scatter(headerIO.local(), Pstream::msgType(), comm);
590 
591  return realIsPtr;
592 }
593 
594 
596 (
597  const label comm,
598  const label data,
599  labelList& datas
600 )
601 {
602  const label nProcs = UPstream::nProcs(comm);
603  datas.setSize(nProcs);
604 
605  char* data0Ptr = reinterpret_cast<char*>(datas.begin());
606 
607  List<int> recvOffsets;
608  List<int> recvSizes;
609  if (UPstream::master(comm))
610  {
611  recvOffsets.setSize(nProcs);
612  forAll(recvOffsets, proci)
613  {
614  // Note: truncating long int to int since UPstream::gather limited
615  // to ints
616  recvOffsets[proci] =
617  int(reinterpret_cast<char*>(&datas[proci]) - data0Ptr);
618  }
619  recvSizes.setSize(nProcs, sizeof(label));
620  }
621 
623  (
624  reinterpret_cast<const char*>(&data),
625  sizeof(label),
626  data0Ptr,
627  recvSizes,
628  recvOffsets,
629  comm
630  );
631 }
632 
633 
635 (
636  const label comm,
637  const UList<char>& data,
638  const labelUList& recvSizes,
639 
640  const label startProc,
641  const label nProcs,
642 
643  List<int>& sliceOffsets,
644  List<char>& recvData
645 )
646 {
647  // Calculate master data
648  List<int> sliceSizes;
649  if (UPstream::master(comm))
650  {
651  const label numProcs = UPstream::nProcs(comm);
652 
653  sliceSizes.setSize(numProcs, 0);
654  sliceOffsets.setSize(numProcs+1, 0);
655 
656  int totalSize = 0;
657  label proci = startProc;
658  for (label i = 0; i < nProcs; i++)
659  {
660  sliceSizes[proci] = int(recvSizes[proci]);
661  sliceOffsets[proci] = totalSize;
662  totalSize += sliceSizes[proci];
663  proci++;
664  }
665  sliceOffsets[proci] = totalSize;
666  recvData.setSize(totalSize);
667  }
668 
669  int nSend = 0;
670  if
671  (
672  !UPstream::master(comm)
673  && (UPstream::myProcNo(comm) >= startProc)
674  && (UPstream::myProcNo(comm) < startProc+nProcs)
675  )
676  {
677  // Note: UPstream::gather limited to int
678  nSend = int(data.byteSize());
679  }
680 
682  (
683  data.begin(),
684  nSend,
685 
686  recvData.begin(),
687  sliceSizes,
688  sliceOffsets,
689  comm
690  );
691 }
692 
693 
695 (
696  const label comm,
697  const off_t maxBufferSize,
698  const labelUList& recvSizes,
699  const label startProci
700 )
701 {
702  const label nProcs = UPstream::nProcs(comm);
703 
704  label nSendProcs = -1;
705  if (UPstream::master(comm))
706  {
707  off_t totalSize = recvSizes[startProci];
708  label proci = startProci+1;
709  while (proci < nProcs && (totalSize+recvSizes[proci] < maxBufferSize))
710  {
711  totalSize += recvSizes[proci];
712  proci++;
713  }
714 
715  nSendProcs = proci-startProci;
716  }
717 
718  // Scatter nSendProcs
719  label n;
721  (
722  reinterpret_cast<const char*>(&nSendProcs),
723  List<int>(nProcs, sizeof(nSendProcs)),
724  List<int>(nProcs, 0),
725  reinterpret_cast<char*>(&n),
726  sizeof(n),
727  comm
728  );
729 
730  return n;
731 }
732 
733 
735 (
736  const label comm,
737  autoPtr<OSstream>& osPtr,
738  List<std::streamoff>& start,
739  const UList<char>& data,
740 
741  const labelUList& recvSizes,
742  const PtrList<SubList<char>>& slaveData,
743 
744  const UPstream::commsTypes commsType,
745  const bool syncReturnState
746 )
747 {
748  if (debug)
749  {
750  Pout<< "decomposedBlockData::writeBlocks:"
751  << " stream:" << (osPtr.valid() ? osPtr().name() : "invalid")
752  << " data:" << data.size()
753  << " (master only) slaveData:" << slaveData.size()
754  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
755  }
756 
757  const label nProcs = UPstream::nProcs(comm);
758 
759  bool ok = true;
760 
761  if (slaveData.size())
762  {
763  // Already have gathered the slave data. communicator only used to
764  // check who is the master
765 
766  if (UPstream::master(comm))
767  {
768  OSstream& os = osPtr();
769 
770  start.setSize(nProcs);
771 
772  // Write master data
773  {
774  os << nl << "// Processor" << UPstream::masterNo() << nl;
775  start[UPstream::masterNo()] = os.stdStream().tellp();
776  os << data;
777  }
778 
779  // Write slaves
780  for (label proci = 1; proci < nProcs; proci++)
781  {
782  os << nl << nl << "// Processor" << proci << nl;
783  start[proci] = os.stdStream().tellp();
784 
785  os << slaveData[proci];
786  }
787 
788  ok = os.good();
789  }
790  }
791  else if (commsType == UPstream::commsTypes::scheduled)
792  {
793  if (UPstream::master(comm))
794  {
795  start.setSize(nProcs);
796 
797  OSstream& os = osPtr();
798 
799  // Write master data
800  {
801  os << nl << "// Processor" << UPstream::masterNo() << nl;
802  start[UPstream::masterNo()] = os.stdStream().tellp();
803  os << data;
804  }
805  // Write slaves
806  List<char> elems;
807  for (label proci = 1; proci < nProcs; proci++)
808  {
809  elems.setSize(recvSizes[proci]);
811  (
813  proci,
814  elems.begin(),
815  elems.size(),
817  comm
818  );
819 
820  os << nl << nl << "// Processor" << proci << nl;
821  start[proci] = os.stdStream().tellp();
822  os << elems;
823  }
824 
825  ok = os.good();
826  }
827  else
828  {
830  (
833  data.begin(),
834  data.byteSize(),
836  comm
837  );
838  }
839  }
840  else
841  {
842  // Write master data
843  if (UPstream::master(comm))
844  {
845  start.setSize(nProcs);
846 
847  OSstream& os = osPtr();
848 
849  os << nl << "// Processor" << UPstream::masterNo() << nl;
850  start[UPstream::masterNo()] = os.stdStream().tellp();
851  os << data;
852  }
853 
854 
855  // Find out how many processor can be received into
856  // maxMasterFileBufferSize
857 
858  // Starting slave processor and number of processors
859  label startProc = 1;
860  label nSendProcs = nProcs-1;
861 
862  while (nSendProcs > 0 && startProc < nProcs)
863  {
864  nSendProcs = calcNumProcs
865  (
866  comm,
867  off_t
868  (
870  maxMasterFileBufferSize
871  ),
872  recvSizes,
873  startProc
874  );
875 
876  if (nSendProcs == 0)
877  {
878  break;
879  }
880 
881 
882  // Gather data from (a slice of) the slaves
883  List<int> sliceOffsets;
884  List<char> recvData;
885  gatherSlaveData
886  (
887  comm,
888  data,
889  recvSizes,
890 
891  startProc, // startProc,
892  nSendProcs, // nProcs,
893 
894  sliceOffsets,
895  recvData
896  );
897 
898  if (UPstream::master(comm))
899  {
900  OSstream& os = osPtr();
901 
902  // Write slaves
903  for
904  (
905  label proci = startProc;
906  proci < startProc+nSendProcs;
907  proci++
908  )
909  {
910  os << nl << nl << "// Processor" << proci << nl;
911  start[proci] = os.stdStream().tellp();
912 
913  os <<
915  (
916  recvData,
917  sliceOffsets[proci+1]-sliceOffsets[proci],
918  sliceOffsets[proci]
919  );
920  }
921  }
922 
923  startProc += nSendProcs;
924  }
925 
926  if (UPstream::master(comm))
927  {
928  ok = osPtr().good();
929  }
930  }
931 
932  if (syncReturnState)
933  {
934  //- Enable to get synchronised error checking. Is the one that keeps
935  // slaves as slow as the master (which does all the writing)
936  Pstream::scatter(ok, Pstream::msgType(), comm);
937  }
938 
939  return ok;
940 }
941 
942 
944 {
945  autoPtr<ISstream> isPtr;
946  fileName objPath(fileHandler().filePath(false, *this, word::null));
947  if (UPstream::master(comm_))
948  {
949  isPtr.reset(new IFstream(objPath));
950  IOobject::readHeader(isPtr());
951  }
952 
953  List<char>& data = *this;
954  return readBlocks(comm_, isPtr, data, commsType_);
955 }
956 
957 
959 {
960  const List<char>& data = *this;
961 
962  string str
963  (
964  reinterpret_cast<const char*>(data.cbegin()),
965  data.byteSize()
966  );
967 
968  IOobject io(*this);
969  if (Pstream::master(comm_))
970  {
971  IStringStream is(name(), str);
972  io.readHeader(is);
973  }
974 
975  // Scatter header information
976 
977  // version
978  string versionString(os.version().str());
979  Pstream::scatter(versionString, Pstream::msgType(), comm_);
980 
981  // stream
982  string formatString;
983  {
984  OStringStream os;
985  os << os.format();
986  formatString = os.str();
987  Pstream::scatter(formatString, Pstream::msgType(), comm_);
988  }
989 
990  // word masterName(name());
991  // Pstream::scatter(masterName, Pstream::msgType(), comm_);
992 
994  Pstream::scatter(io.note(), Pstream::msgType(), comm_);
995  // Pstream::scatter(io.instance(), Pstream::msgType(), comm);
996  // Pstream::scatter(io.local(), Pstream::msgType(), comm);
997 
998  fileName masterLocation(instance()/db().dbDir()/local());
999  Pstream::scatter(masterLocation, Pstream::msgType(), comm_);
1000 
1001  if (!Pstream::master(comm_))
1002  {
1003  writeHeader
1004  (
1005  os,
1006  IOstream::versionNumber(IStringStream(versionString)()),
1007  IOstream::formatEnum(formatString),
1008  io.headerClassName(),
1009  io.note(),
1010  masterLocation,
1011  name()
1012  );
1013  }
1014 
1015  os.writeQuoted(str, false);
1016 
1017  if (!Pstream::master(comm_))
1018  {
1020  }
1021 
1022  return os.good();
1023 }
1024 
1025 
1027 (
1031  const bool write
1032 ) const
1033 {
1034  autoPtr<OSstream> osPtr;
1035  if (UPstream::master(comm_))
1036  {
1037  // Note: always write binary. These are strings so readable
1038  // anyway. They have already be tokenised on the sending side.
1039  osPtr.reset(new OFstream(objectPath(), IOstream::BINARY, ver, cmp));
1040  IOobject::writeHeader(osPtr());
1041  }
1042 
1043  labelList recvSizes;
1044  gather(comm_, label(this->byteSize()), recvSizes);
1045 
1046  List<std::streamoff> start;
1047  PtrList<SubList<char>> slaveData; // dummy slave data
1048  return writeBlocks
1049  (
1050  comm_,
1051  osPtr,
1052  start,
1053  *this,
1054  recvSizes,
1055  slaveData,
1056  commsType_
1057  );
1058 }
1059 
1060 
1062 {
1063  label nBlocks = 0;
1064 
1065  IFstream is(fName);
1066  is.fatalCheck("decomposedBlockData::numBlocks(const fileName&)");
1067 
1068  if (!is.good())
1069  {
1070  return nBlocks;
1071  }
1072 
1073  // Skip header
1074  token firstToken(is);
1075 
1076  if
1077  (
1078  is.good()
1079  && firstToken.isWord()
1080  && firstToken.wordToken() == IOobject::foamFile
1081  )
1082  {
1083  dictionary headerDict(is);
1084  is.version(headerDict.lookup("version"));
1085  is.format(headerDict.lookup("format"));
1086  }
1087 
1088  List<char> data;
1089  while (is.good())
1090  {
1091  token sizeToken(is);
1092  if (!sizeToken.isLabel())
1093  {
1094  return nBlocks;
1095  }
1096  is.putBack(sizeToken);
1097 
1098  is >> data;
1099  nBlocks++;
1100  }
1101 
1102  return nBlocks;
1103 }
1104 
1105 
1106 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Input from file stream.
Definition: IFstream.H:85
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
static Stream & writeBanner(Stream &os, bool noHint=false)
Write the standard OpenFOAM file/dictionary banner.
Definition: IOobjectI.H:45
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:119
static Stream & writeEndDivider(Stream &os)
Write the standard end file divider.
Definition: IOobjectI.H:103
string & note()
Return non-constant access to the optional note.
Definition: IOobject.H:328
readOption readOpt() const
Definition: IOobject.H:360
static constexpr const char * foamFile
Keyword for the FoamFile header sub-dictionary.
Definition: IOobject.H:104
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:316
virtual void rename(const word &newName)
Rename.
Definition: IOobject.H:340
static Stream & writeDivider(Stream &os)
Write the standard file section divider.
Definition: IOobjectI.H:93
bool readHeader(Istream &)
Read header.
const word & name() const
Return name.
Definition: IOobject.H:310
bool writeHeader(Ostream &) const
Write header.
Version number type.
Definition: IOstream.H:97
string str() const
Return the versionNumber as a character string.
Definition: IOstream.C:116
static const versionNumber currentVersion
Current version number.
Definition: IOstream.H:203
streamFormat format() const
Return current stream format.
Definition: IOstream.H:374
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.H:294
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:105
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
versionNumber version() const
Return the stream version.
Definition: IOstream.H:396
static streamFormat formatEnum(const word &)
Return stream format of given format name.
Definition: IOstream.C:39
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:330
Input inter-processor communications stream.
Definition: IPstream.H:54
Input from memory buffer stream.
Definition: IStringStream.H:52
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
void putBack(const token &)
Put back token.
Definition: Istream.C:30
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void operator=(const UList< T > &)
Assignment to UList operator. Takes linear time.
Definition: List.C:376
void setSize(const label)
Reset size of List.
Definition: List.C:281
Output to file stream.
Definition: OFstream.H:86
Output inter-processor communications stream.
Definition: OPstream.H:54
Generic output stream.
Definition: OSstream.H:54
virtual ostream & stdStream()
Access to underlying std::ostream.
Definition: OSstream.H:180
Output to memory buffer stream.
Definition: OStringStream.H:52
string str() const
Return the string.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
virtual Ostream & writeQuoted(const std::string &, const bool quoted=true)=0
Write std::string surrounded by quotes.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
A List obtained as a section of another List.
Definition: SubList.H:56
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:57
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Read into given buffer from given processor and return the.
Definition: UIPread.C:79
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:74
const_iterator cbegin() const
Return const_iterator to begin traversing the constant UList.
Definition: UListI.H:232
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
iterator begin()
Return an iterator to begin traversing the UList.
Definition: UListI.H:216
std::streamsize byteSize() const
Return the binary size in number of characters of the UList.
Definition: UList.C:100
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:58
static bool write(const commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Write given buffer to given processor.
Definition: UOPwrite.C:34
commsTypes
Types of communications.
Definition: UPstream.H:65
static int masterNo()
Process index of the master.
Definition: UPstream.H:417
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static const NamedEnum< commsTypes, 3 > commsTypeNames
Definition: UPstream.H:71
static void gather(const char *sendData, int sendSize, char *recvData, const UList< int > &recvSizes, const UList< int > &recvOffsets, const label communicator=0)
Receive data from all processors on the master.
Definition: UPstream.C:96
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:411
static void scatter(const char *sendData, const UList< int > &sendSizes, const UList< int > &sendOffsets, char *recvData, int recvSize, const label communicator=0)
Send data to all processors from the root of the communicator.
Definition: UPstream.C:111
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set)
Definition: autoPtrI.H:83
void reset(T *=nullptr)
If object pointer already set, delete object and set to given.
Definition: autoPtrI.H:114
decomposedBlockData is a List<char> with IO on the master processor only.
static bool writeBlocks(const label comm, autoPtr< OSstream > &osPtr, List< std::streamoff > &start, const UList< char > &masterData, const labelUList &recvSizes, const PtrList< SubList< char >> &slaveData, const UPstream::commsTypes, const bool syncReturnState=true)
Write *this. Ostream only valid on master. Returns starts of.
static void gatherSlaveData(const label comm, const UList< char > &data, const labelUList &recvSizes, const label startProc, const label nProcs, List< int > &recvOffsets, List< char > &recvData)
Helper: gather data from (subset of) slaves. Returns.
virtual bool writeData(Ostream &) const
Write separated content. Assumes content is the serialised data.
static bool readMasterHeader(IOobject &, Istream &)
Read header. Call only on master.
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool write) const
Write using given format, version and compression.
static void gather(const label comm, const label data, labelList &datas)
Helper: gather single label. Note: using native Pstream.
static label numBlocks(const fileName &)
Detect number of blocks in a file.
static void writeHeader(Ostream &os, const IOstream::versionNumber version, const IOstream::streamFormat format, const word &type, const string &note, const fileName &location, const word &name)
Helper: write FoamFile IOobject header.
decomposedBlockData(const label comm, const IOobject &, const UPstream::commsTypes=UPstream::commsTypes::scheduled)
Construct given an IOobject.
static bool readBlocks(const label comm, autoPtr< ISstream > &isPtr, List< char > &data, const UPstream::commsTypes commsType)
Read data into *this. ISstream is only valid on master.
static autoPtr< ISstream > readBlock(const label blocki, Istream &is, IOobject &headerIO)
Read selected block (non-seeking) + header information.
static label calcNumProcs(const label comm, const off_t maxBufferSize, const labelUList &recvSizes, const label startProci)
Helper: determine number of processors whose recvSizes fits.
virtual bool read()
Read object.
virtual ~decomposedBlockData()
Destructor.
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:710
A class for handling file names.
Definition: fileName.H:82
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
bool headerOk()
Read and check header info.
Definition: regIOobject.C:453
A token holds items read from Istream.
Definition: token.H:73
bool isLabel() const
Definition: tokenI.H:571
bool isWord() const
Definition: tokenI.H:298
const word & wordToken() const
Definition: tokenI.H:303
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define WarningInFunction
Report a warning using Foam::Warning.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
void writeHeader(std::ostream &, const bool isBinary, const std::string &title)
Write header.
Namespace for OpenFOAM.
const fileOperation & fileHandler()
Get current file handler.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
defineTypeNameAndDebug(combustionModel, 0)
IOerror FatalIOError
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
static const char nl
Definition: Ostream.H:266
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
word format(conversionProperties.lookup("format"))