Repository navigation
Fix energy conservation in 1D VlasovAmpere runs with diagonal scaling - #741
Closed
max-models wants to merge 4 commits into
Closed
max-models wants to merge 4 commits into
max-models wants to merge 4 commits into
Conversation
In a periodic direction with fewer points than the band width (2p + 1 > n, e.g. a single element in a 1D run), StencilMatrix.diagonal() returns only the entry at offset 0, while the entries at offsets k = m n also lie on the main diagonal. The diagonal D of the mass matrix was therefore wrong, and MassMatrixPreconditioner with diagonal_scaling=True (the default since #739) was no longer exact on the logical cube; in VlasovAmpereCoupling this broke energy conservation in 1D runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… before the push The pusher kernel reads the ghost regions of e_sum directly. They were only correct if the Schur solver happened to return its solution with valid ghost regions, which is no longer the case with the diagonal scaling of MassMatrixPreconditioner (default since #739): its last step is a StencilDiagonalMatrix.dot that writes only the owned entries. In 1D runs (one element in e2, e3) every evaluation reads ghost values, and the total energy was no longer conserved (drift ~1e-4 instead of ~1e-12). The other couplings already update the ghost regions before pushing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
max-models
added a commit
that referenced
this pull request
Oct 10, 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
Since #739 made
diagonal_scaling=Truethe default ofMassMatrixPreconditioner, the total energy of 1DVlasovAmpereOneSpeciesruns (one element in e2 and e3) is no longer conserved: it drifts by ~1.5e-4 per step instead of ~1e-12. This breakstest_verif_VlasovAmpereOneSpecies.py::test_energy_conservationin #738. This PR fixes two bugs:VlasovAmpereCoupling: update the ghost regions of the mid-point field before the push. The pusher kernel reads the ghost regions ofe_sumdirectly. They were only correct as long as the Schur solver happened to return valid ghost regions. With the diagonal scaling it doesn't, because its last step is aStencilDiagonalMatrix.dot, which writes only the owned entries. In 1D runs every evaluation reads ghost values. The other couplings (EfieldWeightsCoupling,CurrentCoupling6DCurrent,CurrentCoupling5DCurlb) already update the ghost regions before pushing.Diagonal scaling: include the band entries that wrap onto the diagonal. In a periodic direction with fewer points than the band width (
2p + 1 > n, e.g. a single element), the band entries at offsetsk = m nalso lie on the main diagonal.StencilMatrix.diagonal()returns only the entry atk = 0, so the diagonal D of the mass matrix was wrong, andMassMatrixPreconditionerwith diagonal scaling was no longer exact on the logical cube. Fixed with_stencil_local_diagonalin_local_diagonal, whichMassMatrixPreconditioner._core_diagonalnow uses.Tests
test_mass_matrices.py::test_mass_preconditioner_diagonal_scaling_periodic_exact: checks that the preconditioner with diagonal scaling inverts M0 to M3 exactly on the Cuboid, including grids with one element. Without the fix, 6 of the 12 cases fail.test_preconditioner_transpose.py,test_stiffness_preconditioner.py,test_mass_matrices.py::test_mass_preconditioner*andtest_poisson.py(127 / 151 passed). With Fix total energy at t=0 in Vlasov-Ampère/Maxwell models (ghost regions, control variate) #738 merged in,test_verif_VlasovAmpereOneSpecies.pypasses (3 passed).🤖 Generated with Claude Code