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