[754c454] | 1 | double form_volume(double radius); |
---|
| 2 | double Iq(double q,double dnn,double d_factor, double radius,double sld, double solvent_sld); |
---|
| 3 | double 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 | |
---|
| 7 | double _BCC_Integrand(double q, double dnn, double d_factor, double theta, double phi); |
---|
| 8 | double _BCCeval(double Theta, double Phi, double temp1, double temp3); |
---|
| 9 | double _sphereform(double q, double radius, double sld, double solvent_sld); |
---|
| 10 | |
---|
| 11 | |
---|
| 12 | double _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 | |
---|
| 22 | double _BCCeval(double Theta, double Phi, double temp1, double temp3) { |
---|
| 23 | |
---|
| 24 | double result; |
---|
[82d239a] | 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)); |
---|
[754c454] | 38 | |
---|
| 39 | return (result); |
---|
| 40 | } |
---|
| 41 | |
---|
| 42 | double _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); |
---|
[c95dc908] | 46 | const double bes = (qr == 0.0 ? 1.0 : 3.0*(sn-qr*cn)/(qr*qr*qr)); |
---|
[754c454] | 47 | const double fq = bes * (sld - solvent_sld)*form_volume(radius); |
---|
| 48 | return 1.0e-4*fq*fq; |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | double form_volume(double radius){ |
---|
| 52 | return 1.333333333333333*M_PI*radius*radius*radius; |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | |
---|
| 56 | double 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; |
---|
[c95dc908] | 74 | const double zphi = ( Gauss150Z[i]*(vb-va) + va + vb )/2.0; //the outer dummy is phi |
---|
[754c454] | 75 | for(int j=0;j<150;j++) { |
---|
| 76 | //20 gauss points for the inner integral |
---|
[c95dc908] | 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); |
---|
[754c454] | 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 | |
---|
| 97 | double 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 | } |
---|