Hi everyone,
I’m working on simulating cyclic adsorption processes (TVSA / PSA-type) using VoronoiFVM.jl, which I use to semi-discretize a set of PDEs in space. The resulting system of ODEs (or DAEs) is integrated over time to simulate column dynamics such as direct breakthrough or full cyclic steady-state operation.
I’m now interested in differentiating through this time-dependent PDE system to compute gradients of scalar performance metrics (e.g. total CO₂ outflow over a cycle) with respect to model hyperparameters such as inlet velocity (u_feed
), feed temperature, outlet pressure, etc.
I understand that SciMLSensitivity.jl provides efficient adjoint and reverse-mode sensitivity algorithms for computing gradients of scalar outputs with respect to parameters in ODE/DAE systems.
My questions are:
- Is it possible to use reverse-mode automatic differentiation through a VoronoiFVM.jl simulation to compute gradients of integrals of the PDE solution with respect to such parameters?
- What is the recommended way to structure this?
Here is a minimal sketch of what I’m doing
using VoronoiFVM, DifferentialEquations
function column_model(; u_feed, T_feed, P_out)
# PDE setup ...
data = (params = (; u_feed=u_feed, T_feed=T_feed, P_out=P_out), )
sys = VoronoiFVM.System(grid;
storage, flux, reaction, source, bcondition, boutflow,
data, outflowboundaries=[data.Γ_in, data.Γ_out])
problem = ODEProblem(sys, inival, (0, duration))
sol = solve(problem, FBDF(); kwargs...)
return sol, sys
end
# Example target quantity: total outlet concentration
function performance_metric(u_feed, T_feed, P_out)
sol, sys = column_model(; u_feed, T_feed, P_out)
tf = TestFunctionFactory(sys)
T = testfunction(tf, [1], [2])
outflow = integrate(sys, T, sol; rate=false)
total_outflow = - trapz(outflow.t, reduce(hcat, outflow.u)')
return total_outflow[data.ic_CO2]
end
When I attempt to use reverse-mode AD via SciMLSensitivity.jl, I get the following error:
ERROR: `p` is not a SciMLStructure. This is required for adjoint sensitivity analysis.
For more information, see the documentation on SciMLStructures.jl for the definition
of the SciMLStructures interface. In particular, adjoint sensitivities only apply to `Tunable`.
As I understand it, the current SciMLSensitivity interface expects parameters to be passed as a parameter vector p
threaded into the ODEProblem.
However, in my case, the parameters enter through data.params
in the VoronoiFVM setup, not as a flat vector p
.
For context, the ultimate goal is to enable gradient-based optimization of cyclic adsorption processes, where each cycle involves solving the PDE system multiple times under varying boundary conditions.
Any guidance on how to make this setup AD-compatible would be greatly appreciated!