source: sasmodels/sasmodels/models/spherical_sld.c @ a7c2cfe

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

Bug fixes in spherical sld model

  • Property mode set to 100644
File size: 6.6 KB
Line 
1static double form_volume(
2    int n_shells,
3    double radius_core,
4    double thick_flat[],
5    double thick_inter[])
6{
7    double radius = 0.0;
8    int i;
9    double r = radius_core;
10    for (i=0; i < n_shells; i++) {
11        r += thick_inter[i];
12        r += thick_flat[i];
13    }
14    return M_4PI_3*cube(r);
15}
16
17
18static double sphere_sld_kernel(double dp[], double q) {
19  int n = dp[0];
20  int i,j,k;
21
22  double scale = dp[1];
23  double thick_inter_core = dp[2];
24  double sld_core = dp[4];
25  double sld_solv = dp[5];
26  double background = dp[6];
27  double npts = dp[57]; //number of sub_layers in each interface
28  double nsl=npts;//21.0; //nsl = Num_sub_layer:  must be ODD double number
29  int n_s;
30
31  double sld_i,sld_f,dz,bes,fun,f,vol,qr,r,contr,f2;
32  double sign,slope=0.0;
33  double pi;
34
35  double total_thick=0.0;
36
37  int fun_type[12];
38  double sld[12];
39  double thick_inter[12];
40  double thick[12];
41  double fun_coef[12];
42
43  fun_type[0] = dp[3];
44  fun_coef[0] = fabs(dp[58]);
45  for (i =1; i<=n; i++){
46    sld[i] = dp[i+6];
47    thick_inter[i]= dp[i+16];
48    thick[i] = dp[i+26];
49    fun_type[i] = dp[i+36];
50    fun_coef[i] = fabs(dp[i+46]);
51    total_thick += thick[i];
52    total_thick += thick_inter[i];
53  }
54  sld[0] = sld_core;
55  sld[n+1] = sld_solv;
56  thick[0] = dp[59];
57  thick[n+1] = total_thick/5.0;
58  thick_inter[0] = thick_inter_core;
59  thick_inter[n+1] = 0.0;
60  fun_coef[n+1] = 0.0;
61  pi = 4.0*atan(1.0);
62  f = 0.0;
63  r = 0.0;
64  vol = 0.0;
65  //vol_pre = 0.0;
66  //vol_sub = 0.0;
67  sld_f = sld_core;
68
69  //floor_nsl = floor(nsl/2.0);
70
71  dz = 0.0;
72  // iteration for # of shells + core + solvent
73  for (i=0;i<=n+1; i++){
74    //iteration for N sub-layers
75    //if (fabs(thick[i]) <= 1e-24){
76    //   continue;
77    //}
78    // iteration for flat and interface
79    for (j=0;j<2;j++){
80      // iteration for sub_shells in the interface
81      // starts from #1 sub-layer
82      for (n_s=1;n_s<=nsl; n_s++){
83        // for solvent, it doesn't have an interface
84        if (i==n+1 && j==1)
85          break;
86        // for flat layers
87        if (j==0){
88          dz = thick[i];
89          sld_i = sld[i];
90          slope = 0.0;
91        }
92        // for interfacial sub_shells
93        else{
94          dz = thick_inter[i]/nsl;
95          // find sld_i at the outer boundary of sub-layer #n_s
96          sld_i = intersldfunc(fun_type[i],nsl, n_s, fun_coef[i], sld[i], sld[i+1]);
97          // calculate slope
98          slope= (sld_i -sld_f)/dz;
99        }
100        contr = sld_f-slope*r;
101        // iteration for the left and right boundary of the shells(or sub_shells)
102        for (k=0; k<2; k++){
103          // At r=0, the contribution to I is zero, so skip it.
104          if ( i == 0 && j == 0 && k == 0){
105            continue;
106          }
107          // On the top of slovent there is no interface; skip it.
108          if (i == n+1 && k == 1){
109            continue;
110          }
111          // At the right side (outer) boundary
112          if ( k == 1){
113            sign = 1.0;
114            r += dz;
115          }
116          // At the left side (inner) boundary
117          else{
118            sign = -1.0;
119          }
120          qr = q * r;
121          fun = 0.0;
122
123          if(qr == 0.0){
124            // sigular point
125            bes = sign * 1.0;
126          }
127          else{
128            // for flat sub-layer
129            //TODO: Single precision calculation most likely fails here
130            //bes = sign *  3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr);
131            bes = sign *  sph_j1c(qr);
132            if (fabs(slope) > 0.0 ){
133              //fun = sign * 3.0 * r * (2.0*qr*sin(qr)-((qr*qr)-2.0)*cos(qr))/(qr * qr * qr * qr);
134              fun = sign * r * sph_j1c(qr) + sign * 3.0 * sin(qr)/(qr * qr * q )
135                + sign * 6.0 * cos(qr)/(qr * qr * qr * q);
136            }
137          }
138
139          //Some initial optimization tries
140          /*bes = (qr == 0.0 ? sign * 1.0 : sign *  3.0 * (sin(qr) - qr * cos(qr)) / (qr * qr * qr));
141          //TODO: Will have to chnage this function
142          if (qr!= 0.0 && fabs(slope) > 0.0 ){
143            fun = sign * 3.0 * r * (2.0*qr*sin(qr)-((qr*qr)-2.0)*cos(qr))/(qr * qr * qr * qr);
144          }*/
145
146          // update total volume
147          vol = 4.0 * pi / 3.0 * r * r * r;
148          // we won't do the following volume correction for now.
149          // substrate empty area of volume
150          //if (k == 1 && fabs(sld_in[i]-sld_solv) < 1e-04*fabs(sld_solv) && fun_type[i]==0){
151          //  vol_sub += (vol_pre - vol);
152          //}
153          f += vol * (bes * contr + fun * slope);
154        }
155        // remember this sld as sld_f
156        sld_f = sld_i;
157        // no sub-layer iteration (n_s loop) for the flat layer
158        if (j==0)
159          break;
160      }
161    }
162  }
163  f2 = f * f / vol;
164
165  return (f2);
166}
167
168
169/**
170 * Function to evaluate 1D SphereSLD function
171 * @param q: q-value
172 * @return: function value
173 */
174static double Iq(double q,
175    int n_shells,
176    int npts_inter,
177    double radius_core,
178    double sld_core,
179    double sld_solvent,
180    double sld_flat[],
181    double thick_flat[],
182    double func_inter[],
183    double thick_inter[],
184    double nu_inter[] ) {
185
186    //printf("Number of points %d\n",npts_inter);
187    double intensity;
188    //TODO: Remove this container at later stage.
189    double dp[60];
190    dp[0] = n_shells;
191    //This is scale will also have to be removed at some stage
192    dp[1] = 1.0;
193    dp[2] = thick_inter[0];
194    dp[3] = func_inter[0];
195    dp[4] = sld_core;
196    dp[5] = sld_solvent;
197    dp[6] = 0.0;
198
199    for (int i=1; i<n_shells; i++){
200        dp[i+7] = sld_flat[i];
201        dp[i+17] = thick_inter[i];
202        dp[i+27] = thick_flat[i];
203        dp[i+37] = func_inter[i];
204        dp[i+47] = nu_inter[i];
205    }
206
207    dp[57] = npts_inter;
208    dp[58] = nu_inter[0];
209    dp[59] = radius_core;
210
211    intensity = 1.0e-4*sphere_sld_kernel(dp,q);
212    //printf("%10d\n",intensity);
213    return intensity;
214}
215
216/**
217 * Function to evaluate 2D SphereSLD function
218 * @param q_x: value of Q along x
219 * @param q_y: value of Q along y
220 * @return: function value
221 */
222
223/*static double Iqxy(double qx, double qy,
224    int n_shells,
225    int npts_inter,
226    double radius_core
227    double sld_core,
228    double sld_solvent,
229    double sld_flat[],
230    double thick_flat[],
231    double func_inter[],
232    double thick_inter[],
233    double nu_inter[],
234    ) {
235
236    double q = sqrt(qx*qx + qy*qy);
237    return Iq(q, n_shells, npts_inter, radius_core, sld_core, sld_solvent,
238    sld_flat[], thick_flat[], func_inter[], thick_inter[], nu_inter[])
239}*/
240
Note: See TracBrowser for help on using the repository browser.