source: sasmodels/sasmodels/models/spherical_sld.c @ 391ea92

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 391ea92 was 391ea92, checked in by wojciech, 8 years ago

Speherical_SLD c file added - not working yet

  • Property mode set to 100644
File size: 11.5 KB
Line 
1//Headers
2static double form_volume(double thick_inter[],
3    double thick_flat_[],
4    double core_radius,
5    int n_shells);
6
7double Iq(double q,
8    int n_shells,
9    double thick_inter[],
10    double func_inter[],
11    double sld_core,
12    double sld_solvent,
13    double sld_flat[],
14    double thick_flat[],
15    double nu_inter[],
16    int npts_inter,
17    double core_radius);
18
19double Iqxy(double qx, double qy,
20    int n_shells,
21    double thick_inter[],
22    double func_inter[],
23    double sld_core,
24    double sld_solvent,
25    double sld_flat[],
26    double thick_flat[],
27    double nu_inter[],
28    int npts_inter,
29    double core_radius);
30
31//Main code
32static double form_volume(double thick_inter[],
33    double thick_flat_[],
34    double core_radius,
35    int n)
36{
37    double radius = 0.0;
38    int i;
39    double r = core_radius;
40    for (i=0; i < n; i++) {
41        r += thick_inter[i];
42        r += thick_flat[i];
43    }
44    return M_4PI_3*cube(r);
45}
46
47
48static double sphere_sld_kernel(double dp[], double q) {
49  int n = dp[0];
50  int i,j,k;
51
52  double scale = dp[1];
53  double thick_inter_core = dp[2];
54  double sld_core = dp[4];
55  double sld_solv = dp[5];
56  double background = dp[6];
57  double npts = dp[57]; //number of sub_layers in each interface
58  double nsl=npts;//21.0; //nsl = Num_sub_layer:  MUST ODD number in double //no other number works now
59  int n_s;
60
61  double sld_i,sld_f,dz,bes,fun,f,vol,qr,r,contr,f2;
62  double sign,slope=0.0;
63  double pi;
64
65  //int* fun_type;
66  //double* sld;
67  //double* thick_inter;
68  //double* thick;
69  //double* fun_coef;
70
71  double total_thick=0.0;
72
73  //fun_type = (int*)malloc((n+2)*sizeof(int));
74  //sld = (double*)malloc((n+2)*sizeof(double));
75  //thick_inter = (double*)malloc((n+2)*sizeof(double));
76  //thick = (double*)malloc((n+2)*sizeof(double));
77  //fun_coef = (double*)malloc((n+2)*sizeof(double));
78
79  //TODO: Solution to avoid mallocs but probablyu can be done better
80  int fun_type[12];
81  double sld[12];
82  double thick_inter[12];
83  double thick[12];
84  double fun_coef[12];
85
86  fun_type[0] = dp[3];
87  fun_coef[0] = fabs(dp[58]);
88  for (i =1; i<=n; i++){
89    sld[i] = dp[i+6];
90    thick_inter[i]= dp[i+16];
91    thick[i] = dp[i+26];
92    fun_type[i] = dp[i+36];
93    fun_coef[i] = fabs(dp[i+46]);
94    total_thick += thick[i];
95    total_thick += thick_inter[i];
96  }
97  sld[0] = sld_core;
98  sld[n+1] = sld_solv;
99  thick[0] = dp[59];
100  thick[n+1] = total_thick/5.0;
101  thick_inter[0] = thick_inter_core;
102  thick_inter[n+1] = 0.0;
103  fun_coef[n+1] = 0.0;
104  pi = 4.0*atan(1.0);
105  f = 0.0;
106  r = 0.0;
107  vol = 0.0;
108  //vol_pre = 0.0;
109  //vol_sub = 0.0;
110  sld_f = sld_core;
111
112  //floor_nsl = floor(nsl/2.0);
113
114  dz = 0.0;
115  // iteration for # of shells + core + solvent
116  for (i=0;i<=n+1; i++){
117    //iteration for N sub-layers
118    //if (fabs(thick[i]) <= 1e-24){
119    //   continue;
120    //}
121    // iteration for flat and interface
122    for (j=0;j<2;j++){
123      // iteration for sub_shells in the interface
124      // starts from #1 sub-layer
125      for (n_s=1;n_s<=nsl; n_s++){
126        // for solvent, it doesn't have an interface
127        if (i==n+1 && j==1)
128          break;
129        // for flat layers
130        if (j==0){
131          dz = thick[i];
132          sld_i = sld[i];
133          slope = 0.0;
134        }
135        // for interfacial sub_shells
136        else{
137          dz = thick_inter[i]/nsl;
138          // find sld_i at the outer boundary of sub-layer #n_s
139          sld_i = intersldfunc(fun_type[i],nsl, n_s, fun_coef[i], sld[i], sld[i+1]);
140          // calculate slope
141          slope= (sld_i -sld_f)/dz;
142        }
143        contr = sld_f-slope*r;
144        // iteration for the left and right boundary of the shells(or sub_shells)
145        for (k=0; k<2; k++){
146          // At r=0, the contribution to I is zero, so skip it.
147          if ( i == 0 && j == 0 && k == 0){
148            continue;
149          }
150          // On the top of slovent there is no interface; skip it.
151          if (i == n+1 && k == 1){
152            continue;
153          }
154          // At the right side (outer) boundary
155          if ( k == 1){
156            sign = 1.0;
157            r += dz;
158          }
159          // At the left side (inner) boundary
160          else{
161            sign = -1.0;
162          }
163          qr = q * r;
164          fun = 0.0;
165
166          if(qr == 0.0){
167            // sigular point
168            bes = sign * 1.0;
169          }
170          else{
171            // for flat sub-layer
172            //TODO: Single precision calculation most likely fails here
173            //bes = sign *  3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr);
174            bes = sign *  sph_j1c(qr);
175            if (fabs(slope) > 0.0 ){
176              //fun = sign * 3.0 * r * (2.0*qr*sin(qr)-((qr*qr)-2.0)*cos(qr))/(qr * qr * qr * qr);
177              fun = sign * r * sph_j1c(qr)  +  sign * 3.0 * sin(qr)/(qr * qr * q ) + sign * 6.0 * cos(qr)/(qr * qr * qr * q);
178            }
179          }
180
181          //Some initial optimization tries
182          /*bes = (qr == 0.0 ? sign * 1.0 : sign *  3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr));
183          //TODO: Will have to chnage this function
184          if (qr!= 0.0 && fabs(slope) > 0.0 ){
185            fun = sign * 3.0 * r * (2.0*qr*sin(qr)-((qr*qr)-2.0)*cos(qr))/(qr * qr * qr * qr);
186          }*/
187
188          // update total volume
189          vol = 4.0 * pi / 3.0 * r * r * r;
190          // we won't do the following volume correction for now.
191          // substrate empty area of volume
192          //if (k == 1 && fabs(sld_in[i]-sld_solv) < 1e-04*fabs(sld_solv) && fun_type[i]==0){
193          //  vol_sub += (vol_pre - vol);
194          //}
195          f += vol * (bes * contr + fun * slope);
196        }
197        // remember this sld as sld_f
198        sld_f = sld_i;
199        // no sub-layer iteration (n_s loop) for the flat layer
200        if (j==0)
201          break;
202      }
203    }
204  }
205  //vol += vol_sub;
206  f2 = f * f / vol;
207  //f2 *= scale;
208  //f2 += background;
209  //free(fun_type);
210  //free(sld);
211  //free(thick_inter);
212  //free(thick);
213  //free(fun_coef);
214
215  return (f2);
216}
217
218
219/**
220 * Function to evaluate 1D SphereSLD function
221 * @param q: q-value
222 * @return: function value
223 */
224double Iq(double q,
225    int n_shells, double thick_inter_0, int func_inter_0, double core0_sld, double solvent_sld,
226    double flat1_sld, double flat2_sld, double flat3_sld, double flat4_sld, double flat5_sld,
227    double flat6_sld, double flat7_sld, double flat8_sld, double flat9_sld, double flat10_sld,
228    double thick_inter_1, double thick_inter_2, double thick_inter_3, double thick_inter_4, double thick_inter_5,
229    double thick_inter_6, double thick_inter_7, double thick_inter_8, double thick_inter_9, double thick_inter_10,
230    double thick_flat_1, double thick_flat_2, double thick_flat_3, double thick_flat_4, double thick_flat_5,
231    double thick_flat_6, double thick_flat_7, double thick_flat_8, double thick_flat_9, double thick_flat_10,
232    int func_inter_1, int func_inter_2, int func_inter_3, int func_inter_4, int func_inter_5,
233    int func_inter_6, int func_inter_7, int func_inter_8, int func_inter_9, int func_inter_10,
234    double nu_inter_1, double nu_inter_2,double nu_inter_3, double nu_inter_4, double nu_inter_5,
235    double nu_inter_6, double nu_inter_7, double nu_inter_8, double nu_inter_9, double nu_inter_10,
236    int npts_inter, double nu_inter_0, double rad_core_0) {
237
238    //printf("Number of points %d\n",npts_inter);
239    double intensity;
240    //TODO: Remove this container at later stage. It is only kept to minimize stupid errors now
241    double dp[60];
242    dp[0] = n_shells;
243    //This is scale will also have to be removed at some stage
244    dp[1] = 1.0;
245    dp[2] = thick_inter_0;
246    dp[3] = func_inter_0;
247    dp[4] = core0_sld;
248    dp[5] = solvent_sld;
249    dp[6] = 0.0;
250
251    dp[7] = flat1_sld;
252    dp[8] = flat2_sld;
253    dp[9] = flat3_sld;
254    dp[10] = flat4_sld;
255    dp[11] = flat5_sld;
256    dp[12] = flat6_sld;
257    dp[13] = flat7_sld;
258    dp[14] = flat8_sld;
259    dp[15] = flat9_sld;
260    dp[16] = flat10_sld;
261
262    dp[17] = thick_inter_1;
263    dp[18] = thick_inter_2;
264    dp[19] = thick_inter_3;
265    dp[20] = thick_inter_4;
266    dp[21] = thick_inter_5;
267    dp[22] = thick_inter_6;
268    dp[23] = thick_inter_7;
269    dp[24] = thick_inter_8;
270    dp[25] = thick_inter_9;
271    dp[26] = thick_inter_10;
272
273    dp[27] = thick_flat_1;
274    dp[28] = thick_flat_2;
275    dp[29] = thick_flat_3;
276    dp[30] = thick_flat_4;
277    dp[31] = thick_flat_5;
278    dp[32] = thick_flat_6;
279    dp[33] = thick_flat_7;
280    dp[34] = thick_flat_8;
281    dp[35] = thick_flat_9;
282    dp[36] = thick_flat_10;
283
284    dp[37] = func_inter_1;
285    dp[38] = func_inter_2;
286    dp[39] = func_inter_3;
287    dp[40] = func_inter_4;
288    dp[41] = func_inter_5;
289    dp[42] = func_inter_6;
290    dp[43] = func_inter_7;
291    dp[44] = func_inter_8;
292    dp[45] = func_inter_9;
293    dp[46] = func_inter_10;
294
295    dp[47] = nu_inter_1;
296    dp[48] = nu_inter_2;
297    dp[49] = nu_inter_3;
298    dp[50] = nu_inter_4;
299    dp[51] = nu_inter_5;
300    dp[52] = nu_inter_6;
301    dp[53] = nu_inter_7;
302    dp[54] = nu_inter_8;
303    dp[55] = nu_inter_9;
304    dp[56] = nu_inter_10;
305
306    dp[57] = npts_inter;
307    dp[58] = nu_inter_0;
308    dp[59] = rad_core_0;
309
310    intensity = 1.0e-4*sphere_sld_kernel(dp,q);
311    //printf("%10d\n",intensity);
312    return intensity;
313}
314
315/**
316 * Function to evaluate 2D SphereSLD function
317 * @param q_x: value of Q along x
318 * @param q_y: value of Q along y
319 * @return: function value
320 */
321double Iqxy(double qx, double qy,
322    int n_shells, double thick_inter_0, int func_inter_0, double core0_sld, double solvent_sld,
323    double flat1_sld, double flat2_sld, double flat3_sld, double flat4_sld, double flat5_sld,
324    double flat6_sld, double flat7_sld, double flat8_sld, double flat9_sld, double flat10_sld,
325    double thick_inter_1, double thick_inter_2, double thick_inter_3, double thick_inter_4, double thick_inter_5,
326    double thick_inter_6, double thick_inter_7, double thick_inter_8, double thick_inter_9, double thick_inter_10,
327    double thick_flat_1, double thick_flat_2, double thick_flat_3, double thick_flat_4, double thick_flat_5,
328    double thick_flat_6, double thick_flat_7, double thick_flat_8, double thick_flat_9, double thick_flat_10,
329    int func_inter_1, int func_inter_2, int func_inter_3, int func_inter_4, int func_inter_5,
330    int func_inter_6, int func_inter_7, int func_inter_8, int func_inter_9, int func_inter_10,
331    double nu_inter_1, double nu_inter_2,double nu_inter_3, double nu_inter_4, double nu_inter_5,
332    double nu_inter_6, double nu_inter_7, double nu_inter_8, double nu_inter_9, double nu_inter_10,
333    int npts_inter, double nu_inter_0, double rad_core_0) {
334
335    double q = sqrt(qx*qx + qy*qy);
336    return Iq(q, n_shells, thick_inter_0, func_inter_0, core0_sld, solvent_sld,
337    flat1_sld, flat2_sld, flat3_sld, flat4_sld, flat5_sld,
338    flat6_sld, flat7_sld, flat8_sld, flat9_sld, flat10_sld,
339    thick_inter_1, thick_inter_2, thick_inter_3, thick_inter_4, thick_inter_5,
340    thick_inter_6, thick_inter_7, thick_inter_8, thick_inter_9, thick_inter_10,
341    thick_flat_1, thick_flat_2, thick_flat_3, thick_flat_4, thick_flat_5,
342    thick_flat_6, thick_flat_7, thick_flat_8, thick_flat_9, thick_flat_10,
343    func_inter_1, func_inter_2, func_inter_3, func_inter_4, func_inter_5,
344    func_inter_6, func_inter_7, func_inter_8, func_inter_9, func_inter_10,
345    nu_inter_1, nu_inter_2, nu_inter_3, nu_inter_4, nu_inter_5,
346    nu_inter_6, nu_inter_7, nu_inter_8, nu_inter_9, nu_inter_10,
347    npts_inter, nu_inter_0, rad_core_0);
348
349    //TODO: Check if evalute rphi is not needed?
350
351}
352
Note: See TracBrowser for help on using the repository browser.