Changeset 63d4dd1 in sasmodels for sasmodels/models/triaxial_ellipsoid.c


Ignore:
Timestamp:
Nov 9, 2018 3:25:10 PM (5 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
7126c04
Parents:
599993b9 (diff), cf3d0ce (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'beta_approx' into ticket-1015-gpu-mem-error

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/models/triaxial_ellipsoid.c

    r108e70e r99658f6  
    88 
    99static double 
    10 Iq(double q, 
     10radius_from_curvature(double radius_equat_minor, double radius_equat_major, double radius_polar) 
     11{ 
     12    // Trivial cases 
     13    if (radius_equat_minor == radius_equat_major == radius_polar) return radius_polar; 
     14    if (radius_equat_minor * radius_equat_major * radius_polar == 0.)  return 0.; 
     15 
     16 
     17    double r_equat_equiv, r_polar_equiv; 
     18    double radii[3] = {radius_equat_minor, radius_equat_major, radius_polar}; 
     19    double radmax = fmax(radii[0],fmax(radii[1],radii[2])); 
     20 
     21    double radius_1 = radmax; 
     22    double radius_2 = radmax; 
     23    double radius_3 = radmax; 
     24 
     25    for(int irad=0; irad<3; irad++) { 
     26        if (radii[irad] < radius_1) { 
     27            radius_3 = radius_2; 
     28            radius_2 = radius_1; 
     29            radius_1 = radii[irad]; 
     30            } else { 
     31                if (radii[irad] < radius_2) { 
     32                        radius_2 = radii[irad]; 
     33                } 
     34            } 
     35    } 
     36    if(radius_2-radius_1 > radius_3-radius_2) { 
     37        r_equat_equiv = sqrt(radius_2*radius_3); 
     38        r_polar_equiv = radius_1; 
     39    } else  { 
     40        r_equat_equiv = sqrt(radius_1*radius_2); 
     41        r_polar_equiv = radius_3; 
     42    } 
     43 
     44    // see equation (26) in A.Isihara, J.Chem.Phys. 18(1950)1446-1449 
     45    const double ratio = (r_polar_equiv < r_equat_equiv 
     46                          ? r_polar_equiv / r_equat_equiv 
     47                          : r_equat_equiv / r_polar_equiv); 
     48    const double e1 = sqrt(1.0 - ratio*ratio); 
     49    const double b1 = 1.0 + asin(e1) / (e1 * ratio); 
     50    const double bL = (1.0 + e1) / (1.0 - e1); 
     51    const double b2 = 1.0 + 0.5 * ratio * ratio / e1 * log(bL); 
     52    const double delta = 0.75 * b1 * b2; 
     53    const double ddd = 2.0 * (delta + 1.0) * r_polar_equiv * r_equat_equiv * r_equat_equiv; 
     54    return 0.5 * cbrt(ddd); 
     55} 
     56 
     57static double 
     58radius_from_volume(double radius_equat_minor, double radius_equat_major, double radius_polar) 
     59{ 
     60    return cbrt(radius_equat_minor*radius_equat_major*radius_polar); 
     61} 
     62 
     63static double 
     64radius_from_min_dimension(double radius_equat_minor, double radius_equat_major, double radius_polar) 
     65{ 
     66    const double rad_equat_min = (radius_equat_minor < radius_equat_major ? radius_equat_minor : radius_equat_major); 
     67    return (rad_equat_min < radius_polar ? rad_equat_min : radius_polar); 
     68} 
     69 
     70static double 
     71radius_from_max_dimension(double radius_equat_minor, double radius_equat_major, double radius_polar) 
     72{ 
     73    const double rad_equat_max = (radius_equat_minor < radius_equat_major ? radius_equat_major : radius_equat_minor); 
     74    return (rad_equat_max > radius_polar ? rad_equat_max : radius_polar); 
     75} 
     76 
     77static double 
     78effective_radius(int mode, double radius_equat_minor, double radius_equat_major, double radius_polar) 
     79{ 
     80    switch (mode) { 
     81    default: 
     82    case 1: // equivalent biaxial ellipsoid average curvature 
     83        return radius_from_curvature(radius_equat_minor,radius_equat_major, radius_polar); 
     84    case 2: // equivalent volume sphere 
     85        return radius_from_volume(radius_equat_minor,radius_equat_major, radius_polar); 
     86    case 3: // min radius 
     87        return radius_from_min_dimension(radius_equat_minor,radius_equat_major, radius_polar); 
     88    case 4: // max radius 
     89        return radius_from_max_dimension(radius_equat_minor,radius_equat_major, radius_polar); 
     90    } 
     91} 
     92 
     93static void 
     94Fq(double q, 
     95    double *F1, 
     96    double *F2, 
    1197    double sld, 
    1298    double sld_solvent, 
     
    20106    const double zm = M_PI_4; 
    21107    const double zb = M_PI_4; 
    22     double outer = 0.0; 
     108    double outer_sum_F1 = 0.0; 
     109    double outer_sum_F2 = 0.0; 
    23110    for (int i=0;i<GAUSS_N;i++) { 
    24111        //const double u = GAUSS_Z[i]*(upper-lower)/2 + (upper + lower)/2; 
     
    26113        const double pa_sinsq_phi = pa*square(sin(phi)); 
    27114 
    28         double inner = 0.0; 
     115        double inner_sum_F1 = 0.0; 
     116        double inner_sum_F2 = 0.0; 
    29117        const double um = 0.5; 
    30118        const double ub = 0.5; 
     
    34122            const double r = radius_equat_major*sqrt(pa_sinsq_phi*(1.0-usq) + 1.0 + pc*usq); 
    35123            const double fq = sas_3j1x_x(q*r); 
    36             inner += GAUSS_W[j] * fq * fq; 
     124            inner_sum_F1 += GAUSS_W[j] * fq; 
     125            inner_sum_F2 += GAUSS_W[j] * fq * fq; 
    37126        } 
    38         outer += GAUSS_W[i] * inner;  // correcting for dx later 
     127        outer_sum_F1 += GAUSS_W[i] * inner_sum_F1;  // correcting for dx later 
     128        outer_sum_F2 += GAUSS_W[i] * inner_sum_F2;  // correcting for dx later 
    39129    } 
    40130    // translate integration ranges from [-1,1] to [lower,upper] and normalize by 4 pi 
    41     const double fqsq = outer/4.0;  // = outer*um*zm*8.0/(4.0*M_PI); 
    42     const double vol = form_volume(radius_equat_minor, radius_equat_major, radius_polar); 
    43     const double drho = (sld - sld_solvent); 
    44     return 1.0e-4 * square(vol*drho) * fqsq; 
     131    outer_sum_F1 *= 0.25;  // = outer*um*zm*8.0/(4.0*M_PI); 
     132    outer_sum_F2 *= 0.25;  // = outer*um*zm*8.0/(4.0*M_PI); 
     133 
     134    const double volume = form_volume(radius_equat_minor, radius_equat_major, radius_polar); 
     135    const double contrast = (sld - sld_solvent); 
     136    *F1 = 1.0e-2 * contrast * volume * outer_sum_F1; 
     137    *F2 = 1.0e-4 * square(contrast * volume) * outer_sum_F2; 
    45138} 
     139 
    46140 
    47141static double 
Note: See TracChangeset for help on using the changeset viewer.