Skip to content

Commit bf64b0b

Browse files
authored
Merge pull request #4074 from roystgnr/polygon_elements
(Arbitrary-) Polygon elements
2 parents 2734f85 + 8d05c27 commit bf64b0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2261
-175
lines changed

Makefile.in

+157-10
Large diffs are not rendered by default.

include/Makefile.in

+2
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,11 @@ include_HEADERS = \
744744
geom/elem_range.h \
745745
geom/elem_side_builder.h \
746746
geom/face.h \
747+
geom/face_c0polygon.h \
747748
geom/face_inf_quad.h \
748749
geom/face_inf_quad4.h \
749750
geom/face_inf_quad6.h \
751+
geom/face_polygon.h \
750752
geom/face_quad.h \
751753
geom/face_quad4.h \
752754
geom/face_quad4_shell.h \

include/enums/enum_elem_type.h

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ enum ElemType : int {
7979
PYRAMID18 = 37,
8080
// Another shell elem
8181
QUADSHELL9 = 38,
82+
// An arbitrary polygon with N EDGE2 sides
83+
C0POLYGON = 39,
8284
// Invalid
8385
INVALID_ELEM}; // should always be last
8486

include/fe/fe_abstract.h

+23-6
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,25 @@ class FEAbstract : public ReferenceCountedObject<FEAbstract>
488488
*/
489489
virtual unsigned int n_quadrature_points () const = 0;
490490

491+
/**
492+
* \returns The element that the current shape functions have been
493+
* calculated for. Useful in determining when shape functions must
494+
* be recomputed.
495+
*/
496+
const Elem * get_elem() const { return _elem; }
497+
491498
/**
492499
* \returns The element type that the current shape functions
493-
* have been calculated for. Useful in determining when shape
494-
* functions must be recomputed.
500+
* have been calculated for, or \p INVALID_ELEM if no such element
501+
* exists. Useful in determining when shape functions must be
502+
* recomputed.
503+
*
504+
* This is generally redundant with _elem->type(), but must be
505+
* cached separately for cases (such as internal FE use in
506+
* QComposite) where _elem might be a dangling pointer to a
507+
* temporary.
495508
*/
496-
ElemType get_type() const { return elem_type; }
509+
ElemType get_type() const { return _elem_type; }
497510

498511
/**
499512
* \returns The p refinement level that the current shape
@@ -717,10 +730,14 @@ class FEAbstract : public ReferenceCountedObject<FEAbstract>
717730
FEType fe_type;
718731

719732
/**
720-
* The element type the current data structures are
721-
* set up for.
733+
* The element type the current data structures were set up for.
734+
*/
735+
ElemType _elem_type;
736+
737+
/**
738+
* The element the current data structures were set up for.
722739
*/
723-
ElemType elem_type;
740+
const Elem * _elem;
724741

725742
/**
726743
* The element p-refinement level the current data structures are

include/geom/elem.h

+63-22
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,25 @@ class Elem : public ReferenceCountedObject<Elem>,
237237
*/
238238
static const subdomain_id_type invalid_subdomain_id;
239239

240+
/**
241+
* \returns true iff this element type can vary in topology (e.g.
242+
* have different numbers of sides and/or nodes) at runtime. For
243+
* such general polygons or polyhedra, APIs which assume a fixed
244+
* topology are not safe to use.
245+
*/
246+
virtual bool runtime_topology() const { return false; }
247+
240248
/**
241249
* \returns A pointer to the "reference element" associated
242250
* with this element. The reference element is the image of this
243251
* element in reference parametric space. Importantly, it is *not*
244252
* an actual element in the mesh, but rather a Singleton-type
245253
* object, so for example all \p Quad4 elements share the same
246254
* \p reference_elem().
255+
*
256+
* If the element is of a type that can admit multiple topologies,
257+
* such as a Polygon subtype, then there is no reference element;
258+
* for such types this method should not be used.
247259
*/
248260
const Elem * reference_elem () const;
249261

@@ -608,6 +620,10 @@ class Elem : public ReferenceCountedObject<Elem>,
608620
/**
609621
* This array maps the integer representation of the \p ElemType enum
610622
* to the number of nodes in the element.
623+
*
624+
* This is only usable for simple types for which the node number
625+
* is fixed; for more general types like Polygon subclasses an actual
626+
* instantiated Elem must be queried.
611627
*/
612628
static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
613629

@@ -639,6 +655,10 @@ class Elem : public ReferenceCountedObject<Elem>,
639655
/**
640656
* This array maps the integer representation of the \p ElemType enum
641657
* to the number of sides on the element.
658+
*
659+
* This is only usable for simple types for which the node number
660+
* is fixed; for more general types like Polygon subclasses an actual
661+
* instantiated Elem must be queried.
642662
*/
643663
static const unsigned int type_to_n_sides_map[INVALID_ELEM];
644664

@@ -693,6 +713,10 @@ class Elem : public ReferenceCountedObject<Elem>,
693713
/**
694714
* This array maps the integer representation of the \p ElemType enum
695715
* to the number of edges on the element.
716+
*
717+
* This is only usable for simple types for which the node number
718+
* is fixed; for more general types like Polygon subclasses an actual
719+
* instantiated Elem must be queried.
696720
*/
697721
static const unsigned int type_to_n_edges_map[INVALID_ELEM];
698722

@@ -1057,8 +1081,8 @@ class Elem : public ReferenceCountedObject<Elem>,
10571081
{ libmesh_not_implemented(); return std::make_pair(0.,0.); }
10581082

10591083
/**
1060-
* \returns \p true if the point p is contained in this element,
1061-
* false otherwise.
1084+
* \returns \p true if the physical point p is contained in this
1085+
* element, false otherwise.
10621086
*
10631087
* For linear elements, performs an initial tight bounding box check
10641088
* (as an optimization step) and (if that passes) then uses the
@@ -1844,14 +1868,12 @@ class Elem : public ReferenceCountedObject<Elem>,
18441868

18451869
#endif
18461870

1847-
1848-
1849-
18501871
/**
18511872
* \returns An Elem of type \p type wrapped in a smart pointer.
18521873
*/
18531874
static std::unique_ptr<Elem> build (const ElemType type,
18541875
Elem * p=nullptr);
1876+
18551877
/**
18561878
* Calls the build() method above with a nullptr parent, and
18571879
* additionally sets the newly-created Elem's id. This can be useful
@@ -1860,6 +1882,20 @@ class Elem : public ReferenceCountedObject<Elem>,
18601882
static std::unique_ptr<Elem> build_with_id (const ElemType type,
18611883
dof_id_type id);
18621884

1885+
/**
1886+
* \returns An Elem of the same type as \p this, wrapped in a smart
1887+
* pointer.
1888+
*
1889+
* This is not a complete clone() method (since e.g. it does not set
1890+
* node pointers; the standard use case reassigns node pointers from
1891+
* a different mesh), but it is necessary to use this instead of
1892+
* build() for runtime-polymorphic elements like Polygon subtypes
1893+
* whose "type" depends on more than their type(), and it is useful
1894+
* to use this for elements whose id, unique_id, extra integers,
1895+
* etc. should be preserved in the near-clone.
1896+
*/
1897+
virtual std::unique_ptr<Elem> disconnected_clone () const;
1898+
18631899
/**
18641900
* Returns the number of independent permutations of element nodes -
18651901
* e.g. a cube can be reoriented to put side 0 where side N is (for
@@ -2310,7 +2346,8 @@ Elem::Elem(const unsigned int nn,
23102346
// If this ever legitimately fails we need to increase max_n_nodes
23112347
libmesh_assert_less_equal(nn, max_n_nodes);
23122348

2313-
// Initialize the nodes data structure
2349+
// Initialize the nodes data structure if we're given a pointer to
2350+
// memory for it.
23142351
if (_nodes)
23152352
{
23162353
for (unsigned int n=0; n<nn; n++)
@@ -2320,27 +2357,31 @@ Elem::Elem(const unsigned int nn,
23202357
// Initialize the neighbors/parent data structure
23212358
// _elemlinks = new Elem *[ns+1];
23222359

2323-
// We now require that we get allocated data from a subclass
2324-
libmesh_assert (_elemlinks);
2325-
2326-
_elemlinks[0] = p;
2360+
// Initialize the elements data structure if we're given a pointer
2361+
// to memory for it. If we *weren't* given memory for it, e.g.
2362+
// because a subclass like an arbitrary Polygon needs to
2363+
// heap-allocate this memory, then that subclass will have to handle
2364+
// this initialization too.
2365+
if (_elemlinks)
2366+
{
2367+
_elemlinks[0] = p;
23272368

2328-
for (unsigned int n=1; n<ns+1; n++)
2329-
_elemlinks[n] = nullptr;
2369+
for (unsigned int n=1; n<ns+1; n++)
2370+
_elemlinks[n] = nullptr;
23302371

2331-
// Optionally initialize data from the parent
2332-
if (this->parent() != nullptr)
2333-
{
2334-
this->subdomain_id() = this->parent()->subdomain_id();
2335-
this->processor_id() = this->parent()->processor_id();
2336-
_map_type = this->parent()->_map_type;
2337-
_map_data = this->parent()->_map_data;
2338-
}
2372+
// Optionally initialize data from the parent
2373+
if (this->parent())
2374+
{
2375+
this->subdomain_id() = this->parent()->subdomain_id();
2376+
this->processor_id() = this->parent()->processor_id();
2377+
_map_type = this->parent()->_map_type;
2378+
_map_data = this->parent()->_map_data;
23392379

23402380
#ifdef LIBMESH_ENABLE_AMR
2341-
if (this->parent())
2342-
this->set_p_level(this->parent()->p_level());
2381+
this->set_p_level(this->parent()->p_level());
23432382
#endif
2383+
}
2384+
}
23442385
}
23452386

23462387

0 commit comments

Comments
 (0)