Changeset 85b856b in sasview for sansmodels/src/c_models


Ignore:
Timestamp:
Jan 4, 2012 4:08:55 PM (13 years ago)
Author:
Mathieu Doucet <doucetm@…>
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
Message:

Testing C refactor on BarBell?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/c_models/barbell.cpp

    r67424cd r85b856b  
    2828extern "C" { 
    2929        #include "libCylinder.h" 
     30  #include "GaussWeights.h" 
    3031        #include "barbell.h" 
    3132} 
     
    4647} 
    4748 
     49double 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} 
    48116/** 
    49117 * Function to evaluate 1D scattering function 
     
    123191 */ 
    124192double 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; 
    137207 
    138208        // Get the dispersion points for the rad_bar 
     
    168238        // Loop over radius weight points 
    169239        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; 
    171241                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; 
    173243                        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; 
    175245                                // Average over theta distribution 
    176246                                for(size_t l=0; l< weights_theta.size(); l++) { 
    177                                         dp.theta = weights_theta[l].value; 
     247                                        _theta = weights_theta[l].value; 
    178248                                        // Average over phi distribution 
    179249                                        for(size_t m=0; m< weights_phi.size(); m++) { 
    180                                                 dp.phi = weights_phi[m].value; 
     250                                                _phi = weights_phi[m].value; 
    181251                                                //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); 
    185279 
    186280                                                double _ptvalue = weights_rad_bar[i].weight 
     
    190284                                                                                        * weights_phi[m].weight 
    191285                                                                                        * vol_i 
    192                                                                                         * barbell_analytical_2DXY(&dp, qx, qy); 
     286                                                                                        * output; 
    193287                                                                                        //* pow(weights_rad[i].value,3.0); 
     288 
    194289                                                // Consider when there is infinte or nan. 
    195290                                                if ( _ptvalue == INFINITY || _ptvalue == NAN){ 
Note: See TracChangeset for help on using the changeset viewer.