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
101
102
103
104
105
106
107
108
109
110
|
#!/usr/bin/env python3
"""
Generates random rough surface of the sample with the given
heights statistics and lateral roughness spectrum.
"""
import numpy as np
import bornagain as ba
from bornagain import nm, nm2, nm3
from matplotlib import gridspec
from bornagain.numpyutil import Arrayf64Converter as dac
def plot(h):
rms = np.std(surface)
fig = bp.plt.figure(figsize=(10, 6))
gs = gridspec.GridSpec(3, 2)
gs.update(left=0.1, right=0.48, wspace=0.15, hspace=0.5)
# map
fig.add_subplot(gs[:-1, :])
bp.plt.imshow(h, extent = [0, Lx, 0, Ly], cmap='inferno', aspect='auto')
bp.plt.colorbar()
# psd
fig.add_subplot(gs[-1, 0])
factor = X_points*Y_points/np.sqrt(Lx*Ly)
N = np.floor(X_points/2 + 1).astype(int)
psd = abs(np.fft.rfft2(h)/factor)**2
psd_points_x = np.array([psd[0][i] for i in range(1, N)])
f_points_x = np.array([i/Lx for i in range(1, N)])
bp.plt.plot(f_points_x, psd_points_x)
bp.plt.yscale('log')
bp.plt.xscale('log')
bp.plt.title('PSD')
bp.plt.xlabel('$\\nu, nm^{-1}$')
# hist
fig.add_subplot(gs[-1, 1])
bp.plt.hist(h.flatten(), range=[-4*rms, 4*rms],
bins=300, color='black')
bp.plt.title('Height histogram')
bp.plt.xlabel('h, nm')
bp.plt.tick_params(left = False, labelleft = False)
bp.plt.show()
def get_sample():
"""
A sample with one layer on a substrate, with partially
correlated roughnesses.
"""
# defining materials
vacuum = ba.RefractiveMaterial("ambience", 0, 0)
material_layer = ba.RefractiveMaterial("layer", 5e-6, 0)
material_substrate = ba.RefractiveMaterial("substrate", 15e-6, 0)
# defining roughness
height_distribution = ba.ErfTransient()
max_spat_freq = 0.5*nm
# for layer
omega = 1*nm3
a1 = 1
a2 = 10*nm
a3 = 100*nm2
a4 = 1000*nm3
autocorr_layer = ba.LinearGrowthModel(omega, a1, a2, a3, a4, max_spat_freq)
roughness_layer = ba.Roughness(autocorr_layer, height_distribution)
# for substrate
sigma = 0.9*nm
alpha = 0.5
xi = 35*nm
autocorr_sub = ba.SelfAffineFractalModel(sigma, alpha, xi, max_spat_freq)
roughness_sub = ba.Roughness(autocorr_sub, height_distribution)
# defining layers
l_ambience = ba.Layer(vacuum)
l_layer = ba.Layer(material_layer, 25*nm, roughness_layer)
l_substrate = ba.Layer(material_substrate, roughness_sub)
# adding layers
my_sample = ba.Sample()
my_sample.addLayer(l_ambience)
my_sample.addLayer(l_layer)
my_sample.addLayer(l_substrate)
return my_sample
if __name__ == '__main__':
# sample size
Lx = 1000*nm
Ly = 1000*nm
X_points = 512
Y_points = 512
sample = get_sample()
layer_index = 1 # top interface
seed = -1 # seed < 0 ==> random every time
# generate roughness map
roughness_map = ba.RoughnessMap(X_points, Y_points, Lx, Ly,
sample, layer_index, seed)
surface = dac.npArray(roughness_map.generate())
print("rms = {:.3}".format(np.std(surface)),"nm")
plot(surface)
bp.plt.show()
|