[66d119f] | 1 | r""" |
---|
| 2 | Definition |
---|
| 3 | ---------- |
---|
| 4 | |
---|
[98ce141] | 5 | This model provides the form factor, $P(q)$, for stacked discs (tactoids) |
---|
| 6 | with a core/layer structure which is constructed itself as $P(q) S(Q)$ |
---|
| 7 | multiplying a $P(q)$ for individual core/layer disks by a structure factor |
---|
| 8 | $S(q)$ proposed by Kratky and Porod in 1949\ [#CIT1949]_ assuming the next |
---|
| 9 | neighbor distance (d-spacing) in the stack of parallel discs obeys a Gaussian |
---|
| 10 | distribution. As such the normalization of this "composite" form factor is |
---|
| 11 | relative to the individual disk volume, not the volume of the stack of disks. |
---|
[2d81cfe] | 12 | This model is appropriate for example for non non exfoliated clay particles |
---|
| 13 | such as Laponite. |
---|
[98ce141] | 14 | |
---|
[5111921] | 15 | .. figure:: img/stacked_disks_geometry.png |
---|
[66d119f] | 16 | |
---|
[98ce141] | 17 | Geometry of a single core/layer disk |
---|
| 18 | |
---|
[66d119f] | 19 | The scattered intensity $I(q)$ is calculated as |
---|
| 20 | |
---|
| 21 | .. math:: |
---|
| 22 | |
---|
| 23 | I(q) = N\int_{0}^{\pi /2}\left[ \Delta \rho_t |
---|
[98ce141] | 24 | \left( V_t f_t(q,\alpha) - V_c f_c(q,\alpha)\right) + \Delta |
---|
| 25 | \rho_c V_c f_c(q,\alpha)\right]^2 S(q,\alpha)\sin{\alpha}\ d\alpha |
---|
| 26 | + \text{background} |
---|
[66d119f] | 27 | |
---|
| 28 | where the contrast |
---|
| 29 | |
---|
| 30 | .. math:: |
---|
| 31 | |
---|
[40a87fa] | 32 | \Delta \rho_i = \rho_i - \rho_\text{solvent} |
---|
[66d119f] | 33 | |
---|
[2d81cfe] | 34 | and $N$ is the number of individual (single) discs per unit volume, $\alpha$ |
---|
| 35 | is the angle between the axis of the disc and $q$, and $V_t$ and $V_c$ are the |
---|
[98ce141] | 36 | total volume and the core volume of a single disc, respectively, and |
---|
[66d119f] | 37 | |
---|
| 38 | .. math:: |
---|
| 39 | |
---|
[98ce141] | 40 | f_t(q,\alpha) = |
---|
[40a87fa] | 41 | \left(\frac{\sin(q(d+h)\cos{\alpha})}{q(d+h)\cos{\alpha}}\right) |
---|
[66d119f] | 42 | \left(\frac{2J_1(qR\sin{\alpha})}{qR\sin{\alpha}} \right) |
---|
| 43 | |
---|
[98ce141] | 44 | f_c(q,\alpha) = |
---|
[40a87fa] | 45 | \left(\frac{\sin(qh)\cos{\alpha})}{qh\cos{\alpha}}\right) |
---|
| 46 | \left(\frac{2J_1(qR\sin{\alpha})}{qR\sin{\alpha}}\right) |
---|
[66d119f] | 47 | |
---|
[a807206] | 48 | where $d$ = thickness of the layer (*thick_layer*), |
---|
| 49 | $2h$ = core thickness (*thick_core*), and $R$ = radius of the disc (*radius*). |
---|
[66d119f] | 50 | |
---|
| 51 | .. math:: |
---|
| 52 | |
---|
[98ce141] | 53 | S(q,\alpha) = 1 + \frac{1}{2}\sum_{k=1}^n(n-k)\cos{(kDq\cos{\alpha})} |
---|
| 54 | \exp\left[ -k(q)^2(D\cos{\alpha}~\sigma_d)^2/2\right] |
---|
[66d119f] | 55 | |
---|
[40a87fa] | 56 | where $n$ is the total number of the disc stacked (*n_stacking*), |
---|
| 57 | $D = 2(d+h)$ is the next neighbor center-to-center distance (d-spacing), |
---|
[7c57861] | 58 | and $\sigma_d$ = the Gaussian standard deviation of the d-spacing (*sigma_d*). |
---|
[98ce141] | 59 | Note that $D\cos(\alpha)$ is the component of $D$ parallel to $q$ and the last |
---|
[f3073b0] | 60 | term in the equation above is effectively a Debye-Waller factor term. |
---|
[66d119f] | 61 | |
---|
| 62 | .. note:: |
---|
[98ce141] | 63 | |
---|
| 64 | 1. Each assembly in the stack is layer/core/layer, so the spacing of the |
---|
[40a87fa] | 65 | cores is core plus two layers. The 2nd virial coefficient of the cylinder |
---|
| 66 | is calculated based on the *radius* and *length* |
---|
[a807206] | 67 | = *n_stacking* * (*thick_core* + 2 * *thick_layer*) |
---|
[66d119f] | 68 | values, and used as the effective radius for $S(Q)$ when $P(Q) * S(Q)$ |
---|
| 69 | is applied. |
---|
| 70 | |
---|
[98ce141] | 71 | 2. the resolution smearing calculation uses 76 Gaussian quadrature points |
---|
| 72 | to properly smear the model since the function is HIGHLY oscillatory, |
---|
| 73 | especially around the q-values that correspond to the repeat distance of |
---|
| 74 | the layers. |
---|
| 75 | |
---|
[110f69c] | 76 | 2d scattering from oriented stacks is calculated in the same way as for |
---|
| 77 | cylinders, for further details of the calculation and angular dispersions |
---|
| 78 | see :ref:`orientation`. |
---|
[66d119f] | 79 | |
---|
[9802ab3] | 80 | .. figure:: img/cylinder_angle_definition.png |
---|
[66d119f] | 81 | |
---|
[eda8b30] | 82 | Angles $\theta$ and $\phi$ orient the stack of discs relative |
---|
[110f69c] | 83 | to the beam line coordinates, where the beam is along the $z$ axis. |
---|
| 84 | Rotation $\theta$, initially in the $xz$ plane, is carried out first, |
---|
| 85 | then rotation $\phi$ about the $z$ axis. Orientation distributions are |
---|
| 86 | described as rotations about two perpendicular axes $\delta_1$ and |
---|
| 87 | $\delta_2$ in the frame of the cylinder itself, which when |
---|
| 88 | $\theta = \phi = 0$ are parallel to the $Y$ and $X$ axes. |
---|
[66d119f] | 89 | |
---|
| 90 | |
---|
[98ce141] | 91 | Our model is derived from the form factor calculations implemented in a |
---|
[07300ea] | 92 | c-library provided by the NIST Center for Neutron Research\ [#CIT_Kline]_ |
---|
[66d119f] | 93 | |
---|
[e664a11] | 94 | References |
---|
| 95 | ---------- |
---|
[66d119f] | 96 | |
---|
[98ce141] | 97 | .. [#CIT1949] O Kratky and G Porod, *J. Colloid Science*, 4, (1949) 35 |
---|
| 98 | .. [#CIT_Kline] S R Kline, *J Appl. Cryst.*, 39 (2006) 895 |
---|
| 99 | .. [#] J S Higgins and H C Benoit, *Polymers and Neutron Scattering*, |
---|
| 100 | Clarendon, Oxford, 1994 |
---|
| 101 | .. [#] A Guinier and G Fournet, *Small-Angle Scattering of X-Rays*, |
---|
| 102 | John Wiley and Sons, New York, 1955 |
---|
[53215cf] | 103 | |
---|
[98ce141] | 104 | Authorship and Verification |
---|
| 105 | ---------------------------- |
---|
[53215cf] | 106 | |
---|
[98ce141] | 107 | * **Author:** NIST IGOR/DANSE **Date:** pre 2010 |
---|
[ef07e95] | 108 | * **Last Modified by:** Paul Butler and Paul Kienzle **Date:** November 26, 2016 |
---|
| 109 | * **Last Reviewed by:** Paul Butler and Paul Kienzle **Date:** November 26, 2016 |
---|
[66d119f] | 110 | """ |
---|
| 111 | |
---|
[2d81cfe] | 112 | import numpy as np |
---|
[0b56f38] | 113 | from numpy import inf, sin, cos, pi |
---|
[66d119f] | 114 | |
---|
| 115 | name = "stacked_disks" |
---|
[98ce141] | 116 | title = "Form factor for a stacked set of non exfoliated core/shell disks" |
---|
[66d119f] | 117 | description = """\ |
---|
| 118 | One layer of disk consists of a core, a top layer, and a bottom layer. |
---|
| 119 | radius = the radius of the disk |
---|
[a807206] | 120 | thick_core = thickness of the core |
---|
| 121 | thick_layer = thickness of a layer |
---|
[e664a11] | 122 | sld_core = the SLD of the core |
---|
| 123 | sld_layer = the SLD of the layers |
---|
[66d119f] | 124 | n_stacking = the number of the disks |
---|
[7c57861] | 125 | sigma_d = Gaussian STD of d-spacing |
---|
[e664a11] | 126 | sld_solvent = the SLD of the solvent |
---|
[66d119f] | 127 | """ |
---|
| 128 | category = "shape:cylinder" |
---|
| 129 | |
---|
| 130 | # pylint: disable=bad-whitespace, line-too-long |
---|
| 131 | # ["name", "units", default, [lower, upper], "type","description"], |
---|
| 132 | parameters = [ |
---|
[a807206] | 133 | ["thick_core", "Ang", 10.0, [0, inf], "volume", "Thickness of the core disk"], |
---|
| 134 | ["thick_layer", "Ang", 10.0, [0, inf], "volume", "Thickness of layer each side of core"], |
---|
[66d119f] | 135 | ["radius", "Ang", 15.0, [0, inf], "volume", "Radius of the stacked disk"], |
---|
[edf1e8b] | 136 | ["n_stacking", "", 1.0, [1, inf], "volume", "Number of stacked layer/core/layer disks"], |
---|
[7c57861] | 137 | ["sigma_d", "Ang", 0, [0, inf], "", "Sigma of nearest neighbor spacing"], |
---|
[42356c8] | 138 | ["sld_core", "1e-6/Ang^2", 4, [-inf, inf], "sld", "Core scattering length density"], |
---|
| 139 | ["sld_layer", "1e-6/Ang^2", 0.0, [-inf, inf], "sld", "Layer scattering length density"], |
---|
| 140 | ["sld_solvent", "1e-6/Ang^2", 5.0, [-inf, inf], "sld", "Solvent scattering length density"], |
---|
[9b79f29] | 141 | ["theta", "degrees", 0, [-360, 360], "orientation", "Orientation of the stacked disk axis w/respect incoming beam"], |
---|
| 142 | ["phi", "degrees", 0, [-360, 360], "orientation", "Rotation about beam"], |
---|
[66d119f] | 143 | ] |
---|
| 144 | # pylint: enable=bad-whitespace, line-too-long |
---|
| 145 | |
---|
[43b7eea] | 146 | source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "stacked_disks.c"] |
---|
[66d119f] | 147 | |
---|
[8f04da4] | 148 | def random(): |
---|
| 149 | radius = 10**np.random.uniform(1, 4.7) |
---|
| 150 | total_stack = 10**np.random.uniform(1, 4.7) |
---|
| 151 | n_stacking = int(10**np.random.uniform(0, np.log10(total_stack)-1) + 0.5) |
---|
| 152 | d = total_stack/n_stacking |
---|
| 153 | thick_core = np.random.uniform(0, d-2) # at least 1 A for each layer |
---|
| 154 | thick_layer = (d - thick_core)/2 |
---|
| 155 | # Let polydispersity peak around 15%; 95% < 0.4; max=100% |
---|
| 156 | sigma_d = d * np.random.beta(1.5, 7) |
---|
| 157 | pars = dict( |
---|
| 158 | thick_core=thick_core, |
---|
| 159 | thick_layer=thick_layer, |
---|
| 160 | radius=radius, |
---|
| 161 | n_stacking=n_stacking, |
---|
| 162 | sigma_d=sigma_d, |
---|
| 163 | ) |
---|
| 164 | return pars |
---|
| 165 | |
---|
[66d119f] | 166 | demo = dict(background=0.001, |
---|
| 167 | scale=0.01, |
---|
[a807206] | 168 | thick_core=10.0, |
---|
| 169 | thick_layer=10.0, |
---|
[66d119f] | 170 | radius=15.0, |
---|
| 171 | n_stacking=1, |
---|
[7c57861] | 172 | sigma_d=0, |
---|
[e664a11] | 173 | sld_core=4, |
---|
| 174 | sld_layer=0.0, |
---|
| 175 | sld_solvent=5.0, |
---|
[b7e8b94] | 176 | theta=90, |
---|
[66d119f] | 177 | phi=0) |
---|
[b7e8b94] | 178 | # After redefinition of spherical coordinates - |
---|
| 179 | # tests had in old coords theta=0, phi=0; new coords theta=90, phi=0 |
---|
[0b56f38] | 180 | q = 0.1 |
---|
| 181 | # april 6 2017, rkh added a 2d unit test, assume correct! |
---|
| 182 | qx = q*cos(pi/6.0) |
---|
| 183 | qy = q*sin(pi/6.0) |
---|
[b7e8b94] | 184 | # Accuracy tests based on content in test/utest_extra_models.py. |
---|
[f3073b0] | 185 | # Added 2 tests with n_stacked = 5 using SasView 3.1.2 - PDB; |
---|
| 186 | # for which alas q=0.001 values seem closer to n_stacked=1 not 5, |
---|
| 187 | # changed assuming my 4.1 code OK, RKH |
---|
[bb4b509] | 188 | tests = [ |
---|
[b7e8b94] | 189 | [{'thick_core': 10.0, |
---|
| 190 | 'thick_layer': 15.0, |
---|
| 191 | 'radius': 3000.0, |
---|
| 192 | 'n_stacking': 1.0, |
---|
| 193 | 'sigma_d': 0.0, |
---|
| 194 | 'sld_core': 4.0, |
---|
| 195 | 'sld_layer': -0.4, |
---|
[bb4b509] | 196 | 'sld_solvent': 5.0, |
---|
[b7e8b94] | 197 | 'theta': 90.0, |
---|
| 198 | 'phi': 0.0, |
---|
| 199 | 'scale': 0.01, |
---|
| 200 | 'background': 0.001, |
---|
| 201 | }, 0.001, 5075.12], |
---|
| 202 | [{'thick_core': 10.0, |
---|
| 203 | 'thick_layer': 15.0, |
---|
| 204 | 'radius': 3000.0, |
---|
| 205 | 'n_stacking': 5, |
---|
| 206 | 'sigma_d': 0.0, |
---|
| 207 | 'sld_core': 4.0, |
---|
| 208 | 'sld_layer': -0.4, |
---|
[bb4b509] | 209 | 'sld_solvent': 5.0, |
---|
[b7e8b94] | 210 | 'theta': 90.0, |
---|
| 211 | 'phi': 0.0, |
---|
| 212 | 'scale': 0.01, |
---|
| 213 | 'background': 0.001, |
---|
[2d81cfe] | 214 | # n_stacking=1 not 5 ? slight change in value here 11jan2017, |
---|
| 215 | # check other cpu types |
---|
| 216 | #}, 0.001, 5065.12793824], |
---|
| 217 | #}, 0.001, 5075.11570493], |
---|
[b7e8b94] | 218 | }, 0.001, 25325.635693], |
---|
| 219 | [{'thick_core': 10.0, |
---|
| 220 | 'thick_layer': 15.0, |
---|
[0b56f38] | 221 | 'radius': 100.0, |
---|
| 222 | 'n_stacking': 5, |
---|
| 223 | 'sigma_d': 0.0, |
---|
| 224 | 'sld_core': 4.0, |
---|
| 225 | 'sld_layer': -0.4, |
---|
[bb4b509] | 226 | 'sld_solvent': 5.0, |
---|
[0b56f38] | 227 | 'theta': 90.0, |
---|
| 228 | 'phi': 20.0, |
---|
| 229 | 'scale': 0.01, |
---|
[bb4b509] | 230 | 'background': 0.001, |
---|
| 231 | }, (qx, qy), 0.0491167089952], |
---|
[0b56f38] | 232 | [{'thick_core': 10.0, |
---|
| 233 | 'thick_layer': 15.0, |
---|
[b7e8b94] | 234 | 'radius': 3000.0, |
---|
| 235 | 'n_stacking': 5, |
---|
| 236 | 'sigma_d': 0.0, |
---|
| 237 | 'sld_core': 4.0, |
---|
| 238 | 'sld_layer': -0.4, |
---|
[bb4b509] | 239 | 'sld_solvent': 5.0, |
---|
[b7e8b94] | 240 | 'theta': 90.0, |
---|
| 241 | 'phi': 0.0, |
---|
| 242 | 'scale': 0.01, |
---|
| 243 | 'background': 0.001, |
---|
[2d81cfe] | 244 | # n_stacking=1 not 5 ? slight change in value here 11jan2017, |
---|
| 245 | # check other cpu types |
---|
| 246 | #}, 0.164, 0.0127673597265], |
---|
| 247 | #}, 0.164, 0.01480812968], |
---|
[b7e8b94] | 248 | }, 0.164, 0.0598367986509], |
---|
| 249 | |
---|
| 250 | [{'thick_core': 10.0, |
---|
| 251 | 'thick_layer': 15.0, |
---|
| 252 | 'radius': 3000.0, |
---|
| 253 | 'n_stacking': 1.0, |
---|
| 254 | 'sigma_d': 0.0, |
---|
| 255 | 'sld_core': 4.0, |
---|
| 256 | 'sld_layer': -0.4, |
---|
[bb4b509] | 257 | 'sld_solvent': 5.0, |
---|
[b7e8b94] | 258 | 'theta': 90.0, |
---|
| 259 | 'phi': 0.0, |
---|
| 260 | 'scale': 0.01, |
---|
| 261 | 'background': 0.001, |
---|
[2d81cfe] | 262 | # second test here was at q=90, changed it to q=5, |
---|
| 263 | # note I(q) is then just value of flat background |
---|
[b7e8b94] | 264 | }, [0.001, 5.0], [5075.12, 0.001]], |
---|
| 265 | |
---|
| 266 | [{'thick_core': 10.0, |
---|
| 267 | 'thick_layer': 15.0, |
---|
| 268 | 'radius': 3000.0, |
---|
| 269 | 'n_stacking': 1.0, |
---|
| 270 | 'sigma_d': 0.0, |
---|
| 271 | 'sld_core': 4.0, |
---|
| 272 | 'sld_layer': -0.4, |
---|
[bb4b509] | 273 | 'sld_solvent': 5.0, |
---|
[b7e8b94] | 274 | 'theta': 90.0, |
---|
| 275 | 'phi': 0.0, |
---|
| 276 | 'scale': 0.01, |
---|
| 277 | 'background': 0.001, |
---|
| 278 | }, ([0.4, 0.5]), [0.00105074, 0.00121761]], |
---|
[2d81cfe] | 279 | #[{'thick_core': 10.0, |
---|
| 280 | # 'thick_layer': 15.0, |
---|
| 281 | # 'radius': 3000.0, |
---|
| 282 | # 'n_stacking': 1.0, |
---|
| 283 | # 'sigma_d': 0.0, |
---|
| 284 | # 'sld_core': 4.0, |
---|
| 285 | # 'sld_layer': -0.4, |
---|
| 286 | # 'sld_solvent': 5.0, |
---|
| 287 | # 'theta': 90.0, |
---|
| 288 | # 'phi': 20.0, |
---|
| 289 | # 'scale': 0.01, |
---|
| 290 | # 'background': 0.001, |
---|
| 291 | # 2017-05-18 PAK temporarily suppress output of qx,qy test; j1 is |
---|
| 292 | # not accurate for large qr |
---|
| 293 | # }, (qx, qy), 0.0341738733124], |
---|
| 294 | # }, (qx, qy), None], |
---|
[b7e8b94] | 295 | |
---|
| 296 | [{'thick_core': 10.0, |
---|
| 297 | 'thick_layer': 15.0, |
---|
| 298 | 'radius': 3000.0, |
---|
| 299 | 'n_stacking': 1.0, |
---|
| 300 | 'sigma_d': 0.0, |
---|
| 301 | 'sld_core': 4.0, |
---|
| 302 | 'sld_layer': -0.4, |
---|
[bb4b509] | 303 | 'sld_solvent': 5.0, |
---|
[b7e8b94] | 304 | 'theta': 90.0, |
---|
| 305 | 'phi': 0.0, |
---|
| 306 | 'scale': 0.01, |
---|
| 307 | 'background': 0.001, |
---|
| 308 | }, ([1.3, 1.57]), [0.0010039, 0.0010038]], |
---|
| 309 | ] |
---|
[1b85b55] | 310 | # 11Jan2017 RKH checking unit test again, note they are all 1D, no 2D |
---|