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

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 36cbbe74 was 890ac7f1, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

Re #5 fixing samsmodels compilation on MSVC

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