source: sasmodels/sasmodels/models/rectangular_prism.py @ 8de1477

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

rectangular_prism/hollow_rectangular_prism: add 2d models

  • Property mode set to 100644
File size: 5.4 KB
Line 
1# rectangular_prism model
2# Note: model title and parameter table are inserted automatically
3r"""
4
5This model provides the form factor, $P(q)$, for a rectangular prism.
6
7Note that this model is almost totally equivalent to the existing
8:ref:`parallelepiped` model.
9The only difference is that the way the relevant
10parameters are defined here ($a$, $b/a$, $c/a$ instead of $a$, $b$, $c$)
11which allows use of polydispersity with this model while keeping the shape of
12the prism (e.g. setting $b/a = 1$ and $c/a = 1$ and applying polydispersity
13to *a* will generate a distribution of cubes of different sizes).
14Note also that, contrary to :ref:`parallelepiped`, it does not compute
15the 2D scattering.
16
17
18Definition
19----------
20
21The 1D scattering intensity for this model was calculated by Mittelbach and
22Porod (Mittelbach, 1961), but the implementation here is closer to the
23equations given by Nayuk and Huber (Nayuk, 2012).
24Note also that the angle definitions used in the code and the present
25documentation correspond to those used in (Nayuk, 2012) (see Fig. 1 of
26that reference), with $\theta$ corresponding to $\alpha$ in that paper,
27and not to the usual convention used for example in the
28:ref:`parallelepiped` model. As the present model does not compute
29the 2D scattering, this has no further consequences.
30
31In this model the scattering from a massive parallelepiped with an
32orientation with respect to the scattering vector given by $\theta$
33and $\phi$
34
35.. math::
36
37  A_P\,(q) =
38      \frac{\sin \left( \tfrac{1}{2}qC \cos\theta \right) }{\tfrac{1}{2} qC \cos\theta}
39      \,\times\,
40      \frac{\sin \left( \tfrac{1}{2}qA \cos\theta \right) }{\tfrac{1}{2} qA \cos\theta}
41      \,\times\ ,
42      \frac{\sin \left( \tfrac{1}{2}qB \cos\theta \right) }{\tfrac{1}{2} qB \cos\theta}
43
44where $A$, $B$ and $C$ are the sides of the parallelepiped and must fulfill
45$A \le B \le C$, $\theta$ is the angle between the $z$ axis and the
46longest axis of the parallelepiped $C$, and $\phi$ is the angle between the
47scattering vector (lying in the $xy$ plane) and the $y$ axis.
48
49The normalized form factor in 1D is obtained averaging over all possible
50orientations
51
52.. math::
53  P(q) =  \frac{2}{\pi} \int_0^{\frac{\pi}{2}} \,
54  \int_0^{\frac{\pi}{2}} A_P^2(q) \, \sin\theta \, d\theta \, d\phi
55
56And the 1D scattering intensity is calculated as
57
58.. math::
59  I(q) = \text{scale} \times V \times (\rho_\text{p} -
60  \rho_\text{solvent})^2 \times P(q)
61
62where $V$ is the volume of the rectangular prism, $\rho_\text{p}$
63is the scattering length of the parallelepiped, $\rho_\text{solvent}$
64is the scattering length of the solvent, and (if the data are in absolute
65units) *scale* represents the volume fraction (which is unitless).
66
67**The 2D scattering intensity is not computed by this model.**
68
69
70Validation
71----------
72
73Validation of the code was conducted by comparing the output of the 1D model
74to the output of the existing :ref:`parallelepiped` model.
75
76
77References
78----------
79
80P Mittelbach and G Porod, *Acta Physica Austriaca*, 14 (1961) 185-211
81
82R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854
83
84"""
85
86from numpy import pi, inf, sqrt
87
88name = "rectangular_prism"
89title = "Rectangular parallelepiped with uniform scattering length density."
90description = """
91    I(q)= scale*V*(sld - sld_solvent)^2*P(q,theta,phi)+background
92        P(q,theta,phi) = (2/pi) * double integral from 0 to pi/2 of ...
93           AP^2(q)*sin(theta)*dtheta*dphi
94        AP = S(q*C*cos(theta)/2) * S(q*A*sin(theta)*sin(phi)/2) * S(q*B*sin(theta)*cos(phi)/2)
95        S(x) = sin(x)/x
96"""
97category = "shape:parallelepiped"
98
99#             ["name", "units", default, [lower, upper], "type","description"],
100parameters = [["sld", "1e-6/Ang^2", 6.3, [-inf, inf], "sld",
101               "Parallelepiped scattering length density"],
102              ["sld_solvent", "1e-6/Ang^2", 1, [-inf, inf], "sld",
103               "Solvent scattering length density"],
104              ["length_a", "Ang", 35, [0, inf], "volume",
105               "Shorter side of the parallelepiped"],
106              ["b2a_ratio", "", 1, [0, inf], "volume",
107               "Ratio sides b/a"],
108              ["c2a_ratio", "", 1, [0, inf], "volume",
109               "Ratio sides c/a"],
110              ["theta", "degrees", 0, [-360, 360], "orientation",
111               "c axis to beam angle"],
112              ["phi", "degrees", 0, [-360, 360], "orientation",
113               "rotation about beam"],
114              ["psi", "degrees", 0, [-360, 360], "orientation",
115               "rotation about c axis"],
116             ]
117
118source = ["lib/gauss76.c", "rectangular_prism.c"]
119
120def ER(length_a, b2a_ratio, c2a_ratio):
121    """
122        Return equivalent radius (ER)
123    """
124    b_side = length_a * b2a_ratio
125    c_side = length_a * c2a_ratio
126
127    # surface average radius (rough approximation)
128    surf_rad = sqrt(length_a * b_side / pi)
129
130    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
131    return 0.5 * (ddd) ** (1. / 3.)
132
133def random():
134    import numpy as np
135    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
136    pars = dict(
137        length_a=a,
138        b2a_ratio=b/a,
139        c2a_ratio=c/a,
140    )
141    return pars
142
143# parameters for demo
144demo = dict(scale=1, background=0,
145            sld=6.3, sld_solvent=1.0,
146            length_a=35, b2a_ratio=1, c2a_ratio=1,
147            length_a_pd=0.1, length_a_pd_n=10,
148            b2a_ratio_pd=0.1, b2a_ratio_pd_n=1,
149            c2a_ratio_pd=0.1, c2a_ratio_pd_n=1)
150
151tests = [[{}, 0.2, 0.375248406825],
152         [{}, [0.2], [0.375248406825]],
153        ]
Note: See TracBrowser for help on using the repository browser.