Changeset 58210db in sasmodels


Ignore:
Timestamp:
Jul 29, 2016 12:56:37 AM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
f67f26c
Parents:
4f1f876
Message:

hollow cylinder performance improvements

Location:
sasmodels/models
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/models/hollow_cylinder.c

    r2f5c6d4 r58210db  
    99 
    1010// From Igor library 
    11 static double hollow_cylinder_scaling(double integrand, double delrho, double volume) 
     11static double hollow_cylinder_scaling( 
     12    double integrand, double delrho, double volume) 
    1213{ 
    13         double answer; 
    14         // Multiply by contrast^2 
    15         answer = integrand*delrho*delrho; 
     14    double answer; 
     15    // Multiply by contrast^2 
     16    answer = integrand*delrho*delrho; 
    1617 
    17         //normalize by cylinder volume 
    18         answer *= volume*volume; 
     18    //normalize by cylinder volume 
     19    answer *= volume*volume; 
    1920 
    20         //convert to [cm-1] 
    21         answer *= 1.0e-4; 
     21    //convert to [cm-1] 
     22    answer *= 1.0e-4; 
    2223 
    23         return answer; 
     24    return answer; 
    2425} 
    2526 
    26 static double _hollow_cylinder_kernel(double q, double core_radius, double radius, 
    27         double length, double dum) 
     27 
     28static double _hollow_cylinder_kernel( 
     29    double q, double core_radius, double radius, double length, double dum) 
    2830{ 
    29     double gamma,arg1,arg2,lam1,lam2,psi,sinarg,t2,retval;              //local variables 
    30      
    31     gamma = core_radius/radius; 
    32     arg1 = q*radius*sqrt(1.0-dum*dum);          //1=shell (outer radius) 
    33     arg2 = q*core_radius*sqrt(1.0-dum*dum);                     //2=core (inner radius) 
    34     if (arg1 == 0.0){ 
    35         lam1 = 1.0; 
    36     }else{ 
    37         lam1 = sas_J1c(arg1); 
    38     } 
    39     if (arg2 == 0.0){ 
    40         lam2 = 1.0; 
    41     }else{ 
    42         lam2 = sas_J1c(arg2); 
    43     } 
    44     //Todo: Need to check psi behavior as gamma goes to 1. 
    45     psi = (lam1 -  gamma*gamma*lam2)/(1.0-gamma*gamma);         //SRK 10/19/00 
    46     sinarg = q*length*dum/2.0; 
    47     if (sinarg == 0.0){ 
    48         t2 = 1.0; 
    49     }else{ 
    50         t2 = sin(sinarg)/sinarg; 
    51     } 
     31    //Note: lim_{r -> r_c} psi = J0(core_radius*qs) 
     32    const double qs = q*sqrt(1.0-dum*dum); 
     33    const double lam1 = sas_J1c(radius*qs); 
     34    const double lam2 = sas_J1c(core_radius*qs); 
     35    const double gamma_sq = square(core_radius/radius); 
     36    const double psi = (lam1 - gamma_sq*lam2)/(1.0 - gamma_sq); //SRK 10/19/00 
     37    const double t2 = sinc(q*length*dum/2.0); 
    5238 
    53     retval = psi*psi*t2*t2; 
    54      
    55     return(retval); 
     39    return square(psi*t2); 
    5640} 
    57 static double hollow_cylinder_analytical_2D_scaled(double q, double q_x, double q_y, double radius, double core_radius, double length, double sld, 
    58         double solvent_sld, double theta, double phi) { 
    59         double cyl_x, cyl_y; //, cyl_z 
    60         //double q_z; 
    61         double vol, cos_val, delrho; 
    62         double answer; 
    63         //convert angle degree to radian 
    64         double pi = 4.0*atan(1.0); 
    65         theta = theta * pi/180.0; 
    66         phi = phi * pi/180.0; 
    67         delrho = solvent_sld - sld; 
    6841 
    69         // Cylinder orientation 
    70         cyl_x = cos(theta) * cos(phi); 
    71         cyl_y = sin(theta); 
    72         //cyl_z = -cos(theta) * sin(phi); 
    7342 
    74         // q vector 
    75         //q_z = 0; 
     43static double hollow_cylinder_analytical_2D_scaled( 
     44    double q, double q_x, double q_y, double radius, double core_radius, 
     45    double length, double sld, double solvent_sld, double theta, double phi) 
     46{ 
     47    double cyl_x, cyl_y; //, cyl_z 
     48    //double q_z; 
     49    double vol, cos_val, delrho; 
     50    double answer; 
     51    //convert angle degree to radian 
     52    theta = theta * M_PI_180; 
     53    phi = phi * M_PI_180; 
     54    delrho = solvent_sld - sld; 
    7655 
    77         // Compute the angle btw vector q and the 
    78         // axis of the cylinder 
    79         cos_val = cyl_x*q_x + cyl_y*q_y;// + cyl_z*q_z; 
     56    // Cylinder orientation 
     57    cyl_x = cos(theta) * cos(phi); 
     58    cyl_y = sin(theta); 
     59    //cyl_z = -cos(theta) * sin(phi); 
    8060 
    81         answer = _hollow_cylinder_kernel(q, core_radius, radius, length, cos_val); 
     61    // q vector 
     62    //q_z = 0; 
    8263 
    83         vol = form_volume(radius, core_radius, length); 
    84         answer = hollow_cylinder_scaling(answer, delrho, vol); 
     64    // Compute the angle btw vector q and the 
     65    // axis of the cylinder 
     66    cos_val = cyl_x*q_x + cyl_y*q_y;// + cyl_z*q_z; 
    8567 
    86         return answer; 
     68    answer = _hollow_cylinder_kernel(q, core_radius, radius, length, cos_val); 
     69 
     70    vol = form_volume(radius, core_radius, length); 
     71    answer = hollow_cylinder_scaling(answer, delrho, vol); 
     72 
     73    return answer; 
    8774} 
    8875 
     
    9077double form_volume(double radius, double core_radius, double length) 
    9178{ 
    92         double pi = 4.0*atan(1.0); 
    93         double v_shell = pi*length*(radius*radius-core_radius*core_radius); 
    94         return(v_shell); 
     79    double v_shell = M_PI*length*(radius*radius-core_radius*core_radius); 
     80    return(v_shell); 
    9581} 
    9682 
    9783 
    98 double Iq(double q, double radius, double core_radius, double length, double sld, 
    99         double solvent_sld) 
     84double Iq(double q, double radius, double core_radius, double length, 
     85    double sld, double solvent_sld) 
    10086{ 
    10187    int i; 
    102         int nord=76;                    //order of integration 
    103         double lower,upper,zi, inter;           //upper and lower integration limits 
    104         double summ,answer,delrho;                      //running tally of integration 
    105         double norm,volume;     //final calculation variables 
    106          
    107         delrho = solvent_sld - sld; 
    108         lower = 0.0; 
    109         upper = 1.0;            //limits of numerical integral 
     88    double lower,upper,zi, inter;               //upper and lower integration limits 
     89    double summ,answer,delrho;                  //running tally of integration 
     90    double norm,volume; //final calculation variables 
    11091 
    111         summ = 0.0;                     //initialize intergral 
    112         for(i=0;i<nord;i++) { 
    113                 zi = ( Gauss76Z[i] * (upper-lower) + lower + upper )/2.0; 
    114                 inter = Gauss76Wt[i] * _hollow_cylinder_kernel(q, core_radius, radius, length, zi); 
    115                 summ += inter; 
    116         } 
    117          
    118         norm = summ*(upper-lower)/2.0; 
    119         volume = form_volume(radius, core_radius, length); 
    120         answer = hollow_cylinder_scaling(norm, delrho, volume); 
    121          
    122         return(answer); 
     92    lower = 0.0; 
     93    upper = 1.0;                //limits of numerical integral 
     94 
     95    summ = 0.0;                 //initialize intergral 
     96    for (i=0;i<76;i++) { 
     97        zi = ( Gauss76Z[i] * (upper-lower) + lower + upper )/2.0; 
     98        inter = Gauss76Wt[i] * _hollow_cylinder_kernel(q, core_radius, radius, length, zi); 
     99        summ += inter; 
     100    } 
     101 
     102    norm = summ*(upper-lower)/2.0; 
     103    volume = form_volume(radius, core_radius, length); 
     104    delrho = solvent_sld - sld; 
     105    answer = hollow_cylinder_scaling(norm, delrho, volume); 
     106 
     107    return(answer); 
    123108} 
    124109 
    125 double Iqxy(double qx, double qy, double radius, double core_radius, double length, double sld, 
    126         double solvent_sld, double theta, double phi) 
     110 
     111double Iqxy(double qx, double qy, double radius, double core_radius, 
     112    double length, double sld, double solvent_sld, double theta, double phi) 
    127113{ 
    128         double q; 
    129         q = sqrt(qx*qx+qy*qy); 
    130         return hollow_cylinder_analytical_2D_scaled(q, qx/q, qy/q, radius, core_radius, length, sld, solvent_sld, theta, phi); 
     114    const double q = sqrt(qx*qx+qy*qy); 
     115    return hollow_cylinder_analytical_2D_scaled(q, qx/q, qy/q, radius, core_radius, length, sld, solvent_sld, theta, phi); 
    131116} 
  • sasmodels/models/hollow_cylinder.py

    r42356c8 r58210db  
    7979# pylint: enable=bad-whitespace, line-too-long 
    8080 
    81 source = ["lib/polevl.c","lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"] 
     81source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "hollow_cylinder.c"] 
    8282 
    8383# pylint: disable=W0613 
Note: See TracChangeset for help on using the changeset viewer.