source: sasmodels/sasmodels/models/core_shell_bicelle_elliptical.py @ a34b811

ticket-1257-vesicle-productticket_1156ticket_822_more_unit_tests
Last change on this file since a34b811 was a34b811, checked in by Paul Kienzle <pkienzle@…>, 5 years ago

use radius_effective/radius_effective_mode/radius_effective_modes consistently throughout the code

  • Property mode set to 100644
File size: 8.4 KB
Line 
1r"""
2Definition
3----------
4
5This model provides the form factor for an elliptical cylinder with a
6core-shell scattering length density profile. Thus this is a variation
7of the core-shell bicelle model, but with an elliptical cylinder for the core.
8Outer shells on the rims and flat ends may be of different thicknesses and
9scattering length densities. The form factor is normalized by the total
10particle volume.
11
12.. figure:: img/core_shell_bicelle_geometry.png
13
14    Schematic cross-section of bicelle. Note however that the model here
15    calculates for rectangular, not curved, rims as shown below.
16
17.. figure:: img/core_shell_bicelle_parameters.png
18
19   Cross section of model used here. Users will have
20   to decide how to distribute "heads" and "tails" between the rim, face
21   and core regions in order to estimate appropriate starting parameters.
22
23Given the scattering length densities (sld) $\rho_c$, the core sld, $\rho_f$,
24the face sld, $\rho_r$, the rim sld and $\rho_s$ the solvent sld, the
25scattering length density variation along the bicelle axis is:
26
27.. math::
28
29    \rho(r) =
30      \begin{cases}
31      &\rho_c \text{ for } 0 \lt r \lt R; -L \lt z\lt L \\[1.5ex]
32      &\rho_f \text{ for } 0 \lt r \lt R; -(L+2t) \lt z\lt -L;
33      L \lt z\lt (L+2t) \\[1.5ex]
34      &\rho_r\text{ for } 0 \lt r \lt R; -(L+2t) \lt z\lt -L; L \lt z\lt (L+2t)
35      \end{cases}
36
37The form factor for the bicelle is calculated in cylindrical coordinates, where
38$\alpha$ is the angle between the $Q$ vector and the cylinder axis, and $\psi$
39is the angle for the ellipsoidal cross section core, to give:
40
41.. math::
42
43    I(Q,\alpha,\psi) = \frac{\text{scale}}{V_t} \cdot
44        F(Q,\alpha, \psi)^2 \cdot sin(\alpha) + \text{background}
45
46where a numerical integration of $F(Q,\alpha, \psi)^2 \cdot sin(\alpha)$
47is carried out over \alpha and \psi for:
48
49.. math::
50    :nowrap:
51
52    \begin{align*}
53    F(Q,\alpha,\psi) = &\bigg[
54    (\rho_c - \rho_f) V_c
55     \frac{2J_1(QR'sin \alpha)}{QR'sin\alpha}
56     \frac{sin(QLcos\alpha/2)}{Q(L/2)cos\alpha} \\
57    &+(\rho_f - \rho_r) V_{c+f}
58     \frac{2J_1(QR'sin\alpha)}{QR'sin\alpha}
59     \frac{sin(Q(L/2+t_f)cos\alpha)}{Q(L/2+t_f)cos\alpha} \\
60    &+(\rho_r - \rho_s) V_t
61     \frac{2J_1(Q(R'+t_r)sin\alpha)}{Q(R'+t_r)sin\alpha}
62     \frac{sin(Q(L/2+t_f)cos\alpha)}{Q(L/2+t_f)cos\alpha}
63    \bigg]
64    \end{align*}
65
66where
67
68.. math::
69
70    R'=\frac{R}{\sqrt{2}}\sqrt{(1+X_{core}^{2}) + (1-X_{core}^{2})cos(\psi)}
71
72
73and $V_t = \pi.(R+t_r)(Xcore.R+t_r)^2.(L+2.t_f)$ is the total volume of
74the bicelle, $V_c = \pi.Xcore.R^2.L$ the volume of the core,
75$V_{c+f} = \pi.Xcore.R^2.(L+2.t_f)$ the volume of the core plus the volume
76of the faces, $R$ is the radius of the core, $Xcore$ is the axial ratio of
77the core, $L$ the length of the core, $t_f$ the thickness of the face, $t_r$
78the thickness of the rim and $J_1$ the usual first order bessel function.
79The core has radii $R$ and $Xcore.R$ so is circular, as for the
80core_shell_bicelle model, for $Xcore$ =1. Note that you may need to
81limit the range of $Xcore$, especially if using the Monte-Carlo algorithm,
82as setting radius to $R/Xcore$ and axial ratio to $1/Xcore$ gives an
83equivalent solution!
84
85The output of the 1D scattering intensity function for randomly oriented
86bicelles is then given by integrating over all possible $\alpha$ and $\psi$.
87
88For oriented bicelles the *theta*, *phi* and *psi* orientation parameters will
89appear when fitting 2D data, see the :ref:`elliptical-cylinder` model
90for further information.
91
92.. figure:: img/elliptical_cylinder_angle_definition.png
93
94    Definition of the angles for the oriented core_shell_bicelle_elliptical particles.
95
96Model verified using Monte Carlo simulation for 1D and 2D scattering.
97
98References
99----------
100
101.. [#] L. Onsager, *Ann. New York Acad. Sci.*, 51 (1949) 627-659
102
103Source
104------
105
106`core_shell_bicelle_elliptical.py <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/core_shell_bicelle_elliptical.py>`_
107
108`core_shell_bicelle_elliptical.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/core_shell_bicelle_elliptical.c>`_
109
110Authorship and Verification
111----------------------------
112
113* **Author:** Richard Heenan **Date:** December 14, 2016
114* **Last Modified by:**  Richard Heenan **Date:** December 14, 2016
115* **Last Reviewed by:**  Paul Kienzle **Date:** Feb 28, 2018
116* **Source added by :**  Steve King **Date:** March 25, 2019
117"""
118
119import numpy as np
120from numpy import inf, sin, cos, pi
121
122name = "core_shell_bicelle_elliptical"
123title = "Elliptical cylinder with a core-shell scattering length density profile.."
124description = """
125    core_shell_bicelle_elliptical
126    Elliptical cylinder core, optional shell on the two flat faces, and shell of
127    uniform thickness on its rim (extending around the end faces).
128    Please see full documentation for equations and further details.
129    Involves a double numerical integral around the ellipsoid diameter
130    and the angle of the cylinder axis to Q.
131    Compare also the core_shell_bicelle and elliptical_cylinder models.
132      """
133category = "shape:cylinder"
134
135# pylint: disable=bad-whitespace, line-too-long
136#             ["name", "units", default, [lower, upper], "type", "description"],
137parameters = [
138    ["radius",         "Ang",       30, [0, inf],    "volume",      "Cylinder core radius r_minor"],
139    ["x_core",        "None",       3,  [0, inf],    "volume",      "Axial ratio of core, X = r_major/r_minor"],
140    ["thick_rim",  "Ang",            8, [0, inf],    "volume",      "Rim shell thickness"],
141    ["thick_face", "Ang",           14, [0, inf],    "volume",      "Cylinder face thickness"],
142    ["length",         "Ang",       50, [0, inf],    "volume",      "Cylinder length"],
143    ["sld_core",       "1e-6/Ang^2", 4, [-inf, inf], "sld",         "Cylinder core scattering length density"],
144    ["sld_face",       "1e-6/Ang^2", 7, [-inf, inf], "sld",         "Cylinder face scattering length density"],
145    ["sld_rim",        "1e-6/Ang^2", 1, [-inf, inf], "sld",         "Cylinder rim scattering length density"],
146    ["sld_solvent",    "1e-6/Ang^2", 6, [-inf, inf], "sld",         "Solvent scattering length density"],
147    ["theta",       "degrees",    90.0, [-360, 360], "orientation", "Cylinder axis to beam angle"],
148    ["phi",         "degrees",    0,    [-360, 360], "orientation", "Rotation about beam"],
149    ["psi",         "degrees",    0,    [-360, 360], "orientation", "Rotation about cylinder axis"]
150    ]
151
152# pylint: enable=bad-whitespace, line-too-long
153
154source = ["lib/sas_Si.c", "lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c",
155          "core_shell_bicelle_elliptical.c"]
156have_Fq = True
157radius_effective_modes = [
158    "equivalent cylinder excluded volume", "equivalent volume sphere",
159    "outer rim average radius", "outer rim min radius",
160    "outer max radius", "half outer thickness", "half diagonal",
161    ]
162
163def random():
164    """Return a random parameter set for the model."""
165    outer_major = 10**np.random.uniform(1, 4.7)
166    outer_minor = 10**np.random.uniform(1, 4.7)
167    # Use a distribution with a preference for thin shell or thin core,
168    # limited by the minimum radius. Avoid core,shell radii < 1
169    min_radius = min(outer_major, outer_minor)
170    thick_rim = np.random.beta(0.5, 0.5)*(min_radius-2) + 1
171    radius_major = outer_major - thick_rim
172    radius_minor = outer_minor - thick_rim
173    radius = radius_major
174    x_core = radius_minor/radius_major
175    outer_length = 10**np.random.uniform(1, 4.7)
176    # Caps should be a small percentage of the total length, but at least one
177    # angstrom long.  Since outer length >= 10, the following will suffice
178    thick_face = 10**np.random.uniform(-np.log10(outer_length), -1)*outer_length
179    length = outer_length - thick_face
180    pars = dict(
181        radius=radius,
182        x_core=x_core,
183        thick_rim=thick_rim,
184        thick_face=thick_face,
185        length=length
186    )
187    return pars
188
189
190q = 0.1
191# april 6 2017, rkh added a 2d unit test, NOT READY YET pull #890 branch assume correct!
192qx = q*cos(pi/6.0)
193qy = q*sin(pi/6.0)
194
195tests = [
196    #[{'radius': 30.0, 'x_core': 3.0,
197    #  'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0}, 'ER', 1],
198    #[{'radius': 30.0, 'x_core': 3.0,
199    #  'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0}, 'VR', 1],
200
201    [{'radius': 30.0, 'x_core': 3.0,
202      'thick_rim': 8.0, 'thick_face': 14.0, 'length': 50.0,
203      'sld_core': 4.0, 'sld_face': 7.0, 'sld_rim': 1.0,
204      'sld_solvent': 6.0, 'background': 0.0},
205     0.015, 286.540286],
206    #[{'theta':80., 'phi':10.}, (qx, qy), 7.88866563001],
207]
208
209del qx, qy  # not necessary to delete, but cleaner
Note: See TracBrowser for help on using the repository browser.