@@ -237,13 +237,25 @@ class Elem : public ReferenceCountedObject<Elem>,
237
237
*/
238
238
static const subdomain_id_type invalid_subdomain_id;
239
239
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
+
240
248
/* *
241
249
* \returns A pointer to the "reference element" associated
242
250
* with this element. The reference element is the image of this
243
251
* element in reference parametric space. Importantly, it is *not*
244
252
* an actual element in the mesh, but rather a Singleton-type
245
253
* object, so for example all \p Quad4 elements share the same
246
254
* \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.
247
259
*/
248
260
const Elem * reference_elem () const ;
249
261
@@ -608,6 +620,10 @@ class Elem : public ReferenceCountedObject<Elem>,
608
620
/* *
609
621
* This array maps the integer representation of the \p ElemType enum
610
622
* 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.
611
627
*/
612
628
static const unsigned int type_to_n_nodes_map[INVALID_ELEM];
613
629
@@ -639,6 +655,10 @@ class Elem : public ReferenceCountedObject<Elem>,
639
655
/* *
640
656
* This array maps the integer representation of the \p ElemType enum
641
657
* 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.
642
662
*/
643
663
static const unsigned int type_to_n_sides_map[INVALID_ELEM];
644
664
@@ -693,6 +713,10 @@ class Elem : public ReferenceCountedObject<Elem>,
693
713
/* *
694
714
* This array maps the integer representation of the \p ElemType enum
695
715
* 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.
696
720
*/
697
721
static const unsigned int type_to_n_edges_map[INVALID_ELEM];
698
722
@@ -1057,8 +1081,8 @@ class Elem : public ReferenceCountedObject<Elem>,
1057
1081
{ libmesh_not_implemented (); return std::make_pair (0 .,0 .); }
1058
1082
1059
1083
/* *
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.
1062
1086
*
1063
1087
* For linear elements, performs an initial tight bounding box check
1064
1088
* (as an optimization step) and (if that passes) then uses the
@@ -1844,14 +1868,12 @@ class Elem : public ReferenceCountedObject<Elem>,
1844
1868
1845
1869
#endif
1846
1870
1847
-
1848
-
1849
-
1850
1871
/* *
1851
1872
* \returns An Elem of type \p type wrapped in a smart pointer.
1852
1873
*/
1853
1874
static std::unique_ptr<Elem> build (const ElemType type,
1854
1875
Elem * p=nullptr );
1876
+
1855
1877
/* *
1856
1878
* Calls the build() method above with a nullptr parent, and
1857
1879
* additionally sets the newly-created Elem's id. This can be useful
@@ -1860,6 +1882,20 @@ class Elem : public ReferenceCountedObject<Elem>,
1860
1882
static std::unique_ptr<Elem> build_with_id (const ElemType type,
1861
1883
dof_id_type id);
1862
1884
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
+
1863
1899
/* *
1864
1900
* Returns the number of independent permutations of element nodes -
1865
1901
* 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,
2310
2346
// If this ever legitimately fails we need to increase max_n_nodes
2311
2347
libmesh_assert_less_equal (nn, max_n_nodes);
2312
2348
2313
- // Initialize the nodes data structure
2349
+ // Initialize the nodes data structure if we're given a pointer to
2350
+ // memory for it.
2314
2351
if (_nodes)
2315
2352
{
2316
2353
for (unsigned int n=0 ; n<nn; n++)
@@ -2320,27 +2357,31 @@ Elem::Elem(const unsigned int nn,
2320
2357
// Initialize the neighbors/parent data structure
2321
2358
// _elemlinks = new Elem *[ns+1];
2322
2359
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;
2327
2368
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 ;
2330
2371
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 ;
2339
2379
2340
2380
#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 ());
2343
2382
#endif
2383
+ }
2384
+ }
2344
2385
}
2345
2386
2346
2387
0 commit comments