# TDVP for time-dependent Hamiltonian operators

**URL:** <https://itensor.discourse.group/t/tdvp-for-time-dependent-hamiltonian-operators/1881>\
**Category:** DMRG and Numerical Methods\
**Tags:** tdvp\
**Created:** [July 18, 2024, 10:35am UTC](https://itensor.discourse.group/t/tdvp-for-time-dependent-hamiltonian-operators/1881 "2024-07-18T10:35:40Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![a-m](https://avatars.discourse-cdn.com/v4/letter/a/5f9b8f/32.png) [@a-m](https://itensor.discourse.group/u/a-m)\
**Post date:** [July 18, 2024, 10:35am UTC](https://itensor.discourse.group/t/tdvp-for-time-dependent-hamiltonian-operators/1881/1 "2024-07-18T10:35:40Z")

</div>

Dear ITensor developers,

I would like to know how to use TDVP with a Hamiltonian operator that is time-dependent. I found the example

> <https://github.com/ITensor/ITensorTDVP.jl/blob/main/examples/03_tdvp_time_dependent.jl>

There, the time dependence is in the form of a time-dependent factor multiplying a time-independent Hamiltonian MPO, H(t) = f\_1(t) H\_1(0) + f\_2(t) H\_2(0), and the time-dependent Hamiltonian is given as an argument to `tdvp` by using the `TimeDependentSum` function:

```julia
ψₜ_ode = tdvp(-im * TimeDependentSum(f⃗, H⃗₀), time_stop, ψ₀;
    updater=ode_updater,
    updater_kwargs=(; reltol=tol, abstol=tol),
    time_step,
    maxdim,
    cutoff,
    nsite,
    outputlevel,)

```

What would be the syntax for `tdvp` when the Hamiltonian is not separable into a factor f(t) and a time-independent MPO? I am specifically interested in reproducing the results of the paper [[https://journals.aps.org/prxquantum/pdf/10.1103/PRXQuantum.5.020361](https://journals.aps.org/prxquantum/pdf/10.1103/PRXQuantum.5.020361)], where the adiabatic gauge potential term in the Hamiltonian is time-dependent. I am using the `julia ITensor` version `0.6.16`.

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [July 25, 2024, 3:15pm UTC](https://itensor.discourse.group/t/tdvp-for-time-dependent-hamiltonian-operators/1881/2 "2024-07-25T15:15:08Z")

</div>

It’s a good question. A good way to do totally arbitrary, time-dependent Hamiltonians is to make a custom updater function. If you look further at the example you linked to, you’ll see that the calls to the `tdvp` function also pass a keyword argument:

```julia
tdvp(...,
updater=ode_updater
...

```

and the `ode_updater` function is defined in the `03_updaters.jl` file also in the example folder.

You can think of the `TimeDependentSum` type passed into tdvp and then all the way down to the updater as being a stand-in for any object that you want to pass. If your updater is custom, that type (which gets passed as the `operator` argument of the updater) really can be any object you like. The updater also gets passed keyword arguments from which you can obtain the current time and the time step. Then you can use this information to process the operator any way that suits your calculation in order to finally make an input to the “time stepper” that you want to use.

The example code uses the `ODEProblem` type and `solve` function from the `OrdinaryDiffEQ` package, but you can also use the more standard `exponentiate` function from the `KrylovKit` package which we use as our default TDVP time stepper. All that `KrylovKit` requires is that you pass an operator object which can be called (i.e. operators the “parenthesis” operation of calling the object like a function) and which accepts an ITensor as input. For more information about `exponentiate` please see the [KrylovKit docs](https://jutho.github.io/KrylovKit.jl/stable/man/matfun/#KrylovKit.exponentiate) and also you can take a look at our default `exponentiate_updater` in the file `src/tdvp.jl` in the ITensorTDVP code repo.

A very useful thing to do in all this is to put ITensorTDVP into “dev” mode and then add lines printing out or `@show`’ing various things like types of objects passed into the updater and the keyword arguments received by the updater etc. This is what I often do to remind myself of what objects and information are flowing into each function.

Please respond below if you have further questions.
