source: sasmodels/sasmodels/models/hollow_cylinder.py @ ee5fc99

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since ee5fc99 was ee5fc99, checked in by butler, 6 years ago

Fix VR on hollow cylinder

reverted order to retrun wole,part; fixed associated unit test and
verfified that in fact there is zero change in behavior that we need to
worry about for users… that said not clear what the point of VR is but
should we begin using it it is now correct.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1r"""
2This model provides the form factor, $P(q)$, for a monodisperse hollow right
3angle circular cylinder (rigid tube) where the form factor is normalized by the
4volume of the tube (i.e. not by the external volume).
5
6.. math::
7
8    P(q) = \text{scale} \left<F^2\right>/V_\text{shell} + \text{background}
9
10where the averaging $\left<\ldots\right>$ is applied only for the 1D calculation.
11
12The inside and outside of the hollow cylinder are assumed have the same SLD.
13
14Definition
15----------
16
17The 1D scattering intensity is calculated in the following way (Guinier, 1955)
18
19.. math::
20
21    P(q)           &= (\text{scale})V_\text{shell}\Delta\rho^2
22            \int_0^{1}\Psi^2
23            \left[q_z, R_\text{outer}(1-x^2)^{1/2},
24                       R_\text{core}(1-x^2)^{1/2}\right]
25            \left[\frac{\sin(qHx)}{qHx}\right]^2 dx \\
26    \Psi[q,y,z]    &= \frac{1}{1-\gamma^2}
27            \left[ \Lambda(qy) - \gamma^2\Lambda(qz) \right] \\
28    \Lambda(a)     &= 2 J_1(a) / a \\
29    \gamma         &= R_\text{core} / R_\text{outer} \\
30    V_\text{shell} &= \pi \left(R_\text{outer}^2 - R_\text{core}^2 \right)L \\
31    J_1(x)         &= (\sin(x)-x\cdot \cos(x)) / x^2
32
33where *scale* is a scale factor, $H = L/2$ and $J_1$ is the 1st order
34Bessel function.
35
36**NB**: The 2nd virial coefficient of the cylinder is calculated
37based on the outer radius and full length, which give an the effective radius
38for structure factor $S(q)$ when $P(q) \cdot S(q)$ is applied.
39
40In the parameters,the *radius* is $R_\text{core}$ while *thickness*
41is $R_\text{outer} - R_\text{core}$.
42
43To provide easy access to the orientation of the core-shell cylinder, we define
44the axis of the cylinder using two angles $\theta$ and $\phi$
45(see :ref:`cylinder model <cylinder-angle-definition>`).
46
47References
48----------
49
50L A Feigin and D I Svergun, *Structure Analysis by Small-Angle X-Ray and
51Neutron Scattering*, Plenum Press, New York, (1987)
52
53Authorship and Verification
54----------------------------
55
56* **Author:** NIST IGOR/DANSE **Date:** pre 2010
57* **Last Modified by:** Richard Heenan **Date:** October 06, 2016
58   (reparametrised to use thickness, not outer radius)
59* **Last Reviewed by:** Richard Heenan **Date:** October 06, 2016
60"""
61
62import numpy as np
63from numpy import pi, inf, sin, cos
64
65name = "hollow_cylinder"
66title = ""
67description = """
68P(q) = scale*<f*f>/Vol + background, where f is the scattering amplitude.
69radius = the radius of core
70thickness = the thickness of shell
71length = the total length of the cylinder
72sld = SLD of the shell
73sld_solvent = SLD of the solvent
74background = incoherent background
75"""
76category = "shape:cylinder"
77# pylint: disable=bad-whitespace, line-too-long
78#   ["name", "units", default, [lower, upper], "type","description"],
79parameters = [
80    ["radius",      "Ang",     20.0, [0, inf],    "volume",      "Cylinder core radius"],
81    ["thickness",   "Ang",     10.0, [0, inf],    "volume",      "Cylinder wall thickness"],
82    ["length",      "Ang",    400.0, [0, inf],    "volume",      "Cylinder total length"],
83    ["sld",         "1e-6/Ang^2",  6.3, [-inf, inf], "sld",         "Cylinder sld"],
84    ["sld_solvent", "1e-6/Ang^2",  1,   [-inf, inf], "sld",         "Solvent sld"],
85    ["theta",       "degrees", 90,   [-360, 360], "orientation", "Cylinder axis to beam angle"],
86    ["phi",         "degrees",  0,   [-360, 360], "orientation", "Rotation about beam"],
87    ]
88# pylint: enable=bad-whitespace, line-too-long
89
90source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"]
91
92# pylint: disable=W0613
93def ER(radius, thickness, length):
94    """
95    :param radius:      Cylinder core radius
96    :param thickness:   Cylinder wall thickness
97    :param length:      Cylinder length
98    :return:            Effective radius
99    """
100    router = radius + thickness
101    if router == 0 or length == 0:
102        return 0.0
103    len1 = router
104    len2 = length/2.0
105    term1 = len1*len1*2.0*len2/2.0
106    term2 = 1.0 + (len2/len1)*(1.0 + 1/len2/2.0)*(1.0 + pi*len1/len2/2.0)
107    ddd = 3.0*term1*term2
108    diam = pow(ddd, (1.0/3.0))
109    return diam
110
111def VR(radius, thickness, length):
112    """
113    :param radius:      Cylinder radius
114    :param thickness:   Cylinder wall thickness
115    :param length:      Cylinder length
116    :return:            Volf ratio for P(q)*S(q)
117    """
118    router = radius + thickness
119    vol_core = pi*radius*radius*length
120    vol_total = pi*router*router*length
121    vol_shell = vol_total - vol_core
122    return vol_total, vol_shell
123
124def random():
125    length = 10**np.random.uniform(1, 4.7)
126    outer_radius = 10**np.random.uniform(1, 4.7)
127    # Use a distribution with a preference for thin shell or thin core
128    # Avoid core,shell radii < 1
129    thickness = np.random.beta(0.5, 0.5)*(outer_radius-2) + 1
130    radius = outer_radius - thickness
131    pars = dict(
132        length=length,
133        radius=radius,
134        thickness=thickness,
135    )
136    return pars
137
138# parameters for demo
139demo = dict(scale=1.0, background=0.0, length=400.0, radius=20.0,
140            thickness=10, sld=6.3, sld_solvent=1, theta=90, phi=0,
141            thickness_pd=0.2, thickness_pd_n=9,
142            length_pd=.2, length_pd_n=10,
143            radius_pd=.2, radius_pd_n=9,
144            theta_pd=10, theta_pd_n=5,
145           )
146q = 0.1
147# april 6 2017, rkh added a 2d unit test, assume correct!
148qx = q*cos(pi/6.0)
149qy = q*sin(pi/6.0)
150# Parameters for unit tests
151tests = [
152    [{}, 0.00005, 1764.926],
153    [{}, 'VR', 0.55555556],
154    [{}, 0.001, 1756.76],
155    [{}, (qx, qy), 2.36885476192],
156]
157del qx, qy  # not necessary to delete, but cleaner
Note: See TracBrowser for help on using the repository browser.