legacy_xdr_io.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 
19 
20 // C++ includes
21 #include <iostream>
22 #include <iomanip>
23 
24 #include <vector>
25 #include <string>
26 
27 // Local includes
28 #include "libmesh/legacy_xdr_io.h"
29 #include "libmesh/mesh_base.h"
30 #include "libmesh/mesh_data.h"
31 #include "libmesh/mesh_tools.h" // MeshTools::n_levels(mesh)
32 #include "libmesh/parallel.h" // - which makes write parallel-only
33 #include "libmesh/cell_hex27.h" // Needed for MGF-style Hex27 meshes
34 #include "libmesh/boundary_info.h"
36 #include "libmesh/xdr_mgf.h"
37 #include "libmesh/xdr_mesh.h"
38 #include "libmesh/xdr_mhead.h"
39 #include "libmesh/xdr_soln.h"
40 #include "libmesh/xdr_shead.h"
41 
42 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
43 #include "libmesh/utility.h"
44 #endif
45 
46 
47 namespace libMesh
48 {
49 
50 
51 
52 
53 
54 
55 // ------------------------------------------------------------
56 // LegacyXdrIO members
57 LegacyXdrIO::LegacyXdrIO (MeshBase & mesh, const bool binary_in) :
58  MeshInput<MeshBase> (mesh),
59  MeshOutput<MeshBase>(mesh),
60  _binary (binary_in)
61 {
62 }
63 
64 
65 
66 
67 LegacyXdrIO::LegacyXdrIO (const MeshBase & mesh, const bool binary_in) :
68  MeshOutput<MeshBase>(mesh),
69  _binary (binary_in)
70 {
71 }
72 
73 
74 
75 
77 {
78 }
79 
80 
81 
82 
84 {
85  return _binary;
86 }
87 
88 
89 
90 
91 bool LegacyXdrIO::binary () const
92 {
93  return _binary;
94 }
95 
96 
97 
98 void LegacyXdrIO::read (const std::string & name)
99 {
100  // This is a serial-only process for now;
101  // the Mesh should be read on processor 0 and
102  // broadcast later
104  return;
105 
106  if (this->binary())
107  this->read_binary (name);
108  else
109  this->read_ascii (name);
110 }
111 
112 
113 
114 void LegacyXdrIO::read_mgf (const std::string & name)
115 {
116  if (this->binary())
117  this->read_binary (name, LegacyXdrIO::MGF);
118  else
119  this->read_ascii (name, LegacyXdrIO::MGF);
120 }
121 
122 
123 
124 void LegacyXdrIO::write (const std::string & name)
125 {
126  if (this->binary())
127  this->write_binary (name);
128  else
129  this->write_ascii (name);
130 }
131 
132 
133 
134 void LegacyXdrIO::write_mgf (const std::string & name)
135 {
136  if (this->binary())
137  this->write_binary (name, LegacyXdrIO::MGF);
138  else
139  this->write_ascii (name, LegacyXdrIO::MGF);
140 }
141 
142 
143 
144 void LegacyXdrIO::read_mgf_soln (const std::string & name,
145  std::vector<Number> & soln,
146  std::vector<std::string> & var_names) const
147 {
148  libmesh_deprecated();
149 
150 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
151 
152  // buffer for writing separately
153  std::vector<Real> real_soln;
154  std::vector<Real> imag_soln;
155 
156  Utility::prepare_complex_data (soln, real_soln, imag_soln);
157 
158  this->read_soln (Utility::complex_filename(name, 0),
159  real_soln,
160  var_names);
161 
162  this->read_soln (Utility::complex_filename(name, 1),
163  imag_soln,
164  var_names);
165 
166 #else
167 
168  this->read_soln (name, soln, var_names);
169 
170 #endif
171 }
172 
173 
174 
175 void LegacyXdrIO::write_mgf_soln (const std::string & name,
176  std::vector<Number> & soln,
177  std::vector<std::string> & var_names) const
178 {
179  libmesh_deprecated();
180 
181 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
182 
183  // buffer for writing separately
184  std::vector<Real> real_soln;
185  std::vector<Real> imag_soln;
186 
187  Utility::prepare_complex_data (soln, real_soln, imag_soln);
188 
189  this->write_soln (Utility::complex_filename(name, 0),
190  real_soln,
191  var_names);
192 
193  this->write_soln (Utility::complex_filename(name, 1),
194  imag_soln,
195  var_names);
196 
197 #else
198 
199  this->write_soln (name, soln, var_names);
200 
201 #endif
202 }
203 
204 
205 
206 void LegacyXdrIO::read_ascii (const std::string & name,
207  const LegacyXdrIO::FileFormat originator)
208 {
209  // get a writeable reference to the underlying mesh
211 
212  // clear any existing mesh data
213  mesh.clear();
214 
215  // read the mesh
216  this->read_mesh (name, originator);
217 }
218 
219 
220 
221 #ifndef LIBMESH_HAVE_XDR
222 void LegacyXdrIO::read_binary (const std::string & name,
224 {
225 
226  libMesh::err << "WARNING: Compiled without XDR binary support.\n"
227  << "Will try ASCII instead" << std::endl << std::endl;
228 
229  this->read_ascii (name);
230 }
231 #else
232 void LegacyXdrIO::read_binary (const std::string & name,
233  const LegacyXdrIO::FileFormat originator)
234 {
235  // get a writeable reference to the underlying mesh
237 
238  // clear any existing mesh data
239  mesh.clear();
240 
241  // read the mesh
242  this->read_mesh (name, originator);
243 }
244 #endif
245 
246 
247 
248 void LegacyXdrIO::write_ascii (const std::string & name, const LegacyXdrIO::FileFormat originator)
249 {
250  this->write_mesh (name, originator);
251 }
252 
253 
254 
255 #ifndef LIBMESH_HAVE_XDR
256 void LegacyXdrIO::write_binary (const std::string & name, const LegacyXdrIO::FileFormat)
257 {
258  libMesh::err << "WARNING: Compiled without XDR binary support.\n"
259  << "Will try ASCII instead" << std::endl << std::endl;
260 
261  this->write_ascii (name);
262 }
263 #else
264 void LegacyXdrIO::write_binary (const std::string & name, const LegacyXdrIO::FileFormat originator)
265 {
266  this->write_mesh (name, originator);
267 }
268 #endif
269 
270 
271 
272 void LegacyXdrIO::read_mesh (const std::string & name,
273  const LegacyXdrIO::FileFormat originator,
274  MeshData * mesh_data)
275 {
276  // This is a serial-only process for now;
277  // the Mesh should be read on processor 0 and
278  // broadcast later
279  libmesh_assert_equal_to (MeshOutput<MeshBase>::mesh().processor_id(), 0);
280 
281  // get a writeable reference to the mesh
283 
284  // clear any data in the mesh
285  mesh.clear();
286 
287  // Keep track of what kinds of elements this file contains
288  elems_of_dimension.clear();
289  elems_of_dimension.resize(4, false);
290 
291  // Create an XdrMESH object.
292  XdrMESH m;
293 
294  // Create a pointer
295  // to an XdrMESH file
296  // header.
297  XdrMHEAD mh;
298 
299  // Open the XDR file for reading.
300  // Note 1: Provide an additional argument
301  // to specify the dimension.
302  //
303  // Note 2: Has to do the right thing for
304  // both binary and ASCII files.
305  m.set_orig_flag(originator);
306  m.init((this->binary() ? XdrMGF::DECODE : XdrMGF::R_ASCII), name.c_str(), 0); // mesh files are always number 0 ...
307 
308  // From here on, things depend
309  // on whether we are reading or
310  // writing! First, we define
311  // header variables that may
312  // be read OR written.
313  unsigned int n_blocks = 0;
314  unsigned int n_levels = 0;
315 
316  if (m.get_orig_flag() == LegacyXdrIO::LIBM)
317  n_levels = m.get_num_levels();
318 
319 
320  std::vector<ElemType> etypes;
321  std::vector<unsigned int> neeb;
322 
323  // Get the information from
324  // the header, and place it
325  // in the header pointer.
326  m.header(&mh);
327 
328  // Read information from the
329  // file header. This depends on
330  // whether its a libMesh or MGF mesh.
331  const int numElem = mh.getNumEl();
332  const int numNodes = mh.getNumNodes();
333  const int totalWeight = mh.getSumWghts();
334  const int numBCs = mh.getNumBCs();
335 
336  // If a libMesh-type mesh, read the augmented mesh information
338  {
339  // Read augmented header
340  n_blocks = mh.get_n_blocks();
341 
342  etypes.resize(n_blocks);
343  mh.get_block_elt_types(etypes);
344 
345  mh.get_num_elem_each_block(neeb);
346  }
347 
348 
349 
350  // Read the connectivity
351  std::vector<int> conn;
352 
353  // Now that we know the
354  // number of nodes and elements,
355  // we can resize the
356  // appropriate vectors if we are
357  // reading information in.
358  mesh.reserve_nodes (numNodes);
359  mesh.reserve_elem (numElem);
360 
361  // Each element stores two extra
362  // locations: one which tells
363  // what type of element it is,
364  // and one which tells how many
365  // nodes it has. Therefore,
366  // the total number of nodes
367  // (totalWeight) must be augmented
368  // by 2 times the number of elements
369  // in order to read in the entire
370  // connectivity array.
371 
372  // Note: This section now depends on
373  // whether we are reading an old-style libMesh,
374  // MGF, or a new-style libMesh mesh.
375  if (m.get_orig_flag() == LegacyXdrIO::DEAL)
376  {
377  conn.resize(totalWeight);
378  m.Icon(&conn[0], 1, totalWeight);
379  }
380 
381  else if (m.get_orig_flag() == LegacyXdrIO::MGF)
382  {
383  conn.resize(totalWeight+(2*numElem));
384  m.Icon(&conn[0], 1, totalWeight+(2*numElem));
385  }
386 
387  else if (m.get_orig_flag() == LegacyXdrIO::LIBM)
388  {
389  conn.resize(totalWeight);
390  m.Icon(&conn[0], 1, totalWeight);
391  }
392 
393  else
394  {
395  // I don't know what type of mesh it is.
396  libmesh_error_msg("Unrecognized flag " << m.get_orig_flag());
397  }
398 
399  // read in the nodal coordinates and form points.
400  {
401  std::vector<Real> coords(numNodes*3); // Always use three coords per node
402  m.coord(&coords[0], 3, numNodes);
403 
404 
405 
406  // Form Nodes out of
407  // the coordinates. If the
408  // MeshData object is active,
409  // add the nodes and ids also
410  // to its map.
411  for (int innd=0; innd<numNodes; ++innd)
412  {
413  Node * node = mesh.add_point (Point(coords[0+innd*3],
414  coords[1+innd*3],
415  coords[2+innd*3]), innd);
416 
417  if (mesh_data != libmesh_nullptr)
418  if (mesh_data->active())
419  {
420  // add the id to the MeshData, so that
421  // it knows the foreign id, even when
422  // the underlying mesh got re-numbered,
423  // refined, elements/nodes added...
424  mesh_data->add_foreign_node_id(node, innd);
425  }
426  }
427  }
428 
429 
430 
431  // Build the elements.
432  // Note: If the originator was MGF, we don't
433  // have to do much checking ...
434  // all the elements are Hex27.
435  // If the originator was
436  // this code, we have to loop over
437  // et and neeb to read in all the
438  // elements correctly.
439  //
440  // (This used to be before the coords block, but it
441  // had to change now that elements store pointers to
442  // nodes. The nodes must exist before we assign them to
443  // the elements. BSK, 1/13/2003)
445  {
446  // This map keeps track of elements we've previously
447  // constructed, to avoid O(n) lookup times for parent pointers
448  // and to enable elements to be added in ascending ID order
449  std::map<unsigned int, Elem *> parents;
450 
451  {
452  unsigned int lastConnIndex = 0;
453  unsigned int lastFaceIndex = 0;
454 
455  // Keep track of Element ids in MGF-style meshes;
456  unsigned int next_elem_id = 0;
457 
458  for (unsigned int level=0; level<=n_levels; level++)
459  {
460  for (unsigned int idx=0; idx<n_blocks; idx++)
461  {
462  for (unsigned int e=lastFaceIndex; e<lastFaceIndex+neeb[level*n_blocks+idx]; e++)
463  {
464  // Build a temporary element of the right type, so we know how
465  // connectivity entries will be on the line for this element.
466  UniquePtr<Elem> temp_elem = Elem::build(etypes[idx]);
467 
468  // A pointer to the element which will eventually be added to the mesh.
469  Elem * elem;
470 
471  // New-style libMesh mesh
472  if (m.get_orig_flag() == LegacyXdrIO::LIBM)
473  {
474  unsigned int self_ID = conn[lastConnIndex + temp_elem->n_nodes()];
475 
476 #ifdef LIBMESH_ENABLE_AMR
477  unsigned int parent_ID = conn[lastConnIndex + temp_elem->n_nodes()+1];
478 
479  if (level > 0)
480  {
481  // Do a linear search for the parent
482  Elem * my_parent;
483 
484  // Search for parent in the parents map (log(n))
485  START_LOG("log(n) search for parent", "LegacyXdrIO::read_mesh");
486  std::map<unsigned int, Elem *>::iterator it = parents.find(parent_ID);
487  STOP_LOG("log(n) search for parent", "LegacyXdrIO::read_mesh");
488 
489  // If the parent was not previously added, we cannot continue.
490  if (it == parents.end())
491  libmesh_error_msg("Parent element with ID " << parent_ID << " not found.");
492 
493  // Set the my_parent pointer
494  my_parent = (*it).second;
495 
496  // my_parent is now INACTIVE, since he has children
498 
499  // Now that we know the parent, build the child
500  elem = Elem::build(etypes[idx],my_parent).release();
501 
502  // The new child is marked as JUST_REFINED
504 
505  // Tell the parent about his new child
506  my_parent->add_child(elem);
507 
508  // sanity check
509  libmesh_assert_equal_to (my_parent->type(), elem->type());
510  }
511 
512  // Add level-0 elements to the mesh
513  else
514 #endif // #ifdef LIBMESH_ENABLE_AMR
515  {
516  elem = Elem::build(etypes[idx]).release();
517  }
518 
519  // Assign the newly-added element's ID so that future
520  // children which may be added can find it correctly.
521  elem->set_id() = self_ID;
522 
523  // Add this element to the map, it may be a parent for a future element
524  START_LOG("insert elem into map", "LegacyXdrIO::read_mesh");
525  parents[self_ID] = elem;
526  STOP_LOG("insert elem into map", "LegacyXdrIO::read_mesh");
527  }
528 
529  // MGF-style meshes
530  else
531  {
532  elem = Elem::build(etypes[idx]).release();
533  elem->set_id(next_elem_id++);
534 
535  elems_of_dimension[elem->dim()] = true;
536 
537  mesh.add_elem(elem);
538  }
539 
540  // Add elements with the same id as in libMesh.
541  // Provided the data files that MeshData reads
542  // were only written with MeshData, then this
543  // should work properly. This is an inline
544  // function, so that for disabled MeshData, this
545  // should not induce too much cost
546  if (mesh_data != libmesh_nullptr)
547  mesh_data->add_foreign_elem_id (elem, e);
548 
549  // Set the node pointers of the newly-created element
550  for (unsigned int innd=0; innd < elem->n_nodes(); innd++)
551  {
552  elem->set_node(innd) = mesh.node_ptr(conn[innd+lastConnIndex]);
553  }
554 
555  lastConnIndex += (m.get_orig_flag() == LegacyXdrIO::LIBM) ? (elem->n_nodes()+2) : elem->n_nodes();
556  }
557  lastFaceIndex += neeb[idx];
558  }
559  }
560  }
561 
562  if (m.get_orig_flag() == LegacyXdrIO::LIBM)
563  {
564  {
565  // Iterate in ascending elem ID order
566  unsigned int next_elem_id = 0;
567  for (std::map<unsigned int, Elem *>::iterator i =
568  parents.begin();
569  i != parents.end(); ++i)
570  {
571  Elem * elem = i->second;
572  if (elem)
573  {
574  elem->set_id(next_elem_id++);
575 
576  elems_of_dimension[elem->dim()] = true;
577 
578  mesh.add_elem(elem);
579  }
580  else
581  // We can probably handle this, but we don't expect it
582  libmesh_error_msg("Unexpected NULL elem encountered while reading libmesh XDR file.");
583  }
584  }
585  }
586  }
587 
588  // MGF-style (1) Hex27 mesh
589  else if (m.get_orig_flag() == LegacyXdrIO::MGF)
590  {
591 
592 #ifdef DEBUG
593  if (mesh_data != libmesh_nullptr)
594  if (mesh_data->active())
595  libmesh_error_msg("ERROR: MeshData not implemented for MGF-style mesh.");
596 #endif
597 
598  for (int ielm=0; ielm < numElem; ++ielm)
599  {
600  Elem * elem = new Hex27;
601  elem->set_id(ielm);
602 
603  elems_of_dimension[elem->dim()] = true;
604 
605  mesh.add_elem(elem);
606 
607  for (int innd=0; innd < 27; ++innd)
608  elem->set_node(innd) = mesh.node_ptr(conn[innd+2+(27+2)*ielm]);
609  }
610  }
611 
612  // Set the mesh dimension to the largest encountered for an element
613  for (unsigned char i=0; i!=4; ++i)
614  if (elems_of_dimension[i])
615  mesh.set_mesh_dimension(i);
616 
617 #if LIBMESH_DIM < 3
618  if (mesh.mesh_dimension() > LIBMESH_DIM)
619  libmesh_error_msg("Cannot open dimension " \
620  << mesh.mesh_dimension() \
621  << " mesh file when configured without " \
622  << mesh.mesh_dimension() \
623  << "D support." );
624 #endif
625 
626  // tell the MeshData object that we are finished
627  // reading data
628  if (mesh_data != libmesh_nullptr)
629  mesh_data->close_foreign_id_maps ();
630 
631  // Free memory used in
632  // the connectivity
633  // vector.
634  conn.clear();
635 
636 
637  // If we are reading,
638  // read in the BCs
639  // from the mesh file,
640  // otherwise write the
641  // boundary conditions
642  // if the BoundaryInfo
643  // object exists.
644  if (numBCs > 0)
645  {
646  std::vector<int> bcs(numBCs*3);
647 
648  // Read the BCs from the XDR file
649  m.BC(&bcs[0], numBCs);
650 
651  // Add to the boundary_info
652  for (int ibc=0; ibc < numBCs; ibc++)
654  (cast_int<dof_id_type>(bcs[0+ibc*3]),
655  cast_int<unsigned short>(bcs[1+ibc*3]),
656  cast_int<boundary_id_type>(bcs[2+ibc*3]));
657  }
658 }
659 
660 
661 
662 void LegacyXdrIO::write_mesh (const std::string & name,
663  const LegacyXdrIO::FileFormat originator)
664 {
665  // get a read-only reference to the mesh
666  const MeshBase & mesh = MeshOutput<MeshBase>::mesh();
667 
668  // n_levels is a parallel-only method
669  libmesh_parallel_only(mesh.comm());
670  const unsigned int n_levels = MeshTools::n_levels(mesh);
671 
672  // The Legacy Xdr IO code only works if we have a serialized mesh
673  libmesh_assert (mesh.is_serial());
674 
675  // In which case only processor 0 needs to do any writing
676  if (MeshOutput<MeshBase>::mesh().processor_id() != 0)
677  return;
678 
679  // Create an XdrMESH object.
680  XdrMESH m;
681 
682  // Create a pointer
683  // to an XdrMESH file
684  // header.
685  XdrMHEAD mh;
686 
687  // Open the XDR file for writing.
688  // Note 1: Provide an additional argument
689  // to specify the dimension.
690  //
691  // Note 2: Has to do the right thing for
692  // both binary and ASCII files.
693  m.set_orig_flag(originator);
694 
695  // From here on, things depend
696  // on whether we are reading or
697  // writing! First, we define
698  // header variables that may
699  // be read OR written.
700  std::vector<unsigned int> neeb;
701  std::vector<ElemType> etypes;
702 
703 
704  int n_non_subactive = 0;
705  int non_subactive_weight = 0;
706 
707  // This map will associate
708  // the distance from the beginning of the set
709  // to each node ID with the node ID itself.
710  std::map<dof_id_type, dof_id_type> node_map;
711 
712  {
713  // For each non-subactive element:
714  // 1.) Increment the number of non subactive elements
715  // 2.) Accumulate the total weight
716  // 3.) Add the node ids to a set of non subactive node ids
717  std::set<dof_id_type> not_subactive_node_ids;
719  const MeshBase::const_element_iterator end_el = mesh.elements_end();
720  for( ; el != end_el; ++el)
721  {
722  const Elem * elem = (*el);
723  if(!elem->subactive())
724  {
725  n_non_subactive++;
726  non_subactive_weight += elem->n_nodes();
727 
728  for (unsigned int n=0; n<elem->n_nodes(); ++n)
729  not_subactive_node_ids.insert(elem->node(n));
730  }
731  }
732 
733  // Now that the set is built, most of the hard work is done. We build
734  // the map next and let the set go out of scope.
735  std::set<dof_id_type>::iterator it = not_subactive_node_ids.begin();
736  const std::set<dof_id_type>::iterator end = not_subactive_node_ids.end();
737  dof_id_type cnt=0;
738  for (; it!=end; ++it)
739  node_map[*it] = cnt++;
740  }
741 
742 
743  const int numElem = n_non_subactive;
744  const int numBCs =
745  cast_int<int>(mesh.get_boundary_info().n_boundary_conds());
746 
747  // Fill the etypes vector with all of the element types found in the mesh
748  MeshTools::elem_types(mesh, etypes);
749 
750  // store number of elements in each block at each refinement level
751  neeb.resize((n_levels+1)*etypes.size());
752 
753  // Store a variable for the number of element types
754  const unsigned int n_el_types =
755  cast_int<unsigned int>(etypes.size());
756 
757  m.set_num_levels(n_levels);
758 
759  // The last argument is zero because mesh files are always number 0 ...
760  m.init((this->binary() ? XdrMGF::ENCODE : XdrMGF::W_ASCII), name.c_str(), 0);
761 
762  // Loop over all levels and all element types to set the entries of neeb
763  for(unsigned int level=0; level<=n_levels; level++)
764  for (unsigned int el_type=0; el_type<n_el_types; el_type++)
765  neeb[level*n_el_types + el_type] =
766  MeshTools::n_non_subactive_elem_of_type_at_level(mesh, etypes[el_type], level);
767  // gotta change this function name!!!
768 
769 
770  // Now we check to see if we're doing
771  // MGF-style headers or libMesh-style
772  // "augmented" headers. An
773  // augmented header contains
774  // information about mesh blocks,
775  // allowing us to optimize storage
776  // and minimize IO requirements
777  // for these meshes.
779  {
780  mh.set_n_blocks(cast_int<unsigned int>(etypes.size()));
781  mh.set_block_elt_types(etypes);
782  mh.set_num_elem_each_block(neeb);
783  }
784  else
785  libmesh_assert_equal_to (etypes.size(), 1);
786 
787  mh.setNumEl(numElem);
788  mh.setNumNodes(cast_int<int>(node_map.size()));
789  mh.setStrSize(65536);
790 
791  // set a local variable for the total weight of the mesh
792  int totalWeight =0;
793 
794  if (m.get_orig_flag() == LegacyXdrIO::DEAL) // old-style LibMesh
795  totalWeight=MeshTools::total_weight(mesh);
796 
797  else if (m.get_orig_flag() == LegacyXdrIO::MGF) // MGF-style
798  totalWeight = MeshTools::total_weight(mesh)+2*numElem;
799 
800  else if (m.get_orig_flag() == LegacyXdrIO::LIBM) // new-style LibMesh
801  totalWeight = non_subactive_weight+2*numElem;
802 
803  else
804  libmesh_error_msg("Unrecognized flag " << m.get_orig_flag());
805 
806  // Set the total weight in the header
807  mh.setSumWghts(totalWeight);
808 
809  mh.setNumBCs(numBCs);
810  mh.setId("Id String"); // You can put whatever you want, it will be ignored
811  mh.setTitle("Title String"); // You can put whatever you want, it will be ignored
812 
813  // Put the information
814  // in the XDR file.
815  m.header(&mh);
816 
817 
818  // Write the connectivity
819  {
820  std::vector<int> conn;
821  LegacyXdrIO::FileFormat orig_type = m.get_orig_flag();
822 
823  // Resize the connectivity vector to hold all the connectivity for the mesh
824  conn.resize(totalWeight);
825 
826  unsigned int lastConnIndex = 0;
827  unsigned int nn = 0;
828 
829  // Loop over levels and types again, write connectivity information to conn.
830  for (unsigned int level=0; level<=n_levels; level++)
831  for (unsigned int idx=0; idx<etypes.size(); idx++)
832  {
833  nn = lastConnIndex = 0;
834 
835  for (unsigned int e=0; e<mesh.n_elem(); e++)
836  if ((mesh.elem(e)->type() == etypes[idx]) &&
837  (mesh.elem(e)->level() == level) &&
838  !mesh.elem(e)->subactive())
839  {
840  int nstart=0;
841 
842  if (orig_type == LegacyXdrIO::DEAL)
843  nn = mesh.elem(e)->n_nodes();
844 
845  else if (orig_type == LegacyXdrIO::MGF)
846  {
847  nstart=2; // ignore the 27 and 0 entries
848  nn = mesh.elem(e)->n_nodes()+2;
849  conn[lastConnIndex + 0] = 27;
850  conn[lastConnIndex + 1] = 0;
851  }
852 
853  else if (orig_type == LegacyXdrIO::LIBM) // LIBMESH format
854  nn = mesh.elem(e)->n_nodes() + 2;
855 
856  else
857  libmesh_error_msg("Unrecognized orig_type = " << orig_type);
858 
859  // Loop over the connectivity entries for this element and write to conn.
860  START_LOG("set connectivity", "LegacyXdrIO::write_mesh");
861  const unsigned int loopmax = (orig_type==LegacyXdrIO::LIBM) ? nn-2 : nn;
862  for (unsigned int n=nstart; n<loopmax; n++)
863  {
864  unsigned int connectivity_value=0;
865 
866  // old-style Libmesh and MGF meshes
867  if (orig_type != LegacyXdrIO::LIBM)
868  connectivity_value = mesh.elem(e)->node(n-nstart);
869 
870  // new-style libMesh meshes: compress the connectivity entries to account for
871  // subactive nodes that will not be in the mesh we write out.
872  else
873  {
874  std::map<dof_id_type, dof_id_type>::iterator pos =
875  node_map.find(mesh.elem(e)->node(n-nstart));
876 
877  libmesh_assert (pos != node_map.end());
878 
879  connectivity_value = (*pos).second;
880  }
881  conn[lastConnIndex + n] = connectivity_value;
882  }
883  STOP_LOG("set connectivity", "LegacyXdrIO::write_mesh");
884 
885  // In the case of an adaptive mesh, set last 2 entries to this ID and parent ID
886  if (orig_type == LegacyXdrIO::LIBM)
887  {
888  int self_ID = mesh.elem(e)->id();
889  int parent_ID = -1;
890  if(level != 0)
891  parent_ID = mesh.elem(e)->parent()->id();
892 
893  // Self ID is the second-to-last entry, Parent ID is the last
894  // entry on each connectivity line
895  conn[lastConnIndex+nn-2] = self_ID;
896  conn[lastConnIndex+nn-1] = parent_ID;
897  }
898 
899  lastConnIndex += nn;
900  }
901 
902  // Send conn to the XDR file. If there are no elements of this level and type,
903  // then nn will be zero, and we there is no connectivity to write.
904  if (nn != 0)
905  m.Icon(&conn[0], nn, lastConnIndex/nn);
906  }
907  }
908 
909  // create the vector of coords and send
910  // it to the XDR file.
911  {
912  std::vector<Real> coords;
913 
914  coords.resize(3*node_map.size());
915  int lastIndex=0;
916 
917  std::map<dof_id_type,dof_id_type>::iterator it = node_map.begin();
918  const std::map<dof_id_type,dof_id_type>::iterator end = node_map.end();
919  for (; it != end; ++it)
920  {
921  const Point & p = mesh.node((*it).first);
922 
923  coords[lastIndex+0] = p(0);
924  coords[lastIndex+1] = p(1);
925  coords[lastIndex+2] = p(2);
926  lastIndex += 3;
927  }
928 
929  // Put the nodes in the XDR file
930  m.coord(&coords[0], 3, cast_int<int>(node_map.size()));
931  }
932 
933 
934  // write the
935  // boundary conditions
936  // if the BoundaryInfo
937  // object exists.
938  if (numBCs > 0)
939  {
940  std::vector<int> bcs(numBCs*3);
941 
942  //libMesh::out << "numBCs=" << numBCs << std::endl;
943 
944  //libMesh::out << "Preparing to write boundary conditions." << std::endl;
945  std::vector<dof_id_type> elem_list;
946  std::vector<unsigned short int> side_list;
947  std::vector<boundary_id_type> elem_id_list;
948 
949  mesh.get_boundary_info().build_side_list (elem_list, side_list, elem_id_list);
950 
951  for (int ibc=0; ibc<numBCs; ibc++)
952  {
953  bcs[0+ibc*3] = elem_list[ibc];
954  bcs[1+ibc*3] = side_list[ibc];
955  bcs[2+ibc*3] = elem_id_list[ibc];
956  }
957 
958  // Put the BCs in the XDR file
959  m.BC(&bcs[0], numBCs);
960  }
961 }
962 
963 
964 
965 void LegacyXdrIO::read_soln (const std::string & name,
966  std::vector<Real> & soln,
967  std::vector<std::string> & var_names) const
968 {
969  // Create an XdrSOLN object.
970  XdrSOLN s;
971 
972  // Create an XdrSHEAD object.
973  XdrSHEAD sh;
974 
975  // Open the XDR file for
976  // reading or writing.
977  // Note 1: Provide an additional argument
978  // to specify the dimension.
979  //
980  // Note 2: Has to do the right thing for
981  // both binary and ASCII files.
982  s.init((this->binary() ? XdrMGF::DECODE : XdrMGF::R_ASCII), name.c_str(), 0); // mesh files are always number 0 ...
983 
984  // From here on, things depend
985  // on whether we are reading or
986  // writing! First, we define
987  // header variables that may
988  // be read OR written.
989  int numVar = 0;
990  int numNodes = 0;
991  const char * varNames;
992 
993  // Get the information from
994  // the header, and place it
995  // in the header pointer.
996  s.header(&sh);
997 
998  // Read information from the
999  // file header. This depends on
1000  // whether its a libMesh or MGF mesh.
1001  numVar = sh.getWrtVar();
1002  numNodes = sh.getNumNodes();
1003  varNames = sh.getVarTitle();
1004 
1005  // Get the variable names
1006  {
1007  var_names.resize(numVar);
1008 
1009  const char * p = varNames;
1010 
1011  for (int i=0; i<numVar; i++)
1012  {
1013  var_names[i] = p;
1014  p += std::strlen(p) + 1;
1015  }
1016  }
1017 
1018  // Read the soln vector
1019  soln.resize(numVar*numNodes);
1020 
1021  s.values(&soln[0], numNodes);
1022 }
1023 
1024 
1025 
1026 void LegacyXdrIO::write_soln (const std::string & name,
1027  std::vector<Real> & soln,
1028  std::vector<std::string> & var_names) const
1029 {
1030  // get a read-only reference to the mesh
1031  const MeshBase & mesh = MeshOutput<MeshBase>::mesh();
1032 
1033  // Create an XdrSOLN object.
1034  XdrSOLN s;
1035 
1036  // Create an XdrSHEAD object.
1037  XdrSHEAD sh;
1038 
1039  // Open the XDR file for
1040  // reading or writing.
1041  // Note 1: Provide an additional argument
1042  // to specify the dimension.
1043  //
1044  // Note 2: Has to do the right thing for
1045  // both binary and ASCII files.
1046  s.init((this->binary() ? XdrMGF::ENCODE : XdrMGF::W_ASCII), name.c_str(), 0); // mesh files are always number 0 ...
1047 
1048  // Build the header
1049  sh.setWrtVar(cast_int<int>(var_names.size()));
1050  sh.setNumVar(cast_int<int>(var_names.size()));
1051  sh.setNumNodes(cast_int<int>(mesh.n_nodes()));
1052  sh.setNumBCs(cast_int<int>(mesh.get_boundary_info().n_boundary_conds()));
1053  sh.setMeshCnt(0);
1054  sh.setKstep(0);
1055  sh.setTime(0.);
1056  sh.setStrSize(65536);
1057  sh.setId("Id String"); // Ignored
1058  sh.setTitle("Title String"); // Ignored
1059  sh.setUserTitle("User Title String"); // Ignored
1060 
1061  // create the variable array
1062  {
1063  std::string var_title;
1064 
1065  for (unsigned int var=0; var<var_names.size(); var++)
1066  {
1067  for (unsigned int c=0; c<var_names[var].size(); c++)
1068  var_title += var_names[var][c];
1069 
1070  var_title += '\0';
1071  }
1072 
1073  sh.setVarTitle(var_title.c_str(), cast_int<int>(var_title.size()));
1074  }
1075 
1076  // Put the informationin the XDR file.
1077  s.header(&sh); // Needs to work for both types of file
1078 
1079  // Write the solution vector
1080  libmesh_assert_equal_to (soln.size(), var_names.size()*mesh.n_nodes());
1081 
1082  s.values(&soln[0], mesh.n_nodes());
1083 }
1084 
1085 } // namespace libMesh
int Icon(int *array, int numvar, int num)
Definition: xdr_mesh.h:89
unsigned int get_num_levels()
Definition: xdr_mgf.h:184
std::string name(const ElemQuality q)
Definition: elem_quality.C:39
int getSumWghts() const
Definition: xdr_mhead.h:83
const BoundaryInfo & get_boundary_info() const
Definition: mesh_base.h:111
void elem_types(const MeshBase &mesh, std::vector< ElemType > &et)
Definition: mesh_tools.C:523
virtual void reserve_nodes(const dof_id_type nn)=0
void get_num_elem_each_block(std::vector< unsigned int > &neeb) const
Definition: xdr_mhead.h:118
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:1554
void setNumVar(int numvar)
Definition: xdr_shead.h:58
bool subactive() const
Definition: elem.h:1739
virtual bool is_serial() const
Definition: mesh_base.h:134
void setNumNodes(int numNodes)
Definition: xdr_head.h:73
void setTime(Real time)
Definition: xdr_shead.h:103
static UniquePtr< Elem > build(const ElemType type, Elem *p=libmesh_nullptr)
Definition: elem.C:216
void read_binary(const std::string &, const LegacyXdrIO::FileFormat=LegacyXdrIO::LIBM)
const char * getVarTitle() const
Definition: xdr_shead.h:130
libmesh_assert(remote_elem)
STOP_LOG("std::sqrt()","ExactErrorEstimator")
void set_orig_flag(LegacyXdrIO::FileFormat in_orig_flag)
Definition: xdr_mgf.h:173
void set_num_elem_each_block(const std::vector< unsigned int > &neeb)
Definition: xdr_mhead.h:123
void write_mgf(const std::string &)
std::string complex_filename(const std::string &basename, unsigned int r_o_c=0)
Definition: utility.C:83
void init(XdrIO_TYPE type, const char *fn, int icnt)
Definition: xdr_soln.h:61
void write_ascii(const std::string &, const LegacyXdrIO::FileFormat=LegacyXdrIO::LIBM)
void setNumEl(int numel)
Definition: xdr_mhead.h:63
void get_block_elt_types(std::vector< ElemType > &bet) const
Definition: xdr_mhead.h:104
std::vector< bool > elems_of_dimension
Definition: mesh_input.h:97
virtual const Node & node(const dof_id_type i) const =0
int header(XdrSHEAD *hd)
Definition: xdr_soln.C:32
void setSumWghts(int sumWghts)
Definition: xdr_mhead.h:76
int getWrtVar() const
Definition: xdr_shead.h:76
const Elem * parent() const
Definition: elem.h:1810
LegacyXdrIO(MeshBase &, const bool=false)
Definition: legacy_xdr_io.C:57
MeshBase & mesh
void add_child(Elem *elem)
Definition: elem.C:1476
const class libmesh_nullptr_t libmesh_nullptr
void set_refinement_flag(const RefinementState rflag)
Definition: elem.h:1946
bool active() const
Definition: mesh_data.h:988
std::size_t n_boundary_conds() const
void set_n_blocks(const unsigned int nb)
Definition: xdr_mhead.h:96
IterBase * end
void add_foreign_node_id(const Node *node, const unsigned int foreign_node_id)
Definition: mesh_data.h:1020
const MT & mesh() const
Definition: mesh_output.h:199
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
int getNumEl() const
Definition: xdr_mhead.h:69
unsigned int get_n_blocks() const
Definition: xdr_mhead.h:91
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
void setUserTitle(const char *title)
Definition: xdr_shead.h:113
dof_id_type & set_id()
Definition: dof_object.h:628
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
void write_binary(const std::string &, const LegacyXdrIO::FileFormat=LegacyXdrIO::LIBM)
virtual element_iterator elements_begin()=0
virtual unsigned int dim() const =0
virtual unsigned int n_nodes() const =0
virtual void write(const std::string &) libmesh_override
virtual Elem * add_elem(Elem *e)=0
int getNumNodes() const
Definition: xdr_head.h:79
virtual element_iterator elements_end()=0
void setStrSize(int strSize)
Definition: xdr_head.h:99
virtual const Elem * elem(const dof_id_type i) const =0
unsigned int n_levels(const MeshBase &mesh)
Definition: mesh_tools.C:626
virtual void read(const std::string &) libmesh_override
Definition: legacy_xdr_io.C:98
void set_block_elt_types(const std::vector< ElemType > &bet)
Definition: xdr_mhead.h:109
void prepare_complex_data(const std::vector< Complex > &source, std::vector< Real > &real_part, std::vector< Real > &imag_part)
Definition: utility.C:99
OStreamProxy err(std::cerr)
void set_mesh_dimension(unsigned char d)
Definition: mesh_base.h:165
void read_ascii(const std::string &, const LegacyXdrIO::FileFormat=LegacyXdrIO::LIBM)
dof_id_type node(const unsigned int i) const
Definition: elem.h:1499
void setId(const char *id)
Definition: xdr_head.h:52
virtual void clear()
Definition: mesh_base.C:238
dof_id_type total_weight(const MeshBase &mesh)
Definition: mesh_tools.C:315
libmesh_parallel_only(this->comm())
void read_soln(const std::string &, std::vector< Real > &, std::vector< std::string > &) const
void init(XdrIO_TYPE type, const char *fn, int icnt, int dim=3)
Definition: xdr_mesh.h:63
void write_mesh(const std::string &, const LegacyXdrIO::FileFormat=LegacyXdrIO::LIBM)
void setNumBCs(int numBCs)
Definition: xdr_head.h:86
void read_mesh(const std::string &, const LegacyXdrIO::FileFormat=LegacyXdrIO::LIBM, MeshData *=libmesh_nullptr)
const Parallel::Communicator & comm() const
unsigned int mesh_dimension() const
Definition: mesh_base.C:127
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
int header(XdrMHEAD *hd)
Definition: xdr_mesh.C:28
void setMeshCnt(int meshCnt)
Definition: xdr_shead.h:81
void close_foreign_id_maps()
Definition: mesh_data.C:219
unsigned int level() const
Definition: elem.h:1852
void read_mgf(const std::string &)
int BC(int *array, int size)
Definition: xdr_mesh.h:107
void add_foreign_elem_id(const Elem *elem, const unsigned int foreign_elem_id)
Definition: mesh_data.h:1046
void write_mgf_soln(const std::string &name, std::vector< Number > &soln, std::vector< std::string > &var_names) const
void setWrtVar(int wrtVar)
Definition: xdr_shead.h:70
void setTitle(const char *title)
Definition: xdr_head.h:62
void setVarTitle(const char *titles, int len)
Definition: xdr_shead.h:124
void set_num_levels(unsigned int num_levels)
Definition: xdr_mgf.h:179
virtual dof_id_type n_elem() const =0
virtual const Node * node_ptr(const dof_id_type i) const =0
dof_id_type id() const
Definition: dof_object.h:619
LegacyXdrIO::FileFormat get_orig_flag() const
Definition: xdr_mgf.h:168
int getNumBCs() const
Definition: xdr_head.h:93
virtual ElemType type() const =0
processor_id_type processor_id()
Definition: libmesh_base.h:96
virtual void reserve_elem(const dof_id_type ne)=0
void setKstep(int kstep)
Definition: xdr_shead.h:92
void read_mgf_soln(const std::string &name, std::vector< Number > &soln, std::vector< std::string > &var_names) const
dof_id_type n_non_subactive_elem_of_type_at_level(const MeshBase &mesh, const ElemType type, const unsigned int level)
Definition: mesh_tools.C:558
virtual dof_id_type n_nodes() const =0
int values(Real *array, int size)
Definition: xdr_soln.h:86
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
uint8_t dof_id_type
Definition: id_types.h:64
int coord(Real *array, int dim, int size)
Definition: xdr_mesh.h:98
START_LOG("std::sqrt()","ExactErrorEstimator")
void write_soln(const std::string &name, std::vector< Real > &soln, std::vector< std::string > &) const