Skip to content

Generate configurable quadrature within contact pair calculations - #278

Open
ebchin wants to merge 51 commits into
developfrom
feature/ebchin/generate-integration-rule
Open

ebchin wants to merge 51 commits into
developfrom
feature/ebchin/generate-integration-rule

Conversation

@ebchin

@ebchin ebchin commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Energy Mortar now generates and consumes pair-local quadrature within each element-pair gap or force calculation. This separates quadrature construction from the contact kernels while keeping generated points and weights local to the calculation.

  • setQuadratureOrder() selects the requested reference polynomial degree for ENERGY_MORTAR. Degrees 0-5 select one, two, or three Gauss-Legendre points; the default degree 5 retains three-point integration. The factory selects the corresponding rule specialization for nodal or quadrature-point enforcement.
  • The adapter owns a PairQuadratureRule<SmoothedProjectedEdgeMapping, EdgeQuadratureRule<N>>, and the Energy Mortar calculator borrows that configured rule. Each pair calculation prepares owning LinearEdgeGeometry objects that the mapping reuses by reference.
  • SmoothedProjectedEdgeMapping owns projection and smoothing behavior. It projects mesh 2 endpoints along the mesh 2 normal onto mesh 1, selects the contributing interval, maps points to both edges, and applies the mesh 1 physical measure exactly once. It calculates projected parent bounds directly and shares the projection determinant between endpoints. Projection geometry no longer depends on InterfacePairChecks.
  • Refined search checks topology and edge orientation only. Projected overlap and the contributing interval are determined during quadrature generation. Mesh 1 remains the non-mortar integration side, and mesh 2 remains the mortar side.
  • Allocation-free generators use fixed-capacity local arrays and can run in device kernels. Energy Mortar assembly remains host-only. Invalid geometry and insufficient output capacity have explicit generation statuses. Energy Mortar checks those statuses before consuming quadrature, including inside differentiated calculations, and throws an exception on failure. Valid empty intervals remain successful zero-point rules.
  • Both Enzyme derivative modes are preserved: geometry-dependent quadrature is regenerated inside differentiation, while frozen reference points and weights are mapped using current geometry. Straight-edge normal gaps are calculated directly from the mesh 2 line so very short valid edges retain their separation.

Co-oriented edge pairs produce zero points before point generation, including when remapping frozen reference points, so they contribute neither tributary area nor residual-gap forces.

The unused ContactFormulation::updateIntegrationRule() operation is removed. Independent quadrature output, persistent interface quadrature storage, and batch allocation or packing remain deferred. This prepares contact calculations for higher-order work; the implemented method still uses two-dimensional linear edges.

Tests cover local quadrature coordinates and weights, polynomial integration, partial overlap, smoothing support, zero-point rules, invalid geometry, bounded writes, and frozen-reference mapping. Additional tests cover oblique projection, the parallel-line fallback, base-rule failure propagation, and degenerate geometry errors for nodal values, gradients, Hessians, and penalty calculations at all three point counts and both derivative modes. Factory tests check both enforcement locations, supported orders, setting changes, and invalid settings. Existing finite-difference coverage checks gradients and Hessians for all three point counts and both derivative modes, including changes in edge length.

Validation with LLVM 19 and Enzyme: eight selected Release suites passed, covering pair quadrature, refined search, interface-pair checks, factory settings, penalty and LM patches, finite differences, and two-rank MFEM Jacobian assembly. The finite-difference suite also passed in an Enzyme Debug build, including the invalid-geometry regression. Pair quadrature passed in the non-Enzyme Debug build. Sequential and OpenMP execution were exercised; CUDA/HIP configurations were unavailable locally. All changed C++ files pass clang-format 19.

Add bounded quadrature storage and reusable edge Gauss rules with independent smoothed interval selection and target projection. Select one-, two-, or three-point rules through the quadrature factory and setQuadratureOrder API.

Update Energy Mortar to use the rule objects while preserving frozen and varying quadrature derivatives. Cover source rules, projections, capacity errors, factory choices, and derivatives in tests.
Construct one projection configuration in the factory and copy it into templated search and quadrature consumers. Remove separate projection settings from Energy Mortar and calculate straight-edge normal gaps directly.

Cover projection selection and short-edge gaps, move shared geometry calculations out of mesh checks, and add Doxygen guidance and documentation for the new APIs and test helpers.
@ebchin
ebchin force-pushed the feature/ebchin/generate-integration-rule branch from 0d2e25b to 536c169 Compare October 27, 2026 05:58
@ebchin
ebchin force-pushed the feature/ebchin/interface-quadrature branch from 035919f to 7139502 Compare October 27, 2026 05:58
@ebchin ebchin changed the title Generate owned integration rules from contact formulations Generate configurable quadrature from contact formulations Oct 27, 2026
@ebchin
ebchin changed the base branch from feature/ebchin/interface-quadrature to feature/ebchin/contact-search October 27, 2026 21:39
@ebchin ebchin changed the title Generate configurable quadrature from contact formulations Generate configurable quadrature within contact pair calculations Oct 27, 2026
# Conflicts:
#	src/tribol/physics/EnergyMortar.cpp
#	src/tribol/physics/EnergyMortarAdapter.cpp
#	src/tribol/physics/EnergyMortarAdapter.hpp
Base automatically changed from feature/ebchin/contact-search to develop October 28, 2026 20:54
ebchin and others added 5 commits October 28, 2026 13:54
Explain geometry setups, expected results, and quadrature storage in plain language. Split tests with distinct purposes and label cases for useful failure messages.

Rename single-element mesh terminology to edge or geometry, update Energy Mortar callers, and clarify that custom factory rule descriptions provide metadata only.

Validation: all 20 CPU quadrature tests pass; Enzyme-related callers were syntax-checked.

@srwopschall srwopschall left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ebchin - Big picture. I like the layout and I am sure it "works", but the codexy language is a big barrier for me to move beyond. There are ambiguous meanings in a lot of the doxygen and variable names. This is important enough that one word has to mean one thing so we have to shore up our lexicon before moving on. This review is phase 1.

Comment thread src/tribol/integ/PairQuadratureRule.hpp Outdated
static constexpr int parent_dimension = Mesh1Geometry::parent_dimension; ///< Mesh1 parent components.
static constexpr int parent_dimension2 = Mesh2Geometry::parent_dimension; ///< Mesh2 parent components.
static constexpr int spatial_dimension = Mesh1Geometry::spatial_dimension; ///< Physical components.
static constexpr int endpoint_count = Mesh1Geometry::endpoint_count; ///< Mesh1 endpoints per element.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vertex_count? endpoint is a little ambiguous to me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed

Comment thread src/tribol/integ/PairQuadratureRule.hpp Outdated
* @param mesh2 Current second-element coordinates, with geometry defined by Mesh2Geometry.
* @return Local reference quadrature with generation status; invalid geometry has zero points.
*/
TRIBOL_HOST_DEVICE TRIBOL_ENZYME_INLINE ReferenceQuadrature generateReferenceQuadrature(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be fine, I'll get used to it, but consider ContactQuadrature or IntegrationSurfaceQuadrature.

I think I'm just getting really confused as to what is reference. I could have sworn there was something where reference can refer to points on [-1,1] interval. Here it sounds like reference refers to quadrature points in some xi space mapped to the physical configuration integration surface. Please go through with a fine tooth comb and align lexicon. We said we will change this to be more specific e.g. IntegrationSurfaceQuadrature. Please update.

@ebchin ebchin Oct 30, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to IntegrationSurfaceRule

Comment thread src/tribol/integ/PairQuadratureRule.hpp Outdated
TRIBOL_HOST_DEVICE TRIBOL_ENZYME_INLINE ReferenceQuadrature generateReferenceQuadrature(
typename Mesh1Geometry::Coordinates mesh1, typename Mesh2Geometry::Coordinates mesh2 ) const
{
return base_rule_.generate( mapping_.makeIntegrationSurface( mesh1, mesh2 ) );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revise input arg naming to reflect that they are elements.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to element1_coords

Comment thread src/tribol/integ/PairQuadratureRule.hpp Outdated
* @return Local paired quadrature with generation status; invalid geometry has zero points.
*/
TRIBOL_HOST_DEVICE TRIBOL_ENZYME_INLINE QuadratureData
mapReferenceQuadrature( typename Mesh1Geometry::Coordinates mesh1, typename Mesh2Geometry::Coordinates mesh2,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update name to be consistent with e.g. mapIntegrationSurfaceQuadrature

Yes, update name to be more clear. We have a forward map, a reverse map, a map from quadrature parent space to overlap, a map from overlap to constituent edges, and a map from those physical configuration edges to parent space for basis evaluation. I think even at the risk of a longer function name, let's call it what it is doing.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapIntegrationSurfaceRuleToElements()

Comment thread src/tribol/integ/Quadrature.hpp Outdated
/**
* @brief Bounds on a one-dimensional integration surface in normalized parent coordinates.
*/
struct EdgeQuadratureInterval {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep this edge specific struct here and consider a note for future development that structs for particular topologies/geometries should go here as part of "common" quadrature stuff.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to file Doxygen comment

Comment thread src/tribol/integ/Quadrature.hpp Outdated
* @tparam Capacity Number of points available in the fixed-size backing arrays.
*/
template <int ParentDimension, IndexT Capacity>
struct ReferenceQuadratureData {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, parent/reference confusion.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParentDimension -> CoordinateDimension and ReferenceQuadratureData -> IntegrationSurfaceRule

Comment thread src/tribol/integ/Quadrature.hpp Outdated
template <int ParentDimension1, int ParentDimension2, bool ReadOnly = false>
struct PairQuadratureView {
using Value = std::conditional_t<ReadOnly, const RealT, RealT>; ///< RealT with the requested write access.
ArrayViewT<Value, 2> geometry1_parent_coordinates; ///< Points on geometry1 [point][parent component].

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these edge 1's endpoint coordinates? The doxygen says points on geometry1 so are they integration points on the physical edge? The arrayview name and doxygen conflict.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified these are quadrature points in element parametric coordinates

Comment thread src/tribol/integ/Quadrature.hpp Outdated
using Value = std::conditional_t<ReadOnly, const RealT, RealT>; ///< RealT with the requested write access.
ArrayViewT<Value, 2> geometry1_parent_coordinates; ///< Points on geometry1 [point][parent component].
ArrayViewT<Value, 2> geometry2_parent_coordinates; ///< Corresponding points on geometry2 [point][parent component].
ArrayViewT<Value> physical_weights; ///< Weights including the mapping's physical integration measure.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are weights suitable for use in the actual weak form evaluation?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these weights already include the physical integration measure

Comment thread src/tribol/integ/Quadrature.hpp Outdated
TRIBOL_HOST_DEVICE TRIBOL_ENZYME_INLINE PairQuadratureView( ArrayViewT<Value, 2> geometry1_points,
ArrayViewT<Value, 2> geometry2_points,
ArrayViewT<Value> weights )
: geometry1_parent_coordinates( geometry1_points ),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please shore up "coordinates" and "points". I realize points have coordinates but parent coordinates sounds like nodes or vertices. I would never read that and know exactly what it is.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented quadrature-point coordinates in each element’s parameterization

Comment thread src/tribol/integ/Quadrature.hpp Outdated
};

/**
* @brief Fixed-capacity quadrature consumed within one element-pair calculation.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update brief to more human readable language :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded to describe the stored quadrature coordinates and weights

@srwopschall srwopschall left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ebchin - Big picture. I like the layout and I am sure it "works", but the codexy language is a big barrier for me to move beyond. There are ambiguous meanings in a lot of the doxygen and variable names. This is important enough that one word has to mean one thing so we have to shore up our lexicon before moving on. This review is phase 1.

ebchin added 30 commits October 30, 2026 09:58
Use CoordinateDimension for integration-surface quadrature and ParametricDimension1/2 for paired element coordinates. Define the element parameterization used for geometry mapping and basis evaluation.

Validation: clang-format 19 and git diff --check pass. Builds and test suites are deferred to the review batch checkpoint.
Identify element coordinate arguments explicitly and distinguish the integration-surface quadrature generator from its generated points and weights.

Validation: clang-format 19 and git diff --check pass. Builds and test suites are deferred to the review batch checkpoint.
Name generated points and weights IntegrationSurfaceRule, rename the edge generator and its header, and use max_points for the maximum successful rule size. Update callers, explicit instantiations, tests, CMake, and release notes.

Validation: clang-format 19, git diff --check, and source name/include checks pass. Builds and test suites are deferred to the review batch checkpoint.
Add ElementPairMapping and IntegrationSurfaceRuleGeneratorFor concepts to check geometry metadata, geometry construction, generation inputs and results, and paired mapping compatibility. Add compile-time acceptance and rejection checks and document the constraints.

Validation: LLVM 19 syntax-only compilation of the pair-quadrature test translation unit, clang-format 19, and git diff --check pass. Full builds, runtime test suites, and CUDA/HIP validation remain deferred to the review batch checkpoint.
Shorten coordinate field and argument names, rename the geometry input view to Coords, and use ParentCoords and GetParentNodeCoords for basis coordinates. Update callers, concepts, tests, and release notes while retaining the EnergyMortarCoordinates suite name.

Validation: LLVM 19 syntax-only compilation of the pair-quadrature and basis-function test translation units, clang-format 19, and git diff --check pass. Full builds, runtime test suites, and CUDA/HIP validation remain deferred to the review batch checkpoint.
Keep topology and geometry integration-surface representations alongside EdgeQuadratureInterval in the shared quadrature header.

Validation: clang-format 19 and git diff --check pass. Comment-only change; existing deferred build and test validation remains pending.
Update includes, the include guard, and the installed-header list to identify the shared quadrature definitions.

Validation: clang-format 19, git diff --check, and old header reference checks pass. Full builds and runtime test suites remain deferred to the review batch checkpoint.
Name the position argument xi in both overloads and document the parametric interval, physical output, and extrapolation behavior.

Validation: clang-format 19 and git diff --check pass. Argument and documentation changes only; full builds and runtime suites remain deferred to the review batch checkpoint.
Document that the default degree five corresponds to a three-point Gauss-Legendre rule in one dimension.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Explain its first-to-second vertex orientation, physical magnitude, and lack of normalization.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Clarify geometry accessors, quadrature views, generator references, mesh arrays, and refined-search input lifetimes. Update related tests, the static-assert diagnostic, and release notes.

Validation: clang-format 19 and git diff --check pass. A token comparison confirms that changes outside comments are limited to the static-assert diagnostic.
Document normal projection, the vertex coordinate convention, and results beyond the edge segment without normalized or unclamped terminology.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Describe Vector as a physical-space vector and edge_ as the unnormalized vector from the first vertex to the second.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Describe the shared Vector alias as a vector in physical space.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Clarify that mapToElements writes each edge's parametric coordinates and physical integration weights.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Describe lower and upper projected coordinates and identify makeIntegrationSurface as the operation that clips and smooths them.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Identify edge2's normal as the projection direction and edge1's parametric coordinate as the returned value, including values beyond the vertices.

Validation: clang-format 19 and git diff --check pass. Documentation-only change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants