Skip to content

Commit 8163809

Browse files
committed
Fix keyword argument handling for SteadyStateODESolver
1 parent 15954c9 commit 8163809

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)
99

1010
- Add support of `QobjEvo` for `steadystate` (ODE solver only). ([#536])
11+
- Fix keyword argument handling for `SteadyStateODESolver`. ([#537])
1112

1213
## [v0.34.1]
1314
Release date: 2025-08-23
@@ -304,3 +305,4 @@ Release date: 2024-11-13
304305
[#520]: https://github.com/qutip/QuantumToolbox.jl/issues/520
305306
[#531]: https://github.com/qutip/QuantumToolbox.jl/issues/531
306307
[#536]: https://github.com/qutip/QuantumToolbox.jl/issues/536
308+
[#537]: https://github.com/qutip/QuantumToolbox.jl/issues/537

src/steadystate.jl

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ end
4747
alg = Tsit5(),
4848
ψ0 = nothing,
4949
tmax = Inf,
50-
)
51-
52-
An ordinary differential equation (ODE) solver for solving [`steadystate`](@ref).
50+
terminate_reltol = 1e-5,
51+
terminate_abstol = 1e-7
52+
)
5353
54-
Solve the stationary state based on time evolution (ordinary differential equations; `OrdinaryDiffEq.jl`) with a given initial state.
54+
An ordinary differential equation (ODE) solver for solving [`steadystate`](@ref). It solves the stationary state based on [`mesolve`](@ref) with a termination condition.
5555
5656
The termination condition of the stationary state ``|\rho\rangle\rangle`` is that either the following condition is `true`:
5757
@@ -69,14 +69,21 @@ or
6969
- `alg::OrdinaryDiffEqAlgorithm=Tsit5()`: The algorithm to solve the ODE.
7070
- `ψ0::Union{Nothing,QuantumObject}=nothing`: The initial state of the system. If not specified, a random pure state will be generated.
7171
- `tmax::Real=Inf`: The final time step for the steady state problem.
72+
- `terminate_reltol` = The relative tolerance for stationary state terminate condition. Default to `1e-5`.
73+
- `terminate_abstol` = The absolute tolerance for stationary state terminate condition. Default to `1e-7`.
74+
75+
!!! warning "Tolerances for terminate condition"
76+
The terminate condition tolerances `terminate_reltol` and `terminate_abstol` should be larger than `reltol` and `abstol` of [`mesolve`](@ref), respectively.
7277
73-
For more details about the solvers, please refer to [`OrdinaryDiffEq.jl`](https://docs.sciml.ai/OrdinaryDiffEq/stable/).
78+
For more details about the solving `alg`orithms, please refer to [`OrdinaryDiffEq.jl`](https://docs.sciml.ai/OrdinaryDiffEq/stable/).
7479
"""
7580
Base.@kwdef struct SteadyStateODESolver{MT<:OrdinaryDiffEqAlgorithm,ST<:Union{Nothing,QuantumObject},T<:Real} <:
7681
SteadyStateSolver
7782
alg::MT = Tsit5()
7883
ψ0::ST = nothing
7984
tmax::T = Inf
85+
terminate_reltol::Real = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol
86+
terminate_abstol::Real = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol
8087
end
8188

8289
@doc raw"""
@@ -200,27 +207,25 @@ function _steadystate(L::QuantumObject{SuperOperator}, solver::SteadyStateDirect
200207
end
201208

202209
function _steadystate(L::AbstractQuantumObject{SuperOperator}, solver::SteadyStateODESolver; kwargs...)
203-
tmax = solver.tmax
204-
205210
ψ0 = isnothing(solver.ψ0) ? rand_ket(L.dimensions) : solver.ψ0
206-
abstol = haskey(kwargs, :abstol) ? kwargs[:abstol] : DEFAULT_ODE_SOLVER_OPTIONS.abstol
207-
reltol = haskey(kwargs, :reltol) ? kwargs[:reltol] : DEFAULT_ODE_SOLVER_OPTIONS.reltol
208-
209211
ftype = _float_type(ψ0)
210-
_terminate_func = SteadyStateODECondition(similar(mat2vec(ket2dm(ψ0)).data))
211-
cb = TerminateSteadyState(abstol, reltol, _terminate_func)
212-
sol = mesolve(
213-
L,
214-
ψ0,
215-
[ftype(0), ftype(tmax)];
216-
alg = solver.alg,
217-
progress_bar = Val(false),
218-
save_everystep = false,
219-
saveat = ftype[],
220-
callback = cb,
221-
kwargs...,
212+
tlist = [ftype(0), ftype(solver.tmax)]
213+
214+
# overwrite some kwargs and throw warning message to tell the users that we are ignoring these settings
215+
haskey(kwargs, :progress_bar) && @warn "Ignore keyword argument 'progress_bar' for SteadyStateODESolver"
216+
haskey(kwargs, :save_everystep) && @warn "Ignore keyword argument 'save_everystep' for SteadyStateODESolver"
217+
haskey(kwargs, :saveat) && @warn "Ignore keyword argument 'saveat' for SteadyStateODESolver"
218+
kwargs2 = merge(kwargs, (progress_bar = Val(false), save_everystep = false, saveat = ftype[]))
219+
220+
# add terminate condition (callback)
221+
cb = TerminateSteadyState(
222+
solver.terminate_abstol,
223+
solver.terminate_reltol,
224+
SteadyStateODECondition(similar(mat2vec(ket2dm(ψ0)).data)),
222225
)
226+
kwargs3 = _merge_kwargs_with_callback(kwargs2, cb)
223227

228+
sol = mesolve(L, ψ0, tlist; kwargs3...)
224229
ρss = sol.states[end]
225230
return ρss
226231
end

0 commit comments

Comments
 (0)