Published October 14, 2026 | Version v3.44.1

Bramble.jl

Authors/Creators

Description

Fast-diagonalisation solvers for Laplacian-like forms, sparse implicit ODE solves on the CSR backend, a per-machine backend profile, a Claude Code plugin for users, and about 250 fixes from the pre-release review. This is the first tag since v3.23.0 (the v3.44.0 version was a pre-release review milestone and was never tagged). It carries several behaviour changes, listed first. Most turn a silent wrong answer into an error.

Breaking

Moving a mesh with predicate-defined markers is refused. change_points!(Ωₕ, pts) and set_points! throw an ArgumentError on a mesh whose labels set_markers! built from a predicate of position: the set would stay computed at the old points. Use change_points!(Ωₕ, domain_markers, pts). Face labels are fine. set_points! with a new point count now rebuilds :boundary and :interior for the new grid (#490). A GMG coarse level refuses predicate labels the same way.

f * uₕ on a composite element is a MethodError. A function times a vector element no longer multiplies component-wise by accident.

inner₊(f, v) with a bare source on the left reads the direction the way the source-node form does, so above one dimension it throws (#511). inner₊ of two tuples of different lengths throws DimensionMismatch (#518), and so do Rₕ, Rₕ!, avgₕ and avgₕ! given a tuple with the wrong number of functions (#506).

Argument refusals are ArgumentErrors that name the value. Every dirichlet_bc! refusal, reaction with an empty or non-Symbol marker, a Bool direction, a point count the mesh cannot hold, and a VectorElement on offset-axis data (#505). A vector dirichlet_bc! given a label with no condition used to skip it and now throws.

Mesh and domain. mesh(Ω(t), ...) evaluates predicates at t; on a time-dependent domain a predicate must take (x, t) (#452). A mesh's first and last points are exactly a and b.

Kronecker. A form whose Kronecker operator is complex is refused with an ArgumentError. A Kronecker operator throws once its mesh has moved in place, naming the mutation, instead of multiplying with stale data. fdm_factorize! refuses a refill whose structure differs from the factorization's.

Solver backends. A singular matrix throws SingularException through Accelerate, Sparspak and a MUMPS refactor, and sym = :auto solves a complex symmetric, non-Hermitian matrix through SuiteSparse. solve refuses a preconditioner without an iterative solver. symmetrize! refuses a non-square matrix.

Removed. bandwidths and blockbandwidths (internal and unused since v3.3.0, #649), the searching threaded sweep, and PatternSink.

Features

Kronecker fast diagonalisation. fdm_factorize builds a reusable factorization of a Laplacian-like form, fdm_factorize!(f, K) and fdm_factorize!(f, a) refill it in place, and fdm_solve! solves with no allocation. Forward, centered, averaged, jump and chained families, Robin faces and single-axis coefficients are solved; mixed derivatives and advection are refused. fdm_preconditioner(a) returns an FDMPreconditioner that inverts the Laplacian-like part of a mixed-derivative form, for a Krylov solve. Kronecker operators also work on composite spaces, and inner_Γ terms expand into one Kronecker term per face.

CSR backend. An implicit ODE solve builds a sparse Jacobian (#677, #682), and the CSR Dirichlet methods accept a zero-based matrix.

Bramble.profile_backends profiles the execution policies on the machine, with a Float32 GPU row on a working Metal device.

norm₁ₕ, snorm₁ₕ and norm(u, "1h") on a composite grid function (#644).

Claude Code plugin (plugins/bramble): teaches the public API to a Claude Code session, with a test that fails when it names something that no longer exists.

Fixes

About 250, from the pre-release review of src/ and the extensions:

  • Restricted sums, scales and differences assemble with no allocation on a warm refill in more shapes (#759, #760), and a plain summand beside a restriction keeps its own product.
  • @operator_family needs no internal imports, and inner₊(κ * ∇ₕ(u), ∇ₕ(v)) infers.
  • viz refuses a 1D input and warns only on a missing backend.
  • A dropped MUMPS factorization is freed, and the MUMPS extension stores a concretely typed Mumps.
  • The pde_solve rrule accepts keywords and conjugates u for a complex gradient. The adjoint defaults to QuadratureAdjoint on a problem built without p.
  • Every Int32 device launcher refuses more than typemax(Int32) entries on the host.

Full list: https://github.com/gpena/Bramble.jl/compare/v3.23.0...v3.44.1

Notes

If you use this software, please cite it as below.

Files

gpena/Bramble.jl-v3.44.1.zip

Files (1.6 MB)

Name Size
md5:38304bde52cffa8cbc2b23504b5b231b
1.6 MB Preview Download

Additional details

Related works

Software