source: sasmodels/sasmodels/models/barbell.c @ d507c3a

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

code tidying

  • Property mode set to 100644
File size: 4.4 KB
Line 
1double form_volume(double bell_radius, double radius, double length);
2double Iq(double q, double sld, double solvent_sld,
3        double bell_radius, double radius, double length);
4double Iqxy(double qx, double qy, double sld, double solvent_sld,
5        double bell_radius, double radius, double length,
6        double theta, double phi);
7
8//barbell kernel - same as dumbell
9double _bell_kernel(double q, double h, double bell_radius,
10        double length, double sin_alpha, double cos_alpha);
11double _bell_kernel(double q, double h, double bell_radius,
12        double length, double sin_alpha, double cos_alpha)
13{
14    const double upper = 1.0;
15    const double lower = -1.0*h/bell_radius;
16
17    double total = 0.0;
18    for (int i = 0; i < 76; i++){
19        const double t = 0.5*(Gauss76Z[i]*(upper-lower)+upper+lower);
20        const double arg1 = q*cos_alpha*(bell_radius*t+h+length*0.5);
21        const double arg2 = q*bell_radius*sin_alpha*sqrt(1.0-t*t);
22        const double be = (arg2 == 0.0 ? 0.5 :J1(arg2)/arg2);
23        const double Fq = cos(arg1)*(1.0-t*t)*be;
24        total += Gauss76Wt[i] * Fq;
25    }
26    const double integral = 0.5*(upper-lower)*total;
27    return 4.0*M_PI*bell_radius*bell_radius*bell_radius*integral;
28}
29
30double form_volume(double bell_radius,
31        double radius,
32        double length)
33{
34
35    // bell radius should never be less than radius when this is called
36    const double hdist = sqrt(bell_radius*bell_radius - radius*radius);
37    const double p1 = 2.0*bell_radius*bell_radius*bell_radius/3.0;
38    const double p2 = bell_radius*bell_radius*hdist;
39    const double p3 = hdist*hdist*hdist/3.0;
40
41    return M_PI*radius*radius*length + 2.0*M_PI*(p1+p2-p3);
42}
43
44double Iq(double q, double sld,
45        double solvent_sld,
46        double bell_radius,
47        double radius,
48        double length)
49{
50    double sn, cn; // slots to hold sincos function output
51
52    if (bell_radius < radius) return NAN;
53
54    const double lower = 0.0;
55    const double upper = M_PI_2;
56    const double h = sqrt(bell_radius*bell_radius-radius*radius);
57    double total = 0.0;
58    for (int i = 0; i < 76; i++){
59        const double alpha= 0.5*(Gauss76Z[i]*(upper-lower) + upper + lower);
60        SINCOS(alpha, sn, cn);
61
62        const double bell_Fq = _bell_kernel(q, h, bell_radius, length, sn, cn);
63
64        const double arg1 = q*length*0.5*cn;
65        const double arg2 = q*radius*sn;
66        // lim_{x->0} J1(x)/x = 1/2,   lim_{x->0} sin(x)/x = 1
67        const double be = (arg2 == 0.0 ? 0.5 :J1(arg2)/arg2);
68        const double si = (arg1 == 0.0 ? 1.0 :sin(arg1)/arg1);
69        const double cyl_Fq = M_PI*radius*radius*length*si*2.0*be;
70
71        const double Aq = cyl_Fq + bell_Fq;
72        total += Gauss76Wt[i] * Aq * Aq * sn;
73    }
74
75    const double form = total*(upper-lower)*0.5;
76
77    //Contrast and volume normalization
78    const double s = (sld - solvent_sld);
79    return form*1.0e-4*s*s; //form_volume(bell_radius,radius,length);
80}
81
82
83
84double Iqxy(double qx, double qy,
85        double sld,
86        double solvent_sld,
87        double bell_radius,
88        double radius,
89        double length,
90        double theta,
91        double phi)
92{
93     double sn, cn; // slots to hold sincos function output
94
95    // Exclude invalid inputs.
96    if (bell_radius < radius) return NAN;
97
98    // Compute angle alpha between q and the cylinder axis
99    SINCOS(theta*M_PI_180, sn, cn);
100    // # The following correction factor exists in sasview, but it can't be
101    // # right, so we are leaving it out for now.
102    const double q = sqrt(qx*qx+qy*qy);
103    const double cos_val = cn*cos(phi*M_PI_180)*qx + sn*qy;
104    const double alpha = acos(cos_val); // rod angle relative to q
105    SINCOS(alpha, sn, cn);
106
107    const double h = sqrt(bell_radius*bell_radius - radius*radius); // negative h
108    const double bell_Fq = _bell_kernel(q, h, bell_radius, length, sn, cn)/sn;
109
110    const double besarg = q*radius*sn;
111    const double siarg = q*0.5*length*cn;
112    // lim_{x->0} J1(x)/x = 1/2,   lim_{x->0} sin(x)/x = 1
113    const double bj = (besarg == 0.0 ? 0.5 : J1(besarg)/besarg);
114    const double si = (siarg == 0.0 ? 1.0 : sin(siarg)/siarg);
115    const double cyl_Fq = M_PI*radius*radius*length*2.0*bj*si;
116
117    // Volume weighted average F(q)
118    const double Aq = cyl_Fq + bell_Fq;
119
120    // Multiply by contrast^2, normalize by cylinder volume and convert to cm-1
121    const double s = (sld - solvent_sld);
122    return 1.0e-4 * Aq * Aq * s * s; // form_volume(radius, cap_radius, length);
123}
Note: See TracBrowser for help on using the repository browser.