source: sasmodels/sasmodels/models/cylinder_onefile.py @ 5d4777d

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 5d4777d was 5d4777d, checked in by Paul Kienzle <pkienzle@…>, 10 years ago

reorganize, check and update models

  • Property mode set to 100644
File size: 7.5 KB
Line 
1# This is how a model would look if we were to stick it all into one file.
2r"""
3CylinderModel
4=============
5
6This model provides the form factor for a right circular cylinder with uniform
7scattering length density. The form factor is normalized by the particle volume.
8
9For information about polarised and magnetic scattering, click here_.
10
11Definition
12----------
13
14The output of the 2D scattering intensity function for oriented cylinders is
15given by (Guinier, 1955)
16
17.. math::
18
19    P(q,\alpha) = \frac{\text{scale}}{V}f^2(q) + \text{bkg}
20
21where
22
23.. math::
24
25    f(q) = 2 (\Delta \rho) V
26           \frac{\sin (q L/2 \cos \alpha)}{q L/2 \cos \alpha}
27           \frac{J_1 (q r \sin \alpha)}{q r \sin \alpha}
28
29and $\alpha$ is the angle between the axis of the cylinder and $\vec q$, $V$
30is the volume of the cylinder, $L$ is the length of the cylinder, $r$ is the
31radius of the cylinder, and $d\rho$ (contrast) is the scattering length density
32difference between the scatterer and the solvent. $J_1$ is the first order
33Bessel function.
34
35To provide easy access to the orientation of the cylinder, we define the
36axis of the cylinder using two angles $\theta$ and $\phi$. Those angles
37are defined in Figure :num:`figure #CylinderModel-orientation`.
38
39.. _CylinderModel-orientation:
40
41.. figure:: img/image061.JPG
42
43    Definition of the angles for oriented cylinders.
44
45.. figure:: img/image062.JPG
46
47    Examples of the angles for oriented pp against the detector plane.
48
49NB: The 2nd virial coefficient of the cylinder is calculated based on the
50radius and length values, and used as the effective radius for $S(Q)$
51when $P(Q) \cdot S(Q)$ is applied.
52
53The returned value is scaled to units of |cm^-1| and the parameters of
54the CylinderModel are the following:
55
56%(parameters)s
57
58The output of the 1D scattering intensity function for randomly oriented
59cylinders is then given by
60
61.. math::
62
63    P(q) = \frac{\text{scale}}{V}
64        \int_0^{\pi/2} f^2(q,\alpha) \sin \alpha d\alpha + \text{background}
65
66The *theta* and *phi* parameters are not used for the 1D output. Our
67implementation of the scattering kernel and the 1D scattering intensity
68use the c-library from NIST.
69
70Validation of the CylinderModel
71-------------------------------
72
73Validation of our code was done by comparing the output of the 1D model
74to the output of the software provided by the NIST (Kline, 2006).
75Figure :num:`figure #CylinderModel-compare` shows a comparison of
76the 1D output of our model and the output of the NIST software.
77
78.. _CylinderModel-compare:
79
80.. figure:: img/image065.JPG
81
82    Comparison of the SasView scattering intensity for a cylinder with the
83    output of the NIST SANS analysis software.
84    The parameters were set to: *Scale* = 1.0, *Radius* = 20 |Ang|,
85    *Length* = 400 |Ang|, *Contrast* = 3e-6 |Ang^-2|, and
86    *Background* = 0.01 |cm^-1|.
87
88In general, averaging over a distribution of orientations is done by
89evaluating the following
90
91.. math::
92
93    P(q) = \int_0^{\pi/2} d\phi
94        \int_0^\pi p(\theta, \phi) P_0(q,\alpha) \sin \theta d\theta
95
96
97where $p(\theta,\phi)$ is the probability distribution for the orientation
98and $P_0(q,\alpha)$ is the scattering intensity for the fully oriented
99system. Since we have no other software to compare the implementation of
100the intensity for fully oriented cylinders, we can compare the result of
101averaging our 2D output using a uniform distribution $p(\theta, \phi) = 1.0$.
102Figure :num:`figure #CylinderModel-crosscheck` shows the result of
103such a cross-check.
104
105.. _CylinderModel-crosscheck:
106
107.. figure:: img/image066.JPG
108
109    Comparison of the intensity for uniformly distributed cylinders
110    calculated from our 2D model and the intensity from the NIST SANS
111    analysis software.
112    The parameters used were: *Scale* = 1.0, *Radius* = 20 |Ang|,
113    *Length* = 400 |Ang|, *Contrast* = 3e-6 |Ang^-2|, and
114    *Background* = 0.0 |cm^-1|.
115"""
116
117from numpy import pi, inf
118
119name = "cylinder"
120title = "Cylinder with uniform scattering length density"
121description = """
122     f(q)= 2*(sldCyl - sldSolv)*V*sin(qLcos(alpha/2))
123            /[qLcos(alpha/2)]*J1(qRsin(alpha/2))/[qRsin(alpha)]
124
125            P(q,alpha)= scale/V*f(q)^(2)+background
126            V: Volume of the cylinder
127            R: Radius of the cylinder
128            L: Length of the cylinder
129            J1: The bessel function
130            alpha: angle betweenthe axis of the
131            cylinder and the q-vector for 1D
132            :the ouput is P(q)=scale/V*integral
133            from pi/2 to zero of...
134            f(q)^(2)*sin(alpha)*dalpha+ bkg
135    """
136
137parameters = [
138#   [ "name", "units", default, [lower, upper], "type",
139#     "description" ],
140    [ "sld", "1e-6/Ang^2", 4, [-inf,inf], "",
141      "Cylinder scattering length density" ],
142    [ "solvent_sld", "1e-6/Ang^2", 1, [-inf,inf], "",
143      "Solvent scattering length density" ],
144    [ "radius", "Ang",  20, [0, inf], "volume",
145      "Cylinder radius" ],
146    [ "length", "Ang",  400, [0, inf], "volume",
147      "Cylinder length" ],
148    [ "theta", "degrees", 60, [-inf, inf], "orientation",
149      "In plane angle" ],
150    [ "phi", "degrees", 60, [-inf, inf], "orientation",
151      "Out of plane angle" ],
152    ]
153
154source = [ "lib/J1.c", "lib/gauss76.c", "lib/cylkernel.c" ]
155
156form_volume = """
157    return M_PI*radius*radius*length;
158    """
159
160Iq = """
161    const real h = REAL(0.5)*length;
162    real summ = REAL(0.0);
163    for (int i=0; i<76 ;i++) {
164        //const real zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
165        const real zi = REAL(0.5)*(Gauss76Z[i]*M_PI_2 + M_PI_2);
166        summ += Gauss76Wt[i] * CylKernel(q, radius, h, zi);
167    }
168    //const real form = (uplim-lolim)/2.0*summ;
169    const real form = summ * M_PI_4;
170
171    // Multiply by contrast^2, normalize by cylinder volume and convert to cm-1
172    // NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
173    // The additional volume factor is for polydisperse volume normalization.
174    const real s = (sld - solvent_sld) * form_volume(radius, length);
175    return REAL(1.0e-4) * form * s * s;
176    """
177
178Iqxy = """
179    real sn, cn; // slots to hold sincos function output
180
181    // Compute angle alpha between q and the cylinder axis
182    SINCOS(theta*M_PI_180, sn, cn);
183    // # The following correction factor exists in sasview, but it can't be
184    // # right, so we are leaving it out for now.
185    // const real correction = fabs(cn)*M_PI_2;
186    const real q = sqrt(qx*qx+qy*qy);
187    const real cos_val = cn*cos(phi*M_PI_180)*(qx/q) + sn*(qy/q);
188    const real alpha = acos(cos_val);
189
190    // The following is CylKernel() / sin(alpha), but we are doing it in place
191    // to avoid sin(alpha)/sin(alpha) for alpha = 0.  It is also a teensy bit
192    // faster since we don't mulitply and divide sin(alpha).
193    SINCOS(alpha, sn, cn);
194    const real besarg = q*radius*sn;
195    const real siarg = REAL(0.5)*q*length*cn;
196    // lim_{x->0} J1(x)/x = 1/2,   lim_{x->0} sin(x)/x = 1
197    const real bj = (besarg == REAL(0.0) ? REAL(0.5) : J1(besarg)/besarg);
198    const real si = (siarg == REAL(0.0) ? REAL(1.0) : sin(siarg)/siarg);
199    const real form = REAL(4.0)*bj*bj*si*si;
200
201    // Multiply by contrast^2, normalize by cylinder volume and convert to cm-1
202    // NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
203    // The additional volume factor is for polydisperse volume normalization.
204    const real s = (sld - solvent_sld) * form_volume(radius, length);
205    return REAL(1.0e-4) * form * s * s; // * correction;
206    """
207
208def ER(radius, length):
209    ddd = 0.75*radius*(2*radius*length + (length+radius)*(length+pi*radius))
210    return 0.5 * (ddd)**(1./3.)
211
Note: See TracBrowser for help on using the repository browser.