source: sasmodels/sasmodels/models/rectangular_prism.c @ d277229

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since d277229 was d277229, checked in by grethevj, 6 years ago

Models updated to include choices for effective interaction radii

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