-
Notifications
You must be signed in to change notification settings - Fork 32
Adds integral evaluation on Bezier curves/bounded regions #848
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
kennyweiss
left a comment
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.
Thanks @jcs15c -- this is great!
I added some suggestions for minor changes.
Please also add a line to the RELEASE-NOTES.
…ncy of primal on mfem
Co-authored-by: Kenny Weiss <[email protected]>
3f5d834 to
b8a0599
Compare
b8a0599 to
4995da1
Compare
kennyweiss
left a comment
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.
Thanks @jcs15c -- this is really nice!
Tag: @davidgunderman
| */ | ||
| inline double evaluate_line_integral_component( | ||
| const primal::BezierCurve<double, 2>& c, | ||
| std::function<double(Point2D)> integrand, |
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 think the lambda should be passed by r-value ref (here and elsewhere):
| std::function<double(Point2D)> integrand, | |
| std::function<double(Point2D)>&& integrand, |
(@kanye-quest -- could you please confirm?)
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'm very unclear on the details, but passing the std::function's by R-value reference is causing some issues with some to-be-implemented winding number code. Specifically, if we pass to evaluate_line_integral a lambda function that is the return value for some other function (see below), then evaluate_line_integral_component can no longer fit the argument to either overloaded definition. This doesn't happen when the std::function's are passed by constant reference, or when the lambda function is not the return value for another function, so I am unsure how to keep this as general as possible.
// An example of function that returns argument to evaluate_line_integral
std::function<Vector2D(Point2D)> get_vector_field(Point2D p)
{
return [p](Point2D x) -> Vector2D { return Vector2D({p[1], p[0]}); };
}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.
Thanks -- ok, sounds like something to think about and try to fix in the future.
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 might have something to do with this function (and the one below) accepting an std::function instead of a Lambda&& like in the other methods. The latter is a universal reference, so it can bind to both lvalues and rvalues.
For what it's worth, I think accepting Lambda&& might be better from an inlineability perspective -- it would be much more difficult for the compiler to inline through a type-erased std::function.
publixsubfan
left a comment
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.
LGTM, and thanks for the tests! Just a few comments to think about.
src/axom/primal/CMakeLists.txt
Outdated
| ELEMENTS operators/evaluate_integral.hpp | ||
| operators/detail/evaluate_integral_impl.hpp | ||
| IF MFEM_FOUND | ||
| ) |
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.
Nit: alignment?
| */ | ||
| inline double evaluate_line_integral_component( | ||
| const primal::BezierCurve<double, 2>& c, | ||
| std::function<double(Point2D)> integrand, |
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 might have something to do with this function (and the one below) accepting an std::function instead of a Lambda&& like in the other methods. The latter is a universal reference, so it can bind to both lvalues and rvalues.
For what it's worth, I think accepting Lambda&& might be better from an inlineability perspective -- it would be much more difficult for the compiler to inline through a type-erased std::function.
| // Get the quadrature for the line integral. | ||
| // Quadrature order is equal to 2*N - 1 | ||
| quad_Q = &(my_IntRules.Get(mfem::Geometry::SEGMENT, 2 * npts_Q - 1)); | ||
| quad_P = &(my_IntRules.Get(mfem::Geometry::SEGMENT, 2 * npts_P - 1)); |
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.
Minor: any reason to use pointers to the IntegrationRules instead of references?
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.
Only that the quest test I used for reference used them, changing it to references makes it much cleaner. Thank you!
| * Regions Bounded by Rational Parametric Curves" by David Gunderman et al. | ||
| */ |
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 appreciate this whole comment! I see you wrote "with ... rules supplied by MFEM," as is accurate. Please add the additional note, to make things extra clear:
| * Regions Bounded by Rational Parametric Curves" by David Gunderman et al. | |
| */ | |
| * Regions Bounded by Rational Parametric Curves" by David Gunderman et al. | |
| * | |
| * \note This requires the MFEM third-party library. | |
| */ |
This Doxygen mirrors the compile-time checks around line 28 of this file and line 15 of evaluate_integral_impl.hpp
| EXPECT_NEAR(evaluate_line_integral(connected_curve, transc_integrand, npts), | ||
| -0.574992518405, | ||
| abs_tol); | ||
| } |
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.
Please add a test with disconnected line segments, as this is noted as possible in the doxygen for evaluate_line_integral. Perhaps displace the middle, linear segment by (0, 2) or some such.
| EXPECT_NEAR(evaluate_line_integral(parabola_shape, winding_field, npts), | ||
| 1.0, | ||
| abs_tol); | ||
| } |
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.
Please add a test for disconnected segments.
agcapps
left a comment
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.
Thanks for this!
evaluate_integrals.hppfile toprimal/operators, which contains methods tomfem, used to evaluate quadrature algorithms.edit: See https://en.wikipedia.org/wiki/Line_integral#Line_integral_of_a_scalar_field and https://en.wikipedia.org/wiki/Line_integral#Line_integral_of_a_vector_field for information about the different types of line integrals.