source: sasmodels/sasmodels/models/sc_paracrystal.c @ 50beefe

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

paracrystal: adjust to new asymmetric orientation definition. Refs #890.

  • 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 = cube(-expm1(-temp1));
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)/M_PI_2;
57
58        return(integrand);
59}
60
61double Iq(double q,
62          double dnn,
63          double d_factor,
64          double radius,
65          double sphere_sld,
66          double solvent_sld)
67{
68        const double va = 0.0;
69        const double vb = M_PI_2; //orientation average, outer integral
70
71    double summ=0.0;
72    double answer=0.0;
73
74        for(int i=0;i<150;i++) {
75                //setup inner integral over the ellipsoidal cross-section
76                double summj=0.0;
77                double zi = ( Gauss150Z[i]*(vb-va) + va + vb )/2.0;
78                for(int j=0;j<150;j++) {
79                        //150 gauss points for the inner integral
80                        double zij = ( Gauss150Z[j]*(vb-va) + va + vb )/2.0;
81                        double tmp = Gauss150Wt[j] * sc_integrand(dnn,d_factor,q,zi,zij);
82                        summj += tmp;
83                }
84                //now calculate the value of the inner integral
85                answer = (vb-va)/2.0*summj;
86
87                //now calculate outer integral
88                double tmp = Gauss150Wt[i] * answer;
89                summ += tmp;
90        }               //final scaling is done at the end of the function, after the NT_FP64 case
91
92        answer = (vb-va)/2.0*summ;
93
94        //Volume fraction calculated from lattice symmetry and sphere radius
95        // NB: 4/3 pi r^3 / dnn^3 = 4/3 pi(r/dnn)^3
96        const double latticeScale = sphere_volume(radius/dnn);
97
98        answer *= sphere_form(q, radius, sphere_sld, solvent_sld)*latticeScale;
99
100        return answer;
101}
102
103double Iqxy(double qx, double qy,
104          double dnn,
105          double d_factor,
106          double radius,
107          double sphere_sld,
108          double solvent_sld,
109          double theta,
110          double phi,
111          double psi)
112{
113    double q, zhat, yhat, xhat;
114    ORIENT_ASYMMETRIC(qx, qy, theta, phi, psi, q, xhat, yhat, zhat);
115
116    const double qd = q*dnn;
117    const double arg = 0.5*square(qd*d_factor);
118    const double tanh_qd = tanh(arg);
119    const double cosh_qd = cosh(arg);
120    const double Zq = tanh_qd/(1. - cos(qd*zhat)/cosh_qd)
121                    * tanh_qd/(1. - cos(qd*yhat)/cosh_qd)
122                    * tanh_qd/(1. - cos(qd*xhat)/cosh_qd);
123
124    const double Fq = sphere_form(q, radius, sphere_sld, solvent_sld)*Zq;
125    //the occupied volume of the lattice
126    const double lattice_scale = sphere_volume(radius/dnn);
127    return lattice_scale * Fq;
128}
Note: See TracBrowser for help on using the repository browser.