-
Notifications
You must be signed in to change notification settings - Fork 295
Bounding box testing for $Entities in GmshIO #3903
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
Conversation
14cc0d3
to
3c6e824
Compare
Oh, better yet, it triggered test failures from consistent meshes and let me catch a bug in it. |
Right now we ignore the point locations and the curve/surface/volume bounding box extents in a GMSH $Entities section; this led to unexpected behavior in libMesh#3899 Let's insist that those locations and bounding boxes are accurate. False positives for these tests are an easy fix (edit the $Entities), whereas missed true positives lead to erroneous simulations.
3c6e824
to
95d841f
Compare
On the bright side, I'm getting more and more happy about our downstream coverage here. |
If the $Entities list says the box bottoms out at 0 but we see 1e-17, that's okay.
ad450bc
to
85637c7
Compare
85637c7
to
eaeedd3
Compare
Job Test MOOSE on eaeedd3 : invalidated by @roystgnr time_steppers/time_adaptive.test can''t possibly be affected by this PR... |
Okay, I'm not sure what's going on in the updated Mac environments, but this PR does not put a segfault in eigenproblems_ex4 and does not put compiler warnings in solid_mechanics/examples/umat_build.build We ought to be ready to merge. |
Real BoundingBox::max_size() const | ||
{ | ||
Real size = 0; | ||
for (unsigned int d = 0; d != LIBMESH_DIM; ++d) |
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.
In the future, after #3895 goes in, we could use make_range
with libmesh_dim
here
src/geom/bounding_box.C
Outdated
for (unsigned int d = 0; d != LIBMESH_DIM; ++d) | ||
{ | ||
Real sized = this->second(d) - this->first(d); | ||
if (!libmesh_isinf(sized)) |
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 would return false
if sized
corresponded to std::numeric_limits<Real>::max()
, wouldn't it? I just read https://en.cppreference.com/w/cpp/numeric/math/isinf to check. If I'm correct, then the behavior of this function doesn't match its doxygen
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.
Yeah, I think you're right. Pushed a fix.
|
||
|
||
bool BoundingBox::contains_point | ||
(const Point & p, Real abs_tol, Real rel_tol) const |
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.
(const Point & p, Real abs_tol, Real rel_tol) const | |
(const Point & p, const Real abs_tol, const Real rel_tol) const |
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.
We generally don't pass parameters by const
value. const
on a reference parameter is making a promise to the user, but const
on a value parameter means nothing to the API semantics (because the value is a copy or a temporary anyway depending on input, and in neither case will the calling code ever see it) but can require future changes to the implementation to change the API syntax.
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.
You can leave it non-const in the header declaration for the reason you stated but mark it as const
in the implementation as that helps communicate to the reader that the parameters (at least in the current implementation) do not change
src/geom/bounding_box.C
Outdated
// Make local variables first to make things more clear in a moment | ||
const Real my_min_x = this->first(0) - tol; | ||
const Real my_max_x = this->second(0) + tol; | ||
bool x_int = is_between(my_min_x, p(0), my_max_x); |
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.
bool x_int = is_between(my_min_x, p(0), my_max_x); | |
const bool x_int = is_between(my_min_x, p(0), my_max_x); |
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.
You could early return if x_int = false
and so on through this function if you wanted to avoid some work
src/mesh/gmsh_io.C
Outdated
BoundingBox expected_bounding_box; | ||
std::swap(expected_bounding_box.min(), | ||
expected_bounding_box.max()); | ||
|
||
if (auto it = entity_to_bounding_box.find | ||
(std::make_pair(entity_dim, entity_tag)); | ||
it != entity_to_bounding_box.end()) | ||
expected_bounding_box = it->second; | ||
|
||
Node * node = mesh.node_ptr(nodetrans[gmsh_node_id]); | ||
|
||
// We'll accept *mostly* consistent. We have | ||
// files that claim a bounding box but still have | ||
// points epsilon outside it. | ||
libmesh_error_msg_if | ||
(!expected_bounding_box.contains_point | ||
(*node, 0, /* relative */ TOLERANCE), | ||
"$Elements dim " << entity_dim << " element " | ||
<< gmsh_element_id << " (entity " << entity_tag << | ||
") has node at " << *static_cast<Node*>(node) | ||
<< "\n outside entity physical bounding box " << | ||
expected_bounding_box); |
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.
Seems like two repetitions of this code. Optionally could add a method/lambda
Co-authored-by: Alex Lindsay <[email protected]>
3dc9778
to
cb9cbf5
Compare
This is the best solution we could come up with to #3899 - continue our existing behavior, but scream and die if the .msh file we're reading is definitely inconsistent with that behavior.
I'm ashamed that this is the first .msh file we've added to our test suite - LCOV confirms that our CI is not hitting
GmshIO::read()
! I'm almost hoping that this PR triggers test failures from inconsistent meshes downstream, just so I can see that there's been something hitting that code.