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 (const int proci : UPstream::subProcs(comm))
344  {
345  List<char> elems(is);
346  is.fatalCheck("read(Istream&) : reading entry");
347 
348  OPstream os
349  (
351  proci,
352  0,
354  comm
355  );
356  os << elems;
357  }
358 
359  ok = is.good();
360  }
361  else
362  {
363  IPstream is
364  (
367  0,
369  comm
370  );
371  is >> data;
372  }
373  }
374  else
375  {
376  PstreamBuffers pBufs
377  (
380  comm
381  );
382 
383  if (UPstream::master(comm))
384  {
385  Istream& is = *isPtr;
386  is.fatalCheck("read(Istream&)");
387 
388  // Read master data
389  {
390  is >> data;
391  is.fatalCheck("read(Istream&) : reading entry");
392  }
393 
394  // Read slave data
395  for (const int proci : UPstream::subProcs(comm))
396  {
397  List<char> elems(is);
398  is.fatalCheck("read(Istream&) : reading entry");
399 
400  UOPstream os(proci, pBufs);
401  os << elems;
402  }
403  }
404 
405  labelList recvSizes;
406  pBufs.finishedSends(recvSizes);
407 
408  if (!UPstream::master(comm))
409  {
410  UIPstream is(UPstream::masterNo(), pBufs);
411  is >> data;
412  }
413  }
414 
415  Pstream::scatter(ok, Pstream::msgType(), comm);
416 
417  return ok;
418 }
419 
420 
422 (
423  const label comm,
424  const fileName& fName,
425  autoPtr<ISstream>& isPtr,
426  IOobject& headerIO,
427  const UPstream::commsTypes commsType
428 )
429 {
430  if (debug)
431  {
432  Pout<< "decomposedBlockData::readBlocks:"
433  << " stream:" << (isPtr ? isPtr->name() : "invalid")
434  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
435  }
436 
437  bool ok = false;
438 
440  autoPtr<ISstream> realIsPtr;
441 
442  if (commsType == UPstream::commsTypes::scheduled)
443  {
444  if (UPstream::master(comm))
445  {
446  Istream& is = *isPtr;
447  is.fatalCheck("read(Istream&)");
448 
449  // Read master data
450  {
451  is >> data;
452  is.fatalCheck("read(Istream&) : reading entry");
453 
454  realIsPtr.reset(new IListStream(std::move(data)));
455  realIsPtr->name() = fName;
456 
457  // Read header
458  if (!headerIO.readHeader(*realIsPtr))
459  {
460  FatalIOErrorInFunction(*realIsPtr)
461  << "problem while reading header for object "
462  << is.name() << exit(FatalIOError);
463  }
464  }
465 
466  // Read slave data
467  for (const int proci : UPstream::subProcs(comm))
468  {
469  is >> data;
470  is.fatalCheck("read(Istream&) : reading entry");
471 
472  OPstream os
473  (
475  proci,
476  0,
478  comm
479  );
480  os << data;
481  }
482 
483  ok = is.good();
484  }
485  else
486  {
487  IPstream is
488  (
491  0,
493  comm
494  );
495  is >> data;
496 
497  realIsPtr.reset(new IListStream(std::move(data)));
498  realIsPtr->name() = fName;
499  }
500  }
501  else
502  {
503  PstreamBuffers pBufs
504  (
507  comm
508  );
509 
510  if (UPstream::master(comm))
511  {
512  Istream& is = *isPtr;
513  is.fatalCheck("read(Istream&)");
514 
515  // Read master data
516  {
517  is >> data;
518  is.fatalCheck("read(Istream&) : reading entry");
519 
520  realIsPtr.reset(new IListStream(std::move(data)));
521  realIsPtr->name() = fName;
522 
523  // Read header
524  if (!headerIO.readHeader(*realIsPtr))
525  {
526  FatalIOErrorInFunction(*realIsPtr)
527  << "problem while reading header for object "
528  << is.name() << exit(FatalIOError);
529  }
530  }
531 
532  // Read slave data
533  for (const int proci : UPstream::subProcs(comm))
534  {
535  List<char> elems(is);
536  is.fatalCheck("read(Istream&) : reading entry");
537 
538  UOPstream os(proci, pBufs);
539  os << elems;
540  }
541 
542  ok = is.good();
543  }
544 
545  labelList recvSizes;
546  pBufs.finishedSends(recvSizes);
547 
548  if (!UPstream::master(comm))
549  {
550  UIPstream is(UPstream::masterNo(), pBufs);
551  is >> data;
552 
553  realIsPtr.reset(new IListStream(std::move(data)));
554  realIsPtr->name() = fName;
555  }
556  }
557 
558  Pstream::scatter(ok, Pstream::msgType(), comm);
559 
560  //- Set stream properties from realIsPtr on master
561 
562  // Scatter master header info
563  string versionString;
564  label formatValue;
565  unsigned labelByteSize;
566  unsigned scalarByteSize;
567  if (UPstream::master(comm))
568  {
569  versionString = realIsPtr().version().str();
570  formatValue = static_cast<label>(realIsPtr().format());
571  labelByteSize = realIsPtr().labelByteSize();
572  scalarByteSize = realIsPtr().scalarByteSize();
573  }
574  Pstream::scatter(versionString); //, Pstream::msgType(), comm);
575  Pstream::scatter(formatValue); //, Pstream::msgType(), comm);
576  Pstream::scatter(labelByteSize); //, Pstream::msgType(), comm);
577  Pstream::scatter(scalarByteSize); //, Pstream::msgType(), comm);
578 
579  realIsPtr().version(IOstream::versionNumber(versionString));
580  realIsPtr().format(IOstream::streamFormat(formatValue));
581  realIsPtr().setLabelByteSize(labelByteSize);
582  realIsPtr().setScalarByteSize(scalarByteSize);
583 
584  word name(headerIO.name());
586  headerIO.rename(name);
588  Pstream::scatter(headerIO.note(), Pstream::msgType(), comm);
589  //Pstream::scatter(headerIO.instance(), Pstream::msgType(), comm);
590  //Pstream::scatter(headerIO.local(), Pstream::msgType(), comm);
591 
592  return realIsPtr;
593 }
594 
595 
597 (
598  const label comm,
599  const label data,
600  labelList& datas
601 )
602 {
603  const label nProcs = UPstream::nProcs(comm);
604  datas.setSize(nProcs);
605 
606  char* data0Ptr = reinterpret_cast<char*>(datas.begin());
607 
608  List<int> recvOffsets;
609  List<int> recvSizes;
610  if (UPstream::master(comm))
611  {
612  recvOffsets.setSize(nProcs);
613  forAll(recvOffsets, proci)
614  {
615  // Note: truncating long int to int since UPstream::gather limited
616  // to ints
617  recvOffsets[proci] =
618  int(reinterpret_cast<char*>(&datas[proci]) - data0Ptr);
619  }
620  recvSizes.setSize(nProcs, sizeof(label));
621  }
622 
624  (
625  reinterpret_cast<const char*>(&data),
626  sizeof(label),
627  data0Ptr,
628  recvSizes,
629  recvOffsets,
630  comm
631  );
632 }
633 
634 
636 (
637  const label comm,
638  const UList<char>& data,
639  const labelUList& recvSizes,
640 
641  const label startProc,
642  const label nProcs,
643 
644  List<int>& sliceOffsets,
645  List<char>& recvData
646 )
647 {
648  // Calculate master data
649  List<int> sliceSizes;
650  if (UPstream::master(comm))
651  {
652  const label numProcs = UPstream::nProcs(comm);
653 
654  sliceSizes.setSize(numProcs, 0);
655  sliceOffsets.setSize(numProcs+1, 0);
656 
657  int totalSize = 0;
658  label proci = startProc;
659  for (label i = 0; i < nProcs; i++)
660  {
661  sliceSizes[proci] = int(recvSizes[proci]);
662  sliceOffsets[proci] = totalSize;
663  totalSize += sliceSizes[proci];
664  ++proci;
665  }
666  sliceOffsets[proci] = totalSize;
667  recvData.setSize(totalSize);
668  }
669 
670  int nSend = 0;
671  if
672  (
673  !UPstream::master(comm)
674  && (UPstream::myProcNo(comm) >= startProc)
675  && (UPstream::myProcNo(comm) < startProc+nProcs)
676  )
677  {
678  // Note: UPstream::gather limited to int
679  nSend = int(data.byteSize());
680  }
681 
683  (
684  data.begin(),
685  nSend,
686 
687  recvData.begin(),
688  sliceSizes,
689  sliceOffsets,
690  comm
691  );
692 }
693 
694 
696 (
697  const label comm,
698  const off_t maxBufferSize,
699  const labelUList& recvSizes,
700  const label startProci
701 )
702 {
703  const label nProcs = UPstream::nProcs(comm);
704 
705  label nSendProcs = -1;
706  if (UPstream::master(comm))
707  {
708  off_t totalSize = recvSizes[startProci];
709  label proci = startProci+1;
710  while (proci < nProcs && (totalSize+recvSizes[proci] < maxBufferSize))
711  {
712  totalSize += recvSizes[proci];
713  proci++;
714  }
715 
716  nSendProcs = proci-startProci;
717  }
718 
719  // Scatter nSendProcs
720  label n;
722  (
723  reinterpret_cast<const char*>(&nSendProcs),
724  List<int>(nProcs, sizeof(nSendProcs)),
725  List<int>(nProcs, Zero),
726  reinterpret_cast<char*>(&n),
727  sizeof(n),
728  comm
729  );
730 
731  return n;
732 }
733 
734 
736 (
737  const label comm,
738  autoPtr<OSstream>& osPtr,
739  List<std::streamoff>& start,
740  const UList<char>& data,
741 
742  const labelUList& recvSizes,
743  const PtrList<SubList<char>>& slaveData,
744 
745  const UPstream::commsTypes commsType,
746  const bool syncReturnState
747 )
748 {
749  if (debug)
750  {
751  Pout<< "decomposedBlockData::writeBlocks:"
752  << " stream:" << (osPtr ? osPtr->name() : "invalid")
753  << " data:" << data.size()
754  << " (master only) slaveData:" << slaveData.size()
755  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
756  }
757 
758  const label nProcs = UPstream::nProcs(comm);
759 
760  bool ok = true;
761 
762  if (slaveData.size())
763  {
764  // Already have gathered the slave data. communicator only used to
765  // check who is the master
766 
767  if (UPstream::master(comm))
768  {
769  OSstream& os = *osPtr;
770 
771  start.setSize(nProcs);
772 
773  // Write master data
774  {
775  os << nl << "// Processor" << UPstream::masterNo() << nl;
776  start[UPstream::masterNo()] = os.stdStream().tellp();
777  os << data;
778  }
779 
780  // Write slaves
781 
782  label slaveOffset = 0;
783 
784  for (label proci = 1; proci < nProcs; ++proci)
785  {
786  os << nl << nl << "// Processor" << proci << nl;
787  start[proci] = os.stdStream().tellp();
788 
789  os << slaveData[proci];
790  slaveOffset += recvSizes[proci];
791  }
792 
793  ok = os.good();
794  }
795  }
796  else if (commsType == UPstream::commsTypes::scheduled)
797  {
798  if (UPstream::master(comm))
799  {
800  start.setSize(nProcs);
801 
802  OSstream& os = *osPtr;
803 
804  // Write master data
805  {
806  os << nl << "// Processor" << UPstream::masterNo() << nl;
807  start[UPstream::masterNo()] = os.stdStream().tellp();
808  os << data;
809  }
810  // Write slaves
811  List<char> elems;
812  for (label proci = 1; proci < nProcs; ++proci)
813  {
814  elems.setSize(recvSizes[proci]);
816  (
818  proci,
819  elems.begin(),
820  elems.size(),
822  comm
823  );
824 
825  os << nl << nl << "// Processor" << proci << nl;
826  start[proci] = os.stdStream().tellp();
827  os << elems;
828  }
829 
830  ok = os.good();
831  }
832  else
833  {
835  (
838  data.begin(),
839  data.byteSize(),
841  comm
842  );
843  }
844  }
845  else
846  {
847  // Write master data
848  if (UPstream::master(comm))
849  {
850  start.setSize(nProcs);
851 
852  OSstream& os = *osPtr;
853 
854  os << nl << "// Processor" << UPstream::masterNo() << nl;
855  start[UPstream::masterNo()] = os.stdStream().tellp();
856  os << data;
857  }
858 
859 
860  // Find out how many processor can be received into
861  // maxMasterFileBufferSize
862 
863  // Starting slave processor and number of processors
864  label startProc = 1;
865  label nSendProcs = nProcs-1;
866 
867  while (nSendProcs > 0 && startProc < nProcs)
868  {
869  nSendProcs = calcNumProcs
870  (
871  comm,
872  off_t
873  (
875  maxMasterFileBufferSize
876  ),
877  recvSizes,
878  startProc
879  );
880 
881  if (nSendProcs == 0)
882  {
883  break;
884  }
885 
886 
887  // Gather data from (a slice of) the slaves
888  List<int> sliceOffsets;
889  List<char> recvData;
890  gatherSlaveData
891  (
892  comm,
893  data,
894  recvSizes,
895 
896  startProc, // startProc,
897  nSendProcs, // nProcs,
898 
899  sliceOffsets,
900  recvData
901  );
902 
903  if (UPstream::master(comm))
904  {
905  OSstream& os = *osPtr;
906 
907  // Write slaves
908  for
909  (
910  label proci = startProc;
911  proci < startProc+nSendProcs;
912  proci++
913  )
914  {
915  os << nl << nl << "// Processor" << proci << nl;
916  start[proci] = os.stdStream().tellp();
917 
918  os <<
920  (
921  recvData,
922  sliceOffsets[proci+1]-sliceOffsets[proci],
923  sliceOffsets[proci]
924  );
925  }
926  }
927 
928  startProc += nSendProcs;
929  }
930 
931  if (UPstream::master(comm))
932  {
933  ok = osPtr->good();
934  }
935  }
936 
937  if (syncReturnState)
938  {
939  //- Enable to get synchronised error checking. Is the one that keeps
940  // slaves as slow as the master (which does all the writing)
941  Pstream::scatter(ok, Pstream::msgType(), comm);
942  }
943 
944  return ok;
945 }
946 
947 
949 {
950  autoPtr<ISstream> isPtr;
951  fileName objPath(fileHandler().filePath(false, *this, word::null));
952  if (UPstream::master(comm_))
953  {
954  isPtr.reset(new IFstream(objPath));
955  IOobject::readHeader(*isPtr);
956  }
957 
958  List<char>& data = *this;
959  return readBlocks(comm_, isPtr, data, commsType_);
960 }
961 
962 
964 {
965  const List<char>& data = *this;
966 
967  IOobject io(*this);
968 
969  // Re-read my own data to find out the header information
970  if (Pstream::master(comm_))
971  {
972  UIListStream headerStream(data);
973  io.readHeader(headerStream);
974  }
975 
976  // Scatter header information
977 
978  string versionString(os.version().str());
979  Pstream::scatter(versionString, Pstream::msgType(), comm_);
980 
981  label formatValue(os.format());
982  Pstream::scatter(formatValue, Pstream::msgType(), comm_);
983 
984  //word masterName(name());
985  //Pstream::scatter(masterName, Pstream::msgType(), comm_);
986 
988  Pstream::scatter(io.note(), Pstream::msgType(), comm_);
989  //Pstream::scatter(io.instance(), Pstream::msgType(), comm);
990  //Pstream::scatter(io.local(), Pstream::msgType(), comm);
991 
992  fileName masterLocation(instance()/db().dbDir()/local());
993  Pstream::scatter(masterLocation, Pstream::msgType(), comm_);
994 
995  if (!Pstream::master(comm_))
996  {
998  (
999  os,
1000  IOstream::versionNumber(versionString),
1001  IOstream::streamFormat(formatValue),
1002  io.headerClassName(),
1003  io.note(),
1004  masterLocation,
1005  name()
1006  );
1007  }
1008 
1009  // Write the character data
1010  if (isA<OFstream>(os))
1011  {
1012  // Serial file output - can use writeRaw()
1013  os.writeRaw(data.cdata(), data.byteSize());
1014  }
1015  else
1016  {
1017  // Other cases are less fortunate, and no std::string_view
1018  std::string str(data.cdata(), data.byteSize());
1019  os.writeQuoted(str, false);
1020  }
1021 
1022  if (!Pstream::master(comm_))
1023  {
1025  }
1026 
1027  return os.good();
1028 }
1029 
1030 
1033  IOstreamOption streamOpt,
1034  const bool valid
1035 ) const
1036 {
1037  // Always write BINARY
1038  streamOpt.format(IOstream::BINARY);
1039 
1040  autoPtr<OSstream> osPtr;
1041  if (UPstream::master(comm_))
1042  {
1043  // Note: always write binary. These are strings so readable anyway.
1044  // They have already be tokenised on the sending side.
1045  osPtr.reset(new OFstream(objectPath(), streamOpt));
1046  IOobject::writeHeader(*osPtr);
1047  }
1048 
1049  labelList recvSizes;
1050  gather(comm_, label(this->byteSize()), recvSizes);
1051 
1052  List<std::streamoff> start;
1053  PtrList<SubList<char>> slaveData; // dummy slave data
1054  return writeBlocks
1055  (
1056  comm_,
1057  osPtr,
1058  start,
1059  *this,
1060  recvSizes,
1061  slaveData,
1062  commsType_
1063  );
1064 }
1065 
1066 
1068 {
1069  label nBlocks = 0;
1070 
1071  IFstream is(fName);
1072  is.fatalCheck("decomposedBlockData::numBlocks(const fileName&)");
1073 
1074  if (!is.good())
1075  {
1076  return nBlocks;
1077  }
1078 
1079  // FoamFile header
1080  token firstToken(is);
1081 
1082  if
1083  (
1084  is.good()
1085  && firstToken.isWord()
1086  && firstToken.wordToken() == "FoamFile"
1087  )
1088  {
1089  dictionary headerDict(is);
1090  is.version(headerDict.get<token>("version"));
1091  is.format(headerDict.get<word>("format"));
1092 
1093  // Obtain number of blocks directly
1094  if (headerDict.readIfPresent("blocks", nBlocks))
1095  {
1096  return nBlocks;
1097  }
1098  }
1099 
1100  // Fallback to brute force read of each data block
1101  List<char> data;
1102  while (is.good())
1103  {
1104  token sizeToken(is);
1105  if (!sizeToken.isLabel())
1106  {
1107  return nBlocks;
1108  }
1109  is.putBack(sizeToken);
1110 
1111  is >> data;
1112  nBlocks++;
1113  }
1114 
1115  return nBlocks;
1116 }
1117 
1118 
1119 // ************************************************************************* //
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 (always 0)
Definition: UPstream.H:452
SubList.H
Foam::IOobject::name
const word & name() const
Return name.
Definition: IOobjectI.H:70
Foam::token::isLabel
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:481
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:53
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:696
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:87
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()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
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::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
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:1354
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:736
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:68
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
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::decomposedBlockData::numBlocks
static label numBlocks(const fileName &fName)
Detect number of blocks in a file.
Definition: decomposedBlockData.C:1067
Foam::token::isWord
bool isWord() const noexcept
Token is WORD or DIRECTIVE word.
Definition: tokenI.H:583
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
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
Foam::UPstream::subProcs
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:516
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:597
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:636
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:77
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::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::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:389
Foam::token::wordToken
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:599
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:963
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::IOobject::headerClassName
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobjectI.H:88
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:71
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:541
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:69
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::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:464
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Fstream.H
Foam::UPstream::scatter
static void scatter(const char *sendData, const UList< int > &sendSizes, const UList< int > &sendOffsets, char *recvData, int recvSize, const label communicator=worldComm)
Send data to all processors from the root of the communicator.
Definition: UPstream.C:198
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: BitOps.H:63
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:401
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:1032
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:55
Foam::Ostream::writeRaw
virtual Ostream & writeRaw(const char *data, std::streamsize count)=0
Low-level raw binary output.
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:446
Foam::UPstream::gather
static void gather(const char *sendData, int sendSize, char *recvData, const UList< int > &recvSizes, const UList< int > &recvOffsets, const label communicator=worldComm)
Receive data from all processors on the master.
Definition: UPstream.C:183
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:948
foamVersion.H