Changes in / [d0462cf:17db833] in sasmodels


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/models/core_shell_parallelepiped.c

    r3a1fc7d rc69d6d6  
    33    double thick_rim_a, double thick_rim_b, double thick_rim_c) 
    44{ 
     5    //return length_a * length_b * length_c; 
    56    return length_a * length_b * length_c + 
    67           2.0 * thick_rim_a * length_b * length_c + 
     
    2324    double thick_rim_c) 
    2425{ 
    25     // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c 
     26    // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c_scaled 
    2627    // Did not understand the code completely, it should be rechecked (Miguel Gonzalez) 
    2728    //Code is rewritten,the code is compliant with Diva Singhs thesis now (Dirk Honecker) 
     
    2930    const double mu = 0.5 * q * length_b; 
    3031 
     32    //calculate volume before rescaling (in original code, but not used) 
     33    //double vol = form_volume(length_a, length_b, length_c, thick_rim_a, thick_rim_b, thick_rim_c); 
     34    //double vol = length_a * length_b * length_c + 
     35    //       2.0 * thick_rim_a * length_b * length_c + 
     36    //       2.0 * thick_rim_b * length_a * length_c + 
     37    //       2.0 * thick_rim_c * length_a * length_b; 
     38 
    3139    // Scale sides by B 
    32     const double a_over_b = length_a / length_b; 
    33     const double c_over_b = length_c / length_b; 
     40    const double a_scaled = length_a / length_b; 
     41    const double c_scaled = length_c / length_b; 
    3442 
    35     double tA_over_b = a_over_b + 2.0*thick_rim_a/length_b; 
    36     double tB_over_b = 1+ 2.0*thick_rim_b/length_b; 
    37     double tC_over_b = c_over_b + 2.0*thick_rim_c/length_b; 
     43    double ta = a_scaled + 2.0*thick_rim_a/length_b; // incorrect ta = (a_scaled + 2.0*thick_rim_a)/length_b; 
     44    double tb = 1+ 2.0*thick_rim_b/length_b; // incorrect tb = (a_scaled + 2.0*thick_rim_b)/length_b; 
     45    double tc = c_scaled + 2.0*thick_rim_c/length_b; //not present 
    3846 
    3947    double Vin = length_a * length_b * length_c; 
    40     double VtA = (2.0 * thick_rim_a * length_b * length_c); 
    41     double VtB = (2.0 * length_a * thick_rim_b * length_c); 
    42     double VtC = (2.0 * length_a * length_b * thick_rim_c); 
     48    //double Vot = (length_a * length_b * length_c + 
     49    //            2.0 * thick_rim_a * length_b * length_c + 
     50    //            2.0 * length_a * thick_rim_b * length_c + 
     51    //            2.0 * length_a * length_b * thick_rim_c); 
     52    double V1 = (2.0 * thick_rim_a * length_b * length_c);    // incorrect V1 (aa*bb*cc+2*ta*bb*cc) 
     53    double V2 = (2.0 * length_a * thick_rim_b * length_c);    // incorrect V2(aa*bb*cc+2*aa*tb*cc) 
     54    double V3 = (2.0 * length_a * length_b * thick_rim_c);    //not present 
    4355 
    4456    // Scale factors (note that drC is not used later) 
    45     const double dr0 = (core_sld-solvent_sld); 
    46     const double drA = (arim_sld-solvent_sld); 
    47     const double drB = (brim_sld-solvent_sld); 
    48     const double drC = (crim_sld-solvent_sld); 
     57    const double drho0 = (core_sld-solvent_sld); 
     58    const double drhoA = (arim_sld-solvent_sld); 
     59    const double drhoB = (brim_sld-solvent_sld); 
     60    const double drhoC = (crim_sld-solvent_sld);  // incorrect const double drC_Vot = (crim_sld-solvent_sld)*Vot; 
     61 
    4962 
    5063    // Precompute scale factors for combining cross terms from the shape 
    51     const double dr0_Vin = dr0*Vin; 
    52     const double drA_VtA = drA*VtA; 
    53     const double drB_VtB = drB*VtB; 
    54     const double drC_VtC = drC*VtC; 
    55     const double drV_delta = dr0_Vin - drA_VtA - drB_VtB - drC_VtC; 
    56  
    57     /*  *************** algorithm description ****************** 
    58  
    59     // Rewrite f as x*siC + y*siCt to move the siC/siCt calculation out 
    60     // of the inner loop.  That is: 
    61  
    62     f = (di-da-db-dc) sa sb sc + da sa' sb sc + db sa sb' sc + dc sa sb sc' 
    63       =  [ (di-da-db-dc) sa sb + da sa' sb + db sa sb' ] sc  + [dc sa sb] sc' 
    64       = x sc + y sc' 
    65  
    66     // where: 
    67     di = delta rho_core V_core 
    68     da = delta rho_rimA V_rimA 
    69     db = delta rho_rimB V_rimB 
    70     dc = delta rho_rimC V_rimC 
    71     sa = j_0 (q_a a/2)    // siA the code 
    72     sb = j_0 (q_b b/2) 
    73     sc = j_0 (q_c c/2) 
    74     sa' = j_0(q_a a_rim/2)  // siAt the code 
    75     sb' = j_0(q_b b_rim/2) 
    76     sc' = j_0(q_c c_rim/2) 
    77  
    78     // qa, qb, and qc are generated using polar coordinates, with the 
    79     // outer loop integrating over [0,1] after the u-substitution 
    80     //    sigma = cos(theta), sqrt(1-sigma^2) = sin(theta) 
    81     // and inner loop integrating over [0, pi/2] as 
    82     //    uu = phi 
    83  
    84     ************************************************************  */ 
     64    const double scale23 = drhoA*V1; 
     65    const double scale14 = drhoB*V2; 
     66    const double scale24 = drhoC*V3; 
     67    const double scale11 = drho0*Vin; 
     68    const double scale12 = drho0*Vin - scale23 - scale14 - scale24; 
    8569 
    8670    // outer integral (with gauss points), integration limits = 0, 1 
    87     double outer_sum = 0; //initialize integral 
     71    double outer_total = 0; //initialize integral 
     72 
    8873    for( int i=0; i<76; i++) { 
    8974        double sigma = 0.5 * ( Gauss76Z[i] + 1.0 ); 
    9075        double mu_proj = mu * sqrt(1.0-sigma*sigma); 
    9176 
    92         // inner integral (with gauss points), integration limits = 0, pi/2 
    93         const double siC = sas_sinx_x(mu * sigma * c_over_b); 
    94         const double siCt = sas_sinx_x(mu * sigma * tC_over_b); 
    95         double inner_sum = 0.0; 
     77        // inner integral (with gauss points), integration limits = 0, 1 
     78        double inner_total = 0.0; 
     79        double inner_total_crim = 0.0; 
    9680        for(int j=0; j<76; j++) { 
    9781            const double uu = 0.5 * ( Gauss76Z[j] + 1.0 ); 
    9882            double sin_uu, cos_uu; 
    9983            SINCOS(M_PI_2*uu, sin_uu, cos_uu); 
    100             const double siA = sas_sinx_x(mu_proj * sin_uu * a_over_b); 
    101             const double siB = sas_sinx_x(mu_proj * cos_uu ); 
    102             const double siAt = sas_sinx_x(mu_proj * sin_uu * tA_over_b); 
    103             const double siBt = sas_sinx_x(mu_proj * cos_uu * tB_over_b); 
     84            const double si1 = sas_sinx_x(mu_proj * sin_uu * a_scaled); 
     85            const double si2 = sas_sinx_x(mu_proj * cos_uu ); 
     86            const double si3 = sas_sinx_x(mu_proj * sin_uu * ta); 
     87            const double si4 = sas_sinx_x(mu_proj * cos_uu * tb); 
    10488 
    105             const double x = drV_delta*siA*siB + drA_VtA*siB*siAt + drB_VtB*siA*siBt; 
    106             const double form = x*siC + drC_VtC*siA*siB*siCt; 
     89            // Expression in libCylinder.c (neither drC nor Vot are used) 
     90            const double form = scale12*si1*si2 + scale23*si2*si3 + scale14*si1*si4; 
     91            const double form_crim = scale11*si1*si2; 
    10792 
    108             inner_sum += Gauss76Wt[j] * form * form; 
     93            //  correct FF : sum of square of phase factors 
     94            inner_total += Gauss76Wt[j] * form * form; 
     95            inner_total_crim += Gauss76Wt[j] * form_crim * form_crim; 
    10996        } 
    110         inner_sum *= 0.5; 
     97        inner_total *= 0.5; 
     98        inner_total_crim *= 0.5; 
    11199        // now sum up the outer integral 
    112         outer_sum += Gauss76Wt[i] * inner_sum; 
     100        const double si = sas_sinx_x(mu * c_scaled * sigma); 
     101        const double si_crim = sas_sinx_x(mu * tc * sigma); 
     102        outer_total += Gauss76Wt[i] * (inner_total * si * si + inner_total_crim * si_crim * si_crim); 
    113103    } 
    114     outer_sum *= 0.5; 
     104    outer_total *= 0.5; 
    115105 
    116106    //convert from [1e-12 A-1] to [cm-1] 
    117     return 1.0e-4 * outer_sum; 
     107    return 1.0e-4 * outer_total; 
    118108} 
    119109 
     
    139129 
    140130    double Vin = length_a * length_b * length_c; 
    141     double VtA = 2.0 * thick_rim_a * length_b * length_c; 
    142     double VtB = 2.0 * length_a * thick_rim_b * length_c; 
    143     double VtC = 2.0 * length_a * length_b * thick_rim_c; 
     131    double V1 = 2.0 * thick_rim_a * length_b * length_c;    // incorrect V1(aa*bb*cc+2*ta*bb*cc) 
     132    double V2 = 2.0 * length_a * thick_rim_b * length_c;    // incorrect V2(aa*bb*cc+2*aa*tb*cc) 
     133    double V3 = 2.0 * length_a * length_b * thick_rim_c; 
     134    // As for the 1D case, Vot is not used 
     135    //double Vot = (length_a * length_b * length_c + 
     136    //              2.0 * thick_rim_a * length_b * length_c + 
     137    //              2.0 * length_a * thick_rim_b * length_c + 
     138    //              2.0 * length_a * length_b * thick_rim_c); 
    144139 
    145140    // The definitions of ta, tb, tc are not the same as in the 1D case because there is no 
    146141    // the scaling by B. 
    147     double tA = length_a + 2.0*thick_rim_a; 
    148     double tB = length_b + 2.0*thick_rim_b; 
    149     double tC = length_c + 2.0*thick_rim_c; 
     142    double ta = length_a + 2.0*thick_rim_a; 
     143    double tb = length_b + 2.0*thick_rim_b; 
     144    double tc = length_c + 2.0*thick_rim_c; 
    150145    //handle arg=0 separately, as sin(t)/t -> 1 as t->0 
    151146    double siA = sas_sinx_x(0.5*length_a*qa); 
    152147    double siB = sas_sinx_x(0.5*length_b*qb); 
    153148    double siC = sas_sinx_x(0.5*length_c*qc); 
    154     double siAt = sas_sinx_x(0.5*tA*qa); 
    155     double siBt = sas_sinx_x(0.5*tB*qb); 
    156     double siCt = sas_sinx_x(0.5*tC*qc); 
     149    double siAt = sas_sinx_x(0.5*ta*qa); 
     150    double siBt = sas_sinx_x(0.5*tb*qb); 
     151    double siCt = sas_sinx_x(0.5*tc*qc); 
    157152 
    158153 
    159154    // f uses Vin, V1, V2, and V3 and it seems to have more sense than the value computed 
    160155    // in the 1D code, but should be checked! 
    161     double f = ( dr0*Vin*siA*siB*siC 
    162                + drA*VtA*(siAt-siA)*siB*siC 
    163                + drB*VtB*siA*(siBt-siB)*siC 
    164                + drC*VtC*siA*siB*(siCt-siC)); 
     156    double f = ( dr0*siA*siB*siC*Vin 
     157               + drA*(siAt-siA)*siB*siC*V1 
     158               + drB*siA*(siBt-siB)*siC*V2 
     159               + drC*siA*siB*(siCt-siC)*V3); 
    165160 
    166161    return 1.0e-4 * f * f; 
Note: See TracChangeset for help on using the changeset viewer.