-
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
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
4ecd1b9
Added evaluate_integral.hpp, changed CMake file, add optional dependa…
jcs15c 3aa6a04
Added test for evaluate_integral methods, changed CMake file
jcs15c 52a24a7
Added copyright info
jcs15c ff23aad
Corrected style
jcs15c 2095c3e
Fixed style, slic logging
jcs15c b5496b1
Fixed lambda function warning
jcs15c 67212d7
Fixed dependency of primal::evaluate_integral on mfem in build system
jcs15c 5a43055
Add implementation file to minimize interface, change CMake
jcs15c 64c9dc3
Minimize interface, add static quadrature rules library
jcs15c b9d0005
Add comments, increase readability
jcs15c 3b57151
Update primal/CMakeLists.txt formatting
jcs15c 1d61386
Added tests for CurvedPolygon interface.
jcs15c 4995da1
Updated style/formatting, compilation optimization
jcs15c 6c02447
update release notes
jcs15c f4935d9
Updated comments
jcs15c b4bef28
Added CurvedPolygon overload to evaluate_line_integral
jcs15c 0534920
Updated to r-value reference for lambda functions
jcs15c b6b1b5b
Merge branch 'develop' into feature/spainhour/bezier_quadrature
jcs15c ddc9791
Changed quadrature rule pointers to references
jcs15c 4d0d9e1
Changed quadrature rule pointers to references
jcs15c 39d5cb7
Merge branch 'feature/spainhour/bezier_quadrature' of https://github.…
jcs15c 702de76
Temporarily removed R-value references
jcs15c de51f54
Add tests for line integrals on disconnected curves
jcs15c 8f75254
Added extra dependencies for Primal
jcs15c 218eac7
Merge branch 'develop' into feature/spainhour/bezier_quadrature
jcs15c 1c3c99d
Merge changes from develop
jcs15c File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
src/axom/primal/operators/detail/evaluate_integral_impl.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and | ||
| // other Axom Project Developers. See the top-level LICENSE file for details. | ||
| // | ||
| // SPDX-License-Identifier: (BSD-3-Clause) | ||
|
|
||
| #ifndef PRIMAL_EVAL_INTEGRAL_IMPL_HPP_ | ||
| #define PRIMAL_EVAL_INTEGRAL_IMPL_HPP_ | ||
|
|
||
| // Axom includes | ||
| #include "axom/config.hpp" // for compile-time configuration options | ||
| #include "axom/primal.hpp" | ||
|
|
||
| // MFEM includes | ||
| #ifdef AXOM_USE_MFEM | ||
| #include "mfem.hpp" | ||
| #else | ||
| #error "Primal's integral evaluation functions require mfem library." | ||
| #endif | ||
|
|
||
| // C++ includes | ||
| #include <cmath> | ||
|
|
||
| namespace axom | ||
| { | ||
| namespace primal | ||
| { | ||
| namespace detail | ||
| { | ||
| /*! | ||
| * \brief Evaluate a scalar field line integral on a single Bezier curve. | ||
| * | ||
| * Evaluate the scalar field line integral with MFEM integration rule | ||
| * | ||
| * \param [in] c the Bezier curve object | ||
| * \param [in] integrand the lambda function representing the integrand. | ||
| * Must accept a 2D point as input and return a double | ||
| * \param [in] quad the mfem integration rule containing nodes and weights | ||
| * \return the value of the integral | ||
| */ | ||
| inline double evaluate_line_integral_component( | ||
| const primal::BezierCurve<double, 2>& c, | ||
| std::function<double(Point2D)> integrand, | ||
| const mfem::IntegrationRule& quad) | ||
| { | ||
| // Store/compute quadrature result | ||
| double full_quadrature = 0.0; | ||
| for(int q = 0; q < quad.GetNPoints(); q++) | ||
| { | ||
| // Get intermediate quadrature point | ||
| // at which to evaluate tangent vector | ||
| auto x_q = c.evaluate(quad.IntPoint(q).x); | ||
| auto dx_q = c.dt(quad.IntPoint(q).x); | ||
|
|
||
| full_quadrature += quad.IntPoint(q).weight * integrand(x_q) * dx_q.norm(); | ||
| } | ||
|
|
||
| return full_quadrature; | ||
| } | ||
|
|
||
| /*! | ||
| * \brief Evaluate a vector field line integral on a single Bezier curve. | ||
| * | ||
| * Evaluate the vector field line integral with MFEM integration rule | ||
| * | ||
| * \param [in] c the Bezier curve object | ||
| * \param [in] integrand the lambda function representing the integrand. | ||
| * Must accept a 2D point as input and return a 2D axom vector object | ||
| * \param [in] quad the mfem integration rule containing nodes and weights | ||
| * \return the value of the integral | ||
| */ | ||
| inline double evaluate_line_integral_component( | ||
| const primal::BezierCurve<double, 2>& c, | ||
| std::function<Vector2D(Point2D)> vec_field, | ||
| const mfem::IntegrationRule& quad) | ||
| { | ||
| // Store/compute quadrature result | ||
| double full_quadrature = 0.0; | ||
| for(int q = 0; q < quad.GetNPoints(); q++) | ||
| { | ||
| // Get intermediate quadrature point | ||
| // on which to evaluate dot product | ||
| auto x_q = c.evaluate(quad.IntPoint(q).x); | ||
| auto dx_q = c.dt(quad.IntPoint(q).x); | ||
| auto func_val = vec_field(x_q); | ||
|
|
||
| full_quadrature += | ||
| quad.IntPoint(q).weight * Vector2D::dot_product(func_val, dx_q); | ||
| } | ||
|
|
||
| return full_quadrature; | ||
| } | ||
|
|
||
| /*! | ||
| * \brief Evaluate the area integral across one component of the curved polygon. | ||
| * | ||
| * Intended to be called for each BezierCurve object in a curved polygon. | ||
| * Uses a Spectral Mesh-Free Quadrature derived from Green's theorem, evaluating | ||
| * the area integral as a line integral of the antiderivative over the curve. | ||
| * For algorithm details, see "Spectral Mesh-Free Quadrature for Planar | ||
| * Regions Bounded by Rational Parametric Curves" by David Gunderman et al. | ||
| * | ||
| * \param [in] cs the array of Bezier curve objects that bound the region | ||
| * \param [in] integrand the lambda function representing the integrand. | ||
| * Must accept a 2D point as input and return a double | ||
| * \param [in] The lower bound of integration for the antiderivatives | ||
| * \param [in] quad_Q the quadrature rule for the line integral | ||
| * \param [in] quad_P the quadrature rule for the antiderivative | ||
| * \return the value of the integral, which is mathematically meaningless. | ||
| */ | ||
| template <class Lambda> | ||
| double evaluate_area_integral_component(const primal::BezierCurve<double, 2>& c, | ||
jcs15c marked this conversation as resolved.
Show resolved
Hide resolved
jcs15c marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Lambda&& integrand, | ||
| double int_lb, | ||
| const mfem::IntegrationRule& quad_Q, | ||
| const mfem::IntegrationRule& quad_P) | ||
| { | ||
| // Store some intermediate values | ||
| double antiderivative = 0.0; | ||
|
|
||
| // Store/compute quadrature result | ||
| double full_quadrature = 0.0; | ||
| for(int q = 0; q < quad_Q.GetNPoints(); q++) | ||
| { | ||
| // Get intermediate quadrature point | ||
| // on which to evaluate antiderivative | ||
| auto x_q = c.evaluate(quad_Q.IntPoint(q).x); | ||
|
|
||
| // Evaluate the antiderivative at x_q, add it to full quadrature | ||
| for(int xi = 0; xi < quad_P.GetNPoints(); xi++) | ||
| { | ||
| // Define interior quadrature points | ||
| auto x_qxi = | ||
| Point2D({x_q[0], (x_q[1] - int_lb) * quad_P.IntPoint(xi).x + int_lb}); | ||
|
|
||
| antiderivative = | ||
| quad_P.IntPoint(xi).weight * (x_q[1] - int_lb) * integrand(x_qxi); | ||
|
|
||
| full_quadrature += quad_Q.IntPoint(q).weight * | ||
| c.dt(quad_Q.IntPoint(q).x)[0] * -antiderivative; | ||
| } | ||
| } | ||
|
|
||
| return full_quadrature; | ||
| } | ||
|
|
||
| } // end namespace detail | ||
| } // end namespace primal | ||
| } // end namespace axom | ||
|
|
||
| #endif | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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):
(@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 toevaluate_line_integrala lambda function that is the return value for some other function (see below), thenevaluate_line_integral_componentcan no longer fit the argument to either overloaded definition. This doesn't happen when thestd::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.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::functioninstead of aLambda&&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-erasedstd::function.