|
47 | 47 | alg = Tsit5(), |
48 | 48 | ψ0 = nothing, |
49 | 49 | 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 | + ) |
53 | 53 |
|
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. |
55 | 55 |
|
56 | 56 | The termination condition of the stationary state ``|\rho\rangle\rangle`` is that either the following condition is `true`: |
57 | 57 |
|
|
69 | 69 | - `alg::OrdinaryDiffEqAlgorithm=Tsit5()`: The algorithm to solve the ODE. |
70 | 70 | - `ψ0::Union{Nothing,QuantumObject}=nothing`: The initial state of the system. If not specified, a random pure state will be generated. |
71 | 71 | - `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. |
72 | 77 |
|
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/). |
74 | 79 | """ |
75 | | -Base.@kwdef struct SteadyStateODESolver{MT<:OrdinaryDiffEqAlgorithm,ST<:Union{Nothing,QuantumObject},T<:Real} <: |
76 | | - SteadyStateSolver |
| 80 | +Base.@kwdef struct SteadyStateODESolver{ |
| 81 | + MT<:OrdinaryDiffEqAlgorithm, |
| 82 | + ST<:Union{Nothing,QuantumObject}, |
| 83 | + TT<:Real, |
| 84 | + RT<:Real, |
| 85 | + AT<:Real, |
| 86 | +} <: SteadyStateSolver |
77 | 87 | alg::MT = Tsit5() |
78 | 88 | ψ0::ST = nothing |
79 | | - tmax::T = Inf |
| 89 | + tmax::TT = Inf |
| 90 | + terminate_reltol::RT = 10 * DEFAULT_ODE_SOLVER_OPTIONS.reltol |
| 91 | + terminate_abstol::AT = 10 * DEFAULT_ODE_SOLVER_OPTIONS.abstol |
80 | 92 | end |
81 | 93 |
|
82 | 94 | @doc raw""" |
@@ -200,27 +212,28 @@ function _steadystate(L::QuantumObject{SuperOperator}, solver::SteadyStateDirect |
200 | 212 | end |
201 | 213 |
|
202 | 214 | function _steadystate(L::AbstractQuantumObject{SuperOperator}, solver::SteadyStateODESolver; kwargs...) |
203 | | - tmax = solver.tmax |
204 | | - |
205 | 215 | ψ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 | | - |
209 | 216 | 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..., |
| 217 | + tlist = [ftype(0), ftype(solver.tmax)] |
| 218 | + |
| 219 | + # overwrite some kwargs and throw warning message to tell the users that we are ignoring these settings |
| 220 | + haskey(kwargs, :progress_bar) && @warn "Ignore keyword argument 'progress_bar' for SteadyStateODESolver" |
| 221 | + haskey(kwargs, :save_everystep) && @warn "Ignore keyword argument 'save_everystep' for SteadyStateODESolver" |
| 222 | + haskey(kwargs, :saveat) && @warn "Ignore keyword argument 'saveat' for SteadyStateODESolver" |
| 223 | + kwargs2 = merge( |
| 224 | + NamedTuple(kwargs), # we convert to NamedTuple just in case if kwargs is empty |
| 225 | + (progress_bar = Val(false), save_everystep = false, saveat = ftype[]), |
| 226 | + ) |
| 227 | + |
| 228 | + # add terminate condition (callback) |
| 229 | + cb = TerminateSteadyState( |
| 230 | + solver.terminate_abstol, |
| 231 | + solver.terminate_reltol, |
| 232 | + SteadyStateODECondition(similar(mat2vec(ket2dm(ψ0)).data)), |
222 | 233 | ) |
| 234 | + kwargs3 = _merge_kwargs_with_callback(kwargs2, cb) |
223 | 235 |
|
| 236 | + sol = mesolve(L, ψ0, tlist; kwargs3...) |
224 | 237 | ρss = sol.states[end] |
225 | 238 | return ρss |
226 | 239 | end |
|
0 commit comments