source: sasmodels/sasmodels/models/hollow_cylinder.py @ 2cc8aa2

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 2cc8aa2 was 2cc8aa2, checked in by richardh, 6 years ago

fixed ER bug in elliptical_cylinder, commented out ER, VR unit tests in 7 models, unit tests now pass

  • Property mode set to 100644
File size: 6.4 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
63Authorship and Verification
64----------------------------
65
66* **Author:** NIST IGOR/DANSE **Date:** pre 2010
67* **Last Modified by:** Paul Butler **Date:** September 06, 2018
68   (corrected VR calculation)
69* **Last Reviewed by:** Paul Butler **Date:** September 06, 2018
70"""
71
72import numpy as np
73from numpy import pi, inf, sin, cos
74
75name = "hollow_cylinder"
76title = ""
77description = """
78P(q) = scale*<f*f>/Vol + background, where f is the scattering amplitude.
79radius = the radius of core
80thickness = the thickness of shell
81length = the total length of the cylinder
82sld = SLD of the shell
83sld_solvent = SLD of the solvent
84background = incoherent background
85"""
86category = "shape:cylinder"
87# pylint: disable=bad-whitespace, line-too-long
88#   ["name", "units", default, [lower, upper], "type","description"],
89parameters = [
90    ["radius",      "Ang",     20.0, [0, inf],    "volume",      "Cylinder core radius"],
91    ["thickness",   "Ang",     10.0, [0, inf],    "volume",      "Cylinder wall thickness"],
92    ["length",      "Ang",    400.0, [0, inf],    "volume",      "Cylinder total length"],
93    ["sld",         "1e-6/Ang^2",  6.3, [-inf, inf], "sld",         "Cylinder sld"],
94    ["sld_solvent", "1e-6/Ang^2",  1,   [-inf, inf], "sld",         "Solvent sld"],
95    ["theta",       "degrees", 90,   [-360, 360], "orientation", "Cylinder axis to beam angle"],
96    ["phi",         "degrees",  0,   [-360, 360], "orientation", "Rotation about beam"],
97    ]
98# pylint: enable=bad-whitespace, line-too-long
99
100source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"]
101have_Fq = True
102effective_radius_type = ["equivalent sphere","outer radius","half length",
103                         "half outer min dimension","half outer max dimension","half outer diagonal"]
104
105# pylint: disable=W0613
106#def ER(radius, thickness, length):
107#    """
108#    :param radius:      Cylinder core radius
109#    :param thickness:   Cylinder wall thickness
110#    :param length:      Cylinder length
111#    :return:            Effective radius
112#    """
113#    router = radius + thickness
114#    if router == 0 or length == 0:
115#        return 0.0
116#    len1 = router
117#    len2 = length/2.0
118#    term1 = len1*len1*2.0*len2/2.0
119#    term2 = 1.0 + (len2/len1)*(1.0 + 1/len2/2.0)*(1.0 + pi*len1/len2/2.0)
120#    ddd = 3.0*term1*term2
121#    diam = pow(ddd, (1.0/3.0))
122#    return diam
123
124def VR(radius, thickness, length):
125    """
126    :param radius:      Cylinder radius
127    :param thickness:   Cylinder wall thickness
128    :param length:      Cylinder length
129    :return:            Volf ratio for P(q)*S(q)
130    """
131    router = radius + thickness
132    vol_core = pi*radius*radius*length
133    vol_total = pi*router*router*length
134    vol_shell = vol_total - vol_core
135    return vol_total, vol_shell
136
137def random():
138    length = 10**np.random.uniform(1, 4.7)
139    outer_radius = 10**np.random.uniform(1, 4.7)
140    # Use a distribution with a preference for thin shell or thin core
141    # Avoid core,shell radii < 1
142    thickness = np.random.beta(0.5, 0.5)*(outer_radius-2) + 1
143    radius = outer_radius - thickness
144    pars = dict(
145        length=length,
146        radius=radius,
147        thickness=thickness,
148    )
149    return pars
150
151# parameters for demo
152demo = dict(scale=1.0, background=0.0, length=400.0, radius=20.0,
153            thickness=10, sld=6.3, sld_solvent=1, theta=90, phi=0,
154            thickness_pd=0.2, thickness_pd_n=9,
155            length_pd=.2, length_pd_n=10,
156            radius_pd=.2, radius_pd_n=9,
157            theta_pd=10, theta_pd_n=5,
158           )
159q = 0.1
160# april 6 2017, rkh added a 2d unit test, assume correct!
161qx = q*cos(pi/6.0)
162qy = q*sin(pi/6.0)
163# Parameters for unit tests
164tests = [
165    [{}, 0.00005, 1764.926],
166#    [{}, 'VR', 0.55555556],
167    [{}, 0.001, 1756.76],
168    [{}, (qx, qy), 2.36885476192],
169]
170del qx, qy  # not necessary to delete, but cleaner
Note: See TracBrowser for help on using the repository browser.