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-------------------------------------------------------------------------------
11License
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
39template<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
52template<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
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
142template<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
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())
176 // Two or more entries, and all entries have identical values.
178 }
179 else if (len < shortLen && is_contiguous<Type>::value)
180 {
181 // Write start contents delimiter
183
184 label idx = 0;
185
186 // Loop over rows
187 for (label i = 0; i < mat.nRows(); ++i)
188 {
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
199 }
200
201 // Write end of contents delimiter
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
233 }
234 }
235
237 return os;
238}
239
240
241// ************************************************************************* //
streamFormat format() const noexcept
Get the current stream format.
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition: Istream.C:169
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition: Istream.C:148
A templated (m x n) matrix of objects of <T>. The layout is (mRows x nCols) - row-major order:
Definition: Matrix.H:81
const Type * cdata() const noexcept
Definition: MatrixI.H:202
bool readMatrix(Istream &is)
Read Matrix from Istream, discarding existing contents.
Definition: MatrixIO.C:53
Ostream & writeMatrix(Ostream &os, const label shortLen=0) const
Definition: MatrixIO.C:144
label size() const
The number of elements in Matrix (m*n)
Definition: MatrixI.H:110
label nCols() const noexcept
The number of columns - same as n()
Definition: Matrix.H:525
label nRows() const noexcept
The number of rows - same as m()
Definition: Matrix.H:519
bool uniform() const
True if all entries have identical values, and Matrix is non-empty.
Definition: MatrixI.H:180
const char * cdata_bytes() const noexcept
Definition: MatrixI.H:216
Matrix() noexcept
Default construct (empty matrix)
Definition: MatrixI.H:49
std::streamsize size_bytes() const noexcept
Definition: MatrixI.H:230
virtual Ostream & write(const char c)
Write character.
Definition: OBJstream.C:78
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A token holds an item read from Istream.
Definition: token.H:69
@ BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:159
@ END_BLOCK
End block [isseparator].
Definition: token.H:160
@ BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
@ END_LIST
End list [isseparator].
Definition: token.H:156
@ SPACE
Space [isspace].
Definition: token.H:125
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
label labelToken() const
Return label value.
Definition: tokenI.H:513
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
patchWriters clear()
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
IOerror FatalIOError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:78