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 | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Matrix.H"
27 #include "Istream.H"
28 #include "Ostream.H"
29 #include "token.H"
30 #include "contiguous.H"
31 
32 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
33 
34 template<class Form, class Type>
36 :
37  n_(0),
38  m_(0),
39  v_(NULL)
40 {
41  operator>>(is, *this);
42 }
43 
44 
45 template<class Form, class Type>
47 {
48  // Anull matrix
49  M.clear();
50 
51  is.fatalCheck("operator>>(Istream&, Matrix<Form, Type>&)");
52 
53  token firstToken(is);
54 
55  is.fatalCheck
56  (
57  "operator>>(Istream&, Matrix<Form, Type>&) : reading first token"
58  );
59 
60  if (firstToken.isLabel())
61  {
62  M.n_ = firstToken.labelToken();
63  M.m_ = readLabel(is);
64 
65  label nm = M.n_*M.m_;
66 
67  // Read list contents depending on data format
68  if (is.format() == IOstream::ASCII || !contiguous<Type>())
69  {
70  // Read beginning of contents
71  char listDelimiter = is.readBeginList("Matrix");
72 
73  if (nm)
74  {
75  M.allocate();
76  Type* v = M.v_[0];
77 
78  if (listDelimiter == token::BEGIN_LIST)
79  {
80  label k = 0;
81 
82  // loop over rows
83  for (label i=0; i<M.n(); i++)
84  {
85  listDelimiter = is.readBeginList("MatrixRow");
86 
87  for (label j=0; j<M.m(); j++)
88  {
89  is >> v[k++];
90 
91  is.fatalCheck
92  (
93  "operator>>(Istream&, Matrix<Form, Type>&) : "
94  "reading entry"
95  );
96  }
97 
98  is.readEndList("MatrixRow");
99  }
100  }
101  else
102  {
103  Type element;
104  is >> element;
105 
106  is.fatalCheck
107  (
108  "operator>>(Istream&, Matrix<Form, Type>&) : "
109  "reading the single entry"
110  );
111 
112  for (label i=0; i<nm; i++)
113  {
114  v[i] = element;
115  }
116  }
117  }
118 
119  // Read end of contents
120  is.readEndList("Matrix");
121  }
122  else
123  {
124  if (nm)
125  {
126  M.allocate();
127  Type* v = M.v_[0];
128 
129  is.read(reinterpret_cast<char*>(v), nm*sizeof(Type));
130 
131  is.fatalCheck
132  (
133  "operator>>(Istream&, Matrix<Form, Type>&) : "
134  "reading the binary block"
135  );
136  }
137  }
138  }
139  else
140  {
141  FatalIOErrorIn("operator>>(Istream&, Matrix<Form, Type>&)", is)
142  << "incorrect first token, expected <int>, found "
143  << firstToken.info()
144  << exit(FatalIOError);
145  }
146 
147  return is;
148 }
149 
150 
151 template<class Form, class Type>
152 Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<Form, Type>& M)
153 {
154  label nm = M.n_*M.m_;
155 
156  os << M.n() << token::SPACE << M.m();
157 
158  // Write list contents depending on data format
159  if (os.format() == IOstream::ASCII || !contiguous<Type>())
160  {
161  if (nm)
162  {
163  bool uniform = false;
164 
165  const Type* v = M.v_[0];
166 
167  if (nm > 1 && contiguous<Type>())
168  {
169  uniform = true;
170 
171  for (label i=0; i< nm; i++)
172  {
173  if (v[i] != v[0])
174  {
175  uniform = false;
176  break;
177  }
178  }
179  }
180 
181  if (uniform)
182  {
183  // Write size of list and start contents delimiter
184  os << token::BEGIN_BLOCK;
185 
186  // Write list contents
187  os << v[0];
188 
189  // Write end of contents delimiter
190  os << token::END_BLOCK;
191  }
192  else if (nm < 10 && contiguous<Type>())
193  {
194  // Write size of list and start contents delimiter
195  os << token::BEGIN_LIST;
196 
197  label k = 0;
198 
199  // loop over rows
200  for (label i=0; i< M.n(); i++)
201  {
202  os << token::BEGIN_LIST;
203 
204  // Write row
205  for (label j=0; j< M.m(); j++)
206  {
207  if (j > 0) os << token::SPACE;
208  os << v[k++];
209  }
210 
211  os << token::END_LIST;
212  }
213 
214  // Write end of contents delimiter
215  os << token::END_LIST;
216  }
217  else
218  {
219  // Write size of list and start contents delimiter
220  os << nl << token::BEGIN_LIST;
221 
222  label k = 0;
223 
224  // loop over rows
225  for (label i=0; i< M.n(); i++)
226  {
227  os << nl << token::BEGIN_LIST;
228 
229  // Write row
230  for (label j=0; j< M.m(); j++)
231  {
232  os << nl << v[k++];
233  }
234 
235  os << nl << token::END_LIST;
236  }
237 
238  // Write end of contents delimiter
239  os << nl << token::END_LIST << nl;
240  }
241  }
242  else
243  {
245  }
246  }
247  else
248  {
249  if (nm)
250  {
251  os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(Type));
252  }
253  }
254 
255  // Check state of IOstream
256  os.check("Ostream& operator<<(Ostream&, const Matrix&)");
257 
258  return os;
259 }
260 
261 
262 // ************************************************************************* //
A templated 2D matrix of objects of <T>, where the n x m matrix dimensions are known and used for sub...
Matrix()
Null constructor.
Definition: MatrixI.H:29
#define M(I)
bool isLabel() const
Definition: tokenI.H:262
void clear()
Clear the Matrix, i.e. set sizes to zero.
Definition: Matrix.C:134
label n() const
Return the number of rows.
Definition: MatrixI.H:56
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
char readBeginList(const char *funcName)
Definition: Istream.C:131
virtual Istream & read(token &)=0
Return next token from stream.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
label readLabel(Istream &is)
Definition: label.H:64
static const char nl
Definition: Ostream.H:260
IOerror FatalIOError
InfoProxy< token > info() const
Return info proxy.
Definition: token.H:372
char readEndList(const char *funcName)
Definition: Istream.C:152
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:107
label k
Boltzmann constant.
streamFormat format() const
Return current stream format.
Definition: IOstream.H:377
A token holds items read from Istream.
Definition: token.H:67
Template function to specify if the data of a type are contiguous.
label labelToken() const
Definition: tokenI.H:267
friend Istream & operator>>(Istream &, Matrix< Form, Type > &)
Read Matrix from Istream, discarding contents of existing Matrix.
Istream & operator>>(Istream &, edgeMesh &)
Definition: edgeMeshIO.C:144
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
Uniform/equally-weighted distribution model.
Definition: uniform.H:47
label m() const
Return the number of columns.
Definition: MatrixI.H:63
#define FatalIOErrorIn(functionName, ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:325