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-2021 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 "charList.H"
38 #include "labelPair.H"
40 #include "ListStream.H"
41 #include "StringStream.H"
42 
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 
45 namespace Foam
46 {
47  defineTypeNameAndDebug(decomposedBlockData, 0);
48 }
49 
50 
51 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
52 
54 (
55  const word& objectType
56 )
57 {
58  return
59  (
60  objectType == decomposedBlockData::typeName
61  );
62 }
63 
64 
66 (
67  const IOobject& io
68 )
69 {
70  return decomposedBlockData::isCollatedType(io.headerClassName());
71 }
72 
73 
74 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
75 
77 (
78  const label comm,
79  const IOobject& io,
80  const UPstream::commsTypes commsType
81 )
82 :
83  regIOobject(io),
84  commsType_(commsType),
85  comm_(comm),
86  contentData_()
87 {
88  // Temporary warning
89  if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED)
90  {
92  << "decomposedBlockData " << name()
93  << " constructed with IOobject::MUST_READ_IF_MODIFIED"
94  " but decomposedBlockData does not support automatic rereading."
95  << endl;
96  }
97  if
98  (
99  (
100  io.readOpt() == IOobject::MUST_READ
101  || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
102  )
103  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
104  )
105  {
106  read();
107  }
108 }
109 
110 
111 // * * * * * * * * * * * * * * * Members Functions * * * * * * * * * * * * * //
112 
114 (
115  Istream& is,
116  List<char>& charData
117 )
118 {
119  // Handle any of these:
120 
121  // 0. NCHARS (...)
122  // 1. List<char> NCHARS (...)
123  // 2. processorN List<char> NCHARS (...) ;
124 
126  token tok(is);
128 
129  // Dictionary format has primitiveEntry keyword:
130  const bool isDictFormat = (tok.isWord() && !tok.isCompound());
131 
132  if (!isDictFormat && tok.good())
133  {
134  is.putBack(tok);
135  }
136  charData.readList(is);
137 
138  if (isDictFormat)
139  {
141  is >> tok;
143 
144  // Swallow trailing ';'
145  if (tok.good() && !tok.isPunctuation(token::END_STATEMENT))
146  {
147  is.putBack(tok);
148  }
149  }
150 
151  return true;
152 }
153 
154 
156 (
157  OSstream& os,
158  const label blocki,
159  const UList<char>& charData
160 )
161 {
162  // Offset to the beginning of this output
163 
164  std::streamoff blockOffset = os.stdStream().tellp();
165 
166  const word procName("processor" + Foam::name(blocki));
167 
168  {
169  os << nl << "// " << procName << nl;
170  charData.writeList(os) << nl;
171  }
172 
173  return blockOffset;
174 }
175 
176 
178 (
179  OSstream& os,
180  IOstreamOption streamOptData,
181  const regIOobject& io,
182  const label blocki,
183  const bool withLocalHeader
184 )
185 {
186  // String(s) from all data to write
187  string contentChars;
188  {
189  OStringStream os(streamOptData);
190 
191  bool ok = true;
192 
193  // Generate FoamFile header on master, without comment banner
194  if (withLocalHeader)
195  {
196  const bool old = IOobject::bannerEnabled(false);
197 
198  ok = io.writeHeader(os);
199 
200  IOobject::bannerEnabled(old);
201  }
202 
203  // Write the data to the Ostream
204  ok = ok && io.writeData(os);
205 
206  if (!ok)
207  {
208  return std::streamoff(-1);
209  }
210 
211  contentChars = os.str();
212  }
213 
214  // The character data
215  UList<char> charData
216  (
217  const_cast<char*>(contentChars.data()),
218  label(contentChars.size())
219  );
220 
221  return decomposedBlockData::writeBlockEntry(os, blocki, charData);
222 }
223 
224 
227 (
228  const label blocki,
229  ISstream& is,
230  IOobject& headerIO
231 )
232 {
233  if (debug)
234  {
235  Pout<< "decomposedBlockData::readBlock:"
236  << " stream:" << is.name() << " attempt to read block " << blocki
237  << endl;
238  }
239 
240  // Extracted header information
241  IOstreamOption streamOptData;
242  unsigned labelWidth = is.labelByteSize();
243  unsigned scalarWidth = is.scalarByteSize();
244 
245  autoPtr<ISstream> realIsPtr;
246 
247  // Read master for header
249  decomposedBlockData::readBlockEntry(is, data);
250 
251  if (blocki == 0)
252  {
253  realIsPtr.reset(new IListStream(std::move(data)));
254  realIsPtr->name() = is.name();
255 
256  {
257  // Read header from first block,
258  // advancing the stream position
259  if (!headerIO.readHeader(*realIsPtr))
260  {
261  FatalIOErrorInFunction(*realIsPtr)
262  << "Problem while reading object header "
263  << is.relativeName() << nl
264  << exit(FatalIOError);
265  }
266  }
267  }
268  else
269  {
270  {
271  // Read header from first block
272  UIListStream headerStream(data);
273  if (!headerIO.readHeader(headerStream))
274  {
275  FatalIOErrorInFunction(headerStream)
276  << "Problem while reading object header "
277  << is.relativeName() << nl
278  << exit(FatalIOError);
279  }
280  streamOptData = static_cast<IOstreamOption>(headerStream);
281  labelWidth = headerStream.labelByteSize();
282  scalarWidth = headerStream.scalarByteSize();
283  }
284 
285  for (label i = 1; i < blocki+1; i++)
286  {
287  // Read and discard data, only retain the last one
288  decomposedBlockData::readBlockEntry(is, data);
289  }
290  realIsPtr.reset(new IListStream(std::move(data)));
291  realIsPtr->name() = is.name();
292 
293  // Apply stream settings
294  realIsPtr().format(streamOptData.format());
295  realIsPtr().version(streamOptData.version());
296  realIsPtr().setLabelByteSize(labelWidth);
297  realIsPtr().setScalarByteSize(scalarWidth);
298  }
299 
300  return realIsPtr;
301 }
302 
303 
305 (
306  const label comm,
307  autoPtr<ISstream>& isPtr,
308  List<char>& data,
309  const UPstream::commsTypes commsType
310 )
311 {
312  if (debug)
313  {
314  Pout<< "decomposedBlockData::readBlocks:"
315  << " stream:" << (isPtr ? isPtr->name() : "invalid")
316  << " commsType:" << Pstream::commsTypeNames[commsType]
317  << " comm:" << comm << endl;
318  }
319 
320  bool ok = false;
321 
322  if (UPstream::master(comm))
323  {
324  auto& is = *isPtr;
326 
327  // Read master data
328  decomposedBlockData::readBlockEntry(is, data);
329  }
330 
331  if (commsType == UPstream::commsTypes::scheduled)
332  {
333  if (UPstream::master(comm))
334  {
335  // Master data already read ...
336  auto& is = *isPtr;
338 
339  // Read and transmit slave data
340  for (const int proci : UPstream::subProcs(comm))
341  {
342  List<char> elems;
343  decomposedBlockData::readBlockEntry(is, elems);
344 
345  OPstream os
346  (
347  UPstream::commsTypes::scheduled,
348  proci,
349  0,
350  UPstream::msgType(),
351  comm
352  );
353  os << elems;
354  }
355 
356  ok = is.good();
357  }
358  else
359  {
360  IPstream is
361  (
362  UPstream::commsTypes::scheduled,
363  UPstream::masterNo(),
364  0,
365  UPstream::msgType(),
366  comm
367  );
368  is >> data;
369  }
370  }
371  else
372  {
373  PstreamBuffers pBufs
374  (
375  UPstream::commsTypes::nonBlocking,
376  UPstream::msgType(),
377  comm
378  );
379 
380  if (UPstream::master(comm))
381  {
382  // Master data already read ...
383  auto& is = *isPtr;
385 
386  // Read and transmit slave data
387  for (const int proci : UPstream::subProcs(comm))
388  {
389  List<char> elems;
390  decomposedBlockData::readBlockEntry(is, elems);
391 
392  UOPstream os(proci, pBufs);
393  os << elems;
394  }
395  }
396 
397  labelList recvSizes;
398  pBufs.finishedSends(recvSizes);
399 
400  if (!UPstream::master(comm))
401  {
402  UIPstream is(UPstream::masterNo(), pBufs);
403  is >> data;
404  }
405  }
406 
407  Pstream::scatter(ok, Pstream::msgType(), comm);
408 
409  return ok;
410 }
411 
412 
414 (
415  const label comm,
416  const fileName& fName,
417  autoPtr<ISstream>& isPtr,
418  IOobject& headerIO,
419  const UPstream::commsTypes commsType
420 )
421 {
422  if (debug)
423  {
424  Pout<< "decomposedBlockData::readBlocks:"
425  << " stream:" << (isPtr ? isPtr->name() : "invalid")
426  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
427  }
428 
429  bool ok = false;
431  autoPtr<ISstream> realIsPtr;
432 
433  if (UPstream::master(comm))
434  {
435  auto& is = *isPtr;
437 
438  // Read master data
439  decomposedBlockData::readBlockEntry(is, data);
440 
441  realIsPtr.reset(new IListStream(std::move(data)));
442  realIsPtr->name() = fName;
443 
444  {
445  // Read header from first block,
446  // advancing the stream position
447  if (!headerIO.readHeader(*realIsPtr))
448  {
449  FatalIOErrorInFunction(*realIsPtr)
450  << "Problem while reading object header "
451  << is.relativeName() << nl
452  << exit(FatalIOError);
453  }
454  }
455  }
456 
457  if (commsType == UPstream::commsTypes::scheduled)
458  {
459  if (UPstream::master(comm))
460  {
461  // Master data already read ...
462  auto& is = *isPtr;
464 
465  // Read and transmit slave data
466  for (const int proci : UPstream::subProcs(comm))
467  {
468  decomposedBlockData::readBlockEntry(is, data);
469 
470  OPstream os
471  (
472  UPstream::commsTypes::scheduled,
473  proci,
474  0,
475  UPstream::msgType(),
476  comm
477  );
478  os << data;
479  }
480 
481  ok = is.good();
482  }
483  else
484  {
485  IPstream is
486  (
487  UPstream::commsTypes::scheduled,
488  UPstream::masterNo(),
489  0,
490  UPstream::msgType(),
491  comm
492  );
493  is >> data;
494 
495  realIsPtr.reset(new IListStream(std::move(data)));
496  realIsPtr->name() = fName;
497  }
498  }
499  else
500  {
501  PstreamBuffers pBufs
502  (
503  UPstream::commsTypes::nonBlocking,
504  UPstream::msgType(),
505  comm
506  );
507 
508  if (UPstream::master(comm))
509  {
510  // Master data already read ...
511  auto& is = *isPtr;
513 
514  // Read and transmit slave data
515  for (const int proci : UPstream::subProcs(comm))
516  {
517  List<char> elems;
518  decomposedBlockData::readBlockEntry(is, elems);
519 
520  UOPstream os(proci, pBufs);
521  os << elems;
522  }
523 
524  ok = is.good();
525  }
526 
527  labelList recvSizes;
528  pBufs.finishedSends(recvSizes);
529 
530  if (!UPstream::master(comm))
531  {
532  UIPstream is(UPstream::masterNo(), pBufs);
533  is >> data;
534 
535  realIsPtr.reset(new IListStream(std::move(data)));
536  realIsPtr->name() = fName;
537  }
538  }
539 
540  Pstream::scatter(ok, Pstream::msgType(), comm);
541 
542  //- Set stream properties from realIsPtr on master
543 
544  // Scatter master header info
545  int verValue;
546  int fmtValue;
547  unsigned labelWidth;
548  unsigned scalarWidth;
549  if (UPstream::master(comm))
550  {
551  verValue = realIsPtr().version().canonical();
552  fmtValue = static_cast<int>(realIsPtr().format());
553  labelWidth = realIsPtr().labelByteSize();
554  scalarWidth = realIsPtr().scalarByteSize();
555  }
556  Pstream::scatter(verValue); //, Pstream::msgType(), comm);
557  Pstream::scatter(fmtValue); //, Pstream::msgType(), comm);
558  Pstream::scatter(labelWidth); //, Pstream::msgType(), comm);
559  Pstream::scatter(scalarWidth); //, Pstream::msgType(), comm);
560 
561  realIsPtr().version(IOstreamOption::versionNumber::canonical(verValue));
562  realIsPtr().format(IOstreamOption::streamFormat(fmtValue));
563  realIsPtr().setLabelByteSize(labelWidth);
564  realIsPtr().setScalarByteSize(scalarWidth);
565 
566  word name(headerIO.name());
567  Pstream::scatter(name, Pstream::msgType(), comm);
568  headerIO.rename(name);
569  Pstream::scatter(headerIO.headerClassName(), Pstream::msgType(), comm);
570  Pstream::scatter(headerIO.note(), Pstream::msgType(), comm);
571  //Pstream::scatter(headerIO.instance(), Pstream::msgType(), comm);
572  //Pstream::scatter(headerIO.local(), Pstream::msgType(), comm);
573 
574  return realIsPtr;
575 }
576 
577 
579 (
580  const label comm,
581  const label data,
582  labelList& datas
583 )
584 {
585  const label nProcs = UPstream::nProcs(comm);
586  datas.resize(nProcs);
587 
588  char* data0Ptr = datas.data_bytes();
589 
590  List<int> recvOffsets;
591  List<int> recvSizes;
592  if (UPstream::master(comm))
593  {
594  recvOffsets.setSize(nProcs);
595  forAll(recvOffsets, proci)
596  {
597  // Note: truncating long int to int since UPstream::gather limited
598  // to ints
599  recvOffsets[proci] =
600  int(reinterpret_cast<char*>(&datas[proci]) - data0Ptr);
601  }
602  recvSizes.setSize(nProcs, sizeof(label));
603  }
604 
605  UPstream::gather
606  (
607  reinterpret_cast<const char*>(&data),
608  sizeof(label),
609  data0Ptr,
610  recvSizes,
611  recvOffsets,
612  comm
613  );
614 }
615 
616 
618 (
619  const label comm,
620  const UList<char>& data,
621  const labelUList& recvSizes,
622 
623  const label startProc,
624  const label nProcs,
625 
626  List<int>& sliceOffsets,
627  List<char>& recvData
628 )
629 {
630  // Calculate master data
631  List<int> sliceSizes;
632  if (UPstream::master(comm))
633  {
634  const label numProcs = UPstream::nProcs(comm);
635 
636  sliceSizes.resize(numProcs, 0);
637  sliceOffsets.resize(numProcs+1, 0);
638 
639  int totalSize = 0;
640  label proci = startProc;
641  for (label i = 0; i < nProcs; i++)
642  {
643  sliceSizes[proci] = int(recvSizes[proci]);
644  sliceOffsets[proci] = totalSize;
645  totalSize += sliceSizes[proci];
646  ++proci;
647  }
648  sliceOffsets[proci] = totalSize;
649  recvData.setSize(totalSize);
650  }
651 
652  int nSend = 0;
653  if
654  (
655  !UPstream::master(comm)
656  && (UPstream::myProcNo(comm) >= startProc)
657  && (UPstream::myProcNo(comm) < startProc+nProcs)
658  )
659  {
660  // Note: UPstream::gather limited to int
661  nSend = int(data.size_bytes());
662  }
663 
664  UPstream::gather
665  (
666  data.cdata(),
667  nSend,
668 
669  recvData.data(),
670  sliceSizes,
671  sliceOffsets,
672  comm
673  );
674 }
675 
676 
678 (
679  const label comm,
680  const off_t maxBufferSize,
681  const labelUList& recvSizes,
682  const label startProci
683 )
684 {
685  const label nProcs = UPstream::nProcs(comm);
686 
687  label nSendProcs = -1;
688  if (UPstream::master(comm))
689  {
690  off_t totalSize = recvSizes[startProci];
691  label proci = startProci+1;
692  while (proci < nProcs && (totalSize+recvSizes[proci] < maxBufferSize))
693  {
694  totalSize += recvSizes[proci];
695  proci++;
696  }
697 
698  nSendProcs = proci-startProci;
699  }
700 
701  // Scatter nSendProcs
702  label n;
703  UPstream::scatter
704  (
705  reinterpret_cast<const char*>(&nSendProcs),
706  List<int>(nProcs, sizeof(nSendProcs)),
707  List<int>(nProcs, Zero),
708  reinterpret_cast<char*>(&n),
709  sizeof(n),
710  comm
711  );
712 
713  return n;
714 }
715 
716 
718 (
719  const label comm,
720  autoPtr<OSstream>& osPtr,
721  List<std::streamoff>& blockOffset,
722  const UList<char>& masterData,
723 
724  const labelUList& recvSizes,
725  const PtrList<SubList<char>>& slaveData,
726 
727  const UPstream::commsTypes commsType,
728  const bool syncReturnState
729 )
730 {
731  if (debug)
732  {
733  Pout<< "decomposedBlockData::writeBlocks:"
734  << " stream:" << (osPtr ? osPtr->name() : "invalid")
735  << " data:" << masterData.size()
736  << " (master only) slaveData:" << slaveData.size()
737  << " commsType:" << Pstream::commsTypeNames[commsType] << endl;
738  }
739 
740  const label nProcs = UPstream::nProcs(comm);
741 
742  bool ok = true;
743 
744  // Write master data
745  if (UPstream::master(comm))
746  {
747  blockOffset.resize(nProcs);
748 
749  OSstream& os = *osPtr;
750 
751  blockOffset[UPstream::masterNo()] =
752  decomposedBlockData::writeBlockEntry
753  (
754  os,
755  UPstream::masterNo(),
756  masterData
757  );
758 
759  ok = os.good();
760  }
761 
762  if (slaveData.size())
763  {
764  // Already have gathered the slave data.
765 
766  if (UPstream::master(comm))
767  {
768  // Master data already written ...
769  OSstream& os = *osPtr;
770 
771  // Write slaves
772  for (label proci = 1; proci < nProcs; ++proci)
773  {
774  blockOffset[proci] =
775  decomposedBlockData::writeBlockEntry
776  (
777  os,
778  proci,
779  slaveData[proci]
780  );
781  }
782 
783  ok = os.good();
784  }
785  }
786  else if (commsType == UPstream::commsTypes::scheduled)
787  {
788  if (UPstream::master(comm))
789  {
790  // Master data already written ...
791  OSstream& os = *osPtr;
792 
793  // Receive and write slaves
794  DynamicList<char> elems;
795  for (label proci = 1; proci < nProcs; ++proci)
796  {
797  elems.resize(recvSizes[proci]);
799  (
800  UPstream::commsTypes::scheduled,
801  proci,
802  elems.data(),
803  elems.size_bytes(),
804  Pstream::msgType(),
805  comm
806  );
807 
808  blockOffset[proci] =
809  decomposedBlockData::writeBlockEntry
810  (
811  os,
812  proci,
813  elems
814  );
815  }
816 
817  ok = os.good();
818  }
819  else
820  {
822  (
823  UPstream::commsTypes::scheduled,
824  UPstream::masterNo(),
825  masterData.cdata(),
826  masterData.size_bytes(),
827  Pstream::msgType(),
828  comm
829  );
830  }
831  }
832  else
833  {
834  // Master data already written ...
835 
836  // Find out how many processor can be received into
837  // maxMasterFileBufferSize
838 
839  // Starting slave processor and number of processors
840  label startProc = 1;
841  label nSendProcs = nProcs-1;
842 
843  while (nSendProcs > 0 && startProc < nProcs)
844  {
845  nSendProcs = calcNumProcs
846  (
847  comm,
848  off_t
849  (
851  maxMasterFileBufferSize
852  ),
853  recvSizes,
854  startProc
855  );
856 
857  if (nSendProcs == 0)
858  {
859  break;
860  }
861 
862 
863  // Gather data from (a slice of) the slaves
864  List<int> sliceOffsets;
865  List<char> recvData;
866  gatherSlaveData
867  (
868  comm,
869  masterData,
870  recvSizes,
871 
872  startProc, // startProc,
873  nSendProcs, // nProcs,
874 
875  sliceOffsets,
876  recvData
877  );
878 
879  if (UPstream::master(comm))
880  {
881  OSstream& os = *osPtr;
882 
883  // Write slaves
884  for
885  (
886  label proci = startProc;
887  proci < startProc+nSendProcs;
888  ++proci
889  )
890  {
891  SubList<char> dataSlice
892  (
893  recvData,
894  sliceOffsets[proci+1]-sliceOffsets[proci],
895  sliceOffsets[proci]
896  );
897 
898  blockOffset[proci] =
899  decomposedBlockData::writeBlockEntry
900  (
901  os,
902  proci,
903  dataSlice
904  );
905  }
906  }
907 
908  startProc += nSendProcs;
909  }
910 
911  if (UPstream::master(comm))
912  {
913  ok = osPtr->good();
914  }
915  }
916 
917  if (syncReturnState)
918  {
919  //- Enable to get synchronised error checking. Is the one that keeps
920  // slaves as slow as the master (which does all the writing)
921  Pstream::scatter(ok, Pstream::msgType(), comm);
922  }
923 
924  return ok;
925 }
926 
927 
929 {
930  autoPtr<ISstream> isPtr;
931  fileName objPath(fileHandler().filePath(false, *this, word::null));
932  if (UPstream::master(comm_))
933  {
934  isPtr.reset(new IFstream(objPath));
935  IOobject::readHeader(*isPtr);
936  }
937 
938  return readBlocks(comm_, isPtr, contentData_, commsType_);
939 }
940 
941 
943 {
944  IOobject io(*this);
945  IOstreamOption streamOpt(os);
946 
947  int verValue;
948  int fmtValue;
949 
950  // Re-read my own data to find out the header information
951  if (Pstream::master(comm_))
952  {
953  UIListStream headerStream(contentData_);
954  io.readHeader(headerStream);
955 
956  verValue = headerStream.version().canonical();
957  fmtValue = static_cast<int>(headerStream.format());
958  }
959 
960  // Scatter header information
961  Pstream::scatter(verValue, Pstream::msgType(), comm_);
962  Pstream::scatter(fmtValue, Pstream::msgType(), comm_);
963 
965  streamOpt.format(IOstreamOption::streamFormat(fmtValue));
966 
967  //word masterName(name());
968  //Pstream::scatter(masterName, Pstream::msgType(), comm_);
969 
971  Pstream::scatter(io.note(), Pstream::msgType(), comm_);
972  //Pstream::scatter(io.instance(), Pstream::msgType(), comm);
973  //Pstream::scatter(io.local(), Pstream::msgType(), comm);
974 
975  fileName masterLocation(instance()/db().dbDir()/local());
976  Pstream::scatter(masterLocation, Pstream::msgType(), comm_);
977 
978  if (!Pstream::master(comm_))
979  {
981  (
982  os,
983  streamOpt, // streamOpt for data
984  io.headerClassName(),
985  io.note(),
986  masterLocation,
987  name(),
988  dictionary()
989  );
990  }
991 
992  // Write the character data
993  if (isA<OFstream>(os))
994  {
995  // Serial file output - can use writeRaw()
996  os.writeRaw(contentData_.cdata(), contentData_.size_bytes());
997  }
998  else
999  {
1000  // Other cases are less fortunate, and no std::string_view
1001  std::string str(contentData_.cdata(), contentData_.size_bytes());
1002  os.writeQuoted(str, false);
1003  }
1004 
1005  if (!Pstream::master(comm_))
1006  {
1008  }
1009 
1010  return os.good();
1011 }
1012 
1013 
1016  IOstreamOption streamOpt,
1017  const bool valid
1018 ) const
1019 {
1020  autoPtr<OSstream> osPtr;
1021  if (UPstream::master(comm_))
1022  {
1023  // Note: always write binary. These are strings so readable anyway.
1024  // They have already be tokenised on the sending side.
1025 
1026  osPtr.reset(new OFstream(objectPath(), IOstreamOption::BINARY));
1027 
1028  // Update meta-data for current state
1029  const_cast<regIOobject&>
1030  (
1031  static_cast<const regIOobject&>(*this)
1032  ).updateMetaData();
1033 
1035  (
1036  *osPtr,
1037  streamOpt, // streamOpt for data
1038  static_cast<const IOobject&>(*this)
1039  );
1040  }
1041 
1042  labelList recvSizes;
1043  gather(comm_, label(contentData_.size_bytes()), recvSizes);
1044 
1045  List<std::streamoff> blockOffsets;
1046  PtrList<SubList<char>> slaveData; // dummy slave data
1047  return writeBlocks
1048  (
1049  comm_,
1050  osPtr,
1051  blockOffsets,
1052  contentData_,
1053  recvSizes,
1054  slaveData,
1055  commsType_
1056  );
1057 }
1058 
1059 
1060 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::DynamicList::resize
void resize(const label len)
Definition: DynamicListI.H:353
Foam::UList::writeList
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition: UListIO.C:79
Foam::UIListStream
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
Definition: UIListStream.H:201
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::decomposedBlockData::comm_
const label comm_
Communicator for all parallel comms.
Definition: decomposedBlockData.H:128
Foam::decomposedBlockData::writeHeader
static void writeHeader(Ostream &os, IOstreamOption streamOptContainer, const word &objectType, const string &note, const fileName &location, const word &objectName, const dictionary &extraEntries)
Helper: write FoamFile IOobject header.
Definition: decomposedBlockDataHeader.C:137
SubList.H
Foam::decomposedBlockData::contentData_
List< char > contentData_
The block content.
Definition: decomposedBlockData.H:131
Foam::UList::cdata
const T * cdata() const noexcept
Return pointer to the underlying array serving as data storage.
Definition: UListI.H:230
Foam::IOstreamOption::versionNumber::canonical
int canonical() const noexcept
From version to canonical integer value.
Definition: IOstreamOption.H:137
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
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:73
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::List::readList
Istream & readList(Istream &is)
Read List from Istream, discarding contents of existing List.
Definition: ListIO.C:49
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::DynamicList< char >
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
Foam::IOobject::writeEndDivider
static Ostream & writeEndDivider(Ostream &os)
Write the standard end file divider.
Definition: IOobjectWriteHeader.C:142
Foam::regIOobject::writeData
virtual bool writeData(Ostream &) const =0
Pure virtual writeData function.
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
Foam::decomposedBlockData::calcNumProcs
static label calcNumProcs(const label comm, const off_t maxBufferSize, const labelUList &recvSizes, const label startProci)
Definition: decomposedBlockData.C:678
Foam::OBJstream::writeQuoted
virtual Ostream & writeQuoted(const std::string &str, const bool quoted=true)
Write std::string surrounded by quotes.
Definition: OBJstream.C:108
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:88
charList.H
objectRegistry.H
Foam::IOstream::fatalCheck
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
OPstream.H
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
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. Always UNCOMPRESSED.
Definition: IListStream.H:132
StringStream.H
Input/output from string buffers.
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1485
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::IOobject::headerClassName
const word & headerClassName() const noexcept
Return name of the class name read from header.
Definition: IOobjectI.H:83
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::OSstream::writeRaw
virtual Ostream & writeRaw(const char *data, std::streamsize count)
Low-level raw binary output.
Definition: OSstream.C:251
ListStream.H
Input/output streams with managed List storage.
Foam::token::isWord
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE)
Definition: tokenI.H:609
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::IOstream::good
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:233
Foam::IOobject::readHeader
bool readHeader(Istream &is)
Definition: IOobjectReadHeader.C:165
Foam::IOstream::labelByteSize
unsigned labelByteSize() const noexcept
The sizeof (label) in bytes associated with the stream.
Definition: IOstream.H:272
Foam::decomposedBlockData::writeBlocks
static bool writeBlocks(const label comm, autoPtr< OSstream > &osPtr, List< std::streamoff > &blockOffset, 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.
Definition: decomposedBlockData.C:718
Foam::blockMeshTools::read
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:57
n
label n
Definition: TABSMDCalcMethod2.H:31
IPstream.H
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::decomposedBlockData::readBlocks
static bool readBlocks(const label comm, autoPtr< ISstream > &isPtr, List< char > &contentChars, const UPstream::commsTypes commsType)
Read data into *this. ISstream is only valid on master.
Definition: decomposedBlockData.C:305
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:579
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.
Definition: decomposedBlockData.C:618
Foam::autoPtr::good
bool good() const noexcept
True if the managed pointer is non-null.
Definition: autoPtr.H:145
Foam::decomposedBlockData::commsType_
const UPstream::commsTypes commsType_
Type to use for gather.
Definition: decomposedBlockData.H:125
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:59
Foam::ISstream::name
virtual const fileName & name() const
Return the name of the stream.
Definition: ISstream.H:113
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done.
Definition: PstreamBuffers.C:73
Foam::IOstreamOption::version
versionNumber version() const noexcept
Get the stream version.
Definition: IOstreamOption.H:338
Foam::decomposedBlockData::readBlockEntry
static bool readBlockEntry(Istream &is, List< char > &charData)
Helper: read block of (binary) character data.
Definition: decomposedBlockData.C:114
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:123
Foam::decomposedBlockData::decomposedBlockData
decomposedBlockData(const label comm, const IOobject &io, const UPstream::commsTypes=UPstream::commsTypes::scheduled)
Construct given an IOobject.
Definition: decomposedBlockData.C:77
Foam::decomposedBlockData::isCollatedType
static bool isCollatedType(const word &objectType)
True if object type is a known collated type.
Definition: decomposedBlockData.C:54
os
OBJstream os(runTime.globalPath()/outputName)
Foam::IOstream::relativeName
fileName relativeName() const
Return the name of the stream relative to the current case.
Definition: IOstream.C:52
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::IOobject::rename
virtual void rename(const word &newName)
Rename.
Definition: IOobject.H:506
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::decomposedBlockData::writeData
virtual bool writeData(Ostream &os) const
Write separated content (assumes content is the serialised data)
Definition: decomposedBlockData.C:942
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Foam::IOobject::readOpt
readOption readOpt() const noexcept
The read option.
Definition: IOobjectI.H:164
Foam::token::good
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:405
Foam::autoPtr::reset
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:69
Foam::autoPtr< Foam::ISstream >
Foam::IOobject::note
const string & note() const noexcept
Return the optional note.
Definition: IOobjectI.H:95
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:73
Foam::fileOperations::masterUncollatedFileOperation
fileOperations that performs all file operations on the master processor. Requires the calls to be pa...
Definition: masterUncollatedFileOperation.H:84
Foam::IOstreamOption::BINARY
"binary"
Definition: IOstreamOption.H:73
masterUncollatedFileOperation.H
Foam::UPstream::msgType
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:540
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Fstream.H
Foam::decomposedBlockData::writeBlockEntry
static std::streamoff writeBlockEntry(OSstream &os, const label blocki, const UList< char > &charData)
Helper: write block of (binary) character data.
Definition: decomposedBlockData.C:156
decomposedBlockData.H
Foam::List< char >
Foam::OStringStream
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:227
Foam::Istream::putBack
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
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
Foam::regIOobject::filePath
virtual fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:430
dictionary.H
Foam::decomposedBlockData::readBlock
static autoPtr< ISstream > readBlock(const label blocki, ISstream &is, IOobject &headerIO)
Read selected block (non-seeking) + header information.
Definition: decomposedBlockData.C:227
PstreamBuffers.H
Foam::word::null
static const word null
An empty word.
Definition: word.H:80
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::token::isCompound
bool isCompound() const noexcept
Token is COMPOUND.
Definition: tokenI.H:716
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:36
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::IOstream::scalarByteSize
unsigned scalarByteSize() const noexcept
The sizeof (scalar) in bytes associated with the stream.
Definition: IOstream.H:278
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
Foam::IOobject::writeHeader
bool writeHeader(Ostream &os) const
Write header with current type()
Definition: IOobjectWriteHeader.C:277
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
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::decomposedBlockData::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
Definition: decomposedBlockData.C:1015
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:55
Foam::UList::size_bytes
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:258
labelPair.H
Foam::decomposedBlockData::read
virtual bool read()
Read object.
Definition: decomposedBlockData.C:928