source: sasmodels/sasmodels/models/rectangular_prism.py @ ef07e95

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

lint

  • Property mode set to 100644
File size: 5.1 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
85import numpy as np
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             ]
111
112source = ["lib/gauss76.c", "rectangular_prism.c"]
113
114def ER(length_a, b2a_ratio, c2a_ratio):
115    """
116        Return equivalent radius (ER)
117    """
118    b_side = length_a * b2a_ratio
119    c_side = length_a * c2a_ratio
120
121    # surface average radius (rough approximation)
122    surf_rad = sqrt(length_a * b_side / pi)
123
124    ddd = 0.75 * surf_rad * (2 * surf_rad * c_side + (c_side + surf_rad) * (c_side + pi * surf_rad))
125    return 0.5 * (ddd) ** (1. / 3.)
126
127def random():
128    a, b, c = 10**np.random.uniform(1, 4.7, size=3)
129    pars = dict(
130        length_a=a,
131        b2a_ratio=b/a,
132        c2a_ratio=c/a,
133    )
134    return pars
135
136# parameters for demo
137demo = dict(scale=1, background=0,
138            sld=6.3, sld_solvent=1.0,
139            length_a=35, b2a_ratio=1, c2a_ratio=1,
140            length_a_pd=0.1, length_a_pd_n=10,
141            b2a_ratio_pd=0.1, b2a_ratio_pd_n=1,
142            c2a_ratio_pd=0.1, c2a_ratio_pd_n=1)
143
144tests = [[{}, 0.2, 0.375248406825],
145         [{}, [0.2], [0.375248406825]],
146        ]
Note: See TracBrowser for help on using the repository browser.