Skip to content

refactor: migrate ODE and interpolation core to odelia#456

Open
dfalster wants to merge 12 commits intodevelopfrom
odelia
Open

refactor: migrate ODE and interpolation core to odelia#456
dfalster wants to merge 12 commits intodevelopfrom
odelia

Conversation

@dfalster
Copy link
Copy Markdown
Member

@dfalster dfalster commented Mar 5, 2026

The core ode stepping machinery from plant has been spun out into a standalone package. This PR tests ability to support plant.

  • add odelia as a dependency DESCRIPTION, remotes/imports/linking)
  • replace internal ODE/interpolator implementations with odelia equivalents
  • regenerate Rcpp/R6 bindings for new types (std::vector, odelia::*)
  • remove legacy solver/interpolator code (inst/include/plant/ode_solver/, interpolator., tk_spline.*, old test helpers)
  • adjust tests and docs to match new solver/interpolator behavior (including deterministic stochastic patch insertion

Some issues to resolve

  • Needed to introduce compatibility wrappers (ode_solver_r6.h, ode_solver_compat.h) and update solver usage across core headers/source [Why is this needed, can it be avoided]
  • Mutant tests are causing a memory explosion, skipped for now, but needs attention

dfalster added 6 commits March 5, 2026 17:43
- Deleted obsolete ODE control header and implementation files.
- Removed ODE interface and related utility functions to streamline the ODE solver.
- Eliminated ODE runner and step classes to simplify the integration process.
- Updated references in patch, resource_spline, scm, species, and stochastic_species headers to use new ODE interface.
- Removed tests related to ODE control and Lorenz system integration.
…e Rcpp bindings

- switch ODE-facing C++ types and interfaces from legacy plant::ode symbols to odelia::ode equivalents across core model classes
- add solver compatibility wrappers in:
  - inst/include/plant/ode_solver_compat.h
  - inst/include/plant/ode_solver_r6.h
- introduce/standardize SolverR6 usage for RcppR6-generated OdeRunner bindings to keep generated code compatible with current solver API
- update YAML generator config (inst/RcppR6_classes.yml) to use concrete std::vector<double> state types and odelia::ode control/state helpers
- regenerate Rcpp outputs (R/RcppExports.R, R/RcppR6.R, src/RcppExports.cpp, src/RcppR6.cpp, RcppR6 pre/post headers)
- update individual/stochastic runner helpers and scaffold templates to match new solver types and accessors
- adjust docs/vignette references to reflect odelia::ode::Solver naming
- verify clean regeneration and build with `make clean RcppR6 all`
- switch SCM and StochasticPatchRunner to `solver.set_state_from_system()` after
  mutating system state, avoiding unnecessary solver resets
- make stochastic patch test deterministic by replacing probabilistic
  `introduce_new_node(1)` with `introduce_new_node_and_update(1)`

This removes flaky failures in `test-stochastic-patch.R` and keeps solver state
synchronization consistent after node introduction/death updates.
@dfalster dfalster requested a review from aornugent March 5, 2026 22:50
dfalster added 2 commits March 6, 2026 15:16
- replace plant::ode::SolverR6 usages with odelia::ode::Solver in Rcpp bindings and generated headers
- adapt wrapper calls to odelia API (advance_adaptive({t0,t1}), advance_fixed({t0,t1}), get_system())
- update inst/RcppR6_classes.yml OdeRunner mapping to native odelia solver
- remove unused shim headers:
  - inst/include/plant/ode_solver_r6.h
  - inst/include/plant/ode_solver_compat.h
- disable solver history collection in performance-critical paths:
  - SCM constructor
  - StochasticPatchRunner constructor
  - OdeRunner constructors in src/RcppR6.cpp
@dfalster
Copy link
Copy Markdown
Member Author

dfalster commented Mar 6, 2026

Mutants running and tests passing, but 1.5x original time. Have been investigating why but no answers yet

dfalster added 3 commits March 6, 2026 21:12
- turn off save_RK45_cache when using build_schedule
- Refactor `SCM::run_next()` into `run_next_impl(sync_patch)` to avoid unnecessary
  patch copies during internal run loops
- Keep solver-owned system (`solver.get_system_ref()`) as the hot-path state and
  only sync back to `patch` when needed
- Update `SCM::run()` history collection to use solver state and sync `patch` once
  at the end
- Return SCM time from `solver.time()` for consistent source-of-truth timing
- Tighten `SCM::reset()` synchronization to keep `patch` and solver state aligned
- Apply the same solver-ref pattern in `StochasticPatchRunner` to reduce copy
  churn around node introduction and adaptive advancement

These changes preserve public behavior while reducing state copy overhead in
frequently executed integration paths.
@dfalster
Copy link
Copy Markdown
Member Author

dfalster commented Mar 6, 2026

Speeds now resolved!

@dfalster dfalster marked this pull request as ready for review March 6, 2026 10:25
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.

1 participant