xdr_mgf.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2016 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 
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 
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  libmesh_error_msg("XDR Error: Accessing file: " << fn << " failed.");
90 
91  // Create the XDR handle
92  mp_xdr_handle = new XDR;
93  xdrstdio_create(mp_xdr_handle,
94  mp_fp,
95  ((m_type == ENCODE) ? XDR_ENCODE : XDR_DECODE));
96 
97  break;
98  }
99 
100 #endif
101 
102  case (XdrMGF::R_ASCII):
103  {
104  mp_in.open(fn, std::ios::in);
105 
106  // Make sure it opened correctly
107  if (!mp_in.good())
108  libmesh_file_error(fn);
109 
110  break;
111  }
112 
113  case (XdrMGF::W_ASCII):
114  {
115  mp_out.open(fn, std::ios::out);
116 
117  // Make sure it opened correctly
118  if (!mp_out.good())
119  libmesh_file_error(fn);
120 
121  break;
122  }
123 
124  default:
125  libmesh_error_msg("Unrecognized file access type!");
126  }
127 
128 
129 
130 
131 
132  // Read/Write the file signature
133  const int bufLen = 12;
134  char buf[bufLen+1];
135 
136  switch (m_type)
137  {
138 
139 #ifdef LIBMESH_HAVE_XDR
140 
141  case (XdrMGF::ENCODE):
142  {
143  char * p = &buf[0];
144  const LegacyXdrIO::FileFormat orig = this->get_orig_flag();
145 
146  std::ostringstream name;
147  if (orig == LegacyXdrIO::DEAL)
148  name << "DEAL 003:003";
149 
150  else if (orig == LegacyXdrIO::MGF)
151  name << "MGF 002:000";
152 
153  else if (orig == LegacyXdrIO::LIBM)
154  name << "LIBM " << this->get_num_levels();
155 
156  else
157  libmesh_error_msg("Unknown orig " << orig);
158 
159  // Fill the buffer
160  std::sprintf(&buf[0], "%s", name.str().c_str());
161 
162  xdr_string(mp_xdr_handle, &p, bufLen); // Writes binary signature
163 
164  break;
165  }
166 
167  case (XdrMGF::DECODE):
168  {
169  char * p = &buf[0];
170  xdr_string(mp_xdr_handle, &p, bufLen); // Reads binary signature
171 
172  // Set the number of levels used in the mesh
173  this->tokenize_first_line(p);
174 
175  break;
176  }
177 
178 #endif
179 
180  case (XdrMGF::W_ASCII):
181  {
182  const LegacyXdrIO::FileFormat orig = this->get_orig_flag();
183 
184  if (orig == LegacyXdrIO::DEAL)
185  std::sprintf(&buf[0], "%s %03d:%03d", "DEAL", 3, 3);
186 
187  else if (orig == LegacyXdrIO::MGF)
188  std::sprintf(&buf[0], "%s %03d:%03d", "MGF ", 2, 0);
189 
190  else if (orig == LegacyXdrIO::LIBM)
191  std::sprintf(&buf[0], "%s %d", "LIBM", this->get_num_levels());
192 
193  mp_out << buf << '\n';
194 
195  break;
196  }
197 
198  case (XdrMGF::R_ASCII):
199  {
200 
201 #ifdef __HP_aCC
202  // weirdly, _only_ here aCC
203  // is not fond of mp_in.getline()
204  // however, using mp_in.getline()
205  // further below is ok...
206  std::string buf_buf;
207  std::getline (mp_in, buf_buf, '\n');
208  libmesh_assert_less_equal (buf_buf.size(), bufLen);
209 
210  buf_buf.copy (buf, std::string::npos);
211 #else
212 
213  // Here we first use getline() to grab the very
214  // first line of the file into a char buffer. Then
215  // this line is tokenized to look for:
216  // 1.) The name LIBM, which specifies the new Mesh style.
217  // 2.) The number of levels in the Mesh which is being read.
218  // Note that "buf" will be further processed below, here we
219  // are just attempting to get the number of levels.
220  mp_in.getline(buf, bufLen+1);
221 
222 #endif
223 
224  // Determine the number of levels in this mesh
225  this->tokenize_first_line(buf);
226 
227  break;
228  }
229 
230  default:
231  libmesh_error_msg("Unknown m_type" << m_type);
232  }
233 
234 
235 
236  // If you are reading or decoding, process the signature
237  if ((m_type == R_ASCII) || (m_type == DECODE))
238  {
239  char name[5];
240  std::strncpy(name, &buf[0], 4);
241  name[4] = '\0';
242 
243  if (std::strcmp (name, "DEAL") == 0)
244  {
245  this->orig_flag = LegacyXdrIO::DEAL; // 0 is the DEAL identifier by definition
246  }
247  else if (std::strcmp (name, "MGF ") == 0)
248  {
249  this->orig_flag = LegacyXdrIO::MGF; // 1 is the MGF identifier by definition
250  }
251  else if (std::strcmp (name, "LIBM") == 0)
252  {
253  this->orig_flag = LegacyXdrIO::LIBM; // the New and Improved XDA
254  }
255 
256  else
257  libmesh_error_msg("ERROR: No originating software can be determined for header string '" << name);
258  }
259 
260 }
261 
262 
263 
264 int XdrMGF::dataBlk(int * array, int numvar, int size)
265 {
266  int totalSize = numvar*size;
267 
268  switch (m_type)
269  {
270 
271 #ifdef LIBMESH_HAVE_XDR
272 
273  case (XdrMGF::DECODE):
274  case (XdrMGF::ENCODE):
275  {
276  xdr_vector(mp_xdr_handle,
277  (char *) &array[0],
278  totalSize,
279  sizeof(int),
280  (xdrproc_t) xdr_int);
281  break;
282  }
283 
284 #endif
285 
286  case (XdrMGF::W_ASCII):
287  {
288  for (int i=0; i<size; i++)
289  {
290  for (int j=0; j<numvar; j++)
291  mp_out << array[i*numvar + j] << " ";
292 
293  mp_out << '\n';
294  }
295 
296  mp_out.flush();
297  break;
298  }
299 
300  case (XdrMGF::R_ASCII):
301  {
302  libmesh_assert (mp_in.good());
303 
304  for (int i=0; i<size; i++)
305  {
306  for (int j=0; j<numvar; j++)
307  {
308  mp_in >> array[i*numvar + j];
309  }
310 
311  mp_in.ignore(); // Read newline
312  }
313 
314  break;
315  }
316 
317  default:
318  // Unknown access type
319  libmesh_error_msg("Unknown m_type" << m_type);
320  }
321 
322  return totalSize;
323 }
324 
325 
326 
327 int XdrMGF::dataBlk(Real * array, int numvar, int size)
328 {
329  int totalSize = numvar*size;
330 
331  // If this function is called by coord(),
332  // numvar is the problem dimension, and
333  // size is the number of nodes in the problem.
334 
335  //libMesh::out << "Total amount of data to be written: " << totalSize << std::endl;
336 
337  switch (m_type)
338  {
339 
340 #ifdef LIBMESH_HAVE_XDR
341 
342  case (XdrMGF::DECODE):
343  case (XdrMGF::ENCODE):
344  {
345  // FIXME - this is probably broken for Real == long double
346  // RHS
347  xdr_vector(mp_xdr_handle,
348  (char *) &array[0],
349  totalSize,
350  sizeof(Real),
351  (xdrproc_t) xdr_REAL);
352  }
353 
354 #endif
355 
356  case (XdrMGF::W_ASCII):
357  {
358  // Save stream flags
359  std::ios_base::fmtflags out_flags = mp_out.flags();
360 
361  // We will use scientific notation with a precision of 16
362  // digits in the following output. The desired precision and
363  // format will automatically determine the width.
364  mp_out << std::scientific
365  << std::setprecision(16);
366 
367  for (int i=0; i<size; i++)
368  {
369  for (int j=0; j<numvar; j++)
370  mp_out << array[i*numvar + j] << " \t";
371 
372  mp_out << '\n';
373  }
374 
375  // Restore stream flags
376  mp_out.flags(out_flags);
377 
378  mp_out.flush();
379  break;
380  }
381 
382  case (XdrMGF::R_ASCII):
383  {
384  libmesh_assert (mp_in.good());
385 
386  for (int i=0; i<size; i++)
387  {
388  libmesh_assert (mp_in.good());
389 
390  for (int j=0; j<numvar; j++)
391  mp_in >> array[i*numvar + j];
392 
393  mp_in.ignore(); // Read newline
394  }
395 
396  break;
397  }
398 
399  default:
400  // Unknown access type
401  libmesh_error_msg("Unknown m_type" << m_type);
402  }
403 
404  return totalSize;
405 }
406 
407 } // namespace libMesh
unsigned int get_num_levels()
Definition: xdr_mgf.h:184
std::string name(const ElemQuality q)
Definition: elem_quality.C:39
void tokenize_first_line(const char *p)
Definition: xdr_mgf.h:242
void fini()
Definition: xdr_mgf.C:35
libmesh_assert(remote_elem)
std::FILE * mp_fp
Definition: xdr_mgf.h:236
const class libmesh_nullptr_t libmesh_nullptr
std::ifstream mp_in
Definition: xdr_mgf.h:228
void init(XdrIO_TYPE t, const char *fn, const char *type, int icnt)
Definition: xdr_mgf.C:68
int dataBlk(int *array, int numvar, int size)
Definition: xdr_mgf.C:264
LegacyXdrIO::FileFormat orig_flag
Definition: xdr_mgf.h:223
std::ofstream mp_out
Definition: xdr_mgf.h:233
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
XdrIO_TYPE m_type
Definition: xdr_mgf.h:200
virtual ~XdrMGF()
Definition: xdr_mgf.C:28
LegacyXdrIO::FileFormat get_orig_flag() const
Definition: xdr_mgf.h:168
OStreamProxy out(std::cout)
XDR * mp_xdr_handle
Definition: xdr_mgf.h:210