Skip to content

Conversation

@ChrisRackauckas-Claude
Copy link
Contributor

Summary

This PR implements callback and event support for OperatorSplittingIntegrator, addressing issue #36.

  • Add full support for discrete callbacks at the outer integrator level
  • Add simplified support for continuous callbacks (endpoint-only checking)
  • Implement proper u_modified! tracking for solution modifications
  • Add savevalues! function for callback-triggered saves
  • Add comprehensive test suite for callback functionality

Design Decisions

As discussed in issue #36, there are two main challenges for callbacks in operator splitting:

  1. Which integrator triggers which callback: We handle callbacks ONLY at the outer integrator level, AFTER all subproblems are solved for a timestep. This ensures callbacks have access to the full solution state.

  2. Visibility of unknowns: By processing callbacks at the outer integrator level, callbacks can see the full solution u, not just partial views that individual subintegrators work with.

For continuous callbacks, full root-finding across split subproblems is not well-defined, so we use simplified endpoint checking (detect sign changes between tprev and t). Users requiring precise event timing should use smaller timesteps or ensure their callback conditions align with the timestep boundaries.

Test plan

  • Discrete callback with simple condition - triggers correctly
  • Discrete callback that modifies u - modification propagates correctly
  • Discrete callback with save_positions - saves work correctly
  • Multiple discrete callbacks - all callbacks execute
  • Continuous callback zero-crossing detection - basic detection works
  • Continuous callback with reflection - affect function executes
  • Callbacks with nested splitting - works with recursive structures
  • u_modified! functionality - flag is properly set/cleared
  • Callback preserves solution accuracy - no-op callback doesn't change solution

All tests pass locally.

cc @ChrisRackauckas

🤖 Generated with Claude Code

This implements callback support for OperatorSplittingIntegrator, addressing issue SciML#36.

Key changes:
- Add savevalues! function to save solution values during callback execution
- Add handle_callbacks! function to process callbacks after each step
- Add apply_discrete_callback! for full discrete callback support
- Add apply_continuous_callback_simple! for simplified continuous callbacks
  (endpoint-only checking without full root-finding)
- Modify __step! to call handle_callbacks! after advancing the solution
- Implement proper u_modified! to track when callbacks modify the solution
- Add comprehensive test suite for callback functionality

Design decisions:
- Callbacks are handled at the outer integrator level only, after all
  subproblems are solved for a timestep. This ensures callbacks have
  access to the full solution state.
- Continuous callbacks use simplified endpoint checking rather than
  full root-finding, as root-finding across split subproblems is not
  well-defined for operator splitting methods.
- When u is modified by a callback, it is propagated to uprev so the
  next step starts correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
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