source: sasmodels/sasmodels/models/fcc_paracrystal.c @ 71b751d

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

update remaining form factors to use Fq interface

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