source: sasmodels/sasmodels/models/elliptical_cylinder.c @ a34b811

ticket-1257-vesicle-productticket_1156ticket_822_more_unit_tests
Last change on this file since a34b811 was a34b811, checked in by Paul Kienzle <pkienzle@…>, 5 years ago

use radius_effective/radius_effective_mode/radius_effective_modes consistently throughout the code

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[2a0b2b1]1static double
[251f54b]2form_volume(double radius_minor, double r_ratio, double length)
[a8b3cdb]3{
[a807206]4    return M_PI * radius_minor * radius_minor * r_ratio * length;
[a8b3cdb]5}
6
[d277229]7static double
[99658f6]8radius_from_excluded_volume(double radius_minor, double r_ratio, double length)
9{
10    const double r_equiv = sqrt(radius_minor*radius_minor*r_ratio);
11    return 0.5*cbrt(0.75*r_equiv*(2.0*r_equiv*length + (r_equiv + length)*(M_PI*r_equiv + length)));
12}
13
14static double
[d277229]15radius_from_volume(double radius_minor, double r_ratio, double length)
16{
17    const double volume_ellcyl = form_volume(radius_minor,r_ratio,length);
[6d5601c]18    return cbrt(volume_ellcyl/M_4PI_3);
[d277229]19}
20
21static double
[a94046f]22radius_from_min_dimension(double radius_minor, double r_ratio, double hlength)
[d277229]23{
24    const double rad_min = (r_ratio > 1.0 ? radius_minor : r_ratio*radius_minor);
[fbaef04]25    return (rad_min < hlength ? rad_min : hlength);
[d277229]26}
27
28static double
[a94046f]29radius_from_max_dimension(double radius_minor, double r_ratio, double hlength)
[d277229]30{
31    const double rad_max = (r_ratio < 1.0 ? radius_minor : r_ratio*radius_minor);
[fbaef04]32    return (rad_max > hlength ? rad_max : hlength);
[d277229]33}
34
35static double
36radius_from_diagonal(double radius_minor, double r_ratio, double length)
37{
38    const double radius_max = (r_ratio > 1.0 ? radius_minor*r_ratio : radius_minor);
39    return sqrt(radius_max*radius_max + 0.25*length*length);
40}
41
42static double
[a34b811]43radius_effective(int mode, double radius_minor, double r_ratio, double length)
[d277229]44{
[ee60aa7]45    switch (mode) {
[d42dd4a]46    default:
[99658f6]47    case 1: // equivalent cylinder excluded volume
48        return radius_from_excluded_volume(radius_minor, r_ratio, length);
49    case 2: // equivalent volume sphere
[d277229]50        return radius_from_volume(radius_minor, r_ratio, length);
[99658f6]51    case 3: // average radius
[d277229]52        return 0.5*radius_minor*(1.0 + r_ratio);
[99658f6]53    case 4: // min radius
[d277229]54        return (r_ratio > 1.0 ? radius_minor : r_ratio*radius_minor);
[99658f6]55    case 5: // max radius
[d277229]56        return (r_ratio < 1.0 ? radius_minor : r_ratio*radius_minor);
[99658f6]57    case 6: // equivalent circular cross-section
[d277229]58        return sqrt(radius_minor*radius_minor*r_ratio);
[99658f6]59    case 7: // half length
[d277229]60        return 0.5*length;
[99658f6]61    case 8: // half min dimension
[a94046f]62        return radius_from_min_dimension(radius_minor,r_ratio,0.5*length);
[99658f6]63    case 9: // half max dimension
[a94046f]64        return radius_from_max_dimension(radius_minor,r_ratio,0.5*length);
[99658f6]65    case 10: // half diagonal
[d277229]66        return radius_from_diagonal(radius_minor,r_ratio,length);
67    }
68}
69
[71b751d]70static void
71Fq(double q, double *F1, double *F2, double radius_minor, double r_ratio, double length,
[68425bf]72   double sld, double solvent_sld)
73{
[a8b3cdb]74    // orientational average limits
[68425bf]75    const double va = 0.0;
76    const double vb = 1.0;
[a8b3cdb]77    // inner integral limits
[68425bf]78    const double vaj=0.0;
79    const double vbj=M_PI;
[a8b3cdb]80
[68425bf]81    const double radius_major = r_ratio * radius_minor;
82    const double rA = 0.5*(square(radius_major) + square(radius_minor));
83    const double rB = 0.5*(square(radius_major) - square(radius_minor));
[a8b3cdb]84
[68425bf]85    //initialize integral
[71b751d]86    double outer_sum_F1 = 0.0;
87    double outer_sum_F2 = 0.0;
[74768cb]88    for(int i=0;i<GAUSS_N;i++) {
[a8b3cdb]89        //setup inner integral over the ellipsoidal cross-section
[74768cb]90        const double cos_val = ( GAUSS_Z[i]*(vb-va) + va + vb )/2.0;
[68425bf]91        const double sin_val = sqrt(1.0 - cos_val*cos_val);
92        //const double arg = radius_minor*sin_val;
[71b751d]93        double inner_sum_F1 = 0.0;
94        double inner_sum_F2 = 0.0;
[74768cb]95        for(int j=0;j<GAUSS_N;j++) {
96            const double theta = ( GAUSS_Z[j]*(vbj-vaj) + vaj + vbj )/2.0;
[68425bf]97            const double r = sin_val*sqrt(rA - rB*cos(theta));
[592343f]98            const double be = sas_2J1x_x(q*r);
[71b751d]99            inner_sum_F1 += GAUSS_W[j] * be;
100            inner_sum_F2 += GAUSS_W[j] * be * be;
[a8b3cdb]101        }
102        //now calculate the value of the inner integral
[71b751d]103        inner_sum_F1 *= 0.5*(vbj-vaj);
104        inner_sum_F2 *= 0.5*(vbj-vaj);
[a8b3cdb]105
106        //now calculate outer integral
[1e7b0db0]107        const double si = sas_sinx_x(q*0.5*length*cos_val);
[71b751d]108        outer_sum_F1 += GAUSS_W[i] * inner_sum_F1 * si;
109        outer_sum_F2 += GAUSS_W[i] * inner_sum_F2 * si * si;
[a8b3cdb]110    }
[71b751d]111    // correct limits and divide integral by pi
112    outer_sum_F1 *= 0.5*(vb-va)/M_PI;
113    outer_sum_F2 *= 0.5*(vb-va)/M_PI;
[a8b3cdb]114
[68425bf]115    // scale by contrast and volume, and convert to to 1/cm units
[71b751d]116    const double volume = form_volume(radius_minor, r_ratio, length);
117    const double contrast = sld - solvent_sld;
118    const double s = contrast*volume;
119    *F1 = 1.0e-2*s*outer_sum_F1;
120    *F2 = 1.0e-4*s*s*outer_sum_F2;
[a8b3cdb]121}
122
123
[2a0b2b1]124static double
[108e70e]125Iqabc(double qa, double qb, double qc,
[68425bf]126     double radius_minor, double r_ratio, double length,
[becded3]127     double sld, double solvent_sld)
[68425bf]128{
129    // Compute:  r = sqrt((radius_major*cos_nu)^2 + (radius_minor*cos_mu)^2)
130    // Given:    radius_major = r_ratio * radius_minor
[82592da]131    const double qr = radius_minor*sqrt(square(r_ratio*qb) + square(qa));
[2a0b2b1]132    const double be = sas_2J1x_x(qr);
133    const double si = sas_sinx_x(qc*0.5*length);
[71b751d]134    const double fq = be * si;
135    const double contrast = sld - solvent_sld;
136    const double volume = form_volume(radius_minor, r_ratio, length);
137    return 1.0e-4 * square(contrast * volume * fq);
[a8b3cdb]138}
Note: See TracBrowser for help on using the repository browser.