Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 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_ELEM_H
21 : #define LIBMESH_ELEM_H
22 :
23 : // Local includes
24 : #include "libmesh/libmesh_common.h"
25 : #include "libmesh/bounding_box.h"
26 : #include "libmesh/dof_object.h"
27 : #include "libmesh/id_types.h"
28 : #include "libmesh/reference_counted_object.h"
29 : #include "libmesh/node.h"
30 : #include "libmesh/enum_elem_type.h" // INVALID_ELEM
31 : #include "libmesh/multi_predicates.h"
32 : #include "libmesh/pointer_to_pointer_iter.h"
33 : #include "libmesh/int_range.h"
34 : #include "libmesh/simple_range.h"
35 : #include "libmesh/variant_filter_iterator.h"
36 : #include "libmesh/hashword.h" // Used in compute_key() functions
37 :
38 : // C++ includes
39 : #include <algorithm>
40 : #include <cstddef>
41 : #include <iostream>
42 : #include <limits.h> // CHAR_BIT
43 : #include <set>
44 : #include <vector>
45 : #include <memory>
46 : #include <array>
47 :
48 : namespace libMesh
49 : {
50 :
51 : // Forward declarations
52 : class BoundaryInfo;
53 : class Elem;
54 : class MeshBase;
55 : class MeshRefinement;
56 : #ifdef LIBMESH_ENABLE_PERIODIC
57 : class PeriodicBoundaries;
58 : class PointLocatorBase;
59 : #endif
60 : template <class SideType, class ParentType>
61 : class Side;
62 : enum ElemQuality : int;
63 : enum IOPackage : int;
64 : enum Order : int;
65 :
66 :
67 : /**
68 : * This is the base class from which all geometric element types are
69 : * derived. The \p Elem class provides standard information such as
70 : * the number of nodes, edges, faces, vertices, children, and
71 : * neighbors it has, as well as access to (or the ability to
72 : * construct) these entities.
73 : *
74 : * An \p Elem has pointers to its \p Node objects. Some of these
75 : * nodes live at the vertices of the element, while others may live on
76 : * edges (and faces in 3D), or interior to the element. The number of
77 : * nodes in a given element, \p n_nodes(), is encoded into the name of
78 : * the class. For example, a \p Tri3 has three nodes which correspond
79 : * to the vertices, while a \p Tri6 has six nodes, three of which are
80 : * located at vertices, and three which are located at the midpoint of
81 : * each edge. Nodes on edges, faces, and element interiors are called
82 : * second-order nodes.
83 : *
84 : * A 1D Elem is an \p Edge, a 2D Elem is a \p Face, and a 3D Elem is a
85 : * \p Cell. An \p Elem is composed of a number of sides, which can
86 : * be accessed as dim-1 dimensional \p Elem types. For example, a \p
87 : * Hex8 is a 3D hexahedral element. A \p Hex8 has 6 sides, which are
88 : * \p Faces of type Quad4.
89 : *
90 : * \author Benjamin S. Kirk
91 : * \date 2002-2007
92 : * \brief The base class for all geometric element types.
93 : */
94 : class Elem : public ReferenceCountedObject<Elem>,
95 : public DofObject
96 : {
97 : protected:
98 :
99 : /**
100 : * Constructor. Creates an element with \p n_nodes nodes,
101 : * \p n_sides sides, \p n_children possible children, and
102 : * parent \p p. The constructor allocates the memory necessary
103 : * to support this data.
104 : */
105 : Elem (const unsigned int n_nodes,
106 : const unsigned int n_sides,
107 : Elem * parent,
108 : Elem ** elemlinkdata,
109 : Node ** nodelinkdata);
110 :
111 : public:
112 :
113 : /**
114 : * Elems are responsible for allocating and deleting space for
115 : * storing pointers to their children during refinement, so they
116 : * cannot currently be (default) copy-constructed or copy-
117 : * assigned. We therefore explicitly delete these operations. In
118 : * addition, the DofObject base class currently has private copy
119 : * construction and assignment operators, so that prevents us from
120 : * copying Elems as well.
121 : */
122 : Elem (Elem &&) = delete;
123 : Elem (const Elem &) = delete;
124 : Elem & operator= (const Elem &) = delete;
125 : Elem & operator= (Elem &&) = delete;
126 :
127 : /**
128 : * Destructor.
129 : */
130 4293416664 : virtual ~Elem() = default;
131 :
132 : /**
133 : * \returns The \p Point associated with local \p Node \p i.
134 : */
135 : const Point & point (const unsigned int i) const;
136 :
137 : /**
138 : * \returns The \p Point associated with local \p Node \p i
139 : * as a writable reference.
140 : */
141 : Point & point (const unsigned int i);
142 :
143 : /**
144 : * \returns The \p Point associated with local \p Node \p i,
145 : * in master element rather than physical coordinates.
146 : */
147 : virtual Point master_point (const unsigned int i) const = 0;
148 :
149 : /**
150 : * \returns The global id number of local \p Node \p i.
151 : */
152 : dof_id_type node_id (const unsigned int i) const;
153 :
154 : /**
155 : * \returns The local id number of global \p Node id \p i,
156 : * or \p invalid_uint if Node id \p i is not local.
157 : */
158 : unsigned int local_node (const dof_id_type i) const;
159 :
160 : /**
161 : * \returns The local index for the \p Node pointer \p node_ptr,
162 : * or \p invalid_uint if \p node_ptr is not a local node.
163 : */
164 : unsigned int get_node_index (const Node * node_ptr) const;
165 :
166 : /**
167 : * \returns A pointer to an array of local node pointers.
168 : */
169 : const Node * const * get_nodes () const;
170 :
171 : /**
172 : * \returns A const pointer to local \p Node \p i.
173 : */
174 : const Node * node_ptr (const unsigned int i) const;
175 :
176 : /**
177 : * \returns A non-const pointer to local \p Node \p i.
178 : */
179 : Node * node_ptr (const unsigned int i);
180 :
181 : /**
182 : * \returns A const reference to local \p Node \p i.
183 : */
184 : const Node & node_ref (const unsigned int i) const;
185 :
186 : /**
187 : * \returns A writable reference to local \p Node \p i.
188 : */
189 : Node & node_ref (const unsigned int i);
190 :
191 : #ifdef LIBMESH_ENABLE_DEPRECATED
192 : /**
193 : * \returns The pointer to the \p Node with local number \p i as a
194 : * writable reference.
195 : *
196 : * \deprecated This setter cannot update the multiple node pointers
197 : * used in a general polyhedron; use the \p set_node overload that
198 : * takes an argument.
199 : */
200 : virtual Node * & set_node (const unsigned int i);
201 : #endif // LIBMESH_ENABLE_DEPRECATED
202 :
203 : /**
204 : * Sets local \p Node \p i to refer to \p node.
205 : */
206 : virtual void set_node (const unsigned int i,
207 : Node * node);
208 :
209 : /**
210 : * Nested classes for use iterating over all nodes of an element.
211 : */
212 : class NodeRefIter;
213 : class ConstNodeRefIter;
214 :
215 : /**
216 : * Returns a range with all nodes of an element, usable in
217 : * range-based for loops. The exact type of the return value here
218 : * may be subject to change in future libMesh releases, but the
219 : * iterators will always dereference to produce a reference to a
220 : * Node.
221 : */
222 : SimpleRange<NodeRefIter> node_ref_range();
223 :
224 : SimpleRange<ConstNodeRefIter> node_ref_range() const;
225 :
226 : /**
227 : * \returns The subdomain that this element belongs to.
228 : */
229 : subdomain_id_type subdomain_id () const;
230 :
231 : /**
232 : * \returns The subdomain that this element belongs to as a
233 : * writable reference.
234 : */
235 : subdomain_id_type & subdomain_id ();
236 :
237 : /**
238 : * A static integral constant representing an invalid subdomain id.
239 : * See also DofObject::{invalid_id, invalid_unique_id, invalid_processor_id}.
240 : *
241 : * \note We don't use the static_cast(-1) trick here since
242 : * \p subdomain_id_type is sometimes a *signed* integer for
243 : * compatibility reasons (see libmesh/id_types.h).
244 : */
245 : static constexpr subdomain_id_type invalid_subdomain_id
246 : = std::numeric_limits<subdomain_id_type>::max();
247 :
248 : /**
249 : * \returns true iff this element type can vary in topology (e.g.
250 : * have different numbers of sides and/or nodes) at runtime. For
251 : * such general polygons or polyhedra, APIs which assume a fixed
252 : * topology are not safe to use.
253 : */
254 287931334 : virtual bool runtime_topology() const { return false; }
255 :
256 : /**
257 : * \returns A pointer to the "reference element" associated
258 : * with this element. The reference element is the image of this
259 : * element in reference parametric space. Importantly, it is *not*
260 : * an actual element in the mesh, but rather a Singleton-type
261 : * object, so for example all \p Quad4 elements share the same
262 : * \p reference_elem().
263 : *
264 : * If the element is of a type that can admit multiple topologies,
265 : * such as a Polygon subtype, then there is no reference element;
266 : * for such types this method should not be used.
267 : */
268 : const Elem * reference_elem () const;
269 :
270 : /**
271 : * \returns An id associated with the \p s side of this element.
272 : * The id is not necessarily unique, but should be close.
273 : */
274 : virtual dof_id_type key (const unsigned int s) const = 0;
275 :
276 : /**
277 : * \returns An id associated with the \p s side of this element, as
278 : * defined solely by element vertices. The id is not necessarily
279 : * unique, but should be close. This is particularly useful in the
280 : * \p MeshBase::find_neighbors() routine.
281 : */
282 : virtual dof_id_type low_order_key (const unsigned int s) const = 0;
283 :
284 : /**
285 : * \returns An id associated with the global node ids of this
286 : * element. The id is not necessarily unique, but should be
287 : * close. Uses the same hash as the key(s) function, so for example
288 : * if "tri3" is side 0 of "tet4", then tri3->key()==tet4->key(0).
289 : */
290 : virtual dof_id_type key () const;
291 :
292 : /**
293 : * \returns \p true if two elements are equivalent, false otherwise.
294 : * This is true if the elements are connected to identical global
295 : * nodes, regardless of how those nodes might be numbered local
296 : * to the elements.
297 : */
298 : bool operator == (const Elem & rhs) const;
299 :
300 : /**
301 : * \returns \p true if two elements have equal topologies, false
302 : * otherwise.
303 : * This is true if the elements connect to nodes of the same id in
304 : * the same order, and neighbors of the same id on each side, the
305 : * same id on any parent and/or interior_parent link, etc.
306 : */
307 : bool topologically_equal (const Elem & rhs) const;
308 :
309 : /**
310 : * \returns A const pointer to the \f$ i^{th} \f$ neighbor of this
311 : * element, or \p nullptr if \p MeshBase::find_neighbors() has not been
312 : * called.
313 : *
314 : * \note If \p MeshBase::find_neighbors() has been called and this
315 : * function still returns \p nullptr, then the side is on a boundary of
316 : * the domain.
317 : */
318 : const Elem * neighbor_ptr (unsigned int i) const;
319 :
320 : /**
321 : * \returns A non-const pointer to the \f$ i^{th} \f$ neighbor of this element.
322 : */
323 : Elem * neighbor_ptr (unsigned int i);
324 :
325 : /**
326 : * Nested "classes" for use iterating over all neighbors of an element.
327 : */
328 : typedef Elem * const * NeighborPtrIter;
329 : typedef const Elem * const * ConstNeighborPtrIter;
330 :
331 : /**
332 : * Returns a range with all neighbors of an element, usable in
333 : * range-based for loops. The exact type of the return value here
334 : * may be subject to change in future libMesh releases, but the
335 : * iterators will always dereference to produce a pointer to a
336 : * neighbor element (or a null pointer, for sides which have no
337 : * neighbors).
338 : */
339 : SimpleRange<NeighborPtrIter> neighbor_ptr_range();
340 :
341 : SimpleRange<ConstNeighborPtrIter> neighbor_ptr_range() const;
342 :
343 : #ifdef LIBMESH_ENABLE_PERIODIC
344 : /**
345 : * \returns A pointer to the \f$ i^{th} \f$ neighbor of this element
346 : * for interior elements. If an element is on a periodic
347 : * boundary, it will return a corresponding element on the opposite
348 : * side.
349 : */
350 : const Elem * topological_neighbor (const unsigned int i,
351 : const MeshBase & mesh,
352 : const PointLocatorBase & point_locator,
353 : const PeriodicBoundaries * pb) const;
354 :
355 : /**
356 : * \returns A writable pointer to the \f$ i^{th} \f$ neighbor of
357 : * this element for interior elements. If an element is on a
358 : * periodic boundary, it will return a corresponding element on the
359 : * opposite side.
360 : */
361 : Elem * topological_neighbor (const unsigned int i,
362 : MeshBase & mesh,
363 : const PointLocatorBase & point_locator,
364 : const PeriodicBoundaries * pb);
365 :
366 : /**
367 : * \returns \p true if the element \p elem in question is a neighbor or
368 : * topological neighbor of this element, \p false otherwise.
369 : */
370 : bool has_topological_neighbor (const Elem * elem,
371 : const MeshBase & mesh,
372 : const PointLocatorBase & point_locator,
373 : const PeriodicBoundaries * pb) const;
374 : #endif
375 :
376 : /**
377 : * Assigns \p n as the \f$ i^{th} \f$ neighbor.
378 : */
379 : void set_neighbor (const unsigned int i, Elem * n);
380 :
381 : /**
382 : * \returns \p true if the element \p elem in question is a neighbor
383 : * of this element, \p false otherwise.
384 : */
385 : bool has_neighbor (const Elem * elem) const;
386 :
387 : /**
388 : * \returns If \p elem is a neighbor of a child of this element, a
389 : * pointer to that child, otherwise \p nullptr.
390 : */
391 : Elem * child_neighbor (Elem * elem);
392 :
393 : /**
394 : * \returns If \p elem is a neighbor of a child of this element, a
395 : * pointer to that child, otherwise \p nullptr.
396 : */
397 : const Elem * child_neighbor (const Elem * elem) const;
398 :
399 : /**
400 : * \returns \p true if this element has a side coincident
401 : * with a boundary (indicated by a \p nullptr neighbor), \p false
402 : * otherwise.
403 : */
404 : bool on_boundary () const;
405 :
406 : /**
407 : * \returns \p true if this element is "semilocal" to the calling
408 : * processor, which must specify its rank.
409 : *
410 : * This method is discouraged, as it uses the *old* definition of
411 : * semilocal (elements which are not local but which are point
412 : * neighbors of something local) rather than any of the new
413 : * definitions discussed in ghosting_functor.h
414 : */
415 : bool is_semilocal (const processor_id_type my_pid) const;
416 :
417 : /**
418 : * This function tells you which neighbor \p e is.
419 : * I.e. if s = a->which_neighbor_am_i(e); then
420 : * a->neighbor(s) will be an ancestor of e.
421 : */
422 : unsigned int which_neighbor_am_i(const Elem * e) const;
423 :
424 : /**
425 : * This function tells you which side the boundary element \p e is.
426 : * I.e. if e = a->build_side_ptr(s) or e = a->side_ptr(s); then
427 : * a->which_side_am_i(e) will be s.
428 : *
429 : * \note An \e exact floating point comparison of the nodal
430 : * positions of \p e is made with the nodal positions of \p this in
431 : * order to perform this test. The idea is that the test will return
432 : * a valid side id if \p e either directly shares Node pointers with
433 : * \p this, or was created by exactly copying some of the nodes of
434 : * \p this (e.g. through BoundaryMesh::sync()). In these
435 : * circumstances, non-fuzzy floating point equality is expected.
436 : *
437 : * \returns The side of \p this the element which \p e is, otherwise
438 : * \p invalid_uint.
439 : */
440 : unsigned int which_side_am_i(const Elem * e) const;
441 :
442 : /**
443 : * \returns The local node id for node \p side_node on side \p side of
444 : * this Elem. Simply relies on the \p side_nodes_map for each of the
445 : * derived types. For example,
446 : * Tri3::local_side_node(0, 0) -> 0
447 : * Tri3::local_side_node(0, 1) -> 1
448 : * Tri3::local_side_node(1, 0) -> 1
449 : * Tri3::local_side_node(1, 1) -> 2
450 : * etc...
451 : */
452 : virtual unsigned int local_side_node(unsigned int side,
453 : unsigned int side_node) const = 0;
454 :
455 : /**
456 : * Similar to Elem::local_side_node(), but instead of a side id, takes
457 : * an edge id and a node id on that edge and returns a local node number
458 : * for the Elem. The implementation relies on the "edge_nodes_map" tables
459 : * for 3D elements. For 2D elements, calls local_side_node(). Throws an
460 : * error if called on 1D elements.
461 : */
462 : virtual unsigned int local_edge_node(unsigned int edge,
463 : unsigned int edge_node) const = 0;
464 :
465 : #ifdef LIBMESH_ENABLE_DEPRECATED
466 : /**
467 : * This function is deprecated, call local_side_node(side, side_node) instead.
468 : */
469 : unsigned int which_node_am_i(unsigned int side,
470 : unsigned int side_node) const;
471 : #endif // LIBMESH_ENABLE_DEPRECATED
472 :
473 : /**
474 : * \returns \p true if a vertex of \p e is contained
475 : * in this element. If \p mesh_connection is true, looks
476 : * specifically for containment possibilities of an element \p e
477 : * that is connected to \p this via membership in the same manifold
478 : * of the same mesh.
479 : */
480 : bool contains_vertex_of(const Elem * e, bool mesh_connection=false) const;
481 :
482 : /**
483 : * \returns \p true if an edge of \p e is contained in
484 : * this element. (Internally, this is done by checking whether at
485 : * least two vertices of \p e are contained in this element).
486 : */
487 : bool contains_edge_of(const Elem * e) const;
488 :
489 : /**
490 : * This function finds all active elements (including this one)
491 : * which are in the same manifold as this element and which touch
492 : * the current active element at the specified point, which should
493 : * be a point in the current element.
494 : *
495 : * Elements which are not "in the same manifold" (e.g. the
496 : * interior_parent of a boundary element) will not be found with
497 : * this method.
498 : *
499 : * Elements which overlap the specified point but which are only
500 : * connected to the current element via elements which do not
501 : * overlap that point (e.g. in a folded or tangled mesh) are not
502 : * considered to "touch" the current element and will not be found
503 : * with this method.
504 : */
505 : void find_point_neighbors(const Point & p,
506 : std::set<const Elem *> & neighbor_set) const;
507 :
508 : /**
509 : * This function finds all active elements (including this one) in
510 : * the same manifold as this element which touch this active element
511 : * at any point.
512 : */
513 : void find_point_neighbors(std::set<const Elem *> & neighbor_set) const;
514 :
515 : /**
516 : * This function finds all active elements (including this one) in
517 : * the same manifold as start_elem (which must be active and must
518 : * touch this element) which touch this element at any point.
519 : */
520 : void find_point_neighbors(std::set<const Elem *> & neighbor_set,
521 : const Elem * start_elem) const;
522 :
523 : /**
524 : * Non-const version of function above. Fills a set of non-const Elem pointers.
525 : */
526 : void find_point_neighbors(std::set<Elem *> & neighbor_set,
527 : Elem * start_elem);
528 :
529 : /**
530 : * This function finds all active elements in the same manifold as
531 : * this element which touch the current active element along the
532 : * whole edge defined by the two points \p p1 and \p p2.
533 : */
534 : void find_edge_neighbors(const Point & p1,
535 : const Point & p2,
536 : std::set<const Elem *> & neighbor_set) const;
537 :
538 : /**
539 : * This function finds all active elements in the same manifold as
540 : * this element which touch the current active element along any
541 : * edge (more precisely, at at least two points).
542 : *
543 : * In this case, elements are included even if they do not touch a
544 : * *whole* edge of this element.
545 : */
546 : void find_edge_neighbors(std::set<const Elem *> & neighbor_set) const;
547 :
548 : /**
549 : * This function finds all active elements (*not* including this
550 : * one) in the parent manifold of this element whose intersection
551 : * with this element has non-zero measure.
552 : */
553 : void find_interior_neighbors(std::set<const Elem *> & neighbor_set) const;
554 :
555 : /**
556 : * Non-const version of function above that fills up a vector of
557 : * non-const Elem pointers instead.
558 : */
559 : void find_interior_neighbors(std::set<Elem *> & neighbor_set);
560 :
561 : /**
562 : * Resets this element's neighbors' appropriate neighbor pointers
563 : * and its parent's and children's appropriate pointers
564 : * to point to null instead of to this.
565 : *
566 : * To be used before an element is deleted from a mesh.
567 : */
568 : void remove_links_to_me ();
569 :
570 : /**
571 : * Resets this element's neighbors' appropriate neighbor pointers
572 : * and its parent's and children's appropriate pointers
573 : * to point to the global remote_elem instead of this.
574 : * Used by the library before an element becomes remote on the
575 : * local processor.
576 : */
577 : void make_links_to_me_remote ();
578 :
579 : /**
580 : * Resets the \p neighbor_side pointers of our nth neighbor (and
581 : * its descendants, if appropriate) to point to this Elem instead of
582 : * to the global remote_elem. Used by the library when a formerly
583 : * remote element is being added to the local processor.
584 : */
585 : void make_links_to_me_local (unsigned int n, unsigned int neighbor_side);
586 :
587 : /**
588 : * \returns \p true if this element is remote, false otherwise.
589 : *
590 : * A remote element (see \p RemoteElem) is a syntactic convenience --
591 : * it is a placeholder for an element which exists on some other
592 : * processor. Local elements are required to have valid neighbors,
593 : * and these ghost elements may have remote neighbors for data
594 : * structure consistency. The use of remote elements helps ensure
595 : * that any element we may access has a \p nullptr neighbor only if it
596 : * lies on the physical boundary of the domain.
597 : */
598 7280126 : virtual bool is_remote () const
599 7280126 : { return false; }
600 :
601 : /**
602 : * \returns The connectivity for this element in a specific
603 : * format, which is specified by the IOPackage tag.
604 : */
605 : virtual void connectivity(const unsigned int sc,
606 : const IOPackage iop,
607 : std::vector<dof_id_type> & conn) const = 0;
608 :
609 : /**
610 : * Writes the element connectivity for various IO packages
611 : * to the passed ostream "out". Not virtual, since it is
612 : * implemented in the base class.
613 : */
614 : void write_connectivity (std::ostream & out,
615 : const IOPackage iop) const;
616 :
617 : /**
618 : * \returns The type of element that has been derived from this
619 : * base class.
620 : */
621 : virtual ElemType type () const = 0;
622 :
623 : /**
624 : * This array maps the integer representation of the \p ElemType enum
625 : * to the geometric dimension of the element.
626 : *
627 : * This is currently usable even for complicated subclasses with
628 : * runtime-varying topology.
629 : */
630 : static const unsigned int type_to_dim_map[INVALID_ELEM];
631 :
632 : /**
633 : * \returns The dimensionality of the object.
634 : */
635 : virtual unsigned short dim () const = 0;
636 :
637 : /**
638 : * This array maps the integer representation of the \p ElemType enum
639 : * to the number of nodes in the element.
640 : *
641 : * This is only usable for simple types for which the node number
642 : * is fixed; for more general types like Polygon subclasses an actual
643 : * instantiated Elem must be queried.
644 : */
645 : static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
646 :
647 : /**
648 : * \returns The number of nodes this element contains.
649 : */
650 : virtual unsigned int n_nodes () const = 0;
651 :
652 : /**
653 : * The maximum number of nodes *any* element can contain.
654 : * This is useful for replacing heap vectors with stack arrays.
655 : */
656 : static const unsigned int max_n_nodes = 27;
657 :
658 : /**
659 : * \returns An integer range from 0 up to (but not including)
660 : * the number of nodes this element contains.
661 : */
662 : IntRange<unsigned short> node_index_range () const;
663 :
664 : /**
665 : * \returns The number of nodes the given child of this element
666 : * contains. Except in odd cases like pyramid refinement this will
667 : * be the same as the number of nodes in the parent element.
668 : */
669 18635183 : virtual unsigned int n_nodes_in_child (unsigned int /*c*/) const
670 18635183 : { return this->n_nodes(); }
671 :
672 : /**
673 : * This array maps the integer representation of the \p ElemType enum
674 : * to the number of sides on the element.
675 : *
676 : * This is only usable for simple types for which the node number
677 : * is fixed; for more general types like Polygon subclasses an actual
678 : * instantiated Elem must be queried.
679 : */
680 : static const unsigned int type_to_n_sides_map[INVALID_ELEM];
681 :
682 : /**
683 : * \returns The number of sides the element that has been derived
684 : * from this class has. In 2D the number of sides is the number
685 : * of edges, in 3D the number of sides is the number of faces.
686 : */
687 : virtual unsigned int n_sides () const = 0;
688 :
689 : /**
690 : * \returns The type of element for side \p s.
691 : */
692 : virtual ElemType side_type (const unsigned int s) const = 0;
693 :
694 : /**
695 : * \returns the normal (outwards-facing) of the side of the element at the vertex-average of the side
696 : * @param s the side of interest
697 : */
698 : virtual Point side_vertex_average_normal(const unsigned int s) const;
699 :
700 : /**
701 : * \returns An integer range from 0 up to (but not including)
702 : * the number of sides this element has.
703 : */
704 : IntRange<unsigned short> side_index_range () const;
705 :
706 : /**
707 : * \returns The number of neighbors the element that has been derived
708 : * from this class has.
709 : *
710 : * Only face (or edge in 2D) neighbors are stored, so this method
711 : * returns n_sides(). At one point we intended to allow derived
712 : * classes to override this, but too much current libMesh code
713 : * assumes n_neighbors==n_sides.
714 : */
715 85303600 : unsigned int n_neighbors () const
716 152202622 : { return this->n_sides(); }
717 :
718 : /**
719 : * \returns The number of vertices the element that has been derived
720 : * from this class has.
721 : */
722 : virtual unsigned int n_vertices () const = 0;
723 :
724 : /**
725 : * \returns The number of edges the element that has been derived
726 : * from this class has.
727 : */
728 : virtual unsigned int n_edges () const = 0;
729 :
730 : /**
731 : * \returns An integer range from 0 up to (but not including)
732 : * the number of edges this element has.
733 : */
734 : IntRange<unsigned short> edge_index_range () const;
735 :
736 : /**
737 : * This array maps the integer representation of the \p ElemType enum
738 : * to the number of edges on the element.
739 : *
740 : * This is only usable for simple types for which the node number
741 : * is fixed; for more general types like Polygon subclasses an actual
742 : * instantiated Elem must be queried.
743 : */
744 : static const unsigned int type_to_n_edges_map[INVALID_ELEM];
745 :
746 : /**
747 : * \returns The number of faces the element that has been derived
748 : * from this class has.
749 : */
750 : virtual unsigned int n_faces () const = 0;
751 :
752 : /**
753 : * \returns An integer range from 0 up to (but not including)
754 : * the number of faces this element has.
755 : */
756 : IntRange<unsigned short> face_index_range () const;
757 :
758 : /**
759 : * \returns The number of children the element that has been derived
760 : * from this class may have.
761 : */
762 : virtual unsigned int n_children () const = 0;
763 :
764 : /**
765 : * \returns \p true if the specified (local) node number is a vertex node.
766 : */
767 : virtual bool is_vertex(const unsigned int i) const = 0;
768 :
769 : /**
770 : * \returns \p true if the specified child has a vertex at the
771 : * specified (child-local) node number.
772 : * Except in odd cases like pyramid refinement the child will have
773 : * the same local structure as the parent element.
774 : */
775 169263 : virtual bool is_vertex_on_child (unsigned int /*c*/,
776 : unsigned int n) const
777 169263 : { return this->is_vertex(n); }
778 :
779 : /**
780 : * \returns \p true if this element has a vertex at the specified
781 : * (child-local) node number \p n of the specified child \p c.
782 : */
783 : virtual bool is_vertex_on_parent(unsigned int c,
784 : unsigned int n) const;
785 :
786 : /**
787 : * \returns \p true if the specified (local) node number is an edge node.
788 : * For 1D elements, is_edge() is equivalent to is_internal().
789 : */
790 : virtual bool is_edge(const unsigned int i) const = 0;
791 :
792 : /**
793 : * \returns \p true if the specified (local) node number is a face node.
794 : * For 2D elements, is_face() is equivalent to is_internal().
795 : * For 1D elements, is_face() == false.
796 : */
797 : virtual bool is_face(const unsigned int i) const = 0;
798 :
799 : /**
800 : * \returns \p true if the specified (local) node number is an internal node.
801 : */
802 : bool is_internal(const unsigned int i) const;
803 :
804 : /**
805 : * \returns \p true if the specified (local) node number is on the
806 : * specified side.
807 : */
808 : virtual bool is_node_on_side(const unsigned int n,
809 : const unsigned int s) const = 0;
810 :
811 : /**
812 : * \returns the (local) node numbers on the specified side
813 : */
814 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int /*s*/) const = 0;
815 :
816 : /**
817 : * \returns the (local) node numbers on the specified edge
818 : */
819 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int /*e*/) const = 0;
820 :
821 : /**
822 : * \returns the (local) side numbers that touch the specified edge
823 : */
824 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int /*e*/) const = 0;
825 :
826 : /**
827 : * \returns the (local) edge numbers that touch the specified node
828 : */
829 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int /*n*/) const = 0;
830 :
831 : /**
832 : * \returns \p true if the specified (local) node number is on the
833 : * specified edge.
834 : */
835 : virtual bool is_node_on_edge(const unsigned int n,
836 : const unsigned int e) const = 0;
837 :
838 : /**
839 : * \returns \p true if the specified edge is on the specified side.
840 : */
841 : virtual bool is_edge_on_side(const unsigned int e,
842 : const unsigned int s) const = 0;
843 :
844 : /**
845 : * \returns The side number opposite to \p s (for a tensor product
846 : * element), or throws an error otherwise.
847 : */
848 : virtual unsigned int opposite_side(const unsigned int s) const;
849 :
850 : /**
851 : * \returns The local node number for the node opposite to node n
852 : * on side \p opposite_side(s) (for a tensor product element), or
853 : * throws an error otherwise.
854 : */
855 : virtual unsigned int opposite_node(const unsigned int n,
856 : const unsigned int s) const;
857 :
858 : /**
859 : * \returns The number of sub-elements this element may be broken
860 : * down into for visualization purposes. For example, 1 for a
861 : * linear triangle, 4 for a quadratic (6-noded) triangle, etc...
862 : */
863 : virtual unsigned int n_sub_elem () const = 0;
864 :
865 : /**
866 : * \returns A temporary element coincident with side \p i.
867 : *
868 : * This method returns the _minimum_ element necessary to uniquely
869 : * identify the side. For example, the side of a hexahedron is
870 : * always returned as a 4-noded quadrilateral, regardless of what
871 : * type of hex you are dealing with. Important data like subdomain
872 : * id, p level, or mapping type may be omitted from the temporary
873 : * element. If you want a first-class full-ordered face (i.e. a
874 : * 9-noded quad face for a 27-noded hexahedron), use the
875 : * build_side_ptr method.
876 : *
877 : * \note The const version of this function is non-virtual; it
878 : * simply calls the virtual non-const version and const_casts the
879 : * return type.
880 : */
881 : virtual std::unique_ptr<Elem> side_ptr (unsigned int i) = 0;
882 : std::unique_ptr<const Elem> side_ptr (unsigned int i) const;
883 :
884 : /**
885 : * Resets the loose element \p side, which may currently point to a
886 : * different side than \p i or even a different element than \p
887 : * this, to point to side \p i on \p this. If \p side is currently
888 : * an element of the wrong type, it will be freed and a new element
889 : * allocated; otherwise no memory allocation will occur.
890 : *
891 : * This will cause \p side to be a minimum-ordered element, even if
892 : * it is handed a higher-ordered element that must be replaced.
893 : *
894 : * The const version of this function is non-virtual; it simply
895 : * calls the virtual non-const version and const_casts the return
896 : * type.
897 : */
898 : virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
899 : void side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
900 :
901 : /**
902 : * \returns An temporary element coincident with side \p i wrapped
903 : * in a smart pointer.
904 : *
905 : * The element returned is full-ordered and full-featured, in
906 : * contrast to the side method. For example, calling
907 : * build_side_ptr(0) on a 20-noded hex in subdomain 5 will build a
908 : * 8-noded quadrilateral coincident with face 0, assign it subdomain
909 : * id 5, and pass back the pointer.
910 : *
911 : * The side element's id() is undefined; it is a temporary element
912 : * not added to any mesh.
913 : *
914 : * A \p std::unique_ptr<Elem> is returned to prevent a memory leak.
915 : * This way the user need not remember to delete the object.
916 : *
917 : * The const version of this function is non-virtual; it simply
918 : * calls the virtual non-const version and const_casts the return
919 : * type.
920 : */
921 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) = 0;
922 : std::unique_ptr<const Elem> build_side_ptr (const unsigned int i) const;
923 :
924 : #ifdef LIBMESH_ENABLE_DEPRECATED
925 : /*
926 : * Older versions of libMesh supported a "proxy" option here.
927 : */
928 0 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i, bool proxy)
929 0 : { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
930 :
931 : std::unique_ptr<const Elem> build_side_ptr (const unsigned int i, bool proxy) const
932 : { if (proxy) libmesh_error(); libmesh_deprecated(); return this->build_side_ptr(i); }
933 : #endif
934 :
935 : /**
936 : * Resets the loose element \p side, which may currently point to a
937 : * different side than \p i or even a different element than \p
938 : * this, to point to side \p i on \p this. If \p side is currently
939 : * an element of the wrong type, it will be freed and a new element
940 : * allocated; otherwise no memory allocation will occur.
941 : *
942 : * This will cause \p side to be a full-ordered element, even if it
943 : * is handed a lower-ordered element that must be replaced.
944 : *
945 : * The const version of this function is non-virtual; it simply
946 : * calls the virtual non-const version and const_casts the return
947 : * type.
948 : */
949 : virtual void build_side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) = 0;
950 : void build_side_ptr (std::unique_ptr<const Elem> & side, const unsigned int i) const;
951 :
952 : /**
953 : * \returns An element coincident with edge \p i wrapped in a smart pointer.
954 : *
955 : * The element returned is full-ordered. For example, calling
956 : * build_edge_ptr(0) on a 20-noded hex will build a 3-noded edge
957 : * coincident with edge 0 and pass back the pointer. A \p
958 : * std::unique_ptr<Elem> is returned to prevent a memory leak. This way
959 : * the user need not remember to delete the object.
960 : *
961 : * The const version of this function is non-virtual; it simply
962 : * calls the virtual non-const version and const_casts the return
963 : * type.
964 : */
965 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) = 0;
966 : std::unique_ptr<const Elem> build_edge_ptr (const unsigned int i) const;
967 :
968 : /**
969 : * Resets the loose element \p edge, which may currently point to a
970 : * different edge than \p i or even a different element than \p
971 : * this, to point to edge \p i on \p this. If \p edge is currently
972 : * an element of the wrong type, it will be freed and a new element
973 : * allocated; otherwise no memory allocation will occur.
974 : *
975 : * This will cause \p edge to be a full-ordered element, even if it
976 : * is handed a lower-ordered element that must be replaced.
977 : *
978 : * The const version of this function is non-virtual; it simply
979 : * calls the virtual non-const version and const_casts the return
980 : * type.
981 : */
982 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) = 0;
983 : void build_edge_ptr (std::unique_ptr<const Elem> & edge, const unsigned int i) const;
984 :
985 : /**
986 : * This array maps the integer representation of the \p ElemType enum
987 : * to the default approximation order of elements of that type.
988 : *
989 : * This is currently usable even for complicated subclasses with
990 : * runtime-varying topology.
991 : */
992 : static const Order type_to_default_order_map[INVALID_ELEM];
993 :
994 : /**
995 : * \returns The default approximation order for this element. This
996 : * is the order that will be used to compute the map to the
997 : * reference element.
998 : */
999 : virtual Order default_order () const = 0;
1000 :
1001 : /**
1002 : * \returns The maximum supported approximation order for nodal
1003 : * (Lagrange or Rational Bezier-Bernstein) variables on this element
1004 : * type. This is usually the same as the default order.
1005 : */
1006 38604133 : virtual Order supported_nodal_order() const { return default_order(); }
1007 :
1008 : /**
1009 : * \returns The default approximation order for side elements of
1010 : * this element type. This may be lower for elements with 'bubble
1011 : * functions' in the Lagrange basis.
1012 : */
1013 481370 : virtual Order default_side_order () const { return default_order(); }
1014 :
1015 : #ifdef LIBMESH_ENABLE_DEPRECATED
1016 : /**
1017 : * Calls Elem::vertex_average() for backwards compatibility.
1018 : *
1019 : * \deprecated This method has now been deprecated, so it will be
1020 : * removed at some point in the future. Calls to Elem::centroid()
1021 : * in user code should be updated to either call
1022 : * Elem::vertex_average() or Elem::true_centroid() on a case by case
1023 : * basis.
1024 : */
1025 : virtual Point centroid () const;
1026 : #endif // LIBMESH_ENABLE_DEPRECATED
1027 :
1028 : /**
1029 : * \returns The "true" geometric centroid of the element, c=(cx, cy,
1030 : * cz), where:
1031 : *
1032 : * [cx] [\int x dV]
1033 : * [cy] := (1/V) * [\int y dV]
1034 : * [cz] [\int z dV]
1035 : *
1036 : * This method is virtual since some derived elements might want to
1037 : * use shortcuts to compute their centroid. For most element types,
1038 : * this method is more expensive than calling vertex_average(), so
1039 : * if you only need a point which is located "somewhere" in the
1040 : * interior of the element, consider calling vertex_average() instead.
1041 : */
1042 : virtual Point true_centroid () const;
1043 :
1044 : /**
1045 : * \returns A Point at the average of the elment's vertices.
1046 : *
1047 : * \note This used to be the base class centroid() implementation, but
1048 : * the centroid is only equal to the vertex average in some special cases.
1049 : * The centroid() implementation now returns the "true" centroid of the
1050 : * element (up to quadrature error).
1051 : */
1052 : Point vertex_average () const;
1053 :
1054 : /**
1055 : * \returns The "circumcenter of mass" (area-weighted average of
1056 : * triangulation circumcenters) of the element.
1057 : *
1058 : * Not implemented for infinite elements, not currently implemented
1059 : * for 3D elements, currently ignores curvature of element edges.
1060 : */
1061 0 : virtual Point quasicircumcenter () const
1062 0 : { libmesh_not_implemented(); }
1063 :
1064 : /**
1065 : * \returns The minimum vertex separation for the element.
1066 : */
1067 : virtual Real hmin () const;
1068 :
1069 : /**
1070 : * \returns The maximum vertex separation for the element.
1071 : */
1072 : virtual Real hmax () const;
1073 :
1074 : /**
1075 : * \returns The (length/area/volume) of the geometric element.
1076 : *
1077 : * If the element is twisted or inverted such that the mapping
1078 : * Jacobian is singular at any point, implementations of this method
1079 : * may return a "net" volume or may simply return NaN.
1080 : */
1081 : virtual Real volume () const;
1082 :
1083 : /**
1084 : * \returns A bounding box (not necessarily the minimal bounding box)
1085 : * containing the geometric element.
1086 : *
1087 : * The base class implementation determines a bounding box for the
1088 : * element *nodes*, which should be sufficient for first order
1089 : * finite elements. Higher order geometric elements will need to
1090 : * override with an implementation which takes curved elements into
1091 : * account.
1092 : */
1093 : virtual BoundingBox loose_bounding_box () const;
1094 :
1095 : /**
1096 : * \returns A quantitative assessment of element quality based on
1097 : * the quality metric \p q specified by the user. Not all ElemQuality
1098 : * metrics are supported for all Elem types; consult the Elem::quality()
1099 : * overrides for specific Elem types to determine which quality metrics
1100 : * are supported. The ElemQuality metrics with generic support for all
1101 : * Elems with dimension > 1 are:
1102 : * .) EDGE_LENGTH_RATIO - ratio of maximum to minimum edge (in 2D,
1103 : * side) length, where the min/max is taken over all Elem edges.
1104 : * .) MIN,MAX_ANGLE - The minimum (respectively maximum) angle
1105 : * between all pairs of adjacent Elem edges, in degrees. Note
1106 : * that, in 3D, these are *not* the dihedral angles (angle
1107 : * between adjacent planar faces of the element), which we plan to
1108 : * add support for in the future. In 2D, we compute the angle
1109 : * between adjacent sides for this metric.
1110 : */
1111 : virtual Real quality (const ElemQuality q) const;
1112 :
1113 : /**
1114 : * \returns The suggested quality bounds for the Elem based on
1115 : * quality measure \p q.
1116 : *
1117 : * These are the values suggested by the CUBIT User's Manual. Since
1118 : * this function can have no possible meaning for an abstract Elem,
1119 : * it is an error in the base class.
1120 : */
1121 0 : virtual std::pair<Real,Real> qual_bounds (const ElemQuality) const
1122 0 : { libmesh_not_implemented(); return std::make_pair(0.,0.); }
1123 :
1124 : /**
1125 : * \returns \p true if the physical point p is contained in this
1126 : * element, false otherwise.
1127 : *
1128 : * For linear elements, performs an initial tight bounding box check
1129 : * (as an optimization step) and (if that passes) then uses the
1130 : * user-defined tolerance "tol" in a call to inverse_map() to actually
1131 : * test if the point is in the element. For quadratic elements, the
1132 : * bounding box optimization is skipped, and only the inverse_map()
1133 : * steps are performed.
1134 : *
1135 : * \note This routine should not be used to determine if a point
1136 : * is merely "nearby" an element to within some tolerance. For that,
1137 : * use Elem::close_to_point() instead.
1138 : */
1139 : virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const;
1140 :
1141 : /**
1142 : * \returns \p true if the master-space point p is contained in the
1143 : * reference element corresponding to this element, false otherwise.
1144 : *
1145 : * Since we are doing floating point comparisons here the parameter
1146 : * \p eps can be specified to indicate a tolerance. For example,
1147 : * \f$ x \le 1 \f$ becomes \f$ x \le 1 + \epsilon \f$.
1148 : */
1149 : virtual bool on_reference_element(const Point & p,
1150 : const Real eps = TOLERANCE) const = 0;
1151 :
1152 : /**
1153 : * \returns \p true if this element is "close" to the point p, where
1154 : * "close" is determined by the tolerance tol.
1155 : */
1156 : virtual bool close_to_point(const Point & p, Real tol) const;
1157 :
1158 : /**
1159 : * \returns \p true if edge \p i is positively oriented. An edge is
1160 : * positively oriented iff its first vertex (i.e. zeroth node) is
1161 : * lexicographically greater than its second vertex (i.e. first node).
1162 : */
1163 : bool positive_edge_orientation(const unsigned int i) const;
1164 :
1165 : /**
1166 : * \returns \p true if face \p i is positively oriented. A face is
1167 : * positively oriented iff the triangle defined by the lexicographically
1168 : * least vertex and its two adjacent vertices on the same face is
1169 : * positively oriented. Said triangle is positively oriented iff its
1170 : * vertices are an odd permutation of their lexicographic ordering.
1171 : */
1172 : bool positive_face_orientation(const unsigned int i) const;
1173 :
1174 :
1175 : /**
1176 : * A helper function for copying generic element data (mapping,
1177 : * subdomain, processor) from an element to a derived (child, side,
1178 : * edge) element. Useful for forwards compatibility when new data
1179 : * is added.
1180 : */
1181 : void inherit_data_from(const Elem & src);
1182 :
1183 :
1184 : private:
1185 : /**
1186 : * Shared private implementation used by the contains_point()
1187 : * and close_to_point() routines. The box_tol tolerance is
1188 : * used in the bounding box optimization, the map_tol tolerance is used
1189 : * in the calls to inverse_map() and on_reference_element().
1190 : */
1191 : bool point_test(const Point & p, Real box_tol, Real map_tol) const;
1192 :
1193 : public:
1194 : /**
1195 : * \returns \p true if the element map is definitely affine (i.e. the same at
1196 : * every quadrature point) within numerical tolerances.
1197 : */
1198 0 : virtual bool has_affine_map () const { return false; }
1199 :
1200 : /**
1201 : * \returns \p true if the element map is invertible everywhere on
1202 : * the element, to within a user-specified tolerance. The tolerance
1203 : * is generally used in comparisons against zero, so it should be an
1204 : * absolute rather than a relative tolerance. Throws a
1205 : * libmesh_not_implemented() error unless specialized by derived
1206 : * classes.
1207 : */
1208 : virtual bool has_invertible_map(Real tol = TOLERANCE*TOLERANCE) const;
1209 :
1210 : /**
1211 : * \returns \p true if the Lagrange shape functions on this element
1212 : * are linear.
1213 : */
1214 0 : virtual bool is_linear () const { return false; }
1215 :
1216 : /**
1217 : * Prints relevant information about the element.
1218 : */
1219 : void print_info (std::ostream & os=libMesh::out) const;
1220 :
1221 : /**
1222 : * Prints relevant information about the element to a string.
1223 : */
1224 : std::string get_info () const;
1225 :
1226 : /**
1227 : * \returns \p true if the element is active (i.e. has no active
1228 : * descendants) or AMR is disabled, \p false otherwise.
1229 : *
1230 : * \note It suffices to check the first child only.
1231 : */
1232 : bool active () const;
1233 :
1234 : /**
1235 : * \returns \p true if the element is an ancestor (i.e. has an
1236 : * active child or ancestor child), \p false otherwise or when AMR
1237 : * is disabled.
1238 : */
1239 : bool ancestor () const;
1240 :
1241 : /**
1242 : * \returns \p true if the element is subactive (i.e. has no active
1243 : * descendants), \p false otherwise or if AMR is disabled.
1244 : */
1245 : bool subactive () const;
1246 :
1247 : /**
1248 : * \returns \p true if the element has any children (active or not),
1249 : * \p false otherwise, or if AMR is disabled.
1250 : */
1251 : bool has_children () const;
1252 :
1253 : /**
1254 : * \returns \p true if the element has any descendants other than
1255 : * its immediate children, \p false otherwise, or if AMR is disabled.
1256 : */
1257 : bool has_ancestor_children () const;
1258 :
1259 : /**
1260 : * \returns \p true if \p descendant is a child of \p this, or a
1261 : * child of a child of \p this, etc., \p false otherwise or if AMR
1262 : * is disabled.
1263 : */
1264 : bool is_ancestor_of(const Elem * descendant) const;
1265 :
1266 : /**
1267 : * \returns A const pointer to the element's parent, or \p nullptr if
1268 : * the element was not created via refinement.
1269 : */
1270 : const Elem * parent () const;
1271 :
1272 : /**
1273 : * \returns A pointer to the element's parent, or \p nullptr if
1274 : * the element was not created via refinement.
1275 : */
1276 : Elem * parent ();
1277 :
1278 : /**
1279 : * Sets the pointer to the element's parent.
1280 : * Dangerous! Only use this if you know what you are doing!
1281 : */
1282 : void set_parent (Elem * p);
1283 :
1284 : /**
1285 : * \returns A pointer to the element's top-most (i.e. level-0) parent.
1286 : *
1287 : * That is, \p this if this is a level-0 element, this element's parent
1288 : * if this is a level-1 element, this element's grandparent if this is
1289 : * a level-2 element, etc...
1290 : */
1291 : const Elem * top_parent () const;
1292 :
1293 : /**
1294 : * \returns The higher-dimensional Elem for which this Elem is a face.
1295 : *
1296 : * In some cases it is desirable to extract the boundary (or a subset thereof)
1297 : * of a D-dimensional mesh as a (D-1)-dimensional manifold. In this case
1298 : * we may want to know the 'parent' element from which the manifold elements
1299 : * were extracted. We can easily do that for the level-0 manifold elements
1300 : * by storing the D-dimensional parent. This method provides access to that
1301 : * element.
1302 : *
1303 : * This method returns nullptr if this->dim() == LIBMESH_DIM; in
1304 : * such cases no data storage for an interior parent pointer has
1305 : * been allocated.
1306 : */
1307 : const Elem * interior_parent () const;
1308 :
1309 : Elem * interior_parent ();
1310 :
1311 : /**
1312 : * Sets the pointer to the element's interior_parent.
1313 : * Dangerous! Only use this if you know what you are doing!
1314 : */
1315 : void set_interior_parent (Elem * p);
1316 :
1317 : /**
1318 : * \returns The distance between nodes n1 and n2.
1319 : *
1320 : * Useful for computing the lengths of the sides of elements.
1321 : */
1322 : Real length (const unsigned int n1,
1323 : const unsigned int n2) const;
1324 :
1325 : /**
1326 : * \returns The number of adjacent vertices that uniquely define the
1327 : * location of the \f$ n^{th} \f$ second-order node, or 0 for linear
1328 : * elements.
1329 : *
1330 : * This method is useful when converting linear elements to quadratic
1331 : * elements.
1332 : *
1333 : * \note \p n has to be greater than or equal to \p this->n_vertices().
1334 : */
1335 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const;
1336 :
1337 : /**
1338 : * \returns The element-local number of the \f$ v^{th} \f$ vertex
1339 : * that defines the \f$ n^{th} \f$ second-order node, or 0 for
1340 : * linear elements.
1341 : *
1342 : * \note The value is always less than \p this->n_vertices(), while
1343 : * \p n has to be greater than or equal to \p this->n_vertices().
1344 : */
1345 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n,
1346 : const unsigned int v) const;
1347 :
1348 : /**
1349 : * \returns A pair (c,v), where
1350 : * c == child index, and
1351 : * v == element-local index of the \p \f$ n^{th} \f$
1352 : * second-order node on the parent element.
1353 : * For linear elements, (0,0) is returned.
1354 : *
1355 : * \note The return values are always less than \p this->n_children()
1356 : * and \p this->child_ptr(c)->n_vertices().
1357 : *
1358 : * \note \p n has to be greater than or equal to \p this->n_vertices().
1359 : *
1360 : * \note On refined second-order elements, the return value will
1361 : * satisfy \p this->node_ptr(n) == this->child_ptr(c)->node_ptr(v).
1362 : */
1363 : virtual std::pair<unsigned short int, unsigned short int>
1364 : second_order_child_vertex (const unsigned int n) const;
1365 :
1366 : /**
1367 : * \returns The ElemType of the associated second-order element
1368 : * (which will be the same as the input if the input is already a
1369 : * second-order ElemType) or INVALID_ELEM for elements that cannot be
1370 : * converted into higher order equivalents.
1371 : *
1372 : * For example, when \p this is a \p TET4, then \p TET10 is returned.
1373 : *
1374 : * For some elements, there exist two second-order equivalents, e.g.
1375 : * for \p Quad4 there is \p Quad8 and \p Quad9. When the optional
1376 : * \p full_ordered is \p true, then \p QUAD9 is returned. When
1377 : * \p full_ordered is \p false, then \p QUAD8 is returned.
1378 : */
1379 : static ElemType second_order_equivalent_type (const ElemType et,
1380 : const bool full_ordered=true);
1381 :
1382 : /**
1383 : * \returns The element type of the associated first-order element,
1384 : * or \p INVALID_ELEM for first-order or other elements that cannot be
1385 : * converted into lower order equivalents.
1386 : *
1387 : * For example, when \p this is a \p TET10, then \p TET4 is returned.
1388 : */
1389 : static ElemType first_order_equivalent_type (const ElemType et);
1390 :
1391 : /**
1392 : * \returns The ElemType of the associated "complete" order element
1393 : * (which will be the same as the input if the input is already a
1394 : * complete-order ElemType), or INVALID_ELEM for elements that cannot be
1395 : * converted into complete-order equivalents.
1396 : *
1397 : * The "complete" version of an element is an element which can
1398 : * represent the same geometry but which has nodes available to
1399 : * restore degrees of freedom on any vertex, edge, or face.
1400 : *
1401 : * For example, when \p this is a \p TET4, then \p TET14 is returned.
1402 : */
1403 : static ElemType complete_order_equivalent_type (const ElemType et);
1404 :
1405 : /**
1406 : * \returns The refinement level of the current element.
1407 : *
1408 : * If the element's parent is \p nullptr then by convention it is at
1409 : * level 0, otherwise it is simply at one level greater than its
1410 : * parent.
1411 : */
1412 : unsigned int level () const;
1413 :
1414 : /**
1415 : * \returns The value of the p refinement level of an active
1416 : * element, or the minimum value of the p refinement levels
1417 : * of an ancestor element's descendants.
1418 : */
1419 : unsigned int p_level () const;
1420 :
1421 : /**
1422 : * \returns \p true if the specified child is on the specified side.
1423 : */
1424 : virtual bool is_child_on_side(const unsigned int c,
1425 : const unsigned int s) const = 0;
1426 :
1427 : /**
1428 : * \returns The value of the mapping type for the element.
1429 : */
1430 : ElemMappingType mapping_type () const;
1431 :
1432 : /**
1433 : * Sets the value of the mapping type for the element.
1434 : */
1435 : void set_mapping_type (const ElemMappingType type);
1436 :
1437 : /**
1438 : * \returns The value of the mapping data for the element.
1439 : */
1440 : unsigned char mapping_data () const;
1441 :
1442 : /**
1443 : * Sets the value of the mapping data for the element.
1444 : */
1445 : void set_mapping_data (const unsigned char data);
1446 :
1447 :
1448 : #ifdef LIBMESH_ENABLE_AMR
1449 :
1450 : /**
1451 : * Enumeration of possible element refinement states.
1452 : */
1453 : enum RefinementState { COARSEN = 0,
1454 : DO_NOTHING,
1455 : REFINE,
1456 : JUST_REFINED,
1457 : JUST_COARSENED,
1458 : INACTIVE,
1459 : COARSEN_INACTIVE,
1460 : INVALID_REFINEMENTSTATE };
1461 :
1462 : /**
1463 : * \returns A constant pointer to the \f$ i^{th} \f$ child for this element.
1464 : * For internal use only - skips assertions about null pointers.
1465 : */
1466 : const Elem * raw_child_ptr (unsigned int i) const;
1467 :
1468 : /**
1469 : * \returns A constant pointer to the \f$ i^{th} \f$ child for this element.
1470 : * Do not call if this element has no children, i.e. is active.
1471 : */
1472 : const Elem * child_ptr (unsigned int i) const;
1473 :
1474 : /**
1475 : * \returns A non-constant pointer to the \f$ i^{th} \f$ child for this element.
1476 : * Do not call if this element has no children, i.e. is active.
1477 : */
1478 : Elem * child_ptr (unsigned int i);
1479 :
1480 : /**
1481 : * Nested classes for use iterating over all children of a parent
1482 : * element.
1483 : */
1484 : class ChildRefIter;
1485 : class ConstChildRefIter;
1486 :
1487 : /**
1488 : * Returns a range with all children of a parent element, usable in
1489 : * range-based for loops. The exact type of the return value here
1490 : * may be subject to change in future libMesh releases, but the
1491 : * iterators will always dereference to produce a reference to a
1492 : * child element.
1493 : */
1494 : SimpleRange<ChildRefIter> child_ref_range();
1495 :
1496 : SimpleRange<ConstChildRefIter> child_ref_range() const;
1497 :
1498 : private:
1499 : /**
1500 : * Sets the pointer to the \f$ i^{th} \f$ child for this element.
1501 : * Do not call if this element has no children, i.e. is active.
1502 : */
1503 : void set_child (unsigned int c, Elem * elem);
1504 :
1505 : public:
1506 : /**
1507 : * \returns The child index which \p e corresponds to.
1508 : *
1509 : * I.e. if c = a->which_child_am_i(e); then a->child_ptr(c) will be
1510 : * e.
1511 : */
1512 : unsigned int which_child_am_i(const Elem * e) const;
1513 :
1514 : /**
1515 : * \returns \p true if the specified child is on the specified edge.
1516 : */
1517 : virtual bool is_child_on_edge(const unsigned int c,
1518 : const unsigned int e) const;
1519 :
1520 : /**
1521 : * Adds a child pointer to the array of children of this element.
1522 : * If this is the first child to be added, this method allocates
1523 : * memory in the parent's _children array, otherwise, it just sets
1524 : * the pointer.
1525 : */
1526 : void add_child (Elem * elem);
1527 :
1528 : /**
1529 : * Adds a new child pointer to the specified index in the array of
1530 : * children of this element. If this is the first child to be added,
1531 : * this method allocates memory in the parent's _children array,
1532 : * otherwise, it just sets the pointer.
1533 : */
1534 : void add_child (Elem * elem, unsigned int c);
1535 :
1536 : /**
1537 : * Replaces the child pointer at the specified index in the child array.
1538 : */
1539 : void replace_child (Elem * elem, unsigned int c);
1540 :
1541 : /**
1542 : * Fills the vector \p family with the children of this element,
1543 : * recursively. Calling this method on a twice-refined element
1544 : * will give you the element itself, its direct children, and their
1545 : * children, etc... When the optional parameter \p reset is
1546 : * true, the vector will be cleared before the element and its
1547 : * descendants are added.
1548 : *
1549 : * The family tree only includes ancestor and active elements. To
1550 : * include subactive elements as well, use total_family_tree().
1551 : */
1552 : void family_tree (std::vector<const Elem *> & family,
1553 : bool reset = true) const;
1554 :
1555 : /**
1556 : * Non-const version of function above; fills a vector of non-const pointers.
1557 : */
1558 : void family_tree (std::vector<Elem *> & family,
1559 : bool reset = true);
1560 :
1561 : /**
1562 : * Same as the \p family_tree() member, but also adds any subactive
1563 : * descendants.
1564 : */
1565 : void total_family_tree (std::vector<const Elem *> & family,
1566 : bool reset = true) const;
1567 :
1568 : /**
1569 : * Non-const version of function above; fills a vector of non-const pointers.
1570 : */
1571 : void total_family_tree (std::vector<Elem *> & family,
1572 : bool reset = true);
1573 :
1574 : /**
1575 : * Same as the \p family_tree() member, but only adds the active
1576 : * children. Can be thought of as removing all the inactive
1577 : * elements from the vector created by \p family_tree, but is
1578 : * implemented more efficiently.
1579 : */
1580 : void active_family_tree (std::vector<const Elem *> & active_family,
1581 : bool reset = true) const;
1582 :
1583 : /**
1584 : * Non-const version of function above; fills a vector of non-const pointers.
1585 : */
1586 : void active_family_tree (std::vector<Elem *> & active_family,
1587 : bool reset = true);
1588 :
1589 : /**
1590 : * Same as the \p family_tree() member, but only adds elements
1591 : * which are next to \p side.
1592 : */
1593 : void family_tree_by_side (std::vector<const Elem *> & family,
1594 : unsigned int side,
1595 : bool reset = true) const;
1596 :
1597 : /**
1598 : * Non-const version of function above; fills a vector of non-const pointers.
1599 : */
1600 : void family_tree_by_side (std::vector<Elem *> & family,
1601 : unsigned int side,
1602 : bool reset = true);
1603 :
1604 : /**
1605 : * Same as the \p active_family_tree() member, but only adds elements
1606 : * which are next to \p side.
1607 : */
1608 : void active_family_tree_by_side (std::vector<const Elem *> & family,
1609 : unsigned int side,
1610 : bool reset = true) const;
1611 :
1612 : /**
1613 : * Non-const version of function above; fills a vector of non-const pointers.
1614 : */
1615 : void active_family_tree_by_side (std::vector<Elem *> & family,
1616 : unsigned int side,
1617 : bool reset = true);
1618 :
1619 : /**
1620 : * Same as the \p family_tree() member, but only adds elements
1621 : * which are next to \p neighbor.
1622 : */
1623 : void family_tree_by_neighbor (std::vector<const Elem *> & family,
1624 : const Elem * neighbor,
1625 : bool reset = true) const;
1626 :
1627 : /**
1628 : * Non-const version of function above; fills a vector of non-const pointers.
1629 : */
1630 : void family_tree_by_neighbor (std::vector<Elem *> & family,
1631 : Elem * neighbor,
1632 : bool reset = true);
1633 :
1634 : /**
1635 : * Same as the \p family_tree_by_neighbor() member, but also adds
1636 : * any subactive descendants.
1637 : */
1638 : void total_family_tree_by_neighbor (std::vector<const Elem *> & family,
1639 : const Elem * neighbor,
1640 : bool reset = true) const;
1641 :
1642 : /**
1643 : * Non-const version of function above; fills a vector of non-const pointers.
1644 : */
1645 : void total_family_tree_by_neighbor (std::vector<Elem *> & family,
1646 : Elem * neighbor,
1647 : bool reset = true);
1648 :
1649 : /**
1650 : * Same as the \p family_tree() member, but only adds elements
1651 : * which are next to \p subneighbor. Only applicable when
1652 : * \p this->has_neighbor(neighbor) and
1653 : * \p neighbor->is_ancestor(subneighbor)
1654 : */
1655 : void family_tree_by_subneighbor (std::vector<const Elem *> & family,
1656 : const Elem * neighbor,
1657 : const Elem * subneighbor,
1658 : bool reset = true) const;
1659 :
1660 : /**
1661 : * Non-const version of function above; fills a vector of non-const pointers.
1662 : */
1663 : void family_tree_by_subneighbor (std::vector<Elem *> & family,
1664 : Elem * neighbor,
1665 : Elem * subneighbor,
1666 : bool reset = true);
1667 :
1668 : /**
1669 : * Same as the \p family_tree_by_subneighbor() member, but also adds
1670 : * any subactive descendants.
1671 : */
1672 : void total_family_tree_by_subneighbor (std::vector<const Elem *> & family,
1673 : const Elem * neighbor,
1674 : const Elem * subneighbor,
1675 : bool reset = true) const;
1676 :
1677 : /**
1678 : * Non-const version of function above; fills a vector of non-const pointers.
1679 : */
1680 : void total_family_tree_by_subneighbor (std::vector<Elem *> & family,
1681 : Elem * neighbor,
1682 : Elem * subneighbor,
1683 : bool reset = true);
1684 :
1685 : /**
1686 : * Same as the \p active_family_tree() member, but only adds elements
1687 : * which are next to \p neighbor.
1688 : */
1689 : void active_family_tree_by_neighbor (std::vector<const Elem *> & family,
1690 : const Elem * neighbor,
1691 : bool reset = true) const;
1692 :
1693 : /**
1694 : * Non-const version of function above; fills a vector of non-const pointers.
1695 : */
1696 : void active_family_tree_by_neighbor (std::vector<Elem *> & family,
1697 : Elem * neighbor,
1698 : bool reset = true);
1699 :
1700 : /**
1701 : * Same as the \p active_family_tree_by_neighbor() member, but the
1702 : * \p neighbor here may be a topological (e.g. periodic boundary
1703 : * condition) neighbor, not just a local neighbor.
1704 : */
1705 : void active_family_tree_by_topological_neighbor (std::vector<const Elem *> & family,
1706 : const Elem * neighbor,
1707 : const MeshBase & mesh,
1708 : const PointLocatorBase & point_locator,
1709 : const PeriodicBoundaries * pb,
1710 : bool reset = true) const;
1711 :
1712 : /**
1713 : * Non-const version of function above; fills a vector of non-const pointers.
1714 : */
1715 : void active_family_tree_by_topological_neighbor (std::vector<Elem *> & family,
1716 : Elem * neighbor,
1717 : const MeshBase & mesh,
1718 : const PointLocatorBase & point_locator,
1719 : const PeriodicBoundaries * pb,
1720 : bool reset = true);
1721 :
1722 : /**
1723 : * \returns The value of the refinement flag for the element.
1724 : */
1725 : RefinementState refinement_flag () const;
1726 :
1727 : /**
1728 : * Sets the value of the refinement flag for the element.
1729 : */
1730 : void set_refinement_flag (const RefinementState rflag);
1731 :
1732 : /**
1733 : * \returns The value of the p-refinement flag for the element.
1734 : */
1735 : RefinementState p_refinement_flag () const;
1736 :
1737 : /**
1738 : * Sets the value of the p-refinement flag for the element.
1739 : */
1740 : void set_p_refinement_flag (const RefinementState pflag);
1741 :
1742 : /**
1743 : * \returns The maximum value of the p-refinement levels of
1744 : * an ancestor element's descendants.
1745 : */
1746 : unsigned int max_descendant_p_level () const;
1747 :
1748 : /**
1749 : * \returns The minimum p-refinement level of elements which are
1750 : * descended from this element, and which share a side with the
1751 : * active \p neighbor.
1752 : */
1753 : unsigned int min_p_level_by_neighbor (const Elem * neighbor,
1754 : unsigned int current_min) const;
1755 :
1756 : /**
1757 : * \returns The minimum new p-refinement level (i.e. after refinement
1758 : * and coarsening is done) of elements which are descended from this
1759 : * element and which share a side with the active \p neighbor.
1760 : */
1761 : unsigned int min_new_p_level_by_neighbor (const Elem * neighbor,
1762 : unsigned int current_min) const;
1763 :
1764 : /**
1765 : * Sets the value of the p-refinement level for the element.
1766 : *
1767 : * \note The maximum p-refinement level is currently 255.
1768 : */
1769 : void set_p_level (const unsigned int p);
1770 :
1771 : /**
1772 : * Sets the value of the p-refinement level for the element
1773 : * without altering the p-level of its ancestors
1774 : */
1775 : void hack_p_level (const unsigned int p);
1776 :
1777 : /**
1778 : * Sets the value of the p-refinement level for the element
1779 : * without altering the p-level of its ancestors; also sets the
1780 : * p_refinement_flag, simultaneously so that they can be safely
1781 : * checked for mutual consistency
1782 : */
1783 : void hack_p_level_and_refinement_flag (const unsigned int p,
1784 : RefinementState pflag);
1785 :
1786 : /**
1787 : * Refine the element.
1788 : */
1789 : virtual void refine (MeshRefinement & mesh_refinement);
1790 :
1791 : /**
1792 : * Coarsen the element. This function is non-virtual since it is the same
1793 : * for all element types.
1794 : */
1795 : void coarsen ();
1796 :
1797 : /**
1798 : * Contract an active element, i.e. remove pointers to any
1799 : * subactive children. This should only be called via
1800 : * MeshRefinement::contract, which will also remove subactive
1801 : * children from the mesh.
1802 : */
1803 : void contract ();
1804 :
1805 : #endif
1806 :
1807 : #ifndef NDEBUG
1808 : /**
1809 : * Checks for consistent neighbor links on this element.
1810 : */
1811 : void libmesh_assert_valid_neighbors() const;
1812 :
1813 : /**
1814 : * Checks for a valid id and pointers to nodes with valid ids on
1815 : * this element.
1816 : */
1817 : void libmesh_assert_valid_node_pointers() const;
1818 : #endif // !NDEBUG
1819 :
1820 : /**
1821 : * \returns The local node index of the given point IF said node
1822 : * has a singular Jacobian for this element. If the given point
1823 : * is not a node or is a node and does not have a singular Jacobian,
1824 : * this will return invalid_uint.
1825 : *
1826 : * The intention is for this to be overridden in derived element
1827 : * classes that do have nodes that have singular Jacobians. When
1828 : * mapping failures are caught, we can check this to see if the
1829 : * failed physical point is actually a singular point and
1830 : * return the correct master point.
1831 : */
1832 0 : virtual unsigned int local_singular_node(const Point & /* p */, const Real /* tol */ = TOLERANCE*TOLERANCE) const
1833 0 : { return invalid_uint; }
1834 :
1835 : /**
1836 : * \returns true iff the node at the given index has a singular
1837 : * mapping; i.e. is the degree-4 node on a Pyramid.
1838 : */
1839 0 : virtual bool is_singular_node(unsigned int /* node_i */) const { return false; }
1840 :
1841 : /**
1842 : * \returns The local index of the center node on the side \p side.
1843 : *
1844 : * A center node is a node that is located at the centroid of the given side.
1845 : * If the given side does not have a center node, this will return invalid_uint.
1846 : */
1847 : virtual unsigned int center_node_on_side(const unsigned short side) const;
1848 :
1849 : protected:
1850 :
1851 : /**
1852 : * The protected nested SideIter class is used to iterate over the
1853 : * sides of this Elem. It is a specially-designed class since
1854 : * no sides are actually stored by the element. This iterator-like
1855 : * class has to provide the following three operations
1856 : * 1) operator*
1857 : * 2) operator++
1858 : * 3) operator==
1859 : * The definition can be found at the end of this header file.
1860 : */
1861 : class SideIter;
1862 :
1863 : public:
1864 : /**
1865 : * Useful iterator typedefs
1866 : */
1867 : typedef Predicates::multi_predicate Predicate;
1868 :
1869 : /**
1870 : * Data structure for iterating over sides. Defined at the end of
1871 : * this header file.
1872 : */
1873 : struct side_iterator;
1874 :
1875 : /**
1876 : * Iterator accessor functions
1877 : */
1878 : side_iterator boundary_sides_begin();
1879 : side_iterator boundary_sides_end();
1880 :
1881 : private:
1882 : /**
1883 : * Side iterator helper functions. Used to replace the begin()
1884 : * and end() functions of the STL containers.
1885 : */
1886 : SideIter _first_side();
1887 : SideIter _last_side();
1888 :
1889 : public:
1890 :
1891 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1892 :
1893 : /**
1894 : * \returns \p true if the element is an infinite element,
1895 : * \p false otherwise.
1896 : */
1897 : virtual bool infinite () const = 0;
1898 :
1899 : /**
1900 : * \returns \p true if the specified (local) node number is a
1901 : * "mid-edge" node on an infinite element edge.
1902 : *
1903 : * This is false for all nodes on non-infinite elements, so we won't
1904 : * make it pure virtual, to simplify their code.
1905 : */
1906 0 : virtual bool is_mid_infinite_edge_node(const unsigned int /* n */) const
1907 0 : { libmesh_assert (!this->infinite()); return false; }
1908 :
1909 : /**
1910 : * \returns The origin for an infinite element.
1911 : *
1912 : * Currently, all infinite elements used in a mesh share the same
1913 : * origin. Override this in infinite element classes.
1914 : */
1915 0 : virtual Point origin () const { libmesh_not_implemented(); return Point(); }
1916 :
1917 : #else
1918 :
1919 : static constexpr bool infinite () { return false; }
1920 :
1921 : #endif
1922 :
1923 : /**
1924 : * \returns An Elem of type \p type wrapped in a smart pointer.
1925 : */
1926 : static std::unique_ptr<Elem> build (const ElemType type,
1927 : Elem * p=nullptr);
1928 :
1929 : /**
1930 : * Calls the build() method above with a nullptr parent, and
1931 : * additionally sets the newly-created Elem's id. This can be useful
1932 : * when adding pre-numbered Elems to a Mesh via add_elem() calls.
1933 : */
1934 : static std::unique_ptr<Elem> build_with_id (const ElemType type,
1935 : dof_id_type id);
1936 :
1937 : /**
1938 : * \returns An Elem of the same type as \p this, wrapped in a smart
1939 : * pointer.
1940 : *
1941 : * This is not a complete clone() method (since e.g. it does not set
1942 : * node pointers; the standard use case reassigns node pointers from
1943 : * a different mesh), but it is necessary to use this instead of
1944 : * build() for runtime-polymorphic elements like Polygon subtypes
1945 : * whose "type" depends on more than their type(), and it is useful
1946 : * to use this for elements whose id, unique_id, extra integers,
1947 : * etc. should be preserved in the near-clone.
1948 : */
1949 : virtual std::unique_ptr<Elem> disconnected_clone () const;
1950 :
1951 : /**
1952 : * Returns the number of independent permutations of element nodes -
1953 : * e.g. a cube can be reoriented to put side 0 where side N is (for
1954 : * 0 <= N < 6) and then rotated in one of four ways, giving 24
1955 : * possible permutations.
1956 : *
1957 : * Permutations which change the mapping Jacobian of an element
1958 : * (i.e. flipping the element) are not allowed in this definition.
1959 : */
1960 : virtual unsigned int n_permutations() const = 0;
1961 :
1962 : /**
1963 : * Permutes the element (by swapping node and neighbor pointers)
1964 : * according to the specified index.
1965 : *
1966 : * This is useful for regression testing, by making it easy to make
1967 : * a structured mesh behave more like an arbitrarily unstructured
1968 : * mesh.
1969 : *
1970 : * This is so far *only* used for regression testing, so we do
1971 : * not currently provide a way to permute any boundary side/edge ids
1972 : * along with the element permutation.
1973 : */
1974 : virtual void permute(unsigned int perm_num) = 0;
1975 :
1976 : /**
1977 : * Flips the element (by swapping node and neighbor pointers) to
1978 : * have a mapping Jacobian of opposite sign.
1979 : *
1980 : * This is useful for automatically fixing up elements that have
1981 : * been newly created (e.g. from extrusions) with a negative
1982 : * Jacobian.
1983 : *
1984 : * If \p boundary_info is not null, swap boundary side/edge ids
1985 : * consistently.
1986 : */
1987 : virtual void flip(BoundaryInfo * boundary_info) = 0;
1988 :
1989 : /**
1990 : * \returns Whether the element is flipped compared to standard
1991 : * libMesh (e.g. clockwise for 2D elements) node orientations.
1992 : *
1993 : * Always returns \p false if a 2D element is not in the XY plane or
1994 : * a 1D element is not on the X axis; user code designed to work for
1995 : * embedded manifolds should handle any consistent orientation, and
1996 : * determining whether an orientation is consistent is not a local
1997 : * operation.
1998 : */
1999 : virtual bool is_flipped() const = 0;
2000 :
2001 : /**
2002 : * Flips the element (by swapping node and neighbor pointers) to
2003 : * have a mapping Jacobian of opposite sign, iff we find a negative
2004 : * orientation. This only fixes flipped elements; for tangled
2005 : * elements the only fixes possible are non-local.
2006 : */
2007 : void orient(BoundaryInfo * boundary_info);
2008 :
2009 : #ifdef LIBMESH_ENABLE_AMR
2010 :
2011 : /**
2012 : * \returns The local node id on the parent which corresponds to node
2013 : * \p n of child \p c, or \p invalid_uint if no such parent
2014 : * node exists.
2015 : */
2016 : virtual unsigned int as_parent_node (unsigned int c,
2017 : unsigned int n) const;
2018 :
2019 : /**
2020 : * \returns All the pairs of nodes (indexed by local node id) which
2021 : * should bracket node \p n of child \p c.
2022 : */
2023 : virtual
2024 : const std::vector<std::pair<unsigned char, unsigned char>> &
2025 : parent_bracketing_nodes(unsigned int c,
2026 : unsigned int n) const;
2027 :
2028 : /**
2029 : * \returns All the pairs of nodes (indexed by global node id) which
2030 : * should bracket node \p n of child \p c.
2031 : */
2032 : virtual
2033 : const std::vector<std::pair<dof_id_type, dof_id_type>>
2034 : bracketing_nodes(unsigned int c,
2035 : unsigned int n) const;
2036 :
2037 :
2038 : /**
2039 : * \returns The embedding matrix entry for the requested child.
2040 : */
2041 : virtual Real embedding_matrix (const unsigned int child_num,
2042 : const unsigned int child_node_num,
2043 : const unsigned int parent_node_num) const = 0;
2044 :
2045 : /**
2046 : * \returns A "version number" that identifies which embedding
2047 : * matrix is in use.
2048 : *
2049 : * Some element types may use a different embedding matrix depending
2050 : * on their geometric characteristics.
2051 : */
2052 0 : virtual unsigned int embedding_matrix_version () const { return 0; }
2053 :
2054 : #endif // LIBMESH_ENABLE_AMR
2055 :
2056 :
2057 : protected:
2058 :
2059 : /**
2060 : * Default tolerance to use in has_affine_map().
2061 : */
2062 : static constexpr Real affine_tol = TOLERANCE*TOLERANCE;
2063 :
2064 : /**
2065 : * \returns A hash key computed from a single node id.
2066 : */
2067 : static dof_id_type compute_key (dof_id_type n0);
2068 :
2069 : /**
2070 : * \returns A hash key computed from two node ids.
2071 : */
2072 : static dof_id_type compute_key (dof_id_type n0,
2073 : dof_id_type n1);
2074 :
2075 : /**
2076 : * \returns A hash key computed from three node ids.
2077 : */
2078 : static dof_id_type compute_key (dof_id_type n0,
2079 : dof_id_type n1,
2080 : dof_id_type n2);
2081 :
2082 : /**
2083 : * \returns A hash key computed from four node ids.
2084 : */
2085 : static dof_id_type compute_key (dof_id_type n0,
2086 : dof_id_type n1,
2087 : dof_id_type n2,
2088 : dof_id_type n3);
2089 :
2090 : /**
2091 : * Swaps two node_ptrs
2092 : */
2093 28794629 : void swap2nodes(unsigned int n1, unsigned int n2)
2094 : {
2095 4334448 : Node * temp = this->node_ptr(n1);
2096 30961853 : this->set_node(n1, this->node_ptr(n2));
2097 28794629 : this->set_node(n2, temp);
2098 28794629 : }
2099 :
2100 : /**
2101 : * Swaps two neighbor_ptrs
2102 : */
2103 6786404 : void swap2neighbors(unsigned int n1, unsigned int n2)
2104 : {
2105 793040 : Elem * temp = this->neighbor_ptr(n1);
2106 548184 : this->set_neighbor(n1, this->neighbor_ptr(n2));
2107 548184 : this->set_neighbor(n2, temp);
2108 6861068 : }
2109 :
2110 : /**
2111 : * Swaps two sides in \p boundary_info, if it is non-null.
2112 : */
2113 : void swap2boundarysides(unsigned short s1, unsigned short s2,
2114 : BoundaryInfo * boundary_info) const;
2115 :
2116 : /**
2117 : * Swaps two edges in \p boundary_info, if it is non-null.
2118 : */
2119 : void swap2boundaryedges(unsigned short e1, unsigned short e2,
2120 : BoundaryInfo * boundary_info) const;
2121 :
2122 : /**
2123 : * Swaps three node_ptrs, "rotating" them.
2124 : */
2125 11312324 : void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
2126 : {
2127 12189036 : swap2nodes(n1, n2);
2128 12189036 : swap2nodes(n2, n3);
2129 11312324 : }
2130 :
2131 : /**
2132 : * Swaps three neighbor_ptrs, "rotating" them.
2133 : */
2134 3071806 : void swap3neighbors(unsigned int n1, unsigned int n2,
2135 : unsigned int n3)
2136 : {
2137 3071806 : swap2neighbors(n1, n2);
2138 3071806 : swap2neighbors(n2, n3);
2139 3071806 : }
2140 :
2141 : /**
2142 : * Swaps four node_ptrs, "rotating" them.
2143 : */
2144 3278918 : void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3,
2145 : unsigned int n4)
2146 : {
2147 2952118 : swap3nodes(n1, n2, n3);
2148 3278918 : swap2nodes(n3, n4);
2149 3278918 : }
2150 :
2151 : /**
2152 : * Swaps four neighbor_ptrs, "rotating" them.
2153 : */
2154 618012 : void swap4neighbors(unsigned int n1, unsigned int n2,
2155 : unsigned int n3, unsigned int n4)
2156 : {
2157 618012 : swap3neighbors(n1, n2, n3);
2158 618012 : swap2neighbors(n3, n4);
2159 618012 : }
2160 :
2161 :
2162 : /**
2163 : * An implementation for simple (all sides equal) elements
2164 : */
2165 : template <typename Sideclass, typename Subclass>
2166 : std::unique_ptr<Elem>
2167 : simple_build_side_ptr(const unsigned int i);
2168 :
2169 : /**
2170 : * An implementation for simple (all sides equal) elements
2171 : */
2172 : template <typename Subclass>
2173 : void simple_build_side_ptr(std::unique_ptr<Elem> & side,
2174 : const unsigned int i,
2175 : ElemType sidetype);
2176 :
2177 : /**
2178 : * An implementation for simple (all sides equal) elements
2179 : */
2180 : template <typename Subclass, typename Mapclass>
2181 : void simple_side_ptr(std::unique_ptr<Elem> & side,
2182 : const unsigned int i,
2183 : ElemType sidetype);
2184 :
2185 : /**
2186 : * An implementation for simple (all edges equal) elements
2187 : */
2188 : template <typename Edgeclass, typename Subclass>
2189 : std::unique_ptr<Elem>
2190 : simple_build_edge_ptr(const unsigned int i);
2191 :
2192 : /**
2193 : * An implementation for simple (all edges equal) elements
2194 : */
2195 : template <typename Subclass>
2196 : void simple_build_edge_ptr(std::unique_ptr<Elem> & edge,
2197 : const unsigned int i,
2198 : ElemType edgetype);
2199 :
2200 :
2201 : #ifdef LIBMESH_ENABLE_AMR
2202 :
2203 : /**
2204 : * Elem subclasses which don't do their own bracketing node
2205 : * calculations will need to supply a static cache, since the
2206 : * default calculation is slow.
2207 : */
2208 : virtual
2209 : std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> &
2210 0 : _get_bracketing_node_cache() const
2211 : {
2212 0 : static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c;
2213 0 : libmesh_error();
2214 : return c;
2215 : }
2216 :
2217 : /**
2218 : * Elem subclasses which don't do their own child-to-parent node
2219 : * calculations will need to supply a static cache, since the
2220 : * default calculation is slow.
2221 : */
2222 : virtual
2223 : std::vector<std::vector<std::vector<signed char>>> &
2224 0 : _get_parent_indices_cache() const
2225 : {
2226 0 : static std::vector<std::vector<std::vector<signed char>>> c;
2227 0 : libmesh_error();
2228 : return c;
2229 : }
2230 :
2231 : #endif // LIBMESH_ENABLE_AMR
2232 :
2233 : public:
2234 :
2235 : /**
2236 : * Replaces this element with \p nullptr for all of its neighbors.
2237 : * This is useful when deleting an element.
2238 : */
2239 : void nullify_neighbors ();
2240 :
2241 : protected:
2242 :
2243 : /**
2244 : * Pointers to the nodes we are connected to.
2245 : */
2246 : Node ** _nodes;
2247 :
2248 : /**
2249 : * Pointers to this element's parent and neighbors, and for
2250 : * lower-dimensional elements' interior_parent.
2251 : */
2252 : Elem ** _elemlinks;
2253 :
2254 : #ifdef LIBMESH_ENABLE_AMR
2255 : /**
2256 : * unique_ptr to array of this element's children.
2257 : *
2258 : * A Mesh ultimately owns the child Elems so we are not responsible
2259 : * for deleting them, but we are responsible for cleaning up the
2260 : * array allocated to hold those Elems, hence the unique_ptr.
2261 : */
2262 : std::unique_ptr<Elem *[]> _children;
2263 : #endif
2264 :
2265 : /**
2266 : * The subdomain to which this element belongs.
2267 : */
2268 : subdomain_id_type _sbd_id;
2269 :
2270 : #ifdef LIBMESH_ENABLE_AMR
2271 : /**
2272 : * h refinement flag. This is stored as an unsigned char
2273 : * to save space.
2274 : */
2275 : unsigned char _rflag;
2276 :
2277 : /**
2278 : * p refinement flag. This is stored as an unsigned char
2279 : * to save space.
2280 : */
2281 : unsigned char _pflag;
2282 :
2283 : /**
2284 : * p refinement level - the difference between the
2285 : * polynomial degree on this element and the minimum
2286 : * polynomial degree on the mesh.
2287 : * This is stored as an unsigned char to save space.
2288 : * In theory, these last four bytes might have
2289 : * been padding anyway.
2290 : */
2291 : unsigned char _p_level;
2292 : #endif
2293 :
2294 : /**
2295 : * Mapping function type; currently either 0 (LAGRANGE) or 1
2296 : * (RATIONAL_BERNSTEIN).
2297 : */
2298 : unsigned char _map_type;
2299 :
2300 : /**
2301 : * Mapping function data; currently used when needed to store the
2302 : * RATIONAL_BERNSTEIN nodal weight data index.
2303 : */
2304 : unsigned char _map_data;
2305 : };
2306 :
2307 :
2308 :
2309 : // ------------------------------------------------------------
2310 : // Elem helper classes
2311 : //
2312 : class
2313 : Elem::NodeRefIter : public PointerToPointerIter<Node>
2314 : {
2315 : public:
2316 22574772 : NodeRefIter (Node * const * nodepp) : PointerToPointerIter<Node>(nodepp) {}
2317 : };
2318 :
2319 :
2320 : class
2321 : Elem::ConstNodeRefIter : public PointerToPointerIter<const Node>
2322 : {
2323 : public:
2324 17714884 : ConstNodeRefIter (const Node * const * nodepp) : PointerToPointerIter<const Node>(nodepp) {}
2325 : };
2326 :
2327 :
2328 : #ifdef LIBMESH_ENABLE_AMR
2329 : class
2330 : Elem::ChildRefIter : public PointerToPointerIter<Elem>
2331 : {
2332 : public:
2333 6438188 : ChildRefIter (Elem * const * childpp) : PointerToPointerIter<Elem>(childpp) {}
2334 : };
2335 :
2336 :
2337 : class
2338 : Elem::ConstChildRefIter : public PointerToPointerIter<const Elem>
2339 : {
2340 : public:
2341 2483402 : ConstChildRefIter (const Elem * const * childpp) : PointerToPointerIter<const Elem>(childpp) {}
2342 : };
2343 :
2344 :
2345 :
2346 : inline
2347 57317709 : SimpleRange<Elem::ChildRefIter> Elem::child_ref_range()
2348 : {
2349 3219094 : libmesh_assert(_children);
2350 59998302 : return {_children.get(), _children.get() + this->n_children()};
2351 : }
2352 :
2353 :
2354 : inline
2355 6674014 : SimpleRange<Elem::ConstChildRefIter> Elem::child_ref_range() const
2356 : {
2357 1241701 : libmesh_assert(_children);
2358 6901327 : return {_children.get(), _children.get() + this->n_children()};
2359 : }
2360 : #endif // LIBMESH_ENABLE_AMR
2361 :
2362 :
2363 :
2364 :
2365 : // ------------------------------------------------------------
2366 : // global Elem functions
2367 :
2368 : inline
2369 0 : std::ostream & operator << (std::ostream & os, const Elem & e)
2370 : {
2371 0 : e.print_info(os);
2372 0 : return os;
2373 : }
2374 :
2375 :
2376 : // ------------------------------------------------------------
2377 : // Elem class member functions
2378 : inline
2379 1131190180 : Elem::Elem(const unsigned int nn,
2380 : const unsigned int ns,
2381 : Elem * p,
2382 : Elem ** elemlinkdata,
2383 1131190180 : Node ** nodelinkdata) :
2384 658405231 : _nodes(nodelinkdata),
2385 658405231 : _elemlinks(elemlinkdata),
2386 658405231 : _sbd_id(0),
2387 : #ifdef LIBMESH_ENABLE_AMR
2388 658405231 : _rflag(Elem::DO_NOTHING),
2389 658405231 : _pflag(Elem::DO_NOTHING),
2390 658405231 : _p_level(0),
2391 : #endif
2392 658987127 : _map_type(p ? p->mapping_type() : 0),
2393 1159992844 : _map_data(p ? p->mapping_data() : 0)
2394 : {
2395 1131190180 : this->processor_id() = DofObject::invalid_processor_id;
2396 :
2397 : // If this ever legitimately fails we need to increase max_n_nodes
2398 57049286 : libmesh_assert_less_equal(nn, max_n_nodes);
2399 :
2400 : // We currently only support refinement of elements into child
2401 : // elements of the same type. We can't test elem->type() here,
2402 : // because that's virtual and we're still in the base class
2403 : // constructor, but we can at least usually verify constency with
2404 : // the arguments we were handed.
2405 : #ifndef NDEBUG
2406 57049286 : if (p && !p->runtime_topology())
2407 : {
2408 287216 : libmesh_assert_equal_to(nn, p->n_nodes());
2409 287216 : libmesh_assert_equal_to(ns, p->n_sides());
2410 : }
2411 : #endif
2412 :
2413 : // Initialize the nodes data structure if we're given a pointer to
2414 : // memory for it.
2415 1131190180 : if (_nodes)
2416 : {
2417 5364309004 : for (unsigned int n=0; n<nn; n++)
2418 4233169372 : _nodes[n] = nullptr;
2419 : }
2420 :
2421 : // Initialize the neighbors/parent data structure
2422 : // _elemlinks = new Elem *[ns+1];
2423 :
2424 : // Initialize the elements data structure if we're given a pointer
2425 : // to memory for it. If we *weren't* given memory for it, e.g.
2426 : // because a subclass like an arbitrary Polygon needs to
2427 : // heap-allocate this memory, then that subclass will have to handle
2428 : // this initialization too.
2429 1131190180 : if (_elemlinks)
2430 : {
2431 1131156011 : _elemlinks[0] = p;
2432 :
2433 5171684899 : for (unsigned int n=1; n<ns+1; n++)
2434 4040528888 : _elemlinks[n] = nullptr;
2435 :
2436 : // Optionally initialize data from the parent
2437 1131156011 : if (this->parent())
2438 : {
2439 28802664 : this->subdomain_id() = this->parent()->subdomain_id();
2440 28802664 : this->processor_id() = this->parent()->processor_id();
2441 28802664 : _map_type = this->parent()->_map_type;
2442 28802664 : _map_data = this->parent()->_map_data;
2443 :
2444 : #ifdef LIBMESH_ENABLE_AMR
2445 29097344 : this->set_p_level(this->parent()->p_level());
2446 : #endif
2447 : }
2448 : }
2449 1131190180 : }
2450 :
2451 :
2452 :
2453 : inline
2454 3417344247 : const Point & Elem::point (const unsigned int i) const
2455 : {
2456 3417344247 : libmesh_assert_less (i, this->n_nodes());
2457 3417344247 : libmesh_assert(_nodes[i]);
2458 3417344247 : libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2459 :
2460 47418220167 : return *_nodes[i];
2461 : }
2462 :
2463 :
2464 :
2465 : inline
2466 2660718 : Point & Elem::point (const unsigned int i)
2467 : {
2468 2660718 : libmesh_assert_less (i, this->n_nodes());
2469 :
2470 167012332 : return *_nodes[i];
2471 : }
2472 :
2473 :
2474 :
2475 : inline
2476 87769918 : dof_id_type Elem::node_id (const unsigned int i) const
2477 : {
2478 87769918 : libmesh_assert_less (i, this->n_nodes());
2479 87769918 : libmesh_assert(_nodes[i]);
2480 87769918 : libmesh_assert_not_equal_to (_nodes[i]->id(), Node::invalid_id);
2481 :
2482 963960779 : return _nodes[i]->id();
2483 : }
2484 :
2485 :
2486 :
2487 : inline
2488 389436 : unsigned int Elem::local_node (const dof_id_type i) const
2489 : {
2490 2231246 : for (auto n : make_range(this->n_nodes()))
2491 2231246 : if (this->node_id(n) == i)
2492 11288 : return n;
2493 :
2494 0 : return libMesh::invalid_uint;
2495 : }
2496 :
2497 :
2498 :
2499 : inline
2500 25126435 : const Node * const * Elem::get_nodes () const
2501 : {
2502 136259560 : return _nodes;
2503 : }
2504 :
2505 :
2506 :
2507 : inline
2508 113359836 : const Node * Elem::node_ptr (const unsigned int i) const
2509 : {
2510 113359836 : libmesh_assert_less (i, this->n_nodes());
2511 113359836 : libmesh_assert(_nodes[i]);
2512 :
2513 24236047111 : return _nodes[i];
2514 : }
2515 :
2516 :
2517 :
2518 : inline
2519 206792091 : Node * Elem::node_ptr (const unsigned int i)
2520 : {
2521 206792091 : libmesh_assert_less (i, this->n_nodes());
2522 206792091 : libmesh_assert(_nodes[i]);
2523 :
2524 4714854114 : return _nodes[i];
2525 : }
2526 :
2527 :
2528 :
2529 : inline
2530 19108583 : const Node & Elem::node_ref (const unsigned int i) const
2531 : {
2532 175166337 : return *this->node_ptr(i);
2533 : }
2534 :
2535 :
2536 :
2537 : inline
2538 26066836 : Node & Elem::node_ref (const unsigned int i)
2539 : {
2540 54569066 : return *this->node_ptr(i);
2541 : }
2542 :
2543 :
2544 :
2545 : inline
2546 1391230 : unsigned int Elem::get_node_index (const Node * node_ptr) const
2547 : {
2548 6604229 : for (auto n : make_range(this->n_nodes()))
2549 6592053 : if (this->_nodes[n] == node_ptr)
2550 160652 : return n;
2551 :
2552 0 : return libMesh::invalid_uint;
2553 : }
2554 :
2555 :
2556 :
2557 : #ifdef LIBMESH_ENABLE_DEPRECATED
2558 : inline
2559 0 : Node * & Elem::set_node (const unsigned int i)
2560 : {
2561 0 : libmesh_assert_less (i, this->n_nodes());
2562 :
2563 : libmesh_deprecated();
2564 :
2565 0 : return _nodes[i];
2566 : }
2567 : #endif // LIBMESH_ENABLE_DEPRECATED
2568 :
2569 :
2570 :
2571 : inline
2572 6243093449 : void Elem::set_node (const unsigned int i,
2573 : Node * node)
2574 : {
2575 177702 : libmesh_assert_less (i, this->n_nodes());
2576 :
2577 6531282964 : _nodes[i] = node;
2578 5879175749 : }
2579 :
2580 :
2581 :
2582 : inline
2583 57629745 : subdomain_id_type Elem::subdomain_id () const
2584 : {
2585 537438279 : return _sbd_id;
2586 : }
2587 :
2588 :
2589 :
2590 : inline
2591 42933741 : subdomain_id_type & Elem::subdomain_id ()
2592 : {
2593 124519495 : return _sbd_id;
2594 : }
2595 :
2596 :
2597 :
2598 : inline
2599 98445286 : const Elem * Elem::neighbor_ptr (unsigned int i) const
2600 : {
2601 98445286 : libmesh_assert_less (i, this->n_neighbors());
2602 :
2603 466337265 : return _elemlinks[i+1];
2604 : }
2605 :
2606 :
2607 :
2608 : inline
2609 18203085 : Elem * Elem::neighbor_ptr (unsigned int i)
2610 : {
2611 18203085 : libmesh_assert_less (i, this->n_neighbors());
2612 :
2613 1221729666 : return _elemlinks[i+1];
2614 : }
2615 :
2616 :
2617 :
2618 : inline
2619 9747402 : void Elem::set_neighbor (const unsigned int i, Elem * n)
2620 : {
2621 9747402 : libmesh_assert_less (i, this->n_neighbors());
2622 :
2623 405829111 : _elemlinks[i+1] = n;
2624 508316874 : }
2625 :
2626 :
2627 :
2628 : inline
2629 91038748 : bool Elem::has_neighbor (const Elem * elem) const
2630 : {
2631 272327265 : for (auto n : this->neighbor_ptr_range())
2632 261608880 : if (n == elem)
2633 80622954 : return true;
2634 :
2635 10415794 : return false;
2636 : }
2637 :
2638 :
2639 :
2640 : inline
2641 : Elem * Elem::child_neighbor (Elem * elem)
2642 : {
2643 : for (auto n : elem->neighbor_ptr_range())
2644 : if (n && n->parent() == this)
2645 : return n;
2646 :
2647 : return nullptr;
2648 : }
2649 :
2650 :
2651 :
2652 : inline
2653 : const Elem * Elem::child_neighbor (const Elem * elem) const
2654 : {
2655 : for (auto n : elem->neighbor_ptr_range())
2656 : if (n && n->parent() == this)
2657 : return n;
2658 :
2659 : return nullptr;
2660 : }
2661 :
2662 :
2663 :
2664 : inline
2665 : SimpleRange<Elem::NodeRefIter>
2666 192349791 : Elem::node_ref_range()
2667 : {
2668 201846111 : return {_nodes, _nodes+this->n_nodes()};
2669 : }
2670 :
2671 :
2672 :
2673 : inline
2674 : SimpleRange<Elem::ConstNodeRefIter>
2675 261965644 : Elem::node_ref_range() const
2676 : {
2677 279190948 : return {_nodes, _nodes+this->n_nodes()};
2678 : }
2679 :
2680 :
2681 :
2682 : inline
2683 : IntRange<unsigned short>
2684 60956214 : Elem::node_index_range() const
2685 : {
2686 1416652035 : return {0, cast_int<unsigned short>(this->n_nodes())};
2687 : }
2688 :
2689 :
2690 :
2691 : inline
2692 : IntRange<unsigned short>
2693 410686 : Elem::edge_index_range() const
2694 : {
2695 41948321 : return {0, cast_int<unsigned short>(this->n_edges())};
2696 : }
2697 :
2698 :
2699 :
2700 : inline
2701 : IntRange<unsigned short>
2702 308674 : Elem::face_index_range() const
2703 : {
2704 3655737 : return {0, cast_int<unsigned short>(this->n_faces())};
2705 : }
2706 :
2707 :
2708 :
2709 : inline
2710 : IntRange<unsigned short>
2711 8891420 : Elem::side_index_range() const
2712 : {
2713 357118678 : return {0, cast_int<unsigned short>(this->n_sides())};
2714 : }
2715 :
2716 :
2717 :
2718 :
2719 : inline
2720 826716870 : std::unique_ptr<const Elem> Elem::side_ptr (unsigned int i) const
2721 : {
2722 : // Call the non-const version of this function, return the result as
2723 : // a std::unique_ptr<const Elem>.
2724 75970818 : Elem * me = const_cast<Elem *>(this);
2725 902687688 : return me->side_ptr(i);
2726 : }
2727 :
2728 :
2729 :
2730 : inline
2731 : void
2732 15336 : Elem::side_ptr (std::unique_ptr<const Elem> & elem,
2733 : const unsigned int i) const
2734 : {
2735 : // Hand off to the non-const version of this function
2736 432 : Elem * me = const_cast<Elem *>(this);
2737 864 : std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2738 15336 : me->side_ptr(e, i);
2739 14904 : elem = std::move(e);
2740 15336 : }
2741 :
2742 :
2743 :
2744 : inline
2745 : std::unique_ptr<const Elem>
2746 105821058 : Elem::build_side_ptr (const unsigned int i) const
2747 : {
2748 : // Call the non-const version of this function, return the result as
2749 : // a std::unique_ptr<const Elem>.
2750 2828143 : Elem * me = const_cast<Elem *>(this);
2751 115963143 : return me->build_side_ptr(i);
2752 : }
2753 :
2754 :
2755 :
2756 : inline
2757 : void
2758 38372840 : Elem::build_side_ptr (std::unique_ptr<const Elem> & elem,
2759 : const unsigned int i) const
2760 : {
2761 : // Hand off to the non-const version of this function
2762 827622 : Elem * me = const_cast<Elem *>(this);
2763 1655244 : std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2764 38372840 : me->build_side_ptr(e, i);
2765 36722717 : elem = std::move(e);
2766 38372840 : }
2767 :
2768 :
2769 :
2770 : template <typename Sideclass, typename Subclass>
2771 : inline
2772 : std::unique_ptr<Elem>
2773 155744521 : Elem::simple_build_side_ptr (const unsigned int i)
2774 : {
2775 33123512 : libmesh_assert_less (i, this->n_sides());
2776 :
2777 155744521 : std::unique_ptr<Elem> face = std::make_unique<Sideclass>();
2778 1200576683 : for (auto n : face->node_index_range())
2779 1044832162 : face->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2780 :
2781 155744521 : face->set_interior_parent(this);
2782 144764371 : face->inherit_data_from(*this);
2783 :
2784 155744521 : return face;
2785 0 : }
2786 :
2787 :
2788 :
2789 : template <typename Subclass>
2790 : inline
2791 : void
2792 38036412 : Elem::simple_build_side_ptr (std::unique_ptr<Elem> & side,
2793 : const unsigned int i,
2794 : ElemType sidetype)
2795 : {
2796 1661135 : libmesh_assert_less (i, this->n_sides());
2797 :
2798 38036412 : if (!side.get() || side->type() != sidetype)
2799 : {
2800 147167 : Subclass & real_me = cast_ref<Subclass&>(*this);
2801 1449387 : side = real_me.Subclass::build_side_ptr(i);
2802 : }
2803 : else
2804 : {
2805 37238135 : side->set_interior_parent(this);
2806 35724193 : side->inherit_data_from(*this);
2807 264877869 : for (auto n : side->node_index_range())
2808 227639734 : side->set_node(n, this->node_ptr(Subclass::side_nodes_map[i][n]));
2809 : }
2810 38036412 : }
2811 :
2812 :
2813 :
2814 : template <typename Subclass, typename Mapclass>
2815 : inline
2816 : void
2817 237281959 : Elem::simple_side_ptr (std::unique_ptr<Elem> & side,
2818 : const unsigned int i,
2819 : ElemType sidetype)
2820 : {
2821 4767702 : libmesh_assert_less (i, this->n_sides());
2822 :
2823 237281959 : if (!side.get() || side->type() != sidetype)
2824 : {
2825 16146 : Subclass & real_me = cast_ref<Subclass&>(*this);
2826 1167560 : side = real_me.Subclass::side_ptr(i);
2827 : }
2828 : else
2829 : {
2830 241399238 : side->subdomain_id() = this->subdomain_id();
2831 :
2832 805999108 : for (auto n : side->node_index_range())
2833 569309002 : side->set_node(n, this->node_ptr(Mapclass::side_nodes_map[i][n]));
2834 : }
2835 237281959 : }
2836 :
2837 :
2838 :
2839 : inline
2840 : std::unique_ptr<const Elem>
2841 46700058 : Elem::build_edge_ptr (const unsigned int i) const
2842 : {
2843 : // Call the non-const version of this function, return the result as
2844 : // a std::unique_ptr<const Elem>.
2845 27213958 : Elem * me = const_cast<Elem *>(this);
2846 48809099 : return me->build_edge_ptr(i);
2847 : }
2848 :
2849 :
2850 :
2851 : inline
2852 : void
2853 99164 : Elem::build_edge_ptr (std::unique_ptr<const Elem> & elem,
2854 : const unsigned int i) const
2855 : {
2856 : // Hand off to the non-const version of this function
2857 3020 : Elem * me = const_cast<Elem *>(this);
2858 6040 : std::unique_ptr<Elem> e {const_cast<Elem *>(elem.release())};
2859 99164 : me->build_edge_ptr(e, i);
2860 96144 : elem = std::move(e);
2861 99164 : }
2862 :
2863 :
2864 : template <typename Edgeclass, typename Subclass>
2865 : inline
2866 : std::unique_ptr<Elem>
2867 27878431 : Elem::simple_build_edge_ptr (const unsigned int i)
2868 : {
2869 9812036 : libmesh_assert_less (i, this->n_edges());
2870 :
2871 27878431 : std::unique_ptr<Elem> edge = std::make_unique<Edgeclass>();
2872 :
2873 97685766 : for (auto n : edge->node_index_range())
2874 69807335 : edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2875 :
2876 27878431 : edge->set_interior_parent(this);
2877 26092187 : edge->inherit_data_from(*this);
2878 :
2879 27878431 : return edge;
2880 0 : }
2881 :
2882 :
2883 :
2884 :
2885 : template <typename Subclass>
2886 : inline
2887 : void
2888 137744 : Elem::simple_build_edge_ptr (std::unique_ptr<Elem> & edge,
2889 : const unsigned int i,
2890 : ElemType edgetype)
2891 : {
2892 4196 : libmesh_assert_less (i, this->n_edges());
2893 :
2894 137744 : if (!edge.get() || edge->type() != edgetype)
2895 : {
2896 25 : Subclass & real_me = cast_ref<Subclass&>(*this);
2897 655 : edge = real_me.Subclass::build_edge_ptr(i);
2898 : }
2899 : else
2900 : {
2901 133233 : edge->inherit_data_from(*this);
2902 414504 : for (auto n : edge->node_index_range())
2903 277100 : edge->set_node(n, this->node_ptr(Subclass::edge_nodes_map[i][n]));
2904 : }
2905 137744 : }
2906 :
2907 :
2908 :
2909 : inline
2910 39 : bool Elem::on_boundary () const
2911 : {
2912 : // By convention, the element is on the boundary
2913 : // if it has a nullptr neighbor.
2914 351 : return this->has_neighbor(nullptr);
2915 : }
2916 :
2917 :
2918 :
2919 : inline
2920 155937529 : unsigned int Elem::which_neighbor_am_i (const Elem * e) const
2921 : {
2922 8215859 : libmesh_assert(e);
2923 :
2924 8215859 : const Elem * eparent = e;
2925 :
2926 156728798 : while (eparent->level() > this->level())
2927 : {
2928 263008 : eparent = eparent->parent();
2929 260932 : libmesh_assert(eparent);
2930 : }
2931 :
2932 408462423 : for (auto s : make_range(this->n_sides()))
2933 408454976 : if (this->neighbor_ptr(s) == eparent)
2934 8215859 : return s;
2935 :
2936 0 : return libMesh::invalid_uint;
2937 : }
2938 :
2939 :
2940 :
2941 : inline
2942 180566792 : bool Elem::active() const
2943 : {
2944 : #ifdef LIBMESH_ENABLE_AMR
2945 3767669601 : if ((this->refinement_flag() == INACTIVE) ||
2946 126871899 : (this->refinement_flag() == COARSEN_INACTIVE))
2947 53803579 : return false;
2948 : else
2949 126763213 : return true;
2950 : #else
2951 : return true;
2952 : #endif
2953 : }
2954 :
2955 :
2956 :
2957 :
2958 :
2959 : inline
2960 417348777 : bool Elem::subactive() const
2961 : {
2962 : #ifdef LIBMESH_ENABLE_AMR
2963 46094557 : if (this->active())
2964 34008324 : return false;
2965 12086233 : if (!this->has_children())
2966 3662996 : return true;
2967 85394252 : for (const Elem * my_ancestor = this->parent();
2968 297532306 : my_ancestor != nullptr;
2969 28660802 : my_ancestor = my_ancestor->parent())
2970 24849659 : if (my_ancestor->active())
2971 10516 : return true;
2972 : #endif
2973 :
2974 8412721 : return false;
2975 : }
2976 :
2977 :
2978 :
2979 : inline
2980 46256945 : bool Elem::has_children() const
2981 : {
2982 : #ifdef LIBMESH_ENABLE_AMR
2983 358504506 : if (!_children)
2984 9120630 : return false;
2985 : else
2986 37136315 : return true;
2987 : #else
2988 : return false;
2989 : #endif
2990 : }
2991 :
2992 :
2993 : inline
2994 : bool Elem::has_ancestor_children() const
2995 : {
2996 : #ifdef LIBMESH_ENABLE_AMR
2997 : if (!_children)
2998 : return false;
2999 : else
3000 : for (auto & c : child_ref_range())
3001 : if (c.has_children())
3002 : return true;
3003 : #endif
3004 : return false;
3005 : }
3006 :
3007 :
3008 :
3009 : inline
3010 0 : bool Elem::is_ancestor_of(const Elem *
3011 : #ifdef LIBMESH_ENABLE_AMR
3012 : descendant
3013 : #endif
3014 : ) const
3015 : {
3016 : #ifdef LIBMESH_ENABLE_AMR
3017 0 : const Elem * e = descendant;
3018 10626 : while (e)
3019 : {
3020 8638 : if (this == e)
3021 0 : return true;
3022 0 : e = e->parent();
3023 : }
3024 : #endif
3025 0 : return false;
3026 : }
3027 :
3028 :
3029 :
3030 : inline
3031 1176035968 : const Elem * Elem::parent () const
3032 : {
3033 2544758274 : return _elemlinks[0];
3034 : }
3035 :
3036 :
3037 :
3038 : inline
3039 98479315 : Elem * Elem::parent ()
3040 : {
3041 1584391471 : return _elemlinks[0];
3042 : }
3043 :
3044 :
3045 :
3046 : inline
3047 343128 : void Elem::set_parent (Elem * p)
3048 : {
3049 : // We no longer support using parent() as interior_parent()
3050 343128 : libmesh_assert_equal_to(this->dim(), p ? p->dim() : this->dim());
3051 10061939 : _elemlinks[0] = p;
3052 526127 : }
3053 :
3054 :
3055 :
3056 : inline
3057 824236 : const Elem * Elem::top_parent () const
3058 : {
3059 824236 : const Elem * tp = this;
3060 :
3061 : // Keep getting the element's parent
3062 : // until that parent is at level-0
3063 4369350 : while (tp->parent() != nullptr)
3064 2044366 : tp = tp->parent();
3065 :
3066 824236 : libmesh_assert(tp);
3067 824236 : libmesh_assert_equal_to (tp->level(), 0);
3068 :
3069 824236 : return tp;
3070 : }
3071 :
3072 :
3073 :
3074 : inline
3075 7216477221 : unsigned int Elem::level() const
3076 : {
3077 : #ifdef LIBMESH_ENABLE_AMR
3078 :
3079 : // if I don't have a parent I was
3080 : // created directly from file
3081 : // or by the user, so I am a
3082 : // level-0 element
3083 19958571660 : if (this->parent() == nullptr)
3084 112104820 : return 0;
3085 :
3086 : // if the parent and this element are of different
3087 : // dimensionality we are at the same level as
3088 : // the parent (e.g. we are the 2D side of a
3089 : // 3D element)
3090 13041127800 : if (this->dim() != this->parent()->dim())
3091 0 : return this->parent()->level();
3092 :
3093 : // otherwise we are at a level one
3094 : // higher than our parent
3095 13164305101 : return (this->parent()->level() + 1);
3096 :
3097 : #else
3098 :
3099 : // Without AMR all elements are
3100 : // at level 0.
3101 : return 0;
3102 :
3103 : #endif
3104 : }
3105 :
3106 :
3107 :
3108 : inline
3109 2172887828 : unsigned int Elem::p_level() const
3110 : {
3111 : #ifdef LIBMESH_ENABLE_AMR
3112 53875568890 : return _p_level;
3113 : #else
3114 : return 0;
3115 : #endif
3116 : }
3117 :
3118 :
3119 :
3120 : inline
3121 100873668 : ElemMappingType Elem::mapping_type () const
3122 : {
3123 1262009916 : return static_cast<ElemMappingType>(_map_type);
3124 : }
3125 :
3126 :
3127 :
3128 : inline
3129 46753046 : void Elem::set_mapping_type(const ElemMappingType type)
3130 : {
3131 301180095 : _map_type = cast_int<unsigned char>(type);
3132 46753046 : }
3133 :
3134 :
3135 :
3136 : inline
3137 33329613 : unsigned char Elem::mapping_data () const
3138 : {
3139 138124358 : return _map_data;
3140 : }
3141 :
3142 :
3143 :
3144 : inline
3145 46753039 : void Elem::set_mapping_data(const unsigned char data)
3146 : {
3147 300917321 : _map_data = data;
3148 47016146 : }
3149 :
3150 :
3151 :
3152 : #ifdef LIBMESH_ENABLE_AMR
3153 :
3154 : inline
3155 0 : const Elem * Elem::raw_child_ptr (unsigned int i) const
3156 : {
3157 4240 : if (!_children)
3158 0 : return nullptr;
3159 :
3160 2880 : return _children[i];
3161 : }
3162 :
3163 : inline
3164 90033306 : const Elem * Elem::child_ptr (unsigned int i) const
3165 : {
3166 90033306 : libmesh_assert(_children);
3167 90033306 : libmesh_assert(_children[i]);
3168 :
3169 341159027 : return _children[i];
3170 : }
3171 :
3172 : inline
3173 2095948 : Elem * Elem::child_ptr (unsigned int i)
3174 : {
3175 2095948 : libmesh_assert(_children);
3176 2095948 : libmesh_assert(_children[i]);
3177 :
3178 23606410 : return _children[i];
3179 : }
3180 :
3181 :
3182 : inline
3183 133432 : void Elem::set_child (unsigned int c, Elem * elem)
3184 : {
3185 133432 : libmesh_assert (this->has_children());
3186 :
3187 52216963 : _children[c] = elem;
3188 27078729 : }
3189 :
3190 :
3191 :
3192 : inline
3193 109570340 : unsigned int Elem::which_child_am_i (const Elem * e) const
3194 : {
3195 27331162 : libmesh_assert(e);
3196 27331162 : libmesh_assert (this->has_children());
3197 :
3198 109570340 : unsigned int nc = this->n_children();
3199 292063316 : for (unsigned int c=0; c != nc; c++)
3200 292063316 : if (this->child_ptr(c) == e)
3201 27331162 : return c;
3202 :
3203 0 : libmesh_error_msg("ERROR: which_child_am_i() was called with a non-child!");
3204 :
3205 : return libMesh::invalid_uint;
3206 : }
3207 :
3208 :
3209 :
3210 : inline
3211 352199386 : Elem::RefinementState Elem::refinement_flag () const
3212 : {
3213 4609573408 : return static_cast<RefinementState>(_rflag);
3214 : }
3215 :
3216 :
3217 :
3218 : inline
3219 3563322 : void Elem::set_refinement_flag(RefinementState rflag)
3220 : {
3221 60242820 : _rflag = cast_int<unsigned char>(rflag);
3222 11435648 : }
3223 :
3224 :
3225 :
3226 : inline
3227 86958387 : Elem::RefinementState Elem::p_refinement_flag () const
3228 : {
3229 234319298 : return static_cast<RefinementState>(_pflag);
3230 : }
3231 :
3232 :
3233 :
3234 : inline
3235 2521627 : void Elem::set_p_refinement_flag(RefinementState pflag)
3236 : {
3237 2521276 : if (this->p_level() == 0)
3238 2516000 : libmesh_assert_not_equal_to
3239 : (pflag, Elem::JUST_REFINED);
3240 :
3241 40627059 : _pflag = cast_int<unsigned char>(pflag);
3242 25185094 : }
3243 :
3244 :
3245 :
3246 : inline
3247 0 : unsigned int Elem::max_descendant_p_level () const
3248 : {
3249 : // This is undefined for subactive elements,
3250 : // which have no active descendants
3251 0 : libmesh_assert (!this->subactive());
3252 0 : if (this->active())
3253 0 : return this->p_level();
3254 :
3255 0 : unsigned int max_p_level = _p_level;
3256 0 : for (auto & c : child_ref_range())
3257 0 : max_p_level = std::max(max_p_level,
3258 0 : c.max_descendant_p_level());
3259 0 : return max_p_level;
3260 : }
3261 :
3262 :
3263 :
3264 : inline
3265 46719071 : void Elem::hack_p_level(unsigned int p)
3266 : {
3267 46719071 : if (p == 0)
3268 46634888 : libmesh_assert_not_equal_to
3269 : (this->p_refinement_flag(), Elem::JUST_REFINED);
3270 :
3271 356146910 : _p_level = cast_int<unsigned char>(p);
3272 295465517 : }
3273 :
3274 :
3275 : inline
3276 3602 : void Elem::hack_p_level_and_refinement_flag (unsigned int p,
3277 : RefinementState pflag)
3278 : {
3279 34521331 : _pflag = cast_int<unsigned char>(pflag);
3280 3602 : this->hack_p_level(p);
3281 34502504 : }
3282 :
3283 : #endif // ifdef LIBMESH_ENABLE_AMR
3284 :
3285 :
3286 : inline
3287 290889 : void Elem::orient(BoundaryInfo * boundary_info)
3288 : {
3289 304149 : if (this->is_flipped())
3290 138978 : this->flip(boundary_info);
3291 290889 : }
3292 :
3293 :
3294 : inline
3295 43722 : dof_id_type Elem::compute_key (dof_id_type n0)
3296 : {
3297 43722 : return n0;
3298 : }
3299 :
3300 :
3301 :
3302 : inline
3303 6482039 : dof_id_type Elem::compute_key (dof_id_type n0,
3304 : dof_id_type n1)
3305 : {
3306 : // Order the two so that n0 < n1
3307 177637273 : if (n0 > n1) std::swap (n0, n1);
3308 :
3309 177637273 : return Utility::hashword2(n0, n1);
3310 : }
3311 :
3312 :
3313 :
3314 : inline
3315 49201960 : dof_id_type Elem::compute_key (dof_id_type n0,
3316 : dof_id_type n1,
3317 : dof_id_type n2)
3318 : {
3319 49201960 : std::array<dof_id_type, 3> array = {{n0, n1, n2}};
3320 1770648 : std::sort(array.begin(), array.end());
3321 50972608 : return Utility::hashword(array);
3322 : }
3323 :
3324 :
3325 :
3326 : inline
3327 35740113 : dof_id_type Elem::compute_key (dof_id_type n0,
3328 : dof_id_type n1,
3329 : dof_id_type n2,
3330 : dof_id_type n3)
3331 : {
3332 35740113 : std::array<dof_id_type, 4> array = {{n0, n1, n2, n3}};
3333 1072446 : std::sort(array.begin(), array.end());
3334 36812559 : return Utility::hashword(array);
3335 : }
3336 :
3337 :
3338 :
3339 : inline
3340 227285043 : void Elem::inherit_data_from (const Elem & src)
3341 : {
3342 60777992 : this->set_mapping_type(src.mapping_type());
3343 60777992 : this->set_mapping_data(src.mapping_data());
3344 242581615 : this->subdomain_id() = src.subdomain_id();
3345 60777992 : this->processor_id(src.processor_id());
3346 : #ifdef LIBMESH_ENABLE_AMR
3347 242581615 : this->set_p_level(src.p_level());
3348 : #endif
3349 227285043 : }
3350 :
3351 :
3352 :
3353 : /**
3354 : * The definition of the protected nested SideIter class.
3355 : */
3356 0 : class Elem::SideIter
3357 : {
3358 : public:
3359 : // Constructor with arguments.
3360 0 : SideIter(const unsigned int side_number,
3361 : Elem * parent)
3362 0 : : _side(),
3363 0 : _side_ptr(nullptr),
3364 0 : _parent(parent),
3365 0 : _side_number(side_number)
3366 0 : {}
3367 :
3368 :
3369 : // Empty constructor.
3370 : SideIter()
3371 : : _side(),
3372 : _side_ptr(nullptr),
3373 : _parent(nullptr),
3374 : _side_number(libMesh::invalid_uint)
3375 : {}
3376 :
3377 :
3378 : // Copy constructor
3379 0 : SideIter(const SideIter & other)
3380 0 : : _side(),
3381 0 : _side_ptr(nullptr),
3382 0 : _parent(other._parent),
3383 0 : _side_number(other._side_number)
3384 0 : {}
3385 :
3386 :
3387 : // op=
3388 : SideIter & operator=(const SideIter & other)
3389 : {
3390 : this->_parent = other._parent;
3391 : this->_side_number = other._side_number;
3392 : return *this;
3393 : }
3394 :
3395 : // unary op*
3396 0 : Elem *& operator*() const
3397 : {
3398 : // Set the std::unique_ptr
3399 0 : this->_update_side_ptr();
3400 :
3401 : // Return a reference to _side_ptr
3402 0 : return this->_side_ptr;
3403 : }
3404 :
3405 : // op++
3406 0 : SideIter & operator++()
3407 : {
3408 0 : ++_side_number;
3409 0 : return *this;
3410 : }
3411 :
3412 : // op== Two side iterators are equal if they have
3413 : // the same side number and the same parent element.
3414 0 : bool operator == (const SideIter & other) const
3415 : {
3416 0 : return (this->_side_number == other._side_number &&
3417 0 : this->_parent == other._parent);
3418 : }
3419 :
3420 :
3421 : // Consults the parent Elem to determine if the side
3422 : // is a boundary side. Note: currently side N is a
3423 : // boundary side if neighbor N is nullptr. Be careful,
3424 : // this could possibly change in the future?
3425 0 : bool side_on_boundary() const
3426 : {
3427 0 : return this->_parent->neighbor_ptr(_side_number) == nullptr;
3428 : }
3429 :
3430 : private:
3431 : // Update the _side pointer by building the correct side.
3432 : // This has to be called before dereferencing.
3433 0 : void _update_side_ptr() const
3434 : {
3435 : // Construct new side, store in std::unique_ptr
3436 0 : this->_side = this->_parent->build_side_ptr(this->_side_number);
3437 :
3438 : // Also set our internal naked pointer. Memory is still owned
3439 : // by the std::unique_ptr.
3440 0 : this->_side_ptr = _side.get();
3441 0 : }
3442 :
3443 : // std::unique_ptr to the actual side, handles memory management for
3444 : // the sides which are created during the course of iteration.
3445 : mutable std::unique_ptr<Elem> _side;
3446 :
3447 : // Raw pointer needed to facilitate passing back to the user a
3448 : // reference to a non-temporary raw pointer in order to conform to
3449 : // the variant_filter_iterator interface. It points to the same
3450 : // thing the std::unique_ptr "_side" above holds. What happens if the user
3451 : // calls delete on the pointer passed back? Well, this is an issue
3452 : // which is not addressed by the iterators in libMesh. Basically it
3453 : // is a bad idea to ever call delete on an iterator from the library.
3454 : mutable Elem * _side_ptr;
3455 :
3456 : // Pointer to the parent Elem class which generated this iterator
3457 : Elem * _parent;
3458 :
3459 : // A counter variable which keeps track of the side number
3460 : unsigned int _side_number;
3461 : };
3462 :
3463 :
3464 :
3465 :
3466 :
3467 :
3468 : // Private implementation functions in the Elem class for the side iterators.
3469 : // They have to come after the definition of the SideIter class.
3470 : inline
3471 0 : Elem::SideIter Elem::_first_side()
3472 : {
3473 0 : return SideIter(0, this);
3474 : }
3475 :
3476 :
3477 :
3478 : inline
3479 0 : Elem::SideIter Elem::_last_side()
3480 : {
3481 0 : return SideIter(this->n_neighbors(), this);
3482 : }
3483 :
3484 :
3485 :
3486 :
3487 : /**
3488 : * The definition of the struct used for iterating over sides.
3489 : */
3490 : struct
3491 : Elem::side_iterator : variant_filter_iterator<Elem::Predicate, Elem *>
3492 : {
3493 : // Templated forwarding ctor -- forwards to appropriate variant_filter_iterator ctor
3494 : template <typename PredType, typename IterType>
3495 0 : side_iterator (const IterType & d,
3496 : const IterType & e,
3497 : const PredType & p ) :
3498 0 : variant_filter_iterator<Elem::Predicate, Elem *>(d,e,p) {}
3499 : };
3500 :
3501 :
3502 :
3503 : inline
3504 77825289 : SimpleRange<Elem::NeighborPtrIter> Elem::neighbor_ptr_range()
3505 : {
3506 80898132 : return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3507 : }
3508 :
3509 :
3510 : inline
3511 386729296 : SimpleRange<Elem::ConstNeighborPtrIter> Elem::neighbor_ptr_range() const
3512 : {
3513 388149190 : return {_elemlinks+1, _elemlinks + 1 + this->n_neighbors()};
3514 : }
3515 :
3516 : } // namespace libMesh
3517 :
3518 :
3519 : // Helper function for default caches in Elem subclasses
3520 :
3521 : #define LIBMESH_ENABLE_TOPOLOGY_CACHES \
3522 : virtual \
3523 : std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> & \
3524 : _get_bracketing_node_cache() const override \
3525 : { \
3526 : static std::vector<std::vector<std::vector<std::vector<std::pair<unsigned char, unsigned char>>>>> c; \
3527 : return c; \
3528 : } \
3529 : \
3530 : virtual \
3531 : std::vector<std::vector<std::vector<signed char>>> & \
3532 : _get_parent_indices_cache() const override \
3533 : { \
3534 : static std::vector<std::vector<std::vector<signed char>>> c; \
3535 : return c; \
3536 : }
3537 :
3538 :
3539 :
3540 :
3541 :
3542 :
3543 : #endif // LIBMESH_ELEM_H
|