diff --git a/src/master.jl b/src/master.jl index 164cc514..0cf63ff6 100644 --- a/src/master.jl +++ b/src/master.jl @@ -164,10 +164,10 @@ This version takes the non-hermitian Hamiltonian `Hnh` and jump operators `J` as The jump operators may be `<: AbstractTimeDependentOperator` or other types of operator. """ -function master_nh_dynamic(tspan, rho0::Operator, f::F; +function master_nh_dynamic(tspan, rho0::Operator, f; rates=nothing, fout=nothing, - kwargs...) where {F} + kwargs...) tmp = copy(rho0) dmaster_(t, rho, drho) = dmaster_nh_dynamic!(drho, f, rates, rho, tmp, t) integrate_master(tspan, dmaster_, rho0, fout; kwargs...) @@ -210,12 +210,14 @@ This version takes the Hamiltonian `H` and jump operators `J` as time-dependent The jump operators may be `<: AbstractTimeDependentOperator` or other types of operator. """ -function master_dynamic(tspan, rho0::Operator, f::F; +function master_dynamic(tspan, rho0::Operator, f; rates=nothing, fout=nothing, - kwargs...) where {F} + kwargs...) tmp = copy(rho0) - dmaster_(t, rho, drho) = dmaster_h_dynamic!(drho, f, rates, rho, tmp, t) + dmaster_ = let f = f, tmp = tmp + dmaster_(t, rho, drho) = dmaster_h_dynamic!(drho, f, rates, rho, tmp, t) + end integrate_master(tspan, dmaster_, rho0, fout; kwargs...) end diff --git a/src/schroedinger.jl b/src/schroedinger.jl index 7d44c47b..0910066d 100644 --- a/src/schroedinger.jl +++ b/src/schroedinger.jl @@ -13,7 +13,7 @@ Integrate Schroedinger equation to evolve states or compute propagators. therefore must not be changed. """ function schroedinger(tspan, psi0::T, H::AbstractOperator{B,B}; - fout::Union{Function,Nothing}=nothing, + fout=nothing, kwargs...) where {B,Bo,T<:Union{AbstractOperator{B,Bo},StateVector{B}}} _check_const(H) dschroedinger_(t, psi, dpsi) = dschroedinger!(dpsi, H, psi) @@ -43,10 +43,12 @@ Integrate time-dependent Schroedinger equation to evolve states or compute propa Instead of a function `f`, this takes a time-dependent operator `H`. """ -function schroedinger_dynamic(tspan, psi0, f::F; - fout::Union{Function,Nothing}=nothing, - kwargs...) where {F} - dschroedinger_(t, psi, dpsi) = dschroedinger_dynamic!(dpsi, f, psi, t) +function schroedinger_dynamic(tspan, psi0, f; + fout=nothing, + kwargs...) + dschroedinger_ = let f = f + dschroedinger_(t, psi, dpsi) = dschroedinger_dynamic!(dpsi, f, psi, t) + end tspan, psi0 = _promote_time_and_state(psi0, f, tspan) # promote only if ForwardDiff.Dual x0 = psi0.data state = copy(psi0) diff --git a/src/semiclassical.jl b/src/semiclassical.jl index f94fe496..55505df2 100644 --- a/src/semiclassical.jl +++ b/src/semiclassical.jl @@ -71,10 +71,12 @@ Integrate time-dependent Schrödinger equation coupled to a classical system. normalized nor permanent! * `kwargs...`: Further arguments are passed on to the ode solver. """ -function schroedinger_dynamic(tspan, state0::State, fquantum::F, fclassical!::G; +function schroedinger_dynamic(tspan, state0::State, fquantum, fclassical!; fout=nothing, - kwargs...) where {F, G} - dschroedinger_(t, state, dstate) = dschroedinger_dynamic!(dstate, fquantum, fclassical!, state, t) + kwargs...) + dschroedinger_ = let fquantum = fquantum, fclassical! = fclassical! + dschroedinger_(t, state, dstate) = dschroedinger_dynamic!(dstate, fquantum, fclassical!, state, t) + end x0 = Vector{eltype(state0)}(undef, length(state0)) recast!(x0,state0) state = copy(state0) @@ -101,12 +103,14 @@ Integrate time-dependent master equation coupled to a classical system. permanent! * `kwargs...`: Further arguments are passed on to the ode solver. """ -function master_dynamic(tspan, state0::State{B,T}, fquantum::F, fclassical!::G; +function master_dynamic(tspan, state0::State{B,T}, fquantum, fclassical!; rates=nothing, fout=nothing, tmp=copy(state0.quantum), - kwargs...) where {B,T<:Operator,F,G} - dmaster_(t, state, dstate) = dmaster_h_dynamic!(dstate, fquantum, fclassical!, rates, state, tmp, t) + kwargs...) where {B,T<:Operator} + dmaster_ = let fquantum = fquantum, fclassical! = fclassical! + dmaster_(t, state, dstate) = dmaster_h_dynamic!(dstate, fquantum, fclassical!, rates, state, tmp, t) + end x0 = Vector{eltype(state0)}(undef, length(state0)) recast!(x0,state0) state = copy(state0) @@ -149,14 +153,20 @@ sure to take this into account when computing expectation values! the index of the jump operators with which the jump occured, respectively. * `kwargs...`: Further arguments are passed on to the ode solver. """ -function mcwf_dynamic(tspan, psi0::State{B,T}, fquantum::F, fclassical!::G, fjump_classical!::H; +function mcwf_dynamic(tspan, psi0::State{B,T}, fquantum, fclassical!, fjump_classical!; seed=rand(UInt), rates=nothing, fout=nothing, - kwargs...) where {B,T<:Ket,F,G,H} + kwargs...) where {B,T<:Ket} tmp=copy(psi0.quantum) - dmcwf_(t, psi, dpsi) = dmcwf_h_dynamic!(dpsi, fquantum, fclassical!, rates, psi, tmp, t) - j_(rng, t, psi, psi_new) = jump_dynamic(rng, t, psi, fquantum, fclassical!, fjump_classical!, psi_new, rates) + dmcwf_ = let fquantum = fquantum, fclassical! = fclassical! + dmcwf_(t, psi, dpsi) = dmcwf_h_dynamic!(dpsi, fquantum, fclassical!, rates, psi, tmp, t) + end + J = fquantum(first(tspan), psi0.quantum, psi0.classical)[2] + probs = zeros(real(eltype(psi0)), length(J)) + j_ = let fquantum = fquantum, fclassical! = fclassical!, fjump_classical! = fjump_classical!, probs = probs + j_(rng, t, psi, psi_new) = jump_dynamic(rng, t, psi, fquantum, fclassical!, fjump_classical!, psi_new, probs, rates) + end x0 = Vector{eltype(psi0)}(undef, length(psi0)) recast!(x0,psi0) psi = copy(psi0) @@ -222,7 +232,7 @@ function dmcwf_h_dynamic!(dpsi, fquantum::F, fclassical!::G, rates, psi, tmp, t) return dpsi end -function jump_dynamic(rng, t, psi, fquantum::F, fclassical!::G, fjump_classical!::H, psi_new, rates) where {F,G,H} +function jump_dynamic(rng, t, psi, fquantum::F, fclassical!::G, fjump_classical!::H, psi_new, probs_tmp, rates) where {F,G,H} result = fquantum(t, psi.quantum, psi.classical) QO_CHECKS[] && @assert 3 <= length(result) <= 4 J = result[2] @@ -231,7 +241,7 @@ function jump_dynamic(rng, t, psi, fquantum::F, fclassical!::G, fjump_classical! else rates_ = result[4] end - i = jump(rng, t, psi.quantum, J, psi_new.quantum, rates_) + i = jump(rng, t, psi.quantum, J, psi_new.quantum, probs_tmp, rates_) fjump_classical!(psi.classical, psi_new.quantum, i, t) psi_new.classical .= psi.classical return i diff --git a/src/timeevolution_base.jl b/src/timeevolution_base.jl index 373a0dd1..0f82f083 100644 --- a/src/timeevolution_base.jl +++ b/src/timeevolution_base.jl @@ -12,10 +12,10 @@ function recast! end Integrate using OrdinaryDiffEq """ function integrate(tspan, df::F, x0, - state, dstate, fout::G; + state, dstate, fout; alg = OrdinaryDiffEq.DP5(), steady_state = false, tol = 1e-3, save_everystep = false, saveat=tspan, - callback = nothing, kwargs...) where {F, G} + callback = nothing, kwargs...) where {F} function df_(dx, x, p, t) recast!(state,x) @@ -23,9 +23,12 @@ function integrate(tspan, df::F, x0, df(t, state, dstate) recast!(dx,dstate) end - function fout_(x, t, integrator) - recast!(state,x) - fout(t, state) + + fout_ = let fout = fout, state = state + function fout_(x, t, integrator) + recast!(state,x) + fout(t, state) + end end tType = float(eltype(tspan))