Changeset 68425bf in sasmodels
- Timestamp:
- Oct 16, 2016 12:33:26 AM (8 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 4f79d94
- Parents:
- e30d645
- Location:
- sasmodels
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/conversion_table.py
r14838a3 r68425bf 257 257 "EllipticalCylinderModel", 258 258 { 259 "axis_ratio": "r_ratio", 260 "radius_minor": "r_minor", 261 "sld": "sldCyl", 262 "sld_solvent": "sldSolv", 263 "theta": "cyl_theta", 259 264 "phi": "cyl_phi", 260 265 "psi": "cyl_psi", 261 "theta": "cyl_theta",262 "sld": "sldCyl",263 "axis_ratio": "r_ratio",264 "sld_solvent": "sldSolv"265 266 } 266 267 ], -
sasmodels/models/elliptical_cylinder.c
ra807206 r68425bf 6 6 7 7 8 double _elliptical_cylinder_kernel(double q, double radius_minor, double r_ratio, double theta);9 8 10 double _elliptical_cylinder_kernel(double q, double radius_minor, double r_ratio, double theta) 9 static double 10 _kernel(double q, double radius_minor, double r_ratio, double theta) 11 11 { 12 12 // This is the function LAMBDA1^2 in Feigin's notation … … 30 30 } 31 31 32 double Iq(double q, double radius_minor, double r_ratio, double length, 33 double sld, double solvent_sld) { 32 double 33 Iq(double q, double radius_minor, double r_ratio, double length, 34 double sld, double solvent_sld) 35 { 36 // orientational average limits 37 const double va = 0.0; 38 const double vb = 1.0; 39 // inner integral limits 40 const double vaj=0.0; 41 const double vbj=M_PI; 34 42 35 const int nordi=76; //order of integration 36 const int nordj=20; 37 double va,vb; //upper and lower integration limits 38 double summ,zi,yyy,answer; //running tally of integration 39 double summj,vaj,vbj,zij,arg,si; //for the inner integration 40 41 // orientational average limits 42 va = 0.0; 43 vb = 1.0; 44 // inner integral limits 45 vaj=0.0; 46 vbj=M_PI; 43 const double radius_major = r_ratio * radius_minor; 44 const double rA = 0.5*(square(radius_major) + square(radius_minor)); 45 const double rB = 0.5*(square(radius_major) - square(radius_minor)); 47 46 48 47 //initialize integral 49 summ = 0.0; 50 51 const double delrho = sld - solvent_sld; 52 53 for(int i=0;i<nordi;i++) { 48 double outer_sum = 0.0; 49 for(int i=0;i<76;i++) { 54 50 //setup inner integral over the ellipsoidal cross-section 55 summj=0; 56 zi = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0; //the "x" dummy 57 arg = radius_minor*sqrt(1.0-zi*zi); 58 for(int j=0;j<nordj;j++) { 51 const double cos_val = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0; 52 const double sin_val = sqrt(1.0 - cos_val*cos_val); 53 //const double arg = radius_minor*sin_val; 54 double inner_sum=0; 55 for(int j=0;j<20;j++) { 59 56 //20 gauss points for the inner integral 60 zij = ( Gauss20Z[j]*(vbj-vaj) + vaj + vbj )/2.0; //the "y" dummy 61 yyy = Gauss20Wt[j] * _elliptical_cylinder_kernel(q, arg, r_ratio, zij); 62 summj += yyy; 57 const double theta = ( Gauss20Z[j]*(vbj-vaj) + vaj + vbj )/2.0; 58 const double r = sin_val*sqrt(rA - rB*cos(theta)); 59 const double be = sas_J1c(q*r); 60 inner_sum += Gauss20Wt[j] * be * be; 63 61 } 64 62 //now calculate the value of the inner integral 65 answer = (vbj-vaj)/2.0*summj;63 inner_sum *= 0.5*(vbj-vaj); 66 64 67 65 //now calculate outer integral 68 arg = q*length*zi/2.0; 69 si = square(sinc(arg)); 70 yyy = Gauss76Wt[i] * answer * si; 71 summ += yyy; 66 const double si = sinc(q*0.5*length*cos_val); 67 outer_sum += Gauss76Wt[i] * inner_sum * si * si; 72 68 } 69 outer_sum *= 0.5*(vb-va); 73 70 74 71 //divide integral by Pi 75 answer = (vb-va)/2.0*summ/M_PI; 76 // Multiply by contrast^2 77 answer *= delrho*delrho; 72 const double form = outer_sum/M_PI; 78 73 74 // scale by contrast and volume, and convert to to 1/cm units 79 75 const double vol = form_volume(radius_minor, r_ratio, length); 80 return answer*vol*vol*1.0e-4; 76 const double delrho = sld - solvent_sld; 77 return 1.0e-4*square(delrho*vol)*form; 81 78 } 82 79 83 80 84 double Iqxy(double qx, double qy, double radius_minor, double r_ratio, double length,85 double sld, double solvent_sld, double theta, double phi, double psi) { 86 const double _theta = theta * M_PI / 180.0;87 const double _phi = phi * M_PI / 180.0;88 const double _psi = psi * M_PI / 180.0;89 const double q = sqrt(qx*qx+qy*qy); 90 const double q_x = qx/q;91 const double q_y = qy/q;81 double 82 Iqxy(double qx, double qy, 83 double radius_minor, double r_ratio, double length, 84 double sld, double solvent_sld, 85 double theta, double phi, double psi) 86 { 87 double q, cos_val, cos_mu, cos_nu; 88 ORIENT_ASYMMETRIC(qx, qy, theta, phi, psi, q, cos_val, cos_mu, cos_nu); 92 89 93 //Cylinder orientation 94 double cyl_x = cos(_theta) * cos(_phi); 95 double cyl_y = sin(_theta); 96 97 //cyl_z = -cos(_theta) * sin(_phi); 98 99 // q vector 100 //q_z = 0; 101 102 // Note: cos(alpha) = 0 and 1 will get an 103 // undefined value from CylKernel 104 //alpha = acos( cos_val ); 105 106 //ellipse orientation: 107 // the elliptical corss section was transformed and projected 108 // into the detector plane already through sin(alpha)and furthermore psi remains as same 109 // on the detector plane. 110 // So, all we need is to calculate the angle (nu) of the minor axis of the ellipse wrt 111 // the wave vector q. 112 113 //x- y- component on the detector plane. 114 const double ella_x = -cos(_phi)*sin(_psi) * sin(_theta)+sin(_phi)*cos(_psi); 115 const double ella_y = sin(_psi)*cos(_theta); 116 const double ellb_x = -sin(_theta)*cos(_psi)*cos(_phi)-sin(_psi)*sin(_phi); 117 const double ellb_y = cos(_theta)*cos(_psi); 118 119 // Compute the angle btw vector q and the 120 // axis of the cylinder 121 double cos_val = cyl_x*q_x + cyl_y*q_y;// + cyl_z*q_z; 122 123 // calculate the axis of the ellipse wrt q-coord. 124 double cos_nu = ella_x*q_x + ella_y*q_y; 125 double cos_mu = ellb_x*q_x + ellb_y*q_y; 126 127 // The following test should always pass 128 if (fabs(cos_val)>1.0) { 129 //printf("cyl_ana_2D: Unexpected error: cos(alpha)>1\n"); 130 cos_val = 1.0; 131 } 132 if (fabs(cos_nu)>1.0) { 133 //printf("cyl_ana_2D: Unexpected error: cos(nu)>1\n"); 134 cos_nu = 1.0; 135 } 136 if (fabs(cos_mu)>1.0) { 137 //printf("cyl_ana_2D: Unexpected error: cos(nu)>1\n"); 138 cos_mu = 1.0; 139 } 140 141 const double r_major = r_ratio * radius_minor; 142 const double qr = q*sqrt( r_major*r_major*cos_nu*cos_nu + radius_minor*radius_minor*cos_mu*cos_mu ); 143 const double qL = q*length*cos_val/2.0; 144 145 double Be; 146 if (qr==0){ 147 Be = 0.5; 148 }else{ 149 //Be = NR_BessJ1(qr)/qr; 150 Be = 0.5*sas_J1c(qr); 151 } 152 153 double Si; 154 if (qL==0){ 155 Si = 1.0; 156 }else{ 157 Si = sin(qL)/qL; 158 } 159 160 const double k = 2.0 * Be * Si; 90 // Compute: r = sqrt((radius_major*cos_nu)^2 + (radius_minor*cos_mu)^2) 91 // Given: radius_major = r_ratio * radius_minor 92 const double r = radius_minor*sqrt(square(r_ratio*cos_nu) + cos_mu*cos_mu); 93 const double be = sas_J1c(q*r); 94 const double si = sinc(q*0.5*length*cos_val); 95 const double Aq = be * si; 96 const double delrho = sld - solvent_sld; 161 97 const double vol = form_volume(radius_minor, r_ratio, length); 162 return (sld - solvent_sld) * (sld - solvent_sld) * k * k *vol*vol*1.0e-4;98 return 1.0e-4 * square(delrho * vol * Aq); 163 99 }
Note: See TracChangeset
for help on using the changeset viewer.