source: sasview/sansmodels/src/sans/models/c_extensions/refl.c @ c572e5e

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 c572e5e was 0164899a, checked in by Jae Cho <jhjcho@…>, 14 years ago

new models and some bug fixes

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[35aface]1/**
[0164899a]2 *  model for NR
[35aface]3 */
[0164899a]4// The original code, of which work was not DANSE funded,
5// was provided by J. Cho.
[35aface]6#include <math.h>
7#include "refl.h"
[0164899a]8#include "libmultifunc/librefl.h"
[35aface]9#include <stdio.h>
10#include <stdlib.h>
11
12#define lamda 4.62
13
14
15double re_kernel(double dp[], double q) {
16        int n = dp[0];
17        int i,j,fun_type[n+2];
18
19        double scale = dp[1];
20        double thick_inter_sub = dp[2];
21        double sld_sub = dp[4];
22        double sld_super = dp[5];
23        double background = dp[6];
24
[0164899a]25        double sld[n+2],thick_inter[n+2],thick[n+2],total_thick;
[35aface]26        fun_type[0] = dp[3];
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                total_thick += thick[i] + thick_inter[i];
33        }
34        sld[0] = sld_sub;
35        sld[n+1] = sld_super;
[0164899a]36
[35aface]37        thick[0] = total_thick/5.0;
38        thick[n+1] = total_thick/5.0;
39        thick_inter[0] = thick_inter_sub;
40        thick_inter[n+1] = 0.0;
41
[0164899a]42        double nsl=21.0; //nsl = Num_sub_layer:
43        int n_s;
[339ce67]44    double sld_i,sldim_i,dz,phi,R,ko2;
[0164899a]45    double sign,erfunc, fun;
[35aface]46    double pi;
47        complex  inv_n,phi1,alpha,alpha2,kn,fnm,fnp,rn,Xn,nn,nn2,an,nnp1,one,zero,two,n_sub,n_sup,knp1,Xnp1;
48        pi = 4.0*atan(1.0);
49    one = cassign(1.0,0.0);
50        //zero = cassign(0.0,0.0);
51        two= cassign(0.0,-2.0);
52
53        //Checking if floor is available.
54        //no imaginary sld inputs in this function yet
[0164899a]55    n_sub=cassign(1.0-sld_sub*pow(lamda,2.0)/(2.0*pi),0.0);
56    n_sup=cassign(1.0-sld_super*pow(lamda,2.0)/(2.0*pi),0.0);
[35aface]57    ko2 = pow(2.0*pi/lamda,2.0);
58
59    phi = asin(lamda*q/(4.0*pi));
60    phi1 = cdiv(rcmult(phi,one),n_sup);
61    alpha = cmult(n_sup,ccos(phi1));
62        alpha2 = cmult(alpha,alpha);
63
64    nnp1=n_sub;
65    knp1=csqrt(rcmult(ko2,csub(cmult(nnp1,nnp1),alpha2)));  //nnp1*ko*sin(phinp1)
66    Xnp1=cassign(0.0,0.0);
67    dz = 0.0;
68    // iteration for # of layers +sub from the top
69    for (i=1;i<=n+1; i++){
[0164899a]70        if (fun_type[i-1]==1)
71                fun = 5;
72        else
73                        fun = 0;
[35aface]74                //iteration for 9 sub-layers
75                for (j=0;j<2;j++){
[0164899a]76                        for (n_s=0;n_s<nsl; n_s++){
[35aface]77                                if (j==1){
78                                        if (i==n+1)
79                                                break;
80                                        dz = thick[i];
81                                        sld_i = sld[i];
82                                }
83                                else{
[0164899a]84                                        dz = thick_inter[i-1]/nsl;//nsl;
[339ce67]85                                        if (sld[i-1] == sld[i]){
86                                                sld_i = sld[i];
87                                        }
88                                        else{
[0164899a]89                                                sld_i = intersldfunc(fun,nsl, n_s+0.5, 2.5, sld[i-1], sld[i]);
[339ce67]90                                        }
[35aface]91                                }
[0164899a]92                                nn = cassign(1.0-sld_i*pow(lamda,2.0)/(2.0*pi),0.0);
[35aface]93                                nn2=cmult(nn,nn);
94
95                                kn=csqrt(rcmult(ko2,csub(nn2,alpha2)));        //nn*ko*sin(phin)
96                                an=cexp(rcmult(dz,cmult(two,kn)));
97
98                                fnm=csub(kn,knp1);
99                                fnp=cadd(kn,knp1);
100                                rn=cdiv(fnm,fnp);
101                                Xn=cmult(an,cdiv(cadd(rn,Xnp1),cadd(one,cmult(rn,Xnp1))));    //Xn=an*((rn+Xnp1*anp1)/(1+rn*Xnp1*anp1))
102
103                                Xnp1=Xn;
104                                knp1=kn;
105
106                                if (j==1)
107                                        break;
108                        }
109                }
110    }
111    R=pow(Xn.re,2.0)+pow(Xn.im,2.0);
112    // This temperarily fixes the total reflection for Rfunction and linear.
113    // ToDo: Show why it happens that Xn.re=0 and Xn.im >1!
114    if (Xn.im == 0.0){
115        R=1.0;
116    }
117    R *= scale;
118    R += background;
119
120    return R;
121
122}
123/**
[0164899a]124 * Function to evaluate NR function
125 * @param pars: parameters
[35aface]126 * @param q: q-value
127 * @return: function value
128 */
129double refl_analytical_1D(ReflParameters *pars, double q) {
[0164899a]130        double dp[47];
[35aface]131
132        dp[0] = pars->n_layers;
133        dp[1] = pars->scale;
134        dp[2] = pars->thick_inter0;
135        dp[3] = pars->func_inter0;
[0164899a]136        dp[4] = pars->sld_bottom0;
[35aface]137        dp[5] = pars->sld_medium;
138        dp[6] = pars->background;
139
140        dp[7] = pars->sld_flat1;
141        dp[8] = pars->sld_flat2;
142        dp[9] = pars->sld_flat3;
143        dp[10] = pars->sld_flat4;
144        dp[11] = pars->sld_flat5;
145        dp[12] = pars->sld_flat6;
146        dp[13] = pars->sld_flat7;
147        dp[14] = pars->sld_flat8;
148        dp[15] = pars->sld_flat9;
149        dp[16] = pars->sld_flat10;
150
151        dp[17] = pars->thick_inter1;
152        dp[18] = pars->thick_inter2;
153        dp[19] = pars->thick_inter3;
154        dp[20] = pars->thick_inter4;
155        dp[21] = pars->thick_inter5;
156        dp[22] = pars->thick_inter6;
157        dp[23] = pars->thick_inter7;
158        dp[24] = pars->thick_inter8;
159        dp[25] = pars->thick_inter9;
160        dp[26] = pars->thick_inter10;
161
162        dp[27] = pars->thick_flat1;
163        dp[28] = pars->thick_flat2;
164        dp[29] = pars->thick_flat3;
165        dp[30] = pars->thick_flat4;
166        dp[31] = pars->thick_flat5;
167        dp[32] = pars->thick_flat6;
168        dp[33] = pars->thick_flat7;
169        dp[34] = pars->thick_flat8;
170        dp[35] = pars->thick_flat9;
171        dp[36] = pars->thick_flat10;
172
173        dp[37] = pars->func_inter1;
174        dp[38] = pars->func_inter2;
175        dp[39] = pars->func_inter3;
176        dp[40] = pars->func_inter4;
177        dp[41] = pars->func_inter5;
178        dp[42] = pars->func_inter6;
179        dp[43] = pars->func_inter7;
180        dp[44] = pars->func_inter8;
181        dp[45] = pars->func_inter9;
182        dp[46] = pars->func_inter10;
183
184        return re_kernel(dp, q);
185}
186
187/**
[0164899a]188 * Function to evaluate NR function
189 * @param pars: parameters of NR
[35aface]190 * @param q: q-value
191 * @return: function value
192 */
193double refl_analytical_2D(ReflParameters *pars, double q, double phi) {
194        return refl_analytical_1D(pars,q);
195}
196
197double refl_analytical_2DXY(ReflParameters *pars, double qx, double qy){
198        return refl_analytical_1D(pars,sqrt(qx*qx+qy*qy));
199}
Note: See TracBrowser for help on using the repository browser.