Skip to content

Document direct operator-splitting developer interfaces - #108

Merged
ChrisRackauckas merged 3 commits into
SciML:mainfrom
ChrisRackauckas-Claude:agent/operator-splitting-direct-devdocs
Aug 5, 2026
Merged

Document direct operator-splitting developer interfaces#108
ChrisRackauckas merged 3 commits into
SciML:mainfrom
ChrisRackauckas-Claude:agent/operator-splitting-direct-devdocs

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

  • move developer-interface docstrings to their original generic definitions
  • split user-facing and solver-developer guidance, including extension rules and generic examples
  • add a test-only external operator-splitting solver that uses only the documented generic interfaces
  • reduce the strict-QA exception list to the names that genuinely have no public spelling

Strict QA

The bare run_qa(OrdinaryDiffEqOperatorSplitting) failed on five names, not one. They fall into two groups.

Fixed by accessing the owner. dotview and broadcastable are public in Base.Broadcast but not in Base, and src/config_tree.jl reached them through Base. All four broadcast overloads now qualify through Base.Broadcast, which drops both findings with no exception entry.

Genuinely non-public, so allowed. On Julia 1.12.6:

name Base Base.Broadcast
dotview
broadcastable
BroadcastStyle
materialize!
Broadcasted

materialize! and Broadcasted have no public spelling in either module and no alias, so an empty exception list is unreachable while TreeOption implements .=. They are allowed with the reason inline in test/qa/qa.jl. failfactor_default joins them until a registered OrdinaryDiffEqCore carries SciML/OrdinaryDiffEq.jl#4111 — that one is temporary.

Note that SciMLTesting #43/#44 do not affect any of this; they change the Aqua subprocess load path and the persistent_tasks allowance.

Verification

  • GROUP=Core Pkg.test() on Julia 1.12.6 — all groups pass (adaptivity 70, alias_u0 13, backward 35, callbacks 77, config_tree 140, consistency 27, convergence 90, failure_escalation 20, operator_splitting_api 1342, saving 122, sync 9)
  • test/qa/qa.jl on Julia 1.12.6 (21/21) and 1.10.11 LTS (19/19)
  • strict docs build on Julia 1.12
  • Runic clean on src, test, docs

Dependencies

Ignore until reviewed by @ChrisRackauckas.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Comment thread docs/src/devdocs/index.md Outdated
1. define `SciMLBase.isadaptive(::MyAlgorithm) = true`,
2. define [`OrdinaryDiffEqOperatorSplitting.alg_adaptive_order`](@ref), the order of
its error estimator, and
3. write the tolerance-scaled error estimate to `parent.EEst` at the end of

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No. This should be done with the new interface (set_EEst or so) which we recently added to OrdinaryDiffEqCore.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done in 050a1fb — the guidance, the code block, and the _perform_step! docstring now go through OrdinaryDiffEqCore.set_EEst!, with a note that it and get_EEst are the interface and the field location is an implementation detail.

Worth flagging that the package was already inconsistent with itself here: src/integrator.jl defines OrdinaryDiffEqCore.set_EEst!/get_EEst for the split integrator types and the controllers read the estimate through them, but the built-in PalindromicPairLieTrotterGodunov still assigned the field directly. Since the docs cite it as the complete example, I changed it too, plus a stale comment in integrator.jl describing the estimate as "written to the node's EEst".

I left the two direct writes in reinit_node_controller! alone — those are the implementation side of the hook writing the package's own field, so routing them through set_EEst! would just call back into the same assignment. Say the word if you'd rather they were uniform.

Verified locally on Julia 1.12.6: full Core group passes (adaptivity 70/70 covers the PPLTG estimate path), strict docs build exit 0, Runic clean.

`dotview` and `broadcastable` are public in `Base.Broadcast` but not in `Base`,
so accessing them through `Base` made strict QA flag them. Qualify all four
broadcast overloads through `Base.Broadcast`.

`materialize!` and the `Broadcasted` type it dispatches on have no public
spelling in either module and no alias, so they stay as documented QA
exceptions -- a bare `run_qa` cannot pass while `TreeOption` implements `.=`.
`failfactor_default` joins them until a registered OrdinaryDiffEqCore carries
SciML/OrdinaryDiffEq.jl#4111.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
The adaptive-algorithm guidance told extension authors to assign
`parent.EEst` directly, even though the package already defines
`OrdinaryDiffEqCore.set_EEst!`/`get_EEst` for its integrator types and the
controllers read the estimate through them. Route the documented interface,
its docstring, and the built-in PalindromicPairLieTrotterGodunov that the docs
cite as a complete example through `set_EEst!` instead, so the field location
stays an implementation detail.

The direct writes in `reinit_node_controller!` are left as they are: those are
the implementation side of the hook, on the package's own field.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review August 5, 2026 03:02
@ChrisRackauckas
ChrisRackauckas merged commit e069c53 into SciML:main Aug 5, 2026
10 checks passed
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.

4 participants