source: sasmodels/sasmodels/models/bcc.c @ 7ed702f

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 7ed702f was 7ed702f, checked in by piotr, 8 years ago

Converted MassStructureModel?
Fixed some doc and unit test warnings

  • Property mode set to 100644
File size: 5.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 _BCC_Integrand(double q, double dnn, double d_factor, double theta, double phi);
8double _BCCeval(double Theta, double Phi, double temp1, double temp3);
9double _sphereform(double q, double radius, double sld, double solvent_sld);
10
11
12double _BCC_Integrand(double q, double dnn, double d_factor, double theta, double phi) {
13
14        const double Da = d_factor*dnn;
15        const double temp1 = q*q*Da*Da;
16        const double temp3 = q*dnn;
17
18        double retVal = _BCCeval(theta,phi,temp1,temp3)/(4.0*M_PI);
19        return(retVal);
20}
21
22double _BCCeval(double Theta, double Phi, double temp1, double temp3) {
23
24        double result;
25        double sin_theta,cos_theta,sin_phi,cos_phi;
26        SINCOS(Theta, sin_theta, cos_theta);
27        SINCOS(Phi, sin_phi, cos_phi);
28
29        const double temp6 =  sin_theta;
30        const double temp7 =  sin_theta*cos_phi + sin_theta*sin_phi + cos_theta;
31        const double temp8 = -sin_theta*cos_phi - sin_theta*sin_phi + cos_theta;
32        const double temp9 = -sin_theta*cos_phi + sin_theta*sin_phi - cos_theta;
33        const double temp10 = exp((-1.0/8.0)*temp1*(temp7*temp7 + temp8*temp8 + temp9*temp9));
34        result = pow(1.0-(temp10*temp10),3)*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 _sphereform(double q, double radius, double sld, double solvent_sld){
43    const double qr = q*radius;
44    double sn, cn;
45    SINCOS(qr, sn, cn);
46    const double bes = (qr == 0.0 ? 1.0 : 3.0*(sn-qr*cn)/(qr*qr*qr));
47    const double fq = bes * (sld - solvent_sld)*form_volume(radius);
48    return 1.0e-4*fq*fq;
49}
50
51double form_volume(double radius){
52    return 1.333333333333333*M_PI*radius*radius*radius;
53}
54
55
56double Iq(double q, double dnn,
57  double d_factor, double radius,
58  double sld, double solvent_sld){
59
60        //Volume fraction calculated from lattice symmetry and sphere radius
61        const double s1 = dnn/sqrt(0.75);
62        const double latticescale = 2.0*(4.0/3.0)*M_PI*(radius*radius*radius)/(s1*s1*s1);
63
64    const double va = 0.0;
65    const double vb = 2.0*M_PI;
66    const double vaj = 0.0;
67    const double vbj = M_PI;
68
69    double summ = 0.0;
70    double answer = 0.0;
71        for(int i=0; i<150; i++) {
72                //setup inner integral over the ellipsoidal cross-section
73                double summj=0.0;
74                const double zphi = ( Gauss150Z[i]*(vb-va) + va + vb )/2.0;             //the outer dummy is phi
75                for(int j=0;j<150;j++) {
76                        //20 gauss points for the inner integral
77                        double ztheta = ( Gauss150Z[j]*(vbj-vaj) + vaj + vbj )/2.0;             //the inner dummy is theta
78                        double yyy = Gauss150Wt[j] * _BCC_Integrand(q,dnn,d_factor,ztheta,zphi);
79                        summj += yyy;
80                }
81                //now calculate the value of the inner integral
82                double answer = (vbj-vaj)/2.0*summj;
83
84                //now calculate outer integral
85                summ = summ+(Gauss150Wt[i] * answer);
86        }               //final scaling is done at the end of the function, after the NT_FP64 case
87
88        answer = (vb-va)/2.0*summ;
89        answer = answer*_sphereform(q,radius,sld,solvent_sld)*latticescale;
90
91    return answer;
92
93
94}
95
96
97double Iqxy(double qx, double qy, double dnn,
98    double d_factor, double radius,double sld, double solvent_sld,
99    double theta, double phi, double psi){
100
101  double b3_x, b3_y, b1_x, b1_y, b2_x, b2_y; //b3_z,
102  //double q_z;
103  double cos_val_b3, cos_val_b2, cos_val_b1;
104  double a1_dot_q, a2_dot_q,a3_dot_q;
105  double answer;
106  double Zq, Fkq, Fkq_2;
107
108  //convert to q and make scaled values
109  double q = sqrt(qx*qx+qy*qy);
110  double q_x = qx/q;
111  double q_y = qy/q;
112
113  //convert angle degree to radian
114  theta = theta * M_PI_180;
115  phi = phi * M_PI_180;
116  psi = psi * M_PI_180;
117
118  const double Da = d_factor*dnn;
119  const double s1 = dnn/sqrt(0.75);
120
121
122  //the occupied volume of the lattice
123  const double latticescale = 2.0*(4.0/3.0)*M_PI*(radius*radius*radius)/(s1*s1*s1);
124  // q vector
125  //q_z = 0.0; // for SANS; assuming qz is negligible
126  /// Angles here are respect to detector coordinate
127  ///  instead of against q coordinate(PRB 36(46), 3(6), 1754(3854))
128    // b3 axis orientation
129    b3_x = cos(theta) * cos(phi);
130    b3_y = sin(theta);
131    //b3_z = -cos(theta) * sin(phi);
132    cos_val_b3 =  b3_x*q_x + b3_y*q_y;// + b3_z*q_z;
133
134    //alpha = acos(cos_val_b3);
135    // b1 axis orientation
136    b1_x = -cos(phi)*sin(psi) * sin(theta)+sin(phi)*cos(psi);
137    b1_y = sin(psi)*cos(theta);
138    cos_val_b1 = b1_x*q_x + b1_y*q_y;
139    // b2 axis orientation
140    b2_x = -sin(theta)*cos(psi)*cos(phi)-sin(psi)*sin(phi);
141        b2_y = cos(theta)*cos(psi);
142    cos_val_b2 = b2_x*q_x + b2_y*q_y;
143
144    // The following test should always pass
145    if (fabs(cos_val_b3)>1.0) {
146      //printf("bcc_ana_2D: Unexpected error: cos()>1\n");
147      cos_val_b3 = 1.0;
148    }
149    if (fabs(cos_val_b2)>1.0) {
150      //printf("bcc_ana_2D: Unexpected error: cos()>1\n");
151      cos_val_b2 = 1.0;
152    }
153    if (fabs(cos_val_b1)>1.0) {
154      //printf("bcc_ana_2D: Unexpected error: cos()>1\n");
155      cos_val_b1 = 1.0;
156    }
157    // Compute the angle btw vector q and the a3 axis
158    a3_dot_q = 0.5*dnn*q*(cos_val_b2+cos_val_b1-cos_val_b3);
159
160    // a1 axis
161    a1_dot_q = 0.5*dnn*q*(cos_val_b3+cos_val_b2-cos_val_b1);
162
163    // a2 axis
164    a2_dot_q = 0.5*dnn*q*(cos_val_b3+cos_val_b1-cos_val_b2);
165
166
167    // Get Fkq and Fkq_2
168    Fkq = exp(-0.5*pow(Da/dnn,2.0)*(a1_dot_q*a1_dot_q+a2_dot_q*a2_dot_q+a3_dot_q*a3_dot_q));
169    Fkq_2 = Fkq*Fkq;
170    // Call Zq=Z1*Z2*Z3
171    Zq = (1.0-Fkq_2)/(1.0-2.0*Fkq*cos(a1_dot_q)+Fkq_2);
172    Zq *= (1.0-Fkq_2)/(1.0-2.0*Fkq*cos(a2_dot_q)+Fkq_2);
173    Zq *= (1.0-Fkq_2)/(1.0-2.0*Fkq*cos(a3_dot_q)+Fkq_2);
174
175  // Use SphereForm directly from libigor
176  answer = _sphereform(q,radius,sld,solvent_sld)*Zq*latticescale;
177
178  return answer;
179 }
Note: See TracBrowser for help on using the repository browser.