xdr_mgf.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 // C++ includes
19 #include <iomanip>
20 
21 // Local includes
22 #include "libmesh/xdr_mgf.h"
23 
24 namespace libMesh
25 {
26 
27 // XdrMGF member functions
29 {
30  this->fini();
31 }
32 
33 
34 
36 {
37 
38 #ifdef LIBMESH_HAVE_XDR
39 
40  if (mp_xdr_handle)
41  {
42  //libMesh::out << "Destroying XDR file handle." << std::endl;
43  xdr_destroy(mp_xdr_handle);
44  }
45 
46  //libMesh::out << "Deleting the file handle pointer." << std::endl;
47  delete mp_xdr_handle;
48 
49  mp_xdr_handle = NULL;
50 
51 #endif
52 
53  if (mp_fp)
54  {
55  //libMesh::out << "Closing file." << std::endl;
56  std::fflush(mp_fp);
57  std::fclose(mp_fp);
58  }
59 
60  mp_fp = NULL;
61 }
62 
63 
64 
65 
66 
67 
68 void XdrMGF::init (XdrMGF::XdrIO_TYPE t, const char* fn, const char*, int)
69 {
70  m_type=t;
71 
72  // Close old file if necessary
73  if (mp_fp) this->fini();
74 
75 
76  // Open file
77  switch (m_type)
78  {
79 
80 #ifdef LIBMESH_HAVE_XDR
81 
82  case (XdrMGF::ENCODE):
83  case (XdrMGF::DECODE):
84  {
85  mp_fp = fopen (fn, (m_type == ENCODE) ? "w" : "r");
86 
87  // Make sure the file is ready for use
88  if (!mp_fp)
89  {
90  libMesh::err << "XDR Error: Accessing file: "
91  << fn
92  << " failed."
93  << std::endl;
94  libmesh_error();
95  }
96 
97  // Create the XDR handle
98  mp_xdr_handle = new XDR;
99  xdrstdio_create(mp_xdr_handle,
100  mp_fp,
101  ((m_type == ENCODE) ? XDR_ENCODE : XDR_DECODE));
102 
103  break;
104  }
105 
106 #endif
107 
108  case (XdrMGF::R_ASCII):
109  {
110  mp_in.open(fn, std::ios::in);
111 
112  // Make sure it opened correctly
113  if (!mp_in.good())
114  libmesh_file_error(fn);
115 
116  break;
117  }
118 
119  case (XdrMGF::W_ASCII):
120  {
121  mp_out.open(fn, std::ios::out);
122 
123  // Make sure it opened correctly
124  if (!mp_out.good())
125  libmesh_file_error(fn);
126 
127  break;
128  }
129 
130  default:
131  {
132  libMesh::out << "Unrecognized file access type!" << std::endl;
133  libmesh_error();
134  }
135  }
136 
137 
138 
139 
140 
141  // Read/Write the file signature
142  const int bufLen = 12;
143  char buf[bufLen+1];
144 
145  switch (m_type)
146  {
147 
148 #ifdef LIBMESH_HAVE_XDR
149 
150  case (XdrMGF::ENCODE):
151  {
152  char* p = &buf[0];
153  const LegacyXdrIO::FileFormat orig = this->get_orig_flag();
154 
155  std::ostringstream name;
156  if (orig == LegacyXdrIO::DEAL)
157  name << "DEAL 003:003";
158 
159  else if (orig == LegacyXdrIO::MGF)
160  name << "MGF 002:000";
161 
162  else if (orig == LegacyXdrIO::LIBM)
163  name << "LIBM " << this->get_num_levels();
164 
165  else
166  libmesh_error();
167 
168  // Fill the buffer
169  std::sprintf(&buf[0], "%s", name.str().c_str());
170 
171  xdr_string(mp_xdr_handle, &p, bufLen); // Writes binary signature
172 
173  break;
174  }
175 
176  case (XdrMGF::DECODE):
177  {
178  char* p = &buf[0];
179  xdr_string(mp_xdr_handle, &p, bufLen); // Reads binary signature
180 
181  // Set the number of levels used in the mesh
182  this->tokenize_first_line(p);
183 
184  break;
185  }
186 
187 #endif
188 
189  case (XdrMGF::W_ASCII):
190  {
191  const LegacyXdrIO::FileFormat orig = this->get_orig_flag();
192 
193  if (orig == LegacyXdrIO::DEAL)
194  std::sprintf(&buf[0], "%s %03d:%03d", "DEAL", 3, 3);
195 
196  else if (orig == LegacyXdrIO::MGF)
197  std::sprintf(&buf[0], "%s %03d:%03d", "MGF ", 2, 0);
198 
199  else if (orig == LegacyXdrIO::LIBM)
200  std::sprintf(&buf[0], "%s %d", "LIBM", this->get_num_levels());
201 
202  mp_out << buf << '\n';
203 
204  break;
205  }
206 
207  case (XdrMGF::R_ASCII):
208  {
209 
210 #ifdef __HP_aCC
211  // weirdly, _only_ here aCC
212  // is not fond of mp_in.getline()
213  // however, using mp_in.getline()
214  // further below is ok...
215  std::string buf_buf;
216  std::getline (mp_in, buf_buf, '\n');
217  libmesh_assert_less_equal (buf_buf.size(), bufLen);
218 
219  buf_buf.copy (buf, std::string::npos);
220 #else
221 
222  // Here we first use getline() to grab the very
223  // first line of the file into a char buffer. Then
224  // this line is tokenized to look for:
225  // 1.) The name LIBM, which specifies the new Mesh style.
226  // 2.) The number of levels in the Mesh which is being read.
227  // Note that "buf" will be further processed below, here we
228  // are just attempting to get the number of levels.
229  mp_in.getline(buf, bufLen+1);
230 
231 #endif
232 
233  // Determine the number of levels in this mesh
234  this->tokenize_first_line(buf);
235 
236  break;
237  }
238 
239  default:
240  libmesh_error();
241  }
242 
243 
244 
245  // If you are reading or decoding, process the signature
246  if ((m_type == R_ASCII) || (m_type == DECODE))
247  {
248  char name[5];
249  std::strncpy(name, &buf[0], 4);
250  name[4] = '\0';
251 
252  if (std::strcmp (name, "DEAL") == 0)
253  {
254  this->orig_flag = LegacyXdrIO::DEAL; // 0 is the DEAL identifier by definition
255  }
256  else if (std::strcmp (name, "MGF ") == 0)
257  {
258  this->orig_flag = LegacyXdrIO::MGF; // 1 is the MGF identifier by definition
259  }
260  else if (std::strcmp (name, "LIBM") == 0)
261  {
262  this->orig_flag = LegacyXdrIO::LIBM; // the New and Improved XDA
263  }
264 
265  else
266  {
267  libMesh::err <<
268  "No originating software can be determined for header string '" <<
269  name << "'. Error." << std::endl;
270  libmesh_error();
271  }
272  }
273 
274 }
275 
276 
277 
278 int XdrMGF::dataBlk(int* array, int numvar, int size)
279 {
280  int totalSize = numvar*size;
281 
282  switch (m_type)
283  {
284 
285 #ifdef LIBMESH_HAVE_XDR
286 
287  case (XdrMGF::DECODE):
288  case (XdrMGF::ENCODE):
289  {
290  xdr_vector(mp_xdr_handle,
291  (char *) &array[0],
292  totalSize,
293  sizeof(int),
294  (xdrproc_t) xdr_int);
295  break;
296  }
297 
298 #endif
299 
300  case (XdrMGF::W_ASCII):
301  {
302  for (int i=0; i<size; i++)
303  {
304  for (int j=0; j<numvar; j++)
305  mp_out << array[i*numvar + j] << " ";
306 
307  mp_out << '\n';
308  }
309 
310  mp_out.flush();
311  break;
312  }
313 
314  case (XdrMGF::R_ASCII):
315  {
316  libmesh_assert (mp_in.good());
317 
318  for (int i=0; i<size; i++)
319  {
320  for (int j=0; j<numvar; j++)
321  {
322  mp_in >> array[i*numvar + j];
323  }
324 
325  mp_in.ignore(); // Read newline
326  }
327 
328  break;
329  }
330 
331  default:
332  // Unknown access type
333  libmesh_error();
334  }
335 
336  return totalSize;
337 }
338 
339 
340 
341 int XdrMGF::dataBlk(Real* array, int numvar, int size)
342 {
343  int totalSize = numvar*size;
344 
345  // If this function is called by coord(),
346  // numvar is the problem dimension, and
347  // size is the number of nodes in the problem.
348 
349  //libMesh::out << "Total amount of data to be written: " << totalSize << std::endl;
350 
351  switch (m_type)
352  {
353 
354 #ifdef LIBMESH_HAVE_XDR
355 
356  case (XdrMGF::DECODE):
357  case (XdrMGF::ENCODE):
358  {
359  // FIXME - this is probably broken for Real == long double
360  // RHS
361  xdr_vector(mp_xdr_handle,
362  (char *) &array[0],
363  totalSize,
364  sizeof(Real),
365  (xdrproc_t) xdr_REAL);
366  }
367 
368 #endif
369 
370  case (XdrMGF::W_ASCII):
371  {
372  // Save stream flags
373  std::ios_base::fmtflags out_flags = mp_out.flags();
374 
375  // We will use scientific notation with a precision of 16
376  // digits in the following output. The desired precision and
377  // format will automatically determine the width.
378  mp_out << std::scientific
379  << std::setprecision(16);
380 
381  for (int i=0; i<size; i++)
382  {
383  for (int j=0; j<numvar; j++)
384  mp_out << array[i*numvar + j] << " \t";
385 
386  mp_out << '\n';
387  }
388 
389  // Restore stream flags
390  mp_out.flags(out_flags);
391 
392  mp_out.flush();
393  break;
394  }
395 
396  case (XdrMGF::R_ASCII):
397  {
398  libmesh_assert (mp_in.good());
399 
400  for (int i=0; i<size; i++)
401  {
402  libmesh_assert (mp_in.good());
403 
404  for (int j=0; j<numvar; j++)
405  mp_in >> array[i*numvar + j];
406 
407  mp_in.ignore(); // Read newline
408  }
409 
410  break;
411  }
412 
413  default:
414  // Unknown access type
415  libmesh_error();
416  }
417 
418  return totalSize;
419 }
420 
421 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:07 UTC

Hosted By:
SourceForge.net Logo