source: sasmodels/sasmodels/models/cylinder_clone.c @ 1f21edf

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

restore missing 4x in cylinder.c form

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