source: sasmodels/sasmodels/models/lib/librefl.c @ 7ef3589

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

Spherical sld 1st compiling version

  • Property mode set to 100644
File size: 6.6 KB
Line 
1typedef struct {
2        double re;
3        double im;
4} complex;
5
6complex cassign(real, imag);
7complex cplx_add(x,y);
8complex rcmult(x,y);
9complex cplx_sub(x,y);
10complex cplx_mult(x,y);
11complex cplx_div(x,y);
12complex cplx_exp(b);
13
14double err_mod_func(double n_sub, double ind, double nu);
15double linearfunc(double n_sub, double ind, double nu);
16double power_r(double n_sub, double ind, double nu);
17double exp_r(double n_sub, double ind, double nu);
18double exp_l(double n_sub, double ind, double nu);
19double intersldfunc(int fun_type, double n_sub, double i, double nu, double sld_l, double sld_r);
20double interfunc(int fun_type, double n_sub, double i, double sld_l, double sld_r);
21
22complex cassign(real, imag)
23        double real, imag;
24{
25        complex x;
26        x.re = real;
27        x.im = imag;
28        return x;
29}
30
31
32complex cplx_add(x,y)
33        complex x,y;
34{
35        complex z;
36        z.re = x.re + y.re;
37        z.im = x.im + y.im;
38        return z;
39}
40
41complex rcmult(x,y)
42        double x;
43    complex y;
44{
45        complex z;
46        z.re = x*y.re;
47        z.im = x*y.im;
48        return z;
49}
50
51complex cplx_sub(x,y)
52        complex x,y;
53{
54        complex z;
55        z.re = x.re - y.re;
56        z.im = x.im - y.im;
57        return z;
58}
59
60
61complex cplx_mult(x,y)
62        complex x,y;
63{
64        complex z;
65        z.re = x.re*y.re - x.im*y.im;
66        z.im = x.re*y.im + x.im*y.re;
67        return z;
68}
69
70complex cplx_div(x,y)
71        complex x,y;
72{
73        complex z;
74        z.re = (x.re*y.re + x.im*y.im)/(y.re*y.re + y.im*y.im);
75        z.im = (x.im*y.re - x.re*y.im)/(y.re*y.re + y.im*y.im);
76        return z;
77}
78
79complex cplx_exp(b)
80        complex b;
81{
82        complex z;
83        double br,bi;
84        br=b.re;
85        bi=b.im;
86        z.re = exp(br)*cos(bi);
87        z.im = exp(br)*sin(bi);
88        return z;
89}
90
91
92complex cplx_sqrt(z)    //see Schaum`s Math Handbook p. 22, 6.6 and 6.10
93        complex z;
94{
95        complex c;
96        double zr,zi,x,y,r,w;
97
98        zr=z.re;
99        zi=z.im;
100
101        if (zr==0.0 && zi==0.0)
102        {
103    c.re=0.0;
104        c.im=0.0;
105    return c;
106        }
107        else
108        {
109                x=fabs(zr);
110                y=fabs(zi);
111                if (x>y)
112                {
113                        r=y/x;
114                        w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r)));
115                }
116                else
117                {
118                        r=x/y;
119                        w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r)));
120                }
121                if (zr >=0.0)
122                {
123                        c.re=w;
124                        c.im=zi/(2.0*w);
125                }
126                else
127                {
128                        c.im=(zi >= 0) ? w : -w;
129                        c.re=zi/(2.0*c.im);
130                }
131                return c;
132        }
133}
134
135complex cplx_cos(b)
136        complex b;
137{
138        complex zero,two,z,i,bi,negbi;
139        zero = cassign(0.0,0.0);
140        two = cassign(2.0,0.0);
141        i = cassign(0.0,1.0);
142        bi = cplx_mult(b,i);
143        negbi = cplx_sub(zero,bi);
144        z = cplx_div(cplx_add(cplx_exp(bi),cplx_exp(negbi)),two);
145        return z;
146}
147
148// normalized and modified erf
149//   |
150// 1 +                __  - - - -
151//   |             _
152//       |            _
153//   |        __
154// 0 + - - -
155//   |-------------+------------+--
156//   0           center       n_sub    --->
157//                                     ind
158//
159// n_sub = total no. of bins(or sublayers)
160// ind = x position: 0 to max
161// nu = max x to integration
162double err_mod_func(double n_sub, double ind, double nu)
163{
164  double center, func;
165  if (nu == 0.0)
166                nu = 1e-14;
167        if (n_sub == 0.0)
168                n_sub = 1.0;
169
170
171        //ind = (n_sub-1.0)/2.0-1.0 +ind;
172        center = n_sub/2.0;
173        // transform it so that min(ind) = 0
174        ind -= center;
175        // normalize by max limit
176        ind /= center;
177        // divide by sqrt(2) to get Gaussian func
178        nu /= sqrt(2.0);
179        ind *= nu;
180        // re-scale and normalize it so that max(erf)=1, min(erf)=0
181        func = erf(ind)/erf(nu)/2.0;
182        // shift it by +0.5 in y-direction so that min(erf) = 0
183        func += 0.5;
184
185        return func;
186}
187double linearfunc(double n_sub, double ind, double nu)
188{
189  double bin_size, func;
190        if (n_sub == 0.0)
191                n_sub = 1.0;
192
193        bin_size = 1.0/n_sub;  //size of each sub-layer
194        // rescale
195        ind *= bin_size;
196        func = ind;
197
198        return func;
199}
200// use the right hand side from the center of power func
201double power_r(double n_sub, double ind, double nu)
202{
203  double bin_size,func;
204        if (nu == 0.0)
205                nu = 1e-14;
206        if (n_sub == 0.0)
207                n_sub = 1.0;
208
209        bin_size = 1.0/n_sub;  //size of each sub-layer
210        // rescale
211        ind *= bin_size;
212        func = pow(ind, nu);
213
214        return func;
215}
216// use the left hand side from the center of power func
217double power_l(double n_sub, double ind, double nu)
218{
219  double bin_size, func;
220        if (nu == 0.0)
221                nu = 1e-14;
222        if (n_sub == 0.0)
223                n_sub = 1.0;
224
225        bin_size = 1.0/n_sub;  //size of each sub-layer
226        // rescale
227        ind *= bin_size;
228        func = 1.0-pow((1.0-ind),nu);
229
230        return func;
231}
232// use 1-exp func from x=0 to x=1
233double exp_r(double n_sub, double ind, double nu)
234{
235  double bin_size, func;
236        if (nu == 0.0)
237                nu = 1e-14;
238        if (n_sub == 0.0)
239                n_sub = 1.0;
240
241        bin_size = 1.0/n_sub;  //size of each sub-layer
242        // rescale
243        ind *= bin_size;
244        // modify func so that func(0) =0 and func(max)=1
245        func = 1.0-exp(-nu*ind);
246        // normalize by its max
247        func /= (1.0-exp(-nu));
248
249        return func;
250}
251
252// use the left hand side mirror image of exp func
253double exp_l(double n_sub, double ind, double nu)
254{
255  double bin_size, func;
256        if (nu == 0.0)
257                nu = 1e-14;
258        if (n_sub == 0.0)
259                n_sub = 1.0;
260
261        bin_size = 1.0/n_sub;  //size of each sub-layer
262        // rescale
263        ind *= bin_size;
264        // modify func
265        func = exp(-nu*(1.0-ind))-exp(-nu);
266        // normalize by its max
267        func /= (1.0-exp(-nu));
268
269        return func;
270}
271
272// To select function called
273// At nu = 0 (singular point), call line function
274double intersldfunc(int fun_type, double n_sub, double i, double nu, double sld_l, double sld_r)
275{
276        double sld_i, func;
277        // this condition protects an error from the singular point
278        if (nu == 0.0){
279                nu = 1e-13;
280        }
281        // select func
282        switch(fun_type){
283                case 1 :
284                        func = power_r(n_sub, i, nu);
285                        break;
286                case 2 :
287                        func = power_l(n_sub, i, nu);
288                        break;
289                case 3 :
290                        func = exp_r(n_sub, i, nu);
291                        break;
292                case 4 :
293                        func = exp_l(n_sub, i, nu);
294                        break;
295                case 5 :
296                        func = linearfunc(n_sub, i, nu);
297                        break;
298                default:
299                        func = err_mod_func(n_sub, i, nu);
300                        break;
301        }
302        // compute sld
303        if (sld_r>sld_l){
304                sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
305        }
306        else if (sld_r<sld_l){
307                func = 1.0-func;
308                sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
309        }
310        else{
311                sld_i = sld_r;
312        }
313        return sld_i;
314}
315
316
317// used by refl.c
318double interfunc(int fun_type, double n_sub, double i, double sld_l, double sld_r)
319{
320        double sld_i, func;
321        switch(fun_type){
322                case 0 :
323                        func = err_mod_func(n_sub, i, 2.5);
324                        break;
325                default:
326                        func = linearfunc(n_sub, i, 1.0);
327                        break;
328        }
329        if (sld_r>sld_l){
330                sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
331        }
332        else if (sld_r<sld_l){
333                func = 1.0-func;
334                sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick);
335        }
336        else{
337                sld_i = sld_r;
338        }
339        return sld_i;
340}
Note: See TracBrowser for help on using the repository browser.