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