From eb9da56438e0baf6f4a6ea30085eef07539b0501 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Mon, 12 Oct 2026 14:10:10 -0400 Subject: [PATCH] feat(geometry/deformation/backend/mfem/detail): added radial loactor to help identify points on a surface --- .../backend/mfem/detail/radial_locator.hpp | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/include/serif/geometry/deformation/backend/mfem/detail/radial_locator.hpp diff --git a/src/include/serif/geometry/deformation/backend/mfem/detail/radial_locator.hpp b/src/include/serif/geometry/deformation/backend/mfem/detail/radial_locator.hpp new file mode 100644 index 00000000..a82f0864 --- /dev/null +++ b/src/include/serif/geometry/deformation/backend/mfem/detail/radial_locator.hpp @@ -0,0 +1,79 @@ +#pragma once + +/** + * @file radial_locator.hpp + * @author Emily M. Boudreaux + * + * @brief File containing some utility functions for locating points on a radial shell. + */ + +#include "mfem/fem/intrules.hpp" +#include "mfem/linalg/vector.hpp" +#include "serif/geometry/deformation/failure.hpp" + +namespace mfem { + /** + * @brief Forward definition of the mfem::Mesh class to avoid having to parse the entire mfem mesh header file. + */ + class Mesh; +} + +namespace serif::geometry::deformation::backend::mfem::detail { + /** @struct LocatedBoundaryPoint + * + * @brief A structure representing a located boundary point, including the boundary element index and the integration point on that element. + */ + struct LocatedBoundaryPoint { + int boundary_element; ///< The index of the boundary element where the point is located. + ::mfem::IntegrationPoint point; ///< The integration point on the boundary element where the point is located. + }; + + /** + * @brief compute the cubical local radius of a given position vector. Alternative put: + * compute the \f$L\infty\f$ norm of the position vector (i.e. the maximum absolute value of its components) + * + * @param position The position vector for which to compute the logical radius. + * @returns The logical radius of the position vector, defined as the maximum absolute value of its components (i.e., the L\f$\infty\f$ norm). + */ + [[nodiscard]] double logical_radius(const ::mfem::Vector& position); + + + /** + * @brief Compute the logical radius of a boundary shell in a mesh, given the mesh and the boundary attribute. + * + * @param mesh The mesh containing the boundary shell. + * @param attribute The boundary attribute identifying the shell to compute the logical radius for. + * + * @returns The logical radius of the boundary shell if successful, or a DeformationFailure object if an error occurs (e.g., incompatible discretization, non-finite vertex, or invalid geometry). + * + * @par Explanation + * The algorithm here is as follows + * 1. Loop over all boundary elements. validate they they have the correct attribute id (if not skip them) + * 2. Get the geometry type of the element and validate that it has a valid transformation and is a square (which for mfem really means a quadrilateral). If not return an error + * 3. Get the vertices of the element and loop over them. For each vertex + * a. Transform the vertex into a position vector + * b. validate that each component of the position vector is finite. If not return an error + * c. Compute the logical radius of the position vector (L\f$\infty\f$ norm) and update the minimum and maximum logical radius values seen so far + * d. Increment the number of samples seen so far + * 4. validate that at least one sample was seen, that the minimum values is positive, and that are at least separated by 1e-12 * max(1, maximum). If not return an error + * 5. Return the average of the minimum and maximum logical radius values seen. + * + * Effectively then what this does is find an estimate for the radius of some enclosing surface over the boundary elements. + */ + [[nodiscard]] std::expected boundary_logical_radius(::mfem::Mesh& mesh, int attribute); + + /** + * @brief Locate a projected logical ray on a quadrilateral shell. + * + * @param mesh The mesh containing the boundary shell. + * @param attribute The boundary attribute identifying the shell to locate the point on. + * @param target The target position vector to locate on the boundary shell. + * + * @returns A LocatedBoundaryPoint object representing the located boundary point if successful, or a DeformationFailure object if an error occurs + */ + [[nodiscard]] std::expected locate_boundary_point( + ::mfem::Mesh& mesh, + int attribute, + const ::mfem::Vector& target + ); +}