source: sasmodels/sasmodels/models/core_shell_ellipsoid.py @ 30b60d2

core_shell_microgelscostrafo411magnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 30b60d2 was 30b60d2, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

allow build of both latex and html

  • Property mode set to 100644
File size: 8.4 KB
Line 
1r"""
2Definition
3----------
4
5Parameters for this model are the core axial ratio X and a shell thickness,
6which are more often what we would like to determine and makes the model
7better behaved, particularly when polydispersity is applied than the four
8independent radii used in the original parameterization of this model.
9
10
11.. figure:: img/core_shell_ellipsoid_geometry.png
12
13The geometric parameters of this model are shown in the diagram above, which
14shows (a) a cut through at the circular equator and (b) a cross section through
15the poles, of a prolate ellipsoid.
16
17When *X_core < 1* the core is oblate; when *X_core > 1* it is prolate.
18*X_core = 1* is a spherical core.
19
20For a fixed shell thickness *XpolarShell = 1*, to scale the shell thickness
21pro-rata with the radius set or constrain *XpolarShell = X_core*.
22
23When including an $S(q)$, the radius in $S(q)$ is calculated to be that of
24a sphere with the same 2nd virial coefficient of the outer surface of the
25ellipsoid. This may have some undesirable effects if the aspect ratio of the
26ellipsoid is large (ie, if $X << 1$ or $X >> 1$ ), when the $S(q)$
27- which assumes spheres - will not in any case be valid.  Generating a
28custom product model will enable separate effective volume fraction and effective
29radius in the $S(q)$.
30
31If SAS data are in absolute units, and the SLDs are correct, then scale should
32be the total volume fraction of the "outer particle". When $S(q)$ is introduced
33this moves to the $S(q)$ volume fraction, and scale should then be 1.0,
34or contain some other units conversion factor (for example, if you have SAXS data).
35
36The calculation of intensity follows that for the solid ellipsoid, but with separate
37terms for the core-shell and shell-solvent boundaries.
38
39.. math::
40
41    P(q,\alpha) = \frac{\text{scale}}{V} F^2(q,\alpha) + \text{background}
42
43where
44
45.. math::
46    :nowrap:
47
48    \begin{align*}
49    F(q,\alpha) = &f(q,radius\_equat\_core,radius\_equat\_core.x\_core,\alpha) \\
50    &+ f(q,radius\_equat\_core + thick\_shell,radius\_equat\_core.x\_core + thick\_shell.x\_polar\_shell,\alpha)
51    \end{align*}
52
53where
54
55.. math::
56
57    f(q,R_e,R_p,\alpha) = \frac{3 \Delta \rho V (\sin[qr(R_p,R_e,\alpha)]
58                - \cos[qr(R_p,R_e,\alpha)])}
59                {[qr(R_p,R_e,\alpha)]^3}
60
61and
62
63.. math::
64
65    r(R_e,R_p,\alpha) = \left[ R_e^2 \sin^2 \alpha
66        + R_p^2 \cos^2 \alpha \right]^{1/2}
67
68
69$\alpha$ is the angle between the axis of the ellipsoid and $\vec q$,
70$V = (4/3)\pi R_pR_e^2$ is the volume of the ellipsoid , $R_p$ is the polar radius along the
71rotational axis of the ellipsoid, $R_e$ is the equatorial radius perpendicular
72to the rotational axis of the ellipsoid and $\Delta \rho$ (contrast) is the
73scattering length density difference, either $(sld\_core - sld\_shell)$ or $(sld\_shell - sld\_solvent)$.
74
75For randomly oriented particles:
76
77.. math::
78
79   F^2(q)=\int_{0}^{\pi/2}{F^2(q,\alpha)\sin(\alpha)d\alpha}
80
81For oriented ellipsoids the *theta*, *phi* and *psi* orientation parameters will appear when fitting 2D data,
82see the :ref:`elliptical-cylinder` model for further information.
83
84References
85----------
86see for example:
87Kotlarchyk, M.; Chen, S.-H. J. Chem. Phys., 1983, 79, 2461.
88Berr, S.  J. Phys. Chem., 1987, 91, 4760.
89
90Authorship and Verification
91----------------------------
92
93* **Author:** NIST IGOR/DANSE **Date:** pre 2010
94* **Last Modified by:** Richard Heenan (reparametrised model) **Date:** 2015
95* **Last Reviewed by:** Richard Heenan **Date:** October 6, 2016
96
97"""
98
99from numpy import inf, sin, cos, pi
100
101name = "core_shell_ellipsoid"
102title = "Form factor for an spheroid ellipsoid particle with a core shell structure."
103description = """
104        [core_shell_ellipsoid] Calculates the form factor for an spheroid
105        ellipsoid particle with a core_shell structure.
106        The form factor is averaged over all possible
107        orientations of the ellipsoid such that P(q)
108        = scale*<f^2>/Vol + bkg, where f is the
109        single particle scattering amplitude.
110        [Parameters]:
111        radius_equat_core = equatorial radius of core,
112        x_core = ratio of core polar/equatorial radii,
113        thick_shell = equatorial radius of outer surface,
114        x_polar_shell = ratio of polar shell thickness to equatorial shell thickness,
115        sld_core = SLD_core
116        sld_shell = SLD_shell
117        sld_solvent = SLD_solvent
118        background = Incoherent bkg
119        scale =scale
120        Note:It is the users' responsibility to ensure
121        that shell radii are larger than core radii.
122        oblate: polar radius < equatorial radius
123        prolate :  polar radius > equatorial radius - this new model will make this easier
124        and polydispersity integrals more logical (as previously the shell could disappear).
125    """
126category = "shape:ellipsoid"
127
128# pylint: disable=bad-whitespace, line-too-long
129#             ["name", "units", default, [lower, upper], "type", "description"],
130parameters = [
131    ["radius_equat_core","Ang",     20,   [0, inf],   "volume",      "Equatorial radius of core"],
132    ["x_core",        "None",       3,   [0, inf],    "volume",      "axial ratio of core, X = r_polar/r_equatorial"],
133    ["thick_shell",   "Ang",       30,   [0, inf],    "volume",      "thickness of shell at equator"],
134    ["x_polar_shell", "",           1,   [0, inf],    "volume",      "ratio of thickness of shell at pole to that at equator"],
135    ["sld_core",      "1e-6/Ang^2", 2,   [-inf, inf], "sld",         "Core scattering length density"],
136    ["sld_shell",     "1e-6/Ang^2", 1,   [-inf, inf], "sld",         "Shell scattering length density"],
137    ["sld_solvent",   "1e-6/Ang^2", 6.3, [-inf, inf], "sld",         "Solvent scattering length density"],
138    ["theta",         "degrees",    0,   [-360, 360], "orientation", "elipsoid axis to beam angle"],
139    ["phi",           "degrees",    0,   [-360, 360], "orientation", "rotation about beam"],
140    ]
141# pylint: enable=bad-whitespace, line-too-long
142
143source = ["lib/sas_3j1x_x.c", "lib/gfn.c", "lib/gauss76.c",
144          "core_shell_ellipsoid.c"]
145
146def ER(radius_equat_core, x_core, thick_shell, x_polar_shell):
147    """
148        Returns the effective radius used in the S*P calculation
149    """
150    from .ellipsoid import ER as ellipsoid_ER
151    polar_outer = radius_equat_core*x_core + thick_shell*x_polar_shell
152    equat_outer = radius_equat_core + thick_shell
153    return ellipsoid_ER(polar_outer, equat_outer)
154
155def random():
156    import numpy as np
157    V = 10**np.random.uniform(5, 12)
158    outer_polar = 10**np.random.uniform(1.3, 4)
159    outer_equatorial = np.sqrt(V/outer_polar) # ignore 4/3 pi
160    # Use a distribution with a preference for thin shell or thin core
161    # Avoid core,shell radii < 1
162    thickness_polar = np.random.beta(0.5, 0.5)*(outer_polar-2) + 1
163    thickness_equatorial = np.random.beta(0.5, 0.5)*(outer_equatorial-2) + 1
164    radius_polar = outer_polar - thickness_polar
165    radius_equatorial = outer_equatorial - thickness_equatorial
166    x_core = radius_polar/radius_equatorial
167    x_polar_shell = thickness_polar/thickness_equatorial
168    pars = dict(
169        #background=0, sld=0, sld_solvent=1,
170        radius_equat_core=radius_equatorial,
171        x_core=x_core,
172        thick_shell=thickness_equatorial,
173        x_polar_shell=x_polar_shell,
174    )
175    return pars
176
177q = 0.1
178# tests had in old coords theta=0, phi=0; new coords theta=90, phi=0
179qx = q*cos(pi/6.0)
180qy = q*sin(pi/6.0)
181# 11Jan2017 RKH sorted tests after redefinition of angles
182tests = [
183     # Accuracy tests based on content in test/utest_coreshellellipsoidXTmodel.py
184    [{'radius_equat_core': 200.0,
185      'x_core': 0.1,
186      'thick_shell': 50.0,
187      'x_polar_shell': 0.2,
188      'sld_core': 2.0,
189      'sld_shell': 1.0,
190      'sld_solvent': 6.3,
191      'background': 0.001,
192      'scale': 1.0,
193     }, 1.0, 0.00189402],
194
195    # Additional tests with larger range of parameters
196    [{'background': 0.01}, 0.1, 11.6915],
197
198    [{'radius_equat_core': 20.0,
199      'x_core': 200.0,
200      'thick_shell': 54.0,
201      'x_polar_shell': 3.0,
202      'sld_core': 20.0,
203      'sld_shell': 10.0,
204      'sld_solvent': 6.0,
205      'background': 0.0,
206      'scale': 1.0,
207     }, 0.01, 8688.53],
208
209   # 2D tests
210   [{'background': 0.001,
211     'theta': 90.0,
212     'phi': 0.0,
213     }, (0.4, 0.5), 0.00690673],
214
215   [{'radius_equat_core': 20.0,
216      'x_core': 200.0,
217      'thick_shell': 54.0,
218      'x_polar_shell': 3.0,
219      'sld_core': 20.0,
220      'sld_shell': 10.0,
221      'sld_solvent': 6.0,
222      'background': 0.01,
223      'scale': 0.01,
224      'theta': 90.0,
225      'phi': 0.0,
226     }, (qx, qy), 0.01000025],
227    ]
Note: See TracBrowser for help on using the repository browser.