source: sasmodels/sasmodels/models/fcc_paracrystal.c @ 4962519

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

use square and cube instead of pow()

  • Property mode set to 100644
File size: 3.8 KB
Line 
1double form_volume(double radius);
2double Iq(double q,double dnn,double d_factor, double radius,double sld, double solvent_sld);
3double Iqxy(double qx, double qy, double dnn,
4    double d_factor, double radius,double sld, double solvent_sld,
5    double theta, double phi, double psi);
6
7double _FCC_Integrand(double q, double dnn, double d_factor, double theta, double phi);
8double _FCCeval(double Theta, double Phi, double temp1, double temp3);
9
10
11double _FCC_Integrand(double q, double dnn, double d_factor, double theta, double phi) {
12
13        const double Da = d_factor*dnn;
14        const double temp1 = q*q*Da*Da;
15        const double temp3 = q*dnn;
16
17        double retVal = _FCCeval(theta,phi,temp1,temp3)/(4.0*M_PI);
18        return(retVal);
19}
20
21double _FCCeval(double Theta, double Phi, double temp1, double temp3) {
22
23        double result;
24        double sin_theta,cos_theta,sin_phi,cos_phi;
25        SINCOS(Theta, sin_theta, cos_theta);
26        SINCOS(Phi, sin_phi, cos_phi);
27
28        const double temp6 =  sin_theta;
29        const double temp7 =  sin_theta*sin_phi + cos_theta;
30        const double temp8 = -sin_theta*cos_phi + cos_theta;
31        const double temp9 = -sin_theta*cos_phi + sin_theta*sin_phi;
32
33        const double temp10 = exp((-1.0/8.0)*temp1*((temp7*temp7)+(temp8*temp8)+(temp9*temp9)));
34        result = cube(1.0-(temp10*temp10))*temp6
35            / ( (1.0 - 2.0*temp10*cos(0.5*temp3*temp7) + temp10*temp10)
36              * (1.0 - 2.0*temp10*cos(0.5*temp3*temp8) + temp10*temp10)
37              * (1.0 - 2.0*temp10*cos(0.5*temp3*temp9) + temp10*temp10));
38
39        return (result);
40}
41
42double form_volume(double radius){
43    return sphere_volume(radius);
44}
45
46
47double Iq(double q, double dnn,
48  double d_factor, double radius,
49  double sld, double solvent_sld){
50
51        //Volume fraction calculated from lattice symmetry and sphere radius
52        const double s1 = dnn*sqrt(2.0);
53        const double latticescale = 4.0*sphere_volume(radius/s1);
54
55    const double va = 0.0;
56    const double vb = 2.0*M_PI;
57    const double vaj = 0.0;
58    const double vbj = M_PI;
59
60    double summ = 0.0;
61    double answer = 0.0;
62        for(int i=0; i<150; i++) {
63                //setup inner integral over the ellipsoidal cross-section
64                double summj=0.0;
65                const double zphi = ( Gauss150Z[i]*(vb-va) + va + vb )/2.0;             //the outer dummy is phi
66                for(int j=0;j<150;j++) {
67                        //20 gauss points for the inner integral
68                        double ztheta = ( Gauss150Z[j]*(vbj-vaj) + vaj + vbj )/2.0;             //the inner dummy is theta
69                        double yyy = Gauss150Wt[j] * _FCC_Integrand(q,dnn,d_factor,ztheta,zphi);
70                        summj += yyy;
71                }
72                //now calculate the value of the inner integral
73                double answer = (vbj-vaj)/2.0*summj;
74
75                //now calculate outer integral
76                summ = summ+(Gauss150Wt[i] * answer);
77        }               //final scaling is done at the end of the function, after the NT_FP64 case
78
79        answer = (vb-va)/2.0*summ;
80        answer = answer*sphere_form(q,radius,sld,solvent_sld)*latticescale;
81
82    return answer;
83
84
85}
86
87double Iqxy(double qx, double qy,
88    double dnn, double d_factor, double radius,
89    double sld, double solvent_sld,
90    double theta, double phi, double psi)
91{
92    double q, cos_a1, cos_a2, cos_a3;
93    ORIENT_ASYMMETRIC(qx, qy, theta, phi, psi, q, cos_a3, cos_a2, cos_a1);
94
95    const double a1 = cos_a2 + cos_a3;
96    const double a2 = cos_a3 + cos_a1;
97    const double a3 = cos_a2 + cos_a1;
98    const double qd = 0.5*q*dnn;
99    const double arg = 0.5*square(qd*d_factor)*(a1*a1 + a2*a2 + a3*a3);
100    const double tanh_qd = tanh(arg);
101    const double cosh_qd = cosh(arg);
102    const double Zq = tanh_qd/(1. - cos(qd*a1)/cosh_qd)
103                    * tanh_qd/(1. - cos(qd*a2)/cosh_qd)
104                    * tanh_qd/(1. - cos(qd*a3)/cosh_qd);
105
106    //if (isnan(Zq)) printf("q:(%g,%g) qd: %g a1: %g a2: %g a3: %g arg: %g\n", qx, qy, qd, a1, a2, a3, arg);
107
108    const double Fq = sphere_form(q,radius,sld,solvent_sld)*Zq;
109    //the occupied volume of the lattice
110    const double lattice_scale = 4.0*sphere_volume(M_SQRT1_2*radius/dnn);
111    return lattice_scale * Fq;
112}
Note: See TracBrowser for help on using the repository browser.