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 ba_plot as bp, 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)
bp.plot2d_to_grid(results, 2, unit_aspect=1)
bp.plt.show()
|