Changes in / [17db833:d0462cf] in sasmodels
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/models/core_shell_parallelepiped.c
rc69d6d6 r3a1fc7d 3 3 double thick_rim_a, double thick_rim_b, double thick_rim_c) 4 4 { 5 //return length_a * length_b * length_c;6 5 return length_a * length_b * length_c + 7 6 2.0 * thick_rim_a * length_b * length_c + … … 24 23 double thick_rim_c) 25 24 { 26 // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c _scaled25 // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c 27 26 // Did not understand the code completely, it should be rechecked (Miguel Gonzalez) 28 27 //Code is rewritten,the code is compliant with Diva Singhs thesis now (Dirk Honecker) … … 30 29 const double mu = 0.5 * q * length_b; 31 30 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; 31 // Scale sides by B 32 const double a_over_b = length_a / length_b; 33 const double c_over_b = length_c / length_b; 38 34 39 // Scale sides by B 40 const double a_scaled = length_a / length_b; 41 const double c_scaled = length_c / length_b; 42 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 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; 46 38 47 39 double Vin = length_a * length_b * length_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 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); 55 43 56 44 // Scale factors (note that drC is not used later) 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 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); 62 49 63 50 // Precompute scale factors for combining cross terms from the shape 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; 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 ************************************************************ */ 69 85 70 86 // outer integral (with gauss points), integration limits = 0, 1 71 double outer_total = 0; //initialize integral 72 87 double outer_sum = 0; //initialize integral 73 88 for( int i=0; i<76; i++) { 74 89 double sigma = 0.5 * ( Gauss76Z[i] + 1.0 ); 75 90 double mu_proj = mu * sqrt(1.0-sigma*sigma); 76 91 77 // inner integral (with gauss points), integration limits = 0, 1 78 double inner_total = 0.0; 79 double inner_total_crim = 0.0; 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; 80 96 for(int j=0; j<76; j++) { 81 97 const double uu = 0.5 * ( Gauss76Z[j] + 1.0 ); 82 98 double sin_uu, cos_uu; 83 99 SINCOS(M_PI_2*uu, sin_uu, cos_uu); 84 const double si 1 = sas_sinx_x(mu_proj * sin_uu * a_scaled);85 const double si 2= sas_sinx_x(mu_proj * cos_uu );86 const double si 3 = sas_sinx_x(mu_proj * sin_uu * ta);87 const double si 4 = sas_sinx_x(mu_proj * cos_uu * tb);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); 88 104 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; 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; 92 107 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; 108 inner_sum += Gauss76Wt[j] * form * form; 96 109 } 97 inner_total *= 0.5; 98 inner_total_crim *= 0.5; 110 inner_sum *= 0.5; 99 111 // now sum up the outer integral 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); 112 outer_sum += Gauss76Wt[i] * inner_sum; 103 113 } 104 outer_ total*= 0.5;114 outer_sum *= 0.5; 105 115 106 116 //convert from [1e-12 A-1] to [cm-1] 107 return 1.0e-4 * outer_ total;117 return 1.0e-4 * outer_sum; 108 118 } 109 119 … … 129 139 130 140 double Vin = length_a * length_b * length_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); 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; 139 144 140 145 // The definitions of ta, tb, tc are not the same as in the 1D case because there is no 141 146 // the scaling by B. 142 double t a= length_a + 2.0*thick_rim_a;143 double t b= length_b + 2.0*thick_rim_b;144 double t c= length_c + 2.0*thick_rim_c;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; 145 150 //handle arg=0 separately, as sin(t)/t -> 1 as t->0 146 151 double siA = sas_sinx_x(0.5*length_a*qa); 147 152 double siB = sas_sinx_x(0.5*length_b*qb); 148 153 double siC = sas_sinx_x(0.5*length_c*qc); 149 double siAt = sas_sinx_x(0.5*t a*qa);150 double siBt = sas_sinx_x(0.5*t b*qb);151 double siCt = sas_sinx_x(0.5*t 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); 152 157 153 158 154 159 // f uses Vin, V1, V2, and V3 and it seems to have more sense than the value computed 155 160 // in the 1D code, but should be checked! 156 double f = ( dr0* siA*siB*siC*Vin157 + drA* (siAt-siA)*siB*siC*V1158 + drB* siA*(siBt-siB)*siC*V2159 + drC* siA*siB*(siCt-siC)*V3);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)); 160 165 161 166 return 1.0e-4 * f * f;
Note: See TracChangeset
for help on using the changeset viewer.