1 | # cylinder model |
---|
2 | # Note: model title and parameter table are inserted automatically |
---|
3 | r""" |
---|
4 | |
---|
5 | ... |
---|
6 | """ |
---|
7 | |
---|
8 | import sys |
---|
9 | sys.path.append('/usr/local/lib/python2.7/site-packages/') |
---|
10 | |
---|
11 | import numpy as np # type: ignore |
---|
12 | from numpy import pi, inf # type: ignore |
---|
13 | import mpmath |
---|
14 | import scipy |
---|
15 | |
---|
16 | name = "hexagonal_cylinder" |
---|
17 | title = "Circular cylinder in a hexagonal lattice" |
---|
18 | description = """ |
---|
19 | |
---|
20 | I(q) = scale*P(q)*S(q) + background |
---|
21 | where S(q) is the structure factor for a hexagonal lattice. |
---|
22 | """ |
---|
23 | category = "shape-independent" |
---|
24 | |
---|
25 | # [ "name", "units", default, [lower, upper], "type", "description"], |
---|
26 | parameters = [["length", "Ang", 5000, [0, inf], "","Cylinder length"], |
---|
27 | ["radius", "Ang", 150, [0, inf], "","Cylinder radius"], |
---|
28 | ["a", "Ang", 500, [0, inf], "","Lattice parameter"], |
---|
29 | ["D", "Ang", 5000, [0, inf], "","Size of the ordered domain"], |
---|
30 | ["Rsigma", "", 0.1, [0, inf], "","Polydispersity of radii"], |
---|
31 | ["Asigma", "", 0.002, [0, inf], "","Disorder parameter"], |
---|
32 | ["c", "", 6, [0, inf], "","Correction for Porod invariant"], |
---|
33 | ] |
---|
34 | |
---|
35 | #source = ["hexagonal_cylinder.c"] |
---|
36 | |
---|
37 | def Reflections(hmax): |
---|
38 | nReflections = (hmax+1)*(hmax+2)/2-1; |
---|
39 | reflections = np.empty([nReflections,4]) |
---|
40 | N = -1 |
---|
41 | for h in range(1,hmax+1): |
---|
42 | for k in range(h+1): |
---|
43 | N += 1 |
---|
44 | reflections[N,0] = h |
---|
45 | reflections[N,1] = k |
---|
46 | reflections[N,3] = 1 # f_hkl |
---|
47 | |
---|
48 | ### m_hkl |
---|
49 | if abs(h)==abs(k): |
---|
50 | reflections[N,2] = 6 |
---|
51 | elif h==0: |
---|
52 | reflections[N,2] = 6 |
---|
53 | elif k==0: |
---|
54 | reflections[N,2] = 6 |
---|
55 | else: |
---|
56 | reflections[N,2] = 12 |
---|
57 | |
---|
58 | return reflections |
---|
59 | |
---|
60 | def LatticeFactor(q,a,D,c): |
---|
61 | d = 2 |
---|
62 | n = 1 |
---|
63 | delta = 2*np.pi/D |
---|
64 | vd = np.sqrt(3)/2*a**2 |
---|
65 | Omega_d = 2*np.pi |
---|
66 | hmax = 7 |
---|
67 | |
---|
68 | reflections = Reflections(hmax) |
---|
69 | h_seq = reflections[:,0] |
---|
70 | k_seq = reflections[:,1] |
---|
71 | m_hkl = reflections[:,2] |
---|
72 | f_hkl = reflections[:,3] |
---|
73 | |
---|
74 | Z0 = 0 |
---|
75 | for ii in range(h_seq.shape[0]): |
---|
76 | h = h_seq[ii] |
---|
77 | k = k_seq[ii] |
---|
78 | q_hkl = (4*np.pi)/(a*np.sqrt(3))*np.sqrt(h**2 + h*k + k**2) |
---|
79 | x = q - q_hkl |
---|
80 | |
---|
81 | L_hkl = 1/np.pi * (delta/2)/(x**2 + (delta/2)**2) # Lorentzian peak shape |
---|
82 | #L_hkl = 2/(np.pi*delta)*np.exp(-(4*x**2)/(np.pi*delta**2)) # Gaussian peak shape |
---|
83 | |
---|
84 | dZ = m_hkl[ii]*(f_hkl[ii]**2)*L_hkl |
---|
85 | Z0 += dZ |
---|
86 | Z0prefactor = (c*(2*np.pi)**(d-1))/(n*vd*Omega_d*q**(d-1)) |
---|
87 | Z0 = Z0prefactor*Z0 |
---|
88 | |
---|
89 | return Z0 |
---|
90 | |
---|
91 | def DebyeWaller(q,a,Asigma): |
---|
92 | abar = a |
---|
93 | G = np.exp(-(Asigma**2)*(abar**2)*(q**2)) |
---|
94 | #G = np.exp(-(q**2)) |
---|
95 | |
---|
96 | return G |
---|
97 | |
---|
98 | def betafactor(q,R,Rsigma): |
---|
99 | #beta = np.exp(-(Rsigma**2)*(R**2)*(q**2)) |
---|
100 | |
---|
101 | z = 1/(Rsigma**2) - 1 |
---|
102 | Rbar = R |
---|
103 | Rz = Rbar/(1+z) |
---|
104 | |
---|
105 | a1 = 3.0/2.0 |
---|
106 | a2 = (z+1)/2.0 |
---|
107 | a3 = (z+2)/2.0 |
---|
108 | b1 = 2.0 |
---|
109 | b2 = 3.0 |
---|
110 | x1 = -4.0*(q**2)*(Rz**2) |
---|
111 | avgFd2perp = mpmath.hyp3f2(a1,a2,a3,b1,b2,x1) |
---|
112 | |
---|
113 | x2 = -(q**2)*(Rz**2) |
---|
114 | avgFdperp = mpmath.hyp2f1(a2,a3,b1,x2) |
---|
115 | |
---|
116 | beta = (avgFdperp**2)/avgFd2perp |
---|
117 | |
---|
118 | return beta, avgFd2perp |
---|
119 | |
---|
120 | def Iq(q, length, radius, a, D, Rsigma, Asigma, c): |
---|
121 | """ |
---|
122 | :param q: Input q-value |
---|
123 | :param length: Intrecept in linear model |
---|
124 | :return: Calculated Intensity |
---|
125 | """ |
---|
126 | |
---|
127 | # Structure factor |
---|
128 | Z0 = LatticeFactor(q,a,D,c) |
---|
129 | G = DebyeWaller(q,a,Asigma) |
---|
130 | beta,avgFd2perp = betafactor(q,radius,Rsigma) |
---|
131 | |
---|
132 | S = 1 + beta*(Z0-1)*G |
---|
133 | |
---|
134 | ## Form factor |
---|
135 | si,ci = scipy.special.sici(q*length) |
---|
136 | F2dparallel_or = (2/q*length)*si - (np.sin(q*length/2.0)/(q*length/2))**2 |
---|
137 | P = avgFd2perp*F2dparallel_or |
---|
138 | |
---|
139 | ## Intensity |
---|
140 | I = S*P |
---|
141 | |
---|
142 | return I |
---|
143 | |
---|
144 | def Iqxy(qx, qy, *args): |
---|
145 | """ |
---|
146 | :param qx: Input q_x-value |
---|
147 | :param qy: Input q_y-value |
---|
148 | :param args: Remaining arguments |
---|
149 | :return: 2D-Intensity |
---|
150 | """ |
---|
151 | |
---|
152 | return Iq(qx, *args)*Iq(qy, *args) |
---|
153 | |
---|
154 | |
---|
155 | # ER defaults to 1.0 |
---|
156 | |
---|
157 | # VR defaults to 1.0 |
---|
158 | |
---|
159 | demo = dict(scale=1, background=0, length=50) |
---|
160 | |
---|
161 | |
---|
162 | |
---|
163 | |
---|
164 | |
---|
165 | |
---|
166 | |
---|
167 | |
---|
168 | |
---|
169 | |
---|
170 | |
---|
171 | |
---|
172 | |
---|
173 | |
---|
174 | |
---|
175 | |
---|
176 | |
---|
177 | |
---|
178 | |
---|