Add assemble_lumped_mass! primitive#306
Merged
Merged
Conversation
Compute the partition-of-unity row-sum lumped mass directly via
per-element scatter (density * N[a] * JxW * I_NDIM), into the
assembler's full-DOF residual storage; extract free-DOF unknowns
for non-condensed mode.
Distinct from:
- assemble_mass! (full sparse consistent mass)
- assemble_diagonal!(asm, mass, ...) (diagonal of consistent mass,
rho * integral N_a^2 dV, NOT partition of unity)
- assemble_matrix_action!(asm, mass, U_zeros, ones_free, p) which
silently under-counts contributions from constrained columns and
breaks partition of unity at free DOFs adjacent to Dirichlet
boundaries.
This is the right primitive for explicit central difference dynamics
(a = M^-1 f) and for mass-diagonal Jacobi preconditioning, because it
preserves partition of unity (total mass = density * volume) by
construction.
Reuses the existing assemble_vector! scatter machinery via the
AssembledVector return type, so GPU support is inherited automatically
(fec_atomic_add! over an H1Field on the target backend, no CPU detour).
Test mirrors the existing AssemblerHelperMechanics setup and validates
three invariants: (a) on a fully-free DOF space the result equals the
row sums of the consistent mass matrix; (b) on a BC-restricted space
the result equals (a) restricted to free DOFs; (c) the result
disagrees with the legacy M_red * 1_free approach at free DOFs near
the boundary (regression marker for the under-count bug).
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #306 +/- ##
==========================================
- Coverage 66.33% 65.59% -0.75%
==========================================
Files 55 56 +1
Lines 4848 4868 +20
==========================================
- Hits 3216 3193 -23
- Misses 1632 1675 +43 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
cmhamel
approved these changes
Jun 6, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Adds
assemble_lumped_mass!— a partition-of-unity row-sum lumped mass primitive computed directly via per-element scatter ofdensity * N[a] * JxW * I_NDIM, into the assembler's full-DOF residual storage, with free-DOF unknowns extracted for non-condensed mode.This is distinct from the existing assembly primitives:
assemble_mass!builds the full sparse consistent mass matrix.assemble_diagonal!(asm, mass, ...)extracts the diagonal of the consistent mass (rho * integral N_a^2 dV), which is not partition of unity.assemble_matrix_action!(asm, mass, U_zeros, ones_free, p)silently under-counts contributions from constrained columns and breaks partition of unity at free DOFs adjacent to Dirichlet boundaries.Why this primitive
This is the right primitive for:
a = M^-1 f), where partition of unity (total mass = density × volume) is required to recover correct wave speeds at free DOFs adjacent to a Dirichlet boundary.The row-sum-of-reduced-M approach used previously by some downstream code (Carina.jl) under-counts mass at boundary-adjacent DOFs because
M_red * 1_freemisses theM_{free,BC}cross terms.Implementation notes
Reuses the existing
assemble_vector!scatter machinery via theAssembledVectorreturn type, so GPU support is inherited automatically (fec_atomic_add!over anH1Fieldon the target backend, no CPU detour).Exports:
assemble_lumped_mass!(assembler, func, Uu, p)— assembly entry point, mirrors theassemble_diagonal!calling convention.lumped_mass(asm)— accessor returning free-DOF unknowns (non-condensed) or full-DOF (condensed).