source: sasmodels/sasmodels/models/cylinder.c @ 3e428ec

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 3e428ec was ef2861b, checked in by Paul Kienzle <pkienzle@…>, 10 years ago

cylinder performance tweak

  • Property mode set to 100644
File size: 2.6 KB
RevLine 
[994d77f]1double form_volume(double radius, double length);
2double Iq(double q, double sld, double solvent_sld, double radius, double length);
3double Iqxy(double qx, double qy, double sld, double solvent_sld,
4    double radius, double length, double theta, double phi);
[5d4777d]5
6// twovd = 2 * volume * delta_rho
7// besarg = q * R * sin(alpha)
8// siarg = q * L/2 * cos(alpha)
[ef2861b]9double _cyl(double besarg, double siarg);
10double _cyl(double besarg, double siarg)
[5d4777d]11{
[994d77f]12    const double bj = (besarg == 0.0 ? 0.5 : J1(besarg)/besarg);
13    const double si = (siarg == 0.0 ? 1.0 : sin(siarg)/siarg);
[ef2861b]14    return si*bj;
[5d4777d]15}
[14de349]16
[994d77f]17double form_volume(double radius, double length)
[14de349]18{
19    return M_PI*radius*radius*length;
20}
21
[994d77f]22double Iq(double q,
23    double sld,
24    double solvent_sld,
25    double radius,
26    double length)
[14de349]27{
[994d77f]28    const double qr = q*radius;
29    const double qh = q*0.5*length;
30    double total = 0.0;
31    // double lower=0, upper=M_PI_2;
[14de349]32    for (int i=0; i<76 ;i++) {
[ff7119b]33        // translate a point in [-1,1] to a point in [lower,upper]
[994d77f]34        //const double alpha = ( Gauss76Z[i]*(upper-lower) + upper + lower )/2.0;
35        const double alpha = 0.5*(Gauss76Z[i]*M_PI_2 + M_PI_2);
36        double sn, cn;
[5d4777d]37        SINCOS(alpha, sn, cn);
[ef2861b]38        // For a bit of efficiency, we are moving the 2 V delta rho constant
39        // factor, 2Vd, out of the loop, so this is fq/2Vd rather than fq.
40        const double fq = _cyl(qr*sn, qh*cn);
[5d4777d]41        total += Gauss76Wt[i] * fq * fq * sn;
[14de349]42    }
[ff7119b]43    // translate dx in [-1,1] to dx in [lower,upper]
[994d77f]44    //const double form = (upper-lower)/2.0*total;
[ef2861b]45    const double twovd = 2.0*(sld-solvent_sld)*form_volume(radius, length);
46    return 1.0e-4 * twovd * twovd * total * M_PI_4;
[14de349]47}
48
49
[994d77f]50double Iqxy(double qx, double qy,
51    double sld,
52    double solvent_sld,
53    double radius,
54    double length,
55    double theta,
56    double phi)
[14de349]57{
[5d4777d]58    // TODO: check that radius<0 and length<0 give zero scattering.
59    // This should be the case since the polydispersity weight vector should
60    // be zero length, and this function never called.
[994d77f]61    double sn, cn; // slots to hold sincos function output
[14de349]62
63    // Compute angle alpha between q and the cylinder axis
64    SINCOS(theta*M_PI_180, sn, cn);
[994d77f]65    const double q = sqrt(qx*qx+qy*qy);
[ef2861b]66    const double cos_val = (q==0. ? 1.0 : (cn*cos(phi*M_PI_180)*qx + sn*qy)/q);
[994d77f]67    const double alpha = acos(cos_val);
[ef2861b]68    SINCOS(alpha, sn, cn);
69    //sn = sqrt(1.0 - cos_val*cos_val);
70    //sn = 1.0 - 0.5*cos_val*cos_val;  // if cos_val is very small
71    //cn = cos_val;
[14de349]72
[994d77f]73    const double twovd = 2.0*(sld-solvent_sld)*form_volume(radius, length);
[ef2861b]74    const double fq = twovd * _cyl(q*radius*sn, q*0.5*length*cn);
[994d77f]75    return 1.0e-4 * fq * fq;
[14de349]76}
Note: See TracBrowser for help on using the repository browser.