Block-triangular preconditioners for Maxwell solves - #13
Draft
Alexey-Voronin wants to merge 9 commits into
Draft
Conversation
Alexey-Voronin
marked this pull request as draft
March 25, 2026 16:40
…check inputs manually in mrhyde, use xml decks for block-solvers that get passed to MueLU skipping MrHyDE pre-processing step.
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
This PR adds a block-triangular preconditioner for$2 \times 2$ mixed Maxwell systems in
linear_algebra, where the pivot block, Schur approximation, and per-block solvers are all individually configurable.The code is split into a self-contained
block_prec/module (types, validation, operators, assembly, Schur construction) and integration code insideLinearAlgebraInterface.Currently supported solvers:
AMG,RefMaxwell,Direct,Diagonal;AMG,RefMaxwell,Direct.Mathematical Form
For
the preconditioner factors the system into a pivot solve and a Schur-complement solve.
Currently, two Schur approximations are supported:
base:diag:To make input decks easier to compose, the parameter
Schur pivot block = 0or1is used. After extraction, blocks are relabeled by role (pivot/target), not by original index:J00= pivot diagonal,J11= target diagonal,J10= target-from-pivot,J01= pivot-from-target.Structure
The
block_prec/files are ordered by dependency, each one only pulls from what's above it. I used Teko'sBlockedTpetraOperatorto handle block extraction, MueLu to build AMG and auxiliary-space preconditioners for each block, and Tpetra/Xpetra/Ifpack2 to supply the needed maps, matrices, and smoother wrappers.BlockTypes.hppSchurVariant/BlockPrecTypeenumsParamUtils.hppBlockOperators.hppDiagonalInverseOperator,DirectSolveOperator,BlockDiagonalOperator,BlockTriangularOperator, import/export workspace helpersBlockAssembly.hppbuildInverseDiagonal,buildLumpedM0inv,buildBlockSystemForSet, pivot/Schur block preconditioner dispatchSchurApproximation.hppschurBase,assembleSchurCoreFromInputs(union-sparsity two-pass),buildSchurApproximationentry pointIntegration layer:
linearSolverContext.hppSchurConfig/RefMaxwellDatastructs; phased parse with strict section validationlinearAlgebraInterface_blockprec.hppbuildBlockMaps, block-diagonal build, block-triangular setup (extract → Schur → pivot/Schur precs → assemble operator),validateRefMaxwellBlockInputs, reuse policylinearAlgebraInterface_solvers.hppbuildOrUpdatePreconditionerdispatch,buildRefMaxwellPreconditioner(Xpetra wrapping, hierarchy build/reuse), Belos solver creation and status handlingSome other supporting changes had to be made outside of
linear_algebra:managers/assembly/assemblyManager*.hppAssemblyManager::getWeightedMassto build the mass matrix with all weights = 1. RefMaxwell/ADS uses this in the block-triangular path to assemble the H(curl) M1 matrix with unit weights.managers/solver/solverManager*.hppSolverManager::setupBlockTriangularAuxiliarynow assembles the RefMaxwell auxiliary operators/data (D0/M1/M2, nodal coords, and D1 for ADS), callsgetWeightedMasswith the unit-mass option when needed, and reuses that assembled context across the related linear solver contexts.interfaces/user/userInterface.hppDesign Decisions
The$J_{10},\mathrm{diag}(J_{00})^{-1}J_{01}$ can create fill beyond $J_{11}$ 's sparsity pattern.$J_{11}$ via
diagcorrectionThe problem is that inserting into a
fillComplete'd copy ofsumIntoGlobalValuessilently drops these entries. Instead,assembleSchurCoreFromInputsruns two passes: one to compute the union column set per row, one to accumulate and insert beforefillComplete.Block-triangular has its own
none/update/fullreuse insidesetupBlockTriangularPreconditioner, independently of the outerreuse_preconditionerflag used by the monolithic AMG path.updateskips rebuild when the Jacobian values haven't changed;fullfreezes the operator entirely. RefMaxwell hierarchies are cached per-role (refmaxwell_precfor pivot,schur_refmaxwell_precfor Schur) so reuse on one block doesn't contaminate the other.Tests
Related regression tests have been added to
regression/maxwell/linear_solvers. These a grouped into 3 categoriesPositive:
blocktri_pivot0_direct_direct,blocktri_pivot1_direct_direct,blocktri_pivot1_refmaxwell_gs,blocktri_pivot1_refmaxwell_chebmax linear iters: #) +2 to account for potential variability across machines. The accuracy is verified through output integrated quantities. Printing residual to .gold files is not a architecture/compiler robust regression test.Negative (expected-failure):
blocktri_invalid_unknown_key,blocktri_invalid_schur_type,blocktri_invalid_refmaxwell_keyBaseline:
monolith_blockdiag_jacobi(monolithic vs block-diagonal consistency)Sandbox:
sandbox/testCases/maxwell_solvers/summary/README.mdFuture steps
Currently the block-triangular apply is implemented directly at the Tpetra level in
BlockTriangularOperator. An obious next step would be to express the same 2x2 block operator using Teko block preconditioner factories (e.g. SIMPLE, etc..) with MueLu/RefMaxwell plugged in through Thyra adaptors.