-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(Arbitrary-) Polygon elements #4074
base: devel
Are you sure you want to change the base?
Conversation
Job Coverage, step Generate coverage on 8d05c27 wanted to post the following: Coverage
Warnings
This comment will be updated on new commits. |
48c594b
to
cf92f3f
Compare
Rebasing to fix a |
Some subclasses like Polygon might have to do this for themselves, because they can't heap allocate until after initializing Elem.
Throwing in other method tests here while I'm at it, just to get a quick check before I try to instantiate a Polygon1 in our usual Elem tests
If we have a POLYGON1 or a future POLYHEDRON1 or anything else where the quadrature rule will need to depend on more than just a single element type, we'll need to initialize quadrature objects with the physical element.
Obviously we can't rely on static maps here in general anymore, since we're not going to have a different ElemType and map entry for every possible polyhedron. So, add some invalid_uint entries for the general types, and handle invalid_uint where we might run into it, and query the Elem itself instead of these maps whereever we can.
This lets us do a lot in Polygon that might otherwise have to be pushed down to subclasses, which will be good if we ever have any higher-order or internal-node-having subclasses.
I'll finish Lagrange+Polygon1 support soon, but this will be faster even then, and it'll get Polygon elem unit tests working earlier.
Not sure how I missed this earlier
Some of the tests here don't apply to a non-affine pentagon, or apply with different numbers to a distorted pentagon, or won't apply until we can do a Lagrange basis on a pentagon.
This should be useful in distinguishing Polygon/Polyhedron from more static types.
This should keep caching from breaking on polygon/polyhedra of mixed runtime topology
This should be more forwards compatible than hardcoding a POLYGON1 test.
Putting this in FEInterface was kind of an unintuitive decision in the first place, and now that we're adding runtime-dependent element topology like Polygons we're going to *need* a physical Elem to work with in those cases.
We make this one an equilateral pentagon because a non-skewed polygon won't give us an exact representation of linears for p>1 MONOMIAL
We can't build the old Side objects for Polygon1; the build code there relies on `side_nodes_map`.
This is a bit more descriptive of an important aspect (triangulated mapping), and we can still add terms to indicate higher order in later higher-order versions.
QComposite was hitting undefined behavior here, creating temporary subelements for an internal Lagrange FE, and then when that FE would reinit afterward it would test `get_elem_type()` and hit a dangling pointer.
cf92f3f
to
faed578
Compare
Shouldn't have left it in the header after seeing how big it needed to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main comment is that we should prefer libmesh_error_msg()
to libmesh_error()
even for unlikely errors, since it's just better documentation even when we don't hit the errors.
src/fe/fe_abstract.C
Outdated
if (Elem::type_to_n_nodes_map[itemType] == invalid_uint) | ||
libmesh_error(); | ||
|
||
nodes.resize(Elem::type_to_n_nodes_map[itemType]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems a little clunky to do the Elem::type_to_n_nodes_map[itemType]
lookup twice (once for the error check, once for the resize) and I think you could further improve this diff by using a libmesh_error_msg()
rather than giving no information if there's an error.
src/fe/fe_lagrange.C
Outdated
case C0POLYGON: | ||
// C0Polygon requires using newer FE APIs | ||
if (!e) | ||
libmesh_error(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer a libmesh_error_msg()
with some details here as well.
src/fe/fe_lagrange_shape_2D.C
Outdated
{ | ||
// C0Polygon requires using newer FE APIs | ||
if (!elem) | ||
libmesh_error(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libmesh_error_msg()
src/fe/fe_lagrange_shape_2D.C
Outdated
{ | ||
// C0Polygon requires using newer FE APIs | ||
if (!elem) | ||
libmesh_error(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libmesh_error_msg()
src/geom/elem.C
Outdated
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
invalid_uint, // unused | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because of the enumeration value you chose for C0POLYGON = 50
, yes? What is the reason for having the gap, exactly? It doesn't look like we've left gaps for other types of Elems in the past so my first instinct would have just been to keep the numbering sequential for the new type...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this is embarrassing... honestly, the gaps are there because I have another branch that was going to use them, for higher-order nodal (Lagrange + Rational-Bezier-Bernstein mappings) geometric element support. That branch is probably less than half finished and it's turned out to be less of a priority than I'd expected, though, so I'll reshuffle this now, and whenever I get back to that I'll move its numbers up when I hit the rebase conflicts.
|
||
const auto n_elem_ints = this->n_extra_integers(); | ||
returnval->add_extra_integers(n_elem_ints); | ||
for (unsigned int i = 0; i != n_elem_ints; ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be a make_range()
loop but not a big preference for me.
src/geom/face_c0polygon.C
Outdated
swap2nodes(s,ns-1-s); | ||
swap2neighbors(s,ns-2-s); | ||
swap2boundarysides(s,ns-2-s,boundary_info); | ||
swap2boundaryedges(s,ns-2-s,boundary_info); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need spaces after commas, at least that is how we usually format comma-separated parameter lists?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, but I'm not changing any of the 200ish spots in older files where I forgot the spaces. ;-)
case MIN_ANGLE: | ||
bounds.first = 90. - (180./this->n_sides()); | ||
bounds.second = 180. - (360./this->n_sides()); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that you added these bounds for completeness, but there is no Elem::quality()
implementation yet for Polygons
is there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no specialization, but the base class implementation actually works fine for polygons, and we now test with it in elem_test.C
- I had to add a special case for them because a squashed pentagon I construct for one instantiation has an angle that's even worse than our standard pyramids.
src/quadrature/quadrature.C
Outdated
// Some element types require data from a specific element, so can | ||
// only be used with newer APIs. | ||
if (t == C0POLYGON) | ||
libmesh_error(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libmesh_error_msg()
The base class `Elem::volume()` call caught bad quadrature weights even when something (cancellation?) prevented them from being caught by our FE tests.
This avoids a bunch of unused values in between, and the only point of it was to reduce conflicts with another feature branch that may be delayed a while regardless.
This ended up being a larger diff than I'd hoped for - we need to change a whole swath of Quadrature and FE APIs, to take an
Elem *
orElem &
instead of just anElemType
, if we want to be able to handle elements where a single type might have differing subelement decompositions and/or different values for things liken_dofs
from element to element.With just
Polygon
subclasses, it might been conceivable to just addPENTAGON
,HEXAGON
, etc. enumerated types until we reachedn_sides()
=17 or some such too-crazy-to-exceed value, but I'm hoping that the refactoring here also lets us handle an upcomingPolyhedron
class hierarchy.Since I'm deprecating a bunch of functions, I also uncommented the
libmesh_deprecated()
on a bunch of others while I was at it, and wrapped everything I could in#ifdef LIBMESH_ENABLE_DEPRECATED
to try and catch use cases at compile time.Some InfFE code was using FE/FEInterface calls that were deprecated by @lindsayad as part of his work on p-refinement flexibility, and I'm not sure if I updated them correctly for
p_level() > 0
cases. I don't think anybody has yet tried combining infinite elements with p refinement (@BalticPinguin?), but if somebody did and I just broke it then on the one hand I apologize but on the other I consider that acceptable punishment for not getting an example with feature coverage into CI.