source: sasview/sansmodels/src/sans/models/c_extensions/spheresld.c @ a24f530

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since a24f530 was 3be94e8, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

Re #5 fixing problem with malloc

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/**
2 * spheresld model
3 */
4#include <math.h>
5#include "spheresld.h"
6#include "libmultifunc/librefl.h"
7#include <stdio.h>
8#include <stdlib.h>
9
10#define lamda 4.62
11
12
13double sphere_sld_kernel(double dp[], double q) {
14        int n = dp[0];
15        int i,j,k;
16
17        double scale = dp[1];
18        double thick_inter_core = dp[2];
19        double sld_core = dp[4];
20        double sld_solv = dp[5];
21        double background = dp[6];
22        double npts = dp[57]; //number of sub_layers in each interface
23  double nsl=npts;//21.0; //nsl = Num_sub_layer:  MUST ODD number in double //no other number works now
24  int n_s;
25  int floor_nsl;
26
27  double sld_i,sld_f,dz,bes,fun,f,vol,vol_pre,vol_sub,qr,r,contr,f2;
28  double sign,slope=0.0;
29  double pi;
30  double r0 = 0.0, thick_inter_f;
31
32  int* fun_type;
33  double* sld;
34  double* thick_inter;
35  double* thick;
36  double* fun_coef;
37
38        double total_thick;
39
40        fun_type = (int*)malloc((n+2)*sizeof(int));
41  sld = (double*)malloc((n+2)*sizeof(double));
42  thick_inter = (double*)malloc((n+2)*sizeof(double));
43  thick = (double*)malloc((n+2)*sizeof(double));
44  fun_coef = (double*)malloc((n+2)*sizeof(double));
45
46        fun_type[0] = dp[3];
47        fun_coef[0] = fabs(dp[58]);
48        for (i =1; i<=n; i++){
49                sld[i] = dp[i+6];
50                thick_inter[i]= dp[i+16];
51                thick[i] = dp[i+26];
52                fun_type[i] = dp[i+36];
53                fun_coef[i] = fabs(dp[i+46]);
54                total_thick += thick[i] + thick_inter[i];
55        }
56        sld[0] = sld_core;
57        sld[n+1] = sld_solv;
58        thick[0] = dp[59];
59        thick[n+1] = total_thick/5.0;
60        thick_inter[0] = thick_inter_core;
61        thick_inter[n+1] = 0.0;
62        fun_coef[n+1] = 0.0;
63
64    pi = 4.0*atan(1.0);
65    f = 0.0;
66    r = 0.0;
67    vol = 0.0;
68    vol_pre = 0.0;
69    vol_sub = 0.0;
70    sld_f = sld_core;
71
72        //floor_nsl = floor(nsl/2.0);
73
74    dz = 0.0;
75    // iteration for # of shells + core + solvent
76    for (i=0;i<=n+1; i++){
77                //iteration for N sub-layers
78        //if (fabs(thick[i]) <= 1e-24){
79        //   continue;
80        //}
81        // iteration for flat and interface
82                for (j=0;j<2;j++){
83                        // iteration for sub_shells in the interface
84                        // starts from #1 sub-layer
85                        for (n_s=1;n_s<=nsl; n_s++){
86                                // for solvent, it doesn't have an interface
87                                if (i==n+1 && j==1)
88                                        break;
89                                // for flat layers
90                                if (j==0){
91                                        dz = thick[i];
92                                        sld_i = sld[i];
93                                        slope = 0.0;
94                                }
95                                // for interfacial sub_shells
96                                else{
97                                        dz = thick_inter[i]/nsl;
98                                        // find sld_i at the outer boundary of sub-layer #n_s
99                                        sld_i = intersldfunc(fun_type[i],nsl, n_s, fun_coef[i], sld[i], sld[i+1]);
100                                        // calculate slope
101                                        slope= (sld_i -sld_f)/dz;
102                                }
103                                contr = sld_f-slope*r;
104                                // iteration for the left and right boundary of the shells(or sub_shells)
105                                for (k=0; k<2; k++){
106                                        // At r=0, the contribution to I is zero, so skip it.
107                                        if ( i == 0 && j == 0 && k == 0){
108                                                continue;
109                                                }
110                                        // On the top of slovent there is no interface; skip it.
111                                        if (i == n+1 && k == 1){
112                                                continue;
113                                                }
114                                        // At the right side (outer) boundary
115                                        if ( k == 1){
116                                                sign = 1.0;
117                                                r += dz;
118                                                }
119                                        // At the left side (inner) boundary
120                                        else{
121                                                sign = -1.0;
122                                                }
123                                        qr = q * r;
124                                        fun = 0.0;
125                                        if(qr == 0.0){
126                                                // sigular point
127                                                bes = sign * 1.0;
128                                                }
129                                        else{
130                                                // for flat sub-layer
131                                                bes = sign *  3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr);
132                                                // with linear slope
133                                                if (fabs(slope) > 0.0 ){
134                                                        fun = sign * 3.0 * r * (2.0*qr*sin(qr)-((qr*qr)-2.0)*cos(qr))/(qr * qr * qr * qr);
135                                                        }
136                                                }
137                                        // update total volume
138                                        vol = 4.0 * pi / 3.0 * r * r * r;
139                                        // we won't do the following volume correction for now.
140                                        // substrate empty area of volume
141                                        //if (k == 1 && fabs(sld_in[i]-sld_solv) < 1e-04*fabs(sld_solv) && fun_type[i]==0){
142                                        //      vol_sub += (vol_pre - vol);
143                                        //}
144                                        f += vol * (bes * contr + fun * slope);
145                                }
146                                // remember this sld as sld_f
147                                sld_f =sld_i;
148                                // no sub-layer iteration (n_s loop) for the flat layer
149                                if (j==0)
150                                        break;
151                        }
152                }
153    }
154    //vol += vol_sub;
155    f2 = f * f / vol * 1.0e8;
156        f2 *= scale;
157        f2 += background;
158
159  free(fun_type);
160  free(sld);
161  free(thick_inter);
162  free(thick);
163  free(fun_coef);
164
165    return (f2);
166}
167
168/**
169 * Function to evaluate spheresld function
170 * @param pars: parameters of spheresld
171 * @param q: q-value
172 * @return: function value
173 */
174
175double sphere_sld_analytical_1D(SphereSLDParameters *pars, double q) {
176        double dp[60];
177
178        dp[0] = pars->n_shells;
179        dp[1] = pars->scale;
180        dp[2] = pars->thick_inter0;
181        dp[3] = pars->func_inter0;
182        dp[4] = pars->sld_core0;
183        dp[5] = pars->sld_solv;
184        dp[6] = pars->background;
185
186        dp[7] = pars->sld_flat1;
187        dp[8] = pars->sld_flat2;
188        dp[9] = pars->sld_flat3;
189        dp[10] = pars->sld_flat4;
190        dp[11] = pars->sld_flat5;
191        dp[12] = pars->sld_flat6;
192        dp[13] = pars->sld_flat7;
193        dp[14] = pars->sld_flat8;
194        dp[15] = pars->sld_flat9;
195        dp[16] = pars->sld_flat10;
196
197        dp[17] = pars->thick_inter1;
198        dp[18] = pars->thick_inter2;
199        dp[19] = pars->thick_inter3;
200        dp[20] = pars->thick_inter4;
201        dp[21] = pars->thick_inter5;
202        dp[22] = pars->thick_inter6;
203        dp[23] = pars->thick_inter7;
204        dp[24] = pars->thick_inter8;
205        dp[25] = pars->thick_inter9;
206        dp[26] = pars->thick_inter10;
207
208        dp[27] = pars->thick_flat1;
209        dp[28] = pars->thick_flat2;
210        dp[29] = pars->thick_flat3;
211        dp[30] = pars->thick_flat4;
212        dp[31] = pars->thick_flat5;
213        dp[32] = pars->thick_flat6;
214        dp[33] = pars->thick_flat7;
215        dp[34] = pars->thick_flat8;
216        dp[35] = pars->thick_flat9;
217        dp[36] = pars->thick_flat10;
218
219        dp[37] = pars->func_inter1;
220        dp[38] = pars->func_inter2;
221        dp[39] = pars->func_inter3;
222        dp[40] = pars->func_inter4;
223        dp[41] = pars->func_inter5;
224        dp[42] = pars->func_inter6;
225        dp[43] = pars->func_inter7;
226        dp[44] = pars->func_inter8;
227        dp[45] = pars->func_inter9;
228        dp[46] = pars->func_inter10;
229
230        dp[47] = pars->nu_inter1;
231        dp[48] = pars->nu_inter2;
232        dp[49] = pars->nu_inter3;
233        dp[50] = pars->nu_inter4;
234        dp[51] = pars->nu_inter5;
235        dp[52] = pars->nu_inter6;
236        dp[53] = pars->nu_inter7;
237        dp[54] = pars->nu_inter8;
238        dp[55] = pars->nu_inter9;
239        dp[56] = pars->nu_inter10;
240
241        dp[57] = pars->npts_inter;
242        dp[58] = pars->nu_inter0;
243        dp[59] = pars->rad_core0;
244
245        return sphere_sld_kernel(dp, q);
246}
247
248/**
249 * Function to evaluate spheresld function
250 * @param pars: parameters of spheresld
251 * @param q: q-value
252 * @return: function value
253 */
254double sphere_sld_analytical_2D(SphereSLDParameters *pars, double q, double phi) {
255        return sphere_sld_analytical_1D(pars,q);
256}
257
258double sphere_sld_analytical_2DXY(SphereSLDParameters *pars, double qx, double qy){
259        return sphere_sld_analytical_1D(pars,sqrt(qx*qx+qy*qy));
260}
Note: See TracBrowser for help on using the repository browser.