MatrixIO.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019-2022 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 "Matrix.H"
30 #include "Istream.H"
31 #include "Ostream.H"
32 #include "token.H"
33 #include "contiguous.H"
34 #include "ListPolicy.H"
35 
36 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
37 
38 template<class Form, class Type>
40 :
41  mRows_(0),
42  nCols_(0),
43  v_(nullptr)
44 {
45  this->readMatrix(is);
46 }
47 
48 
49 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
50 
51 template<class Form, class Type>
53 {
54  // Anull matrix
55  clear();
56 
58 
59  token firstToken(is);
60 
61  is.fatalCheck("readMatrix : reading first token");
62 
63  if (firstToken.isLabel())
64  {
65  mRows_ = firstToken.labelToken();
66  nCols_ = readLabel(is);
67  doAlloc();
68 
69  // The total size
70  const label len = size();
71 
72  if (is.format() == IOstreamOption::BINARY && is_contiguous<Type>::value)
73  {
74  // Binary and contiguous
75 
76  if (len)
77  {
78  Detail::readContiguous<Type>
79  (
80  is,
81  this->data_bytes(),
82  this->size_bytes()
83  );
84 
85  is.fatalCheck("readMatrix : reading the binary block");
86  }
87 
88  }
89  else
90  {
91  // Begin of contents marker
92  char listDelimiter = is.readBeginList("Matrix");
93 
94  if (len)
95  {
96  if (listDelimiter == token::BEGIN_LIST)
97  {
98  label idx = 0;
99 
100  // Loop over rows
101  for (label i = 0; i < mRows_; ++i)
102  {
103  listDelimiter = is.readBeginList("MatrixRow");
104 
105  for (label j = 0; j < nCols_; ++j)
106  {
107  is >> v_[idx++];
108  is.fatalCheck("readMatrix : reading entry");
109  }
110 
111  is.readEndList("MatrixRow");
112  }
113  }
114  else // BEGIN_BLOCK
115  {
116  Type element;
117  is >> element;
118 
119  is.fatalCheck("readMatrix : reading the single entry");
120 
121  std::fill(begin(), end(), element);
122  }
123  }
124 
125  // End of contents marker
126  is.readEndList("Matrix");
127  }
128 
129  return len;
130  }
131 
133  << "incorrect first token, expected <int>, found "
134  << firstToken.info() << nl
135  << exit(FatalIOError);
137  return 0;
138 }
139 
140 
141 template<class Form, class Type>
143 (
144  Ostream& os,
145  const label shortLen
146 ) const
147 {
148  const Matrix<Form, Type>& mat = *this;
149 
150  // The total size
151  const label len = mat.size();
152 
153  // Rows, columns size
154  os << mat.nRows() << token::SPACE << mat.nCols();
155 
156  if (os.format() == IOstreamOption::BINARY && is_contiguous<Type>::value)
157  {
158  // Binary and contiguous
159 
160  if (len)
161  {
162  // write(...) includes surrounding start/end delimiters
163  os.write(mat.cdata_bytes(), mat.size_bytes());
164  }
165  }
166  else
167  {
168  if (len)
169  {
170  const Type* v = mat.cdata();
171 
172  // Can the contents be considered 'uniform' (ie, identical)
173  if (len > 1 && is_contiguous<Type>::value && mat.uniform())
174  {
175  // Two or more entries, and all entries have identical values.
176  os << token::BEGIN_BLOCK << v[0] << token::END_BLOCK;
177  }
178  else if (len < shortLen && is_contiguous<Type>::value)
179  {
180  // Write start contents delimiter
181  os << token::BEGIN_LIST;
182 
183  label idx = 0;
184 
185  // Loop over rows
186  for (label i = 0; i < mat.nRows(); ++i)
187  {
188  os << token::BEGIN_LIST;
189 
190  // Write row
191  for (label j = 0; j < mat.nCols(); ++j)
192  {
193  if (j) os << token::SPACE;
194  os << v[idx++];
195  }
196 
197  os << token::END_LIST;
198  }
199 
200  // Write end of contents delimiter
201  os << token::END_LIST;
202  }
203  else
204  {
205  // Write start contents delimiter
206  os << nl << token::BEGIN_LIST;
207 
208  label idx = 0;
209 
210  // Loop over rows
211  for (label i=0; i < mat.nRows(); ++i)
212  {
213  os << nl << token::BEGIN_LIST;
214 
215  // Write row
216  for (label j = 0; j < mat.nCols(); ++j)
217  {
218  os << nl << v[idx++];
219  }
220 
221  os << nl << token::END_LIST;
222  }
223 
224  // Write end of contents delimiter
225  os << nl << token::END_LIST << nl;
226  }
227  }
228  else
229  {
230  // Empty matrix
231  os << token::BEGIN_LIST << token::END_LIST << nl;
232  }
233  }
234 
235  os.check(FUNCTION_NAME);
236  return os;
237 }
238 
239 
240 // ************************************************************************* //
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
char readEndList(const char *funcName)
End read of list data, ends with &#39;)&#39; or &#39;}&#39;.
Definition: Istream.C:162
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
A token holds an item read from Istream.
Definition: token.H:64
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:63
bool readMatrix(Istream &is)
Read Matrix from Istream, discarding existing contents.
Definition: MatrixIO.C:45
label nCols() const noexcept
The number of columns - same as n()
Definition: Matrix.H:736
Ostream & writeMatrix(Ostream &os, const label shortLen=0) const
Write Matrix, with line-breaks in ASCII when length exceeds shortLen.
Definition: MatrixIO.C:136
label size() const
The number of elements in Matrix (m*n)
Definition: MatrixI.H:103
label nRows() const noexcept
The number of rows - same as m()
Definition: Matrix.H:728
bool uniform() const
True if all entries have identical values, and Matrix is non-empty.
Definition: MatrixI.H:173
patchWriters clear()
char readBeginList(const char *funcName)
Begin read of list data, starts with &#39;(&#39; or &#39;{&#39;.
Definition: Istream.C:141
const Type * cdata() const noexcept
Return const pointer to the first data element, which can also be used to address into Matrix content...
Definition: MatrixI.H:195
A templated (m x n) matrix of objects of <T>. The layout is (mRows x nCols) - row-major order: ...
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the Matrix data, no runtime check that the type is actually contiguous...
Definition: MatrixI.H:223
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:194
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage, reinterpreted as byte data...
Definition: MatrixI.H:209
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:51
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
A template class to specify that a data type can be considered as being contiguous in memory...
Definition: contiguous.H:70
Matrix() noexcept
Default construct (empty matrix)
Definition: MatrixI.H:42
constexpr auto begin(C &c) -> decltype(c.begin())
Return iterator to the beginning of the container c.
Definition: stdFoam.H:161
streamFormat format() const noexcept
Get the current stream format.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...