source: sasmodels/sasmodels/models/lib/librefl.c @ 9244430

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

Prototype version of sphericalSLD

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