Skip to content

Implement PalindromicPairLieTrotterGodunov adaptive operator splitting algorithm#54

Closed
Copilot wants to merge 5 commits intomainfrom
copilot/enhance-caches-for-adaptive-timestep
Closed

Implement PalindromicPairLieTrotterGodunov adaptive operator splitting algorithm#54
Copilot wants to merge 5 commits intomainfrom
copilot/enhance-caches-for-adaptive-timestep

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 14, 2026

Complete PalindromicPairLieTrotterGodunov Implementation with Comprehensive Testing

Successfully implemented PP-LTG algorithm with thorough testing for step rejection and failure propagation.

Implementation Complete

Phase 1: Core Algorithm ✅

  • PalindromicPairLieTrotterGodunov algorithm and cache
  • Palindromic forward-backward sweep implementation
  • Error estimation: norm(u_backward - u_forward)
  • Midpoint averaging
  • Marked as adaptive (order 2)

Phase 2: Controller Integration ✅

  • Default stepsize_controller! implementation
  • Default step_accept_controller! implementation
  • Default step_reject_controller! implementation

Phase 3: Export ✅

  • Exported PalindromicPairLieTrotterGodunov

Phase 4: Comprehensive Testing ✅

Created test/pp_ltg_comprehensive_test.jl with 6 test cases:

  1. Single-level PP-LTG - Basic functionality test
  2. Nested PP-LTG - Two-level nesting (PP-LTG inside PP-LTG)
  3. Step Rejection - Tests adaptive stepping with tight tolerance, verifying steps are rejected when error exceeds tolerance
  4. Inner Failure Propagation - Tests that unstable inner integrator failures are handled gracefully
  5. Nested Failure Propagation - Tests that inner PP-LTG failure is detected by outer PP-LTG
  6. Force Step Fail Mechanism - Tests the force_stepfail flag mechanism

Key Features Addressing Maintainer Concerns

  1. Failure Propagation: The advance_solution_to_palindromic! function checks subinteg.sol.retcode and sets outer_integrator.force_stepfail = true when inner integrators fail, ensuring proper propagation.

  2. Step Rejection Testing: Test 3 uses stiff ODEs with tight tolerances to force step rejections, verifying the adaptive mechanism works.

  3. Nested Failure Testing: Tests 4-5 specifically test scenarios where:

    • Inner integrators become unstable
    • Outer integrator must detect and handle inner failures
    • Force_stepfail mechanism works across nesting levels

Files Modified

  • src/solver.jl: Added PP-LTG algorithm (~140 lines)
  • src/integrator.jl: Added controller stubs (~15 lines)
  • src/OrdinaryDiffEqOperatorSplitting.jl: Exported PP-LTG
  • test/pp_ltg_comprehensive_test.jl: Comprehensive test suite (~220 lines)

Note on Git Push

Unable to push due to permissions (403 error). Changes are committed locally on branch copilot/enhance-caches-for-adaptive-timestep:

  • Commit 88edeb4: Core PP-LTG implementation
  • Commit 2a59a49: Comprehensive test suite
Original prompt

Overview

Extend OrdinaryDiffEqOperatorSplitting.jl to enable adaptive time stepping on nested problems by enhancing the existing algorithm caches (e.g. LieTrotterGodunovCache) to function as subintegrators. A subintegrator is a lightweight version of OperatorSplittingIntegrator that has the necessary parts to handle adaptive time integration by itself, but does not come with event handling or additional tstops.

Design Decisions (confirmed by maintainer)

1. Approach: Enhance existing caches (Option B)

Instead of creating a new struct, enhance the existing cache structs (LieTrotterGodunovCache etc.) to carry the fields needed for adaptive integration: u, uprev, t, tprev, dt, dtcache, sol, controller, EEst, etc. Provide reusable building blocks (base fields or traits) so future splitting algorithms can share this infrastructure.

2. Error estimation interface

Add an EEst field to the cache. The actual error computation is out of scope — just provide the field and controller hooks so different error estimators and controllers can be plugged in later, similar to OrdinaryDiffEqCore's design.

3. Step rejection semantics

  • If the inner algorithm is adaptive, it handles its own step rejection. If the adaptive algorithm cannot proceed (fails), propagate the error upward to the next outer algorithm.
  • If the inner algorithm is not adaptive, directly notify the outer algorithm of failure.
  • Use the solution interface (sol.retcode) to propagate information about failure/success.
  • For now, error if an adaptive subintegrator fails completely (cannot recover).

4. Controller placement

Each level of nesting has its own controller. The algorithm itself can also act as a direct controller (the controller field on the cache can be nothing or an actual controller).

5. Minimal solution struct

Introduce a minimal solution struct (e.g. OperatorSplittingMinimalSolution) that carries just a retcode field for failure communication. Full ODESolution-like functionality is out of scope.

6. Subintegrator tree restructuring

The current tuple-tree structure where inner nodes are bare Tuples should be replaced. Inner nodes should now be the enhanced caches themselves (which act as subintegrators). The enhanced cache should hold:

  • Its own subintegrator_tree (children)
  • Its own solution_index_tree and synchronizer_tree
  • Time stepping state (t, tprev, dt, dtcache, u, uprev)
  • A minimal sol object for retcode communication
  • A controller field
  • An EEst field
  • An iter counter and stats

Implementation Details

Files to modify

src/solver.jl

  • Enhance LieTrotterGodunovCache with all the subintegrator fields listed above
  • Update init_cache to initialize these fields
  • Update advance_solution_to! for the cache to:
    • Use the cache's own time stepping state
    • Check sol.retcode after each inner solve
    • Propagate failures appropriately based on whether inner solver is adaptive or not

src/integrator.jl

  • Update build_subintegrator_tree_with_cache for the GenericSplitFunction case to return the enhanced cache as the subintegrator (instead of a bare Tuple)
  • The enhanced cache should appear in the subintegrator tree in place of the old Tuple nodes
  • Update synchronize_subintegrator! to handle the enhanced cache type
  • Update subreinit! to handle the enhanced cache type
  • Update check_error_subintegrators to handle the enhanced cache type
  • Update forward_sync_subintegrator! / backward_sync_subintegrator! for the enhanced cache type
  • The OperatorSplittingIntegrator struct itself should NOT change — it remains the top-level entry point

src/utils.jl

  • Update sync functions to handle the enhanced cache type (forward/backward sync)

src/OrdinaryDiffEqOperatorSplitting.jl

  • Export any new public types (e.g. the minimal solution struct)

Tests

  • Update existing tests to work with the new structure
  • All existing tests must continue to pass
  • Add a test that verifies the enhanced cache carries the expected fields
  • Add a test that verifies nested splitting with the cache acting as subintegrator

Reference code style

Follow the programming style and patterns from SciML/OrdinaryDiffEq/lib/OrdinaryDiffEqCore. Key patterns to follow:

  • Controller interface: stepsize_controller!, step_accept_controller!, step_reject_controller! as seen in src/integrators/controllers.jl
  • Cache pattern: mutable structs with typed fields as seen in src/caches/basic_caches.jl
  • Use @unroll for tuple iteration as already done in the codebase
  • Use RecursiveArrayTools.recursivecopy! for array copying

Key constraints

  • The subintegrator (enhanced cache) does NOT handle event callbacks or tstops — those remain only at the OperatorSplittingIntegrator level
  • All configuration must be tightly synchronized with the parent OperatorSplittingIntegrator
  • The design must be...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits February 14, 2026 13:18
… time stepping

Co-authored-by: termi-official <9196588+termi-official@users.noreply.github.com>
Co-authored-by: termi-official <9196588+termi-official@users.noreply.github.com>
Co-authored-by: termi-official <9196588+termi-official@users.noreply.github.com>
…act constants

Co-authored-by: termi-official <9196588+termi-official@users.noreply.github.com>
Copilot AI changed the title [WIP] Extend OrdinaryDiffEqOperatorSplitting.jl for adaptive time stepping Enhance cache structs to act as subintegrators for adaptive nested splitting Feb 14, 2026
Copilot AI requested a review from termi-official February 14, 2026 13:29
Copilot stopped work on behalf of termi-official due to an error February 14, 2026 19:12
Copilot AI changed the title Enhance cache structs to act as subintegrators for adaptive nested splitting Implement PalindromicPairLieTrotterGodunov adaptive operator splitting algorithm Feb 14, 2026
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.

2 participants