source: sasmodels/sasmodels/models/spherical_sld.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: 5.4 KB
Line 
1static double form_volume(
2    double fp_n_shells,
3    double thickness[],
4    double interface[])
5{
6    int n_shells= (int)(fp_n_shells + 0.5);
7    double r = 0.0;
8    for (int i=0; i < n_shells; i++) {
9        r += thickness[i] + interface[i];
10    }
11    return M_4PI_3*cube(r);
12}
13
14static double
15effective_radius(int mode, double fp_n_shells, double thickness[], double interface[])
16{
17    int n_shells= (int)(fp_n_shells + 0.5);
18    double r = 0.0;
19    for (int i=0; i < n_shells; i++) {
20        r += thickness[i] + interface[i];
21    }
22    return r;
23}
24
25static double blend(int shape, double nu, double z)
26{
27    if (shape==0) {
28        const double num = sas_erf(nu * M_SQRT1_2 * (2.0*z - 1.0));
29        const double denom = 2.0 * sas_erf(nu * M_SQRT1_2);
30        return num/denom + 0.5;
31    } else if (shape==1) {
32        return pow(z, nu);
33    } else if (shape==2) {
34        return 1.0 - pow(1.0 - z, nu);
35    } else if (shape==3) {
36        return expm1(-nu*z)/expm1(-nu);
37    } else if (shape==4) {
38        return expm1(nu*z)/expm1(nu);
39    } else {
40        return NAN;
41    }
42}
43
44static double f_linear(double q, double r, double contrast, double slope)
45{
46    const double qr = q * r;
47    const double qrsq = qr * qr;
48    const double bes = sas_3j1x_x(qr);
49    double sinqr, cosqr;
50    SINCOS(qr, sinqr, cosqr);
51    const double fun = 3.0*r*(2.0*qr*sinqr - (qrsq-2.0)*cosqr)/(qrsq*qrsq);
52    const double vol = M_4PI_3 * cube(r);
53    return vol*(bes*contrast + fun*slope);
54}
55
56static double Iq(
57    double q,
58    double fp_n_shells,
59    double sld_solvent,
60    double sld[],
61    double thickness[],
62    double interface[],
63    double shape[],
64    double nu[],
65    double fp_n_steps)
66{
67    // iteration for # of shells + core + solvent
68    int n_shells = (int)(fp_n_shells + 0.5);
69    int n_steps = (int)(fp_n_steps + 0.5);
70    double f=0.0;
71    double r=0.0;
72    for (int shell=0; shell<n_shells; shell++){
73        const double sld_l = sld[shell];
74
75        // uniform shell; r=0 => r^3=0 => f=0, so works for core as well.
76        f -= M_4PI_3 * cube(r) * sld_l * sas_3j1x_x(q*r);
77        r += thickness[shell];
78        f += M_4PI_3 * cube(r) * sld_l * sas_3j1x_x(q*r);
79
80        // iterate over sub_shells in the interface
81        const double dr = interface[shell]/n_steps;
82        const double delta = (shell==n_shells-1 ? sld_solvent : sld[shell+1]) - sld_l;
83        const double nu_shell = fmax(fabs(nu[shell]), 1.e-14);
84        const int shape_shell = (int)(shape[shell]);
85
86        // if there is no interface the equations don't work
87        if (dr == 0.) continue;
88
89        double sld_in = sld_l;
90        for (int step=1; step <= n_steps; step++) {
91            // find sld_i at the outer boundary of sub-shell step
92            //const double z = (double)step/(double)n_steps;
93            const double z = (double)step/(double)n_steps;
94            const double fraction = blend(shape_shell, nu_shell, z);
95            const double sld_out = fraction*delta + sld_l;
96            // calculate slope
97            const double slope = (sld_out - sld_in)/dr;
98            const double contrast = sld_in - slope*r;
99
100            // iteration for the left and right boundary of the shells
101            f -= f_linear(q, r, contrast, slope);
102            r += dr;
103            f += f_linear(q, r, contrast, slope);
104            sld_in = sld_out;
105        }
106    }
107    // add in solvent effect
108    f -= M_4PI_3 * cube(r) * sld_solvent * sas_3j1x_x(q*r);
109
110    const double f2 = f * f * 1.0e-4;
111    return f2;
112}
113
114static void Fq(
115    double q,
116    double *F1,
117    double *F2,
118    double fp_n_shells,
119    double sld_solvent,
120    double sld[],
121    double thickness[],
122    double interface[],
123    double shape[],
124    double nu[],
125    double fp_n_steps)
126{
127    // iteration for # of shells + core + solvent
128    int n_shells = (int)(fp_n_shells + 0.5);
129    int n_steps = (int)(fp_n_steps + 0.5);
130    double f=0.0;
131    double r=0.0;
132    for (int shell=0; shell<n_shells; shell++){
133        const double sld_l = sld[shell];
134
135        // uniform shell; r=0 => r^3=0 => f=0, so works for core as well.
136        f -= M_4PI_3 * cube(r) * sld_l * sas_3j1x_x(q*r);
137        r += thickness[shell];
138        f += M_4PI_3 * cube(r) * sld_l * sas_3j1x_x(q*r);
139
140        // iterate over sub_shells in the interface
141        const double dr = interface[shell]/n_steps;
142        const double delta = (shell==n_shells-1 ? sld_solvent : sld[shell+1]) - sld_l;
143        const double nu_shell = fmax(fabs(nu[shell]), 1.e-14);
144        const int shape_shell = (int)(shape[shell]);
145
146        // if there is no interface the equations don't work
147        if (dr == 0.) continue;
148
149        double sld_in = sld_l;
150        for (int step=1; step <= n_steps; step++) {
151            // find sld_i at the outer boundary of sub-shell step
152            //const double z = (double)step/(double)n_steps;
153            const double z = (double)step/(double)n_steps;
154            const double fraction = blend(shape_shell, nu_shell, z);
155            const double sld_out = fraction*delta + sld_l;
156            // calculate slope
157            const double slope = (sld_out - sld_in)/dr;
158            const double contrast = sld_in - slope*r;
159
160            // iteration for the left and right boundary of the shells
161            f -= f_linear(q, r, contrast, slope);
162            r += dr;
163            f += f_linear(q, r, contrast, slope);
164            sld_in = sld_out;
165        }
166    }
167    // add in solvent effect
168    f -= M_4PI_3 * cube(r) * sld_solvent * sas_3j1x_x(q*r);
169
170    *F1 = 1e-2*f;
171    *F2 = 1e-4*f*f;
172}
Note: See TracBrowser for help on using the repository browser.