source: sasmodels/sasmodels/models/barbell.py

Last change on this file was d57b06c, checked in by Paul Kienzle <pkienzle@…>, 5 years ago

Merge remote-tracking branch 'origin/master' into ticket-1263-source-link

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