source: sasmodels/sasmodels/models/spherical_sld.c @ 1bf66d9

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

Spherical SLD model doesn't crash but still some work needs to be done

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