source: sasmodels/sasmodels/models/rectangular_prism.c @ 5024a56

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 5024a56 was d42dd4a, checked in by pkienzle, 5 years ago

fix compiler warnings for CUDA

  • Property mode set to 100644
File size: 6.2 KB
Line 
1static double
2form_volume(double length_a, double b2a_ratio, double c2a_ratio)
3{
4    return length_a * (length_a*b2a_ratio) * (length_a*c2a_ratio);
5}
6
7static double
8effective_radius(int mode, double length_a, double b2a_ratio, double c2a_ratio)
9{
10    switch (mode) {
11    default:
12    case 1: // equivalent sphere
13        return cbrt(cube(length_a)*b2a_ratio*c2a_ratio/M_4PI_3);
14    case 2: // half length_a
15        return 0.5 * length_a;
16    case 3: // half length_b
17        return 0.5 * length_a*b2a_ratio;
18    case 4: // half length_c
19        return 0.5 * length_a*c2a_ratio;
20    case 5: // equivalent circular cross-section
21        return length_a*sqrt(b2a_ratio/M_PI);
22    case 6: // half ab diagonal
23        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio)));
24    case 7: // half diagonal
25        return 0.5*sqrt(square(length_a) * (1.0 + square(b2a_ratio) + square(c2a_ratio)));
26    }
27}
28
29static double
30Iq(double q,
31    double sld,
32    double solvent_sld,
33    double length_a,
34    double b2a_ratio,
35    double c2a_ratio)
36{
37    const double length_b = length_a * b2a_ratio;
38    const double length_c = length_a * c2a_ratio;
39    const double a_half = 0.5 * length_a;
40    const double b_half = 0.5 * length_b;
41    const double c_half = 0.5 * length_c;
42
43   //Integration limits to use in Gaussian quadrature
44    const double v1a = 0.0;
45    const double v1b = M_PI_2;  //theta integration limits
46    const double v2a = 0.0;
47    const double v2b = M_PI_2;  //phi integration limits
48
49    double outer_sum = 0.0;
50    for(int i=0; i<GAUSS_N; i++) {
51        const double theta = 0.5 * ( GAUSS_Z[i]*(v1b-v1a) + v1a + v1b );
52        double sin_theta, cos_theta;
53        SINCOS(theta, sin_theta, cos_theta);
54
55        const double termC = sas_sinx_x(q * c_half * cos_theta);
56
57        double inner_sum = 0.0;
58        for(int j=0; j<GAUSS_N; j++) {
59            double phi = 0.5 * ( GAUSS_Z[j]*(v2b-v2a) + v2a + v2b );
60            double sin_phi, cos_phi;
61            SINCOS(phi, sin_phi, cos_phi);
62
63            // Amplitude AP from eqn. (12), rewritten to avoid round-off effects when arg=0
64            const double termA = sas_sinx_x(q * a_half * sin_theta * sin_phi);
65            const double termB = sas_sinx_x(q * b_half * sin_theta * cos_phi);
66            const double AP = termA * termB * termC;
67            inner_sum += GAUSS_W[j] * AP * AP;
68        }
69        inner_sum = 0.5 * (v2b-v2a) * inner_sum;
70        outer_sum += GAUSS_W[i] * inner_sum * sin_theta;
71    }
72
73    double answer = 0.5*(v1b-v1a)*outer_sum;
74
75    // Normalize by Pi (Eqn. 16).
76    // The term (ABC)^2 does not appear because it was introduced before on
77    // the definitions of termA, termB, termC.
78    // The factor 2 appears because the theta integral has been defined between
79    // 0 and pi/2, instead of 0 to pi.
80    answer /= M_PI_2; //Form factor P(q)
81
82    // Multiply by contrast^2 and volume^2
83    const double volume = length_a * length_b * length_c;
84    answer *= square((sld-solvent_sld)*volume);
85
86    // Convert from [1e-12 A-1] to [cm-1]
87    answer *= 1.0e-4;
88
89    return answer;
90}
91
92static void
93Fq(double q,
94    double *F1,
95    double *F2,
96    double sld,
97    double solvent_sld,
98    double length_a,
99    double b2a_ratio,
100    double c2a_ratio)
101{
102    const double length_b = length_a * b2a_ratio;
103    const double length_c = length_a * c2a_ratio;
104    const double a_half = 0.5 * length_a;
105    const double b_half = 0.5 * length_b;
106    const double c_half = 0.5 * length_c;
107
108   //Integration limits to use in Gaussian quadrature
109    const double v1a = 0.0;
110    const double v1b = M_PI_2;  //theta integration limits
111    const double v2a = 0.0;
112    const double v2b = M_PI_2;  //phi integration limits
113
114    double outer_sum_F1 = 0.0;
115    double outer_sum_F2 = 0.0;
116    for(int i=0; i<GAUSS_N; i++) {
117        const double theta = 0.5 * ( GAUSS_Z[i]*(v1b-v1a) + v1a + v1b );
118        double sin_theta, cos_theta;
119        SINCOS(theta, sin_theta, cos_theta);
120
121        const double termC = sas_sinx_x(q * c_half * cos_theta);
122
123        double inner_sum_F1 = 0.0;
124        double inner_sum_F2 = 0.0;
125        for(int j=0; j<GAUSS_N; j++) {
126            double phi = 0.5 * ( GAUSS_Z[j]*(v2b-v2a) + v2a + v2b );
127            double sin_phi, cos_phi;
128            SINCOS(phi, sin_phi, cos_phi);
129
130            // Amplitude AP from eqn. (12), rewritten to avoid round-off effects when arg=0
131            const double termA = sas_sinx_x(q * a_half * sin_theta * sin_phi);
132            const double termB = sas_sinx_x(q * b_half * sin_theta * cos_phi);
133            const double AP = termA * termB * termC;
134            inner_sum_F1 += GAUSS_W[j] * AP;
135            inner_sum_F2 += GAUSS_W[j] * AP * AP;
136        }
137        inner_sum_F1 = 0.5 * (v2b-v2a) * inner_sum_F1;
138        inner_sum_F2 = 0.5 * (v2b-v2a) * inner_sum_F2;
139        outer_sum_F1 += GAUSS_W[i] * inner_sum_F1 * sin_theta;
140        outer_sum_F2 += GAUSS_W[i] * inner_sum_F2 * sin_theta;
141    }
142
143    outer_sum_F1 *= 0.5*(v1b-v1a);
144    outer_sum_F2 *= 0.5*(v1b-v1a);
145
146    // Normalize by Pi (Eqn. 16).
147    // The term (ABC)^2 does not appear because it was introduced before on
148    // the definitions of termA, termB, termC.
149    // The factor 2 appears because the theta integral has been defined between
150    // 0 and pi/2, instead of 0 to pi.
151    outer_sum_F1 /= M_PI_2;
152    outer_sum_F2 /= M_PI_2;
153
154    // Multiply by contrast and volume
155    const double s = (sld-solvent_sld) * (length_a * length_b * length_c);
156
157    // Convert from [1e-12 A-1] to [cm-1]
158    *F1 = 1e-2 * s * outer_sum_F1;
159    *F2 = 1e-4 * s * s * outer_sum_F2;
160}
161
162
163static double
164Iqabc(double qa, double qb, double qc,
165    double sld,
166    double solvent_sld,
167    double length_a,
168    double b2a_ratio,
169    double c2a_ratio)
170{
171    const double length_b = length_a * b2a_ratio;
172    const double length_c = length_a * c2a_ratio;
173    const double a_half = 0.5 * length_a;
174    const double b_half = 0.5 * length_b;
175    const double c_half = 0.5 * length_c;
176
177    // Amplitude AP from eqn. (13)
178    const double termA = sas_sinx_x(qa * a_half);
179    const double termB = sas_sinx_x(qb * b_half);
180    const double termC = sas_sinx_x(qc * c_half);
181    const double AP = termA * termB * termC;
182
183    // Multiply by contrast and volume
184    const double s = (sld-solvent_sld) * (length_a * length_b * length_c);
185
186    // Convert from [1e-12 A-1] to [cm-1]
187    return 1.0e-4 * square(s * AP);
188}
Note: See TracBrowser for help on using the repository browser.