1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 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 #ifndef LIBMESH_MESH_BASE_H
21 #define LIBMESH_MESH_BASE_H
22
23 // Local Includes
24 #include "libmesh/dof_object.h" // for invalid_processor_id
25 #include "libmesh/int_range.h"
26 #include "libmesh/libmesh_common.h"
27 #include "libmesh/multi_predicates.h"
28 #include "libmesh/point_locator_base.h"
29 #include "libmesh/variant_filter_iterator.h"
30 #include "libmesh/parallel_object.h"
31 #include "libmesh/simple_range.h"
32
33 #ifdef LIBMESH_FORWARD_DECLARE_ENUMS
34 namespace libMesh
35 {
36 enum ElemType : int;
37 enum ElemMappingType : unsigned char;
38 }
39 #else
40 #include "libmesh/enum_elem_type.h"
41 #endif
42
43 // C++ Includes
44 #include <cstddef>
45 #include <string>
46 #include <memory>
47
48 namespace libMesh
49 {
50
51 // forward declarations
52 class Elem;
53 class GhostingFunctor;
54 class Node;
55 class Point;
56 class Partitioner;
57 class BoundaryInfo;
58
59 template <class MT>
60 class MeshInput;
61
62
63 /**
64 * This is the \p MeshBase class. This class provides all the data necessary
65 * to describe a geometric entity. It allows for the description of a
66 * \p dim dimensional object that lives in \p LIBMESH_DIM-dimensional space.
67 * \par
68 * A mesh is made of nodes and elements, and this class provides data
69 * structures to store and access both. A mesh may be partitioned into a
70 * number of subdomains, and this class provides that functionality.
71 * Furthermore, this class provides functions for reading and writing a
72 * mesh to disk in various formats.
73 *
74 * \author Benjamin S. Kirk
75 * \date 2002
76 * \brief Base class for Mesh.
77 */
78 class MeshBase : public ParallelObject
79 {
80 public:
81
82 /**
83 * Constructor. Takes \p dim, the dimension of the mesh.
84 * The mesh dimension can be changed (and may automatically be
85 * changed by mesh generation/loading) later.
86 */
87 MeshBase (const Parallel::Communicator & comm_in,
88 unsigned char dim=1);
89
90 /**
91 * Copy-constructor.
92 */
93 MeshBase (const MeshBase & other_mesh);
94
95 /**
96 * Move-constructor - deleted because after a theoretical move-construction
97 * and then destruction of the moved-from object, the moved \p BoundaryInfo
98 * would hold an invalid reference to the moved-from mesh
99 */
100 MeshBase(MeshBase &&) = delete;
101
102 /**
103 * Copy and move assignment are not allowed because MeshBase
104 * subclasses manually manage memory (Elems and Nodes) and therefore
105 * the default versions of these operators would leak memory. Since
106 * we don't want to maintain non-default copy and move assignment
107 * operators at this time, the safest and most self-documenting
108 * approach is to delete them.
109 *
110 * If you need to copy a Mesh, use the clone() method.
111 */
112 MeshBase & operator= (const MeshBase &) = delete;
113 MeshBase & operator= (MeshBase &&) = delete;
114
115 /**
116 * Virtual "copy constructor"
117 */
118 virtual std::unique_ptr<MeshBase> clone() const = 0;
119
120 /**
121 * Destructor.
122 */
123 virtual ~MeshBase ();
124
125 /**
126 * A partitioner to use at each prepare_for_use()
127 */
partitioner()128 virtual std::unique_ptr<Partitioner> & partitioner() { return _partitioner; }
129
130 /**
131 * The information about boundary ids on the mesh
132 */
get_boundary_info()133 const BoundaryInfo & get_boundary_info() const { return *boundary_info; }
134
135 /**
136 * Writable information about boundary ids on the mesh
137 */
get_boundary_info()138 BoundaryInfo & get_boundary_info() { return *boundary_info; }
139
140 /**
141 * Deletes all the element and node data that is currently stored.
142 *
143 * elem and node extra_integer data is nevertheless *retained* here,
144 * for better compatibility between that feature and older code's
145 * use of MeshBase::clear()
146 */
147 virtual void clear ();
148
149 /**
150 * \returns \p true if the mesh has been prepared via a call
151 * to \p prepare_for_use, \p false otherwise.
152 */
is_prepared()153 bool is_prepared () const
154 { return _is_prepared; }
155
156 /**
157 * \returns \p true if all elements and nodes of the mesh
158 * exist on the current processor, \p false otherwise
159 */
is_serial()160 virtual bool is_serial () const
161 { return true; }
162
163 /**
164 * \returns \p true if all elements and nodes of the mesh
165 * exist on the processor 0, \p false otherwise
166 */
is_serial_on_zero()167 virtual bool is_serial_on_zero () const
168 { return true; }
169
170 /**
171 * Asserts that not all elements and nodes of the mesh necessarily
172 * exist on the current processor. Only valid to call on classes
173 * which can be created in a distributed form.
174 */
set_distributed()175 virtual void set_distributed ()
176 { libmesh_error(); }
177
178 /**
179 * \returns \p true if new elements and nodes can and should be
180 * created in synchronization on all processors, \p false otherwise
181 */
is_replicated()182 virtual bool is_replicated () const
183 { return true; }
184
185 /**
186 * Gathers all elements and nodes of the mesh onto
187 * every processor
188 */
allgather()189 virtual void allgather () {}
190
191 /**
192 * Gathers all elements and nodes of the mesh onto
193 * processor zero
194 */
gather_to_zero()195 virtual void gather_to_zero() {}
196
197 /**
198 * When supported, deletes all nonlocal elements of the mesh
199 * except for "ghosts" which touch a local element, and deletes
200 * all nodes which are not part of a local or ghost element
201 */
delete_remote_elements()202 virtual void delete_remote_elements () {}
203
204 /**
205 * \returns The logical dimension of the mesh; i.e. the manifold
206 * dimension of the elements in the mesh. If we ever support
207 * multi-dimensional meshes (e.g. hexes and quads in the same mesh)
208 * then this will return the largest such dimension.
209 */
210 unsigned int mesh_dimension () const;
211
212 /**
213 * Resets the logical dimension of the mesh. If the mesh has
214 * elements of multiple dimensions, this should be set to the largest
215 * dimension. E.g. if the mesh has 1D and 2D elements, this should
216 * be set to 2. If the mesh has 2D and 3D elements, this should be
217 * set to 3.
218 */
set_mesh_dimension(unsigned char d)219 void set_mesh_dimension (unsigned char d)
220 { _elem_dims.clear(); _elem_dims.insert(d); }
221
222 /**
223 * \returns A const reference to a std::set of element dimensions
224 * present in the mesh.
225 */
elem_dimensions()226 const std::set<unsigned char> & elem_dimensions() const
227 { return _elem_dims; }
228
229 /**
230 * Most of the time you should not need to call this, as the element
231 * dimensions will be set automatically by a call to cache_elem_dims(),
232 * therefore only call this if you know what you're doing.
233 *
234 * In some specialized situations, for example when adding a single
235 * Elem on all procs, it can be faster to skip calling cache_elem_dims()
236 * and simply specify the element dimensions manually, which is why this
237 * setter exists.
238 */
239 void set_elem_dimensions(const std::set<unsigned char> & elem_dims);
240
241 /**
242 * \returns The "spatial dimension" of the mesh.
243 *
244 * The spatial dimension is defined as:
245 *
246 * 1 - for an exactly x-aligned mesh of 1D elements
247 * 2 - for an exactly x-y planar mesh of 2D elements
248 * 3 - otherwise
249 *
250 * No tolerance checks are performed to determine whether the Mesh
251 * is x-aligned or x-y planar, only strict equality with zero in the
252 * higher dimensions is checked. Also, x-z and y-z planar meshes are
253 * considered to have spatial dimension == 3.
254 *
255 * The spatial dimension is updated during prepare_for_use() based
256 * on the dimensions of the various elements present in the Mesh,
257 * but is *never automatically decreased* by this function.
258 *
259 * For example, if the user calls set_spatial_dimension(2) and then
260 * later inserts 3D elements into the mesh,
261 * Mesh::spatial_dimension() will return 3 after the next call to
262 * prepare_for_use(). On the other hand, if the user calls
263 * set_spatial_dimension(3) and then inserts only x-aligned 1D
264 * elements into the Mesh, mesh.spatial_dimension() will remain 3.
265 */
266 unsigned int spatial_dimension () const;
267
268 /**
269 * Sets the "spatial dimension" of the Mesh. See the documentation
270 * for Mesh::spatial_dimension() for more information.
271 */
272 void set_spatial_dimension(unsigned char d);
273
274 /**
275 * \returns The number of nodes in the mesh.
276 *
277 * This function and others must be defined in derived classes since
278 * the MeshBase class has no specific storage for nodes or elements.
279 * The standard \p n_nodes() function may return a cached value on
280 * distributed meshes, and so can be called by any processor at any
281 * time.
282 */
283 virtual dof_id_type n_nodes () const = 0;
284
285 /**
286 * \returns The number of nodes in the mesh.
287 *
288 * This function and others must be overridden in derived classes since
289 * the MeshBase class has no specific storage for nodes or elements.
290 * The \p parallel_n_nodes() function computes a parallel-synchronized
291 * value on distributed meshes, and so must be called in parallel
292 * only.
293 */
294 virtual dof_id_type parallel_n_nodes () const = 0;
295
296 /**
297 * \returns The number of nodes on processor \p proc.
298 */
299 dof_id_type n_nodes_on_proc (const processor_id_type proc) const;
300
301 /**
302 * \returns The number of nodes on the local processor.
303 */
n_local_nodes()304 dof_id_type n_local_nodes () const
305 { return this->n_nodes_on_proc (this->processor_id()); }
306
307 /**
308 * \returns The number of nodes owned by no processor.
309 */
n_unpartitioned_nodes()310 dof_id_type n_unpartitioned_nodes () const
311 { return this->n_nodes_on_proc (DofObject::invalid_processor_id); }
312
313 /**
314 * \returns A number greater than or equal to the maximum node id in the
315 * mesh.
316 */
317 virtual dof_id_type max_node_id () const = 0;
318
319 #ifdef LIBMESH_ENABLE_UNIQUE_ID
320 /**
321 * \returns The next unique id to be used.
322 */
next_unique_id()323 unique_id_type next_unique_id() { return _next_unique_id; }
324
325 /**
326 * Sets the next available unique id to be used. On a
327 * ReplicatedMesh, or when adding unpartitioned objects to a
328 * DistributedMesh, this must be kept in sync on all processors.
329 *
330 * On a DistributedMesh, other unique_id values (larger than this
331 * one) may be chosen next, to allow unique_id assignment without
332 * communication.
333 */
334 virtual void set_next_unique_id(unique_id_type id) = 0;
335 #endif
336
337 /**
338 * Reserves space for a known number of nodes.
339 *
340 * \note This method may or may not do anything, depending on the
341 * actual \p Mesh implementation. If you know the number of nodes
342 * you will add and call this method before repeatedly calling \p
343 * add_point() the implementation will be more efficient.
344 */
345 virtual void reserve_nodes (const dof_id_type nn) = 0;
346
347 /**
348 * \returns The number of elements in the mesh.
349 *
350 * The standard n_elem() function may return a cached value on
351 * distributed meshes, and so can be called by any processor at any
352 * time.
353 */
354 virtual dof_id_type n_elem () const = 0;
355
356 /**
357 * \returns The number of elements in the mesh.
358 *
359 * The parallel_n_elem() function computes a parallel-synchronized
360 * value on distributed meshes, and so must be called in parallel
361 * only.
362 */
363 virtual dof_id_type parallel_n_elem () const = 0;
364
365 /**
366 * \returns A number greater than or equal to the maximum element id in the
367 * mesh.
368 */
369 virtual dof_id_type max_elem_id () const = 0;
370
371 /**
372 * \returns A number greater than or equal to the maximum unique_id in the
373 * mesh.
374 */
375 #ifdef LIBMESH_ENABLE_UNIQUE_ID
376 virtual unique_id_type parallel_max_unique_id () const = 0;
377 #endif
378
379 /**
380 * Reserves space for a known number of elements.
381 *
382 * \note This method may or may not do anything, depending on the
383 * actual \p Mesh implementation. If you know the number of
384 * elements you will add and call this method before repeatedly
385 * calling \p add_point() the implementation will be more efficient.
386 */
387 virtual void reserve_elem (const dof_id_type ne) = 0;
388
389 /**
390 * Updates parallel caches so that methods like n_elem()
391 * accurately reflect changes on other processors
392 */
393 virtual void update_parallel_id_counts () = 0;
394
395 /**
396 * \returns The number of active elements in the mesh.
397 *
398 * Implemented in terms of active_element_iterators.
399 */
400 virtual dof_id_type n_active_elem () const = 0;
401
402 /**
403 * \returns The number of elements on processor \p proc.
404 */
405 dof_id_type n_elem_on_proc (const processor_id_type proc) const;
406
407 /**
408 * \returns The number of elements on the local processor.
409 */
n_local_elem()410 dof_id_type n_local_elem () const
411 { return this->n_elem_on_proc (this->processor_id()); }
412
413 /**
414 * \returns The number of elements owned by no processor.
415 */
n_unpartitioned_elem()416 dof_id_type n_unpartitioned_elem () const
417 { return this->n_elem_on_proc (DofObject::invalid_processor_id); }
418
419 /**
420 * \returns The number of active elements on processor \p proc.
421 */
422 dof_id_type n_active_elem_on_proc (const processor_id_type proc) const;
423
424 /**
425 * \returns The number of active elements on the local processor.
426 */
n_active_local_elem()427 dof_id_type n_active_local_elem () const
428 { return this->n_active_elem_on_proc (this->processor_id()); }
429
430 /**
431 * \returns The number of elements that will be written
432 * out in certain I/O formats.
433 *
434 * For example, a 9-noded quadrilateral will be broken into 4 linear
435 * sub-elements for plotting purposes. Thus, for a mesh of 2 \p
436 * QUAD9 elements \p n_tecplot_elem() will return 8. Implemented in
437 * terms of element_iterators.
438 */
439 dof_id_type n_sub_elem () const;
440
441 /**
442 * Same as \p n_sub_elem(), but only counts active elements.
443 */
444 dof_id_type n_active_sub_elem () const;
445
446 /**
447 * \returns A constant reference (for reading only) to the
448 * \f$ i^{th} \f$ point, which should be present in this processor's
449 * subset of the mesh data structure.
450 */
451 virtual const Point & point (const dof_id_type i) const = 0;
452
453 /**
454 * \returns A constant reference (for reading only) to the
455 * \f$ i^{th} \f$ node, which should be present in this processor's
456 * subset of the mesh data structure.
457 */
node_ref(const dof_id_type i)458 virtual const Node & node_ref (const dof_id_type i) const {
459 return *this->node_ptr(i);
460 }
461
462 /**
463 * \returns A reference to the \f$ i^{th} \f$ node, which should be
464 * present in this processor's subset of the mesh data structure.
465 */
node_ref(const dof_id_type i)466 virtual Node & node_ref (const dof_id_type i) {
467 return *this->node_ptr(i);
468 }
469
470 /**
471 * \returns A pointer to the \f$ i^{th} \f$ node, which should be
472 * present in this processor's subset of the mesh data structure.
473 */
474 virtual const Node * node_ptr (const dof_id_type i) const = 0;
475
476 /**
477 * \returns A writable pointer to the \f$ i^{th} \f$ node, which
478 * should be present in this processor's subset of the mesh data
479 * structure.
480 */
481 virtual Node * node_ptr (const dof_id_type i) = 0;
482
483 /**
484 * \returns A pointer to the \f$ i^{th} \f$ node, or \p nullptr if no such
485 * node exists in this processor's mesh data structure.
486 */
487 virtual const Node * query_node_ptr (const dof_id_type i) const = 0;
488
489 /**
490 * \returns A writable pointer to the \f$ i^{th} \f$ node, or \p nullptr if
491 * no such node exists in this processor's mesh data structure.
492 */
493 virtual Node * query_node_ptr (const dof_id_type i) = 0;
494
495 /**
496 * \returns A reference to the \f$ i^{th} \f$ element, which should be
497 * present in this processor's subset of the mesh data structure.
498 */
elem_ref(const dof_id_type i)499 virtual const Elem & elem_ref (const dof_id_type i) const {
500 return *this->elem_ptr(i);
501 }
502
503 /**
504 * \returns A writable reference to the \f$ i^{th} \f$ element, which
505 * should be present in this processor's subset of the mesh data
506 * structure.
507 */
elem_ref(const dof_id_type i)508 virtual Elem & elem_ref (const dof_id_type i) {
509 return *this->elem_ptr(i);
510 }
511
512 /**
513 * \returns A pointer to the \f$ i^{th} \f$ element, which should be
514 * present in this processor's subset of the mesh data structure.
515 */
516 virtual const Elem * elem_ptr (const dof_id_type i) const = 0;
517
518 /**
519 * \returns A writable pointer to the \f$ i^{th} \f$ element, which
520 * should be present in this processor's subset of the mesh data
521 * structure.
522 */
523 virtual Elem * elem_ptr (const dof_id_type i) = 0;
524
525 /**
526 * \returns A pointer to the \f$ i^{th} \f$ element, or nullptr if no
527 * such element exists in this processor's mesh data structure.
528 */
529 virtual const Elem * query_elem_ptr (const dof_id_type i) const = 0;
530
531 /**
532 * \returns A writable pointer to the \f$ i^{th} \f$ element, or nullptr
533 * if no such element exists in this processor's mesh data structure.
534 */
535 virtual Elem * query_elem_ptr (const dof_id_type i) = 0;
536
537 /**
538 * Add a new \p Node at \p Point \p p to the end of the vertex array,
539 * with processor_id \p procid.
540 * Use DofObject::invalid_processor_id (default) to add a node to all
541 * processors, or this->processor_id() to add a node to the local
542 * processor only.
543 * If adding a node locally, passing an \p id other than
544 * DofObject::invalid_id will set that specific node id. Only
545 * do this in parallel if you are manually keeping ids consistent.
546 */
547 virtual Node * add_point (const Point & p,
548 const dof_id_type id = DofObject::invalid_id,
549 const processor_id_type proc_id =
550 DofObject::invalid_processor_id) = 0;
551
552 /**
553 * Add \p Node \p n to the end of the vertex array.
554 */
555 virtual Node * add_node (Node * n) = 0;
556
557 /**
558 * Version of add_node() taking a std::unique_ptr by value. The version
559 * taking a dumb pointer will eventually be deprecated in favor of this
560 * version. This API is intended to indicate that ownership of the Node
561 * is transferred to the Mesh when this function is called, and it should
562 * play more nicely with the Node::build() API which has always returned
563 * a std::unique_ptr.
564 */
565 virtual Node * add_node (std::unique_ptr<Node> n) = 0;
566
567 /**
568 * Insert \p Node \p n into the Mesh at a location consistent with
569 * n->id(), allocating extra storage if necessary. Will error
570 * rather than overwriting an existing Node. Primarily intended for
571 * use with the mesh_inserter_iterator, only use if you know what
572 * you are doing...
573 */
574 virtual Node * insert_node(Node * n) = 0;
575
576 /**
577 * Version of insert_node() taking a std::unique_ptr by value. The version
578 * taking a dumb pointer will eventually be deprecated in favor of this
579 * version. This API is intended to indicate that ownership of the Node
580 * is transferred to the Mesh when this function is called, and it should
581 * play more nicely with the Node::build() API which has always returned
582 * a std::unique_ptr.
583 */
584 virtual Node * insert_node(std::unique_ptr<Node> n) = 0;
585
586 /**
587 * Removes the Node n from the mesh.
588 */
589 virtual void delete_node (Node * n) = 0;
590
591 /**
592 * Takes ownership of node \p n on this partition of a distributed
593 * mesh, by setting n.processor_id() to this->processor_id(), as
594 * well as changing n.id() and moving it in the mesh's internal
595 * container to give it a new authoritative id.
596 */
own_node(Node &)597 virtual void own_node (Node &) {}
598
599 /**
600 * Changes the id of node \p old_id, both by changing node(old_id)->id() and
601 * by moving node(old_id) in the mesh's internal container. No element with
602 * the id \p new_id should already exist.
603 */
604 virtual void renumber_node (dof_id_type old_id, dof_id_type new_id) = 0;
605
606 /**
607 * Add elem \p e to the end of the element array.
608 * To add an element locally, set e->processor_id() before adding it.
609 * To ensure a specific element id, call e->set_id() before adding it;
610 * only do this in parallel if you are manually keeping ids consistent.
611 *
612 * Users should call MeshBase::prepare_for_use() after elements are
613 * added to and/or deleted from the mesh.
614 */
615 virtual Elem * add_elem (Elem * e) = 0;
616
617 /**
618 * Version of add_elem() taking a std::unique_ptr by value. The version
619 * taking a dumb pointer will eventually be deprecated in favor of this
620 * version. This API is intended to indicate that ownership of the Elem
621 * is transferred to the Mesh when this function is called, and it should
622 * play more nicely with the Elem::build() API which has always returned
623 * a std::unique_ptr.
624 */
625 virtual Elem * add_elem (std::unique_ptr<Elem> e) = 0;
626
627 /**
628 * Insert elem \p e to the element array, preserving its id
629 * and replacing/deleting any existing element with the same id.
630 *
631 * Users should call MeshBase::prepare_for_use() after elements are
632 * added to and/or deleted from the mesh.
633 */
634 virtual Elem * insert_elem (Elem * e) = 0;
635
636 /**
637 * Version of insert_elem() taking a std::unique_ptr by value. The version
638 * taking a dumb pointer will eventually be deprecated in favor of this
639 * version. This API is intended to indicate that ownership of the Elem
640 * is transferred to the Mesh when this function is called, and it should
641 * play more nicely with the Elem::build() API which has always returned
642 * a std::unique_ptr.
643 */
644 virtual Elem * insert_elem (std::unique_ptr<Elem> e) = 0;
645
646 /**
647 * Removes element \p e from the mesh. This method must be
648 * implemented in derived classes in such a way that it does not
649 * invalidate element iterators. Users should call
650 * MeshBase::prepare_for_use() after elements are added to and/or
651 * deleted from the mesh.
652 *
653 * \note Calling this method may produce isolated nodes, i.e. nodes
654 * not connected to any element.
655 */
656 virtual void delete_elem (Elem * e) = 0;
657
658 /**
659 * Changes the id of element \p old_id, both by changing elem(old_id)->id()
660 * and by moving elem(old_id) in the mesh's internal container. No element
661 * with the id \p new_id should already exist.
662 */
663 virtual void renumber_elem (dof_id_type old_id, dof_id_type new_id) = 0;
664
665 /**
666 * Returns the default master space to physical space mapping basis
667 * functions to be used on newly added elements.
668 */
default_mapping_type()669 ElemMappingType default_mapping_type () const {
670 return _default_mapping_type;
671 }
672
673 /**
674 * Set the default master space to physical space mapping basis
675 * functions to be used on newly added elements.
676 */
set_default_mapping_type(const ElemMappingType type)677 void set_default_mapping_type (const ElemMappingType type) {
678 _default_mapping_type = type;
679 }
680
681 /**
682 * Returns any default data value used by the master space to
683 * physical space mapping.
684 */
default_mapping_data()685 unsigned char default_mapping_data () const {
686 return _default_mapping_data;
687 }
688
689 /**
690 * Set the default master space to physical space mapping basis
691 * functions to be used on newly added elements.
692 */
set_default_mapping_data(const unsigned char data)693 void set_default_mapping_data (const unsigned char data) {
694 _default_mapping_data = data;
695 }
696
697 /**
698 * Locate element face (edge in 2D) neighbors. This is done with the help
699 * of a \p std::map that functions like a hash table.
700 * After this routine is called all the elements with a \p nullptr neighbor
701 * pointer are guaranteed to be on the boundary. Thus this routine is
702 * useful for automatically determining the boundaries of the domain.
703 * If reset_remote_elements is left to false, remote neighbor links are not
704 * reset and searched for in the local mesh. If reset_current_list is
705 * left as true, then any existing links will be reset before initiating
706 * the algorithm, while honoring the value of the reset_remote_elements
707 * flag.
708 */
709 virtual void find_neighbors (const bool reset_remote_elements = false,
710 const bool reset_current_list = true) = 0;
711
712 /**
713 * Removes any orphaned nodes, nodes not connected to any elements.
714 * Typically done automatically in prepare_for_use
715 */
716 void remove_orphaned_nodes ();
717
718 /**
719 * After partitioning a mesh it is useful to renumber the nodes and elements
720 * so that they lie in contiguous blocks on the processors. This method
721 * does just that.
722 */
723 virtual void renumber_nodes_and_elements () = 0;
724
725 /**
726 * There is no reason for a user to ever call this function.
727 *
728 * This function restores a previously broken element/node numbering such that
729 * \p mesh.node_ref(n).id() == n.
730 */
731 virtual void fix_broken_node_and_element_numbering () = 0;
732
733
734 #ifdef LIBMESH_ENABLE_AMR
735 /**
736 * Delete subactive (i.e. children of coarsened) elements.
737 * This removes all elements descended from currently active
738 * elements in the mesh.
739 */
740 virtual bool contract () = 0;
741 #endif
742
743 /**
744 * Register an integer datum (of type dof_id_type) to be added to
745 * each element in the mesh.
746 *
747 * If the mesh already has elements, data by default is allocated in
748 * each of them. This may be expensive to do repeatedly; use
749 * add_elem_integers instead. Alternatively, the \p allocate_data
750 * option can be manually set to false, but if this is done then a
751 * manual call to \p size_elem_extra_integers() will need to be done
752 * before the new space is usable.
753 *
754 * Newly allocated values for the new datum will be initialized to
755 * \p default_value
756 *
757 * \returns The index number for the new datum, or for the existing
758 * datum if one by the same name has already been added.
759 */
760 unsigned int add_elem_integer(const std::string & name,
761 bool allocate_data = true,
762 dof_id_type default_value = DofObject::invalid_id);
763
764 /**
765 * Register integer data (of type dof_id_type) to be added to
766 * each element in the mesh, one string name for each new integer.
767 *
768 * If the mesh already has elements, data by default is allocated in
769 * each of them.
770 *
771 * Newly allocated values for the new datum with name \p names[i]
772 * will be initialized to \p default_values[i], or to
773 * DofObject::invalid_id if \p default_values is null.
774 *
775 * \returns The index numbers for the new data, and/or for existing
776 * data if data by some of the same names has already been added.
777 */
778 std::vector<unsigned int> add_elem_integers(const std::vector<std::string> & names,
779 bool allocate_data = true,
780 const std::vector<dof_id_type> * default_values = nullptr);
781
782 /*
783 * \returns The index number for the named extra element integer
784 * datum, which must have already been added.
785 */
786 unsigned int get_elem_integer_index(const std::string & name) const;
787
788 /*
789 * \returns Whether or not the mesh has an element integer with its name.
790 */
791 bool has_elem_integer(const std::string & name) const;
792
793 /*
794 * \returns The name for the indexed extra element integer
795 * datum, which must have already been added.
796 */
get_elem_integer_name(unsigned int i)797 const std::string & get_elem_integer_name(unsigned int i) const
798 { return _elem_integer_names[i]; }
799
800 /*
801 * \returns The number of extra element integers for which space is
802 * being reserved on this mesh.
803 *
804 * If non-integer data has been associated, each datum of type T
805 * counts for sizeof(T)/sizeof(dof_id_type) times in the return
806 * value.
807 */
n_elem_integers()808 unsigned int n_elem_integers() const { return _elem_integer_names.size(); }
809
810 /**
811 * Register a datum (of type T) to be added to each element in the
812 * mesh.
813 *
814 * If the mesh already has elements, data by default is allocated in
815 * each of them. This may be expensive to do repeatedly; use
816 * add_elem_data instead. Alternatively, the \p allocate_data
817 * option can be manually set to false, but if this is done then a
818 * manual call to \p size_elem_extra_integers() will need to be done
819 * before the new space is usable.
820 *
821 * Newly allocated values for the new datum will be initialized to
822 * \p *default_value if \p default_value is not null, or to
823 * meaningless memcpy output otherwise.
824 *
825 * \returns The index numbers for the new data, and/or for existing
826 * data if data by some of the same names has already been added.
827 *
828 * If type T is larger than dof_id_type, its data will end up
829 * spanning multiple index values, but will be queried with the
830 * starting index number.
831 *
832 * No type checking is done with this function! If you add data of
833 * type T, don't try to access it with a call specifying type U.
834 */
835 template <typename T>
836 unsigned int add_elem_datum(const std::string & name,
837 bool allocate_data = true,
838 const T * default_value = nullptr);
839
840 /**
841 * Register data (of type T) to be added to each element in the
842 * mesh.
843 *
844 * If the mesh already has elements, data is allocated in each.
845 *
846 * Newly allocated values for the new datum with name \p names[i]
847 * will be initialized to \p default_values[i], or to
848 * meaningless memcpy output if \p default_values is null.
849 *
850 * \returns The starting index number for the new data, or for the
851 * existing data if one by the same name has already been added.
852 *
853 * If type T is larger than dof_id_type, each datum will end up
854 * spanning multiple index values, but will be queried with the
855 * starting index number.
856 *
857 * No type checking is done with this function! If you add data of
858 * type T, don't try to access it with a call specifying type U.
859 */
860 template <typename T>
861 std::vector<unsigned int> add_elem_data(const std::vector<std::string> & names,
862 bool allocate_data = true,
863 const std::vector<T> * default_values = nullptr);
864
865 /**
866 * Register an integer datum (of type dof_id_type) to be added to
867 * each node in the mesh.
868 *
869 * If the mesh already has nodes, data by default is allocated in
870 * each of them. This may be expensive to do repeatedly; use
871 * add_node_integers instead. Alternatively, the \p allocate_data
872 * option can be manually set to false, but if this is done then a
873 * manual call to \p size_node_extra_integers() will need to be done
874 * before the new space is usable.
875 *
876 * Newly allocated values for the new datum will be initialized to
877 * \p default_value
878 *
879 * \returns The index number for the new datum, or for the existing
880 * datum if one by the same name has already been added.
881 */
882 unsigned int add_node_integer(const std::string & name,
883 bool allocate_data = true,
884 dof_id_type default_value = DofObject::invalid_id);
885
886 /**
887 * Register integer data (of type dof_id_type) to be added to
888 * each node in the mesh.
889 *
890 * If the mesh already has nodes, data by default is allocated in
891 * each.
892 *
893 * Newly allocated values for the new datum with name \p names[i]
894 * will be initialized to \p default_values[i], or to
895 * DofObject::invalid_id if \p default_values is null.
896 *
897 * \returns The index numbers for the new data, and/or for existing
898 * data if data by some of the same names has already been added.
899 */
900 std::vector<unsigned int> add_node_integers(const std::vector<std::string> & names,
901 bool allocate_data = true,
902 const std::vector<dof_id_type> * default_values = nullptr);
903
904 /*
905 * \returns The index number for the named extra node integer
906 * datum, which must have already been added.
907 */
908 unsigned int get_node_integer_index(const std::string & name) const;
909
910 /*
911 * \returns Whether or not the mesh has a node integer with its name.
912 */
913 bool has_node_integer(const std::string & name) const;
914
915 /*
916 * \returns The name for the indexed extra node integer
917 * datum, which must have already been added.
918 */
get_node_integer_name(unsigned int i)919 const std::string & get_node_integer_name(unsigned int i) const
920 { return _node_integer_names[i]; }
921
922 /*
923 * \returns The number of extra node integers for which space is
924 * being reserved on this mesh.
925 *
926 * If non-integer data has been associated, each datum of type T
927 * counts for sizeof(T)/sizeof(dof_id_type) times in the return
928 * value.
929 */
n_node_integers()930 unsigned int n_node_integers() const { return _node_integer_names.size(); }
931
932 /**
933 * Register a datum (of type T) to be added to each node in the
934 * mesh.
935 *
936 * If the mesh already has nodes, data by default is allocated in
937 * each of them. This may be expensive to do repeatedly; use
938 * add_node_data instead. Alternatively, the \p allocate_data
939 * option can be manually set to false, but if this is done then a
940 * manual call to \p size_node_extra_integers() will need to be done
941 * before the new space is usable.
942 *
943 * Newly allocated values for the new datum will be initialized to
944 * \p *default_value if \p default_value is not null, or to
945 * meaningless memcpy output otherwise.
946 *
947 * \returns The starting index number for the new datum, or for the
948 * existing datum if one by the same name has already been added.
949 *
950 * If type T is larger than dof_id_type, its data will end up
951 * spanning multiple index values, but will be queried with the
952 * starting index number.
953 *
954 * No type checking is done with this function! If you add data of
955 * type T, don't try to access it with a call specifying type U.
956 */
957 template <typename T>
958 unsigned int add_node_datum(const std::string & name,
959 bool allocate_data = true,
960 const T * default_value = nullptr);
961
962 /**
963 * Register data (of type T) to be added to each node in the
964 * mesh.
965 *
966 * If the mesh already has nodes, data by default is allocated in each.
967 *
968 * Newly allocated values for the new datum with name \p names[i]
969 * will be initialized to \p default_values[i], or to
970 * meaningless memcpy output if \p default_values is null.
971 *
972 * \returns The starting index number for the new data, or for the
973 * existing data if one by the same name has already been added.
974 *
975 * If type T is larger than dof_id_type, its data will end up
976 * spanning multiple index values, but will be queried with the
977 * starting index number.
978 *
979 * No type checking is done with this function! If you add data of
980 * type T, don't try to access it with a call specifying type U.
981 */
982 template <typename T>
983 std::vector<unsigned int> add_node_data(const std::vector<std::string> & name,
984 bool allocate_data = true,
985 const std::vector<T> * default_values = nullptr);
986
987 /**
988 * Prepare a newly ecreated (or read) mesh for use.
989 * This involves 4 steps:
990 * 1.) call \p find_neighbors()
991 * 2.) call \p partition()
992 * 3.) call \p renumber_nodes_and_elements()
993 * 4.) call \p cache_elem_dims()
994 *
995 * The argument to skip renumbering is now deprecated - to prevent a
996 * mesh from being renumbered, set allow_renumbering(false). The argument to skip
997 * finding neighbors is also deprecated. To prevent find_neighbors, set
998 * allow_find_neighbors(false)
999 *
1000 * If this is a distributed mesh, local copies of remote elements
1001 * will be deleted here - to keep those elements replicated during
1002 * preparation, set allow_remote_element_removal(false).
1003 */
1004 void prepare_for_use (const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors);
1005 void prepare_for_use (const bool skip_renumber_nodes_and_elements);
1006 void prepare_for_use ();
1007
1008 /**
1009 * Call the default partitioner (currently \p metis_partition()).
1010 */
1011 virtual void partition (const unsigned int n_parts);
1012
partition()1013 void partition ()
1014 { this->partition(this->n_processors()); }
1015
1016 /**
1017 * Redistribute elements between processors. This gets called
1018 * automatically by the Partitioner, and is a no-op in the case of a
1019 * ReplicatedMesh or serialized DistributedMesh
1020 */
redistribute()1021 virtual void redistribute () {}
1022
1023 /**
1024 * Recalculate any cached data after elements and nodes have been
1025 * repartitioned.
1026 */
update_post_partitioning()1027 virtual void update_post_partitioning () {}
1028
1029 /**
1030 * If false is passed in then this mesh will no longer be renumbered
1031 * when being prepared for use. This may slightly adversely affect
1032 * performance during subsequent element access, particularly when
1033 * using a distributed mesh.
1034 *
1035 * Important! When allow_renumbering(false) is set,
1036 * ReplicatedMesh::n_elem() and ReplicatedMesh::n_nodes() will
1037 * return *wrong* values whenever adaptive refinement is followed by
1038 * adaptive coarsening. (Uniform refinement followed by uniform
1039 * coarsening is OK.) This is due to the fact that n_elem() and
1040 * n_nodes() are currently O(1) functions that just return the size
1041 * of the respective underlying vectors, and this size is wrong when
1042 * the numbering includes "gaps" from nodes and elements that have
1043 * been deleted. We plan to implement a caching mechanism in the
1044 * near future that will fix this incorrect behavior.
1045 */
allow_renumbering(bool allow)1046 void allow_renumbering(bool allow) { _skip_renumber_nodes_and_elements = !allow; }
allow_renumbering()1047 bool allow_renumbering() const { return !_skip_renumber_nodes_and_elements; }
1048
1049 /**
1050 * If \p false is passed then this mesh will no longer work to find element
1051 * neighbors when being prepared for use
1052 */
allow_find_neighbors(bool allow)1053 void allow_find_neighbors(bool allow) { _skip_find_neighbors = !allow; }
allow_find_neighbors()1054 bool allow_find_neighbors() const { return !_skip_find_neighbors; }
1055
1056 /**
1057 * If false is passed in then this mesh will no longer have remote
1058 * elements deleted when being prepared for use; i.e. even a
1059 * DistributedMesh will remain (if it is already) serialized.
1060 * This may adversely affect performance and memory use.
1061 */
allow_remote_element_removal(bool allow)1062 void allow_remote_element_removal(bool allow) { _allow_remote_element_removal = allow; }
allow_remote_element_removal()1063 bool allow_remote_element_removal() const { return _allow_remote_element_removal; }
1064
1065 /**
1066 * If true is passed in then the elements on this mesh will no
1067 * longer be (re)partitioned, and the nodes on this mesh will only
1068 * be repartitioned if they are found "orphaned" via coarsening or
1069 * other removal of the last element responsible for their
1070 * node/element processor id consistency.
1071 *
1072 * \note It would probably be a bad idea to call this on a
1073 * DistributedMesh _before_ the first partitioning has happened...
1074 * because no elements would get assigned to your processor pool.
1075 *
1076 * \note Skipping partitioning can have adverse effects on your
1077 * performance when using AMR... i.e. you could get large load
1078 * imbalances. However you might still want to use this if the
1079 * communication and computation of the rebalance and repartition is
1080 * too high for your application.
1081 *
1082 * It is also possible, for backwards-compatibility purposes, to
1083 * skip noncritical partitioning by resetting the partitioner()
1084 * pointer for this mesh.
1085 */
skip_noncritical_partitioning(bool skip)1086 void skip_noncritical_partitioning(bool skip)
1087 { _skip_noncritical_partitioning = skip; }
1088
skip_noncritical_partitioning()1089 bool skip_noncritical_partitioning() const
1090 { return _skip_noncritical_partitioning || _skip_all_partitioning || !_partitioner.get(); }
1091
1092
1093 /**
1094 * If true is passed in then nothing on this mesh will be
1095 * (re)partitioned.
1096 *
1097 * \note The caveats for skip_noncritical_partitioning() still
1098 * apply, and removing elements from a mesh with this setting
1099 * enabled can leave node processor ids in an inconsistent state
1100 * (not matching any attached element), causing failures in other
1101 * library code. Do not use this setting along with element
1102 * deletion or coarsening.
1103 */
skip_partitioning(bool skip)1104 void skip_partitioning(bool skip) { _skip_all_partitioning = skip; }
1105
skip_partitioning()1106 bool skip_partitioning() const { return _skip_all_partitioning; }
1107
1108 /**
1109 * Adds a functor which can specify ghosting requirements for use on
1110 * distributed meshes. Multiple ghosting functors can be added; any
1111 * element which is required by any functor will be ghosted.
1112 *
1113 * GhostingFunctor memory must be managed by the code which calls
1114 * this function; the GhostingFunctor lifetime is expected to extend
1115 * until either the functor is removed or the Mesh is destructed.
1116 */
add_ghosting_functor(GhostingFunctor & ghosting_functor)1117 void add_ghosting_functor(GhostingFunctor & ghosting_functor)
1118 { _ghosting_functors.insert(&ghosting_functor); }
1119
1120 /**
1121 * Adds a functor which can specify ghosting requirements for use on
1122 * distributed meshes. Multiple ghosting functors can be added; any
1123 * element which is required by any functor will be ghosted.
1124 *
1125 * GhostingFunctor memory when using this method is managed by the
1126 * shared_ptr mechanism.
1127 */
add_ghosting_functor(std::shared_ptr<GhostingFunctor> ghosting_functor)1128 void add_ghosting_functor(std::shared_ptr<GhostingFunctor> ghosting_functor)
1129 { _shared_functors[ghosting_functor.get()] = ghosting_functor;
1130 this->add_ghosting_functor(*ghosting_functor); }
1131
1132 /**
1133 * Removes a functor which was previously added to the set of
1134 * ghosting functors.
1135 */
1136 void remove_ghosting_functor(GhostingFunctor & ghosting_functor);
1137
1138 /**
1139 * Beginning of range of ghosting functors
1140 */
ghosting_functors_begin()1141 std::set<GhostingFunctor *>::const_iterator ghosting_functors_begin() const
1142 { return _ghosting_functors.begin(); }
1143
1144 /**
1145 * End of range of ghosting functors
1146 */
ghosting_functors_end()1147 std::set<GhostingFunctor *>::const_iterator ghosting_functors_end() const
1148 { return _ghosting_functors.end(); }
1149
1150 /**
1151 * Default ghosting functor
1152 */
default_ghosting()1153 GhostingFunctor & default_ghosting() { return *_default_ghosting; }
1154
1155 /**
1156 * Constructs a list of all subdomain identifiers in the global mesh.
1157 * Subdomains correspond to separate subsets of the mesh which could correspond
1158 * e.g. to different materials in a solid mechanics application,
1159 * or regions where different physical processes are important. The subdomain
1160 * mapping is independent from the parallel decomposition.
1161 */
1162 void subdomain_ids (std::set<subdomain_id_type> & ids) const;
1163
1164 /**
1165 * \returns The number of subdomains in the global mesh. Subdomains correspond
1166 * to separate subsets of the mesh which could correspond e.g. to different
1167 * materials in a solid mechanics application, or regions where different
1168 * physical processes are important. The subdomain mapping is independent
1169 * from the parallel decomposition.
1170 */
1171 subdomain_id_type n_subdomains () const;
1172
1173 /**
1174 * \returns The number of partitions which have been defined via
1175 * a call to either mesh.partition() or by building a Partitioner
1176 * object and calling partition.
1177 *
1178 * \note The partitioner object is responsible for setting this
1179 * value.
1180 */
n_partitions()1181 unsigned int n_partitions () const
1182 { return _n_parts; }
1183
1184 /**
1185 * \returns A string containing relevant information
1186 * about the mesh.
1187 */
1188 std::string get_info () const;
1189
1190 /**
1191 * Prints relevant information about the mesh.
1192 */
1193 void print_info (std::ostream & os=libMesh::out) const;
1194
1195 /**
1196 * Equivalent to calling print_info() above, but now you can write:
1197 * Mesh mesh;
1198 * libMesh::out << mesh << std::endl;
1199 */
1200 friend std::ostream & operator << (std::ostream & os, const MeshBase & m);
1201
1202 /**
1203 * Interfaces for reading/writing a mesh to/from a file. Must be
1204 * implemented in derived classes.
1205 */
1206 virtual void read (const std::string & name,
1207 void * mesh_data=nullptr,
1208 bool skip_renumber_nodes_and_elements=false,
1209 bool skip_find_neighbors=false) = 0;
1210 virtual void write (const std::string & name) = 0;
1211
1212 /**
1213 * Converts a mesh with higher-order
1214 * elements into a mesh with linear elements. For
1215 * example, a mesh consisting of \p Tet10 will be converted
1216 * to a mesh with \p Tet4 etc.
1217 */
1218 virtual void all_first_order () = 0;
1219
1220 /**
1221 * Converts a (conforming, non-refined) mesh with linear elements
1222 * into a mesh with second-order elements. For example, a mesh
1223 * consisting of \p Tet4 will be converted to a mesh with \p Tet10
1224 * etc.
1225 *
1226 * \note For some elements like \p Hex8 there exist two higher order
1227 * equivalents, \p Hex20 and \p Hex27. When \p full_ordered is \p
1228 * true (default), then \p Hex27 is built. Otherwise, \p Hex20 is
1229 * built. The same holds obviously for \p Quad4, \p Prism6, etc.
1230 */
1231 virtual void all_second_order (const bool full_ordered=true) = 0;
1232
1233 /**
1234 * We need an empty, generic class to act as a predicate for this
1235 * and derived mesh classes.
1236 */
1237 typedef Predicates::multi_predicate Predicate;
1238
1239 /**
1240 * structs for the element_iterator's.
1241 *
1242 * \note These iterators were designed so that derived mesh classes
1243 * could use the _same_ base class iterators interchangeably. Their
1244 * definition comes later in the header file.
1245 */
1246 struct element_iterator;
1247 struct const_element_iterator;
1248
1249 /**
1250 * structs for the node_iterator's.
1251 *
1252 * \note These iterators were designed so that derived mesh classes
1253 * could use the _same_ base class iterators interchangeably. Their
1254 * definition comes later in the header file.
1255 */
1256 struct node_iterator;
1257 struct const_node_iterator;
1258
1259 /**
1260 * In a few (very rare) cases, the user may have manually tagged the
1261 * elements with specific processor IDs by hand, without using a
1262 * partitioner. In this case, the Mesh will not know that the total
1263 * number of partitions, _n_parts, has changed, unless you call this
1264 * function. This is an O(N active elements) calculation. The return
1265 * value is the number of partitions, and _n_parts is also set by
1266 * this function.
1267 */
1268 unsigned int recalculate_n_partitions();
1269
1270 /**
1271 * \returns A pointer to a subordinate \p PointLocatorBase object
1272 * for this mesh, constructing a master PointLocator first if
1273 * necessary. This should not be used in threaded or
1274 * non-parallel_only code unless the master has already been
1275 * constructed.
1276 */
1277 std::unique_ptr<PointLocatorBase> sub_point_locator () const;
1278
1279 /**
1280 * Set value used by PointLocatorBase::close_to_point_tol().
1281 *
1282 * Defaults to 0.0. If nonzero, calls close_to_point_tol() whenever
1283 * a new PointLocator is built for use by this Mesh. Since the Mesh
1284 * controls the creation and destruction of the PointLocator, if
1285 * there are any parameters we need to customize on it, the Mesh
1286 * will need to know about them.
1287 */
1288 void set_point_locator_close_to_point_tol(Real val);
1289 Real get_point_locator_close_to_point_tol() const;
1290
1291 /**
1292 * Releases the current \p PointLocator object.
1293 */
1294 void clear_point_locator ();
1295
1296 /**
1297 * In the point locator, do we count lower dimensional elements
1298 * when we refine point locator regions? This is relevant in
1299 * tree-based point locators, for example.
1300 */
1301 void set_count_lower_dim_elems_in_point_locator(bool count_lower_dim_elems);
1302
1303 /**
1304 * Get the current value of _count_lower_dim_elems_in_point_locator.
1305 */
1306 bool get_count_lower_dim_elems_in_point_locator() const;
1307
1308 /**
1309 * Verify id and processor_id consistency of our elements and
1310 * nodes containers.
1311 * Calls libmesh_assert() on each possible failure.
1312 * Currently only implemented on DistributedMesh; a serial data
1313 * structure is much harder to get out of sync.
1314 */
libmesh_assert_valid_parallel_ids()1315 virtual void libmesh_assert_valid_parallel_ids() const {}
1316
1317 /**
1318 * \returns A writable reference for getting/setting an optional
1319 * name for a subdomain.
1320 */
1321 std::string & subdomain_name(subdomain_id_type id);
1322 const std::string & subdomain_name(subdomain_id_type id) const;
1323
1324 /**
1325 * \returns The id of the named subdomain if it exists,
1326 * \p Elem::invalid_subdomain_id otherwise.
1327 */
1328 subdomain_id_type get_id_by_name(const std::string & name) const;
1329
1330 //
1331 // element_iterator accessors
1332 //
1333
1334 /**
1335 * Iterate over all the elements in the Mesh.
1336 */
1337 virtual element_iterator elements_begin () = 0;
1338 virtual element_iterator elements_end () = 0;
1339 virtual const_element_iterator elements_begin () const = 0;
1340 virtual const_element_iterator elements_end () const = 0;
1341 virtual SimpleRange<element_iterator> element_ptr_range() = 0;
1342 virtual SimpleRange<const_element_iterator> element_ptr_range() const = 0;
1343
1344 /**
1345 * Iterate over elements for which elem->ancestor() is true.
1346 */
1347 virtual element_iterator ancestor_elements_begin () = 0;
1348 virtual element_iterator ancestor_elements_end () = 0;
1349 virtual const_element_iterator ancestor_elements_begin () const = 0;
1350 virtual const_element_iterator ancestor_elements_end () const = 0;
1351
1352 /**
1353 * Iterate over elements for which elem->subactive() is true.
1354 */
1355 virtual element_iterator subactive_elements_begin () = 0;
1356 virtual element_iterator subactive_elements_end () = 0;
1357 virtual const_element_iterator subactive_elements_begin () const = 0;
1358 virtual const_element_iterator subactive_elements_end () const = 0;
1359
1360 /**
1361 * Iterate over elements for which elem->is_semilocal() is true for the current processor.
1362 */
1363 virtual element_iterator semilocal_elements_begin () = 0;
1364 virtual element_iterator semilocal_elements_end () = 0;
1365 virtual const_element_iterator semilocal_elements_begin () const = 0;
1366 virtual const_element_iterator semilocal_elements_end () const = 0;
1367
1368 /**
1369 * Iterate over elements which are on or have a neighbor on the current processor.
1370 */
1371 virtual element_iterator facelocal_elements_begin () = 0;
1372 virtual element_iterator facelocal_elements_end () = 0;
1373 virtual const_element_iterator facelocal_elements_begin () const = 0;
1374 virtual const_element_iterator facelocal_elements_end () const = 0;
1375
1376 /**
1377 * Iterate over elements of a given level.
1378 */
1379 virtual element_iterator level_elements_begin (unsigned int level) = 0;
1380 virtual element_iterator level_elements_end (unsigned int level) = 0;
1381 virtual const_element_iterator level_elements_begin (unsigned int level) const = 0;
1382 virtual const_element_iterator level_elements_end (unsigned int level) const = 0;
1383
1384 /**
1385 * Iterate over all elements with a specified processor id.
1386 */
1387 virtual element_iterator pid_elements_begin (processor_id_type proc_id) = 0;
1388 virtual element_iterator pid_elements_end (processor_id_type proc_id) = 0;
1389 virtual const_element_iterator pid_elements_begin (processor_id_type proc_id) const = 0;
1390 virtual const_element_iterator pid_elements_end (processor_id_type proc_id) const = 0;
1391
1392 /**
1393 * Iterate over all elements with a specified geometric type.
1394 */
1395 virtual element_iterator type_elements_begin (ElemType type) = 0;
1396 virtual element_iterator type_elements_end (ElemType type) = 0;
1397 virtual const_element_iterator type_elements_begin (ElemType type) const = 0;
1398 virtual const_element_iterator type_elements_end (ElemType type) const = 0;
1399
1400 /**
1401 * Iterate over unpartitioned elements in the Mesh.
1402 */
1403 virtual element_iterator unpartitioned_elements_begin () = 0;
1404 virtual element_iterator unpartitioned_elements_end () = 0;
1405 virtual const_element_iterator unpartitioned_elements_begin () const = 0;
1406 virtual const_element_iterator unpartitioned_elements_end () const = 0;
1407
1408 /**
1409 * Iterate over active unpartitioned elements in the Mesh.
1410 */
1411 virtual element_iterator active_unpartitioned_elements_begin () = 0;
1412 virtual element_iterator active_unpartitioned_elements_end () = 0;
1413 virtual const_element_iterator active_unpartitioned_elements_begin () const = 0;
1414 virtual const_element_iterator active_unpartitioned_elements_end () const = 0;
1415
1416 /**
1417 * Iterate over "ghost" elements in the Mesh. A ghost element is
1418 * one which is *not* local, but *is* semilocal.
1419 */
1420 virtual element_iterator ghost_elements_begin () = 0;
1421 virtual element_iterator ghost_elements_end () = 0;
1422 virtual const_element_iterator ghost_elements_begin () const = 0;
1423 virtual const_element_iterator ghost_elements_end () const = 0;
1424
1425 /**
1426 * Iterate over elements in the Mesh where the solution (as
1427 * distributed by the given DofMap) can be evaluated, for the given
1428 * variable var_num, or for all variables by default.
1429 */
1430 virtual element_iterator
1431 evaluable_elements_begin (const DofMap & dof_map,
1432 unsigned int var_num = libMesh::invalid_uint) = 0;
1433
1434 virtual element_iterator
1435 evaluable_elements_end (const DofMap & dof_map,
1436 unsigned int var_num = libMesh::invalid_uint) = 0;
1437
1438 virtual const_element_iterator
1439 evaluable_elements_begin (const DofMap & dof_map,
1440 unsigned int var_num = libMesh::invalid_uint) const = 0;
1441
1442 virtual const_element_iterator
1443 evaluable_elements_end (const DofMap & dof_map,
1444 unsigned int var_num = libMesh::invalid_uint) const = 0;
1445
1446 #ifdef LIBMESH_ENABLE_AMR
1447 /**
1448 * Iterate over all elements with a specified refinement flag.
1449 */
1450 virtual element_iterator flagged_elements_begin (unsigned char rflag) = 0;
1451 virtual element_iterator flagged_elements_end (unsigned char rflag) = 0;
1452 virtual const_element_iterator flagged_elements_begin (unsigned char rflag) const = 0;
1453 virtual const_element_iterator flagged_elements_end (unsigned char rflag) const = 0;
1454
1455 /**
1456 * Iterate over all elements with a specified refinement flag on a
1457 * specified processor.
1458 */
1459 virtual element_iterator flagged_pid_elements_begin (unsigned char rflag,
1460 processor_id_type pid) = 0;
1461 virtual element_iterator flagged_pid_elements_end (unsigned char rflag,
1462 processor_id_type pid) = 0;
1463 virtual const_element_iterator flagged_pid_elements_begin (unsigned char rflag,
1464 processor_id_type pid) const = 0;
1465 virtual const_element_iterator flagged_pid_elements_end (unsigned char rflag,
1466 processor_id_type pid) const = 0;
1467 #endif
1468
1469 /**
1470 * Active, local, and negation forms of the element iterators described above.
1471 * An "active" element is an element without children (i.e. has not been refined).
1472 * A "local" element is one whose processor_id() matches the current processor.
1473 */
1474 virtual element_iterator active_elements_begin () = 0;
1475 virtual element_iterator active_elements_end () = 0;
1476 virtual const_element_iterator active_elements_begin () const = 0;
1477 virtual const_element_iterator active_elements_end () const = 0;
1478 virtual SimpleRange<element_iterator> active_element_ptr_range() = 0;
1479 virtual SimpleRange<const_element_iterator> active_element_ptr_range() const = 0;
1480
1481 virtual element_iterator local_elements_begin () = 0;
1482 virtual element_iterator local_elements_end () = 0;
1483 virtual const_element_iterator local_elements_begin () const = 0;
1484 virtual const_element_iterator local_elements_end () const = 0;
1485
1486 virtual element_iterator active_semilocal_elements_begin () = 0;
1487 virtual element_iterator active_semilocal_elements_end () = 0;
1488 virtual const_element_iterator active_semilocal_elements_begin () const = 0;
1489 virtual const_element_iterator active_semilocal_elements_end () const = 0;
1490
1491 virtual element_iterator active_type_elements_begin (ElemType type) = 0;
1492 virtual element_iterator active_type_elements_end (ElemType type) = 0;
1493 virtual const_element_iterator active_type_elements_begin (ElemType type) const = 0;
1494 virtual const_element_iterator active_type_elements_end (ElemType type) const = 0;
1495
1496 virtual element_iterator active_pid_elements_begin (processor_id_type proc_id) = 0;
1497 virtual element_iterator active_pid_elements_end (processor_id_type proc_id) = 0;
1498 virtual const_element_iterator active_pid_elements_begin (processor_id_type proc_id) const = 0;
1499 virtual const_element_iterator active_pid_elements_end (processor_id_type proc_id) const = 0;
1500
1501 virtual element_iterator active_subdomain_elements_begin (subdomain_id_type subdomain_id) = 0;
1502 virtual element_iterator active_subdomain_elements_end (subdomain_id_type subdomain_id) = 0;
1503 virtual const_element_iterator active_subdomain_elements_begin (subdomain_id_type subdomain_id) const = 0;
1504 virtual const_element_iterator active_subdomain_elements_end (subdomain_id_type subdomain_id) const = 0;
1505 virtual SimpleRange<element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type subdomain_id) = 0;
1506 virtual SimpleRange<const_element_iterator> active_subdomain_elements_ptr_range(subdomain_id_type subdomain_id) const = 0;
1507
1508 virtual element_iterator active_subdomain_set_elements_begin (std::set<subdomain_id_type> ss) = 0;
1509 virtual element_iterator active_subdomain_set_elements_end (std::set<subdomain_id_type> ss) = 0;
1510 virtual const_element_iterator active_subdomain_set_elements_begin (std::set<subdomain_id_type> ss) const = 0;
1511 virtual const_element_iterator active_subdomain_set_elements_end (std::set<subdomain_id_type> ss) const = 0;
1512 virtual SimpleRange<element_iterator> active_subdomain_set_elements_ptr_range(std::set<subdomain_id_type> ss) = 0;
1513 virtual SimpleRange<const_element_iterator> active_subdomain_set_elements_ptr_range(std::set<subdomain_id_type> ss) const = 0;
1514
1515 virtual element_iterator active_local_subdomain_elements_begin (subdomain_id_type subdomain_id) = 0;
1516 virtual element_iterator active_local_subdomain_elements_end (subdomain_id_type subdomain_id) = 0;
1517 virtual const_element_iterator active_local_subdomain_elements_begin (subdomain_id_type subdomain_id) const = 0;
1518 virtual const_element_iterator active_local_subdomain_elements_end (subdomain_id_type subdomain_id) const = 0;
1519 virtual SimpleRange<element_iterator> active_local_subdomain_elements_ptr_range(subdomain_id_type subdomain_id) = 0;
1520 virtual SimpleRange<const_element_iterator> active_local_subdomain_elements_ptr_range(subdomain_id_type subdomain_id) const = 0;
1521
1522 virtual element_iterator local_level_elements_begin (unsigned int level) = 0;
1523 virtual element_iterator local_level_elements_end (unsigned int level) = 0;
1524 virtual const_element_iterator local_level_elements_begin (unsigned int level) const = 0;
1525 virtual const_element_iterator local_level_elements_end (unsigned int level) const = 0;
1526
1527 virtual element_iterator local_not_level_elements_begin (unsigned int level) = 0;
1528 virtual element_iterator local_not_level_elements_end (unsigned int level) = 0;
1529 virtual const_element_iterator local_not_level_elements_begin (unsigned int level) const = 0;
1530 virtual const_element_iterator local_not_level_elements_end (unsigned int level) const = 0;
1531
1532 virtual element_iterator not_level_elements_begin (unsigned int level) = 0;
1533 virtual element_iterator not_level_elements_end (unsigned int level) = 0;
1534 virtual const_element_iterator not_level_elements_begin (unsigned int level) const = 0;
1535 virtual const_element_iterator not_level_elements_end (unsigned int level) const = 0;
1536
1537 virtual element_iterator active_local_elements_begin () = 0;
1538 virtual element_iterator active_local_elements_end () = 0;
1539 virtual const_element_iterator active_local_elements_begin () const = 0;
1540 virtual const_element_iterator active_local_elements_end () const = 0;
1541 virtual SimpleRange<element_iterator> active_local_element_ptr_range() = 0;
1542 virtual SimpleRange<const_element_iterator> active_local_element_ptr_range() const = 0;
1543
1544 virtual element_iterator active_not_local_elements_begin () = 0;
1545 virtual element_iterator active_not_local_elements_end () = 0;
1546 virtual const_element_iterator active_not_local_elements_begin () const = 0;
1547 virtual const_element_iterator active_not_local_elements_end () const = 0;
1548
1549 virtual element_iterator not_local_elements_begin () = 0;
1550 virtual element_iterator not_local_elements_end () = 0;
1551 virtual const_element_iterator not_local_elements_begin () const = 0;
1552 virtual const_element_iterator not_local_elements_end () const = 0;
1553
1554 virtual element_iterator not_subactive_elements_begin () = 0;
1555 virtual element_iterator not_subactive_elements_end () = 0;
1556 virtual const_element_iterator not_subactive_elements_begin () const = 0;
1557 virtual const_element_iterator not_subactive_elements_end () const = 0;
1558
1559 virtual element_iterator not_active_elements_begin () = 0;
1560 virtual element_iterator not_active_elements_end () = 0;
1561 virtual const_element_iterator not_active_elements_begin () const = 0;
1562 virtual const_element_iterator not_active_elements_end () const = 0;
1563
1564 virtual element_iterator not_ancestor_elements_begin () = 0;
1565 virtual element_iterator not_ancestor_elements_end () = 0;
1566 virtual const_element_iterator not_ancestor_elements_begin () const = 0;
1567 virtual const_element_iterator not_ancestor_elements_end () const = 0;
1568
1569 //
1570 // node_iterator accessors
1571 //
1572
1573 /**
1574 * Iterate over all the nodes in the Mesh.
1575 */
1576 virtual node_iterator nodes_begin () = 0;
1577 virtual node_iterator nodes_end () = 0;
1578 virtual const_node_iterator nodes_begin () const = 0;
1579 virtual const_node_iterator nodes_end () const = 0;
1580 virtual SimpleRange<node_iterator> node_ptr_range() = 0;
1581 virtual SimpleRange<const_node_iterator> node_ptr_range() const = 0;
1582
1583 /**
1584 * Iterate over only the active nodes in the Mesh.
1585 */
1586 virtual node_iterator active_nodes_begin () = 0;
1587 virtual node_iterator active_nodes_end () = 0;
1588 virtual const_node_iterator active_nodes_begin () const = 0;
1589 virtual const_node_iterator active_nodes_end () const = 0;
1590
1591 /**
1592 * Iterate over local nodes (nodes whose processor_id() matches the current processor).
1593 */
1594 virtual node_iterator local_nodes_begin () = 0;
1595 virtual node_iterator local_nodes_end () = 0;
1596 virtual const_node_iterator local_nodes_begin () const = 0;
1597 virtual const_node_iterator local_nodes_end () const = 0;
1598 virtual SimpleRange<node_iterator> local_node_ptr_range() = 0;
1599 virtual SimpleRange<const_node_iterator> local_node_ptr_range() const = 0;
1600
1601 /**
1602 * Iterate over nodes with processor_id() == proc_id
1603 */
1604 virtual node_iterator pid_nodes_begin (processor_id_type proc_id) = 0;
1605 virtual node_iterator pid_nodes_end (processor_id_type proc_id) = 0;
1606 virtual const_node_iterator pid_nodes_begin (processor_id_type proc_id) const = 0;
1607 virtual const_node_iterator pid_nodes_end (processor_id_type proc_id) const = 0;
1608
1609 /**
1610 * Iterate over nodes for which BoundaryInfo::has_boundary_id(node, bndry_id) is true.
1611 */
1612 virtual node_iterator bid_nodes_begin (boundary_id_type bndry_id) = 0;
1613 virtual node_iterator bid_nodes_end (boundary_id_type bndry_id) = 0;
1614 virtual const_node_iterator bid_nodes_begin (boundary_id_type bndry_id) const = 0;
1615 virtual const_node_iterator bid_nodes_end (boundary_id_type bndry_id) const = 0;
1616
1617 /**
1618 * Iterate over nodes for which BoundaryInfo::n_boundary_ids(node) > 0.
1619 */
1620 virtual node_iterator bnd_nodes_begin () = 0;
1621 virtual node_iterator bnd_nodes_end () = 0;
1622 virtual const_node_iterator bnd_nodes_begin () const = 0;
1623 virtual const_node_iterator bnd_nodes_end () const = 0;
1624
1625 /**
1626 * Iterate over nodes in the Mesh where the solution (as
1627 * distributed by the given DofMap) can be evaluated, for the given
1628 * variable var_num, or for all variables by default.
1629 */
1630 virtual node_iterator
1631 evaluable_nodes_begin (const DofMap & dof_map,
1632 unsigned int var_num = libMesh::invalid_uint) = 0;
1633
1634 virtual node_iterator
1635 evaluable_nodes_end (const DofMap & dof_map,
1636 unsigned int var_num = libMesh::invalid_uint) = 0;
1637
1638 virtual const_node_iterator
1639 evaluable_nodes_begin (const DofMap & dof_map,
1640 unsigned int var_num = libMesh::invalid_uint) const = 0;
1641
1642 virtual const_node_iterator
1643 evaluable_nodes_end (const DofMap & dof_map,
1644 unsigned int var_num = libMesh::invalid_uint) const = 0;
1645
1646 /**
1647 * \returns A writable reference to the whole subdomain name map
1648 */
set_subdomain_name_map()1649 std::map<subdomain_id_type, std::string> & set_subdomain_name_map ()
1650 { return _block_id_to_name; }
get_subdomain_name_map()1651 const std::map<subdomain_id_type, std::string> & get_subdomain_name_map () const
1652 { return _block_id_to_name; }
1653
1654
1655 /**
1656 * Search the mesh and cache the different dimensions of the elements
1657 * present in the mesh. This is done in prepare_for_use(), but can
1658 * be done manually by other classes after major mesh modifications.
1659 */
1660 void cache_elem_dims();
1661
1662 /**
1663 * Search the mesh for elements that have a neighboring element
1664 * of dim+1 and set that element as the interior parent
1665 */
1666 void detect_interior_parents();
1667
1668
1669 /**
1670 * This class holds the boundary information. It can store nodes, edges,
1671 * and faces with a corresponding id that facilitates setting boundary
1672 * conditions.
1673 *
1674 * Direct access to this class will be removed in future libMesh
1675 * versions. Use the \p get_boundary_info() accessor instead.
1676 */
1677 std::unique_ptr<BoundaryInfo> boundary_info;
1678
1679
1680 protected:
1681
1682 /**
1683 * \returns A writable reference to the number of partitions.
1684 */
set_n_partitions()1685 unsigned int & set_n_partitions ()
1686 { return _n_parts; }
1687
1688 /**
1689 * The number of partitions the mesh has. This is set by
1690 * the partitioners, and may not be changed directly by
1691 * the user.
1692 *
1693 * \note The number of partitions \e need \e not equal
1694 * this->n_processors(), consider for example the case where you
1695 * simply want to partition a mesh on one processor and view the
1696 * result in GMV.
1697 */
1698 unsigned int _n_parts;
1699
1700 /**
1701 * The default mapping type (typically Lagrange) between master and
1702 * physical space to assign to newly added elements.
1703 */
1704 ElemMappingType _default_mapping_type;
1705
1706 /**
1707 * The default mapping data (unused with Lagrange, used for nodal
1708 * weight lookup index with rational bases) to assign to newly added
1709 * elements.
1710 */
1711 unsigned char _default_mapping_data;
1712
1713 /**
1714 * Flag indicating if the mesh has been prepared for use.
1715 */
1716 bool _is_prepared;
1717
1718 /**
1719 * A \p PointLocator class for this mesh.
1720 * This will not actually be built unless needed. Further, since we want
1721 * our \p point_locator() method to be \p const (yet do the dynamic allocating)
1722 * this needs to be mutable. Since the PointLocatorBase::build() member is used,
1723 * and it operates on a constant reference to the mesh, this is OK.
1724 */
1725 mutable std::unique_ptr<PointLocatorBase> _point_locator;
1726
1727 /**
1728 * Do we count lower dimensional elements in point locator refinement?
1729 * This is relevant in tree-based point locators, for example.
1730 */
1731 bool _count_lower_dim_elems_in_point_locator;
1732
1733 /**
1734 * A partitioner to use at each prepare_for_use().
1735 *
1736 * This will be built in the constructor of each derived class, but
1737 * can be replaced by the user through the partitioner() accessor.
1738 */
1739 std::unique_ptr<Partitioner> _partitioner;
1740
1741 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1742 /**
1743 * The next available unique id for assigning ids to DOF objects
1744 */
1745 unique_id_type _next_unique_id;
1746 #endif
1747
1748 /**
1749 * If this is true then no partitioning should be done with the
1750 * possible exception of orphaned nodes.
1751 */
1752 bool _skip_noncritical_partitioning;
1753
1754 /**
1755 * If this is true then no partitioning should be done.
1756 */
1757 bool _skip_all_partitioning;
1758
1759 /**
1760 * If this is true then renumbering will be kept to a minimum.
1761 *
1762 * This is set when prepare_for_use() is called.
1763 */
1764 bool _skip_renumber_nodes_and_elements;
1765
1766 /**
1767 * If this is \p true then we will skip \p find_neighbors in \p prepare_for_use
1768 */
1769 bool _skip_find_neighbors;
1770
1771 /**
1772 * If this is false then even on DistributedMesh remote elements
1773 * will not be deleted during mesh preparation.
1774 *
1775 * This is true by default.
1776 */
1777 bool _allow_remote_element_removal;
1778
1779 /**
1780 * This structure maintains the mapping of named blocks
1781 * for file formats that support named blocks. Currently
1782 * this is only implemented for ExodusII
1783 */
1784 std::map<subdomain_id_type, std::string> _block_id_to_name;
1785
1786 /**
1787 * We cache the dimension of the elements present in the mesh.
1788 * So, if we have a mesh with 1D and 2D elements, this structure
1789 * will contain 1 and 2.
1790 */
1791 std::set<unsigned char> _elem_dims;
1792
1793 /**
1794 * The "spatial dimension" of the Mesh. See the documentation for
1795 * Mesh::spatial_dimension() for more information.
1796 */
1797 unsigned char _spatial_dimension;
1798
1799 /**
1800 * The array of names for integer data associated with each element
1801 * in the mesh
1802 */
1803 std::vector<std::string> _elem_integer_names;
1804
1805 /**
1806 * The array of default initialization values for integer data
1807 * associated with each element in the mesh
1808 */
1809 std::vector<dof_id_type> _elem_integer_default_values;
1810
1811 /**
1812 * The array of names for integer data associated with each node
1813 * in the mesh
1814 */
1815 std::vector<std::string> _node_integer_names;
1816
1817 /**
1818 * The array of default initialization values for integer data
1819 * associated with each node in the mesh
1820 */
1821 std::vector<dof_id_type> _node_integer_default_values;
1822
1823 /**
1824 * Size extra-integer arrays of all elements in the mesh
1825 */
1826 void size_elem_extra_integers();
1827
1828 /**
1829 * Size extra-integer arrays of all nodes in the mesh
1830 */
1831 void size_node_extra_integers();
1832
1833 /**
1834 * Merge extra-integer arrays from an \p other mesh. Returns two
1835 * mappings from index values in \p other to (possibly newly created)
1836 * index values with the same string name in \p this mesh, the first
1837 * for element integers and the second for node integers.
1838 */
1839 std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
1840 merge_extra_integer_names(const MeshBase & other);
1841
1842 /**
1843 * The default geometric GhostingFunctor, used to implement standard
1844 * libMesh element ghosting behavior. We use a base class pointer
1845 * here to avoid dragging in more header dependencies.
1846 */
1847 std::unique_ptr<GhostingFunctor> _default_ghosting;
1848
1849 /**
1850 * The list of all GhostingFunctor objects to be used when
1851 * distributing a DistributedMesh.
1852 *
1853 * Basically unused by ReplicatedMesh for now, but belongs to
1854 * MeshBase because the cost is trivial.
1855 */
1856 std::set<GhostingFunctor *> _ghosting_functors;
1857
1858 /**
1859 * Hang on to references to any GhostingFunctor objects we were
1860 * passed in shared_ptr form
1861 */
1862 std::map<GhostingFunctor *, std::shared_ptr<GhostingFunctor> > _shared_functors;
1863
1864 /**
1865 * If nonzero, we will call PointLocatorBase::set_close_to_point_tol()
1866 * on any PointLocators that we create.
1867 */
1868 Real _point_locator_close_to_point_tol;
1869
1870 /**
1871 * The partitioner class is a friend so that it can set
1872 * the number of partitions.
1873 */
1874 friend class Partitioner;
1875
1876 /**
1877 * The MeshInput classes are friends so that they can set the number
1878 * of partitions.
1879 */
1880 friend class MeshInput<MeshBase>;
1881
1882 /**
1883 * Make the \p BoundaryInfo class a friend so that
1884 * it can create and interact with \p BoundaryMesh.
1885 */
1886 friend class BoundaryInfo;
1887
1888 /**
1889 * Make the \p MeshCommunication class a friend so that
1890 * it can directly broadcast *_integer_names
1891 */
1892 friend class MeshCommunication;
1893 };
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905 /**
1906 * The definition of the element_iterator struct.
1907 */
1908 struct
1909 MeshBase::element_iterator : variant_filter_iterator<MeshBase::Predicate, Elem *>
1910 {
1911 // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
1912 template <typename PredType, typename IterType>
element_iteratorelement_iterator1913 element_iterator (const IterType & d,
1914 const IterType & e,
1915 const PredType & p ) :
1916 variant_filter_iterator<MeshBase::Predicate, Elem *>(d,e,p) {}
1917 };
1918
1919
1920
1921
1922 /**
1923 * The definition of the const_element_iterator struct. It is similar to the regular
1924 * iterator above, but also provides an additional conversion-to-const ctor.
1925 */
1926 struct
1927 MeshBase::const_element_iterator : variant_filter_iterator<MeshBase::Predicate,
1928 Elem * const,
1929 Elem * const &,
1930 Elem * const *>
1931 {
1932 /**
1933 * Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor.
1934 */
1935 template <typename PredType, typename IterType>
const_element_iteratorconst_element_iterator1936 const_element_iterator (const IterType & d,
1937 const IterType & e,
1938 const PredType & p ) :
1939 variant_filter_iterator<MeshBase::Predicate, Elem * const, Elem * const &, Elem * const *>(d,e,p) {}
1940
1941 /**
1942 * The conversion-to-const ctor. Takes a regular iterator and calls the appropriate
1943 * variant_filter_iterator copy constructor.
1944 *
1945 * \note This one is \e not templated!
1946 */
const_element_iteratorconst_element_iterator1947 const_element_iterator (const MeshBase::element_iterator & rhs) :
1948 variant_filter_iterator<Predicate, Elem * const, Elem * const &, Elem * const *>(rhs) {}
1949 };
1950
1951
1952
1953
1954
1955
1956
1957 /**
1958 * The definition of the node_iterator struct.
1959 */
1960 struct
1961 MeshBase::node_iterator : variant_filter_iterator<MeshBase::Predicate, Node *>
1962 {
1963 /**
1964 * Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor.
1965 */
1966 template <typename PredType, typename IterType>
node_iteratornode_iterator1967 node_iterator (const IterType & d,
1968 const IterType & e,
1969 const PredType & p ) :
1970 variant_filter_iterator<MeshBase::Predicate, Node *>(d,e,p) {}
1971 };
1972
1973
1974
1975
1976 /**
1977 * The definition of the const_node_iterator struct. It is similar to the regular
1978 * iterator above, but also provides an additional conversion-to-const ctor.
1979 */
1980 struct
1981 MeshBase::const_node_iterator : variant_filter_iterator<MeshBase::Predicate,
1982 Node * const,
1983 Node * const &,
1984 Node * const *>
1985 {
1986 /**
1987 * Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor.
1988 */
1989 template <typename PredType, typename IterType>
const_node_iteratorconst_node_iterator1990 const_node_iterator (const IterType & d,
1991 const IterType & e,
1992 const PredType & p ) :
1993 variant_filter_iterator<MeshBase::Predicate, Node * const, Node * const &, Node * const *>(d,e,p) {}
1994
1995 /**
1996 * The conversion-to-const ctor. Takes a regular iterator and calls the appropriate
1997 * variant_filter_iterator copy constructor.
1998 *
1999 * \note This one is *not* templated!
2000 */
const_node_iteratorconst_node_iterator2001 const_node_iterator (const MeshBase::node_iterator & rhs) :
2002 variant_filter_iterator<Predicate, Node * const, Node * const &, Node * const *>(rhs) {}
2003 };
2004
2005
2006 template <typename T>
2007 inline
add_elem_datum(const std::string & name,bool allocate_data,const T * default_value)2008 unsigned int MeshBase::add_elem_datum(const std::string & name,
2009 bool allocate_data,
2010 const T * default_value)
2011 {
2012 const std::size_t old_size = _elem_integer_names.size();
2013
2014 unsigned int n_more_integers = (sizeof(T)-1)/sizeof(dof_id_type);
2015 std::vector<dof_id_type> int_data(n_more_integers+1, DofObject::invalid_id);
2016 if (default_value)
2017 std::memcpy(int_data.data(), default_value, sizeof(T));
2018
2019 unsigned int start_idx = this->add_elem_integer(name, false, int_data[0]);
2020 for (unsigned int i=0; i != n_more_integers; ++i)
2021 this->add_elem_integer(name+"__"+std::to_string(i), false, int_data[i+1]);
2022
2023 if (allocate_data && old_size != _elem_integer_names.size())
2024 this->size_elem_extra_integers();
2025
2026 return start_idx;
2027 }
2028
2029
2030 template <typename T>
2031 inline
add_elem_data(const std::vector<std::string> & names,bool allocate_data,const std::vector<T> * default_values)2032 std::vector<unsigned int> MeshBase::add_elem_data(const std::vector<std::string> & names,
2033 bool allocate_data,
2034 const std::vector<T> * default_values)
2035 {
2036 libmesh_assert(!default_values || default_values->size() == names.size());
2037
2038 std::vector<unsigned int> returnval(names.size());
2039
2040 const std::size_t old_size = _elem_integer_names.size();
2041
2042 for (auto i : index_range(names))
2043 returnval[i] =
2044 this->add_elem_datum<T>(names[i], false,
2045 default_values ?
2046 (*default_values)[i] : nullptr);
2047
2048 if (allocate_data && old_size != _elem_integer_names.size())
2049 this->size_elem_extra_integers();
2050
2051 return returnval;
2052 }
2053
2054
2055 template <typename T>
2056 inline
add_node_datum(const std::string & name,bool allocate_data,const T * default_value)2057 unsigned int MeshBase::add_node_datum(const std::string & name,
2058 bool allocate_data,
2059 const T * default_value)
2060 {
2061 const std::size_t old_size = _node_integer_names.size();
2062
2063 unsigned int n_more_integers = (sizeof(T)-1)/sizeof(dof_id_type);
2064 std::vector<dof_id_type> int_data(n_more_integers+1, DofObject::invalid_id);
2065 if (default_value)
2066 std::memcpy(int_data.data(), default_value, sizeof(T));
2067
2068 unsigned int start_idx = this->add_node_integer(name, false, int_data[0]);
2069 for (unsigned int i=0; i != n_more_integers; ++i)
2070 this->add_node_integer(name+"__"+std::to_string(i), false, int_data[i+1]);
2071
2072 if (allocate_data && old_size != _node_integer_names.size())
2073 this->size_node_extra_integers();
2074
2075 return start_idx;
2076 }
2077
2078
2079 template <typename T>
2080 inline
add_node_data(const std::vector<std::string> & names,bool allocate_data,const std::vector<T> * default_values)2081 std::vector<unsigned int> MeshBase::add_node_data(const std::vector<std::string> & names,
2082 bool allocate_data,
2083 const std::vector<T> * default_values)
2084 {
2085 libmesh_assert(!default_values || default_values->size() == names.size());
2086
2087 std::vector<unsigned int> returnval(names.size());
2088
2089 const std::size_t old_size = _node_integer_names.size();
2090
2091 for (auto i : index_range(names))
2092 returnval[i] =
2093 this->add_node_datum<T>(names[i], false,
2094 default_values ?
2095 (*default_values)[i] : nullptr);
2096
2097 if (allocate_data && old_size != _node_integer_names.size())
2098 this->size_node_extra_integers();
2099
2100 return returnval;
2101 }
2102
2103
2104
2105 } // namespace libMesh
2106
2107 #endif // LIBMESH_MESH_BASE_H
2108