@@ -4,49 +4,58 @@ This file contains helper functions for callbacks. The affect! function are defi
44
55# ######### SESOLVE ##########
66
7- struct SaveFuncSESolve{T1,T2}
8- e_ops:: T1
9- is_empty_e_ops:: T2
7+ struct SaveFuncSESolve{TE,PT<: Union{Nothing,ProgressBar} ,IT}
8+ e_ops:: TE
9+ progr:: PT
10+ iter:: IT
1011end
1112
12- (f:: SaveFuncSESolve )(integrator) = _save_func_sesolve (integrator, f. e_ops, f. is_empty_e_ops )
13- (f:: SaveFuncSESolve{Nothing} )(integrator) = _save_func_sesolve (integrator)
13+ (f:: SaveFuncSESolve )(integrator) = _save_func_sesolve (integrator, f. e_ops, f. progr, f . iter )
14+ (f:: SaveFuncSESolve{Nothing} )(integrator) = _save_func_sesolve (integrator, f . progr )
1415
1516# #
1617
1718# When e_ops is Nothing
18- function _save_func_sesolve (integrator)
19- next! (integrator. p. progr)
19+ function _save_func_sesolve (integrator, progr)
20+ next! (progr)
21+ u_modified! (integrator, false )
22+ return nothing
23+ end
24+
25+ # When progr is Nothing
26+ function _save_func_sesolve (integrator, progr:: Nothing )
2027 u_modified! (integrator, false )
2128 return nothing
2229end
2330
2431# When e_ops is a list of operators
25- function _save_func_sesolve (integrator, e_ops, is_empty_e_ops )
32+ function _save_func_sesolve (integrator, e_ops, progr, iter )
2633 expvals = integrator. p. expvals
27- progr = integrator. p. progr
28- if ! is_empty_e_ops
29- ψ = integrator. u
30- _expect = op -> dot (ψ, op, ψ)
31- @. expvals[:, progr. counter[]+ 1 ] = _expect (e_ops)
32- end
33- return _save_func_sesolve (integrator)
34+ ψ = integrator. u
35+ _expect = op -> dot (ψ, op, ψ)
36+ @. expvals[:, iter[]] = _expect (e_ops)
37+ iter[] += 1
38+
39+ return _save_func_sesolve (integrator, progr)
3440end
3541
36- function _generate_sesolve_callback (e_ops, tlist)
37- is_empty_e_ops = e_ops isa Nothing ? true : isempty (e_ops)
38- _save_affect! = SaveFuncSESolve (get_data .(e_ops), is_empty_e_ops)
42+ function _generate_sesolve_callback (e_ops, tlist, progress_bar)
43+ e_ops_data = e_ops isa Nothing ? nothing : get_data .(e_ops)
44+
45+ progr = getVal (progress_bar) ? ProgressBar (length (tlist), enable = getVal (progress_bar)) : nothing
46+
47+ _save_affect! = SaveFuncSESolve (e_ops_data, progr, Ref (1 ))
3948 return PresetTimeCallback (tlist, _save_affect!, save_positions = (false , false ))
4049end
4150
4251# ######### MCSOLVE ##########
4352
44- struct SaveFuncMCSolve{T1,T2 }
45- e_ops:: T1
46- is_empty_e_ops :: T2
53+ struct SaveFuncMCSolve{TE,IT }
54+ e_ops:: TE
55+ iter :: IT
4756end
4857
49- (f:: SaveFuncMCSolve )(integrator) = _save_func_mcsolve (integrator, f. e_ops, f. is_empty_e_ops )
58+ (f:: SaveFuncMCSolve )(integrator) = _save_func_mcsolve (integrator, f. e_ops, f. iter )
5059
5160struct LindbladJump{T1,T2}
5261 c_ops:: T1
5766
5867# #
5968
60- function _save_func_mcsolve (integrator, e_ops, is_empty_e_ops )
69+ function _save_func_mcsolve (integrator, e_ops, iter )
6170 expvals = integrator. p. expvals
62- progr = integrator. p. progr
6371 cache_mc = integrator. p. mcsolve_params. cache_mc
64- if ! is_empty_e_ops
65- copyto! (cache_mc, integrator. u)
66- normalize! (cache_mc)
67- ψ = cache_mc
68- _expect = op -> dot (ψ, op, ψ)
69- @. expvals[:, progr . counter[] + 1 ] = _expect (e_ops)
70- end
71- next! (progr)
72+
73+ copyto! (cache_mc, integrator. u)
74+ normalize! (cache_mc)
75+ ψ = cache_mc
76+ _expect = op -> dot (ψ, op, ψ)
77+ @. expvals[:, iter[] ] = _expect (e_ops)
78+ iter[] += 1
79+
7280 u_modified! (integrator, false )
7381 return nothing
7482end
@@ -97,8 +105,7 @@ function _generate_mcsolve_kwargs(e_ops, tlist, c_ops, jump_callback, kwargs)
97105 merge (kwargs, (callback = cb1,))
98106 return kwargs2
99107 else
100- is_empty_e_ops = isempty (e_ops)
101- _save_affect! = SaveFuncMCSolve (get_data .(e_ops), is_empty_e_ops)
108+ _save_affect! = SaveFuncMCSolve (get_data .(e_ops), Ref (1 ))
102109 cb2 = _PresetTimeCallback (tlist, _save_affect!, save_positions = (false , false ))
103110 kwargs2 =
104111 haskey (kwargs, :callback ) ? merge (kwargs, (callback = CallbackSet (cb1, cb2, kwargs. callback),)) :
@@ -171,6 +178,36 @@ function _mcsolve_get_e_ops(integrator::AbstractODEIntegrator)
171178 return cb. affect!. e_ops
172179end
173180
181+ #=
182+ _mcsolve_callbacks_new_iter(prob, tlist)
183+
184+ Return the same callbacks of the `prob`, but with the `iter` variable reinitialized to 1.
185+ =#
186+ function _mcsolve_callbacks_new_iter (prob, tlist)
187+ cb = prob. kwargs[:callback ]
188+ return _mcsolve_callbacks_new_iter (cb, tlist)
189+ end
190+ function _mcsolve_callbacks_new_iter (cb:: CallbackSet , tlist)
191+ cb_continuous = cb. continuous_callbacks
192+ cb_discrete = cb. discrete_callbacks
193+
194+ if length (cb_continuous) > 0
195+ idx = 1
196+ e_ops = cb_discrete[idx]. affect!. e_ops
197+ _save_affect! = SaveFuncMCSolve (e_ops, Ref (1 ))
198+ cb_save = _PresetTimeCallback (tlist, _save_affect!, save_positions = (false , false ))
199+ return CallbackSet (cb_continuous... , cb_save, cb_discrete[2 : end ]. .. )
200+ else
201+ idx = 2
202+ e_ops = cb_discrete[idx]. affect!. e_ops
203+ _save_affect! = SaveFuncMCSolve (e_ops, Ref (1 ))
204+ cb_save = _PresetTimeCallback (tlist, _save_affect!, save_positions = (false , false ))
205+ return CallbackSet (cb_continuous... , cb_discrete[1 ], cb_save, cb_discrete[3 : end ]. .. )
206+ end
207+ end
208+ _mcsolve_callbacks_new_iter (cb:: ContinuousCallback , tlist) = cb
209+ _mcsolve_callbacks_new_iter (cb:: DiscreteCallback , tlist) = cb
210+
174211# # Temporary function to avoid errors. Waiting for the PR In DiffEqCallbacks.jl to be merged.
175212
176213import SciMLBase: INITIALIZE_DEFAULT, add_tstop!
0 commit comments