Specular simulation with different roughness models

This example demonstrates how to apply different roughness models in a specular reflectivity calculation. The considered sample is exactly the same as the one described in the reflectometry tutorial, and the basic roughness tutorial. Hewever, now the computation is performed twice with the standard $tanh$ interface profile and the Névot-Croce roughness model that arises from a Gaussian distribution of the deviation from the mean-surface position.

Intensity image

In both cases, the root-mean-square deviation from the mean surface position is chosen to be $\sigma = 1$ nm.

Even though the same selection of the underlying roughness model can be done for GISAS computations, we recommend to always use the default ($tanh$) for those simulations.
 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
#!/usr/bin/env python3
"""
Example of simulating a rough sample with a
tanh and Nevot-Croce roughness model using BornAgain.

"""

from matplotlib import pyplot as plt
import bornagain as ba
from bornagain import deg, angstrom, nm


def get_sample(roughness_model):
    """
    Defines sample and returns it
    """

    # creating materials
    m_ambient = ba.MaterialBySLD("Ambient", 0.0, 0.0)
    m_ti = ba.MaterialBySLD("Ti", -1.9493e-06, 0.0)
    m_ni = ba.MaterialBySLD("Ni", 9.4245e-06, 0.0)
    m_substrate = ba.MaterialBySLD("SiSubstrate", 2.0704e-06, 0.0)

    # creating layers
    ambient_layer = ba.Layer(m_ambient)
    ti_layer = ba.Layer(m_ti, 30*angstrom)
    ni_layer = ba.Layer(m_ni, 70*angstrom)
    substrate_layer = ba.Layer(m_substrate)

    # defining roughness
    roughness = ba.LayerRoughness()
    roughness.setSigma(1.0*nm)

    # creating multilayer
    multi_layer = ba.MultiLayer()
    multi_layer.addLayer(ambient_layer)
    for i in range(10):
        multi_layer.addLayerWithTopRoughness(ti_layer, roughness)
        multi_layer.addLayerWithTopRoughness(ni_layer, roughness)
    multi_layer.addLayerWithTopRoughness(substrate_layer, roughness)

    multi_layer.setRoughnessModel(roughness_model)

    return multi_layer


def get_simulation(sample, scan_size=500):
    """
    Defines and returns a specular simulation.
    """
    simulation = ba.SpecularSimulation()
    scan = ba.AngularSpecScan(1.54*angstrom, scan_size, 0.0*deg, 2.0*deg)
    simulation.setScan(scan)
    simulation.setSample(sample)
    return simulation


def run_simulation(roughness_model=ba.RoughnessModel.TANH):
    """
    Runs simulation and returns its result.
    """
    sample = get_sample(roughness_model)
    simulation = get_simulation(sample)
    simulation.runSimulation()
    return simulation.result()


def plot(result_tanh, result_nevot_croce):

    plt.semilogy(result_nevot_croce.axis(),
                 result_nevot_croce.array(),
                 label="Névot-Croce")
    plt.semilogy(result_tanh.axis(), result_tanh.array(), label="Tanh")

    plt.xlabel(r'$\alpha_i \; (deg)$', fontsize=12)
    plt.ylabel(r'Intensity', fontsize=12)

    plt.legend()
    plt.show()


if __name__ == '__main__':
    result_tanh = run_simulation(roughness_model=ba.RoughnessModel.TANH)
    result_nevot_croce = run_simulation(
        roughness_model=ba.RoughnessModel.NEVOT_CROCE)
    plot(result_tanh, result_nevot_croce)
RoughnessModel.py