2.7. Advanced onebody settings

We show some advanced settings for solving the onebody Schrödinger equation which is based on Solving one-body problems. In the following, syst is a finalized kwant system with leads and we import the onebody module from tkwant:

from tkwant import onebody

2.7.1. Boundary conditions

Special boundary conditions have to be provided in order to solve the dynamic equations for an open quantum systems (with leads). For onebody.WaveFunction they must be precalculated:

boundaries = [tkwant.leads.SimpleBoundary(num_buffer_cells=500)] * len(syst.leads)
scattering_states = kwant.wave_function(syst, energy=1, params={'time':0})
lead, mode = 0, 0
psi_st = scattering_states(lead)[mode]
psi = onebody.WaveFunction.from_kwant(syst, psi_st, boundaries=boundaries, energy=1.)

For the scattering state solver boundary conditions are calculated on the fly. One can provide different boundary conditions by the keyword boundary

boundaries = [tkwant.leads.SimpleBoundary(num_buffer_cells=500)] * len(syst.leads)
psi = onebody.ScatteringStates(syst, energy=1, lead=0, boundaries=boundaries)[mode]

For closed quantum systems (without leads), no boundary conditions are needed.

See also

A tutorial on boundary conditions is given in Boundary conditions. An example script which shows alternative boundary conditions is given in Alternative boundary conditions.

2.7.2. Time integration

The time integration can be changed by prebinding values with the module functool.partial to the onebody solver. In the current example, we change the relative tolerance rtol of the time-stepping algorithm:

import functools as ft
solver_type = ft.partial(tkwant.onebody.solvers.default, rtol=1E-5)
psi = onebody.WaveFunction.from_kwant(syst=syst, boundaries=boundaries,
                                      psi_init=psi_st, energy=1.,
                                      solver_type=solver_type)

2.7.3. Time-dependent perturbation

When the method onebody.WaveFunction.from_kwant() is used, the time-dependent perturbation \(W(t)\) is extracted from the Hamiltonian of a Kwant system. By defaut, Tkwant uses cubic spline interpolation to interpolate \(W(t)\) in time with a static discretization time \(dt\). The interpolation is used for performance reasons, in order to minimize the number of calls to Kwant.

One can change the discretization time \(dt\), which by default is \(dt = 1\), to a different value:

import functools as ft
perturbation_type = ft.partial(tkwant.onebody.kernels.PerturbationInterpolator, dt=0.5)
psi = onebody.WaveFunction.from_kwant(syst=syst, psi_init=psi_st, energy=1.,
                                      boundaries=boundaries,
                                      perturbation_type=perturbation_type)

Setting \(dt = 0\) will switch off interpolation and always evaluate the exact \(W(t)\) function. Alternatively, one can switch off interpolation directly with

psi = onebody.WaveFunction.from_kwant(syst=syst, psi_init=psi_st, energy=1.,
                                      boundaries=boundaries,
                                      perturbation_type=tkwant.onebody.kernels.PerturbationExtractor)

2.7.4. Saving and restarting states

Sometimes we might like to save a state in order to resume a calculation on a later stage. An easy way is to to use the pickle package:

import pickle

psi = onebody.WaveFunction.from_kwant(syst=syst, psi_init=psi_st, energy=1.,
                                      boundaries=boundaries,
                                      kernel_type=onebody.kernels.Scipy)

saved = pickle.dumps(psi)

Saving a state works currently only with the tkwant.onebody.kernels.Scipy kernel. The saved object saved can be stored. Recovering the state later on in order to continue the calculation is possible by using

new_psi = pickle.loads(saved)

See Restarting calculations from previously saved results for the complete code.

See also

An example script showing the restarting of states is given in Restarting calculations from previously saved results.