source: sasmodels/sasmodels/models/hollow_cylinder.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 months ago

use radius_effective/radius_effective_mode/radius_effective_modes consistently throughout the code

  • Property mode set to 100644
File size: 6.6 KB
Line 
1r"""
2Definition
3----------
4
5This model provides the form factor, $P(q)$, for a monodisperse hollow right
6angle circular cylinder (rigid tube) where the The inside and outside of the
7hollow cylinder are assumed to have the same SLD and the form factor is thus
8normalized by the volume of the tube (i.e. not by the total cylinder volume).
9
10.. math::
11
12    P(q) = \text{scale} \left<F^2\right>/V_\text{shell} + \text{background}
13
14where the averaging $\left<\ldots\right>$ is applied only for the 1D
15calculation. If Intensity is given on an absolute scale, the scale factor here
16is the volume fraction of the shell.  This differs from
17the :ref:`core-shell-cylinder` in that, in that case, scale is the volume
18fraction of the entire cylinder (core+shell). The application might be for a
19bilayer which wraps into a hollow tube and the volume fraction of material is
20all in the shell, whereas the :ref:`core-shell-cylinder` model might be used for
21a cylindrical micelle where the tails in the core have a different SLD than the
22headgroups (in the shell) and the volume fraction of material comes fromm the
23whole cyclinder.  NOTE: the hollow_cylinder represents a tube whereas the
24core_shell_cylinder includes a shell layer covering the ends (end caps) as well.
25
26
27The 1D scattering intensity is calculated in the following way (Guinier, 1955)
28
29.. math::
30
31    P(q)           &= (\text{scale})V_\text{shell}\Delta\rho^2
32            \int_0^{1}\Psi^2
33            \left[q_z, R_\text{outer}(1-x^2)^{1/2},
34                       R_\text{core}(1-x^2)^{1/2}\right]
35            \left[\frac{\sin(qHx)}{qHx}\right]^2 dx \\
36    \Psi[q,y,z]    &= \frac{1}{1-\gamma^2}
37            \left[ \Lambda(qy) - \gamma^2\Lambda(qz) \right] \\
38    \Lambda(a)     &= 2 J_1(a) / a \\
39    \gamma         &= R_\text{core} / R_\text{outer} \\
40    V_\text{shell} &= \pi \left(R_\text{outer}^2 - R_\text{core}^2 \right)L \\
41    J_1(x)         &= (\sin(x)-x\cdot \cos(x)) / x^2
42
43where *scale* is a scale factor, $H = L/2$ and $J_1$ is the 1st order
44Bessel function.
45
46**NB**: The 2nd virial coefficient of the cylinder is calculated
47based on the outer radius and full length, which give an the effective radius
48for structure factor $S(q)$ when $P(q) \cdot S(q)$ is applied.
49
50In the parameters,the *radius* is $R_\text{core}$ while *thickness*
51is $R_\text{outer} - R_\text{core}$.
52
53To provide easy access to the orientation of the core-shell cylinder, we define
54the axis of the cylinder using two angles $\theta$ and $\phi$
55(see :ref:`cylinder model <cylinder-angle-definition>`).
56
57References
58----------
59
60.. [#] L A Feigin and D I Svergun, *Structure Analysis by Small-Angle X-Ray and
61   Neutron Scattering*, Plenum Press, New York, (1987)
62.. [#] L. Onsager, *Ann. New York Acad. Sci.*, 51 (1949) 627-659
63
64Source
65------
66
67`hollow_cylinder.py <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/hollow_cylinder.py>`_
68
69`hollow_cylinder.c <https://github.com/SasView/sasmodels/blob/master/sasmodels/models/hollow_cylinder.c>`_
70
71Authorship and Verification
72----------------------------
73
74* **Author:** NIST IGOR/DANSE **Date:** pre 2010
75* **Last Modified by:** Paul Butler **Date:** September 06, 2018
76   (corrected VR calculation)
77* **Last Reviewed by:** Paul Butler **Date:** September 06, 2018
78* **Source added by :** Steve King **Date:** March 25, 2019
79"""
80from __future__ import division
81
82import numpy as np
83from numpy import pi, inf, sin, cos
84
85name = "hollow_cylinder"
86title = ""
87description = """
88P(q) = scale*<f*f>/Vol + background, where f is the scattering amplitude.
89radius = the radius of core
90thickness = the thickness of shell
91length = the total length of the cylinder
92sld = SLD of the shell
93sld_solvent = SLD of the solvent
94background = incoherent background
95"""
96category = "shape:cylinder"
97# pylint: disable=bad-whitespace, line-too-long
98#   ["name", "units", default, [lower, upper], "type","description"],
99parameters = [
100    ["radius",      "Ang",     20.0, [0, inf],    "volume",      "Cylinder core radius"],
101    ["thickness",   "Ang",     10.0, [0, inf],    "volume",      "Cylinder wall thickness"],
102    ["length",      "Ang",    400.0, [0, inf],    "volume",      "Cylinder total length"],
103    ["sld",         "1e-6/Ang^2",  6.3, [-inf, inf], "sld",         "Cylinder sld"],
104    ["sld_solvent", "1e-6/Ang^2",  1,   [-inf, inf], "sld",         "Solvent sld"],
105    ["theta",       "degrees", 90,   [-360, 360], "orientation", "Cylinder axis to beam angle"],
106    ["phi",         "degrees",  0,   [-360, 360], "orientation", "Rotation about beam"],
107    ]
108# pylint: enable=bad-whitespace, line-too-long
109
110source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"]
111have_Fq = True
112radius_effective_modes = [
113    "excluded volume", "equivalent outer volume sphere",
114    "outer radius", "half length",
115    "half outer min dimension", "half outer max dimension",
116    "half outer diagonal",
117    ]
118
119def random():
120    """Return a random parameter set for the model."""
121    length = 10**np.random.uniform(1, 4.7)
122    outer_radius = 10**np.random.uniform(1, 4.7)
123    # Use a distribution with a preference for thin shell or thin core
124    # Avoid core,shell radii < 1
125    thickness = np.random.beta(0.5, 0.5)*(outer_radius-2) + 1
126    radius = outer_radius - thickness
127    pars = dict(
128        length=length,
129        radius=radius,
130        thickness=thickness,
131    )
132    return pars
133
134# parameters for demo
135demo = dict(scale=1.0, background=0.0, length=400.0, radius=20.0,
136            thickness=10, sld=6.3, sld_solvent=1, theta=90, phi=0,
137            thickness_pd=0.2, thickness_pd_n=9,
138            length_pd=.2, length_pd_n=10,
139            radius_pd=.2, radius_pd_n=9,
140            theta_pd=10, theta_pd_n=5,
141           )
142
143def r_eff(radius, thickness, length):
144    """R_eff from excluded volume"""
145    radius += thickness
146    return (0.5*(0.75*radius*(2.0*radius*length
147                              + (radius + length)*(pi*radius + length))
148                )**(1./3.))
149
150def shell_volume(radius, thickness, length):
151    """shell volume for parameter set"""
152    return pi*((radius+thickness)**2-radius**2)*length
153
154def form_shell_ratio(radius, thickness, length):
155    """form:shell ratio"""
156    return (radius+thickness)**2/((radius+thickness)**2 - radius**2)
157
158q = 0.1
159# april 6 2017, rkh added a 2d unit test, assume correct!
160qx = q*cos(pi/6.0)
161qy = q*sin(pi/6.0)
162test_pars = [
163    parameters[0][2], # radius
164    parameters[1][2], # thickness
165    parameters[2][2], # length
166]
167# Parameters for unit tests
168tests = [
169    [{}, 0.00005, 1764.926],
170    [{}, 0.1, None, None,
171     r_eff(*test_pars), shell_volume(*test_pars), form_shell_ratio(*test_pars),
172    ],
173    [{}, 0.001, 1756.76],
174    [{}, (qx, qy), 2.36885476192],
175]
176del qx, qy, test_pars  # not necessary to delete, but cleaner
Note: See TracBrowser for help on using the repository browser.