source: sasmodels/sasmodels/models/sc_paracrystal.c @ 11ca2ab

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

add macros for theta-phi-psi orientation

  • Property mode set to 100644
File size: 3.5 KB
Line 
1double form_volume(double radius);
2
3double Iq(double q,
4          double dnn,
5          double d_factor,
6          double radius,
7          double sphere_sld,
8          double solvent_sld);
9
10double Iqxy(double qx, double qy,
11            double dnn,
12            double d_factor,
13            double radius,
14            double sphere_sld,
15            double solvent_sld,
16            double theta,
17            double phi,
18            double psi);
19
20double form_volume(double radius)
21{
22    return sphere_volume(radius);
23}
24
25static double
26sc_eval(double theta, double phi, double temp3, double temp4, double temp5)
27{
28    double cnt, snt;
29    SINCOS(theta, cnt, snt);
30
31    double cnp, snp;
32    SINCOS(phi, cnp, snp);
33
34        double temp6 = snt;
35        double temp7 = -1.0*temp3*snt*cnp;
36        double temp8 = temp3*snt*snp;
37        double temp9 = temp3*cnt;
38        double result = temp6/((1.0-temp4*cos((temp7))+temp5)*
39                               (1.0-temp4*cos((temp8))+temp5)*
40                               (1.0-temp4*cos((temp9))+temp5));
41        return (result);
42}
43
44static double
45sc_integrand(double dnn, double d_factor, double qq, double xx, double yy)
46{
47    //Function to calculate integrand values for simple cubic structure
48
49        double da = d_factor*dnn;
50        double temp1 = qq*qq*da*da;
51        double temp2 = pow( 1.0-exp(-1.0*temp1) ,3);
52        double temp3 = qq*dnn;
53        double temp4 = 2.0*exp(-0.5*temp1);
54        double temp5 = exp(-1.0*temp1);
55
56        double integrand = temp2*sc_eval(yy,xx,temp3,temp4,temp5);
57        integrand *= 2.0/M_PI;
58
59        return(integrand);
60}
61
62double Iq(double q,
63          double dnn,
64          double d_factor,
65          double radius,
66          double sphere_sld,
67          double solvent_sld)
68{
69        const double va = 0.0;
70        const double vb = M_PI/2.0; //orientation average, outer integral
71
72    double summ=0.0;
73    double answer=0.0;
74
75        for(int i=0;i<150;i++) {
76                //setup inner integral over the ellipsoidal cross-section
77                double summj=0.0;
78                double zi = ( Gauss150Z[i]*(vb-va) + va + vb )/2.0;
79                for(int j=0;j<150;j++) {
80                        //150 gauss points for the inner integral
81                        double zij = ( Gauss150Z[j]*(vb-va) + va + vb )/2.0;
82                        double tmp = Gauss150Wt[j] * sc_integrand(dnn,d_factor,q,zi,zij);
83                        summj += tmp;
84                }
85                //now calculate the value of the inner integral
86                answer = (vb-va)/2.0*summj;
87
88                //now calculate outer integral
89                double tmp = Gauss150Wt[i] * answer;
90                summ += tmp;
91        }               //final scaling is done at the end of the function, after the NT_FP64 case
92
93        answer = (vb-va)/2.0*summ;
94
95        //Volume fraction calculated from lattice symmetry and sphere radius
96        // NB: 4/3 pi r^3 / dnn^3 = 4/3 pi(r/dnn)^3
97        const double latticeScale = sphere_volume(radius/dnn);
98
99        answer *= sphere_form(q, radius, sphere_sld, solvent_sld)*latticeScale;
100
101        return answer;
102}
103
104double Iqxy(double qx, double qy,
105          double dnn,
106          double d_factor,
107          double radius,
108          double sphere_sld,
109          double solvent_sld,
110          double theta,
111          double phi,
112          double psi)
113{
114    double q, cos_a1, cos_a2, cos_a3;
115    ORIENT_ASYMMETRIC(qx, qy, theta, phi, psi, q, cos_a3, cos_a2, cos_a1);
116
117    const double qd = q*dnn;
118    const double exp_qd = exp(0.5*square(qd*d_factor));
119    const double sinh_qd = 0.5*exp_qd - 0.5/exp_qd;
120    const double cosh_qd = 0.5*exp_qd + 0.5/exp_qd;
121
122    const double Zq = sinh_qd/(cosh_qd - cos(qd*cos_a1))
123                    * sinh_qd/(cosh_qd - cos(qd*cos_a2))
124                    * sinh_qd/(cosh_qd - cos(qd*cos_a3));
125
126    const double Fq = sphere_form(q, radius, sphere_sld, solvent_sld)*Zq;
127    //the occupied volume of the lattice
128    const double lattice_scale = sphere_volume(radius/dnn);
129    return lattice_scale * Fq;
130}
Note: See TracBrowser for help on using the repository browser.