source: sasmodels/sasmodels/models/capped_cylinder.py @ b297ba9

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

lint

  • Property mode set to 100644
File size: 7.0 KB
RevLine 
[5d4777d]1r"""
[b0c4271]2Definitions
3-----------
4
[5d4777d]5Calculates the scattering from a cylinder with spherical section end-caps.
[eb69cce]6Like :ref:`barbell`, this is a sphereocylinder with end caps that have a
7radius larger than that of the cylinder, but with the center of the end cap
[e65a3e7]8radius lying within the cylinder. This model simply becomes a convex
[eb69cce]9lens when the length of the cylinder $L=0$. See the diagram for the details
10of the geometry and restrictions on parameter values.
[5d4777d]11
[eb69cce]12.. figure:: img/capped_cylinder_geometry.jpg
[5d4777d]13
[eb69cce]14    Capped cylinder geometry, where $r$ is *radius*, $R$ is *bell_radius* and
15    $L$ is *length*. Since the end cap radius $R \geq r$ and by definition
16    for this geometry $h < 0$, $h$ is then defined by $r$ and $R$ as
17    $h = - \sqrt{R^2 - r^2}$
[5d4777d]18
[eb69cce]19The scattered intensity $I(q)$ is calculated as
[5d4777d]20
21.. math::
22
[fcb33e4]23    I(q) = \frac{\Delta \rho^2}{V} \left<A^2(q,\alpha).sin(\alpha)\right>
[5d4777d]24
[fcb33e4]25where the amplitude $A(q,\alpha)$ with the rod axis at angle $\alpha$ to $q$ is given as
[5d4777d]26
27.. math::
28
[eb69cce]29    A(q) =&\ \pi r^2L
[fcb33e4]30        \frac{\sin\left(\tfrac12 qL\cos\alpha\right)}
31            {\tfrac12 qL\cos\alpha}
32        \frac{2 J_1(qr\sin\alpha)}{qr\sin\alpha} \\
[19dcb933]33        &\ + 4 \pi R^3 \int_{-h/R}^1 dt
[fcb33e4]34        \cos\left[ q\cos\alpha
[19dcb933]35            \left(Rt + h + {\tfrac12} L\right)\right]
36        \times (1-t^2)
[fcb33e4]37        \frac{J_1\left[qR\sin\alpha \left(1-t^2\right)^{1/2}\right]}
38             {qR\sin\alpha \left(1-t^2\right)^{1/2}}
[5d4777d]39
[eb69cce]40The $\left<\ldots\right>$ brackets denote an average of the structure over
41all orientations. $\left< A^2(q)\right>$ is then the form factor, $P(q)$.
[5d4777d]42The scale factor is equivalent to the volume fraction of cylinders, each of
[eb69cce]43volume, $V$. Contrast $\Delta\rho$ is the difference of scattering length
44densities of the cylinder and the surrounding solvent.
[5d4777d]45
46The volume of the capped cylinder is (with $h$ as a positive value here)
47
48.. math::
49
[19dcb933]50    V = \pi r_c^2 L + \tfrac{2\pi}{3}(R-h)^2(2R + h)
[5d4777d]51
52
[eb69cce]53and its radius of gyration is
[5d4777d]54
[19dcb933]55.. math::
56
57    R_g^2 =&\ \left[ \tfrac{12}{5}R^5
58        + R^4\left(6h+\tfrac32 L\right)
59        + R^2\left(4h^2 + L^2 + 4Lh\right)
60        + R^2\left(3Lh^2 + \tfrac32 L^2h\right) \right. \\
61        &\ \left. + \tfrac25 h^5 - \tfrac12 Lh^4 - \tfrac12 L^2h^3
62        + \tfrac14 L^3r^2 + \tfrac32 Lr^4 \right]
63        \left( 4R^3 6R^2h - 2h^3 + 3r^2L \right)^{-1}
64
[5d4777d]65
[19dcb933]66.. note::
[5d4777d]67
[eb69cce]68    The requirement that $R \geq r$ is not enforced in the model!
[19dcb933]69    It is up to you to restrict this during analysis.
[5d4777d]70
71The 2D scattering intensity is calculated similar to the 2D cylinder model.
72
[9802ab3]73.. figure:: img/cylinder_angle_definition.png
[5d4777d]74
75    Definition of the angles for oriented 2D cylinders.
76
77
[eb69cce]78References
79----------
[5d4777d]80
[b0c4271]81.. [#] H Kaya, *J. Appl. Cryst.*, 37 (2004) 223-230
[31df0c9]82.. [#] H Kaya and N-R deSouza, *J. Appl. Cryst.*, 37 (2004) 508-509 (addenda
[b0c4271]83   and errata)
[b297ba9]84L. Onsager, Ann. New York Acad. Sci. 51, 627-659 (1949).
[b0c4271]85
86Authorship and Verification
87----------------------------
[5d4777d]88
[b0c4271]89* **Author:** NIST IGOR/DANSE **Date:** pre 2010
90* **Last Modified by:** Paul Butler **Date:** September 30, 2016
[fcb33e4]91* **Last Reviewed by:** Richard Heenan **Date:** January 4, 2017
[5d4777d]92"""
[2d81cfe]93
94import numpy as np
[0b56f38]95from numpy import inf, sin, cos, pi
[5d4777d]96
97name = "capped_cylinder"
98title = "Right circular cylinder with spherical end caps and uniform SLD"
99description = """That is, a sphereocylinder
[485aee2]100    with end caps that have a radius larger than
101    that of the cylinder and the center of the
102    end cap radius lies within the cylinder.
103    Note: As the length of cylinder -->0,
[e65a3e7]104    it becomes a Convex Lens.
[2222134]105    It must be that radius <(=) radius_cap.
[485aee2]106    [Parameters];
107    scale: volume fraction of spheres,
108    background:incoherent background,
109    radius: radius of the cylinder,
110    length: length of the cylinder,
[2222134]111    radius_cap: radius of the semi-spherical cap,
[485aee2]112    sld: SLD of the capped cylinder,
[e65a3e7]113    sld_solvent: SLD of the solvent.
[5d4777d]114"""
[a5d0d00]115category = "shape:cylinder"
[dcdf29d]116# pylint: disable=bad-whitespace, line-too-long
[485aee2]117#             ["name", "units", default, [lower, upper], "type", "description"],
[42356c8]118parameters = [["sld",         "1e-6/Ang^2", 4, [-inf, inf], "sld",    "Cylinder scattering length density"],
119              ["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "sld",    "Solvent scattering length density"],
[dcdf29d]120              ["radius",      "Ang",       20, [0, inf],    "volume", "Cylinder radius"],
121
[485aee2]122              # TODO: use an expression for cap radius with fixed bounds.
123              # The current form requires cap radius R bigger than cylinder radius r.
124              # Could instead use R/r in [1,inf], r/R in [0,1], or the angle between
125              # cylinder and cap in [0,90].  The problem is similar for the barbell
126              # model.  Propose r/R in [0,1] in both cases, with the model specifying
127              # cylinder radius in the capped cylinder model and sphere radius in the
128              # barbell model.  This leads to the natural value of zero for no cap
129              # in the capped cylinder, and zero for no bar in the barbell model.  In
130              # both models, one would be a pill.
[2222134]131              ["radius_cap", "Ang",     20, [0, inf],    "volume", "Cap radius"],
[dcdf29d]132              ["length",     "Ang",    400, [0, inf],    "volume", "Cylinder length"],
[9b79f29]133              ["theta",      "degrees", 60, [-360, 360], "orientation", "cylinder axis to beam angle"],
134              ["phi",        "degrees", 60, [-360, 360], "orientation", "rotation about beam"],
[485aee2]135             ]
[dcdf29d]136# pylint: enable=bad-whitespace, line-too-long
[485aee2]137
[26141cb]138source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "capped_cylinder.c"]
[71b751d]139have_Fq = True
[ee60aa7]140effective_radius_type = [
[b297ba9]141    "equivalent cylinder excluded volume", "equivalent volume sphere",
142    "radius", "half length", "half total length",
[ee60aa7]143    ]
[485aee2]144
[31df0c9]145def random():
[b297ba9]146    """Return a random parameter set for the model."""
[31df0c9]147    # TODO: increase volume range once problem with bell radius is fixed
148    # The issue is that bell radii of more than about 200 fail at high q
[2d81cfe]149    volume = 10**np.random.uniform(7, 9)
150    bar_volume = 10**np.random.uniform(-4, -1)*volume
151    bell_volume = volume - bar_volume
[31df0c9]152    bell_radius = (bell_volume/6)**0.3333  # approximate
153    min_bar = bar_volume/np.pi/bell_radius**2
154    bar_length = 10**np.random.uniform(0, 3)*min_bar
155    bar_radius = np.sqrt(bar_volume/bar_length/np.pi)
156    if bar_radius > bell_radius:
157        bell_radius, bar_radius = bar_radius, bell_radius
158    pars = dict(
159        #background=0,
160        radius_cap=bell_radius,
161        radius=bar_radius,
162        length=bar_length,
163    )
164    return pars
165
166
[485aee2]167demo = dict(scale=1, background=0,
[e65a3e7]168            sld=6, sld_solvent=1,
[2222134]169            radius=260, radius_cap=290, length=290,
[485aee2]170            theta=30, phi=15,
171            radius_pd=.2, radius_pd_n=1,
[2222134]172            radius_cap_pd=.2, radius_cap_pd_n=1,
[485aee2]173            length_pd=.2, length_pd_n=10,
174            theta_pd=15, theta_pd_n=45,
175            phi_pd=15, phi_pd_n=1)
[0b56f38]176q = 0.1
177# april 6 2017, rkh add unit tests, NOT compared with any other calc method, assume correct!
178qx = q*cos(pi/6.0)
179qy = q*sin(pi/6.0)
[2d81cfe]180tests = [
181    [{}, 0.075, 26.0698570695],
182    [{'theta':80., 'phi':10.}, (qx, qy), 0.561811990502],
183]
184del qx, qy  # not necessary to delete, but cleaner
Note: See TracBrowser for help on using the repository browser.