Skip to content

Add Implementation for AMF-type ODE schemes#3334

Merged
ChrisRackauckas merged 6 commits intomasterfrom
u/amf
Apr 9, 2026
Merged

Add Implementation for AMF-type ODE schemes#3334
ChrisRackauckas merged 6 commits intomasterfrom
u/amf

Conversation

@utkarsh530
Copy link
Copy Markdown
Member

@utkarsh530 utkarsh530 commented Apr 3, 2026

Checklist

  • Appropriate tests were added
  • Any code changes were done in a way that does not break public API
  • All documentation related to code changes were updated
  • The new code follows the
    contributor guidelines, in particular the SciML Style Guide and
    COLPRAC.
  • Any new documentation only uses public API

Additional context

Implementing AMF-type schemes for solving ODEs.

  • build_amf_function(f!; jac, split = nothing, amf_factors = nothing) is the single construction entry point.
  • jac provides the full Jacobian operator and becomes the jac_prototype on the returned ODEFunction.
  • If split is omitted, the builder constructs the exact Rosenbrock W operator from jac.
  • If split = (J₁, J₂, ...) is provided, the builder forms the default AMF operator as the ordered product ∏ᵢ (I - γJᵢ).
  • split is operator-based: each Jᵢ is an AbstractSciMLOperator carrying its own structure and update rules.
  • If a problem has a better structured AMF representation than the default I - γJᵢ product, amf_factors = (W₁, W₂, ...) can be passed directly.
  • In that case, the builder uses the supplied AMF factors as the W_prototype product while still using jac as the full Jacobian prototype.
  • AMF(alg) remains a thin solver wrapper that plugs the operator-aware linear solve into an otherwise standard SciML solve workflow.

@utkarsh530 utkarsh530 marked this pull request as ready for review April 9, 2026 05:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an OrdinaryDiffEqAMF subpackage to support AMF-style Rosenbrock-W solves using SciMLOperator-based Jacobians/W_prototype, along with regression tests validating correctness on standard model problems.

Changes:

  • Introduces AMF algorithm wrapper and SciMLOpFactorization LinearSolve backend.
  • Adds AMFOperator and build_amf_function utilities for constructing jac_prototype/W_prototype operator pipelines.
  • Adds POLLU and 2D finite-difference regression tests plus a runtests.jl entrypoint.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
lib/OrdinaryDiffEqAMF/src/OrdinaryDiffEqAMF.jl New module wiring/exports for AMF functionality.
lib/OrdinaryDiffEqAMF/src/amf.jl Adds AMF wrapper that injects an AMF linear solver into Rosenbrock-W algorithms.
lib/OrdinaryDiffEqAMF/src/linsolve.jl Implements a LinearSolve algorithm intended to factorize operator-based W.
lib/OrdinaryDiffEqAMF/src/operators.jl Adds operator constructors and build_amf_function helper to set jac_prototype/W_prototype.
lib/OrdinaryDiffEqAMF/test/runtests.jl Test entrypoint including new regressions.
lib/OrdinaryDiffEqAMF/test/test_pollu.jl Regression test on POLLU stiff chemical kinetics model.
lib/OrdinaryDiffEqAMF/test/test_fd2d.jl Regression + validation tests for AMF split operators and custom factors.
lib/OrdinaryDiffEqAMF/Project.toml New package manifest for OrdinaryDiffEqAMF.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return SciMLBase.build_linear_solution(alg, y, nothing, cache)
end

LinearSolve.needs_concrete_A(::SciMLOpFactorization) = true
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

needs_concrete_A(::SciMLOpFactorization) = true will cause LinearSolve to concretize operator A into a matrix before solving. That contradicts the stated goal in AMF docs (avoid densifying W_prototype) and can lead to very large allocations/OOM for big Kronecker-style operators. Prefer setting this to false (and ensuring factorize/ldiv! operate on the SciMLOperator form), or if densification is actually required then update the AMF docstring/implementation to match that behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +131 to +132
actual_sparsity = isnothing(sparsity) ? convert(AbstractMatrix, J_op) : sparsity
return SciMLBase.ODEFunction(f!; jac_prototype = J_op, W_prototype = W_op, sparsity = actual_sparsity)
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

When sparsity is not provided, computing it via convert(AbstractMatrix, J_op) forces full materialization of the Jacobian operator into an N×N matrix. This can be prohibitively expensive and undermines the operator-based approach. Consider only passing the sparsity keyword when the caller supplies it, or using a cheap sparsity-pattern representation that doesn’t require concretizing J_op.

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +107
isnothing(jac_cache) && (jac_cache = zeros(N))
isnothing(w_cache) && (w_cache = zeros(N))

J_op = cache_operator(jac, jac_cache)
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The default caches zeros(N) appear inconsistent with how cache_operator is used elsewhere in this PR (tests allocate zeros(N^2) for cached N×N matrix-like operators). If cache_operator expects storage for the concretized operator (common for MatrixOperator/operator sums), zeros(N) will be undersized and can trigger bounds errors or incorrect caching during matrix materialization (e.g., for factorization/sparsity). Recommend sizing these defaults to zeros(N^2) (or zeros(N, N) depending on SciMLOperators’ expected cache shape), or using a SciMLOperators API that allocates an appropriately-sized cache automatically.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +15
[compat]
julia = "1"
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The [compat] section pins only julia. For a registered/consumable Julia package, it’s important to add compat bounds for direct deps (e.g., SciMLBase, SciMLOperators, LinearSolve, Reexport, OrdinaryDiffEqCore) to avoid resolver breakage and unintended upgrades. Please add appropriate version bounds based on the APIs you rely on.

Copilot uses AI. Check for mistakes.
@ChrisRackauckas ChrisRackauckas merged commit 2293fa7 into master Apr 9, 2026
81 of 90 checks passed
@ChrisRackauckas ChrisRackauckas deleted the u/amf branch April 9, 2026 15:52
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.

3 participants