Ignore:
Timestamp:
Nov 1, 2010 4:22:12 PM (14 years ago)
Author:
Jae Cho <jhjcho@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
4b3d25b
Parents:
6cda91f
Message:

new models and some bug fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/sans/models/c_extensions/refl.c

    r339ce67 r0164899a  
    11/** 
    2  * Scattering model for a sphere 
     2 *  model for NR 
    33 */ 
    4  
     4// The original code, of which work was not DANSE funded, 
     5// was provided by J. Cho. 
    56#include <math.h> 
    67#include "refl.h" 
     8#include "libmultifunc/librefl.h" 
    79#include <stdio.h> 
    810#include <stdlib.h> 
     
    1012#define lamda 4.62 
    1113 
    12 typedef struct { 
    13         double re; 
    14         double im; 
    15 } complex; 
    16  
    17 typedef struct { 
    18         complex a; 
    19         complex b; 
    20         complex c; 
    21         complex d; 
    22 } matrix; 
    23  
    24 complex cassign(real, imag) 
    25         double real, imag; 
    26 { 
    27         complex x; 
    28         x.re = real; 
    29         x.im = imag; 
    30         return x; 
    31 } 
    32  
    33  
    34 complex cadd(x,y) 
    35         complex x,y; 
    36 { 
    37         complex z; 
    38         z.re = x.re + y.re; 
    39         z.im = x.im + y.im; 
    40         return z; 
    41 } 
    42  
    43 complex rcmult(x,y) 
    44         double x; 
    45     complex y; 
    46 { 
    47         complex z; 
    48         z.re = x*y.re; 
    49         z.im = x*y.im; 
    50         return z; 
    51 } 
    52  
    53 complex csub(x,y) 
    54         complex x,y; 
    55 { 
    56         complex z; 
    57         z.re = x.re - y.re; 
    58         z.im = x.im - y.im; 
    59         return z; 
    60 } 
    61  
    62  
    63 complex cmult(x,y) 
    64         complex x,y; 
    65 { 
    66         complex z; 
    67         z.re = x.re*y.re - x.im*y.im; 
    68         z.im = x.re*y.im + x.im*y.re; 
    69         return z; 
    70 } 
    71  
    72 complex cdiv(x,y) 
    73         complex x,y; 
    74 { 
    75         complex z; 
    76         z.re = (x.re*y.re + x.im*y.im)/(y.re*y.re + y.im*y.im); 
    77         z.im = (x.im*y.re - x.re*y.im)/(y.re*y.re + y.im*y.im); 
    78         return z; 
    79 } 
    80  
    81 complex cexp(b) 
    82         complex b; 
    83 { 
    84         complex z; 
    85         double br,bi; 
    86         br=b.re; 
    87         bi=b.im; 
    88         z.re = exp(br)*cos(bi); 
    89         z.im = exp(br)*sin(bi); 
    90         return z; 
    91 } 
    92  
    93  
    94 complex csqrt(z)   /* see Schaum`s Math Handbook p. 22, 6.6 and 6.10 */ 
    95         complex z; 
    96 { 
    97         complex c; 
    98         double zr,zi,x,y,r,w; 
    99  
    100         zr=z.re; 
    101         zi=z.im; 
    102  
    103         if (zr==0.0 && zi==0.0) 
    104         { 
    105     c.re=0.0; 
    106         c.im=0.0; 
    107     return c; 
    108         } 
    109         else 
    110         { 
    111                 x=fabs(zr); 
    112                 y=fabs(zi); 
    113                 if (x>y) 
    114                 { 
    115                         r=y/x; 
    116                         w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r))); 
    117                 } 
    118                 else 
    119                 { 
    120                         r=x/y; 
    121                         w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r))); 
    122                 } 
    123                 if (zr >=0.0) 
    124                 { 
    125                         c.re=w; 
    126                         c.im=zi/(2.0*w); 
    127                 } 
    128                 else 
    129                 { 
    130                         c.im=(zi >= 0) ? w : -w; 
    131                         c.re=zi/(2.0*c.im); 
    132                 } 
    133                 return c; 
    134         } 
    135 } 
    136  
    137 complex ccos(b) 
    138         complex b; 
    139 { 
    140         complex neg,negb,zero,two,z,i,bi,negbi; 
    141         zero = cassign(0.0,0.0); 
    142         two = cassign(2.0,0.0); 
    143         i = cassign(0.0,1.0); 
    144         bi = cmult(b,i); 
    145         negbi = csub(zero,bi); 
    146         z = cdiv(cadd(cexp(bi),cexp(negbi)),two); 
    147         return z; 
    148 } 
    149  
    150 double errfunc(n_sub, i) 
    151         double n_sub; 
    152         int i; 
    153 { 
    154         double bin_size, ind, func; 
    155         ind = i; 
    156         // i range = [ -4..4], x range = [ -2.5..2.5] 
    157         bin_size = n_sub/2.0/2.5;  //size of each sub-layer 
    158         // rescale erf so that 0 < erf < 1 in -2.5 <= x <= 2.5 
    159         func = (erf(ind/bin_size)/2.0+0.5); 
    160         return func; 
    161 } 
    162  
    163 double linefunc(n_sub, i) 
    164         double n_sub; 
    165         int i; 
    166 { 
    167         double bin_size, ind, func; 
    168         ind = i + 0.5; 
    169         // i range = [ -4..4], x range = [ -2.5..2.5] 
    170         bin_size = 1.0/n_sub;  //size of each sub-layer 
    171         // rescale erf so that 0 < erf < 1 in -2.5 <= x <= 2.5 
    172         func = ((ind + floor(n_sub/2.0))*bin_size); 
    173         return func; 
    174 } 
    175  
    176 double parabolic_r(n_sub, i) 
    177         double n_sub; 
    178         int i; 
    179 { 
    180         double bin_size, ind, func; 
    181         ind = i + 0.5; 
    182         // i range = [ -4..4], x range = [ 0..1] 
    183         bin_size = 1.0/n_sub;  //size of each sub-layer; n_sub = 0 is a singular point (error) 
    184         func = ((ind + floor(n_sub/2.0))*bin_size)*((ind + floor(n_sub/2.0))*bin_size); 
    185         return func; 
    186 } 
    187  
    188 double parabolic_l(n_sub, i) 
    189         double n_sub; 
    190         int i; 
    191 { 
    192         double bin_size,ind, func; 
    193         ind = i + 0.5; 
    194         bin_size = 1.0/n_sub;  //size of each sub-layer; n_sub = 0 is a singular point (error) 
    195         func =1.0-(((ind + floor(n_sub/2.0))*bin_size) - 1.0) *(((ind + floor(n_sub/2.0))*bin_size) - 1.0); 
    196         return func; 
    197 } 
    198  
    199 double cubic_r(n_sub, i) 
    200         double n_sub; 
    201         int i; 
    202 { 
    203         double bin_size,ind, func; 
    204         ind = i + 0.5; 
    205         // i range = [ -4..4], x range = [ 0..1] 
    206         bin_size = 1.0/n_sub;  //size of each sub-layer; n_sub = 0 is a singular point (error) 
    207         func = ((ind+ floor(n_sub/2.0))*bin_size)*((ind + floor(n_sub/2.0))*bin_size)*((ind + floor(n_sub/2.0))*bin_size); 
    208         return func; 
    209 } 
    210  
    211 double cubic_l(n_sub, i) 
    212         double n_sub; 
    213         int i; 
    214 { 
    215         double bin_size,ind, func; 
    216         ind = i + 0.5; 
    217         bin_size = 1.0/n_sub;  //size of each sub-layer; n_sub = 0 is a singular point (error) 
    218         func = 1.0+(((ind + floor(n_sub/2.0)))*bin_size - 1.0)*(((ind + floor(n_sub/2.0)))*bin_size - 1.0)*(((ind + floor(n_sub/2.0)))*bin_size - 1.0); 
    219         return func; 
    220 } 
    221  
    222 double interfunc(fun_type, n_sub, i, sld_l, sld_r) 
    223         double n_sub, sld_l, sld_r; 
    224         int fun_type, i; 
    225 { 
    226         double sld_i, func; 
    227         switch(fun_type){ 
    228                 case 1 : 
    229                         func = linefunc(n_sub, i); 
    230                         break; 
    231                 case 2 : 
    232                         func = parabolic_r(n_sub, i); 
    233                         break; 
    234                 case 3 : 
    235                         func = parabolic_l(n_sub, i); 
    236                         break; 
    237                 case 4 : 
    238                         func = cubic_r(n_sub, i); 
    239                         break; 
    240                 case 5 : 
    241                         func = cubic_l(n_sub, i); 
    242                         break; 
    243                 default: 
    244                         func = errfunc(n_sub, i); 
    245                         break; 
    246         } 
    247         if (sld_r>sld_l){ 
    248                 sld_i = (sld_r-sld_l)*func+sld_l; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick); 
    249         } 
    250         else if (sld_r<sld_l){ 
    251                 func = 1.0-func; 
    252                 sld_i = (sld_l-sld_r)*func+sld_r; //sld_cal(sld[i],sld[i+1],n_sub,dz,thick); 
    253         } 
    254         else{ 
    255                 sld_i = sld_r; 
    256         } 
    257         return sld_i; 
    258 } 
    25914 
    26015double re_kernel(double dp[], double q) { 
     
    26823        double background = dp[6]; 
    26924 
    270         double sld[n+2],sld_im[n+2],thick_inter[n+2],thick[n+2],total_thick; 
     25        double sld[n+2],thick_inter[n+2],thick[n+2],total_thick; 
    27126        fun_type[0] = dp[3]; 
    27227        for (i =1; i<=n; i++){ 
     
    27530                thick[i] = dp[i+26]; 
    27631                fun_type[i] = dp[i+36]; 
    277                 sld_im[i] = dp[i+46]; 
    278  
    27932                total_thick += thick[i] + thick_inter[i]; 
    28033        } 
    28134        sld[0] = sld_sub; 
    28235        sld[n+1] = sld_super; 
    283         sld_im[0] = fabs(dp[0+56]); 
    284         sld_im[n+1] = fabs(dp[1+56]); 
     36 
    28537        thick[0] = total_thick/5.0; 
    28638        thick[n+1] = total_thick/5.0; 
     
    28840        thick_inter[n+1] = 0.0; 
    28941 
    290         double nsl=21.0; //nsl = Num_sub_layer:  MUST ODD number in double //no other number works now 
    291         int n_s, floor_nsl; 
     42        double nsl=21.0; //nsl = Num_sub_layer: 
     43        int n_s; 
    29244    double sld_i,sldim_i,dz,phi,R,ko2; 
    293     double sign,erfunc; 
     45    double sign,erfunc, fun; 
    29446    double pi; 
    29547        complex  inv_n,phi1,alpha,alpha2,kn,fnm,fnp,rn,Xn,nn,nn2,an,nnp1,one,zero,two,n_sub,n_sup,knp1,Xnp1; 
     
    29951        two= cassign(0.0,-2.0); 
    30052 
    301         floor_nsl = floor(nsl/2.0); 
    302  
    30353        //Checking if floor is available. 
    30454        //no imaginary sld inputs in this function yet 
    305     n_sub=cassign(1.0-sld_sub*pow(lamda,2.0)/(2.0*pi),pow(lamda,2.0)/(2.0*pi)*sld_im[0]); 
    306     n_sup=cassign(1.0-sld_super*pow(lamda,2.0)/(2.0*pi),pow(lamda,2.0)/(2.0*pi)*sld_im[n+1]); 
     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); 
    30757    ko2 = pow(2.0*pi/lamda,2.0); 
    30858 
     
    31868    // iteration for # of layers +sub from the top 
    31969    for (i=1;i<=n+1; i++){ 
     70        if (fun_type[i-1]==1) 
     71                fun = 5; 
     72        else 
     73                        fun = 0; 
    32074                //iteration for 9 sub-layers 
    32175                for (j=0;j<2;j++){ 
    322                         for (n_s=-floor_nsl;n_s<=floor_nsl; n_s++){ 
     76                        for (n_s=0;n_s<nsl; n_s++){ 
    32377                                if (j==1){ 
    32478                                        if (i==n+1) 
     
    32680                                        dz = thick[i]; 
    32781                                        sld_i = sld[i]; 
    328                                         sldim_i = sld_im[i]; 
    32982                                } 
    33083                                else{ 
    331                                         dz = thick_inter[i-1]/nsl; 
     84                                        dz = thick_inter[i-1]/nsl;//nsl; 
    33285                                        if (sld[i-1] == sld[i]){ 
    33386                                                sld_i = sld[i]; 
    33487                                        } 
    33588                                        else{ 
    336                                                 sld_i = interfunc(fun_type[i-1],nsl, n_s, sld[i-1], sld[i]); 
    337                                         } 
    338                                         if (sld_im[i-1] == sld_im[i]){ 
    339                                                 sldim_i = sld_im[i]; 
    340                                         } 
    341                                         else{ 
    342                                                 sldim_i = interfunc(fun_type[i-1],nsl, n_s, sld_im[i-1], sld_im[i]); 
     89                                                sld_i = intersldfunc(fun,nsl, n_s+0.5, 2.5, sld[i-1], sld[i]); 
    34390                                        } 
    34491                                } 
    345                                 nn = cassign(1.0-sld_i*pow(lamda,2.0)/(2.0*pi),pow(lamda,2.0)/(2.0*pi)*sldim_i); 
     92                                nn = cassign(1.0-sld_i*pow(lamda,2.0)/(2.0*pi),0.0); 
    34693                                nn2=cmult(nn,nn); 
    34794 
     
    375122} 
    376123/** 
    377  * Function to evaluate 1D scattering function 
    378  * @param pars: parameters of the sphere 
     124 * Function to evaluate NR function 
     125 * @param pars: parameters 
    379126 * @param q: q-value 
    380127 * @return: function value 
    381128 */ 
    382129double refl_analytical_1D(ReflParameters *pars, double q) { 
    383         double dp[59]; 
     130        double dp[47]; 
    384131 
    385132        dp[0] = pars->n_layers; 
     
    387134        dp[2] = pars->thick_inter0; 
    388135        dp[3] = pars->func_inter0; 
    389         dp[4] = pars->sld_sub0; 
     136        dp[4] = pars->sld_bottom0; 
    390137        dp[5] = pars->sld_medium; 
    391138        dp[6] = pars->background; 
     
    435182        dp[46] = pars->func_inter10; 
    436183 
    437         dp[47] = pars->sldIM_flat1; 
    438         dp[48] = pars->sldIM_flat2; 
    439         dp[49] = pars->sldIM_flat3; 
    440         dp[50] = pars->sldIM_flat4; 
    441         dp[51] = pars->sldIM_flat5; 
    442         dp[52] = pars->sldIM_flat6; 
    443         dp[53] = pars->sldIM_flat7; 
    444         dp[54] = pars->sldIM_flat8; 
    445         dp[55] = pars->sldIM_flat9; 
    446         dp[56] = pars->sldIM_flat10; 
    447  
    448         dp[57] = pars->sldIM_sub0; 
    449         dp[58] = pars->sldIM_medium; 
    450  
    451184        return re_kernel(dp, q); 
    452185} 
    453186 
    454187/** 
    455  * Function to evaluate 2D scattering function 
    456  * @param pars: parameters of the sphere 
     188 * Function to evaluate NR function 
     189 * @param pars: parameters of NR 
    457190 * @param q: q-value 
    458191 * @return: function value 
Note: See TracChangeset for help on using the changeset viewer.