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

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 830622f was 830622f, checked in by Mathieu Doucet <doucetm@…>, 12 years ago

Re #5 fixing spheresld compilation on MSVC

  • Property mode set to 100644
File size: 6.5 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,fun_type[n+2];
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);
41  sld = (double*)malloc(n+2);
42  thick_inter = (double*)malloc(n+2);
43  thick = (double*)malloc(n+2);
44  fun_coef = (double*)malloc(n+2);
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(sld_im);
162  free(thick_inter);
163  free(thick);
164  free(fun_coef);
165
166    return (f2);
167}
168
169/**
170 * Function to evaluate spheresld function
171 * @param pars: parameters of spheresld
172 * @param q: q-value
173 * @return: function value
174 */
175
176double sphere_sld_analytical_1D(SphereSLDParameters *pars, double q) {
177        double dp[60];
178
179        dp[0] = pars->n_shells;
180        dp[1] = pars->scale;
181        dp[2] = pars->thick_inter0;
182        dp[3] = pars->func_inter0;
183        dp[4] = pars->sld_core0;
184        dp[5] = pars->sld_solv;
185        dp[6] = pars->background;
186
187        dp[7] = pars->sld_flat1;
188        dp[8] = pars->sld_flat2;
189        dp[9] = pars->sld_flat3;
190        dp[10] = pars->sld_flat4;
191        dp[11] = pars->sld_flat5;
192        dp[12] = pars->sld_flat6;
193        dp[13] = pars->sld_flat7;
194        dp[14] = pars->sld_flat8;
195        dp[15] = pars->sld_flat9;
196        dp[16] = pars->sld_flat10;
197
198        dp[17] = pars->thick_inter1;
199        dp[18] = pars->thick_inter2;
200        dp[19] = pars->thick_inter3;
201        dp[20] = pars->thick_inter4;
202        dp[21] = pars->thick_inter5;
203        dp[22] = pars->thick_inter6;
204        dp[23] = pars->thick_inter7;
205        dp[24] = pars->thick_inter8;
206        dp[25] = pars->thick_inter9;
207        dp[26] = pars->thick_inter10;
208
209        dp[27] = pars->thick_flat1;
210        dp[28] = pars->thick_flat2;
211        dp[29] = pars->thick_flat3;
212        dp[30] = pars->thick_flat4;
213        dp[31] = pars->thick_flat5;
214        dp[32] = pars->thick_flat6;
215        dp[33] = pars->thick_flat7;
216        dp[34] = pars->thick_flat8;
217        dp[35] = pars->thick_flat9;
218        dp[36] = pars->thick_flat10;
219
220        dp[37] = pars->func_inter1;
221        dp[38] = pars->func_inter2;
222        dp[39] = pars->func_inter3;
223        dp[40] = pars->func_inter4;
224        dp[41] = pars->func_inter5;
225        dp[42] = pars->func_inter6;
226        dp[43] = pars->func_inter7;
227        dp[44] = pars->func_inter8;
228        dp[45] = pars->func_inter9;
229        dp[46] = pars->func_inter10;
230
231        dp[47] = pars->nu_inter1;
232        dp[48] = pars->nu_inter2;
233        dp[49] = pars->nu_inter3;
234        dp[50] = pars->nu_inter4;
235        dp[51] = pars->nu_inter5;
236        dp[52] = pars->nu_inter6;
237        dp[53] = pars->nu_inter7;
238        dp[54] = pars->nu_inter8;
239        dp[55] = pars->nu_inter9;
240        dp[56] = pars->nu_inter10;
241
242        dp[57] = pars->npts_inter;
243        dp[58] = pars->nu_inter0;
244        dp[59] = pars->rad_core0;
245
246        return sphere_sld_kernel(dp, q);
247}
248
249/**
250 * Function to evaluate spheresld function
251 * @param pars: parameters of spheresld
252 * @param q: q-value
253 * @return: function value
254 */
255double sphere_sld_analytical_2D(SphereSLDParameters *pars, double q, double phi) {
256        return sphere_sld_analytical_1D(pars,q);
257}
258
259double sphere_sld_analytical_2DXY(SphereSLDParameters *pars, double qx, double qy){
260        return sphere_sld_analytical_1D(pars,sqrt(qx*qx+qy*qy));
261}
Note: See TracBrowser for help on using the repository browser.