Skip to content

src: add periodicorbit/Collocation.jl to test new BVP interface in PO…#329

Open
rveltz wants to merge 14 commits into
masterfrom
328-use-bvp-interface-to-encode-periodic-orbits
Open

src: add periodicorbit/Collocation.jl to test new BVP interface in PO…#329
rveltz wants to merge 14 commits into
masterfrom
328-use-bvp-interface-to-encode-periodic-orbits

Conversation

@rveltz

@rveltz rveltz commented Jun 29, 2026

Copy link
Copy Markdown
Member

close #328

@rveltz rveltz linked an issue Jun 29, 2026 that may be closed by this pull request
12 tasks
rveltz and others added 13 commits June 29, 2026 14:03
…hase conditions

- Extract phase condition structures into `src/bvp/Sections.jl` with `AbstractSection`.
- Implement `SectionSS`, `SectionTrapeze`, and `SectionCollocation` to encapsulate phase condition data (normals, centers, ϕ, xπ, ∂ϕ) and their respective `update!` methods.
- Refactor `Shooting`, `Trapeze`, and `Collocation` structs in `periodicorbit` to use the new section fields rather than raw vectors.
- Move generic vector `_duplicate` utility to `src/periodicorbit/Sections.jl` specifically for `SectionPS` and `NormalForms` usage, removing the mathematically incorrect duplication for Standard Shooting.
- Fix `LA.dot` scope issue in `PeriodicOrbitTrapeze.jl` for GPU compatibility.
- Ensure type stability in `DiscretizedPO` type aliases with explicit `where {Tf, 𝒯}` bounds in `Collocation.jl`.
- Add default values to `Shooting` discretizer fields (`M=1`, `alg=nothing`, `parallel=false`).
- Update all associated periodic orbit tests to reflect the new BVP interfaces.
…d accessors

- Add `(sect::SectionTrapeze)(u)` and `(sect::SectionTrapeze)(u, T)` functors to
  match the `SectionSS` design and respect the generic `AbstractSection` interface.
- Implement explicit getter functions across all section types:
  - `SectionSS` (`get_normal`, `get_center`)
  - `SectionTrapeze` (`get_ϕ`, `get_xπ`)
  - `SectionCollocation` (`get_ϕ`, `get_∂ϕ`)
  - `SectionPS` (`get_normals`, `get_centers`, `get_normals_bar`, `get_centers_bar`)
- Update `PeriodicOrbitTrapeze.jl` to evaluate phase conditions and its Jacobian
  using the new `SectionTrapeze` functor rather than explicit dot products.
- Refactor `PeriodicOrbitTrapeze.jl` to use `get_ϕ` accessors, storing them in
  local variables for improved code readability and robustness.
…tructure**

This commit transitions the `Collocation` methods for periodic orbits away from the monolithic legacy implementation towards the new, modular `DiscretizedBVP` and `DiscretizedPO` infrastructure. It establishes a solid and highly optimized foundation for the BVP solver before implementing analytical Jacobians.

**Key Changes:**
* **Optimized BVP Residual:** Implemented `__bvp_residual_collocation` in `src/bvp/collocation/residual.jl`. The new inner loop avoids memory allocations when evaluating the vector field `model.F(u, p)` by using pre-allocated buffers from `cache.coll_cache.tmp`.
* **Removed `po_coll` Dependencies:** Fully decoupled the mesh adaptation and continuation logic in `src/bvp/BVPBifProblem.jl` from the legacy `po_coll` object. All operations (including `_compute_error!` and `__interpolate_posolution`) now rely strictly on the new `mesh_cache`.
* **Phase Condition Updates:** Wired the phase condition updates (`updatesection!`) into the new architecture. The underlying math (`ϕ`, `∂ϕ`, and `∇phase` updates) is cleanly isolated in `src/bvp/collocation/section.jl` and properly called during the continuation loop in `__update_bvp_coll!`.
* **Legacy Code Preservation:** Restored the legacy `CollocationDisc` methods (`po_residual`, `po_jacobian`, and utility getters) as commented-out reference code in `src/periodicorbit/Collocation.jl` to document the transition and preserve the old mathematical logic.
* **Testing:** Validated the new architecture against `stuartLandauCollocationDisc.jl` using `AutoDiffDense`.

**Next Steps:**
- Re-implement exact dense and sparse analytical Jacobians for `Collocation`.
- Port the numerical integration function (`∫`) to use `mesh_cache`.
… Orbits

This commit fixes critical bugs in the continuation loop and mesh adaptation for DiscretizedPO that were introduced during the transition to the new BVP infrastructure.

Key Changes:

Fixed Phase Condition Updates: The updatesection! function was failing to trigger during continuation because __update_bvp_coll! only accepted a DiscretizedBVP. We extended its signature to Union{DiscretizedBVP, DiscretizedPO} and added specific BK.update! overloads for BVPBifProblem{<:DiscretizedPO}. This ensures the DiscretizedPO wrapper is passed down, allowing updatesection!(::DiscretizedPO) to properly dispatch and update ϕ and ∂ϕ.
Fixed Cache Access Errors: Replaced direct field accesses like d_bvp.cache.mesh_cache (which caused a FieldError for DiscretizedPO) with the generic getter get_cache(d_bvp).mesh_cache in __update_bvp_coll!. This guarantees compatibility regardless of whether the underlying object is a pure BVP or a Periodic Orbit.
Cleaned up save_solution: Fixed save_solution for pure DiscretizedBVPs which erroneously still referenced the legacy po_coll object. It now correctly relies on get_cache(bvp).mesh_cache and correctly returns nothing for the phase condition, as expected for pure BVPs.
…legacy issues

- Fix state extraction in `bvp_jacobian_dense!`: replace hardcoded `u[1:end-1]` (period stripping) with generic `_bvp_coll_get_Xm` and `_bvp_coll_get_T` accessors to support both `DiscretizedBVP` and `DiscretizedPO` seamlessly.
- Refactor internal jacobian API: `bvp_jacobian_dense!` and `bvp_jacobian_sparse_blocks!` now accept a pure `BifFunction` instead of the whole `BifurcationProblem` wrapper, making the codebase cleaner and preventing side-effect programming.
- Fix `BifurcationProblem` construction in `jacobian.jl` to use `lens=1` instead of `nothing`, preventing `AssertionError` crashes during problem instantiation.
- Fix spurious `BK.` module prefixes for `meshadapt` and `get_times` inside `BVPBifProblem.jl` and `DiscretizedBVP.jl` which broke BVP saving.

This successfully restores full BVP collocation continuation tests (`test/bvp/bratu_collocation.jl`).
…ation and address review feedback

This commit introduces the full suite of analytical Jacobians (dense, sparse blocks, and sparse in-place) for the generic `DiscretizedBVP` and `DiscretizedPO` collocation API, while also incorporating recent code review feedback.

Key changes:
- **Jacobian Implementations**:
  - Added `bvp_jacobian_dense!` for analytical dense Jacobian evaluation.
  - Added `bvp_jacobian_sparse_blocks!` for out-of-place sparse block generation.
  - Added `bvp_jacobian_sparse_inplace!` for highly optimized, zero-allocation updates directly modifying the underlying `nzval` of `SparseMatrixCSC`.
- **Sparse Indexing Fix**: Fixed `get_blocks` in `Collocation.jl` to correctly map block indices to `nzval` memory offsets using `findnz`, resolving `MethodError` and `Float64` invalid index crashes during in-place updates.
- **API Cleanups**:
  - Removed `Reexport.@reexport using .BVP` in `BifurcationKit.jl` in favor of explicit `export` declarations for better namespace control.
  - Introduced the `get_mesh_cache` accessor in `DiscretizedBVP.jl` and replaced direct `.mesh_cache` property accesses across `BVPBifProblem.jl`.
- **Type Stability for AD**: Removed hardcoded `Float64` allocations (`zeros(0)` and `[1.0]`) when instantiating local `BifurcationProblem`s inside `jacobian.jl`. Replaced with generic `T = eltype(u)` to ensure type-stability and proper support for ForwardDiff Dual numbers.

Tests (including `stuartLandauCollocationDisc.jl`) run successfully with the new generic API.
…dPO interface

This commit introduces a parallel implementation of the Condensation of
Parameters (COP) linear solver that operates entirely on the new BVP
architecture (DiscretizedPO).

Changes included:
- Renamed `src/periodicorbit/cop.jl` to `cop_legacy.jl` to preserve the
  legacy functionality untouched.
- Implemented a new `src/periodicorbit/cop.jl` leveraging the standardized
  BVP getters (`BVP.get_coll_cache`, `BVP.state_dimension`, etc.) instead
  of directly accessing fields from the legacy `Collocation` struct.
- Refactored `COPCACHE` and `COPBLS` structs to use outer constructors
  instead of inner constructors, adhering to standard Julia practices and
  allowing easier generic instantiation.
- Added a comparative test suite (`cop_new_vs_legacy.jl`) confirming that
  the new implementation provides exact numerical matches for dim=0, 1, 2
  and performs similarly or slightly faster (less GC overhead).

WARNING:
The new COP solver is currently restricted to `DiscretizedPO` (Periodic Orbits)
rather than any generic `DiscretizedBVP`. This is because the underlying COP
algorithm currently hardcodes Periodic Boundary Conditions (injecting `In`
and `-In` identity blocks) and explicitly assumes the period `T` is part of
the external unknowns. Further refactoring is required to generalize this
solver to arbitrary Boundary Value Problems.
…izers

This commit cleans up the internal BVP mechanics by strictly enforcing
the use of getters, removing direct field accesses and hardcoded shape
assumptions across all discretization schemes.

Changes included:
- Replaced all hardcoded `reshape(@view(X[...]), n, M)` calls in `Shooting`,
  `Trapeze`, and `Collocation` residuals/jacobians with a unified
  `get_time_slices(d_bvp, X)` interface.
- Updated `get_time_slices` to safely extract only the time-domain state
  variables, automatically ignoring trailing parameters (such as the
  period `T`).
- Forwarded `get_time_interval` correctly from `DiscretizedPO` and
  `DiscretizedBVP` down to the `BVPModel`.
- Replaced direct struct field accesses (like `bvp.discretizer.M` or
  `disc.Ntst`) in BVP integration and residual routines with the standard
  getters (`mesh_size`, `get_ntst`, `get_m`).
- Added `get_ntst` and `get_m` accessors for the `Collocation` discretizer
  in `Discretizers.jl`.
Replace hardcoded BK.update! specializations on BVPBifProblem{<:DiscretizedPO}
with a clean singleton-based dispatch mechanism.

- Add `struct UpdateFunctionForPOFunctional end` as a callable singleton
  with methods for standard and codim-2 continuation
- Fix `BK.update!` delegation to forward `prob` as first argument to the
  stored callable (was missing, making the singleton pattern impossible)
- Add `POBifProblem` convenience constructor that wraps `BVPBifProblem`
  with `update! = UpdateFunctionForPOFunctional()`
- Remove 4 hardcoded `BK.update!` methods on `DiscretizedPO` collocation
- Clean up: remove dead code, unused `oldmesh` variable, redundant alias
- Export `POBifProblem` and `UpdateFunctionForPOFunctional` from `BVP` module
  and top-level `BifurcationKit`; fix double export of `BVPBifProblem`
- Add end-to-end tests for `POBifProblem` (residual + PALC continuation)
- Fix missing `_test_sorted` helper in `stuartLandauTrap.jl` test file

All 4341 tests pass.
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.

Use BVP interface to encode periodic orbits

2 participants