Use Enzyme in ipopt rather than FiniteDiff#20
Merged
Conversation
# Conflicts: # Project.toml # examples/budgerigar.jl # src/endotherm/thermoregulation/ipopt.jl # src/endotherm/thermoregulation/rulebased.jl
Caller-side updates for upstream renames: generated_heat_flow → metabolic_heat_flow, per-side insulation_depth/conductivity moved under .dorsal/.ventral, shape_b → axis_ratio_b, respiration_mass → respiration_mass_flow. Adds `smoothing` field on IPOPTControl (default SmoothBound(1e-5)) threaded into nlp_pack so AD sees differentiable kinks.
mrke
approved these changes
May 11, 2026
| generated_heat_flow_ipopt, skin_temperature_ipopt, insulation_temperature_ipopt) | ||
|
|
||
| generated_heat_flow_ipopt = out.energy_flows.generated_heat_flow | ||
| generated_heat_flow_ipopt = out.energy_flows.metabolic_heat_flow |
Member
Author
There was a problem hiding this comment.
how come? why would it change?
| called at runtime when L-BFGS is active. | ||
| **Differentiation strategy.** Gradients and constraint Jacobians are computed via | ||
| [`Enzyme.jl`](https://github.com/EnzymeAD/Enzyme.jl): reverse-mode for the scalar objective | ||
| gradient and forward-mode for the constraint Jacobian. The `hess` and `cons_h` callbacks |
Contributor
There was a problem hiding this comment.
can delete this last caveat - it's repeated below in the limitations
| # of `p` doesn't compose with Unitful values. | ||
| # hess! and cons_h! are registered (required by IpoptOptimizer) but not | ||
| # called at runtime when hessian_approximation="limited-memory" is set. | ||
| function grad_fn!(g, x, _) |
Contributor
There was a problem hiding this comment.
we should go for expressive names in this IPOPT code too
Member
Author
There was a problem hiding this comment.
Yeah, all of these functions likely need to be deleted later on
Contributor
|
Would be good to keep finite diff as an option, at least initially to compare performance |
|
@rafaqz anything I can do for better unit support in DI? |
rafaqz
commented
May 11, 2026
rafaqz
added a commit
that referenced
this pull request
Jun 21, 2026
* initial implementation of IPOPT - slow but works * speed up IPOPT, add weighting factors for user specification of thermoregulatory strategy, update budgerigar plots * faster setup and better names for IPOPT approach, plus updated plots for budgie comparison Co-authored-by: Copilot <copilot@github.com> * remove generated heat flow as an effector, add optional core-skin temperature gradient based constraint, implement q10 effect * add document on IPOPT, remove warm-start strategy from budgie * update Project.toml * update Project.toml * update Project.toml * update Project.toml * Better names (#15) * update names for endotherm related code * better names for ectotherm thermoregulation code * update Project.toml --------- Co-authored-by: Rafael Schouten <rafaelschouten@gmail.com> * refactor thermoregulate * bugfix shape_b * Update IPOPT implementation to new HeatExchange names and NLP hook (#19) * update to new names and NLP hooks * update to IPOPT code to allow MultiSidedNLP (dorso/ventral-specific calculations) to work, plus naming consistency updates and docs update * update Project.toml * Use Enzyme in ipopt rather than FiniteDiff (#20) * working Enzyme # Conflicts: # Project.toml # examples/budgerigar.jl # src/endotherm/thermoregulation/ipopt.jl # src/endotherm/thermoregulation/rulebased.jl * Track HeatExchange API renames and add smoothing kwarg to IPOPTControl Caller-side updates for upstream renames: generated_heat_flow → metabolic_heat_flow, per-side insulation_depth/conductivity moved under .dorsal/.ventral, shape_b → axis_ratio_b, respiration_mass → respiration_mass_flow. Adds `smoothing` field on IPOPTControl (default SmoothBound(1e-5)) threaded into nlp_pack so AD sees differentiable kinks. * cleanup and deps * more cleanup * Apply suggestion from @rafaqz * aspect_ratio to axis_ratio (#23) * aspect_ratio to axis_ratio * update HeatExchange.jl branch in Project.toml * change HeatExchange.jl version in Project.toml * use fluid=Air(), convert remaining cases of aspect_ratio* in example_variables_and_parameters, revert HeatExchange.jl version to main * fix fluid specification in endotherm test script * Move example heat exchange pars to HeatExchange.jl (#21) * remove HeatExchange.jl parameter and variable examples (now live in HeatExchange.jl as per issue #4) * update HeatExchange.jl branch --------- Co-authored-by: Rafael Schouten <rafaelschouten@gmail.com> * Reverse mode and exact hessians (#22) * bugfix number type instability with Dual * Switch IPOPT backend to direct Ipopt.jl and export solver cache - Drop Optimization.jl / OptimizationIpopt.jl / SciMLBase in favour of the direct Ipopt.jl C interface. Gives access to the primal+dual warm-start API (IpoptProblem.x / mult_g) that the SciMLBase wrappers do not expose, so consecutive solves at similar parameter settings reuse the previous solution as the new initial guess. - Export IPOPTSolverCache so callers can construct the cache once and pass it across sweeps. - ipopt.jl rewritten end-to-end: cached buffers for primals, duals, bounds, constraint values, and Enzyme.forward-over-reverse Hessian (replaces FiniteDiff). - Adopt HeatExchange Air/Water Fluid singletons in examples and test data: example_environment_pars defaults to Air(); endotherm test now maps the FLTYPE input flag to Water()/Air(). - Add bench_ipopt_sweep.jl and hessian_validation.jl examples for benchmarking warm-start speedup and Hessian correctness. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * cleanup * better multiple dispatch * more dispatch simplifications * Expand abbreviated names and make IPOPTSolverCache immutable Spell out short identifiers in the IPOPT thermoregulation code: lb/ub/u0, lcons/ucons, metab_pars/int_cond/evap_pars/opt_pars/nlp_pars, M/sT/iT init shorthand, jac_*/hess_*/lag_* AD buffers, eval_f/eval_g/eval_grad_f/ eval_jac_g/eval_h closures, and the corresponding type parameters. Drop the mutable-struct on IPOPTSolverCache: the only mutating field was the warm-start flag, now stored as Base.RefValue{Bool}. * Pipe init NamedTuple through thermoregulate; turn IPOPT callbacks into functors - `thermoregulate` and `IPOPTSolverCache` take a single `init` NamedTuple (`metabolic_heat_flow`, `skin_temperature`, `insulation_temperature`) instead of three loose positional args, threaded through the rule-based loop, IPOPT builder, `_inputs!`, and `_refresh!`. - Rename `_IPOPTState` to `IPOPTParameters` and its instance field to `ipopt_parameters` — what it holds is per-solve problem parameters, not optimizer state. The mutable cell is just so the callbacks can be reused across solves. - Replace the anonymous Ipopt callback closures with six named functor structs (`EvaluateObjective`, `EvaluateConstraints`, `EvaluateObjectiveGradient`, `EvaluateConstraintJacobian`, `EvaluateHessian`, `LagrangianGradient`), all subtypes of `Function` so `Ipopt.IpoptProblem`'s typed callback fields accept them. - Collapse `_build_cache` into two layered `IPOPTSolverCache` constructors and factor out `_problem_size` / `_constraint_bounds` so the strategy-specific dimensions live in one place. - Deduplicate `_inputs!`: one shared body computes all scalars and parameter NamedTuples; the strategy-specific index layout is delegated to a small `_write_layout!` dispatched on packed type. - Drop the `effectors[i]` magic numbers in `_objective_value` — name only the variables each method actually uses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * update ipopt doc, including background on the method, and add a rulebased doc * cleanup with templates * no branch for HeatExchange * dont specify LinearAlgebra version * use fibrous not fur --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: mrke <mrke@unimelb.edu.au> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Rafael Schouten <rafaelschouten@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Still has a few hacky approaches skipping around DifferentiationInterface because of units.
We need to extract the unit stripping code from debtool into a shared package to clean this up.