source: sasmodels/sasmodels/models/sc_paracrystal.c @ becded3

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since becded3 was becded3, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

update oriented models to new interface (which will be in the next commit)

  • Property mode set to 100644
File size: 2.7 KB
Line 
1static double
2sc_Zq(double qa, double qb, double qc, double dnn, double d_factor)
3{
4    const double a1 = qa;
5    const double a2 = qb;
6    const double a3 = qc;
7
8    // Numerator: (1 - exp(a)^2)^3
9    //         => (-(exp(2a) - 1))^3
10    //         => -expm1(2a)^3
11    // Denominator: prod(1 - 2 cos(d ak) exp(a) + exp(2a))
12    //         => prod(exp(a)^2 - 2 cos(d ak) exp(a) + 1)
13    //         => prod((exp(a) - 2 cos(d ak)) * exp(a) + 1)
14    const double arg = -0.5*square(dnn*d_factor)*(a1*a1 + a2*a2 + a3*a3);
15    const double exp_arg = exp(arg);
16    const double Zq = -cube(expm1(2.0*arg))
17        / ( ((exp_arg - 2.0*cos(dnn*a1))*exp_arg + 1.0)
18          * ((exp_arg - 2.0*cos(dnn*a2))*exp_arg + 1.0)
19          * ((exp_arg - 2.0*cos(dnn*a3))*exp_arg + 1.0));
20
21    return Zq;
22}
23
24// occupied volume fraction calculated from lattice symmetry and sphere radius
25static double
26sc_volume_fraction(double radius, double dnn)
27{
28    return sphere_volume(radius/dnn);
29}
30
31static double
32form_volume(double radius)
33{
34    return sphere_volume(radius);
35}
36
37
38static double
39Iq(double q, double dnn,
40    double d_factor, double radius,
41    double sld, double solvent_sld)
42{
43    // translate a point in [-1,1] to a point in [0, 2 pi]
44    const double phi_m = M_PI_4;
45    const double phi_b = M_PI_4;
46    // translate a point in [-1,1] to a point in [0, pi]
47    const double theta_m = M_PI_4;
48    const double theta_b = M_PI_4;
49
50
51    double outer_sum = 0.0;
52    for(int i=0; i<150; i++) {
53        double inner_sum = 0.0;
54        const double theta = Gauss150Z[i]*theta_m + theta_b;
55        double sin_theta, cos_theta;
56        SINCOS(theta, sin_theta, cos_theta);
57        const double qc = q*cos_theta;
58        const double qab = q*sin_theta;
59        for(int j=0;j<150;j++) {
60            const double phi = Gauss150Z[j]*phi_m + phi_b;
61            double sin_phi, cos_phi;
62            SINCOS(phi, sin_phi, cos_phi);
63            const double qa = qab*cos_phi;
64            const double qb = qab*sin_phi;
65            const double form = sc_Zq(qa, qb, qc, dnn, d_factor);
66            inner_sum += Gauss150Wt[j] * form;
67        }
68        inner_sum *= phi_m;  // sum(f(x)dx) = sum(f(x)) dx
69        outer_sum += Gauss150Wt[i] * inner_sum * sin_theta;
70    }
71    outer_sum *= theta_m;
72    const double Zq = outer_sum/M_PI_2;
73    const double Pq = sphere_form(q, radius, sld, solvent_sld);
74
75    return sc_volume_fraction(radius, dnn) * Pq * Zq;
76}
77
78
79static double
80Iqxy(double qa, double qb, double qc,
81    double dnn, double d_factor, double radius,
82    double sld, double solvent_sld)
83{
84    const double q = sqrt(qa*qa + qb*qb + qc*qc);
85    const double Pq = sphere_form(q, radius, sld, solvent_sld);
86    const double Zq = sc_Zq(qa, qb, qc, dnn, d_factor);
87    return sc_volume_fraction(radius, dnn) * Pq * Zq;
88}
Note: See TracBrowser for help on using the repository browser.