decomposedBlockData.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2017-2018 OpenFOAM Foundation
9  Copyright (C) 2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "decomposedBlockData.H"
30 #include "OPstream.H"
31 #include "IPstream.H"
32 #include "PstreamBuffers.H"
33 #include "Fstream.H"
34 #include "dictionary.H"
35 #include "objectRegistry.H"
36 #include "SubList.H"
37 #include "labelPair.H"
39 #include "IListStream.H"
40 #include "foamVersion.H"
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46  defineTypeNameAndDebug(decomposedBlockData, 0);
47 }
48 
49 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
50 
52 (
53  const label comm,
54  const IOobject& io,
55  const UPstream::commsTypes commsType
56 )
57 :
58  regIOobject(io),
59  commsType_(commsType),
60  comm_(comm)
61 {
62  // Temporary warning
63  if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
64  {
66  << "decomposedBlockData " << name()
67  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
68  " but decomposedBlockData does not support automatic rereading."
69  << endl;
70  }
71  if
72  (
73  (
74  io.readOpt() == IOobject::MUST_READ
75  || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
76  )
77  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
78  )
79  {
80  read();
81  }
82 }
83 
84 
86 (
87  const label comm,
88  const IOobject& io,
89  const UList<char>& list,
90  const UPstream::commsTypes commsType
91 )
92 :
93  regIOobject(io),
94  commsType_(commsType),
95  comm_(comm)
96 {
97  // Temporary warning
98  if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
99  {
101  << "decomposedBlockData " << name()
102  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
103  " but decomposedBlockData does not support automatic rereading."
104  << endl;
105  }
106 
107  if
108  (
109  (
110  io.readOpt() == IOobject::MUST_READ
111  || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
112  )
113  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
114  )
115  {
116  read();
117  }
118  else
119  {
120  List<char>::operator=(list);
121  }
122 }
123 
124 
126 (
127  const label comm,
128  const IOobject& io,
129  List<char>&& list,
130  const UPstream::commsTypes commsType
131 )
132 :
133  regIOobject(io),
134  commsType_(commsType),
135  comm_(comm)
136 {
137  // Temporary warning
138  if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
139  {
141  << "decomposedBlockData " << name()
142  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
143  " but decomposedBlockData does not support automatic rereading."
144  << endl;
145  }
146 
147  List<char>::transfer(list);
148 
149  if
150  (
151  (
152  io.readOpt() == IOobject::MUST_READ
153  || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
154  )
155  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
156  )
157  {
158  read();
159  }
160 }
161 
162 
163 // * * * * * * * * * * * * * * * Members Functions * * * * * * * * * * * * * //
164 
166 {
167  if (debug)
168  {
169  Pout<< "decomposedBlockData::readMasterHeader:"
170  << " stream:" << is.name() << endl;
171  }
172 
173  // Master-only reading of header
174  is.fatalCheck("read(Istream&)");
175 
176  List<char> data(is);
177  is.fatalCheck("read(Istream&) : reading entry");
178 
179  UIListStream headerStream(data);
180  headerStream.name() = is.name();
181 
182  return io.readHeader(headerStream);
183 }
184 
185 
187 (
188  Ostream& os,
191  const word& type,
192  const string& note,
193  const fileName& location,
194  const word& name
195 )
196 {
198  << "FoamFile\n{\n"
199  << " version " << version << ";\n"
200  << " format " << format << ";\n"
201  << " class " << type << ";\n";
202 
203  // This may be useful to have as well
204  if (os.format() == IOstream::BINARY)
205  {
206  os << " arch " << foamVersion::buildArch << ";\n";
207  }
208 
209  if (Pstream::parRun())
210  {
211  os << " blocks " << Pstream::nProcs() << ";\n";
212  }
213 
214  if (note.size())
215  {
216  os << " note " << note << ";\n";
217  }
218 
219  if (location.size())
220  {
221  os << " location " << location << ";\n";
222  }
223 
224  os << " object " << name << ";\n"
225  << "}" << nl;
226 
227  IOobject::writeDivider(os) << nl;
228 }
229 
230 
232 (
233  const label blocki,
234  Istream& is,
235  IOobject& headerIO
236 )
237 {
238  if (debug)
239  {
240  Pout<< "decomposedBlockData::readBlock:"
241  << " stream:" << is.name() << " attempt to read block " << blocki
242  << endl;
243  }
244 
245  is.fatalCheck("read(Istream&)");
246 
247  autoPtr<ISstream> realIsPtr;
248 
249  if (blocki == 0)
250  {
251  List<char> data(is);
252  is.fatalCheck("read(Istream&) : reading entry");
253 
254  realIsPtr.reset(new IListStream(std::move(data)));
255  realIsPtr->name() = is.name();
256 
257  // Read header
258  if (!headerIO.readHeader(*realIsPtr))
259  {
260  FatalIOErrorInFunction(*realIsPtr)
261  << "problem while reading header for object "
262  << is.name() << exit(FatalIOError);
263  }
264  }
265  else
266  {
267  // Read master for header
268  List<char> data(is);
269  is.fatalCheck("read(Istream&) : reading entry");
270 
273  unsigned labelByteSize;
274  unsigned scalarByteSize;
275  {
276  UIListStream headerStream(data);
277 
278  // Read header
279  if (!headerIO.readHeader(headerStream))
280  {
281  FatalIOErrorInFunction(headerStream)
282  << "problem while reading header for object "
283  << is.name() << exit(FatalIOError);
284  }
285  ver = headerStream.version();
286  fmt = headerStream.format();
287  labelByteSize = headerStream.labelByteSize();
288  scalarByteSize = headerStream.scalarByteSize();
289  }
290 
291  for (label i = 1; i < blocki+1; i++)
292  {
293  // Read and discard data, only retain the last one
294  is >> data;
295  is.fatalCheck("read(Istream&) : reading entry");
296  }
297  realIsPtr.reset(new IListStream(std::move(data)));
298  realIsPtr->name() = is.name();
299 
300  // Apply master stream settings to realIsPtr
301  realIsPtr().format(fmt);
302  realIsPtr().version(ver);
303  realIsPtr().setLabelByteSize(labelByteSize);
304  realIsPtr().setScalarByteSize(scalarByteSize);
305  }
306 
307  return realIsPtr;
308 }
309 
310 
312 (
313  const label comm,
314  autoPtr<ISstream>& isPtr,
315  List<char>& data,
316  const UPstream::commsTypes commsType
317 )
318 {
319  if (debug)
320  {
321  Pout<< "decomposedBlockData::readBlocks:"
322  << " stream:" << (isPtr ? isPtr->name() : "invalid")
323  << " commsType:" << Pstream::commsTypeNames[commsType]
324  << " comm:" << comm << endl;
325  }
326 
327  bool ok = false;
328 
329  if (commsType == UPstream::commsTypes::scheduled)
330  {
331  if (UPstream::master(comm))
332  {
333  Istream& is = *isPtr;
334  is.fatalCheck("read(Istream&)");
335 
336  // Read master data
337  {
338  is >> data;
339  is.fatalCheck("read(Istream&) : reading entry");
340  }
341 
342  // Read slave data
343  for
344  (
345  label proci = 1;
346  proci < UPstream::nProcs(comm);
347  ++proci
348  )
349  {
350  List<char> elems(is);
351  is.fatalCheck("read(Istream&) : reading entry");
352 
353  OPstream os
354  (
356  proci,
357  0,
359  comm
360  );
361  os << elems;
362  }
363 
364  ok = is.good();
365  }
366  else
367  {
368  IPstream is
369  (
372  0,
374  comm
375  );
376  is >> data;
377  }
378  }
379  else
380  {
381  PstreamBuffers pBufs
382  (
385  comm
386  );
387 
388  if (UPstream::master(comm))
389  {
390  Istream& is = *isPtr;
391  is.fatalCheck("read(Istream&)");
392 
393  // Read master data
394  {
395  is >> data;
396  is.fatalCheck("read(Istream&) : reading entry");
397  }
398 
399  // Read slave data
400  for
401  (
402  label proci = 1;
403  proci < UPstream::nProcs(comm);
404  ++proci
405  )
406  {
407  List<char> elems(is);
408  is.fatalCheck("read(Istream&) : reading entry");
409 
410  UOPstream os(proci, pBufs);
411  os << elems;
412  }
413  }
414 
415  labelList recvSizes;
416  pBufs.finishedSends(recvSizes);
417 
418  if (!UPstream::master(comm))
419  {
420  UIPstream is(UPstream::masterNo(), pBufs);
421  is >> data;
422  }
423  }
424 
425  Pstream::scatter(ok, Pstream::msgType(), comm);
426 
427  return ok;
428 }
429 
430 
432 (
433  const label comm,
434  const fileName& fName,
435  autoPtr<ISstream>& isPtr,
436  IOobject& headerIO,
437  const UPstream::commsTypes commsType
438 )
439 {
440  if (debug)
441  {
442  Pout<< "decomposedBlockData::readBlocks:"
443  << " stream:" << (isPtr ? isPtr->name() : "invalid")
444  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
445  }
446 
447  bool ok = false;
448 
450  autoPtr<ISstream> realIsPtr;
451 
452  if (commsType == UPstream::commsTypes::scheduled)
453  {
454  if (UPstream::master(comm))
455  {
456  Istream& is = *isPtr;
457  is.fatalCheck("read(Istream&)");
458 
459  // Read master data
460  {
461  is >> data;
462  is.fatalCheck("read(Istream&) : reading entry");
463 
464  realIsPtr.reset(new IListStream(std::move(data)));
465  realIsPtr->name() = fName;
466 
467  // Read header
468  if (!headerIO.readHeader(*realIsPtr))
469  {
470  FatalIOErrorInFunction(*realIsPtr)
471  << "problem while reading header for object "
472  << is.name() << exit(FatalIOError);
473  }
474  }
475 
476  // Read slave data
477  for
478  (
479  label proci = 1;
480  proci < UPstream::nProcs(comm);
481  ++proci
482  )
483  {
484  is >> data;
485  is.fatalCheck("read(Istream&) : reading entry");
486 
487  OPstream os
488  (
490  proci,
491  0,
493  comm
494  );
495  os << data;
496  }
497 
498  ok = is.good();
499  }
500  else
501  {
502  IPstream is
503  (
506  0,
508  comm
509  );
510  is >> data;
511 
512  realIsPtr.reset(new IListStream(std::move(data)));
513  realIsPtr->name() = fName;
514  }
515  }
516  else
517  {
518  PstreamBuffers pBufs
519  (
522  comm
523  );
524 
525  if (UPstream::master(comm))
526  {
527  Istream& is = *isPtr;
528  is.fatalCheck("read(Istream&)");
529 
530  // Read master data
531  {
532  is >> data;
533  is.fatalCheck("read(Istream&) : reading entry");
534 
535  realIsPtr.reset(new IListStream(std::move(data)));
536  realIsPtr->name() = fName;
537 
538  // Read header
539  if (!headerIO.readHeader(*realIsPtr))
540  {
541  FatalIOErrorInFunction(*realIsPtr)
542  << "problem while reading header for object "
543  << is.name() << exit(FatalIOError);
544  }
545  }
546 
547  // Read slave data
548  for
549  (
550  label proci = 1;
551  proci < UPstream::nProcs(comm);
552  ++proci
553  )
554  {
555  List<char> elems(is);
556  is.fatalCheck("read(Istream&) : reading entry");
557 
558  UOPstream os(proci, pBufs);
559  os << elems;
560  }
561 
562  ok = is.good();
563  }
564 
565  labelList recvSizes;
566  pBufs.finishedSends(recvSizes);
567 
568  if (!UPstream::master(comm))
569  {
570  UIPstream is(UPstream::masterNo(), pBufs);
571  is >> data;
572 
573  realIsPtr.reset(new IListStream(std::move(data)));
574  realIsPtr->name() = fName;
575  }
576  }
577 
578  Pstream::scatter(ok, Pstream::msgType(), comm);
579 
580  //- Set stream properties from realIsPtr on master
581 
582  // Scatter master header info
583  string versionString;
584  label formatValue;
585  unsigned labelByteSize;
586  unsigned scalarByteSize;
587  if (UPstream::master(comm))
588  {
589  versionString = realIsPtr().version().str();
590  formatValue = static_cast<label>(realIsPtr().format());
591  labelByteSize = realIsPtr().labelByteSize();
592  scalarByteSize = realIsPtr().scalarByteSize();
593  }
594  Pstream::scatter(versionString); //, Pstream::msgType(), comm);
595  Pstream::scatter(formatValue); //, Pstream::msgType(), comm);
596  Pstream::scatter(labelByteSize); //, Pstream::msgType(), comm);
597  Pstream::scatter(scalarByteSize); //, Pstream::msgType(), comm);
598 
599  realIsPtr().version(IOstream::versionNumber(versionString));
600  realIsPtr().format(IOstream::streamFormat(formatValue));
601  realIsPtr().setLabelByteSize(labelByteSize);
602  realIsPtr().setScalarByteSize(scalarByteSize);
603 
604  word name(headerIO.name());
606  headerIO.rename(name);
608  Pstream::scatter(headerIO.note(), Pstream::msgType(), comm);
609  //Pstream::scatter(headerIO.instance(), Pstream::msgType(), comm);
610  //Pstream::scatter(headerIO.local(), Pstream::msgType(), comm);
611 
612  return realIsPtr;
613 }
614 
615 
617 (
618  const label comm,
619  const label data,
620  labelList& datas
621 )
622 {
623  const label nProcs = UPstream::nProcs(comm);
624  datas.setSize(nProcs);
625 
626  char* data0Ptr = reinterpret_cast<char*>(datas.begin());
627 
628  List<int> recvOffsets;
629  List<int> recvSizes;
630  if (UPstream::master(comm))
631  {
632  recvOffsets.setSize(nProcs);
633  forAll(recvOffsets, proci)
634  {
635  // Note: truncating long int to int since UPstream::gather limited
636  // to ints
637  recvOffsets[proci] =
638  int(reinterpret_cast<char*>(&datas[proci]) - data0Ptr);
639  }
640  recvSizes.setSize(nProcs, sizeof(label));
641  }
642 
644  (
645  reinterpret_cast<const char*>(&data),
646  sizeof(label),
647  data0Ptr,
648  recvSizes,
649  recvOffsets,
650  comm
651  );
652 }
653 
654 
656 (
657  const label comm,
658  const UList<char>& data,
659  const labelUList& recvSizes,
660 
661  const label startProc,
662  const label nProcs,
663 
664  List<int>& sliceOffsets,
665  List<char>& recvData
666 )
667 {
668  // Calculate master data
669  List<int> sliceSizes;
670  if (UPstream::master(comm))
671  {
672  const label numProcs = UPstream::nProcs(comm);
673 
674  sliceSizes.setSize(numProcs, 0);
675  sliceOffsets.setSize(numProcs+1, 0);
676 
677  int totalSize = 0;
678  label proci = startProc;
679  for (label i = 0; i < nProcs; i++)
680  {
681  sliceSizes[proci] = int(recvSizes[proci]);
682  sliceOffsets[proci] = totalSize;
683  totalSize += sliceSizes[proci];
684  ++proci;
685  }
686  sliceOffsets[proci] = totalSize;
687  recvData.setSize(totalSize);
688  }
689 
690  int nSend = 0;
691  if
692  (
693  !UPstream::master(comm)
694  && (UPstream::myProcNo(comm) >= startProc)
695  && (UPstream::myProcNo(comm) < startProc+nProcs)
696  )
697  {
698  // Note: UPstream::gather limited to int
699  nSend = int(data.byteSize());
700  }
701 
703  (
704  data.begin(),
705  nSend,
706 
707  recvData.begin(),
708  sliceSizes,
709  sliceOffsets,
710  comm
711  );
712 }
713 
714 
716 (
717  const label comm,
718  const off_t maxBufferSize,
719  const labelUList& recvSizes,
720  const label startProci
721 )
722 {
723  const label nProcs = UPstream::nProcs(comm);
724 
725  label nSendProcs = -1;
726  if (UPstream::master(comm))
727  {
728  off_t totalSize = recvSizes[startProci];
729  label proci = startProci+1;
730  while (proci < nProcs && (totalSize+recvSizes[proci] < maxBufferSize))
731  {
732  totalSize += recvSizes[proci];
733  proci++;
734  }
735 
736  nSendProcs = proci-startProci;
737  }
738 
739  // Scatter nSendProcs
740  label n;
742  (
743  reinterpret_cast<const char*>(&nSendProcs),
744  List<int>(nProcs, sizeof(nSendProcs)),
745  List<int>(nProcs, Zero),
746  reinterpret_cast<char*>(&n),
747  sizeof(n),
748  comm
749  );
750 
751  return n;
752 }
753 
754 
756 (
757  const label comm,
758  autoPtr<OSstream>& osPtr,
759  List<std::streamoff>& start,
760  const UList<char>& data,
761 
762  const labelUList& recvSizes,
763  const PtrList<SubList<char>>& slaveData,
764 
765  const UPstream::commsTypes commsType,
766  const bool syncReturnState
767 )
768 {
769  if (debug)
770  {
771  Pout<< "decomposedBlockData::writeBlocks:"
772  << " stream:" << (osPtr ? osPtr->name() : "invalid")
773  << " data:" << data.size()
774  << " (master only) slaveData:" << slaveData.size()
775  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
776  }
777 
778  const label nProcs = UPstream::nProcs(comm);
779 
780  bool ok = true;
781 
782  if (slaveData.size())
783  {
784  // Already have gathered the slave data. communicator only used to
785  // check who is the master
786 
787  if (UPstream::master(comm))
788  {
789  OSstream& os = *osPtr;
790 
791  start.setSize(nProcs);
792 
793  // Write master data
794  {
795  os << nl << "// Processor" << UPstream::masterNo() << nl;
796  start[UPstream::masterNo()] = os.stdStream().tellp();
797  os << data;
798  }
799 
800  // Write slaves
801 
802  label slaveOffset = 0;
803 
804  for (label proci = 1; proci < nProcs; ++proci)
805  {
806  os << nl << nl << "// Processor" << proci << nl;
807  start[proci] = os.stdStream().tellp();
808 
809  os << slaveData[proci];
810  slaveOffset += recvSizes[proci];
811  }
812 
813  ok = os.good();
814  }
815  }
816  else if (commsType == UPstream::commsTypes::scheduled)
817  {
818  if (UPstream::master(comm))
819  {
820  start.setSize(nProcs);
821 
822  OSstream& os = *osPtr;
823 
824  // Write master data
825  {
826  os << nl << "// Processor" << UPstream::masterNo() << nl;
827  start[UPstream::masterNo()] = os.stdStream().tellp();
828  os << data;
829  }
830  // Write slaves
831  List<char> elems;
832  for (label proci = 1; proci < nProcs; ++proci)
833  {
834  elems.setSize(recvSizes[proci]);
836  (
838  proci,
839  elems.begin(),
840  elems.size(),
842  comm
843  );
844 
845  os << nl << nl << "// Processor" << proci << nl;
846  start[proci] = os.stdStream().tellp();
847  os << elems;
848  }
849 
850  ok = os.good();
851  }
852  else
853  {
855  (
858  data.begin(),
859  data.byteSize(),
861  comm
862  );
863  }
864  }
865  else
866  {
867  // Write master data
868  if (UPstream::master(comm))
869  {
870  start.setSize(nProcs);
871 
872  OSstream& os = *osPtr;
873 
874  os << nl << "// Processor" << UPstream::masterNo() << nl;
875  start[UPstream::masterNo()] = os.stdStream().tellp();
876  os << data;
877  }
878 
879 
880  // Find out how many processor can be received into
881  // maxMasterFileBufferSize
882 
883  // Starting slave processor and number of processors
884  label startProc = 1;
885  label nSendProcs = nProcs-1;
886 
887  while (nSendProcs > 0 && startProc < nProcs)
888  {
889  nSendProcs = calcNumProcs
890  (
891  comm,
892  off_t
893  (
895  maxMasterFileBufferSize
896  ),
897  recvSizes,
898  startProc
899  );
900 
901  if (nSendProcs == 0)
902  {
903  break;
904  }
905 
906 
907  // Gather data from (a slice of) the slaves
908  List<int> sliceOffsets;
909  List<char> recvData;
910  gatherSlaveData
911  (
912  comm,
913  data,
914  recvSizes,
915 
916  startProc, // startProc,
917  nSendProcs, // nProcs,
918 
919  sliceOffsets,
920  recvData
921  );
922 
923  if (UPstream::master(comm))
924  {
925  OSstream& os = *osPtr;
926 
927  // Write slaves
928  for
929  (
930  label proci = startProc;
931  proci < startProc+nSendProcs;
932  proci++
933  )
934  {
935  os << nl << nl << "// Processor" << proci << nl;
936  start[proci] = os.stdStream().tellp();
937 
938  os <<
940  (
941  recvData,
942  sliceOffsets[proci+1]-sliceOffsets[proci],
943  sliceOffsets[proci]
944  );
945  }
946  }
947 
948  startProc += nSendProcs;
949  }
950 
951  if (UPstream::master(comm))
952  {
953  ok = osPtr->good();
954  }
955  }
956 
957  if (syncReturnState)
958  {
959  //- Enable to get synchronised error checking. Is the one that keeps
960  // slaves as slow as the master (which does all the writing)
961  Pstream::scatter(ok, Pstream::msgType(), comm);
962  }
963 
964  return ok;
965 }
966 
967 
969 {
970  autoPtr<ISstream> isPtr;
971  fileName objPath(fileHandler().filePath(false, *this, word::null));
972  if (UPstream::master(comm_))
973  {
974  isPtr.reset(new IFstream(objPath));
975  IOobject::readHeader(*isPtr);
976  }
977 
978  List<char>& data = *this;
979  return readBlocks(comm_, isPtr, data, commsType_);
980 }
981 
982 
984 {
985  const List<char>& data = *this;
986 
987  IOobject io(*this);
988 
989  // Re-read my own data to find out the header information
990  if (Pstream::master(comm_))
991  {
992  UIListStream headerStream(data);
993  io.readHeader(headerStream);
994  }
995 
996  // Scatter header information
997 
998  string versionString(os.version().str());
999  Pstream::scatter(versionString, Pstream::msgType(), comm_);
1000 
1001  label formatValue(os.format());
1002  Pstream::scatter(formatValue, Pstream::msgType(), comm_);
1003 
1004  //word masterName(name());
1005  //Pstream::scatter(masterName, Pstream::msgType(), comm_);
1006 
1008  Pstream::scatter(io.note(), Pstream::msgType(), comm_);
1009  //Pstream::scatter(io.instance(), Pstream::msgType(), comm);
1010  //Pstream::scatter(io.local(), Pstream::msgType(), comm);
1011 
1012  fileName masterLocation(instance()/db().dbDir()/local());
1013  Pstream::scatter(masterLocation, Pstream::msgType(), comm_);
1014 
1015  if (!Pstream::master(comm_))
1016  {
1017  writeHeader
1018  (
1019  os,
1020  IOstream::versionNumber(versionString),
1021  IOstream::streamFormat(formatValue),
1022  io.headerClassName(),
1023  io.note(),
1024  masterLocation,
1025  name()
1026  );
1027  }
1028 
1029  // Write the character data
1030  if (isA<OFstream>(os))
1031  {
1032  // Serial file output - can use writeRaw()
1033  os.writeRaw(data.cdata(), data.byteSize());
1034  }
1035  else
1036  {
1037  // Other cases are less fortunate, and no std::string_view
1038  std::string str(data.cdata(), data.byteSize());
1039  os.writeQuoted(str, false);
1040  }
1041 
1042  if (!Pstream::master(comm_))
1043  {
1045  }
1046 
1047  return os.good();
1048 }
1049 
1050 
1053  IOstreamOption streamOpt,
1054  const bool valid
1055 ) const
1056 {
1057  // Always write BINARY
1058  streamOpt.format(IOstream::BINARY);
1059 
1060  autoPtr<OSstream> osPtr;
1061  if (UPstream::master(comm_))
1062  {
1063  // Note: always write binary. These are strings so readable anyway.
1064  // They have already be tokenised on the sending side.
1065  osPtr.reset(new OFstream(objectPath(), streamOpt));
1066  IOobject::writeHeader(*osPtr);
1067  }
1068 
1069  labelList recvSizes;
1070  gather(comm_, label(this->byteSize()), recvSizes);
1071 
1072  List<std::streamoff> start;
1073  PtrList<SubList<char>> slaveData; // dummy slave data
1074  return writeBlocks
1075  (
1076  comm_,
1077  osPtr,
1078  start,
1079  *this,
1080  recvSizes,
1081  slaveData,
1082  commsType_
1083  );
1084 }
1085 
1086 
1088 {
1089  label nBlocks = 0;
1090 
1091  IFstream is(fName);
1092  is.fatalCheck("decomposedBlockData::numBlocks(const fileName&)");
1093 
1094  if (!is.good())
1095  {
1096  return nBlocks;
1097  }
1098 
1099  // FoamFile header
1100  token firstToken(is);
1101 
1102  if
1103  (
1104  is.good()
1105  && firstToken.isWord()
1106  && firstToken.wordToken() == "FoamFile"
1107  )
1108  {
1109  dictionary headerDict(is);
1110  is.version(headerDict.get<token>("version"));
1111  is.format(headerDict.get<word>("format"));
1112 
1113  // Obtain number of blocks directly
1114  if (headerDict.readIfPresent("blocks", nBlocks))
1115  {
1116  return nBlocks;
1117  }
1118  }
1119 
1120  // Fallback to brute force read of each data block
1121  List<char> data;
1122  while (is.good())
1123  {
1124  token sizeToken(is);
1125  if (!sizeToken.isLabel())
1126  {
1127  return nBlocks;
1128  }
1129  is.putBack(sizeToken);
1130 
1131  is >> data;
1132  nBlocks++;
1133  }
1134 
1135  return nBlocks;
1136 }
1137 
1138 
1139 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::IOstream::labelByteSize
unsigned labelByteSize() const
The label byte-size associated with the stream.
Definition: IOstream.H:263
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:109
Foam::UIListStream
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
Definition: UIListStream.H:202
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
Foam::UPstream::commsTypes::nonBlocking
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master.
Definition: UPstream.H:433
SubList.H
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:57
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:85
Foam::decomposedBlockData::readBlock
static autoPtr< ISstream > readBlock(const label blocki, Istream &is, IOobject &headerIO)
Read selected block (non-seeking) + header information.
Definition: decomposedBlockData.C:232
Foam::IOobject::writeBanner
static Ostream & writeBanner(Ostream &os, bool noHint=false)
Write the standard OpenFOAM file/dictionary banner.
Definition: IOobjectWriteHeader.C:45
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:52
Foam::IOobject::writeEndDivider
static Ostream & writeEndDivider(Ostream &os)
Write the standard end file divider.
Definition: IOobjectWriteHeader.C:109
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:53
Foam::decomposedBlockData::calcNumProcs
static label calcNumProcs(const label comm, const off_t maxBufferSize, const labelUList &recvSizes, const label startProci)
Helper: determine number of processors whose recvSizes fits.
Definition: decomposedBlockData.C:716
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:427
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:88
Foam::Ostream::writeQuoted
virtual Ostream & writeQuoted(const std::string &str, const bool quoted=true)=0
Write std::string surrounded by quotes.
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:415
objectRegistry.H
Foam::IOstream::fatalCheck
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:57
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:289
Foam::IOstreamOption::currentVersion
static const versionNumber currentVersion
The current version number (2.0)
Definition: IOstreamOption.H:168
OPstream.H
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::IListStream
An ISstream with internal List storage.
Definition: IListStream.H:133
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1170
Foam::FatalIOError
IOerror FatalIOError
Foam::decomposedBlockData::writeBlocks
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.
Definition: decomposedBlockData.C:756
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::token
A token holds an item read from Istream.
Definition: token.H:69
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
Foam::writeHeader
static void writeHeader(Ostream &os, const word &fieldName)
Definition: rawSurfaceWriterImpl.C:49
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
Foam::decomposedBlockData::numBlocks
static label numBlocks(const fileName &fName)
Detect number of blocks in a file.
Definition: decomposedBlockData.C:1087
Foam::UPstream::gather
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:183
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::token::isLabel
bool isLabel() const
Token is LABEL.
Definition: tokenI.H:471
Foam::IOobject::readHeader
bool readHeader(Istream &is)
Read header.
Definition: IOobjectReadHeader.C:35
Foam::UIPstream::read
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:81
n
label n
Definition: TABSMDCalcMethod2.H:31
format
word format(conversionProperties.get< word >("format"))
Foam::UOPstream::write
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:36
IPstream.H
Foam::decomposedBlockData::readMasterHeader
static bool readMasterHeader(IOobject &, Istream &)
Read header. Call only on master.
Definition: decomposedBlockData.C:165
Foam::IOstreamOption::versionNumber
Representation of a major/minor version number.
Definition: IOstreamOption.H:85
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::OSstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: OSstream.H:107
Foam::decomposedBlockData::writeHeader
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.
Definition: decomposedBlockData.C:187
Foam::OSstream::stdStream
virtual std::ostream & stdStream()
Access to underlying std::ostream.
Definition: OSstream.H:222
Foam::decomposedBlockData::gather
static void gather(const label comm, const label data, labelList &datas)
Helper: gather single label. Note: using native Pstream.
Definition: decomposedBlockData.C:617
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::decomposedBlockData::gatherSlaveData
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.
Definition: decomposedBlockData.C:656
Foam::IOstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: IOstream.C:39
Foam::OSstream
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:54
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:62
Foam::ISstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: ISstream.H:124
Foam::UPstream::commsTypeNames
static const Enum< commsTypes > commsTypeNames
Names of the communication types.
Definition: UPstream.H:74
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
Definition: PstreamBuffers.C:80
Foam::UPstream::commsTypes::scheduled
Foam::IOstreamOption::version
versionNumber version() const noexcept
Get the stream version.
Definition: IOstreamOption.H:341
Foam::blockMeshTools::read
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:33
Foam::UPstream::scatter
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:198
Foam::IOstreamOption::versionNumber::str
std::string str() const
A string representation of major.minor.
Definition: IOstreamOption.H:152
Foam::IOstreamOption::streamFormat
streamFormat
Data format (ascii | binary)
Definition: IOstreamOption.H:70
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::token::isWord
bool isWord() const
Token is WORD or DIRECTIVE word.
Definition: tokenI.H:573
Foam::decomposedBlockData::decomposedBlockData
decomposedBlockData(const label comm, const IOobject &io, const UPstream::commsTypes=UPstream::commsTypes::scheduled)
Construct given an IOobject.
Definition: decomposedBlockData.C:52
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::IOobject::rename
virtual void rename(const word &newName)
Rename.
Definition: IOobject.H:381
Foam::token::wordToken
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:589
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::foamVersion::version
const std::string version
OpenFOAM version (name or stringified number) as a std::string.
Foam::decomposedBlockData::writeData
virtual bool writeData(Ostream &os) const
Write separated content. Assumes content is the serialised data.
Definition: decomposedBlockData.C:983
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:87
Foam::IOobject::headerClassName
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobjectI.H:88
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:445
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:439
IListStream.H
Foam::IOobject::note
const string & note() const
Return the optional note.
Definition: IOobjectI.H:100
Foam::autoPtr< Foam::ISstream >
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:68
Foam::fileOperations::masterUncollatedFileOperation
fileOperations that performs all file operations on the master processor. Requires the calls to be pa...
Definition: masterUncollatedFileOperation.H:85
Foam::IOstreamOption::BINARY
"binary"
Definition: IOstreamOption.H:73
masterUncollatedFileOperation.H
Foam::UPstream::msgType
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:492
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:66
Foam::decomposedBlockData::readBlocks
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.
Definition: decomposedBlockData.C:312
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Fstream.H
Input/output from file streams.
Foam::IOobject::writeDivider
static Ostream & writeDivider(Ostream &os)
Write the standard file section divider.
Definition: IOobjectWriteHeader.C:99
decomposedBlockData.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::foamVersion::labelByteSize
unsigned labelByteSize(const std::string &str)
Extract label size (in bytes) from "label=" tag in string.
Foam::IOobject::readOpt
readOption readOpt() const
The read option.
Definition: IOobjectI.H:165
Foam::Istream::putBack
void putBack(const token &tok)
Put back token.
Definition: Istream.C:53
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::foamVersion::buildArch
const std::string buildArch
Foam::UList
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:103
dictionary.H
PstreamBuffers.H
Foam::word::null
static const word null
An empty word.
Definition: word.H:77
Foam::foamVersion::scalarByteSize
unsigned scalarByteSize(const std::string &str)
Extract scalar size (in bytes) from "scalar=" tag in string.
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:52
Foam::IOobject::writeHeader
bool writeHeader(Ostream &os) const
Write header.
Definition: IOobjectWriteHeader.C:156
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:392
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:56
Foam::IOstream::good
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:224
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::decomposedBlockData::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: decomposedBlockData.C:1052
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:298
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:54
Foam::Ostream::writeRaw
virtual Ostream & writeRaw(const char *data, std::streamsize count)=0
Low-level raw binary output.
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417
Foam::IOstream::scalarByteSize
unsigned scalarByteSize() const
The scalar byte-size associated with the stream.
Definition: IOstream.H:269
labelPair.H
Foam::decomposedBlockData::read
virtual bool read()
Read object.
Definition: decomposedBlockData.C:968
foamVersion.H