mesh_data.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 <sstream>
22 
23 // Local includes
24 #include "libmesh/mesh_data.h"
25 #include "libmesh/mesh_base.h"
27 #include "libmesh/elem.h"
28 
29 namespace libMesh
30 {
31 
32 
33 //------------------------------------------------------
34 // MeshData functions
36  _mesh (m),
37  _data_descriptor (""),
38  _node_id_map_closed (false),
39  _node_data_closed (false),
40  _elem_id_map_closed (false),
41  _elem_data_closed (false),
42  _active (false),
43  _compatibility_mode (false),
44  _unv_header (libmesh_nullptr)
45 {
46  // This class isn't actively maintained, doesn't work in parallel,
47  // and usually isn't as good a solution as adding an additional
48  // ExplicitSystem with appropriate data field(s).
49  libmesh_deprecated();
50 }
51 
52 
53 
54 
56 {
57  clear();
58 }
59 
60 
61 
62 
63 
64 void MeshData::activate (const std::string & descriptor)
65 {
66 #ifdef DEBUG
68  libMesh::err << "WARNING: MeshData was in compatibility mode, now being activated."
69  << std::endl;
70 #endif
71 
72  _compatibility_mode = false;
73  _active = true;
74  _data_descriptor = descriptor;
75 }
76 
77 
78 
79 
80 
81 void MeshData::enable_compatibility_mode (const std::string & descriptor)
82 {
83  if (!_active)
84  {
85  _compatibility_mode = true;
86  _active = false;
87  // do as if the id maps are already closed
88  _node_id_map_closed = true;
89  _elem_id_map_closed = true;
90  _data_descriptor = descriptor;
91  // we can safely clear the id maps
92  _node_id.clear();
93  _id_node.clear();
94  _elem_id.clear();
95  _id_elem.clear();
96  }
97 #ifdef DEBUG
98  else
99  libMesh::err << "WARNING: MeshData was in compatibility mode, now being activated."
100  << std::endl;
101 #endif
102 }
103 
104 
105 
106 
107 
108 
110 {
111  _data_descriptor = "";
112  _node_data.clear();
113  _elem_data.clear();
114  _node_data_closed = false;
115  _elem_data_closed = false;
116 }
117 
118 
119 
120 
121 
122 void MeshData::slim (const bool node_id_map,
123  const bool elem_id_map)
124 {
125  if (this->active())
126  {
127 
128  if (node_id_map)
129  {
130  // dumb check
132 
133  _node_id_map_closed = false;
134  _node_id.clear();
135  _id_node.clear();
136  }
137 
138  if (elem_id_map)
139  {
140  // dumb check
142 
143  _elem_id_map_closed = false;
144  _elem_id.clear();
145  _id_elem.clear();
146  }
147  }
148 
149 #ifdef DEBUG
150  else if (this->compatibility_mode())
151  {
152  libMesh::err << "WARNING: No need for MeshData::slim() in compatibility mode." << std::endl;
153  }
154 #endif
155 }
156 
157 
158 
159 
160 void MeshData::translate (const MeshBase & out_mesh,
161  std::vector<Number> & values,
162  std::vector<std::string> & names) const
163 {
165 
166  LOG_SCOPE("translate()", "MeshData");
167 
168  const unsigned int n_comp = this->n_val_per_node();
169 
170  // transfer our nodal data to a vector
171  // that may be written concurrently
172  // with the \p out_mesh.
173  {
174  // reserve memory for the nodal data
175  values.reserve(n_comp*out_mesh.n_nodes());
176 
177  // iterate over the mesh's nodes
178  MeshBase::const_node_iterator nodes_it = out_mesh.nodes_begin();
179  const MeshBase::const_node_iterator nodes_end = out_mesh.nodes_end();
180 
181  // Do not use the \p get_data() method, but the operator()
182  // method, since this returns by default a zero value,
183  // when there is no nodal data.
184  for (; nodes_it != nodes_end; ++nodes_it)
185  {
186  const Node * node = *nodes_it;
187 
188  for (unsigned int c= 0; c<n_comp; c++)
189  values.push_back(this->operator()(node, c));
190  }
191  }
192 
193 
194 
195  // Now we have the data, nicely stored in \p values.
196  // It remains to give names to the data, then write to
197  // file.
198  {
199  names.reserve(n_comp);
200 
201  // this naming scheme only works up to n_comp=100
202  // (at least for gmv-accepted variable names)
203  libmesh_assert_less (n_comp, 100);
204 
205  for (unsigned int n=0; n<n_comp; n++)
206  {
207  std::ostringstream name_buf;
208  name_buf << "bc_" << n;
209  names.push_back(name_buf.str());
210  }
211  }
212 }
213 
214 
215 
216 
218 {
219  if (_active)
220  {
221  libmesh_assert (!_elem_id.empty());
222  libmesh_assert (!_id_elem.empty());
223  libmesh_assert (!_node_id.empty());
224  libmesh_assert (!_id_node.empty());
225 
226  _elem_id_map_closed = true;
227  _node_id_map_closed = true;
228  }
229 }
230 
231 
232 
233 
234 
235 void MeshData::read (const std::string & name)
236 {
237  LOG_SCOPE("read()", "MeshData");
238 
240 
241  // the id maps have to be closed before reading
242  // (note that in compatibility mode these are also true)
244 
245 #ifdef DEBUG
246  if (this->compatibility_mode())
247  libMesh::err << "WARNING: MeshData in compatibility mode, node and element ids" << std::endl
248  << " stored in file may be totally different from libMesh ids!" << std::endl;
249 #endif
250 
251  // Read the file based on extension. We let all processors read the
252  // data because it would be inaccurate to let only one processor
253  // have it and we're too lazy to code up a proper parallel read or
254  // read+broadcast right now.
255 
256  if (name.rfind(".xta") < name.size())
257  this->read_xdr (name, READ);
258 
259  else if (name.rfind(".xtr") < name.size())
260  this->read_xdr (name, DECODE);
261 
262  else if (name.rfind(".unv") < name.size())
263  this->read_unv (name);
264 
265  else if ((name.rfind(".node") < name.size()) ||
266  (name.rfind(".ele") < name.size()))
267  this->read_tetgen (name);
268 
269  else
270  libmesh_error_msg(" ERROR: Unrecognized file extension: " << name \
271  << "\n I understand the following:\n\n" \
272  << " *.xta -- Internal ASCII data format\n" \
273  << " *.xtr -- Internal binary data format\n" \
274  << " *.unv -- I-deas format");
275 }
276 
277 
278 
279 
280 
281 
282 void MeshData::write (const std::string & name)
283 {
284  LOG_SCOPE("write()", "MeshData");
285 
287 
288  // the id maps have to be closed before writing
289  // (note that in compatibility mode these are also true)
291 
292 #ifdef DEBUG
293  if (this->compatibility_mode())
294  libMesh::err << "WARNING: MeshData in compatibility mode. Node and element ids" << std::endl
295  << " written to file may differ from libMesh numbering" << std::endl
296  << " next time this file is read!" << std::endl;
297 #endif
298 
299  // Read the file based on extension
300  {
301  if (name.rfind(".xta") < name.size())
302  write_xdr (name, WRITE);
303 
304  else if (name.rfind(".xtr") < name.size())
305  write_xdr (name, ENCODE);
306 
307  else if (name.rfind(".unv") < name.size())
308  write_unv (name);
309 
310  else
311  libmesh_error_msg(" ERROR: Unrecognized file extension: " << name \
312  << "\n I understand the following:\n\n" \
313  << " *.xta -- Internal ASCII data format\n" \
314  << " *.xtr -- Internal binary data format\n" \
315  << " *.unv -- I-deas format");
316  }
317 }
318 
319 
320 
321 
322 std::string MeshData::get_info() const
323 {
324  std::ostringstream oss;
325 
326  if (this->active() || this->compatibility_mode())
327  {
328  oss << " MeshData Information:\n";
329  if (this->active())
330  oss << " object activated.\n";
331  if (this->compatibility_mode())
332  oss << " object in compatibility mode.\n";
333  if (this->_data_descriptor != "")
334  oss << " descriptor=" << this->_data_descriptor << '\n';
335  if (this->elem_initialized())
336  oss << " Element associated data initialized.\n"
337  << " n_val_per_elem()=" << this->n_val_per_elem() << '\n'
338  << " n_elem_data()=" << this->n_elem_data() << '\n';
339  if (this->node_initialized())
340  oss << " Node associated data initialized.\n"
341  << " n_val_per_node()=" << this->n_val_per_node() << '\n'
342  << " n_node_data()=" << this->n_node_data() << '\n';
343  }
344  else
345  oss << " MeshData neither active nor in compatibility mode.\n";
346 
347  return oss.str();
348 }
349 
350 
351 
352 
353 void MeshData::print_info(std::ostream & os) const
354 {
355  os << this->get_info()
356  << std::endl;
357 }
358 
359 
360 std::ostream & operator << (std::ostream & os, const MeshData & m)
361 {
362  m.print_info(os);
363  return os;
364 }
365 
366 
367 
368 
369 const Node * MeshData::foreign_id_to_node (const unsigned int fid) const
370 {
371  if (_active)
372  {
373  // when active, use our _id_node map
375 
376  std::map<unsigned int,
377  const Node *>::const_iterator pos = _id_node.find(fid);
378 
379  if (pos == _id_node.end())
380  libmesh_error_msg("ERROR: Have no Node * associated with the foreign id = " << fid);
381 
382  else
383  return pos->second;
384  }
385  else if (_compatibility_mode)
386  // when only in compatibility mode,
387  // return the node stored in the MeshBase
388  // under its current id
389  return this->_mesh.node_ptr(fid);
390 
391  libmesh_error_msg("We'll never get here!");
392  return libmesh_nullptr;
393 }
394 
395 
396 
397 
398 
399 unsigned int MeshData::node_to_foreign_id (const Node * n) const
400 {
401  libmesh_assert(n);
402 
403  if (_active)
404  {
405  // when active, use our _node_id map
407 
408  // look it up in the map
409  std::map<const Node *,
410  unsigned int>::const_iterator pos = _node_id.find(n);
411 
412  if (pos == _node_id.end())
413  libmesh_error_msg("ERROR: No foreign id stored for the node with the libMesh id = " << n->id());
414 
415  else
416  return pos->second;
417  }
418  else if (_compatibility_mode)
419  // when only in compatibility mode,
420  // return libMesh's node id
421  return n->id();
422 
423  libmesh_error_msg("We'll never get here!");
424  return 0;
425 }
426 
427 
428 
429 
430 
431 
432 
433 
434 const Elem * MeshData::foreign_id_to_elem (const unsigned int fid) const
435 {
436  if (_active)
437  {
438  // when active, use our _id_elem map
440 
441  std::map<unsigned int,
442  const Elem *>::const_iterator pos = _id_elem.find(fid);
443 
444  if (pos == _id_elem.end())
445  libmesh_error_msg("ERROR: Have no Elem * associated with the foreign id = " << fid);
446 
447  else
448  return pos->second;
449  }
450  else if (_compatibility_mode)
451  // when only in compatibility mode,
452  // return element using the libMesh id
453  return this->_mesh.elem_ptr(fid);
454 
455  libmesh_error_msg("We'll never get here!");
456  return libmesh_nullptr;
457 }
458 
459 
460 
461 
462 
463 unsigned int MeshData::elem_to_foreign_id (const Elem * e) const
464 {
465  libmesh_assert(e);
466 
467  if (_active)
468  {
469  // when active, use our _id_elem map
471 
472  // look it up in the map
473  std::map<const Elem *,
474  unsigned int>::const_iterator pos = _elem_id.find(e);
475 
476  if (pos == _elem_id.end())
477  libmesh_error_msg("ERROR: No foreign id stored for the element with the libMesh id = " << e->id());
478 
479  else
480  return pos->second;
481  }
482  else if (_compatibility_mode)
483  // when only in compatibility mode,
484  // return libMesh's element id
485  return e->id();
486 
487  libmesh_error_msg("We'll never get here!");
488  return 0;
489 }
490 
491 
492 
493 
494 
495 
496 
497 void MeshData::insert_node_data (std::map<const Node *,
498  std::vector<Number> > & nd,
499  const bool close_elem_data)
500 {
501  libmesh_assert (this->_active || this->_compatibility_mode);
502  // these are also true in compatibility mode
504 
505  if (this->_node_data_closed)
506  libmesh_error_msg("ERROR: Nodal data already closed! Use clear() first!");
507 
508  libmesh_assert (this->_node_data.empty());
509 
510 #ifdef DEBUG
511  std::map<const Node *,
512  std::vector<Number> >::const_iterator nd_pos = nd.begin();
513  std::map<const Node *,
514  std::vector<Number> >::const_iterator nd_end = nd.end();
515 
516  // Compare entity-by-entity that the
517  // sizes of the std::vector's are identical.
518  // For this, simply take the length of the 0th
519  // entry as reference length, and compare this
520  // with the length of the 1st, 2nd...
521  libmesh_assert (nd_pos != nd_end);
522  const std::size_t reference_length = (*nd_pos).second.size();
523 
524  // advance, so that we compare with the 1st
525  ++nd_pos;
526 
527  for (; nd_pos != nd_end; ++nd_pos)
528  if ( (*nd_pos).second.size() != reference_length)
529  libmesh_error_msg("ERROR: Size mismatch.");
530 #endif
531 
532  // copy over
533  _node_data = nd;
534 
535  // we may freely trash the nd
536  nd.clear();
537 
538  // close node data
539  this->_node_data_closed = true;
540 
541  // if user wants to, then close elem data, too
542  if (close_elem_data)
543  {
545  this->_elem_data_closed = true;
546  }
547 }
548 
549 
550 
551 
552 
553 void MeshData::insert_elem_data (std::map<const Elem *,
554  std::vector<Number> > & ed,
555  const bool close_node_data)
556 {
557  libmesh_assert (this->_active || this->_compatibility_mode);
558  // these are also true in compatibility mode
560 
561  if (this->_elem_data_closed)
562  libmesh_error_msg("ERROR: Element data already closed! Use clear() first!");
563 
564  libmesh_assert (this->_elem_data.empty());
565 
566 #ifdef DEBUG
567  std::map<const Elem *,
568  std::vector<Number> >::const_iterator ed_pos = ed.begin();
569  std::map<const Elem *,
570  std::vector<Number> >::const_iterator ed_end = ed.end();
571 
572  // Compare entity-by-entity that the
573  // sizes of the std::vector's are identical.
574  const std::size_t reference_length = (*ed_pos).second.size();
575  ++ed_pos;
576 
577  for (; ed_pos != ed_end; ++ed_pos)
578  if ( (*ed_pos).second.size() != reference_length)
579  libmesh_error_msg("ERROR: Size mismatch.");
580 #endif
581 
582  // copy over
583  _elem_data = ed;
584 
585  // we may freely trash the ed
586  ed.clear();
587 
588  // close elem data
589  this->_elem_data_closed = true;
590 
591  // if user wants to, then close node data, too
592  if (close_node_data)
593  {
595  this->_node_data_closed = true;
596  }
597 }
598 
599 
600 
601 
602 
603 unsigned int MeshData::n_val_per_node () const
604 {
605  libmesh_assert (this->_active || this->_compatibility_mode);
607 
608  if (!this->_node_data.empty())
609  {
610  std::map<const Node *,
611  std::vector<Number> >::const_iterator pos = _node_data.begin();
612  libmesh_assert (pos != _node_data.end());
613  return cast_int<unsigned int>(pos->second.size());
614  }
615  else
616  return 0;
617 }
618 
619 
620 
621 
623 {
624  libmesh_assert (this->_active || this->_compatibility_mode);
626 
627  return cast_int<dof_id_type>(this->_node_data.size());
628 }
629 
630 
631 
632 
633 unsigned int MeshData::n_val_per_elem () const
634 {
635  libmesh_assert (this->_active || this->_compatibility_mode);
637 
638  if (!_elem_data.empty())
639  {
640  std::map<const Elem *,
641  std::vector<Number> >::const_iterator pos = _elem_data.begin();
642  libmesh_assert (pos != _elem_data.end());
643  return cast_int<unsigned int>(pos->second.size());
644  }
645  else
646  return 0;
647 }
648 
649 
650 
651 
653 {
654  libmesh_assert (this->_active || this->_compatibility_mode);
656 
657  return cast_int<dof_id_type>(_elem_data.size());
658 }
659 
660 
661 
662 
663 void MeshData::assign (const MeshData & omd)
664 {
668 
669  // we have to be able to modify our elem id maps
671 
673  this->_active = omd._active;
675 
676  // this is ok because we do not manage the UnvHeader
677  // in terms of memory, but only hold a pointer to it...
678  this->_unv_header = omd._unv_header;
679 
680  // Now copy the foreign id maps -- but only for the
681  // nodes. The nodes of the boundary mesh are actually
682  // nodes of the volume mesh.
683  this->_node_id = omd._node_id;
684  this->_id_node = omd._id_node;
685 
686  // The element vector of the boundary mesh contains elements
687  // that are new, and there _cannot_ be any associated
688  // foreign id in the maps. Therefore, fill the maps with
689  // the libMesh id's. But only when the other MeshData
690  // has element ids.
691  if ((this->_active) && (omd._elem_id.size() != 0))
692  {
693 
696 
697  for (; elem_it != elem_end; ++elem_it)
698  {
699  const Elem * elem = *elem_it;
700  this->add_foreign_elem_id(elem, elem->id());
701  }
702  }
703 
704  // now we can safely assign omd's value
706 
707 
708  // and finally the node- and element-associated data
709  this->_node_data = omd._node_data;
710  this->_elem_data = omd._elem_data;
711 }
712 
713 } // namespace libMesh
std::string name(const ElemQuality q)
Definition: elem_quality.C:39
bool _node_id_map_closed
Definition: mesh_data.h:575
A geometric point in (x,y,z) space associated with a DOF.
Definition: node.h:54
unsigned int n_val_per_elem() const
Definition: mesh_data.C:633
libmesh_assert(remote_elem)
void insert_node_data(std::map< const Node *, std::vector< Number > > &nd, const bool close_elem_data=true)
Definition: mesh_data.C:497
The base class for all geometric element types.
Definition: elem.h:92
const class libmesh_nullptr_t libmesh_nullptr
bool active() const
Definition: mesh_data.h:988
void write_xdr(const std::string &name, const XdrMODE mode=WRITE)
bool _elem_id_map_closed
Definition: mesh_data.h:593
void slim(const bool node_id_map=true, const bool elem_id_map=true)
Definition: mesh_data.C:122
Base class for Mesh.
Definition: mesh_base.h:70
void print_info(std::ostream &os=libMesh::out) const
Definition: mesh_data.C:353
std::map< unsigned int, const Node * > _id_node
Definition: mesh_data.h:539
bool elem_initialized() const
Definition: mesh_data.h:1004
virtual node_iterator nodes_begin()=0
virtual element_iterator elements_begin()=0
void translate(const MeshBase &out_mesh, std::vector< Number > &data_values, std::vector< std::string > &data_names) const
Definition: mesh_data.C:160
unsigned int node_to_foreign_id(const Node *n) const
Definition: mesh_data.C:399
std::string get_info() const
Definition: mesh_data.C:322
bool _compatibility_mode
Definition: mesh_data.h:614
virtual element_iterator elements_end()=0
MeshData(const MeshBase &m)
Definition: mesh_data.C:35
const Elem * foreign_id_to_elem(const unsigned int fid) const
Definition: mesh_data.C:434
bool _elem_data_closed
Definition: mesh_data.h:599
void read_unv(const std::string &file_name)
OStreamProxy err(std::cerr)
void read_xdr(const std::string &name, const XdrMODE mode=READ)
std::string _data_descriptor
Definition: mesh_data.h:515
void write(const std::string &name)
Definition: mesh_data.C:282
virtual const Elem * elem_ptr(const dof_id_type i) const =0
dof_id_type n_elem_data() const
Definition: mesh_data.C:652
unsigned int elem_to_foreign_id(const Elem *n) const
Definition: mesh_data.C:463
std::map< const Elem *, unsigned int > _elem_id
Definition: mesh_data.h:556
virtual node_iterator nodes_end()=0
void read(const std::string &name)
Definition: mesh_data.C:235
void write_unv(const std::string &file_name)
const MeshBase & _mesh
Definition: mesh_data.h:509
MeshDataUnvHeader * _unv_header
Definition: mesh_data.h:619
void activate(const std::string &descriptor="")
Definition: mesh_data.C:64
void insert_elem_data(std::map< const Elem *, std::vector< Number > > &ed, const bool close_node_data=true)
Definition: mesh_data.C:553
void close_foreign_id_maps()
Definition: mesh_data.C:217
void enable_compatibility_mode(const std::string &descriptor="")
Definition: mesh_data.C:81
dof_id_type n_node_data() const
Definition: mesh_data.C:622
std::map< unsigned int, const Elem * > _id_elem
Definition: mesh_data.h:562
void add_foreign_elem_id(const Elem *elem, const unsigned int foreign_elem_id)
Definition: mesh_data.h:1046
std::map< const Node *, unsigned int > _node_id
Definition: mesh_data.h:532
void assign(const MeshData &omd)
Definition: mesh_data.C:663
unsigned int n_val_per_node() const
Definition: mesh_data.C:603
const Node * foreign_id_to_node(const unsigned int fid) const
Definition: mesh_data.C:369
std::map< const Node *, std::vector< Number > > _node_data
Definition: mesh_data.h:525
virtual const Node * node_ptr(const dof_id_type i) const =0
dof_id_type id() const
Definition: dof_object.h:624
void read_tetgen(const std::string &name)
std::map< const Elem *, std::vector< Number > > _elem_data
Definition: mesh_data.h:549
std::ostream & operator<<(std::ostream &os, const FEAbstract &fe)
Definition: fe_abstract.C:780
bool compatibility_mode() const
Definition: mesh_data.h:996
virtual dof_id_type n_nodes() const =0
bool node_initialized() const
Definition: mesh_data.h:1012
uint8_t dof_id_type
Definition: id_types.h:64
bool _node_data_closed
Definition: mesh_data.h:581