Polarized SANS

Result

Polarized SANS result

Sample

Polarized SANS 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
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = ["bornagain>=25,<26"]
# ///
"""
Polarized SANS from magnetic core-shell particles in four spin channels.
"""
import bornagain as ba
ba.require_versions("bornagain>=25,<26")
from bornagain import deg, nm, nm2, R3


def get_sample():
    """
    A sample with a magnetic core-shell particle in a solvent.
    """

    # Materials
    magnetization = R3(0, 1e6, 0)  # (A/m)
    core_color = (0.86, 0.24, 0.18)
    core_mat = ba.RefractiveMaterial("Core", core_color, 6e-06, 2e-08, magnetization)
    shell_color = (0.25, 0.65, 0.35)
    shell_mat = ba.RefractiveMaterial("Shell", shell_color, 1e-07, 2e-08)
    solvent_color = (0.90, 0.93, 0.97)
    solvent_mat = ba.RefractiveMaterial("Solvent", solvent_color, 5e-06, 0)

    # Core-shell particle
    core_radius = 10*nm
    shell_radius = 12*nm
    core = ba.Particle(core_mat, ba.Sphere(core_radius))
    core.translate(R3(0, 0, shell_radius - core_radius))
    shell = ba.Particle(shell_mat, ba.Sphere(shell_radius))
    particle = ba.CoreAndShell(core, shell)

    # Layers: two solvent layers, particles deposited at their interface
    layer_top = ba.Layer(solvent_mat)
    layer_bottom = ba.Layer(solvent_mat)
    layer_top.deposit2D(ba.Dilute2D(0.001/nm2, particle))

    # Sample
    sample = ba.Sample()
    sample.addLayer(layer_top)
    sample.addLayer(layer_bottom)

    return sample


def get_simulation(sample, polarizer, analyzer):
    """
    A SANS simulation for one polarization channel.
    """
    n = 200

    # Beam nearly parallel to the sample plane:
    beam = ba.Beam(1e9, 0.4*nm, 0.001*deg)

    # Detector opposite to source:
    detector = ba.SphericalDetector(n, -7*deg, 7*deg, n, -7*deg, 7*deg)

    beam.setPolarization(polarizer)
    detector.setAnalyzer(analyzer)

    simulation = ba.ScatteringSimulation(beam, sample, detector)
    # SANS form-factor scattering in solvent, not an averaged decorated layer.
    simulation.options().setUseAvgMaterials(False)
    return simulation


def simulate(polarizer, analyzer, title):
    """
    Runs one polarization channel.
    """
    sample = get_sample()
    result = get_simulation(sample, polarizer, analyzer).simulate()
    result.setTitle(title)
    return result


if __name__ == '__main__':
    spin_up = R3(0, 1, 0)
    spin_down = -spin_up
    channels = [
        ("$++$", spin_up, spin_up),
        ("$+-$", spin_up, spin_down),
        ("$-+$", spin_down, spin_up),
        ("$--$", spin_down, spin_down),
    ]
    results = [
        simulate(polarizer, analyzer, title)
        for title, polarizer, analyzer in channels
    ]
    ba.showSample3D(get_sample(), sample_size=120*nm, seed=0)

    ba.plot2d_to_grid(results, 2, unit_aspect=1)
    ba.plt.show()
auto/Examples/sas/PolarizedSANS.py