I apologize for my late response! I’ve tried a few things with the observer system, but the best I can get is to save both the MPS and MPO to a HDF5 file and use those to restart a calculation (from this old forum post: Write MPS to file in Julia - ITensor Support Q&A). My current issue is that my calculation is sometimes cancelled before the results can be printed. Is there a way I can output to file during a calculation? This is my current working versions of the example you linked to, both the initial file and the restarted version! Thank you!!
First TDVP calculation:
using ITensorMPS: MPO, MPS, OpSum, expect, inner, siteinds, tdvp
using Observers: observer
using HDF5
function main()
function heisenberg(N)
os = OpSum()
for j in 1:(N - 1)
os += 0.5, "S+", j, "S-", j + 1
os += 0.5, "S-", j, "S+", j + 1
os += "Sz", j, "Sz", j + 1
end
return os
end
N = 10
s = siteinds("S=1/2", N; conserve_qns = true)
H = MPO(heisenberg(N), s)
step(; sweep) = sweep
current_time(; current_time) = current_time
return_state(; state) = state
measure_sz(; state) = expect(state, "Sz"; sites = length(state) ÷ 2)
obs = observer(
"steps" => step, "times" => current_time, "states" => return_state, "sz" => measure_sz
)
init = MPS(s, n -> isodd(n) ? "Up" : "Dn")
state = tdvp(
H, -1.0im, init; time_step = -0.1im, cutoff = 1.0e-12, (step_observer!) = obs, outputlevel = 1
)
println("\nResults")
println("=======")
for n in 1:length(obs.steps)
print("step = ", obs.steps[n])
print(", time = ", round(obs.times[n]; digits = 3))
print(", |⟨ψⁿ|ψⁱ⟩| = ", round(abs(inner(obs.states[n], init)); digits = 3))
print(", |⟨ψⁿ|ψᶠ⟩| = ", round(abs(inner(obs.states[n], state)); digits = 3))
print(", ⟨Sᶻ⟩ = ", round(obs.sz[n]; digits = 3))
println()
fo = h5open("output.h5", "w")
write(fo, "MPS", state)
write(fo, "MPO", H)
close(fo)
end
return nothing
end
main()
Second TDVP calculation:
using ITensorMPS: MPO, MPS, OpSum, expect, inner, siteinds, tdvp
using Observers: observer
using HDF5
function main()
function heisenberg(N)
os = OpSum()
for j in 1:(N - 1)
os += 0.5, "S+", j, "S-", j + 1
os += 0.5, "S-", j, "S+", j + 1
os += "Sz", j, "Sz", j + 1
end
return os
end
f = h5open("output.h5", "r")
psi = read(f, "MPS", MPS)
H = read(f, "MPO", MPO)
close(f)
N = 10
#s = siteinds("S=1/2", N; conserve_qns = true)
#H = MPO(heisenberg(N), s)
step(; sweep) = sweep
current_time(; current_time) = current_time
return_state(; state) = state
measure_sz(; state) = expect(state, "Sz"; sites = length(state) ÷ 2)
obs = observer(
"steps" => step, "times" => current_time, "states" => return_state, "sz" => measure_sz
)
init = psi
state = tdvp(
H, -1.0im, init; time_step = -0.1im, cutoff = 1.0e-12, (step_observer!) = obs, outputlevel = 1
)
println("\nResults")
println("=======")
for n in 1:length(obs.steps)
print("step = ", obs.steps[n])
print(", time = ", round(obs.times[n]; digits = 3))
print(", |⟨ψⁿ|ψⁱ⟩| = ", round(abs(inner(obs.states[n], init)); digits = 3))
print(", |⟨ψⁿ|ψᶠ⟩| = ", round(abs(inner(obs.states[n], state)); digits = 3))
print(", ⟨Sᶻ⟩ = ", round(obs.sz[n]; digits = 3))
println()
fo = h5open("output_2.h5", "w")
write(fo, "MPS", state)
write(fo, "MPO", H)
close(fo)
end
return nothing
end