Skip to content

Analyzers

Analyze wavepacket dynamics during time propagation.

An analyzer collects data from a grid at the times it is called with that grid. Every analyzer is callable as analyzer(grid), so it can be passed directly as callback to SplitOperator.propagate() or in the analyzers list of the animation functions:

obs = Observables() obs(grid) # record the initial state prop.propagate(grid, dt, n_steps, callback=obs, every=10) obs.t, obs.position

All analyzers except Wigner, Husimi (1d only) and FarField (2d only) work on 1d and 2d grids. Time integrals use the trapezoidal rule on the sample times, which need not be equidistant (except for AutoCorrelation.spectrum()). Analyzers copy what they need, so the grid may change after each call. None of them plots or prints anything.

Analyzer

Base class: collects data from a grid each time it is called.

add_data(grid)

Take data from the grid at its current time grid.t.

Observables()

Bases: Analyzer

Record norm and expectation values.

After a series of calls, the attributes hold arrays with one entry per call:

  • t: times
  • norm: \(\Vert\psi\Vert\) (decreases with absorbers)
  • position: \(\langle x\rangle\), in 2d \((\langle x\rangle, \langle y\rangle)\)
  • momentum: \(\langle p\rangle\), in 2d \((\langle p_x\rangle, \langle p_y\rangle)\)
  • width: \(\Delta x\), in 2d \((\Delta x, \Delta y)\)
  • energy: \(\langle H\rangle\) (without the absorber); constant for time-independent potentials, so its drift is a check of the time step

In 2d, position, momentum and width have shape (n, 2).

t property

Sample times.

norm property

\(\Vert\psi\Vert\).

position property

\(\langle x\rangle\), in 2d \((\langle x\rangle, \langle y\rangle)\).

momentum property

\(\langle p\rangle\), in 2d \((\langle p_x\rangle, \langle p_y\rangle)\).

width property

\(\Delta x\), in 2d \((\Delta x, \Delta y)\).

energy property

\(\langle H\rangle\).

AutoCorrelation(reference=None)

Bases: Analyzer

Record the autocorrelation function \(C(t) = \langle\psi_0|\psi(t)\rangle\) and compute the spectrum from it.

Parameters:

Name Type Description Default
reference array

\(\psi_0\). Defaults to the wavefunction of the first call.

None

t property

Sample times.

C property

\(C(t)\) at the sample times.

spectrum(window='hann')

Spectrum \(|\tilde C(E)| = \left|\int_0^T w(t)\,e^{iEt}\,C(t)\,\mathrm{d}t\right|\).

Expanding \(\psi_0\) in eigenstates, \(C(t) = \sum_n |c_n|^2 e^{-iE_n t}\), so the spectrum has peaks at the eigenenergies \(E_n\), weighted by \(|c_n|^2\); cmp. Feit et al., J. Comp. Phys. 47, 412 (1982). The resolution is about \(2\pi/T\), the largest energy \(\pi/\Delta t\).

Parameters:

Name Type Description Default
window str or tuple

Window \(w(t)\), as understood by scipy.signal.get_window(). Only its second half is used, which decays from 1 at \(t = 0\) to 0 at \(t = T\) (since \(C(-t) = C(t)^*\)). Defaults to Hann.

'hann'

Returns:

Name Type Description
E array

Energies, ascending.

amplitude array

\(|\tilde C(E)|\).

EigenstateFilter(energies, t_max)

Bases: Analyzer

Build eigenstates for given energies on the fly, without storing the wavefunction at every time step.

For each energy \(E\) the filter accumulates \(\varphi_E = \int_0^{T} w(t)\, e^{iEt}\,\psi(t)\,\mathrm{d}t\), with half a Hann window \(w(t) = (1 + \cos(\pi t/T))/2\) that decays from 1 at \(t = 0\) to 0 at \(t = T\). Times are counted from the first call. Cmp. Feit et al., J. Comp. Phys. 47, 412 (1982).

The energy resolution is about \(2\pi/T\); states closer in energy are mixed.

Parameters:

Name Type Description Default
energies float or array - like

Energies to filter for.

required
t_max float

Filter time \(T\). Data added later than \(T\) after the first call is ignored.

required

eigenstates()

Return the filtered states, normalized to \(\Vert\varphi_E\Vert = 1\).

Returns:

Name Type Description
phi complex array

phi[i] belongs to energies[i].

EigenfunctionBuilder()

Bases: Analyzer

Store \(\psi(t)\) to build eigenstates for energies chosen after the propagation, e.g. from the peaks of AutoCorrelation.spectrum().

This needs memory for all stored wavefunctions; use EigenstateFilter if the energies are known in advance. The filter is the same, with \(T\) the time between the first and the last call.

eigenstates(energies)

Filtered states for the given energies, see EigenstateFilter.

Parameters:

Name Type Description Default
energies float or array - like
required

Returns:

Name Type Description
phi complex array

phi[i] belongs to energies[i].

IntegratedDensity()

Bases: Analyzer

Time integrated density \(\int |\psi(\mathbf{r}, t)|^2\,\mathrm{d}t\).

Shows where a wave has been, e.g. the branches of branched flow. Subclasses integrate other densities by overriding _density(grid).

density property

The integrated density so far.

FarField(r_min, r_max, center=(0.0, 0.0), k_range=None, n_angles=360, edge=None)

Bases: IntegratedDensity

Far field of the waves emitted by a cavity or scatterer at center. 2d only.

Far from its source, a wave moves along its momentum, so the far field is the distribution of the momentum directions of the emitted wave. The analyzer takes the wave in a ring \(r_\mathrm{min} < |\mathbf{r} - \mathbf{r}_c| < r_\mathrm{max}\) (with edges smoothed over edge), which excludes the source, Fourier transforms it and integrates the momentum density \(|\tilde\psi(\mathbf{k}, t)|^2\) over time. Every part of the emitted wave crosses the ring once, in the same time for every direction, so

\[I(\varphi) = \int_{k_\mathrm{min}}^{k_\mathrm{max}} \int |\tilde\psi(k\cos\varphi, k\sin\varphi, t)|^2\,\mathrm{d}t\;k\,\mathrm{d}k\]

is proportional to the probability emitted per angle \(\varphi\). The time integrated momentum density itself is in density, on the momenta (grid.kx_vals, grid.ky_vals) in FFT order.

The ring should start a few wavelengths outside the source, so that evanescent fields are excluded, end inside the absorber, and be wide enough to resolve the angles: its width \(\Delta r\) blurs them by about \(1/(k\Delta r)\). The propagation should last until the emission has passed the ring. Waves reflected back from the absorber are counted as well.

Parameters:

Name Type Description Default
r_min float

Radii of the ring.

required
r_max float

Radii of the ring.

required
center tuple of float

Center \(\mathbf{r}_c\) of the ring.

(0.0, 0.0)
k_range tuple of float

Range of \(|\mathbf{k}|\) in \(I(\varphi)\), e.g. around the wavenumber of an emitting mode. Defaults to all momenta on the grid.

None
n_angles int

Number of angles \(\varphi\) on \([-\pi, \pi)\).

360
edge float

Width of the smoothed edges; defaults to an eighth of the ring width.

None

angles property

The angles \(\varphi\), in \([-\pi, \pi)\).

intensity property

\(I(\varphi)\) at angles.

Flux(position, axis=0)

Bases: Analyzer

Probability flux through a point (1d) or a line (2d).

The current density is \(j = \mathrm{Im}(\psi^*\nabla\psi)\) (atomic units, \(m = 1\)), with the derivative taken spectrally. In 1d the flux is \(j(x_0, t)\), in 2d the flux through the line \(x = x_0\) (axis=0) or \(y = y_0\) (axis=1). The time integral of the flux is the probability that has passed, e.g. the transmission through a barrier. Unlike the probability to the right of the barrier, it counts the transmitted part even after an absorber has swallowed it.

The flux at a single point is sensitive to high momentum components, e.g. from discontinuous potentials. Call the analyzer at every time step and use a time step that resolves the relevant momenta; otherwise the time integral can be off by several percent.

Parameters:

Name Type Description Default
position float

\(x_0\) (or \(y_0\)). The nearest grid point (line) is used.

required
axis int

In 2d, the axis normal to the line.

0

t property

Sample times.

flux property

Flux at the sample times; positive in the direction of the axis.

transferred property

Probability that has passed so far, \(\int j\,\mathrm{d}t\).

cumulative()

Probability that has passed, at each sample time.

Wigner(x_lim=None, p_lim=None)

Bases: Analyzer

Record the Wigner function \(W(x, p)\) at each call, see so_schroedinger.phasespace.wigner(). 1d only.

Each snapshot needs len(x) * len(p) floats (2N² for the full range on N grid points), so x_lim and p_lim help for many snapshots.

Parameters:

Name Type Description Default
x_lim tuple of float

Phase space window to record.

None
p_lim tuple of float

Phase space window to record.

None

t property

Sample times.

W property

Snapshots, W[n, i, j] at time t[n] and (x[i], p[j]).

Husimi(sigma=1.0, x_lim=None, p_lim=None)

Bases: Wigner

Record the Husimi function \(Q(x, p)\) at each call, see so_schroedinger.phasespace.husimi(). 1d only.

The snapshots are in W, as for Wigner.

Parameters:

Name Type Description Default
sigma float

Position width of the coherent states.

1.0
x_lim tuple of float

Phase space window to record.

None
p_lim tuple of float

Phase space window to record.

None