Resonator

This example computes the neutron field inside a multilayer resonator over depth and incident angle. The beam enters from the silicon side; because the BornAgain layer stack is ordered from the incident side downward, silicon is therefore the ambient layer in the model.

The complete stack is Si | Ti | Pt | Ti | TiO$_2$ | D$_2$O. The first Ti/Pt pair forms the main resonating region, while the thinner Ti and TiO$_2$ layers separate it from D$_2$O. The depth origin is the Si/Ti interface and the $z$ axis points back toward the silicon. A Gaussian grazing-angle distribution is applied at every scan point, so the map includes the finite angular spread of the incident beam.

Geometry

Layer sequence, depth coordinates, and incident beam of the neutron resonator

Result

Resonator result

Sample

Resonator sample

Python script

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = ["bornagain>=25,<26"]
# ///
"""
Basic example of depth-probe simulation with BornAgain.

Sample layers are Si | Ti | Pt | Ti | TiO2 | D2O.
Beam comes from Si side.
Therefore we model the stack with Si on top.
The z axis points from D2O to Si; z=0 is at the Si/Ti interface.
"""
import bornagain as ba
ba.require_versions("bornagain>=25,<26")
from bornagain import angstrom, deg, nm


# layer thicknesses in angstroms
t_Ti = 130*angstrom
t_Pt = 320*angstrom
t_Ti_top = 100*angstrom
t_TiO2 = 30*angstrom

#  beam data
ai_min = 0.05*deg  # min incident angle; divergence samples stay above horizon
ai_max = 1*deg  # maximum incident angle
wl = 10*angstrom  # wavelength

# convolution parameters
d_ang = 0.01*ba.deg  # spread width for incident angle

#  depth position span
z_min = -100*nm
z_max = 100*nm


def get_sample():
    """
    Constructs a sample with one resonating Ti/Pt layer
    """

    # Materials
    d2o_color = (0.90, 0.93, 0.97)
    d2o_mat = ba.RefractiveMaterial("D2O", d2o_color, 0.00010116, 1.809e-12)
    pt_color = (0.93, 0.72, 0.25)
    pt_mat = ba.RefractiveMaterial("Pt", pt_color, 0.00010117, 3.01822e-08)
    si_color = (0.30, 0.62, 0.86)
    si_mat = ba.RefractiveMaterial("Si", si_color, 3.3009e-05, 0)
    ti_color = (0.05, 0.62, 0.55)
    ti_mat = ba.RefractiveMaterial("Ti", ti_color, -3.0637e-05, 1.5278e-08)
    tio2_color = (0.48, 0.32, 0.80)
    tio2_mat = ba.RefractiveMaterial("TiO2", tio2_color, 4.1921e-05, 8.1293e-09)

    # Layers
    layer_1 = ba.Layer(si_mat)
    layer_2 = ba.Layer(ti_mat, 13*nm)
    layer_3 = ba.Layer(pt_mat, 32*nm)
    layer_4 = ba.Layer(ti_mat, 10*nm)
    layer_5 = ba.Layer(tio2_mat, 3*nm)
    layer_6 = ba.Layer(d2o_mat)

    # Sample
    sample = ba.Sample()
    sample.addLayer(layer_1)
    sample.addLayer(layer_2)
    sample.addLayer(layer_3)
    sample.addLayer(layer_4)
    sample.addLayer(layer_5)
    sample.addLayer(layer_6)

    return sample


def get_simulation(sample):
    """
    A depth-probe simulation.
    """
    nz = 500
    na = 5000

    scan = ba.AlphaScan(na, ai_min, ai_max)
    scan.setWavelength(wl)

    alpha_distr = ba.DistributionGaussian(0, d_ang, 25, 3.)
    scan.setGrazingAngleDistribution(alpha_distr)

    z_axis = ba.EquiDivision("z (nm)", nz, z_min, z_max)
    simulation = ba.DepthprobeSimulation(scan, sample, z_axis)

    return simulation


if __name__ == '__main__':
    sample = get_sample()
    simulation = get_simulation(sample)
    result = simulation.simulate()
    ba.showSample3D(sample, sample_size=160*nm, seed=0)
    ba.plot_datafield(result, frame_aspect=1.618)
    ba.plt.show()
auto/Examples/depthprobe/Resonator.py