Changeset 85b856b in sasview for sansmodels/src/c_models
- Timestamp:
- Jan 4, 2012 4:08:55 PM (13 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 43cc1ad2
- Parents:
- fb732dc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sansmodels/src/c_models/barbell.cpp
r67424cd r85b856b 28 28 extern "C" { 29 29 #include "libCylinder.h" 30 #include "GaussWeights.h" 30 31 #include "barbell.h" 31 32 } … … 46 47 } 47 48 49 double bar2d_kernel(double dp[], double q, double alpha) { 50 int j; 51 double Pi; 52 double scale,contr,bkg,sldc,slds; 53 double len,rad,hDist,endRad; 54 int nordj=76; 55 double zi=alpha,yyy,answer; //running tally of integration 56 double summj,vaj,vbj,zij; //for the inner integration 57 double arg1,arg2,inner,be; 58 59 60 scale = dp[0]; 61 rad = dp[1]; 62 len = dp[2]; 63 endRad = dp[3]; 64 sldc = dp[4]; 65 slds = dp[5]; 66 bkg = dp[6]; 67 68 hDist = sqrt(fabs(endRad*endRad-rad*rad)); //by definition for this model 69 70 contr = sldc-slds; 71 72 Pi = 4.0*atan(1.0); 73 vaj = -1.0*hDist/endRad; 74 vbj = 1.0; //endpoints of inner integral 75 76 summj=0.0; 77 78 for(j=0;j<nordj;j++) { 79 //20 gauss points for the inner integral 80 zij = ( Gauss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0; //the "t" dummy 81 yyy = Gauss76Wt[j] * Dumb_kernel(dp,q,zij,zi); //uses the same Kernel as the Dumbbell, here L>0 82 summj += yyy; 83 } 84 //now calculate the value of the inner integral 85 inner = (vbj-vaj)/2.0*summj; 86 inner *= 4.0*Pi*endRad*endRad*endRad; 87 88 //now calculate outer integrand 89 arg1 = q*len/2.0*cos(zi); 90 arg2 = q*rad*sin(zi); 91 yyy = inner; 92 93 if(arg2 == 0) { 94 be = 0.5; 95 } else { 96 be = NR_BessJ1(arg2)/arg2; 97 } 98 99 if(arg1 == 0.0) { //limiting value of sinc(0) is 1; sinc is not defined in math.h 100 yyy += Pi*rad*rad*len*2.0*be; 101 } else { 102 yyy += Pi*rad*rad*len*sin(arg1)/arg1*2.0*be; 103 } 104 yyy *= yyy; //sin(zi); 105 answer = yyy; 106 107 108 answer /= Pi*rad*rad*len + 2.0*Pi*(2.0*endRad*endRad*endRad/3.0+endRad*endRad*hDist-hDist*hDist*hDist/3.0); //divide by volume 109 answer *= 1.0e8; //convert to cm^-1 110 answer *= contr*contr; 111 answer *= scale; 112 answer += bkg; 113 114 return answer; 115 } 48 116 /** 49 117 * Function to evaluate 1D scattering function … … 123 191 */ 124 192 double BarBellModel :: operator()(double qx, double qy) { 125 BarBellParameters dp; 126 127 dp.scale = scale(); 128 dp.rad_bar = rad_bar(); 129 dp.len_bar = len_bar(); 130 dp.rad_bell = rad_bell(); 131 dp.sld_barbell = sld_barbell(); 132 dp.sld_solv = sld_solv(); 133 dp.background = 0.0; 134 dp.theta = theta(); 135 dp.phi = phi(); 136 193 double dp[7]; 194 195 // Fill parameter array for IGOR library 196 // Add the background after averaging 197 dp[0] = scale(); 198 dp[1] = rad_bar(); 199 dp[2] = len_bar(); 200 dp[3] = rad_bell(); 201 dp[4] = sld_barbell(); 202 dp[5] = sld_solv(); 203 dp[6] = 0.0; 204 205 double _theta = 0.0; 206 double _phi = 0.0; 137 207 138 208 // Get the dispersion points for the rad_bar … … 168 238 // Loop over radius weight points 169 239 for(size_t i=0; i<weights_rad_bar.size(); i++) { 170 dp .rad_bar= weights_rad_bar[i].value;240 dp[1] = weights_rad_bar[i].value; 171 241 for(size_t j=0; j<weights_len_bar.size(); j++) { 172 dp .len_bar= weights_len_bar[j].value;242 dp[2] = weights_len_bar[j].value; 173 243 for(size_t k=0; k<weights_rad_bell.size(); k++) { 174 dp .rad_bell= weights_rad_bell[k].value;244 dp[3] = weights_rad_bell[k].value; 175 245 // Average over theta distribution 176 246 for(size_t l=0; l< weights_theta.size(); l++) { 177 dp.theta = weights_theta[l].value;247 _theta = weights_theta[l].value; 178 248 // Average over phi distribution 179 249 for(size_t m=0; m< weights_phi.size(); m++) { 180 dp.phi = weights_phi[m].value;250 _phi = weights_phi[m].value; 181 251 //Un-normalize Form by volume 182 hDist = sqrt(fabs(dp.rad_bell*dp.rad_bell-dp.rad_bar*dp.rad_bar)); 183 vol_i = pi*dp.rad_bar*dp.rad_bar*dp.len_bar+2.0*pi*(2.0*dp.rad_bell*dp.rad_bell*dp.rad_bell/3.0 184 +dp.rad_bell*dp.rad_bell*hDist-hDist*hDist*hDist/3.0); 252 hDist = sqrt(fabs(dp[3]*dp[3]-dp[1]*dp[1])); 253 vol_i = pi*dp[1]*dp[1]*dp[2]+2.0*pi*(2.0*dp[3]*dp[3]*dp[3]/3.0 254 +dp[3]*dp[3]*hDist-hDist*hDist*hDist/3.0); 255 256 const double q = sqrt(qx*qx+qy*qy); 257 //convert angle degree to radian 258 const double pi = 4.0*atan(1.0); 259 260 // Cylinder orientation 261 const double cyl_x = sin(_theta * pi/180.0) * cos(_phi * pi/180.0); 262 const double cyl_y = sin(_theta * pi/180.0) * sin(_phi * pi/180.0); 263 264 // Compute the angle btw vector q and the 265 // axis of the cylinder (assume qz = 0) 266 const double cos_val = cyl_x*qx + cyl_y*qy; 267 268 // The following test should always pass 269 if (fabs(cos_val)>1.0) { 270 return 0; 271 } 272 273 // Note: cos(alpha) = 0 and 1 will get an 274 // undefined value from CylKernel 275 const double alpha = acos( cos_val ); 276 277 // Call the IGOR library function to get the kernel 278 const double output = bar2d_kernel(dp, q, alpha)/sin(alpha); 185 279 186 280 double _ptvalue = weights_rad_bar[i].weight … … 190 284 * weights_phi[m].weight 191 285 * vol_i 192 * barbell_analytical_2DXY(&dp, qx, qy);286 * output; 193 287 //* pow(weights_rad[i].value,3.0); 288 194 289 // Consider when there is infinte or nan. 195 290 if ( _ptvalue == INFINITY || _ptvalue == NAN){
Note: See TracChangeset
for help on using the changeset viewer.