Changeset 1941ec6 in sasmodels for sasmodels/models
- Timestamp:
- Dec 18, 2017 1:52:27 PM (6 years ago)
- Children:
- 67cc0ff
- Parents:
- 8224d24 (diff), 93fbc34 (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. - git-author:
- Paul Kienzle <pkienzle@…> (12/18/17 13:51:43)
- git-committer:
- Paul Kienzle <pkienzle@…> (12/18/17 13:52:27)
- Location:
- sasmodels/models
- Files:
-
- 1 added
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/models/_spherepy.py
ref07e95 r108e70e 88 88 Iq.vectorized = True # Iq accepts an array of q values 89 89 90 def Iqxy(qx, qy, sld, sld_solvent, radius):91 return Iq(sqrt(qx ** 2 + qy ** 2), sld, sld_solvent, radius)92 Iqxy.vectorized = True # Iqxy accepts arrays of qx, qy values93 94 90 def sesans(z, sld, sld_solvent, radius): 95 91 """ -
sasmodels/models/barbell.c
rbecded3 r108e70e 23 23 const double qab_r = radius_bell*qab; // Q*R*sin(theta) 24 24 double total = 0.0; 25 for (int i = 0; i < 76; i++){26 const double t = G auss76Z[i]*zm + zb;25 for (int i = 0; i < GAUSS_N; i++){ 26 const double t = GAUSS_Z[i]*zm + zb; 27 27 const double radical = 1.0 - t*t; 28 28 const double bj = sas_2J1x_x(qab_r*sqrt(radical)); 29 29 const double Fq = cos(m*t + b) * radical * bj; 30 total += G auss76Wt[i] * Fq;30 total += GAUSS_W[i] * Fq; 31 31 } 32 32 // translate dx in [-1,1] to dx in [lower,upper] … … 73 73 const double zb = M_PI_4; 74 74 double total = 0.0; 75 for (int i = 0; i < 76; i++){76 const double alpha= G auss76Z[i]*zm + zb;75 for (int i = 0; i < GAUSS_N; i++){ 76 const double alpha= GAUSS_Z[i]*zm + zb; 77 77 double sin_alpha, cos_alpha; // slots to hold sincos function output 78 78 SINCOS(alpha, sin_alpha, cos_alpha); 79 79 const double Aq = _fq(q*sin_alpha, q*cos_alpha, h, radius_bell, radius, half_length); 80 total += G auss76Wt[i] * Aq * Aq * sin_alpha;80 total += GAUSS_W[i] * Aq * Aq * sin_alpha; 81 81 } 82 82 // translate dx in [-1,1] to dx in [lower,upper] … … 90 90 91 91 static double 92 Iq xy(double qab, double qc,92 Iqac(double qab, double qc, 93 93 double sld, double solvent_sld, 94 94 double radius_bell, double radius, double length) -
sasmodels/models/bcc_paracrystal.c
rea60e08 r108e70e 81 81 82 82 double outer_sum = 0.0; 83 for(int i=0; i< 150; i++) {83 for(int i=0; i<GAUSS_N; i++) { 84 84 double inner_sum = 0.0; 85 const double theta = G auss150Z[i]*theta_m + theta_b;85 const double theta = GAUSS_Z[i]*theta_m + theta_b; 86 86 double sin_theta, cos_theta; 87 87 SINCOS(theta, sin_theta, cos_theta); 88 88 const double qc = q*cos_theta; 89 89 const double qab = q*sin_theta; 90 for(int j=0;j< 150;j++) {91 const double phi = G auss150Z[j]*phi_m + phi_b;90 for(int j=0;j<GAUSS_N;j++) { 91 const double phi = GAUSS_Z[j]*phi_m + phi_b; 92 92 double sin_phi, cos_phi; 93 93 SINCOS(phi, sin_phi, cos_phi); … … 95 95 const double qb = qab*sin_phi; 96 96 const double form = bcc_Zq(qa, qb, qc, dnn, d_factor); 97 inner_sum += G auss150Wt[j] * form;97 inner_sum += GAUSS_W[j] * form; 98 98 } 99 99 inner_sum *= phi_m; // sum(f(x)dx) = sum(f(x)) dx 100 outer_sum += G auss150Wt[i] * inner_sum * sin_theta;100 outer_sum += GAUSS_W[i] * inner_sum * sin_theta; 101 101 } 102 102 outer_sum *= theta_m; … … 107 107 108 108 109 static double Iq xy(double qa, double qb, double qc,109 static double Iqabc(double qa, double qb, double qc, 110 110 double dnn, double d_factor, double radius, 111 111 double sld, double solvent_sld) -
sasmodels/models/capped_cylinder.c
rbecded3 r108e70e 30 30 const double qab_r = radius_cap*qab; // Q*R*sin(theta) 31 31 double total = 0.0; 32 for (int i=0; i< 76 ;i++) {33 const double t = G auss76Z[i]*zm + zb;32 for (int i=0; i<GAUSS_N; i++) { 33 const double t = GAUSS_Z[i]*zm + zb; 34 34 const double radical = 1.0 - t*t; 35 35 const double bj = sas_2J1x_x(qab_r*sqrt(radical)); 36 36 const double Fq = cos(m*t + b) * radical * bj; 37 total += G auss76Wt[i] * Fq;37 total += GAUSS_W[i] * Fq; 38 38 } 39 39 // translate dx in [-1,1] to dx in [lower,upper] … … 95 95 const double zb = M_PI_4; 96 96 double total = 0.0; 97 for (int i=0; i< 76;i++) {98 const double theta = G auss76Z[i]*zm + zb;97 for (int i=0; i<GAUSS_N ;i++) { 98 const double theta = GAUSS_Z[i]*zm + zb; 99 99 double sin_theta, cos_theta; // slots to hold sincos function output 100 100 SINCOS(theta, sin_theta, cos_theta); … … 103 103 const double Aq = _fq(qab, qc, h, radius_cap, radius, half_length); 104 104 // scale by sin_theta for spherical coord integration 105 total += G auss76Wt[i] * Aq * Aq * sin_theta;105 total += GAUSS_W[i] * Aq * Aq * sin_theta; 106 106 } 107 107 // translate dx in [-1,1] to dx in [lower,upper] … … 115 115 116 116 static double 117 Iq xy(double qab, double qc,117 Iqac(double qab, double qc, 118 118 double sld, double solvent_sld, double radius, 119 119 double radius_cap, double length) -
sasmodels/models/core_shell_bicelle.c
rbecded3 r108e70e 52 52 53 53 double total = 0.0; 54 for(int i=0;i< N_POINTS_76;i++) {55 double theta = (G auss76Z[i] + 1.0)*uplim;54 for(int i=0;i<GAUSS_N;i++) { 55 double theta = (GAUSS_Z[i] + 1.0)*uplim; 56 56 double sin_theta, cos_theta; // slots to hold sincos function output 57 57 SINCOS(theta, sin_theta, cos_theta); 58 58 double fq = bicelle_kernel(q*sin_theta, q*cos_theta, radius, thick_radius, thick_face, 59 59 halflength, sld_core, sld_face, sld_rim, sld_solvent); 60 total += G auss76Wt[i]*fq*fq*sin_theta;60 total += GAUSS_W[i]*fq*fq*sin_theta; 61 61 } 62 62 … … 67 67 68 68 static double 69 Iq xy(double qab, double qc,69 Iqac(double qab, double qc, 70 70 double radius, 71 71 double thick_rim, -
sasmodels/models/core_shell_bicelle_elliptical.c
r82592da r108e70e 37 37 //initialize integral 38 38 double outer_sum = 0.0; 39 for(int i=0;i< 76;i++) {39 for(int i=0;i<GAUSS_N;i++) { 40 40 //setup inner integral over the ellipsoidal cross-section 41 41 //const double va = 0.0; 42 42 //const double vb = 1.0; 43 //const double cos_theta = ( G auss76Z[i]*(vb-va) + va + vb )/2.0;44 const double cos_theta = ( G auss76Z[i] + 1.0 )/2.0;43 //const double cos_theta = ( GAUSS_Z[i]*(vb-va) + va + vb )/2.0; 44 const double cos_theta = ( GAUSS_Z[i] + 1.0 )/2.0; 45 45 const double sin_theta = sqrt(1.0 - cos_theta*cos_theta); 46 46 const double qab = q*sin_theta; … … 49 49 const double si2 = sas_sinx_x((halfheight+thick_face)*qc); 50 50 double inner_sum=0.0; 51 for(int j=0;j< 76;j++) {51 for(int j=0;j<GAUSS_N;j++) { 52 52 //76 gauss points for the inner integral (WAS 20 points,so this may make unecessarily slow, but playing safe) 53 53 // inner integral limits 54 54 //const double vaj=0.0; 55 55 //const double vbj=M_PI; 56 //const double phi = ( G auss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0;57 const double phi = ( G auss76Z[j] +1.0)*M_PI_2;56 //const double phi = ( GAUSS_Z[j]*(vbj-vaj) + vaj + vbj )/2.0; 57 const double phi = ( GAUSS_Z[j] +1.0)*M_PI_2; 58 58 const double rr = sqrt(r2A - r2B*cos(phi)); 59 59 const double be1 = sas_2J1x_x(rr*qab); … … 61 61 const double fq = dr1*si1*be1 + dr2*si2*be2 + dr3*si2*be1; 62 62 63 inner_sum += G auss76Wt[j] * fq * fq;63 inner_sum += GAUSS_W[j] * fq * fq; 64 64 } 65 65 //now calculate outer integral 66 outer_sum += G auss76Wt[i] * inner_sum;66 outer_sum += GAUSS_W[i] * inner_sum; 67 67 } 68 68 … … 71 71 72 72 static double 73 Iq xy(double qa, double qb, double qc,73 Iqabc(double qa, double qb, double qc, 74 74 double r_minor, 75 75 double x_core, -
sasmodels/models/core_shell_bicelle_elliptical_belt_rough.c
r82592da r108e70e 7 7 double length) 8 8 { 9 return M_PI*( (r_minor + thick_rim)*(r_minor*x_core + thick_rim)* length + 9 return M_PI*( (r_minor + thick_rim)*(r_minor*x_core + thick_rim)* length + 10 10 square(r_minor)*x_core*2.0*thick_face ); 11 11 } … … 47 47 //initialize integral 48 48 double outer_sum = 0.0; 49 for(int i=0;i< 76;i++) {49 for(int i=0;i<GAUSS_N;i++) { 50 50 //setup inner integral over the ellipsoidal cross-section 51 51 // since we generate these lots of times, why not store them somewhere? 52 //const double cos_alpha = ( G auss76Z[i]*(vb-va) + va + vb )/2.0;53 const double cos_alpha = ( G auss76Z[i] + 1.0 )/2.0;52 //const double cos_alpha = ( GAUSS_Z[i]*(vb-va) + va + vb )/2.0; 53 const double cos_alpha = ( GAUSS_Z[i] + 1.0 )/2.0; 54 54 const double sin_alpha = sqrt(1.0 - cos_alpha*cos_alpha); 55 55 double inner_sum=0; … … 58 58 si1 = sas_sinx_x(sinarg1); 59 59 si2 = sas_sinx_x(sinarg2); 60 for(int j=0;j< 76;j++) {60 for(int j=0;j<GAUSS_N;j++) { 61 61 //76 gauss points for the inner integral (WAS 20 points,so this may make unecessarily slow, but playing safe) 62 //const double beta = ( G auss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0;63 const double beta = ( G auss76Z[j] +1.0)*M_PI_2;62 //const double beta = ( GAUSS_Z[j]*(vbj-vaj) + vaj + vbj )/2.0; 63 const double beta = ( GAUSS_Z[j] +1.0)*M_PI_2; 64 64 const double rr = sqrt(r2A - r2B*cos(beta)); 65 65 double besarg1 = q*rr*sin_alpha; … … 67 67 be1 = sas_2J1x_x(besarg1); 68 68 be2 = sas_2J1x_x(besarg2); 69 inner_sum += G auss76Wt[j] *square(dr1*si1*be1 +69 inner_sum += GAUSS_W[j] *square(dr1*si1*be1 + 70 70 dr2*si1*be2 + 71 71 dr3*si2*be1); 72 72 } 73 73 //now calculate outer integral 74 outer_sum += G auss76Wt[i] * inner_sum;74 outer_sum += GAUSS_W[i] * inner_sum; 75 75 } 76 76 … … 79 79 80 80 static double 81 Iq xy(double qa, double qb, double qc,81 Iqabc(double qa, double qb, double qc, 82 82 double r_minor, 83 83 double x_core, … … 114 114 return 1.0e-4 * Aq*exp(-0.5*(square(qa) + square(qb) + square(qc) )*square(sigma)); 115 115 } 116 -
sasmodels/models/core_shell_bicelle_elliptical_belt_rough.py
r110f69c r108e70e 149 149 ["sld_rim", "1e-6/Ang^2", 1, [-inf, inf], "sld", "Cylinder rim scattering length density"], 150 150 ["sld_solvent", "1e-6/Ang^2", 6, [-inf, inf], "sld", "Solvent scattering length density"], 151 ["sigma", "Ang", 0, [0, inf], "", "interfacial roughness"], 151 152 ["theta", "degrees", 90.0, [-360, 360], "orientation", "cylinder axis to beam angle"], 152 153 ["phi", "degrees", 0, [-360, 360], "orientation", "rotation about beam"], 153 154 ["psi", "degrees", 0, [-360, 360], "orientation", "rotation about cylinder axis"], 154 ["sigma", "Ang", 0, [0, inf], "", "interfacial roughness"]155 155 ] 156 156 -
sasmodels/models/core_shell_cylinder.c
rbecded3 r108e70e 30 30 const double shell_vd = form_volume(radius,thickness,length) * (shell_sld-solvent_sld); 31 31 double total = 0.0; 32 for (int i=0; i< 76;i++) {32 for (int i=0; i<GAUSS_N ;i++) { 33 33 // translate a point in [-1,1] to a point in [0, pi/2] 34 //const double theta = ( G auss76Z[i]*(upper-lower) + upper + lower )/2.0;34 //const double theta = ( GAUSS_Z[i]*(upper-lower) + upper + lower )/2.0; 35 35 double sin_theta, cos_theta; 36 const double theta = G auss76Z[i]*M_PI_4 + M_PI_4;36 const double theta = GAUSS_Z[i]*M_PI_4 + M_PI_4; 37 37 SINCOS(theta, sin_theta, cos_theta); 38 38 const double qab = q*sin_theta; … … 40 40 const double fq = _cyl(core_vd, core_r*qab, core_h*qc) 41 41 + _cyl(shell_vd, shell_r*qab, shell_h*qc); 42 total += G auss76Wt[i] * fq * fq * sin_theta;42 total += GAUSS_W[i] * fq * fq * sin_theta; 43 43 } 44 44 // translate dx in [-1,1] to dx in [lower,upper] … … 48 48 49 49 50 double Iq xy(double qab, double qc,50 double Iqac(double qab, double qc, 51 51 double core_sld, 52 52 double shell_sld, -
sasmodels/models/core_shell_ellipsoid.c
rbecded3 r108e70e 59 59 const double b = 0.5; 60 60 double total = 0.0; //initialize intergral 61 for(int i=0;i< 76;i++) {62 const double cos_theta = G auss76Z[i]*m + b;61 for(int i=0;i<GAUSS_N;i++) { 62 const double cos_theta = GAUSS_Z[i]*m + b; 63 63 const double sin_theta = sqrt(1.0 - cos_theta*cos_theta); 64 64 double fq = _cs_ellipsoid_kernel(q*sin_theta, q*cos_theta, … … 66 66 equat_shell, polar_shell, 67 67 sld_core_shell, sld_shell_solvent); 68 total += G auss76Wt[i] * fq * fq;68 total += GAUSS_W[i] * fq * fq; 69 69 } 70 70 total *= m; … … 75 75 76 76 static double 77 Iq xy(double qab, double qc,77 Iqac(double qab, double qc, 78 78 double radius_equat_core, 79 79 double x_core, -
sasmodels/models/core_shell_parallelepiped.c
r904cd9c r108e70e 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 //Code is rewritten,the code is compliant with Diva Singhs thesis now (Dirk Honecker) 45 // Code is rewritten,the code is compliant with Diva Singhs thesis now (Dirk Honecker) 46 // Code rewritten (PAK) 29 47 30 const double mu = 0.5 * q * length_b;48 const double half_q = 0.5*q; 31 49 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; 50 const double tA = length_a + 2.0*thick_rim_a; 51 const double tB = length_b + 2.0*thick_rim_b; 52 const double tC = length_c + 2.0*thick_rim_c; 38 53 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 46 47 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 55 56 // 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; 54 // Scale factors 55 const double dr0 = (core_sld-solvent_sld); 56 const double drA = (arim_sld-solvent_sld); 57 const double drB = (brim_sld-solvent_sld); 58 const double drC = (crim_sld-solvent_sld); 69 59 70 60 // outer integral (with gauss points), integration limits = 0, 1 71 double outer_total = 0; //initialize integral 61 double outer_sum = 0; //initialize integral 62 for( int i=0; i<GAUSS_N; i++) { 63 const double cos_alpha = 0.5 * ( GAUSS_Z[i] + 1.0 ); 64 const double mu = half_q * sqrt(1.0-cos_alpha*cos_alpha); 72 65 73 for( int i=0; i<76; i++) { 74 double sigma = 0.5 * ( Gauss76Z[i] + 1.0 ); 75 double mu_proj = mu * sqrt(1.0-sigma*sigma); 66 // inner integral (with gauss points), integration limits = 0, pi/2 67 const double siC = length_c * sas_sinx_x(length_c * cos_alpha * half_q); 68 const double siCt = tC * sas_sinx_x(tC * cos_alpha * half_q); 69 double inner_sum = 0.0; 70 for(int j=0; j<GAUSS_N; j++) { 71 const double beta = 0.5 * ( GAUSS_Z[j] + 1.0 ); 72 double sin_beta, cos_beta; 73 SINCOS(M_PI_2*beta, sin_beta, cos_beta); 74 const double siA = length_a * sas_sinx_x(length_a * mu * sin_beta); 75 const double siB = length_b * sas_sinx_x(length_b * mu * cos_beta); 76 const double siAt = tA * sas_sinx_x(tA * mu * sin_beta); 77 const double siBt = tB * sas_sinx_x(tB * mu * cos_beta); 76 78 77 // inner integral (with gauss points), integration limits = 0, 1 78 double inner_total = 0.0;79 double inner_total_crim = 0.0;80 for(int j=0; j<76; j++) {81 const double uu = 0.5 * ( Gauss76Z[j] + 1.0);82 double sin_uu, cos_uu; 83 SINCOS(M_PI_2*uu, sin_uu, cos_uu);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); 79 #if OVERLAPPING 80 const double f = dr0*siA*siB*siC 81 + drA*(siAt-siA)*siB*siC 82 + drB*siAt*(siBt-siB)*siC 83 + drC*siAt*siBt*(siCt-siC); 84 #else 85 const double f = dr0*siA*siB*siC 86 + drA*(siAt-siA)*siB*siC 87 + drB*siA*(siBt-siB)*siC 88 + drC*siA*siB*(siCt-siC); 89 #endif 88 90 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; 92 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; 91 inner_sum += GAUSS_W[j] * f * f; 96 92 } 97 inner_total *= 0.5; 98 inner_total_crim *= 0.5; 93 inner_sum *= 0.5; 99 94 // 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); 95 outer_sum += GAUSS_W[i] * inner_sum; 103 96 } 104 outer_ total*= 0.5;97 outer_sum *= 0.5; 105 98 106 99 //convert from [1e-12 A-1] to [cm-1] 107 return 1.0e-4 * outer_ total;100 return 1.0e-4 * outer_sum; 108 101 } 109 102 110 103 static double 111 Iq xy(double qa, double qb, double qc,104 Iqabc(double qa, double qb, double qc, 112 105 double core_sld, 113 106 double arim_sld, … … 128 121 const double drC = crim_sld-solvent_sld; 129 122 130 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 used135 //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);139 140 123 // The definitions of ta, tb, tc are not the same as in the 1D case because there is no 141 124 // 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); 125 const double tA = length_a + 2.0*thick_rim_a; 126 const double tB = length_b + 2.0*thick_rim_b; 127 const double tC = length_c + 2.0*thick_rim_c; 128 const double siA = length_a*sas_sinx_x(0.5*length_a*qa); 129 const double siB = length_b*sas_sinx_x(0.5*length_b*qb); 130 const double siC = length_c*sas_sinx_x(0.5*length_c*qc); 131 const double siAt = tA*sas_sinx_x(0.5*tA*qa); 132 const double siBt = tB*sas_sinx_x(0.5*tB*qb); 133 const double siCt = tC*sas_sinx_x(0.5*tC*qc); 152 134 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); 135 #if OVERLAPPING 136 const double f = dr0*siA*siB*siC 137 + drA*(siAt-siA)*siB*siC 138 + drB*siAt*(siBt-siB)*siC 139 + drC*siAt*siBt*(siCt-siC); 140 #else 141 const double f = dr0*siA*siB*siC 142 + drA*(siAt-siA)*siB*siC 143 + drB*siA*(siBt-siB)*siC 144 + drC*siA*siB*(siCt-siC); 145 #endif 160 146 161 147 return 1.0e-4 * f * f; -
sasmodels/models/core_shell_parallelepiped.py
r2d81cfe r10ee838 5 5 Calculates the form factor for a rectangular solid with a core-shell structure. 6 6 The thickness and the scattering length density of the shell or 7 "rim" can be different on each (pair) of faces. However at this time the 1D 8 calculation does **NOT** actually calculate a c face rim despite the presence 9 of the parameter. Some other aspects of the 1D calculation may be wrong. 10 11 .. note:: 12 This model was originally ported from NIST IGOR macros. However, it is not 13 yet fully understood by the SasView developers and is currently under review. 7 "rim" can be different on each (pair) of faces. 14 8 15 9 The form factor is normalized by the particle volume $V$ such that … … 21 15 where $\langle \ldots \rangle$ is an average over all possible orientations 22 16 of the rectangular solid. 23 24 17 25 18 The function calculated is the form factor of the rectangular solid below. … … 41 34 V = ABC + 2t_ABC + 2t_BAC + 2t_CAB 42 35 43 **meaning that there are "gaps" at the corners of the solid.** Again note that 44 $t_C = 0$ currently. 36 **meaning that there are "gaps" at the corners of the solid.** 45 37 46 38 The intensity calculated follows the :ref:`parallelepiped` model, with the 47 39 core-shell intensity being calculated as the square of the sum of the 48 amplitudes of the core and shell, in the same manner as a core-shell model. 49 50 .. math:: 51 52 F_{a}(Q,\alpha,\beta)= 53 \left[\frac{\sin(\tfrac{1}{2}Q(L_A+2t_A)\sin\alpha \sin\beta) 54 }{\tfrac{1}{2}Q(L_A+2t_A)\sin\alpha\sin\beta} 55 - \frac{\sin(\tfrac{1}{2}QL_A\sin\alpha \sin\beta) 56 }{\tfrac{1}{2}QL_A\sin\alpha \sin\beta} \right] 57 \left[\frac{\sin(\tfrac{1}{2}QL_B\sin\alpha \sin\beta) 58 }{\tfrac{1}{2}QL_B\sin\alpha \sin\beta} \right] 59 \left[\frac{\sin(\tfrac{1}{2}QL_C\sin\alpha \sin\beta) 60 }{\tfrac{1}{2}QL_C\sin\alpha \sin\beta} \right] 61 62 .. note:: 63 64 Why does t_B not appear in the above equation? 65 For the calculation of the form factor to be valid, the sides of the solid 66 MUST (perhaps not any more?) be chosen such that** $A < B < C$. 67 If this inequality is not satisfied, the model will not report an error, 68 but the calculation will not be correct and thus the result wrong. 40 amplitudes of the core and the slabs on the edges. 41 42 the scattering amplitude is computed for a particular orientation of the 43 core-shell parallelepiped with respect to the scattering vector and then 44 averaged over all possible orientations, where $\alpha$ is the angle between 45 the $z$ axis and the $C$ axis of the parallelepiped, $\beta$ is 46 the angle between projection of the particle in the $xy$ detector plane 47 and the $y$ axis. 48 49 .. math:: 50 51 F(Q) 52 &= (\rho_\text{core}-\rho_\text{solvent}) 53 S(Q_A, A) S(Q_B, B) S(Q_C, C) \\ 54 &+ (\rho_\text{A}-\rho_\text{solvent}) 55 \left[S(Q_A, A+2t_A) - S(Q_A, Q)\right] S(Q_B, B) S(Q_C, C) \\ 56 &+ (\rho_\text{B}-\rho_\text{solvent}) 57 S(Q_A, A) \left[S(Q_B, B+2t_B) - S(Q_B, B)\right] S(Q_C, C) \\ 58 &+ (\rho_\text{C}-\rho_\text{solvent}) 59 S(Q_A, A) S(Q_B, B) \left[S(Q_C, C+2t_C) - S(Q_C, C)\right] 60 61 with 62 63 .. math:: 64 65 S(Q, L) = L \frac{\sin \tfrac{1}{2} Q L}{\tfrac{1}{2} Q L} 66 67 and 68 69 .. math:: 70 71 Q_A &= \sin\alpha \sin\beta \\ 72 Q_B &= \sin\alpha \cos\beta \\ 73 Q_C &= \cos\alpha 74 75 76 where $\rho_\text{core}$, $\rho_\text{A}$, $\rho_\text{B}$ and $\rho_\text{C}$ 77 are the scattering length of the parallelepiped core, and the rectangular 78 slabs of thickness $t_A$, $t_B$ and $t_C$, respectively. $\rho_\text{solvent}$ 79 is the scattering length of the solvent. 69 80 70 81 FITTING NOTES 82 ~~~~~~~~~~~~~ 83 71 84 If the scale is set equal to the particle volume fraction, $\phi$, the returned 72 value is the scattered intensity per unit volume, $I(q) = \phi P(q)$. 73 However, **no interparticle interference effects are included in this 74 calculation.** 85 value is the scattered intensity per unit volume, $I(q) = \phi P(q)$. However, 86 **no interparticle interference effects are included in this calculation.** 75 87 76 88 There are many parameters in this model. Hold as many fixed as possible with 77 89 known values, or you will certainly end up at a solution that is unphysical. 78 90 79 Constraints must be applied during fitting to ensure that the inequality80 $A < B < C$ is not violated. The calculation will not report an error,81 but the results will not be correct.82 83 91 The returned value is in units of |cm^-1|, on absolute scale. 84 92 85 93 NB: The 2nd virial coefficient of the core_shell_parallelepiped is calculated 86 94 based on the the averaged effective radius $(=\sqrt{(A+2t_A)(B+2t_B)/\pi})$ 87 and length $(C+2t_C)$ values, after appropriately 88 sorting the three dimensions to give an oblate or prolate particle, to give an 89 effective radius,for $S(Q)$ when $P(Q) * S(Q)$ is applied.95 and length $(C+2t_C)$ values, after appropriately sorting the three dimensions 96 to give an oblate or prolate particle, to give an effective radius, 97 for $S(Q)$ when $P(Q) * S(Q)$ is applied. 90 98 91 99 For 2d data the orientation of the particle is required, described using 92 angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, for further details93 of the calculation and angular dispersions see :ref:`orientation`.100 angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, for further 101 details of the calculation and angular dispersions see :ref:`orientation`. 94 102 The angle $\Psi$ is the rotational angle around the *long_c* axis. For example, 95 103 $\Psi = 0$ when the *short_b* axis is parallel to the *x*-axis of the detector. 104 105 For 2d, constraints must be applied during fitting to ensure that the 106 inequality $A < B < C$ is not violated, and hence the correct definition 107 of angles is preserved. The calculation will not report an error, 108 but the results may be not correct. 96 109 97 110 .. figure:: img/parallelepiped_angle_definition.png … … 114 127 Equations (1), (13-14). (in German) 115 128 .. [#] D Singh (2009). *Small angle scattering studies of self assembly in 116 lipid mixtures*, John 's Hopkins University Thesis (2009) 223-225. `Available129 lipid mixtures*, Johns Hopkins University Thesis (2009) 223-225. `Available 117 130 from Proquest <http://search.proquest.com/docview/304915826?accountid 118 131 =26379>`_ … … 175 188 Return equivalent radius (ER) 176 189 """ 177 178 # surface average radius (rough approximation) 179 surf_rad = sqrt((length_a + 2.0*thick_rim_a) * (length_b + 2.0*thick_rim_b) / pi) 180 181 height = length_c + 2.0*thick_rim_c 182 183 ddd = 0.75 * surf_rad * (2 * surf_rad * height + (height + surf_rad) * (height + pi * surf_rad)) 184 return 0.5 * (ddd) ** (1. / 3.) 190 from .parallelepiped import ER as ER_p 191 192 a = length_a + 2*thick_rim_a 193 b = length_b + 2*thick_rim_b 194 c = length_c + 2*thick_rim_c 195 return ER_p(a, b, c) 185 196 186 197 # VR defaults to 1.0 … … 216 227 psi_pd=10, psi_pd_n=1) 217 228 218 # rkh 7/4/17 add random unit test for 2d, note make all params different, 2d values not tested against other codes or models 229 # rkh 7/4/17 add random unit test for 2d, note make all params different, 230 # 2d values not tested against other codes or models 219 231 if 0: # pak: model rewrite; need to update tests 220 232 qx, qy = 0.2 * cos(pi/6.), 0.2 * sin(pi/6.) -
sasmodels/models/cylinder.c
rbecded3 r108e70e 21 21 22 22 double total = 0.0; 23 for (int i=0; i< 76;i++) {24 const double theta = G auss76Z[i]*zm + zb;23 for (int i=0; i<GAUSS_N ;i++) { 24 const double theta = GAUSS_Z[i]*zm + zb; 25 25 double sin_theta, cos_theta; // slots to hold sincos function output 26 26 // theta (theta,phi) the projection of the cylinder on the detector plane 27 27 SINCOS(theta , sin_theta, cos_theta); 28 28 const double form = fq(q*sin_theta, q*cos_theta, radius, length); 29 total += G auss76Wt[i] * form * form * sin_theta;29 total += GAUSS_W[i] * form * form * sin_theta; 30 30 } 31 31 // translate dx in [-1,1] to dx in [lower,upper] … … 45 45 46 46 static double 47 Iq xy(double qab, double qc,47 Iqac(double qab, double qc, 48 48 double sld, 49 49 double solvent_sld, -
sasmodels/models/ellipsoid.c
rbecded3 r108e70e 22 22 23 23 // translate a point in [-1,1] to a point in [0, 1] 24 // const double u = G auss76Z[i]*(upper-lower)/2 + (upper+lower)/2;24 // const double u = GAUSS_Z[i]*(upper-lower)/2 + (upper+lower)/2; 25 25 const double zm = 0.5; 26 26 const double zb = 0.5; 27 27 double total = 0.0; 28 for (int i=0;i< 76;i++) {29 const double u = G auss76Z[i]*zm + zb;28 for (int i=0;i<GAUSS_N;i++) { 29 const double u = GAUSS_Z[i]*zm + zb; 30 30 const double r = radius_equatorial*sqrt(1.0 + u*u*v_square_minus_one); 31 31 const double f = sas_3j1x_x(q*r); 32 total += G auss76Wt[i] * f * f;32 total += GAUSS_W[i] * f * f; 33 33 } 34 34 // translate dx in [-1,1] to dx in [lower,upper] … … 39 39 40 40 static double 41 Iq xy(double qab, double qc,41 Iqac(double qab, double qc, 42 42 double sld, 43 43 double sld_solvent, -
sasmodels/models/elliptical_cylinder.c
r82592da r108e70e 22 22 //initialize integral 23 23 double outer_sum = 0.0; 24 for(int i=0;i< 76;i++) {24 for(int i=0;i<GAUSS_N;i++) { 25 25 //setup inner integral over the ellipsoidal cross-section 26 const double cos_val = ( G auss76Z[i]*(vb-va) + va + vb )/2.0;26 const double cos_val = ( GAUSS_Z[i]*(vb-va) + va + vb )/2.0; 27 27 const double sin_val = sqrt(1.0 - cos_val*cos_val); 28 28 //const double arg = radius_minor*sin_val; 29 29 double inner_sum=0; 30 for(int j=0;j<76;j++) { 31 //20 gauss points for the inner integral, increase to 76, RKH 6Nov2017 32 const double theta = ( Gauss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0; 30 for(int j=0;j<GAUSS_N;j++) { 31 const double theta = ( GAUSS_Z[j]*(vbj-vaj) + vaj + vbj )/2.0; 33 32 const double r = sin_val*sqrt(rA - rB*cos(theta)); 34 33 const double be = sas_2J1x_x(q*r); 35 inner_sum += G auss76Wt[j] * be * be;34 inner_sum += GAUSS_W[j] * be * be; 36 35 } 37 36 //now calculate the value of the inner integral … … 40 39 //now calculate outer integral 41 40 const double si = sas_sinx_x(q*0.5*length*cos_val); 42 outer_sum += G auss76Wt[i] * inner_sum * si * si;41 outer_sum += GAUSS_W[i] * inner_sum * si * si; 43 42 } 44 43 outer_sum *= 0.5*(vb-va); … … 55 54 56 55 static double 57 Iq xy(double qa, double qb, double qc,56 Iqabc(double qa, double qb, double qc, 58 57 double radius_minor, double r_ratio, double length, 59 58 double sld, double solvent_sld) -
sasmodels/models/elliptical_cylinder.py
r2d81cfe ra261a83 121 121 # pylint: enable=bad-whitespace, line-too-long 122 122 123 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "lib/gauss20.c", 124 "elliptical_cylinder.c"] 123 source = ["lib/polevl.c", "lib/sas_J1.c", "lib/gauss76.c", "elliptical_cylinder.c"] 125 124 126 125 demo = dict(scale=1, background=0, radius_minor=100, axis_ratio=1.5, length=400.0, -
sasmodels/models/fcc_paracrystal.c
rf728001 r108e70e 53 53 54 54 double outer_sum = 0.0; 55 for(int i=0; i< 150; i++) {55 for(int i=0; i<GAUSS_N; i++) { 56 56 double inner_sum = 0.0; 57 const double theta = G auss150Z[i]*theta_m + theta_b;57 const double theta = GAUSS_Z[i]*theta_m + theta_b; 58 58 double sin_theta, cos_theta; 59 59 SINCOS(theta, sin_theta, cos_theta); 60 60 const double qc = q*cos_theta; 61 61 const double qab = q*sin_theta; 62 for(int j=0;j< 150;j++) {63 const double phi = G auss150Z[j]*phi_m + phi_b;62 for(int j=0;j<GAUSS_N;j++) { 63 const double phi = GAUSS_Z[j]*phi_m + phi_b; 64 64 double sin_phi, cos_phi; 65 65 SINCOS(phi, sin_phi, cos_phi); … … 67 67 const double qb = qab*sin_phi; 68 68 const double form = fcc_Zq(qa, qb, qc, dnn, d_factor); 69 inner_sum += G auss150Wt[j] * form;69 inner_sum += GAUSS_W[j] * form; 70 70 } 71 71 inner_sum *= phi_m; // sum(f(x)dx) = sum(f(x)) dx 72 outer_sum += G auss150Wt[i] * inner_sum * sin_theta;72 outer_sum += GAUSS_W[i] * inner_sum * sin_theta; 73 73 } 74 74 outer_sum *= theta_m; … … 80 80 81 81 82 static double Iq xy(double qa, double qb, double qc,82 static double Iqabc(double qa, double qb, double qc, 83 83 double dnn, double d_factor, double radius, 84 84 double sld, double solvent_sld) -
sasmodels/models/flexible_cylinder_elliptical.c
r592343f r74768cb 17 17 double sum=0.0; 18 18 19 for(int i=0;i< N_POINTS_76;i++) {20 const double zi = ( G auss76Z[i] + 1.0 )*M_PI_4;19 for(int i=0;i<GAUSS_N;i++) { 20 const double zi = ( GAUSS_Z[i] + 1.0 )*M_PI_4; 21 21 double sn, cn; 22 22 SINCOS(zi, sn, cn); 23 23 const double arg = q*sqrt(a*a*sn*sn + b*b*cn*cn); 24 24 const double yyy = sas_2J1x_x(arg); 25 sum += G auss76Wt[i] * yyy * yyy;25 sum += GAUSS_W[i] * yyy * yyy; 26 26 } 27 27 sum *= 0.5; -
sasmodels/models/hollow_cylinder.c
rbecded3 r108e70e 38 38 39 39 double summ = 0.0; //initialize intergral 40 for (int i=0;i< 76;i++) {41 const double cos_theta = 0.5*( G auss76Z[i] * (upper-lower) + lower + upper );40 for (int i=0;i<GAUSS_N;i++) { 41 const double cos_theta = 0.5*( GAUSS_Z[i] * (upper-lower) + lower + upper ); 42 42 const double sin_theta = sqrt(1.0 - cos_theta*cos_theta); 43 43 const double form = _fq(q*sin_theta, q*cos_theta, 44 44 radius, thickness, length); 45 summ += G auss76Wt[i] * form * form;45 summ += GAUSS_W[i] * form * form; 46 46 } 47 47 … … 52 52 53 53 static double 54 Iq xy(double qab, double qc,54 Iqac(double qab, double qc, 55 55 double radius, double thickness, double length, 56 56 double sld, double solvent_sld) -
sasmodels/models/hollow_rectangular_prism.c
r1e7b0db0 r108e70e 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 for(int i=0; i< 76; i++) {41 for(int i=0; i<GAUSS_N; i++) { 42 42 43 const double theta = 0.5 * ( G auss76Z[i]*(v1b-v1a) + v1a + v1b );43 const double theta = 0.5 * ( GAUSS_Z[i]*(v1b-v1a) + v1a + v1b ); 44 44 double sin_theta, cos_theta; 45 45 SINCOS(theta, sin_theta, cos_theta); … … 49 49 50 50 double inner_sum = 0.0; 51 for(int j=0; j< 76; j++) {51 for(int j=0; j<GAUSS_N; j++) { 52 52 53 const double phi = 0.5 * ( G auss76Z[j]*(v2b-v2a) + v2a + v2b );53 const double phi = 0.5 * ( GAUSS_Z[j]*(v2b-v2a) + v2a + v2b ); 54 54 double sin_phi, cos_phi; 55 55 SINCOS(phi, sin_phi, cos_phi); … … 66 66 const double AP2 = vol_core * termA2 * termB2 * termC2; 67 67 68 inner_sum += G auss76Wt[j] * square(AP1-AP2);68 inner_sum += GAUSS_W[j] * square(AP1-AP2); 69 69 } 70 70 inner_sum *= 0.5 * (v2b-v2a); 71 71 72 outer_sum += G auss76Wt[i] * inner_sum * sin(theta);72 outer_sum += GAUSS_W[i] * inner_sum * sin(theta); 73 73 } 74 74 outer_sum *= 0.5*(v1b-v1a); … … 84 84 return 1.0e-4 * delrho * delrho * form; 85 85 } 86 87 double Iqabc(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
r2d81cfe r0e55afe 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 -
sasmodels/models/hollow_rectangular_prism_thin_walls.c
rab2aea8 r74768cb 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 … … 29 29 const double v2a = 0.0; 30 30 const double v2b = M_PI_2; //phi integration limits 31 31 32 32 double outer_sum = 0.0; 33 for(int i=0; i< 76; i++) {34 const double theta = 0.5 * ( G auss76Z[i]*(v1b-v1a) + v1a + v1b );33 for(int i=0; i<GAUSS_N; i++) { 34 const double theta = 0.5 * ( GAUSS_Z[i]*(v1b-v1a) + v1a + v1b ); 35 35 36 36 double sin_theta, cos_theta; … … 44 44 45 45 double inner_sum = 0.0; 46 for(int j=0; j< 76; j++) {47 const double phi = 0.5 * ( G auss76Z[j]*(v2b-v2a) + v2a + v2b );46 for(int j=0; j<GAUSS_N; j++) { 47 const double phi = 0.5 * ( GAUSS_Z[j]*(v2b-v2a) + v2a + v2b ); 48 48 49 49 double sin_phi, cos_phi; … … 62 62 * ( cos_a*sin_b/cos_phi + cos_b*sin_a/sin_phi ); 63 63 64 inner_sum += G auss76Wt[j] * square(AL+AT);64 inner_sum += GAUSS_W[j] * square(AL+AT); 65 65 } 66 66 67 67 inner_sum *= 0.5 * (v2b-v2a); 68 outer_sum += G auss76Wt[i] * inner_sum * sin_theta;68 outer_sum += GAUSS_W[i] * inner_sum * sin_theta; 69 69 } 70 70 -
sasmodels/models/lib/gauss150.c
r994d77f r74768cb 7 7 * 8 8 */ 9 #ifdef GAUSS_N 10 # undef GAUSS_N 11 # undef GAUSS_Z 12 # undef GAUSS_W 13 #endif 14 #define GAUSS_N 150 15 #define GAUSS_Z Gauss150Z 16 #define GAUSS_W Gauss150Wt 17 18 // Note: using array size 152 so that it is a multiple of 4 9 19 10 20 // Gaussians 11 constant double Gauss150Z[15 0]={21 constant double Gauss150Z[152]={ 12 22 -0.9998723404457334, 13 23 -0.9993274305065947, … … 159 169 0.9983473449340834, 160 170 0.9993274305065947, 161 0.9998723404457334 171 0.9998723404457334, 172 0., 173 0. 162 174 }; 163 175 164 constant double Gauss150Wt[15 0]={176 constant double Gauss150Wt[152]={ 165 177 0.0003276086705538, 166 178 0.0007624720924706, … … 312 324 0.0011976474864367, 313 325 0.0007624720924706, 314 0.0003276086705538 326 0.0003276086705538, 327 0., 328 0. 315 329 }; -
sasmodels/models/lib/gauss20.c
r994d77f r74768cb 7 7 * 8 8 */ 9 #ifdef GAUSS_N 10 # undef GAUSS_N 11 # undef GAUSS_Z 12 # undef GAUSS_W 13 #endif 14 #define GAUSS_N 20 15 #define GAUSS_Z Gauss20Z 16 #define GAUSS_W Gauss20Wt 9 17 10 18 // Gaussians -
sasmodels/models/lib/gauss76.c
r66d119f r74768cb 7 7 * 8 8 */ 9 #define N_POINTS_76 76 9 #ifdef GAUSS_N 10 # undef GAUSS_N 11 # undef GAUSS_Z 12 # undef GAUSS_W 13 #endif 14 #define GAUSS_N 76 15 #define GAUSS_Z Gauss76Z 16 #define GAUSS_W Gauss76Wt 10 17 11 18 // Gaussians 12 constant double Gauss76Wt[ N_POINTS_76]={19 constant double Gauss76Wt[76]={ 13 20 .00126779163408536, //0 14 21 .00294910295364247, … … 89 96 }; 90 97 91 constant double Gauss76Z[ N_POINTS_76]={98 constant double Gauss76Z[76]={ 92 99 -.999505948362153, //0 93 100 -.997397786355355, -
sasmodels/models/line.py
r2d81cfe r108e70e 57 57 Iq.vectorized = True # Iq accepts an array of q values 58 58 59 59 60 def Iqxy(qx, qy, *args): 60 61 """ … … 69 70 70 71 Iqxy.vectorized = True # Iqxy accepts an array of qx qy values 72 73 # uncomment the following to test Iqxy in C models 74 #del Iq, Iqxy 75 #c_code = """ 76 #static double Iq(double q, double b, double m) { return m*q+b; } 77 #static double Iqxy(double qx, double qy, double b, double m) 78 #{ return (m*qx+b)*(m*qy+b); } 79 #""" 71 80 72 81 def random(): -
sasmodels/models/parallelepiped.c
r9b7b23f r108e70e 23 23 double outer_total = 0; //initialize integral 24 24 25 for( int i=0; i< 76; i++) {26 const double sigma = 0.5 * ( G auss76Z[i] + 1.0 );25 for( int i=0; i<GAUSS_N; i++) { 26 const double sigma = 0.5 * ( GAUSS_Z[i] + 1.0 ); 27 27 const double mu_proj = mu * sqrt(1.0-sigma*sigma); 28 28 … … 30 30 // corresponding to angles from 0 to pi/2. 31 31 double inner_total = 0.0; 32 for(int j=0; j< 76; j++) {33 const double uu = 0.5 * ( G auss76Z[j] + 1.0 );32 for(int j=0; j<GAUSS_N; j++) { 33 const double uu = 0.5 * ( GAUSS_Z[j] + 1.0 ); 34 34 double sin_uu, cos_uu; 35 35 SINCOS(M_PI_2*uu, sin_uu, cos_uu); 36 36 const double si1 = sas_sinx_x(mu_proj * sin_uu * a_scaled); 37 37 const double si2 = sas_sinx_x(mu_proj * cos_uu); 38 inner_total += G auss76Wt[j] * square(si1 * si2);38 inner_total += GAUSS_W[j] * square(si1 * si2); 39 39 } 40 40 inner_total *= 0.5; 41 41 42 42 const double si = sas_sinx_x(mu * c_scaled * sigma); 43 outer_total += G auss76Wt[i] * inner_total * si * si;43 outer_total += GAUSS_W[i] * inner_total * si * si; 44 44 } 45 45 outer_total *= 0.5; … … 53 53 54 54 static double 55 Iq xy(double qa, double qb, double qc,55 Iqabc(double qa, double qb, double qc, 56 56 double sld, 57 57 double solvent_sld, -
sasmodels/models/pringle.c
r1e7b0db0 r74768cb 29 29 double sumC = 0.0; // initialize integral 30 30 double r; 31 for (int i=0; i < 76; i++) {32 r = G auss76Z[i]*zm + zb;31 for (int i=0; i < GAUSS_N; i++) { 32 r = GAUSS_Z[i]*zm + zb; 33 33 34 34 const double qrs = r*q_sin_psi; 35 35 const double qrrc = r*r*q_cos_psi; 36 36 37 double y = G auss76Wt[i] * r * sas_JN(n, beta*qrrc) * sas_JN(2*n, qrs);37 double y = GAUSS_W[i] * r * sas_JN(n, beta*qrrc) * sas_JN(2*n, qrs); 38 38 double S, C; 39 39 SINCOS(alpha*qrrc, S, C); … … 86 86 87 87 double sum = 0.0; 88 for (int i = 0; i < 76; i++) {89 double psi = G auss76Z[i]*zm + zb;88 for (int i = 0; i < GAUSS_N; i++) { 89 double psi = GAUSS_Z[i]*zm + zb; 90 90 double sin_psi, cos_psi; 91 91 SINCOS(psi, sin_psi, cos_psi); … … 93 93 double sinc_term = square(sas_sinx_x(q * thickness * cos_psi / 2.0)); 94 94 double pringle_kernel = 4.0 * sin_psi * bessel_term * sinc_term; 95 sum += G auss76Wt[i] * pringle_kernel;95 sum += GAUSS_W[i] * pringle_kernel; 96 96 } 97 97 -
sasmodels/models/rectangular_prism.c
r1e7b0db0 r108e70e 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 for(int i=0; i< 76; i++) {31 const double theta = 0.5 * ( G auss76Z[i]*(v1b-v1a) + v1a + v1b );30 for(int i=0; i<GAUSS_N; i++) { 31 const double theta = 0.5 * ( GAUSS_Z[i]*(v1b-v1a) + v1a + v1b ); 32 32 double sin_theta, cos_theta; 33 33 SINCOS(theta, sin_theta, cos_theta); … … 36 36 37 37 double inner_sum = 0.0; 38 for(int j=0; j< 76; j++) {39 double phi = 0.5 * ( G auss76Z[j]*(v2b-v2a) + v2a + v2b );38 for(int j=0; j<GAUSS_N; j++) { 39 double phi = 0.5 * ( GAUSS_Z[j]*(v2b-v2a) + v2a + v2b ); 40 40 double sin_phi, cos_phi; 41 41 SINCOS(phi, sin_phi, cos_phi); … … 45 45 const double termB = sas_sinx_x(q * b_half * sin_theta * cos_phi); 46 46 const double AP = termA * termB * termC; 47 inner_sum += G auss76Wt[j] * AP * AP;47 inner_sum += GAUSS_W[j] * AP * AP; 48 48 } 49 49 inner_sum = 0.5 * (v2b-v2a) * inner_sum; 50 outer_sum += G auss76Wt[i] * inner_sum * sin_theta;50 outer_sum += GAUSS_W[i] * inner_sum * sin_theta; 51 51 } 52 52 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 Iqabc(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
r2d81cfe r0e55afe 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 -
sasmodels/models/sc_paracrystal.c
rf728001 r108e70e 54 54 55 55 double outer_sum = 0.0; 56 for(int i=0; i< 150; i++) {56 for(int i=0; i<GAUSS_N; i++) { 57 57 double inner_sum = 0.0; 58 const double theta = G auss150Z[i]*theta_m + theta_b;58 const double theta = GAUSS_Z[i]*theta_m + theta_b; 59 59 double sin_theta, cos_theta; 60 60 SINCOS(theta, sin_theta, cos_theta); 61 61 const double qc = q*cos_theta; 62 62 const double qab = q*sin_theta; 63 for(int j=0;j< 150;j++) {64 const double phi = G auss150Z[j]*phi_m + phi_b;63 for(int j=0;j<GAUSS_N;j++) { 64 const double phi = GAUSS_Z[j]*phi_m + phi_b; 65 65 double sin_phi, cos_phi; 66 66 SINCOS(phi, sin_phi, cos_phi); … … 68 68 const double qb = qab*sin_phi; 69 69 const double form = sc_Zq(qa, qb, qc, dnn, d_factor); 70 inner_sum += G auss150Wt[j] * form;70 inner_sum += GAUSS_W[j] * form; 71 71 } 72 72 inner_sum *= phi_m; // sum(f(x)dx) = sum(f(x)) dx 73 outer_sum += G auss150Wt[i] * inner_sum * sin_theta;73 outer_sum += GAUSS_W[i] * inner_sum * sin_theta; 74 74 } 75 75 outer_sum *= theta_m; … … 82 82 83 83 static double 84 Iq xy(double qa, double qb, double qc,84 Iqabc(double qa, double qb, double qc, 85 85 double dnn, double d_factor, double radius, 86 86 double sld, double solvent_sld) -
sasmodels/models/stacked_disks.c
rbecded3 r108e70e 81 81 double halfheight = 0.5*thick_core; 82 82 83 for(int i=0; i< N_POINTS_76; i++) {84 double zi = (G auss76Z[i] + 1.0)*M_PI_4;83 for(int i=0; i<GAUSS_N; i++) { 84 double zi = (GAUSS_Z[i] + 1.0)*M_PI_4; 85 85 double sin_alpha, cos_alpha; // slots to hold sincos function output 86 86 SINCOS(zi, sin_alpha, cos_alpha); … … 95 95 solvent_sld, 96 96 d); 97 summ += G auss76Wt[i] * yyy * sin_alpha;97 summ += GAUSS_W[i] * yyy * sin_alpha; 98 98 } 99 99 … … 142 142 143 143 static double 144 Iq xy(double qab, double qc,144 Iqac(double qab, double qc, 145 145 double thick_core, 146 146 double thick_layer, -
sasmodels/models/triaxial_ellipsoid.c
rbecded3 r108e70e 21 21 const double zb = M_PI_4; 22 22 double outer = 0.0; 23 for (int i=0;i< 76;i++) {24 //const double u = G auss76Z[i]*(upper-lower)/2 + (upper + lower)/2;25 const double phi = G auss76Z[i]*zm + zb;23 for (int i=0;i<GAUSS_N;i++) { 24 //const double u = GAUSS_Z[i]*(upper-lower)/2 + (upper + lower)/2; 25 const double phi = GAUSS_Z[i]*zm + zb; 26 26 const double pa_sinsq_phi = pa*square(sin(phi)); 27 27 … … 29 29 const double um = 0.5; 30 30 const double ub = 0.5; 31 for (int j=0;j< 76;j++) {31 for (int j=0;j<GAUSS_N;j++) { 32 32 // translate a point in [-1,1] to a point in [0, 1] 33 const double usq = square(G auss76Z[j]*um + ub);33 const double usq = square(GAUSS_Z[j]*um + ub); 34 34 const double r = radius_equat_major*sqrt(pa_sinsq_phi*(1.0-usq) + 1.0 + pc*usq); 35 35 const double fq = sas_3j1x_x(q*r); 36 inner += G auss76Wt[j] * fq * fq;36 inner += GAUSS_W[j] * fq * fq; 37 37 } 38 outer += G auss76Wt[i] * inner; // correcting for dx later38 outer += GAUSS_W[i] * inner; // correcting for dx later 39 39 } 40 40 // translate integration ranges from [-1,1] to [lower,upper] and normalize by 4 pi … … 46 46 47 47 static double 48 Iq xy(double qa, double qb, double qc,48 Iqabc(double qa, double qb, double qc, 49 49 double sld, 50 50 double sld_solvent,
Note: See TracChangeset
for help on using the changeset viewer.