Changeset 688d315 in sasmodels
- Timestamp:
- Nov 20, 2017 11:45:30 AM (7 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- c11d09f, 0e55afe
- Parents:
- 4073633 (diff), 8c7d5d5 (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. - Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/models/core_shell_parallelepiped.py
r4073633 r688d315 215 215 216 216 # rkh 7/4/17 add random unit test for 2d, note make all params different, 2d values not tested against other codes or models 217 qx, qy = 0.2 * cos(pi/6.), 0.2 * sin(pi/6.) 218 tests = [[{}, 0.2, 0.533149288477], 219 [{}, [0.2], [0.533149288477]],220 [{'theta':10.0, 'phi':20.0}, (qx, qy), 0.0853299803222],221 [{'theta':10.0, 'phi':20.0}, [(qx, qy)], [0.0853299803222]],222 ]223 del tests # TODO: fix the tests 224 del qx, qy # not necessary to delete, but cleaner217 if 0: # pak: model rewrite; need to update tests 218 qx, qy = 0.2 * cos(pi/6.), 0.2 * sin(pi/6.) 219 tests = [[{}, 0.2, 0.533149288477], 220 [{}, [0.2], [0.533149288477]], 221 [{'theta':10.0, 'phi':20.0}, (qx, qy), 0.0853299803222], 222 [{'theta':10.0, 'phi':20.0}, [(qx, qy)], [0.0853299803222]], 223 ] 224 del qx, qy # not necessary to delete, but cleaner -
explore/asymint.py
r1820208 r49eb251 86 86 a, b, c = env.mpf(a), env.mpf(b), env.mpf(c) 87 87 def Fq(qa, qb, qc): 88 siA = env.sas_sinx_x( 0.5*a*qa/2)89 siB = env.sas_sinx_x( 0.5*b*qb/2)90 siC = env.sas_sinx_x( 0.5*c*qc/2)88 siA = env.sas_sinx_x(a*qa/2) 89 siB = env.sas_sinx_x(b*qb/2) 90 siC = env.sas_sinx_x(c*qc/2) 91 91 return siA * siB * siC 92 92 Fq.__doc__ = "parallelepiped a=%g, b=%g c=%g"%(a, b, c) 93 93 volume = a*b*c 94 94 norm = CONTRAST**2*volume/10000 95 return norm, Fq 96 97 def make_core_shell_parallelepiped(a, b, c, da, db, dc, slda, sldb, sldc, env=NPenv): 98 a, b, c = env.mpf(a), env.mpf(b), env.mpf(c) 99 da, db, dc = env.mpf(da), env.mpf(db), env.mpf(dc) 100 slda, sldb, sldc = env.mpf(slda), env.mpf(sldb), env.mpf(sldc) 101 drV0 = CONTRAST*a*b*c 102 dra, drb, drc = slda-SLD_SOLVENT, sldb-SLD_SOLVENT, sldc-SLD_SOLVENT 103 Aa, Ab, Ac = b*c, a*c, a*b 104 Ta, Tb, Tc = a + 2*da, b + 2*db, c + 2*dc 105 drVa, drVb, drVc = dra*a*Aa, drb*b*Ab, drc*c*Ac 106 drVTa, drVTb, drVTc = dra*Ta*Aa, drb*Tb*Ab, drc*Tc*Ac 107 def Fq(qa, qb, qc): 108 siA = env.sas_sinx_x(a*qa/2) 109 siB = env.sas_sinx_x(b*qb/2) 110 siC = env.sas_sinx_x(c*qc/2) 111 siAt = env.sas_sinx_x(Ta*qa/2) 112 siBt = env.sas_sinx_x(Tb*qb/2) 113 siCt = env.sas_sinx_x(Tc*qc/2) 114 return (drV0*siA*siB*siC 115 + (drVTa*siAt-drVa*siA)*siB*siC 116 + siA*(drVTb*siBt-drVb*siB)*siC 117 + siA*siB*(drVTc*siCt-drVc*siC)) 118 Fq.__doc__ = "core-shell parallelepiped a=%g, b=%g c=%g"%(a, b, c) 119 volume = a*b*c + 2*da*Aa + 2*db*Ab + 2*dc*Ac 120 norm = 1/(volume*10000) 95 121 return norm, Fq 96 122 … … 184 210 NORM, KERNEL = make_parallelepiped(A, B, C) 185 211 NORM_MP, KERNEL_MP = make_parallelepiped(A, B, C, env=MPenv) 212 elif shape == 'core_shell_parallelepiped': 213 #A, B, C = 4450, 14000, 47 214 #A, B, C = 445, 140, 47 # integer for the sake of mpf 215 A, B, C = 6800, 114, 1380 216 DA, DB, DC = 2300, 21, 58 217 SLDA, SLDB, SLDC = "5", "-0.3", "11.5" 218 if 1: # C shortest 219 B, C = C, B 220 DB, DC = DC, DB 221 SLDB, SLDC = SLDC, SLDB 222 elif 0: # C longest 223 A, C = C, A 224 DA, DC = DC, DA 225 SLDA, SLDC = SLDC, SLDA 226 NORM, KERNEL = make_core_shell_parallelepiped(A, B, C, DA, DB, DC, SLDA, SLDB, SLDC) 227 NORM_MP, KERNEL_MP = make_core_shell_parallelepiped(A, B, C, DA, DB, DC, SLDA, SLDB, SLDC, env=MPenv) 186 228 elif shape == 'paracrystal': 187 229 LATTICE = 'bcc' … … 342 384 print("gauss-150", *gauss_quad_2d(Q, n=150)) 343 385 print("gauss-500", *gauss_quad_2d(Q, n=500)) 386 print("gauss-1025", *gauss_quad_2d(Q, n=1025)) 387 print("gauss-2049", *gauss_quad_2d(Q, n=2049)) 344 388 #gridded_2d(Q, n=2**8+1) 345 389 gridded_2d(Q, n=2**10+1) 346 #gridded_2d(Q, n=2**1 3+1)390 #gridded_2d(Q, n=2**12+1) 347 391 #gridded_2d(Q, n=2**15+1) 348 if shape != 'paracrystal': # adaptive forms are too slow! 392 if shape not in ('paracrystal', 'core_shell_parallelepiped'): 393 # adaptive forms on models for which the calculations are fast enough 349 394 print("dblquad", *scipy_dblquad_2d(Q)) 350 395 print("semi-romberg-100", *semi_romberg_2d(Q, n=100)) -
sasmodels/compare.py
r3bfd924 r376b0ee 788 788 data = empty_data2D(q, resolution=res) 789 789 data.accuracy = opts['accuracy'] 790 set_beam_stop(data, 0.0004)790 set_beam_stop(data, qmin) 791 791 index = ~data.mask 792 792 else: … … 1354 1354 if model_info != model_info2: 1355 1355 pars2 = randomize_pars(model_info2, pars2) 1356 limit_dimensions(model_info , pars2, maxdim)1356 limit_dimensions(model_info2, pars2, maxdim) 1357 1357 # Share values for parameters with the same name 1358 1358 for k, v in pars.items(): -
sasmodels/models/core_shell_parallelepiped.c
r904cd9c rfc0b7aa 1 // Set OVERLAPPING to 1 in order to fill in the edges of the box, with 2 // c endcaps and b overlapping a. With the proper choice of parameters, 3 // (setting rim slds to sld, core sld to solvent, rim thickness to thickness 4 // and subtracting 2*thickness from length, this should match the hollow 5 // rectangular prism.) Set it to 0 for the documented behaviour. 6 #define OVERLAPPING 0 1 7 static double 2 8 form_volume(double length_a, double length_b, double length_c, 3 9 double thick_rim_a, double thick_rim_b, double thick_rim_c) 4 10 { 5 //return length_a * length_b * length_c; 6 return length_a * length_b * length_c + 7 2.0 * thick_rim_a * length_b * length_c + 8 2.0 * thick_rim_b * length_a * length_c + 9 2.0 * thick_rim_c * length_a * length_b; 11 return 12 #if OVERLAPPING 13 // Hollow rectangular prism only includes the volume of the shell 14 // so uncomment the next line when comparing. Solid rectangular 15 // prism, or parallelepiped want filled cores, so comment when 16 // comparing. 17 //-length_a * length_b * length_c + 18 (length_a + 2.0*thick_rim_a) * 19 (length_b + 2.0*thick_rim_b) * 20 (length_c + 2.0*thick_rim_c); 21 #else 22 length_a * length_b * length_c + 23 2.0 * thick_rim_a * length_b * length_c + 24 2.0 * length_a * thick_rim_b * length_c + 25 2.0 * length_a * length_b * thick_rim_c; 26 #endif 10 27 } 11 28 … … 24 41 double thick_rim_c) 25 42 { 26 // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c _scaled43 // Code converted from functions CSPPKernel and CSParallelepiped in libCylinder.c 27 44 // Did not understand the code completely, it should be rechecked (Miguel Gonzalez) 28 45 //Code is rewritten,the code is compliant with Diva Singhs thesis now (Dirk Honecker) … … 30 47 const double mu = 0.5 * q * length_b; 31 48 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; 49 // Scale sides by B 50 const double a_over_b = length_a / length_b; 51 const double c_over_b = length_c / length_b; 38 52 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 53 double tA_over_b = a_over_b + 2.0*thick_rim_a/length_b; 54 double tB_over_b = 1+ 2.0*thick_rim_b/length_b; 55 double tC_over_b = c_over_b + 2.0*thick_rim_c/length_b; 46 56 47 57 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 58 #if OVERLAPPING 59 const double capA_area = length_b*length_c; 60 const double capB_area = (length_a+2.*thick_rim_a)*length_c; 61 const double capC_area = (length_a+2.*thick_rim_a)*(length_b+2.*thick_rim_b); 62 #else 63 const double capA_area = length_b*length_c; 64 const double capB_area = length_a*length_c; 65 const double capC_area = length_a*length_b; 66 #endif 67 const double Va = length_a * capA_area; 68 const double Vb = length_b * capB_area; 69 const double Vc = length_c * capC_area; 70 const double Vat = Va + 2.0 * thick_rim_a * capA_area; 71 const double Vbt = Vb + 2.0 * thick_rim_b * capB_area; 72 const double Vct = Vc + 2.0 * thick_rim_c * capC_area; 55 73 56 74 // 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 62 63 // 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; 75 const double dr0 = (core_sld-solvent_sld); 76 const double drA = (arim_sld-solvent_sld); 77 const double drB = (brim_sld-solvent_sld); 78 const double drC = (crim_sld-solvent_sld); 69 79 70 80 // outer integral (with gauss points), integration limits = 0, 1 71 double outer_total = 0; //initialize integral 72 81 double outer_sum = 0; //initialize integral 73 82 for( int i=0; i<76; i++) { 74 83 double sigma = 0.5 * ( Gauss76Z[i] + 1.0 ); 75 84 double mu_proj = mu * sqrt(1.0-sigma*sigma); 76 85 77 // inner integral (with gauss points), integration limits = 0, 1 78 double inner_total = 0.0; 79 double inner_total_crim = 0.0; 86 // inner integral (with gauss points), integration limits = 0, pi/2 87 const double siC = sas_sinx_x(mu * sigma * c_over_b); 88 const double siCt = sas_sinx_x(mu * sigma * tC_over_b); 89 double inner_sum = 0.0; 80 90 for(int j=0; j<76; j++) { 81 91 const double uu = 0.5 * ( Gauss76Z[j] + 1.0 ); 82 92 double sin_uu, cos_uu; 83 93 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);94 const double siA = sas_sinx_x(mu_proj * sin_uu * a_over_b); 95 const double siB = sas_sinx_x(mu_proj * cos_uu ); 96 const double siAt = sas_sinx_x(mu_proj * sin_uu * tA_over_b); 97 const double siBt = sas_sinx_x(mu_proj * cos_uu * tB_over_b); 88 98 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; 99 #if OVERLAPPING 100 const double f = dr0*Vin*siA*siB*siC 101 + drA*(Vat*siAt-Va*siA)*siB*siC 102 + drB*siAt*(Vbt*siBt-Vb*siB)*siC 103 + drC*siAt*siBt*(Vct*siCt-Vc*siC); 104 #else 105 const double f = dr0*Vin*siA*siB*siC 106 + drA*(Vat*siAt-Va*siA)*siB*siC 107 + drB*siA*(Vbt*siBt-Vb*siB)*siC 108 + drC*siA*siB*(Vct*siCt-Vc*siC); 109 #endif 92 110 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; 111 inner_sum += Gauss76Wt[j] * f * f; 96 112 } 97 inner_total *= 0.5; 98 inner_total_crim *= 0.5; 113 inner_sum *= 0.5; 99 114 // 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); 115 outer_sum += Gauss76Wt[i] * inner_sum; 103 116 } 104 outer_ total*= 0.5;117 outer_sum *= 0.5; 105 118 106 119 //convert from [1e-12 A-1] to [cm-1] 107 return 1.0e-4 * outer_ total;120 return 1.0e-4 * outer_sum; 108 121 } 109 122 … … 129 142 130 143 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); 144 #if OVERLAPPING 145 const double capA_area = length_b*length_c; 146 const double capB_area = (length_a+2.*thick_rim_a)*length_c; 147 const double capC_area = (length_a+2.*thick_rim_a)*(length_b+2.*thick_rim_b); 148 #else 149 const double capA_area = length_b*length_c; 150 const double capB_area = length_a*length_c; 151 const double capC_area = length_a*length_b; 152 #endif 153 const double Va = length_a * capA_area; 154 const double Vb = length_b * capB_area; 155 const double Vc = length_c * capC_area; 156 const double Vat = Va + 2.0 * thick_rim_a * capA_area; 157 const double Vbt = Vb + 2.0 * thick_rim_b * capB_area; 158 const double Vct = Vc + 2.0 * thick_rim_c * capC_area; 139 159 140 160 // The definitions of ta, tb, tc are not the same as in the 1D case because there is no 141 161 // the scaling by B. 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; 145 //handle arg=0 separately, as sin(t)/t -> 1 as t->0 146 double siA = sas_sinx_x(0.5*length_a*qa); 147 double siB = sas_sinx_x(0.5*length_b*qb); 148 double siC = sas_sinx_x(0.5*length_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); 162 const double tA = length_a + 2.0*thick_rim_a; 163 const double tB = length_b + 2.0*thick_rim_b; 164 const double tC = length_c + 2.0*thick_rim_c; 165 const double siA = sas_sinx_x(0.5*length_a*qa); 166 const double siB = sas_sinx_x(0.5*length_b*qb); 167 const double siC = sas_sinx_x(0.5*length_c*qc); 168 const double siAt = sas_sinx_x(0.5*tA*qa); 169 const double siBt = sas_sinx_x(0.5*tB*qb); 170 const double siCt = sas_sinx_x(0.5*tC*qc); 152 171 153 154 // f uses Vin, V1, V2, and V3 and it seems to have more sense than the value computed 155 // in the 1D code, but should be checked! 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); 172 #if OVERLAPPING 173 const double f = dr0*Vin*siA*siB*siC 174 + drA*(Vat*siAt-Va*siA)*siB*siC 175 + drB*siAt*(Vbt*siBt-Vb*siB)*siC 176 + drC*siAt*siBt*(Vct*siCt-Vc*siC); 177 #else 178 const double f = dr0*Vin*siA*siB*siC 179 + drA*(Vat*siAt-Va*siA)*siB*siC 180 + drB*siA*(Vbt*siBt-Vb*siB)*siC 181 + drC*siA*siB*(Vct*siCt-Vc*siC); 182 #endif 160 183 161 184 return 1.0e-4 * f * f; -
sasmodels/models/hollow_rectangular_prism.c
r1e7b0db0 r8de1477 1 1 double form_volume(double length_a, double b2a_ratio, double c2a_ratio, double thickness); 2 double Iq(double q, double sld, double solvent_sld, double length_a, 2 double Iq(double q, double sld, double solvent_sld, double length_a, 3 3 double b2a_ratio, double c2a_ratio, double thickness); 4 4 … … 37 37 const double v2a = 0.0; 38 38 const double v2b = M_PI_2; //phi integration limits 39 39 40 40 double outer_sum = 0.0; 41 41 for(int i=0; i<76; i++) { … … 84 84 return 1.0e-4 * delrho * delrho * form; 85 85 } 86 87 double Iqxy(double qa, double qb, double qc, 88 double sld, 89 double solvent_sld, 90 double length_a, 91 double b2a_ratio, 92 double c2a_ratio, 93 double thickness) 94 { 95 const double length_b = length_a * b2a_ratio; 96 const double length_c = length_a * c2a_ratio; 97 const double a_half = 0.5 * length_a; 98 const double b_half = 0.5 * length_b; 99 const double c_half = 0.5 * length_c; 100 const double vol_total = length_a * length_b * length_c; 101 const double vol_core = 8.0 * (a_half-thickness) * (b_half-thickness) * (c_half-thickness); 102 103 // Amplitude AP from eqn. (13) 104 105 const double termA1 = sas_sinx_x(qa * a_half); 106 const double termA2 = sas_sinx_x(qa * (a_half-thickness)); 107 108 const double termB1 = sas_sinx_x(qb * b_half); 109 const double termB2 = sas_sinx_x(qb * (b_half-thickness)); 110 111 const double termC1 = sas_sinx_x(qc * c_half); 112 const double termC2 = sas_sinx_x(qc * (c_half-thickness)); 113 114 const double AP1 = vol_total * termA1 * termB1 * termC1; 115 const double AP2 = vol_core * termA2 * termB2 * termC2; 116 117 // Multiply by contrast^2. Factor corresponding to volume^2 cancels with previous normalization. 118 const double delrho = sld - solvent_sld; 119 120 // Convert from [1e-12 A-1] to [cm-1] 121 return 1.0e-4 * square(delrho * (AP1-AP2)); 122 } -
sasmodels/models/hollow_rectangular_prism.py
r30b60d2 r393facf 5 5 This model provides the form factor, $P(q)$, for a hollow rectangular 6 6 parallelepiped with a wall of thickness $\Delta$. 7 It computes only the 1D scattering, not the 2D. 7 8 8 9 9 Definition … … 66 66 (which is unitless). 67 67 68 **The 2D scattering intensity is not computed by this model.** 68 For 2d data the orientation of the particle is required, described using 69 angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, for further details 70 of the calculation and angular dispersions see :ref:`orientation` . 71 The angle $\Psi$ is the rotational angle around the long *C* axis. For example, 72 $\Psi = 0$ when the *B* axis is parallel to the *x*-axis of the detector. 73 74 For 2d, constraints must be applied during fitting to ensure that the inequality 75 $A < B < C$ is not violated, and hence the correct definition of angles is preserved. The calculation will not report an error, 76 but the results may be not correct. 77 78 .. figure:: img/parallelepiped_angle_definition.png 79 80 Definition of the angles for oriented hollow rectangular prism. 81 Note that rotation $\theta$, initially in the $xz$ plane, is carried out first, then 82 rotation $\phi$ about the $z$ axis, finally rotation $\Psi$ is now around the axis of the prism. 83 The neutron or X-ray beam is along the $z$ axis. 84 85 .. figure:: img/parallelepiped_angle_projection.png 86 87 Examples of the angles for oriented hollow rectangular prisms against the 88 detector plane. 69 89 70 90 … … 113 133 ["thickness", "Ang", 1, [0, inf], "volume", 114 134 "Thickness of parallelepiped"], 135 ["theta", "degrees", 0, [-360, 360], "orientation", 136 "c axis to beam angle"], 137 ["phi", "degrees", 0, [-360, 360], "orientation", 138 "rotation about beam"], 139 ["psi", "degrees", 0, [-360, 360], "orientation", 140 "rotation about c axis"], 115 141 ] 116 142 … … 175 201 [{}, [0.2], [0.76687283098]], 176 202 ] 177 -
sasmodels/models/rectangular_prism.c
r1e7b0db0 r8de1477 1 1 double form_volume(double length_a, double b2a_ratio, double c2a_ratio); 2 double Iq(double q, double sld, double solvent_sld, double length_a, 2 double Iq(double q, double sld, double solvent_sld, double length_a, 3 3 double b2a_ratio, double c2a_ratio); 4 4 … … 26 26 const double v2a = 0.0; 27 27 const double v2b = M_PI_2; //phi integration limits 28 28 29 29 double outer_sum = 0.0; 30 30 for(int i=0; i<76; i++) { … … 53 53 double answer = 0.5*(v1b-v1a)*outer_sum; 54 54 55 // Normalize by Pi (Eqn. 16). 56 // The term (ABC)^2 does not appear because it was introduced before on 55 // Normalize by Pi (Eqn. 16). 56 // The term (ABC)^2 does not appear because it was introduced before on 57 57 // the definitions of termA, termB, termC. 58 // The factor 2 appears because the theta integral has been defined between 58 // The factor 2 appears because the theta integral has been defined between 59 59 // 0 and pi/2, instead of 0 to pi. 60 60 answer /= M_PI_2; //Form factor P(q) … … 64 64 answer *= square((sld-solvent_sld)*volume); 65 65 66 // Convert from [1e-12 A-1] to [cm-1] 66 // Convert from [1e-12 A-1] to [cm-1] 67 67 answer *= 1.0e-4; 68 68 69 69 return answer; 70 70 } 71 72 73 double Iqxy(double qa, double qb, double qc, 74 double sld, 75 double solvent_sld, 76 double length_a, 77 double b2a_ratio, 78 double c2a_ratio) 79 { 80 const double length_b = length_a * b2a_ratio; 81 const double length_c = length_a * c2a_ratio; 82 const double a_half = 0.5 * length_a; 83 const double b_half = 0.5 * length_b; 84 const double c_half = 0.5 * length_c; 85 const double volume = length_a * length_b * length_c; 86 87 // Amplitude AP from eqn. (13) 88 89 const double termA = sas_sinx_x(qa * a_half); 90 const double termB = sas_sinx_x(qb * b_half); 91 const double termC = sas_sinx_x(qc * c_half); 92 93 const double AP = termA * termB * termC; 94 95 // Multiply by contrast^2. Factor corresponding to volume^2 cancels with previous normalization. 96 const double delrho = sld - solvent_sld; 97 98 // Convert from [1e-12 A-1] to [cm-1] 99 return 1.0e-4 * square(volume * delrho * AP); 100 } -
sasmodels/models/rectangular_prism.py
r31df0c9 r393facf 12 12 the prism (e.g. setting $b/a = 1$ and $c/a = 1$ and applying polydispersity 13 13 to *a* will generate a distribution of cubes of different sizes). 14 Note also that, contrary to :ref:`parallelepiped`, it does not compute15 the 2D scattering.16 14 17 15 … … 26 24 that reference), with $\theta$ corresponding to $\alpha$ in that paper, 27 25 and not to the usual convention used for example in the 28 :ref:`parallelepiped` model. As the present model does not compute 29 the 2D scattering, this has no further consequences. 26 :ref:`parallelepiped` model. 30 27 31 28 In this model the scattering from a massive parallelepiped with an … … 65 62 units) *scale* represents the volume fraction (which is unitless). 66 63 67 **The 2D scattering intensity is not computed by this model.** 64 For 2d data the orientation of the particle is required, described using 65 angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, for further details 66 of the calculation and angular dispersions see :ref:`orientation` . 67 The angle $\Psi$ is the rotational angle around the long *C* axis. For example, 68 $\Psi = 0$ when the *B* axis is parallel to the *x*-axis of the detector. 69 70 For 2d, constraints must be applied during fitting to ensure that the inequality 71 $A < B < C$ is not violated, and hence the correct definition of angles is preserved. The calculation will not report an error, 72 but the results may be not correct. 73 74 .. figure:: img/parallelepiped_angle_definition.png 75 76 Definition of the angles for oriented core-shell parallelepipeds. 77 Note that rotation $\theta$, initially in the $xz$ plane, is carried out first, then 78 rotation $\phi$ about the $z$ axis, finally rotation $\Psi$ is now around the axis of the cylinder. 79 The neutron or X-ray beam is along the $z$ axis. 80 81 .. figure:: img/parallelepiped_angle_projection.png 82 83 Examples of the angles for oriented rectangular prisms against the 84 detector plane. 85 68 86 69 87 … … 108 126 ["c2a_ratio", "", 1, [0, inf], "volume", 109 127 "Ratio sides c/a"], 128 ["theta", "degrees", 0, [-360, 360], "orientation", 129 "c axis to beam angle"], 130 ["phi", "degrees", 0, [-360, 360], "orientation", 131 "rotation about beam"], 132 ["psi", "degrees", 0, [-360, 360], "orientation", 133 "rotation about c axis"], 110 134 ] 111 135
Note: See TracChangeset
for help on using the changeset viewer.