Real-space visualization of rough interfaces

The roughness of a sample can be turned into real-space height maps. Use them

  • to compare with atomic-force-microscopy (AFM) images;
  • to check the chosen autocorrelation, cross-correlation, and height-distribution parameters.

There are two generators:

  • RoughnessMap(...).generate() maps one interface, independently of the others;
  • RoughnessMap.generateInterfaceMaps(...) maps several interfaces together, including their cross-correlation.

Open the complete example.

One interface

roughness_map = ba.RoughnessMap(
    n_pts_x, n_pts_y, Lx, Ly, sample, i_layer, seed=42)
heights = roughness_map.generate()
  • n_pts_x, n_pts_y: number of grid points along x and y.
  • Lx, Ly: map size in nm.
  • i_layer: layer whose top interface is mapped; the ambient layer has index 0.
  • seed: optional, default 0. New generators with the same seed produce the same map. Repeated calls on one generator produce new realizations.

generate() returns a NumPy array of shape (n_pts_y, n_pts_x) with height offsets in nm relative to the flat interface.

The map is generated with the iterative amplitude-adjusted Fourier transform (IAAFT) algorithm. It adjusts a random surface until it reproduces the target spectrum and height distribution (Pérez-Ràfols & Almqvist, Tribology International 131, 591-604 (2019)).

Several interfaces

maps = ba.RoughnessMap.generateInterfaceMaps(
    n_pts_x, n_pts_y, Lx, Ly, sample, interface_indices, seed=42)

The result is a NumPy array of shape (len(interface_indices), n_pts_y, n_pts_x), in the requested order. For example, interface_indices=[1, 2] returns the maps of interfaces 1 and 2.

The maps are built bottom-up:

  1. The lowest rough interface is generated as with generate(), using the same seed.
  2. Each interface above is built from the one below. It inherits the part prescribed by the cross-correlation model and adds an independent part with the remaining spectrum.

This makes features replicated between neighboring interfaces visible.

Differences from generate():

  • The whole rough stack is always generated; interface_indices only selects the returned maps. For an upper interface, the result therefore differs from RoughnessMap(..., i, seed).generate().
  • Only the lowest rough interface has its height distribution adjusted. Upper interfaces follow the target spectra; their height distribution is approximate.