Changeset 2126131 in sasmodels
- Timestamp:
- Oct 17, 2016 1:38:58 PM (8 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- f719764
- Parents:
- 9762341
- Location:
- sasmodels/models
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/models/pearl_necklace.c
r3a48772 r2126131 1 double _pearl_necklace_kernel(double q, double radius, double edge_sep,2 double thick_string, double num_pearls, double sld_pearl,3 double sld_string, double sld_solv);4 1 double form_volume(double radius, double edge_sep, 5 double thick_string, double num_pearls); 6 2 double thick_string, double num_pearls); 7 3 double Iq(double q, double radius, double edge_sep, 8 9 4 double thick_string, double num_pearls, double sld, 5 double string_sld, double solvent_sld); 10 6 11 7 #define INVALID(v) (v.thick_string >= v.radius || v.num_pearls <= 0) 12 8 13 9 // From Igor library 14 double _pearl_necklace_kernel(double q, double radius, double edge_sep, double thick_string, 15 double num_pearls, double sld_pearl, double sld_string, double sld_solv) 10 static double 11 _pearl_necklace_kernel(double q, double radius, double edge_sep, double thick_string, 12 double num_pearls, double sld_pearl, double sld_string, double sld_solv) 16 13 { 17 //relative slds 18 double contrast_pearl = sld_pearl - sld_solv; 19 double contrast_string = sld_string - sld_solv; 20 21 // number of string segments 22 num_pearls = floor(num_pearls + 0.5); //Force integer number of pearls 23 double num_strings = num_pearls - 1.0; 24 25 // center to center distance between the neighboring pearls 26 double A_s = edge_sep + 2.0 * radius; 27 28 // Repeated Calculations 29 double sincasq = sinc(q*A_s); 30 double oneminussinc = 1 - sincasq; 31 double q_r = q * radius; 32 double q_edge = q * edge_sep; 33 34 // each volume 35 double string_vol = edge_sep * M_PI * thick_string * thick_string / 4.0; 36 double pearl_vol = M_4PI_3 * radius * radius * radius; 14 // number of string segments 15 num_pearls = floor(num_pearls + 0.5); //Force integer number of pearls 16 const double num_strings = num_pearls - 1.0; 37 17 38 //total volume 39 double tot_vol; 40 //each masses 41 double m_r= contrast_string * string_vol; 42 double m_s= contrast_pearl * pearl_vol; 43 double psi, gamma, beta; 44 //form factors 45 double sss, srr, srs; //cross 46 double srr_1, srr_2, srr_3; 47 double form_factor; 48 tot_vol = num_strings * string_vol; 49 tot_vol += num_pearls * pearl_vol; 18 //each masses: contrast * volume 19 const double contrast_pearl = sld_pearl - sld_solv; 20 const double contrast_string = sld_string - sld_solv; 21 const double string_vol = edge_sep * M_PI_4 * thick_string * thick_string; 22 const double pearl_vol = M_4PI_3 * radius * radius * radius; 23 const double m_string = contrast_string * string_vol; 24 const double m_pearl = contrast_pearl * pearl_vol; 50 25 51 //sine functions of a pearl 52 psi = sin(q_r); 53 psi -= q_r * cos(q_r); 54 psi *= 3.0; 55 psi /= q_r * q_r * q_r; 26 // center to center distance between the neighboring pearls 27 const double A_s = edge_sep + 2.0 * radius; 56 28 57 // Note take only 20 terms in Si series: 10 terms may be enough though. 58 gamma = Si(q_edge); 59 gamma /= (q_edge); 60 beta = Si(q * (A_s - radius)); 61 beta -= Si(q_r); 62 beta /= q_edge; 29 //sine functions of a pearl 30 // Note: lim_(q->0) Si(q*a)/(q*b) = a/b 31 // So therefore: 32 // beta = q==0. ? 1.0 : (Si(q*(A_s-radius)) - Si(q*radius))/q_edge; 33 // gamma = q==0. ? 1.0 : Si(q_edge)/q_edge; 34 // But there is a 1/(1-sinc) term below which blows up so don't bother 35 const double q_edge = q * edge_sep; 36 const double beta = (Si(q*(A_s-radius)) - Si(q*radius)) / q_edge; 37 const double gamma = Si(q_edge) / q_edge; 38 const double psi = sph_j1c(q*radius); 63 39 64 // form factor for num_pearls 65 sss = 1.0 - pow(sincasq, num_pearls); 66 sss /= oneminussinc * oneminussinc; 67 sss *= -sincasq; 68 sss -= num_pearls / 2.0; 69 sss += num_pearls / oneminussinc; 70 sss *= 2.0 * m_s * psi * m_s * psi; 40 // Precomputed sinc terms 41 const double si = sinc(q*A_s); 42 const double omsi = 1.0 - si; 43 const double pow_si = pow(si, num_pearls); 71 44 72 // form factor for num_strings (like thin rods) 73 srr_1 = -sinc(q_edge/2.0) * sinc(q_edge/2.0); 45 // form factor for num_pearls 46 const double sss = 2.0*square(m_pearl*psi) * ( 47 - si * (1.0 - pow_si) / (omsi*omsi) 48 + num_pearls / omsi 49 - 0.5 * num_pearls 50 ); 74 51 75 srr_1 += 2.0 * gamma; 76 srr_1 *= num_strings; 77 srr_2 = 2.0/oneminussinc; 78 srr_2 *= num_strings; 79 srr_2 *= beta * beta; 80 srr_3 = 1.0 - pow(sincasq, num_strings); 81 srr_3 /= oneminussinc * oneminussinc; 82 srr_3 *= beta * beta; 83 srr_3 *= -2.0; 52 // form factor for num_strings (like thin rods) 53 const double srr = m_string * m_string * ( 54 - 2.0 * (1.0 - pow_si/si)*beta*beta / (omsi*omsi) 55 + 2.0 * num_strings*beta*beta / omsi 56 + num_strings * (2.0*gamma - square(sinc(q_edge/2.0))) 57 ); 84 58 85 // total srr 86 srr = srr_1 + srr_2 + srr_3; 87 srr *= m_r * m_r; 59 // form factor for correlations 60 const double srs = 4.0 * m_string * m_pearl * beta * psi * ( 61 - si * (1.0 - pow_si/si) / (omsi*omsi) 62 + num_strings / omsi 63 ); 88 64 89 // form factor for correlations 90 srs = 1.0; 91 srs -= pow(sincasq, num_strings); 92 srs /= oneminussinc * oneminussinc; 93 srs *= -sincasq; 94 srs += num_strings/oneminussinc; 95 srs *= 4.0; 96 srs *= (m_r * m_s * beta * psi); 65 const double form = sss + srr + srs; 97 66 98 form_factor = sss + srr + srs; 99 form_factor /= (tot_vol * 1.0e4); // norm by volume and A^-1 to cm^-1 100 101 return (form_factor); 67 return 1.0e-4 * form; 102 68 } 103 69 104 70 double form_volume(double radius, double edge_sep, 105 71 double thick_string, double num_pearls) 106 72 { 107 double total_vol; 73 num_pearls = floor(num_pearls + 0.5); //Force integer number of pearls 108 74 109 double number_of_strings = num_pearls - 1.0;110 111 double string_vol = edge_sep * M_PI * thick_string * thick_string / 4.0;112 double pearl_vol = M_4PI_3 * radius * radius * radius;75 const double num_strings = num_pearls - 1.0; 76 const double string_vol = edge_sep * M_PI_4 * thick_string * thick_string; 77 const double pearl_vol = M_4PI_3 * radius * radius * radius; 78 const double volume = num_strings*string_vol + num_pearls*pearl_vol; 113 79 114 total_vol = number_of_strings * string_vol; 115 total_vol += num_pearls * pearl_vol; 116 117 return(total_vol); 80 return volume; 118 81 } 119 82 120 83 double Iq(double q, double radius, double edge_sep, 121 122 84 double thick_string, double num_pearls, double sld, 85 double string_sld, double solvent_sld) 123 86 { 124 double value, tot_vol; 125 126 value = _pearl_necklace_kernel(q, radius, edge_sep, thick_string, 127 num_pearls, sld, string_sld, solvent_sld); 128 tot_vol = form_volume(radius, edge_sep, thick_string, num_pearls); 87 const double form = _pearl_necklace_kernel(q, radius, edge_sep, 88 thick_string, num_pearls, sld, string_sld, solvent_sld); 129 89 130 return value*tot_vol;90 return form; 131 91 } -
sasmodels/models/pearl_necklace.py
r4962519 r2126131 92 92 ] 93 93 94 source = ["lib/Si.c", " pearl_necklace.c"]94 source = ["lib/Si.c", "lib/sph_j1c.c", "pearl_necklace.c"] 95 95 single = False # use double precision unless told otherwise 96 96
Note: See TracChangeset
for help on using the changeset viewer.