source: sasview/sansmodels/src/libigor/libCylinder.c @ 6534d4d

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 6534d4d was 96b59384, checked in by Jae Cho <jhjcho@…>, 15 years ago

added 2D and model descpt.

  • Property mode set to 100644
File size: 54.5 KB
RevLine 
[ae3ce4e]1/*      CylinderFit.c
2
3A simplified project designed to act as a template for your curve fitting function.
4The fitting function is a Cylinder form factor. No resolution effects are included (yet)
5*/
6
7#include "StandardHeaders.h"                    // Include ANSI headers, Mac headers
8#include "GaussWeights.h"
9#include "libCylinder.h"
10/*      CylinderForm  :  calculates the form factor of a cylinder at the give x-value p->x
11
12Warning:
13The call to WaveData() below returns a pointer to the middle
14of an unlocked Macintosh handle. In the unlikely event that your
15calculations could cause memory to move, you should copy the coefficient
16values to local variables or an array before such operations.
17*/
18double
19CylinderForm(double dp[], double q)
20{
21        int i;
22        double Pi;
23        double scale,radius,length,delrho,bkg,halfheight;               //local variables of coefficient wave
24        int nord=76;                    //order of integration
25        double uplim,lolim;             //upper and lower integration limits
26        double summ,zi,yyy,answer,vcyl;                 //running tally of integration
[8e91f01]27
[ae3ce4e]28        Pi = 4.0*atan(1.0);
29        lolim = 0;
30        uplim = Pi/2.0;
[8e91f01]31
[ae3ce4e]32        summ = 0.0;                     //initialize intergral
[8e91f01]33
[ae3ce4e]34        scale = dp[0];                  //make local copies in case memory moves
35        radius = dp[1];
36        length = dp[2];
37        delrho = dp[3];
38        bkg = dp[4];
39        halfheight = length/2.0;
40        for(i=0;i<nord;i++) {
41                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
42                yyy = Gauss76Wt[i] * CylKernel(q, radius, halfheight, zi);
43                summ += yyy;
44        }
[8e91f01]45
[ae3ce4e]46        answer = (uplim-lolim)/2.0*summ;
47        // Multiply by contrast^2
48        answer *= delrho*delrho;
49        //normalize by cylinder volume
50        //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
51        vcyl=Pi*radius*radius*length;
52        answer *= vcyl;
53        //convert to [cm-1]
54        answer *= 1.0e8;
55        //Scale
56        answer *= scale;
57        // add in the background
58        answer += bkg;
[8e91f01]59
[ae3ce4e]60        return answer;
61}
62
63/*      EllipCyl76X  :  calculates the form factor of a elliptical cylinder at the given x-value p->x
64
65Uses 76 pt Gaussian quadrature for both integrals
66
67Warning:
68The call to WaveData() below returns a pointer to the middle
69of an unlocked Macintosh handle. In the unlikely event that your
70calculations could cause memory to move, you should copy the coefficient
71values to local variables or an array before such operations.
72*/
73double
74EllipCyl76(double dp[], double q)
75{
76        int i,j;
77        double Pi;
78        double scale,ra,nu,length,delrho,bkg;           //local variables of coefficient wave
79        int nord=76;                    //order of integration
80        double va,vb;           //upper and lower integration limits
81        double summ,zi,yyy,answer,vell;                 //running tally of integration
82        double summj,vaj,vbj,zij,arg;                   //for the inner integration
[8e91f01]83
[ae3ce4e]84        Pi = 4.0*atan(1.0);
85        va = 0;
86        vb = 1;         //orintational average, outer integral
87        vaj=0;
88        vbj=Pi;         //endpoints of inner integral
[8e91f01]89
[ae3ce4e]90        summ = 0.0;                     //initialize intergral
[8e91f01]91
[ae3ce4e]92        scale = dp[0];                  //make local copies in case memory moves
93        ra = dp[1];
94        nu = dp[2];
95        length = dp[3];
96        delrho = dp[4];
97        bkg = dp[5];
98        for(i=0;i<nord;i++) {
99                //setup inner integral over the ellipsoidal cross-section
100                summj=0;
101                zi = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0;             //the "x" dummy
102                arg = ra*sqrt(1-zi*zi);
103                for(j=0;j<nord;j++) {
104                        //76 gauss points for the inner integral as well
105                        zij = ( Gauss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0;                //the "y" dummy
106                        yyy = Gauss76Wt[j] * EllipCylKernel(q,arg,nu,zij);
107                        summj += yyy;
108                }
109                //now calculate the value of the inner integral
110                answer = (vbj-vaj)/2.0*summj;
111                //divide integral by Pi
112                answer /=Pi;
[8e91f01]113
[ae3ce4e]114                //now calculate outer integral
115                arg = q*length*zi/2;
116                yyy = Gauss76Wt[i] * answer * sin(arg) * sin(arg) / arg / arg;
117                summ += yyy;
118        }
119        answer = (vb-va)/2.0*summ;
120        // Multiply by contrast^2
121        answer *= delrho*delrho;
122        //normalize by cylinder volume
123        //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
124        vell = Pi*ra*(nu*ra)*length;
125        answer *= vell;
126        //convert to [cm-1]
127        answer *= 1.0e8;
128        //Scale
129        answer *= scale;
130        // add in the background
131        answer += bkg;
[8e91f01]132
[ae3ce4e]133        return answer;
134}
135
136/*      EllipCyl20X  :  calculates the form factor of a elliptical cylinder at the given x-value p->x
137
138Uses 76 pt Gaussian quadrature for orientational integral
139Uses 20 pt quadrature for the inner integral over the elliptical cross-section
140
141Warning:
142The call to WaveData() below returns a pointer to the middle
143of an unlocked Macintosh handle. In the unlikely event that your
144calculations could cause memory to move, you should copy the coefficient
145values to local variables or an array before such operations.
146*/
147double
148EllipCyl20(double dp[], double q)
149{
150        int i,j;
151        double Pi;
152        double scale,ra,nu,length,delrho,bkg;           //local variables of coefficient wave
153        int nordi=76;                   //order of integration
154        int nordj=20;
155        double va,vb;           //upper and lower integration limits
156        double summ,zi,yyy,answer,vell;                 //running tally of integration
157        double summj,vaj,vbj,zij,arg;                   //for the inner integration
[8e91f01]158
[ae3ce4e]159        Pi = 4.0*atan(1.0);
160        va = 0;
161        vb = 1;         //orintational average, outer integral
162        vaj=0;
163        vbj=Pi;         //endpoints of inner integral
[8e91f01]164
[ae3ce4e]165        summ = 0.0;                     //initialize intergral
[8e91f01]166
[ae3ce4e]167        scale = dp[0];                  //make local copies in case memory moves
168        ra = dp[1];
169        nu = dp[2];
170        length = dp[3];
171        delrho = dp[4];
172        bkg = dp[5];
173        for(i=0;i<nordi;i++) {
174                //setup inner integral over the ellipsoidal cross-section
175                summj=0;
176                zi = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0;             //the "x" dummy
177                arg = ra*sqrt(1-zi*zi);
178                for(j=0;j<nordj;j++) {
179                        //20 gauss points for the inner integral
180                        zij = ( Gauss20Z[j]*(vbj-vaj) + vaj + vbj )/2.0;                //the "y" dummy
181                        yyy = Gauss20Wt[j] * EllipCylKernel(q,arg,nu,zij);
182                        summj += yyy;
183                }
184                //now calculate the value of the inner integral
185                answer = (vbj-vaj)/2.0*summj;
186                //divide integral by Pi
187                answer /=Pi;
[8e91f01]188
[ae3ce4e]189                //now calculate outer integral
190                arg = q*length*zi/2;
191                yyy = Gauss76Wt[i] * answer * sin(arg) * sin(arg) / arg / arg;
192                summ += yyy;
193        }
[8e91f01]194
[ae3ce4e]195        answer = (vb-va)/2.0*summ;
196        // Multiply by contrast^2
197        answer *= delrho*delrho;
198        //normalize by cylinder volume
199        //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
200        vell = Pi*ra*(nu*ra)*length;
201        answer *= vell;
202        //convert to [cm-1]
203        answer *= 1.0e8;
204        //Scale
205        answer *= scale;
206        // add in the background
[8e91f01]207        answer += bkg;
208
[ae3ce4e]209        return answer;
210}
211
212/*      TriaxialEllipsoidX  :  calculates the form factor of a Triaxial Ellipsoid at the given x-value p->x
213
214Uses 76 pt Gaussian quadrature for both integrals
215
216Warning:
217The call to WaveData() below returns a pointer to the middle
218of an unlocked Macintosh handle. In the unlikely event that your
219calculations could cause memory to move, you should copy the coefficient
220values to local variables or an array before such operations.
221*/
222double
223TriaxialEllipsoid(double dp[], double q)
224{
225        int i,j;
226        double Pi;
227        double scale,aa,bb,cc,delrho,bkg;               //local variables of coefficient wave
228        int nordi=76;                   //order of integration
229        int nordj=76;
230        double va,vb;           //upper and lower integration limits
231        double summ,zi,yyy,answer;                      //running tally of integration
232        double summj,vaj,vbj,zij;                       //for the inner integration
[8e91f01]233
[ae3ce4e]234        Pi = 4.0*atan(1.0);
235        va = 0;
236        vb = 1;         //orintational average, outer integral
237        vaj = 0;
238        vbj = 1;                //endpoints of inner integral
[8e91f01]239
[ae3ce4e]240        summ = 0.0;                     //initialize intergral
[8e91f01]241
[ae3ce4e]242        scale = dp[0];                  //make local copies in case memory moves
243        aa = dp[1];
244        bb = dp[2];
245        cc = dp[3];
246        delrho = dp[4];
247        bkg = dp[5];
248        for(i=0;i<nordi;i++) {
249                //setup inner integral over the ellipsoidal cross-section
250                summj=0;
251                zi = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0;             //the "x" dummy
252                for(j=0;j<nordj;j++) {
253                        //20 gauss points for the inner integral
254                        zij = ( Gauss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0;                //the "y" dummy
255                        yyy = Gauss76Wt[j] * TriaxialKernel(q,aa,bb,cc,zi,zij);
256                        summj += yyy;
257                }
258                //now calculate the value of the inner integral
259                answer = (vbj-vaj)/2.0*summj;
[8e91f01]260
[ae3ce4e]261                //now calculate outer integral
262                yyy = Gauss76Wt[i] * answer;
263                summ += yyy;
264        }               //final scaling is done at the end of the function, after the NT_FP64 case
[8e91f01]265
[ae3ce4e]266        answer = (vb-va)/2.0*summ;
267        // Multiply by contrast^2
268        answer *= delrho*delrho;
269        //normalize by ellipsoid volume
270        answer *= 4*Pi/3*aa*bb*cc;
271        //convert to [cm-1]
272        answer *= 1.0e8;
273        //Scale
274        answer *= scale;
275        // add in the background
276        answer += bkg;
[8e91f01]277
[ae3ce4e]278        return answer;
279}
280
281/*      ParallelepipedX  :  calculates the form factor of a Parallelepiped (a rectangular solid)
282at the given x-value p->x
283
284Uses 76 pt Gaussian quadrature for both integrals
285
286Warning:
287The call to WaveData() below returns a pointer to the middle
288of an unlocked Macintosh handle. In the unlikely event that your
289calculations could cause memory to move, you should copy the coefficient
290values to local variables or an array before such operations.
291*/
292double
293Parallelepiped(double dp[], double q)
294{
295        int i,j;
296        double scale,aa,bb,cc,delrho,bkg;               //local variables of coefficient wave
297        int nordi=76;                   //order of integration
298        int nordj=76;
299        double va,vb;           //upper and lower integration limits
300        double summ,yyy,answer;                 //running tally of integration
301        double summj,vaj,vbj;                   //for the inner integration
302        double mu,mudum,arg,sigma,uu,vol;
[8e91f01]303
304
[ae3ce4e]305        //      Pi = 4.0*atan(1.0);
306        va = 0;
307        vb = 1;         //orintational average, outer integral
308        vaj = 0;
309        vbj = 1;                //endpoints of inner integral
[8e91f01]310
[ae3ce4e]311        summ = 0.0;                     //initialize intergral
[8e91f01]312
[ae3ce4e]313        scale = dp[0];                  //make local copies in case memory moves
314        aa = dp[1];
315        bb = dp[2];
316        cc = dp[3];
317        delrho = dp[4];
318        bkg = dp[5];
[8e91f01]319
[ae3ce4e]320        mu = q*bb;
321        vol = aa*bb*cc;
322        // normalize all WRT bb
323        aa = aa/bb;
324        cc = cc/bb;
[8e91f01]325
[ae3ce4e]326        for(i=0;i<nordi;i++) {
327                //setup inner integral over the ellipsoidal cross-section
328                summj=0;
329                sigma = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0;          //the outer dummy
[8e91f01]330
[ae3ce4e]331                for(j=0;j<nordj;j++) {
332                        //76 gauss points for the inner integral
333                        uu = ( Gauss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0;         //the inner dummy
334                        mudum = mu*sqrt(1-sigma*sigma);
335                        yyy = Gauss76Wt[j] * PPKernel(aa,mudum,uu);
336                        summj += yyy;
337                }
338                //now calculate the value of the inner integral
339                answer = (vbj-vaj)/2.0*summj;
[8e91f01]340
[ae3ce4e]341                arg = mu*cc*sigma/2;
342                if ( arg == 0 ) {
343                        answer *= 1;
344                } else {
345                        answer *= sin(arg)*sin(arg)/arg/arg;
346                }
[8e91f01]347
[ae3ce4e]348                //now sum up the outer integral
349                yyy = Gauss76Wt[i] * answer;
350                summ += yyy;
351        }               //final scaling is done at the end of the function, after the NT_FP64 case
[8e91f01]352
[ae3ce4e]353        answer = (vb-va)/2.0*summ;
354        // Multiply by contrast^2
355        answer *= delrho*delrho;
356        //normalize by volume
357        answer *= vol;
358        //convert to [cm-1]
359        answer *= 1.0e8;
360        //Scale
361        answer *= scale;
362        // add in the background
363        answer += bkg;
[8e91f01]364
[ae3ce4e]365        return answer;
366}
367
368/*      HollowCylinderX  :  calculates the form factor of a Hollow Cylinder
369at the given x-value p->x
370
371Uses 76 pt Gaussian quadrature for the single integral
372
373Warning:
374The call to WaveData() below returns a pointer to the middle
375of an unlocked Macintosh handle. In the unlikely event that your
376calculations could cause memory to move, you should copy the coefficient
377values to local variables or an array before such operations.
378*/
379double
380HollowCylinder(double dp[], double q)
381{
382        int i;
383        double scale,rcore,rshell,length,delrho,bkg;            //local variables of coefficient wave
384        int nord=76;                    //order of integration
385        double va,vb,zi;                //upper and lower integration limits
386        double summ,answer,pi;                  //running tally of integration
[8e91f01]387
[ae3ce4e]388        pi = 4.0*atan(1.0);
389        va = 0;
390        vb = 1;         //limits of numerical integral
[8e91f01]391
[ae3ce4e]392        summ = 0.0;                     //initialize intergral
[8e91f01]393
[ae3ce4e]394        scale = dp[0];          //make local copies in case memory moves
395        rcore = dp[1];
396        rshell = dp[2];
397        length = dp[3];
398        delrho = dp[4];
399        bkg = dp[5];
[8e91f01]400
[ae3ce4e]401        for(i=0;i<nord;i++) {
402                zi = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0;
403                summ += Gauss76Wt[i] * HolCylKernel(q, rcore, rshell, length, zi);
404        }
[8e91f01]405
[ae3ce4e]406        answer = (vb-va)/2.0*summ;
407        // Multiply by contrast^2
408        answer *= delrho*delrho;
409        //normalize by volume
410        answer *= pi*(rshell*rshell-rcore*rcore)*length;
411        //convert to [cm-1]
412        answer *= 1.0e8;
413        //Scale
414        answer *= scale;
415        // add in the background
416        answer += bkg;
[8e91f01]417
[ae3ce4e]418        return answer;
419}
420
421/*      EllipsoidFormX  :  calculates the form factor of an ellipsoid of revolution with semiaxes a:a:nua
422at the given x-value p->x
423
424Uses 76 pt Gaussian quadrature for the single integral
425
426Warning:
427The call to WaveData() below returns a pointer to the middle
428of an unlocked Macintosh handle. In the unlikely event that your
429calculations could cause memory to move, you should copy the coefficient
430values to local variables or an array before such operations.
431*/
432double
433EllipsoidForm(double dp[], double q)
434{
435        int i;
436        double scale,a,nua,delrho,bkg;          //local variables of coefficient wave
437        int nord=76;                    //order of integration
438        double va,vb,zi;                //upper and lower integration limits
439        double summ,answer,pi;                  //running tally of integration
[8e91f01]440
[ae3ce4e]441        pi = 4.0*atan(1.0);
442        va = 0;
443        vb = 1;         //limits of numerical integral
[8e91f01]444
[ae3ce4e]445        summ = 0.0;                     //initialize intergral
[8e91f01]446
[ae3ce4e]447        scale = dp[0];                  //make local copies in case memory moves
448        nua = dp[1];
449        a = dp[2];
450        delrho = dp[3];
451        bkg = dp[4];
[8e91f01]452
[ae3ce4e]453        for(i=0;i<nord;i++) {
454                zi = ( Gauss76Z[i]*(vb-va) + va + vb )/2.0;
455                summ += Gauss76Wt[i] * EllipsoidKernel(q, a, nua, zi);
456        }
[8e91f01]457
[ae3ce4e]458        answer = (vb-va)/2.0*summ;
459        // Multiply by contrast^2
460        answer *= delrho*delrho;
461        //normalize by volume
462        answer *= 4*pi/3*a*a*nua;
463        //convert to [cm-1]
464        answer *= 1.0e8;
465        //Scale
466        answer *= scale;
467        // add in the background
468        answer += bkg;
[8e91f01]469
[ae3ce4e]470        return answer;
471}
472
473
474/*      Cyl_PolyRadiusX  :  calculates the form factor of a cylinder at the given x-value p->x
475the cylinder has a polydisperse cross section
476
477*/
478double
479Cyl_PolyRadius(double dp[], double q)
480{
481        int i;
482        double scale,radius,length,pd,delrho,bkg;               //local variables of coefficient wave
483        int nord=20;                    //order of integration
484        double uplim,lolim;             //upper and lower integration limits
485        double summ,zi,yyy,answer,Vpoly;                        //running tally of integration
486        double range,zz,Pi;
[8e91f01]487
[ae3ce4e]488        Pi = 4.0*atan(1.0);
489        range = 3.4;
[8e91f01]490
[ae3ce4e]491        summ = 0.0;                     //initialize intergral
[8e91f01]492
[ae3ce4e]493        scale = dp[0];                  //make local copies in case memory moves
494        radius = dp[1];
495        length = dp[2];
496        pd = dp[3];
497        delrho = dp[4];
498        bkg = dp[5];
[8e91f01]499
[ae3ce4e]500        zz = (1.0/pd)*(1.0/pd) - 1.0;
[8e91f01]501
[ae3ce4e]502        lolim = radius*(1.0-range*pd);          //set the upper/lower limits to cover the distribution
503        if(lolim<0) {
504                lolim = 0;
505        }
506        if(pd>0.3) {
507                range = 3.4 + (pd-0.3)*18.0;
508        }
509        uplim = radius*(1.0+range*pd);
[8e91f01]510
[ae3ce4e]511        for(i=0;i<nord;i++) {
512                zi = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
513                yyy = Gauss20Wt[i] * Cyl_PolyRadKernel(q, radius, length, zz, delrho, zi);
514                summ += yyy;
515        }
[8e91f01]516
[ae3ce4e]517        answer = (uplim-lolim)/2.0*summ;
518        //normalize by average cylinder volume
519        //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
520        Vpoly=Pi*radius*radius*length*(zz+2.0)/(zz+1.0);
521        answer /= Vpoly;
522        //convert to [cm-1]
523        answer *= 1.0e8;
524        //Scale
525        answer *= scale;
526        // add in the background
527        answer += bkg;
[8e91f01]528
[ae3ce4e]529        return answer;
530}
531
532/*      Cyl_PolyLengthX  :  calculates the form factor of a cylinder at the given x-value p->x
533the cylinder has a polydisperse Length
534
535*/
536double
537Cyl_PolyLength(double dp[], double q)
538{
539        int i;
540        double scale,radius,length,pd,delrho,bkg;               //local variables of coefficient wave
541        int nord=20;                    //order of integration
542        double uplim,lolim;             //upper and lower integration limits
543        double summ,zi,yyy,answer,Vpoly;                        //running tally of integration
544        double range,zz,Pi;
[8e91f01]545
546
[ae3ce4e]547        Pi = 4.0*atan(1.0);
548        range = 3.4;
[8e91f01]549
[ae3ce4e]550        summ = 0.0;                     //initialize intergral
[8e91f01]551
[ae3ce4e]552        scale = dp[0];                  //make local copies in case memory moves
553        radius = dp[1];
554        length = dp[2];
555        pd = dp[3];
556        delrho = dp[4];
557        bkg = dp[5];
[8e91f01]558
[ae3ce4e]559        zz = (1.0/pd)*(1.0/pd) - 1.0;
[8e91f01]560
[ae3ce4e]561        lolim = length*(1.0-range*pd);          //set the upper/lower limits to cover the distribution
562        if(lolim<0) {
563                lolim = 0;
564        }
565        if(pd>0.3) {
566                range = 3.4 + (pd-0.3)*18.0;
567        }
568        uplim = length*(1.0+range*pd);
[8e91f01]569
[ae3ce4e]570        for(i=0;i<nord;i++) {
571                zi = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
572                yyy = Gauss20Wt[i] * Cyl_PolyLenKernel(q, radius, length, zz, delrho, zi);
573                summ += yyy;
574        }
[8e91f01]575
[ae3ce4e]576        answer = (uplim-lolim)/2.0*summ;
577        //normalize by average cylinder volume (first moment)
578        //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
579        Vpoly=Pi*radius*radius*length;
580        answer /= Vpoly;
581        //convert to [cm-1]
582        answer *= 1.0e8;
583        //Scale
584        answer *= scale;
585        // add in the background
586        answer += bkg;
[8e91f01]587
[ae3ce4e]588        return answer;
589}
590
591/*      CoreShellCylinderX  :  calculates the form factor of a cylinder at the given x-value p->x
592the cylinder has a core-shell structure
593
594*/
595double
596CoreShellCylinder(double dp[], double q)
597{
598        int i;
599        double scale,rcore,length,bkg;          //local variables of coefficient wave
600        double thick,rhoc,rhos,rhosolv;
601        int nord=76;                    //order of integration
602        double uplim,lolim,halfheight;          //upper and lower integration limits
603        double summ,zi,yyy,answer,Vcyl;                 //running tally of integration
604        double Pi;
[8e91f01]605
[ae3ce4e]606        Pi = 4.0*atan(1.0);
[8e91f01]607
[ae3ce4e]608        lolim = 0.0;
609        uplim = Pi/2.0;
[8e91f01]610
[ae3ce4e]611        summ = 0.0;                     //initialize intergral
[8e91f01]612
[ae3ce4e]613        scale = dp[0];          //make local copies in case memory moves
614        rcore = dp[1];
615        thick = dp[2];
616        length = dp[3];
617        rhoc = dp[4];
618        rhos = dp[5];
619        rhosolv = dp[6];
620        bkg = dp[7];
[8e91f01]621
[ae3ce4e]622        halfheight = length/2.0;
[8e91f01]623
[ae3ce4e]624        for(i=0;i<nord;i++) {
625                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
626                yyy = Gauss76Wt[i] * CoreShellCylKernel(q, rcore, thick, rhoc,rhos,rhosolv, halfheight, zi);
627                summ += yyy;
628        }
[8e91f01]629
[ae3ce4e]630        answer = (uplim-lolim)/2.0*summ;
[8e91f01]631        // length is the total core length
[ae3ce4e]632        Vcyl=Pi*(rcore+thick)*(rcore+thick)*(length+2.0*thick);
633        answer /= Vcyl;
634        //convert to [cm-1]
635        answer *= 1.0e8;
636        //Scale
637        answer *= scale;
638        // add in the background
639        answer += bkg;
[8e91f01]640
[ae3ce4e]641        return answer;
642}
643
644
645/*      PolyCoShCylinderX  :  calculates the form factor of a core-shell cylinder at the given x-value p->x
646the cylinder has a polydisperse CORE radius
647
648*/
649double
650PolyCoShCylinder(double dp[], double q)
651{
652        int i;
653        double scale,radius,length,sigma,bkg;           //local variables of coefficient wave
654        double rad,radthick,facthick,rhoc,rhos,rhosolv;
655        int nord=20;                    //order of integration
656        double uplim,lolim;             //upper and lower integration limits
657        double summ,yyy,answer,Vpoly;                   //running tally of integration
658        double Pi,AR,Rsqrsumm,Rsqryyy,Rsqr;
[8e91f01]659
[ae3ce4e]660        Pi = 4.0*atan(1.0);
[8e91f01]661
[ae3ce4e]662        summ = 0.0;                     //initialize intergral
663        Rsqrsumm = 0.0;
[8e91f01]664
[ae3ce4e]665        scale = dp[0];
666        radius = dp[1];
667        sigma = dp[2];                          //sigma is the standard mean deviation
668        length = dp[3];
669        radthick = dp[4];
670        facthick= dp[5];
671        rhoc = dp[6];
672        rhos = dp[7];
673        rhosolv = dp[8];
674        bkg = dp[9];
[8e91f01]675
[ae3ce4e]676        lolim = exp(log(radius)-(4.*sigma));
677        if (lolim<0) {
678                lolim=0;                //to avoid numerical error when  va<0 (-ve r value)
679        }
680        uplim = exp(log(radius)+(4.*sigma));
[8e91f01]681
[ae3ce4e]682        for(i=0;i<nord;i++) {
683                rad = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
684                AR=(1.0/(rad*sigma*sqrt(2.0*Pi)))*exp(-(0.5*((log(radius/rad))/sigma)*((log(radius/rad))/sigma)));
685                yyy = AR* Gauss20Wt[i] * CSCylIntegration(q,rad,radthick,facthick,rhoc,rhos,rhosolv,length);
686                Rsqryyy= Gauss20Wt[i] * AR * (rad+radthick)*(rad+radthick);             //SRK normalize to total dimensions
687                summ += yyy;
688                Rsqrsumm += Rsqryyy;
689        }
[8e91f01]690
[ae3ce4e]691        answer = (uplim-lolim)/2.0*summ;
692        Rsqr = (uplim-lolim)/2.0*Rsqrsumm;
693        //normalize by average cylinder volume
694        Vpoly = Pi*Rsqr*(length+2*facthick);
695        answer /= Vpoly;
696        //convert to [cm-1]
697        answer *= 1.0e8;
698        //Scale
699        answer *= scale;
700        // add in the background
701        answer += bkg;
[8e91f01]702
[ae3ce4e]703        return answer;
704}
705
706/*      OblateFormX  :  calculates the form factor of a core-shell Oblate ellipsoid at the given x-value p->x
707the ellipsoid has a core-shell structure
708
709*/
710double
711OblateForm(double dp[], double q)
712{
713        int i;
714        double scale,crmaj,crmin,trmaj,trmin,delpc,delps,bkg;
715        int nord=76;                    //order of integration
716        double uplim,lolim;             //upper and lower integration limits
717        double summ,zi,yyy,answer,oblatevol;                    //running tally of integration
718        double Pi;
[8e91f01]719
[ae3ce4e]720        Pi = 4.0*atan(1.0);
[8e91f01]721
[ae3ce4e]722        lolim = 0.0;
723        uplim = 1.0;
[8e91f01]724
[ae3ce4e]725        summ = 0.0;                     //initialize intergral
[8e91f01]726
727
[ae3ce4e]728        scale = dp[0];          //make local copies in case memory moves
729        crmaj = dp[1];
730        crmin = dp[2];
731        trmaj = dp[3];
732        trmin = dp[4];
733        delpc = dp[5];
734        delps = dp[6];
[8e91f01]735        bkg = dp[7];
736
[ae3ce4e]737        for(i=0;i<nord;i++) {
738                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
739                yyy = Gauss76Wt[i] * gfn4(zi,crmaj,crmin,trmaj,trmin,delpc,delps,q);
740                summ += yyy;
741        }
[8e91f01]742
[ae3ce4e]743        answer = (uplim-lolim)/2.0*summ;
744        // normalize by particle volume
745        oblatevol = 4*Pi/3*trmaj*trmaj*trmin;
746        answer /= oblatevol;
[8e91f01]747
[ae3ce4e]748        //convert to [cm-1]
749        answer *= 1.0e8;
750        //Scale
751        answer *= scale;
752        // add in the background
753        answer += bkg;
[8e91f01]754
[ae3ce4e]755        return answer;
756}
757
758/*      ProlateFormX  :  calculates the form factor of a core-shell Prolate ellipsoid at the given x-value p->x
759the ellipsoid has a core-shell structure
760
761*/
762double
763ProlateForm(double dp[], double q)
764{
765        int i;
766        double scale,crmaj,crmin,trmaj,trmin,delpc,delps,bkg;
767        int nord=76;                    //order of integration
768        double uplim,lolim;             //upper and lower integration limits
769        double summ,zi,yyy,answer,prolatevol;                   //running tally of integration
770        double Pi;
[8e91f01]771
[ae3ce4e]772        Pi = 4.0*atan(1.0);
[8e91f01]773
[ae3ce4e]774        lolim = 0.0;
775        uplim = 1.0;
[8e91f01]776
[ae3ce4e]777        summ = 0.0;                     //initialize intergral
[8e91f01]778
[ae3ce4e]779        scale = dp[0];          //make local copies in case memory moves
780        crmaj = dp[1];
781        crmin = dp[2];
782        trmaj = dp[3];
783        trmin = dp[4];
784        delpc = dp[5];
785        delps = dp[6];
[8e91f01]786        bkg = dp[7];
787
[ae3ce4e]788        for(i=0;i<nord;i++) {
789                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
790                yyy = Gauss76Wt[i] * gfn2(zi,crmaj,crmin,trmaj,trmin,delpc,delps,q);
791                summ += yyy;
792        }
[8e91f01]793
[ae3ce4e]794        answer = (uplim-lolim)/2.0*summ;
795        // normalize by particle volume
796        prolatevol = 4*Pi/3*trmaj*trmin*trmin;
797        answer /= prolatevol;
[8e91f01]798
[ae3ce4e]799        //convert to [cm-1]
800        answer *= 1.0e8;
801        //Scale
802        answer *= scale;
803        // add in the background
804        answer += bkg;
[8e91f01]805
[ae3ce4e]806        return answer;
807}
808
809
810/*      StackedDiscsX  :  calculates the form factor of a stacked "tactoid" of core shell disks
811like clay platelets that are not exfoliated
812
813*/
814double
815StackedDiscs(double dp[], double q)
816{
817        int i;
818        double scale,length,bkg,rcore,thick,rhoc,rhol,rhosolv,N,gsd;            //local variables of coefficient wave
819        double va,vb,vcyl,summ,yyy,zi,halfheight,d,answer;
820        int nord=76;                    //order of integration
821        double Pi;
[8e91f01]822
823
[ae3ce4e]824        Pi = 4.0*atan(1.0);
[8e91f01]825
[ae3ce4e]826        va = 0.0;
827        vb = Pi/2.0;
[8e91f01]828
[ae3ce4e]829        summ = 0.0;                     //initialize intergral
[8e91f01]830
[ae3ce4e]831        scale = dp[0];
832        rcore = dp[1];
833        length = dp[2];
834        thick = dp[3];
835        rhoc = dp[4];
836        rhol = dp[5];
837        rhosolv = dp[6];
838        N = dp[7];
839        gsd = dp[8];
840        bkg = dp[9];
[8e91f01]841
[ae3ce4e]842        d=2.0*thick+length;
843        halfheight = length/2.0;
[8e91f01]844
[ae3ce4e]845        for(i=0;i<nord;i++) {
846                zi = ( Gauss76Z[i]*(vb-va) + vb + va )/2.0;
847                yyy = Gauss76Wt[i] * Stackdisc_kern(q, rcore, rhoc,rhol,rhosolv, halfheight,thick,zi,gsd,d,N);
848                summ += yyy;
849        }
[8e91f01]850
[ae3ce4e]851        answer = (vb-va)/2.0*summ;
[8e91f01]852        // length is the total core length
[ae3ce4e]853        vcyl=Pi*rcore*rcore*(2.0*thick+length)*N;
854        answer /= vcyl;
855        //Convert to [cm-1]
856        answer *= 1.0e8;
857        //Scale
858        answer *= scale;
859        // add in the background
860        answer += bkg;
[8e91f01]861
[ae3ce4e]862        return answer;
863}
864
865
866/*      LamellarFFX  :  calculates the form factor of a lamellar structure - no S(q) effects included
867
868*/
869double
870LamellarFF(double dp[], double q)
871{
872        double scale,del,sig,contr,bkg;         //local variables of coefficient wave
873        double inten, qval,Pq;
874        double Pi;
[8e91f01]875
876
[ae3ce4e]877        Pi = 4.0*atan(1.0);
878        scale = dp[0];
879        del = dp[1];
880        sig = dp[2]*del;
881        contr = dp[3];
882        bkg = dp[4];
[34c3020]883        qval = q;
[8e91f01]884
[ae3ce4e]885        Pq = 2.0*contr*contr/qval/qval*(1.0-cos(qval*del)*exp(-0.5*qval*qval*sig*sig));
[8e91f01]886
[ae3ce4e]887        inten = 2.0*Pi*scale*Pq/(qval*qval);            //this is now dimensionless...
[8e91f01]888
[ae3ce4e]889        inten /= del;                   //normalize by the thickness (in A)
[8e91f01]890
[ae3ce4e]891        inten *= 1.0e8;         // 1/A to 1/cm
[8e91f01]892
[ae3ce4e]893        return(inten+bkg);
894}
895
896/*      LamellarPSX  :  calculates the form factor of a lamellar structure - with S(q) effects included
897-------
898------- resolution effects ARE included, but only a CONSTANT default value, not the real q-dependent resolution!!
899
900        */
901double
902LamellarPS(double dp[], double q)
903{
904        double scale,dd,del,sig,contr,NN,Cp,bkg;                //local variables of coefficient wave
905        double inten, qval,Pq,Sq,alpha,temp,t1,t2,t3,dQ;
906        double Pi,Euler,dQDefault,fii;
907        int ii,NNint;
[8e91f01]908
[ae3ce4e]909        Euler = 0.5772156649;           // Euler's constant
[8e91f01]910        dQDefault = 0.0;//0.0025;               //[=] 1/A, q-resolution, default value
[ae3ce4e]911        dQ = dQDefault;
[8e91f01]912
[ae3ce4e]913        Pi = 4.0*atan(1.0);
914        qval = q;
[8e91f01]915
[ae3ce4e]916        scale = dp[0];
917        dd = dp[1];
918        del = dp[2];
919        sig = dp[3]*del;
920        contr = dp[4];
921        NN = trunc(dp[5]);              //be sure that NN is an integer
922        Cp = dp[6];
923        bkg = dp[7];
[8e91f01]924
[ae3ce4e]925        Pq = 2.0*contr*contr/qval/qval*(1.0-cos(qval*del)*exp(-0.5*qval*qval*sig*sig));
[8e91f01]926
[ae3ce4e]927        NNint = (int)NN;                //cast to an integer for the loop
928        ii=0;
929        Sq = 0.0;
930        for(ii=1;ii<(NNint-1);ii+=1) {
[8e91f01]931
[ae3ce4e]932                fii = (double)ii;               //do I really need to do this?
[8e91f01]933
[ae3ce4e]934                temp = 0.0;
935                alpha = Cp/4.0/Pi/Pi*(log(Pi*ii) + Euler);
936                t1 = 2.0*dQ*dQ*dd*dd*alpha;
937                t2 = 2.0*qval*qval*dd*dd*alpha;
938                t3 = dQ*dQ*dd*dd*ii*ii;
[8e91f01]939
[ae3ce4e]940                temp = 1.0-ii/NN;
941                temp *= cos(dd*qval*ii/(1.0+t1));
942                temp *= exp(-1.0*(t2 + t3)/(2.0*(1.0+t1)) );
943                temp /= sqrt(1.0+t1);
[8e91f01]944
[ae3ce4e]945                Sq += temp;
946        }
[8e91f01]947
[ae3ce4e]948        Sq *= 2.0;
949        Sq += 1.0;
[8e91f01]950
[ae3ce4e]951        inten = 2.0*Pi*scale*Pq*Sq/(dd*qval*qval);
[8e91f01]952
[ae3ce4e]953        inten *= 1.0e8;         // 1/A to 1/cm
[8e91f01]954
[ae3ce4e]955    return(inten+bkg);
956}
957
958
959/*      LamellarPS_HGX  :  calculates the form factor of a lamellar structure - with S(q) effects included
960-------
961------- resolution effects ARE included, but only a CONSTANT default value, not the real q-dependent resolution!!
962
963        */
964double
965LamellarPS_HG(double dp[], double q)
966{
967        double scale,dd,delT,delH,SLD_T,SLD_H,SLD_S,NN,Cp,bkg;          //local variables of coefficient wave
968        double inten,qval,Pq,Sq,alpha,temp,t1,t2,t3,dQ,drh,drt;
969        double Pi,Euler,dQDefault,fii;
970        int ii,NNint;
[8e91f01]971
972
[ae3ce4e]973        Euler = 0.5772156649;           // Euler's constant
[96b59384]974        dQDefault = 0; //0.0025;                //[=] 1/A, q-resolution, default value
[ae3ce4e]975        dQ = dQDefault;
[8e91f01]976
[ae3ce4e]977        Pi = 4.0*atan(1.0);
978        qval= q;
[8e91f01]979
[ae3ce4e]980        scale = dp[0];
981        dd = dp[1];
982        delT = dp[2];
983        delH = dp[3];
984        SLD_T = dp[4];
985        SLD_H = dp[5];
986        SLD_S = dp[6];
987        NN = trunc(dp[7]);              //be sure that NN is an integer
988        Cp = dp[8];
989        bkg = dp[9];
[8e91f01]990
991
[ae3ce4e]992        drh = SLD_H - SLD_S;
993        drt = SLD_T - SLD_S;    //correction 13FEB06 by L.Porcar
[8e91f01]994
[ae3ce4e]995        Pq = drh*(sin(qval*(delH+delT))-sin(qval*delT)) + drt*sin(qval*delT);
996        Pq *= Pq;
997        Pq *= 4.0/(qval*qval);
[8e91f01]998
[ae3ce4e]999        NNint = (int)NN;                //cast to an integer for the loop
1000        ii=0;
1001        Sq = 0.0;
1002        for(ii=1;ii<(NNint-1);ii+=1) {
[8e91f01]1003
[ae3ce4e]1004                fii = (double)ii;               //do I really need to do this?
[8e91f01]1005
[ae3ce4e]1006                temp = 0.0;
1007                alpha = Cp/4.0/Pi/Pi*(log(Pi*ii) + Euler);
1008                t1 = 2.0*dQ*dQ*dd*dd*alpha;
1009                t2 = 2.0*qval*qval*dd*dd*alpha;
1010                t3 = dQ*dQ*dd*dd*ii*ii;
[8e91f01]1011
[ae3ce4e]1012                temp = 1.0-ii/NN;
1013                temp *= cos(dd*qval*ii/(1.0+t1));
1014                temp *= exp(-1.0*(t2 + t3)/(2.0*(1.0+t1)) );
1015                temp /= sqrt(1.0+t1);
[8e91f01]1016
[ae3ce4e]1017                Sq += temp;
1018        }
[8e91f01]1019
[ae3ce4e]1020        Sq *= 2.0;
1021        Sq += 1.0;
[8e91f01]1022
[ae3ce4e]1023        inten = 2.0*Pi*scale*Pq*Sq/(dd*qval*qval);
[8e91f01]1024
[ae3ce4e]1025        inten *= 1.0e8;         // 1/A to 1/cm
[8e91f01]1026
[ae3ce4e]1027        return(inten+bkg);
1028}
1029
1030/*      LamellarFF_HGX  :  calculates the form factor of a lamellar structure - no S(q) effects included
1031but extra SLD for head groups is included
1032
1033*/
1034double
1035LamellarFF_HG(double dp[], double q)
1036{
1037        double scale,delT,delH,slds,sldh,sldt,bkg;              //local variables of coefficient wave
1038        double inten, qval,Pq,drh,drt;
1039        double Pi;
[8e91f01]1040
1041
[ae3ce4e]1042        Pi = 4.0*atan(1.0);
1043        qval= q;
1044        scale = dp[0];
1045        delT = dp[1];
1046        delH = dp[2];
1047        sldt = dp[3];
1048        sldh = dp[4];
1049        slds = dp[5];
1050        bkg = dp[6];
[8e91f01]1051
1052
[ae3ce4e]1053        drh = sldh - slds;
1054        drt = sldt - slds;              //correction 13FEB06 by L.Porcar
[8e91f01]1055
[ae3ce4e]1056        Pq = drh*(sin(qval*(delH+delT))-sin(qval*delT)) + drt*sin(qval*delT);
1057        Pq *= Pq;
1058        Pq *= 4.0/(qval*qval);
[8e91f01]1059
[ae3ce4e]1060        inten = 2.0*Pi*scale*Pq/(qval*qval);            //dimensionless...
[8e91f01]1061
[ae3ce4e]1062        inten /= 2.0*(delT+delH);                       //normalize by the bilayer thickness
[8e91f01]1063
[ae3ce4e]1064        inten *= 1.0e8;         // 1/A to 1/cm
[8e91f01]1065
[ae3ce4e]1066        return(inten+bkg);
1067}
1068
1069/*      FlexExclVolCylX  :  calculates the form factor of a flexible cylinder with a circular cross section
1070-- incorporates Wei-Ren Chen's fixes - 2006
1071
1072        */
1073double
1074FlexExclVolCyl(double dp[], double q)
1075{
1076        double scale,L,B,bkg,rad,qr,cont;
1077        double Pi,flex,crossSect,answer;
[8e91f01]1078
1079
[ae3ce4e]1080        Pi = 4.0*atan(1.0);
[8e91f01]1081
[ae3ce4e]1082        scale = dp[0];          //make local copies in case memory moves
1083        L = dp[1];
1084        B = dp[2];
1085        rad = dp[3];
1086        cont = dp[4];
1087        bkg = dp[5];
[8e91f01]1088
1089
[ae3ce4e]1090        qr = q*rad;
[8e91f01]1091
[ae3ce4e]1092        flex = Sk_WR(q,L,B);
[8e91f01]1093
[ae3ce4e]1094        crossSect = (2.0*NR_BessJ1(qr)/qr)*(2.0*NR_BessJ1(qr)/qr);
1095        flex *= crossSect;
1096        flex *= Pi*rad*rad*L;
1097        flex *= cont*cont;
1098        flex *= 1.0e8;
1099        answer = scale*flex + bkg;
[8e91f01]1100
[ae3ce4e]1101        return answer;
1102}
1103
1104/*      FlexCyl_EllipX  :  calculates the form factor of a flexible cylinder with an elliptical cross section
1105-- incorporates Wei-Ren Chen's fixes - 2006
1106
1107        */
1108double
1109FlexCyl_Ellip(double dp[], double q)
1110{
1111        double scale,L,B,bkg,rad,qr,cont,ellRatio;
1112        double Pi,flex,crossSect,answer;
[8e91f01]1113
1114
[ae3ce4e]1115        Pi = 4.0*atan(1.0);
1116        scale = dp[0];          //make local copies in case memory moves
1117        L = dp[1];
1118        B = dp[2];
1119        rad = dp[3];
1120        ellRatio = dp[4];
1121        cont = dp[5];
1122        bkg = dp[6];
[8e91f01]1123
[ae3ce4e]1124        qr = q*rad;
[8e91f01]1125
[ae3ce4e]1126        flex = Sk_WR(q,L,B);
[8e91f01]1127
[ae3ce4e]1128        crossSect = EllipticalCross_fn(q,rad,(rad*ellRatio));
1129        flex *= crossSect;
1130        flex *= Pi*rad*rad*ellRatio*L;
1131        flex *= cont*cont;
1132        flex *= 1.0e8;
1133        answer = scale*flex + bkg;
[8e91f01]1134
[ae3ce4e]1135        return answer;
1136}
1137
1138double
1139EllipticalCross_fn(double qq, double a, double b)
1140{
1141    double uplim,lolim,Pi,summ,arg,zi,yyy,answer;
1142    int i,nord=76;
[8e91f01]1143
[ae3ce4e]1144    Pi = 4.0*atan(1.0);
1145    lolim=0.0;
1146    uplim=Pi/2.0;
1147    summ=0.0;
[8e91f01]1148
[ae3ce4e]1149    for(i=0;i<nord;i++) {
1150                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1151                arg = qq*sqrt(a*a*sin(zi)*sin(zi)+b*b*cos(zi)*cos(zi));
1152                yyy = pow((2.0 * NR_BessJ1(arg) / arg),2);
1153                yyy *= Gauss76Wt[i];
1154                summ += yyy;
1155    }
1156    answer = (uplim-lolim)/2.0*summ;
1157    answer *= 2.0/Pi;
1158    return(answer);
[8e91f01]1159
[ae3ce4e]1160}
1161/*      FlexCyl_PolyLenX  :  calculates the form factor of a flecible cylinder at the given x-value p->x
1162the cylinder has a polydisperse Length
1163
1164*/
1165double
1166FlexCyl_PolyLen(double dp[], double q)
1167{
1168        int i;
1169        double scale,radius,length,pd,delrho,bkg,lb;            //local variables of coefficient wave
1170        int nord=20;                    //order of integration
1171        double uplim,lolim;             //upper and lower integration limits
1172        double summ,zi,yyy,answer,Vpoly;                        //running tally of integration
1173        double range,zz,Pi;
[8e91f01]1174
[ae3ce4e]1175        Pi = 4.0*atan(1.0);
1176        range = 3.4;
[8e91f01]1177
[ae3ce4e]1178        summ = 0.0;                     //initialize intergral
1179        scale = dp[0];                  //make local copies in case memory moves
1180        length = dp[1];                 //radius
1181        pd = dp[2];                     // average length
1182        lb = dp[3];
1183        radius = dp[4];
1184        delrho = dp[5];
1185        bkg = dp[6];
[8e91f01]1186
[ae3ce4e]1187        zz = (1.0/pd)*(1.0/pd) - 1.0;
[8e91f01]1188
[ae3ce4e]1189        lolim = length*(1.0-range*pd);          //set the upper/lower limits to cover the distribution
1190        if(lolim<0) {
1191                lolim = 0;
1192        }
1193        if(pd>0.3) {
1194                range = 3.4 + (pd-0.3)*18.0;
1195        }
1196        uplim = length*(1.0+range*pd);
[8e91f01]1197
[ae3ce4e]1198        for(i=0;i<nord;i++) {
1199                zi = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1200                yyy = Gauss20Wt[i] * FlePolyLen_kernel(q,radius,length,lb,zz,delrho,zi);
1201                summ += yyy;
1202        }
[8e91f01]1203
[ae3ce4e]1204        answer = (uplim-lolim)/2.0*summ;
1205        //normalize by average cylinder volume (first moment), using the average length
1206        Vpoly=Pi*radius*radius*length;
1207        answer /= Vpoly;
[8e91f01]1208
[ae3ce4e]1209        answer *=delrho*delrho;
[8e91f01]1210
[ae3ce4e]1211        //convert to [cm-1]
1212        answer *= 1.0e8;
1213        //Scale
1214        answer *= scale;
1215        // add in the background
1216        answer += bkg;
[8e91f01]1217
[ae3ce4e]1218        return answer;
1219}
1220
1221/*      FlexCyl_PolyLenX  :  calculates the form factor of a flexible cylinder at the given x-value p->x
1222the cylinder has a polydisperse cross sectional radius
1223
1224*/
1225double
1226FlexCyl_PolyRad(double dp[], double q)
1227{
1228        int i;
1229        double scale,radius,length,pd,delrho,bkg,lb;            //local variables of coefficient wave
1230        int nord=76;                    //order of integration
1231        double uplim,lolim;             //upper and lower integration limits
1232        double summ,zi,yyy,answer,Vpoly;                        //running tally of integration
1233        double range,zz,Pi;
[8e91f01]1234
1235
[ae3ce4e]1236        Pi = 4.0*atan(1.0);
1237        range = 3.4;
[8e91f01]1238
[ae3ce4e]1239        summ = 0.0;                     //initialize intergral
[8e91f01]1240
[ae3ce4e]1241        scale = dp[0];                  //make local copies in case memory moves
1242        length = dp[1];                 //radius
1243        lb = dp[2];                     // average length
1244        radius = dp[3];
1245        pd = dp[4];
1246        delrho = dp[5];
1247        bkg = dp[6];
[8e91f01]1248
[ae3ce4e]1249        zz = (1.0/pd)*(1.0/pd) - 1.0;
[8e91f01]1250
[ae3ce4e]1251        lolim = radius*(1.0-range*pd);          //set the upper/lower limits to cover the distribution
1252        if(lolim<0) {
1253                lolim = 0;
1254        }
1255        if(pd>0.3) {
1256                range = 3.4 + (pd-0.3)*18.0;
1257        }
1258        uplim = radius*(1.0+range*pd);
[8e91f01]1259
[ae3ce4e]1260        for(i=0;i<nord;i++) {
1261                //zi = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1262                //yyy = Gauss20Wt[i] * FlePolyRad_kernel(q,radius,length,lb,zz,delrho,zi);
1263                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1264                yyy = Gauss76Wt[i] * FlePolyRad_kernel(q,radius,length,lb,zz,delrho,zi);
1265                summ += yyy;
1266        }
[8e91f01]1267
[ae3ce4e]1268        answer = (uplim-lolim)/2.0*summ;
1269        //normalize by average cylinder volume (second moment), using the average radius
1270        Vpoly = Pi*radius*radius*length*(zz+2.0)/(zz+1.0);
1271        answer /= Vpoly;
[8e91f01]1272
[ae3ce4e]1273        answer *=delrho*delrho;
[8e91f01]1274
[ae3ce4e]1275        //convert to [cm-1]
1276        answer *= 1.0e8;
1277        //Scale
1278        answer *= scale;
1279        // add in the background
1280        answer += bkg;
[8e91f01]1281
[ae3ce4e]1282        return answer;
1283}
1284
1285/////////functions for WRC implementation of flexible cylinders
1286static double
1287Sk_WR(double q, double L, double b)
1288{
1289        //
1290        double p1,p2,p1short,p2short,q0,qconnect;
1291        double C,epsilon,ans,q0short,Sexvmodify,pi;
[8e91f01]1292
[ae3ce4e]1293        pi = 4.0*atan(1.0);
[8e91f01]1294
[ae3ce4e]1295        p1 = 4.12;
1296        p2 = 4.42;
1297        p1short = 5.36;
1298        p2short = 5.62;
1299        q0 = 3.1;
1300        qconnect = q0/b;
[8e91f01]1301        //
[ae3ce4e]1302        q0short = fmax(1.9/sqrt(Rgsquareshort(q,L,b)),3.0);
[8e91f01]1303
[ae3ce4e]1304        //
1305        if(L/b > 10.0) {
1306                C = 3.06/pow((L/b),0.44);
1307                epsilon = 0.176;
1308        } else {
1309                C = 1.0;
1310                epsilon = 0.170;
1311        }
1312        //
[8e91f01]1313
[ae3ce4e]1314        if( L > 4*b ) { // Longer Chains
1315                if (q*b <= 3.1) {               //Modified by Yun on Oct. 15,
1316                        Sexvmodify = Sexvnew(q, L, b);
1317                        ans = Sexvmodify + C * (4.0/15.0 + 7.0/(15.0*u_WR(q,L,b)) - (11.0/15.0 + 7.0/(15.0*u_WR(q,L,b)))*exp(-u_WR(q,L,b)))*(b/L);
1318                } else { //q(i)*b > 3.1
1319                        ans = a1long(q, L, b, p1, p2, q0)/(pow((q*b),p1)) + a2long(q, L, b, p1, p2, q0)/(pow((q*b),p2)) + pi/(q*L);
[8e91f01]1320                }
[ae3ce4e]1321        } else { //L <= 4*b Shorter Chains
1322                if (q*b <= fmax(1.9/sqrt(Rgsquareshort(q,L,b)),3.0) ) {
1323                        if (q*b<=0.01) {
1324                                ans = 1.0 - Rgsquareshort(q,L,b)*(q*q)/3.0;
1325                        } else {
1326                                ans = Sdebye1(q,L,b);
1327                        }
1328                } else {        //q*b > max(1.9/sqrt(Rgsquareshort(q(i),L,b)),3)
1329                        ans = a1short(q,L,b,p1short,p2short,q0short)/(pow((q*b),p1short)) + a2short(q,L,b,p1short,p2short,q0short)/(pow((q*b),p2short)) + pi/(q*L);
1330                }
1331        }
[8e91f01]1332
[ae3ce4e]1333        return(ans);
1334        //return(a2long(q, L, b, p1, p2, q0));
1335}
1336
1337//WR named this w (too generic)
1338static double
1339w_WR(double x)
1340{
1341    double yy;
1342    yy = 0.5*(1 + tanh((x - 1.523)/0.1477));
[8e91f01]1343
[ae3ce4e]1344    return (yy);
1345}
1346
1347//
1348static double
1349u1(double q, double L, double b)
1350{
1351    double yy;
[8e91f01]1352
[ae3ce4e]1353    yy = Rgsquareshort(q,L,b)*q*q;
[8e91f01]1354
[ae3ce4e]1355    return (yy);
1356}
1357
1358// was named u
1359static double
1360u_WR(double q, double L, double b)
1361{
1362    double yy;
1363    yy = Rgsquare(q,L,b)*q*q;
1364    return (yy);
1365}
1366
1367
1368
1369//
1370static double
1371Rgsquarezero(double q, double L, double b)
[8e91f01]1372{
[ae3ce4e]1373    double yy;
1374    yy = (L*b/6.0) * (1.0 - 1.5*(b/L) + 1.5*pow((b/L),2) - 0.75*pow((b/L),3)*(1.0 - exp(-2.0*(L/b))));
[8e91f01]1375
[ae3ce4e]1376    return (yy);
1377}
1378
1379//
1380static double
1381Rgsquareshort(double q, double L, double b)
[8e91f01]1382{
[ae3ce4e]1383    double yy;
1384    yy = AlphaSquare(L/b) * Rgsquarezero(q,L,b);
[8e91f01]1385
[ae3ce4e]1386    return (yy);
1387}
1388
1389//
1390static double
1391Rgsquare(double q, double L, double b)
1392{
1393    double yy;
1394    yy = AlphaSquare(L/b)*L*b/6.0;
[8e91f01]1395
[ae3ce4e]1396    return (yy);
1397}
1398
1399//
1400static double
1401AlphaSquare(double x)
[8e91f01]1402{
[ae3ce4e]1403    double yy;
1404    yy = pow( (1.0 + (x/3.12)*(x/3.12) + (x/8.67)*(x/8.67)*(x/8.67)),(0.176/3.0) );
[8e91f01]1405
[ae3ce4e]1406    return (yy);
1407}
1408
1409// ?? funciton is not used - but should the log actually be log10???
1410static double
1411miu(double x)
[8e91f01]1412{
[ae3ce4e]1413    double yy;
1414    yy = (1.0/8.0)*(9.0*x - 2.0 + 2.0*log(1.0 + x)/x)*exp(1.0/2.565*(1.0/x + (1.0 - 1.0/(x*x))*log(1.0 + x)));
[8e91f01]1415
[ae3ce4e]1416    return (yy);
1417}
1418
1419//
1420static double
1421Sdebye(double q, double L, double b)
[8e91f01]1422{
[ae3ce4e]1423    double yy;
1424    yy = 2.0*(exp(-u_WR(q,L,b)) + u_WR(q,L,b) -1.0)/(pow((u_WR(q,L,b)),2));
[8e91f01]1425
[ae3ce4e]1426    return (yy);
1427}
1428
1429//
1430static double
1431Sdebye1(double q, double L, double b)
[8e91f01]1432{
[ae3ce4e]1433    double yy;
1434    yy = 2.0*(exp(-u1(q,L,b)) + u1(q,L,b) -1.0)/( pow((u1(q,L,b)),2.0) );
[8e91f01]1435
[ae3ce4e]1436    return (yy);
1437}
1438
1439//
1440static double
1441Sexv(double q, double L, double b)
[8e91f01]1442{
[ae3ce4e]1443    double yy,C1,C2,C3,miu,Rg2;
1444    C1=1.22;
1445    C2=0.4288;
1446    C3=-1.651;
1447    miu = 0.585;
[8e91f01]1448
[ae3ce4e]1449    Rg2 = Rgsquare(q,L,b);
[8e91f01]1450
[ae3ce4e]1451    yy = (1.0 - w_WR(q*sqrt(Rg2)))*Sdebye(q,L,b) + w_WR(q*sqrt(Rg2))*(C1*pow((q*sqrt(Rg2)),(-1.0/miu)) +  C2*pow((q*sqrt(Rg2)),(-2.0/miu)) +    C3*pow((q*sqrt(Rg2)),(-3.0/miu)));
[8e91f01]1452
[ae3ce4e]1453    return (yy);
1454}
1455
1456// this must be WR modified version
1457static double
1458Sexvnew(double q, double L, double b)
[8e91f01]1459{
[ae3ce4e]1460    double yy,C1,C2,C3,miu;
1461    double del=1.05,C_star2,Rg2;
[8e91f01]1462
[ae3ce4e]1463    C1=1.22;
1464    C2=0.4288;
1465    C3=-1.651;
1466    miu = 0.585;
[8e91f01]1467
[ae3ce4e]1468    //calculating the derivative to decide on the corection (cutoff) term?
1469    // I have modified this from WRs original code
[8e91f01]1470
[ae3ce4e]1471    if( (Sexv(q*del,L,b)-Sexv(q,L,b))/(q*del - q) >= 0.0 ) {
1472        C_star2 = 0.0;
1473    } else {
1474        C_star2 = 1.0;
1475    }
[8e91f01]1476
[ae3ce4e]1477    Rg2 = Rgsquare(q,L,b);
[8e91f01]1478
[ae3ce4e]1479        yy = (1.0 - w_WR(q*sqrt(Rg2)))*Sdebye(q,L,b) + C_star2*w_WR(q*sqrt(Rg2))*(C1*pow((q*sqrt(Rg2)),(-1.0/miu)) + C2*pow((q*sqrt(Rg2)),(-2.0/miu)) + C3*pow((q*sqrt(Rg2)),(-3.0/miu)));
[8e91f01]1480
[ae3ce4e]1481    return (yy);
1482}
1483
1484// these are the messy ones
1485static double
1486a2short(double q, double L, double b, double p1short, double p2short, double q0)
[8e91f01]1487{
[ae3ce4e]1488    double yy,Rg2_sh;
1489    double t1,E,Rg2_sh2,Et1,Emt1,q02,q0p;
1490    double pi;
[8e91f01]1491
[ae3ce4e]1492    E = 2.718281828459045091;
1493        pi = 4.0*atan(1.0);
1494    Rg2_sh = Rgsquareshort(q,L,b);
1495    Rg2_sh2 = Rg2_sh*Rg2_sh;
1496    t1 = ((q0*q0*Rg2_sh)/(b*b));
1497    Et1 = pow(E,t1);
[8e91f01]1498    Emt1 =pow(E,-t1);
[ae3ce4e]1499    q02 = q0*q0;
1500    q0p = pow(q0,(-4.0 + p2short) );
[8e91f01]1501
[ae3ce4e]1502    //E is the number e
1503    yy = ((-(1.0/(L*((p1short - p2short))*Rg2_sh2)*((b*Emt1*q0p*((8.0*b*b*b*L - 8.0*b*b*b*Et1*L - 2.0*b*b*b*L*p1short + 2.0*b*b*b*Et1*L*p1short + 4.0*b*L*q02*Rg2_sh + 4.0*b*Et1*L*q02*Rg2_sh - 2.0*b*Et1*L*p1short*q02*Rg2_sh - Et1*pi*q02*q0*Rg2_sh2 + Et1*p1short*pi*q02*q0*Rg2_sh2)))))));
[8e91f01]1504
[ae3ce4e]1505    return (yy);
1506}
1507
1508//
1509static double
1510a1short(double q, double L, double b, double p1short, double p2short, double q0)
[8e91f01]1511{
[ae3ce4e]1512    double yy,Rg2_sh;
1513    double t1,E,Rg2_sh2,Et1,Emt1,q02,q0p,b3;
1514        double pi;
[8e91f01]1515
[ae3ce4e]1516    E = 2.718281828459045091;
1517        pi = 4.0*atan(1.0);
1518    Rg2_sh = Rgsquareshort(q,L,b);
1519    Rg2_sh2 = Rg2_sh*Rg2_sh;
1520    b3 = b*b*b;
1521    t1 = ((q0*q0*Rg2_sh)/(b*b));
1522    Et1 = pow(E,t1);
[8e91f01]1523    Emt1 =pow(E,-t1);
[ae3ce4e]1524    q02 = q0*q0;
1525    q0p = pow(q0,(-4.0 + p1short) );
[8e91f01]1526
1527    yy = ((1.0/(L*((p1short - p2short))*Rg2_sh2)*((b*Emt1*q0p*((8.0*b3*L - 8.0*b3*Et1*L - 2.0*b3*L*p2short + 2.0*b3*Et1*L*p2short + 4.0*b*L*q02*Rg2_sh + 4.0*b*Et1*L*q02*Rg2_sh - 2.0*b*Et1*L*p2short*q02*Rg2_sh - Et1*pi*q02*q0*Rg2_sh2 + Et1*p2short*pi*q02*q0*Rg2_sh2))))));
1528
[ae3ce4e]1529    return(yy);
1530}
1531
1532// this one will be lots of trouble
1533static double
1534a2long(double q, double L, double b, double p1, double p2, double q0)
1535{
1536    double yy,C1,C2,C3,C4,C5,miu,C,Rg2;
1537    double t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,pi;
1538    double E,b2,b3,b4,q02,q03,q04,q05,Rg22;
[8e91f01]1539
[ae3ce4e]1540    pi = 4.0*atan(1.0);
1541    E = 2.718281828459045091;
1542    if( L/b > 10.0) {
1543        C = 3.06/pow((L/b),0.44);
1544    } else {
1545        C = 1.0;
1546    }
[8e91f01]1547
[ae3ce4e]1548    C1 = 1.22;
1549    C2 = 0.4288;
1550    C3 = -1.651;
1551    C4 = 1.523;
1552    C5 = 0.1477;
1553    miu = 0.585;
[8e91f01]1554
[ae3ce4e]1555    Rg2 = Rgsquare(q,L,b);
1556    Rg22 = Rg2*Rg2;
1557    b2 = b*b;
1558    b3 = b*b*b;
1559    b4 = b3*b;
1560    q02 = q0*q0;
1561    q03 = q0*q0*q0;
1562    q04 = q03*q0;
1563    q05 = q04*q0;
[8e91f01]1564
[ae3ce4e]1565    t1 = (1.0/(b* p1*pow(q0,((-1.0) - p1 - p2)) - b*p2*pow(q0,((-1.0) - p1 - p2)) ));
[8e91f01]1566
[ae3ce4e]1567    t2 = (b*C*(((-1.0*((14.0*b3)/(15.0*q03*Rg2))) + (14*b3*pow(E,(-((q02*Rg2)/b2))))/(15*q03*Rg2) + (2*pow(E,(-((q02*Rg2)/b2)))*q0*((11.0/15.0 + (7*b2)/(15*q02*Rg2)))*Rg2)/b)))/L;
[8e91f01]1568
[ae3ce4e]1569    t3 = (sqrt(Rg2)*((C3*pow((((sqrt(Rg2)*q0)/b)),((-3)/miu)) + C2*pow((((sqrt(Rg2)*q0)/b)),((-2)/miu)) + C1*pow((((sqrt(Rg2)*q0)/b)),((-1.0)/miu))))*pow(sech_WR(((-C4) + (sqrt(Rg2)*q0)/b)/C5),2))/(2*C5);
[8e91f01]1570
[ae3ce4e]1571    t4 = (b4*sqrt(Rg2)*(((-1) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*pow(sech_WR(((-C4) + (sqrt(Rg2)*q0)/b)/C5),2))/(C5*q04*Rg22);
[8e91f01]1572
[ae3ce4e]1573    t5 = (2*b4*(((2*q0*Rg2)/b - (2*pow(E,(-((q02*Rg2)/b2)))*q0*Rg2)/b))*((1 + 1.0/2.0*(((-1) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))))/(q04*Rg22);
[8e91f01]1574
[ae3ce4e]1575    t6 = (8*b4*b*(((-1) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*((1 + 1.0/2.0*(((-1) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))))/(q05*Rg22);
[8e91f01]1576
[ae3ce4e]1577    t7 = (((-((3*C3*sqrt(Rg2)*pow((((sqrt(Rg2)*q0)/b)),((-1) - 3/miu)))/miu)) - (2*C2*sqrt(Rg2)*pow((((sqrt(Rg2)*q0)/b)),((-1) - 2/miu)))/miu - (C1*sqrt(Rg2)*pow((((sqrt(Rg2)*q0)/b)),((-1) - 1/miu)))/miu));
[8e91f01]1578
[ae3ce4e]1579    t8 = ((1 + tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5)));
[8e91f01]1580
[ae3ce4e]1581    t9 = (b*C*((4.0/15.0 - pow(E,(-((q02*Rg2)/b2)))*((11.0/15.0 + (7*b2)/(15*q02*Rg2))) + (7*b2)/(15*q02*Rg2))))/L;
[8e91f01]1582
[ae3ce4e]1583    t10 = (2*b4*(((-1) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*((1 + 1.0/2.0*(((-1) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))))/(q04*Rg22);
[8e91f01]1584
1585
[ae3ce4e]1586    yy = ((-1*(t1* ((-pow(q0,-p1)*(((b2*pi)/(L*q02) + t2 + t3 - t4 + t5 - t6 + 1.0/2.0*t7*t8)) - b*p1*pow(q0,((-1) - p1))*(((-((b*pi)/(L*q0))) + t9 + t10 + 1.0/2.0*((C3*pow((((sqrt(Rg2)*q0)/b)),((-3)/miu)) + C2*pow((((sqrt(Rg2)*q0)/b)),((-2)/miu)) + C1*pow((((sqrt(Rg2)*q0)/b)),((-1)/miu))))*((1 + tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))))))));
[8e91f01]1587
[ae3ce4e]1588    return (yy);
1589}
1590
1591//need to define this on my own
1592static double
1593sech_WR(double x)
[8e91f01]1594{
[ae3ce4e]1595        return(1/cosh(x));
1596}
1597
1598//
1599static double
1600a1long(double q, double L, double b, double p1, double p2, double q0)
[8e91f01]1601{
[ae3ce4e]1602    double yy,C,C1,C2,C3,C4,C5,miu,Rg2;
1603    double t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15;
1604    double E,pi;
1605    double b2,b3,b4,q02,q03,q04,q05,Rg22;
[8e91f01]1606
[ae3ce4e]1607    pi = 4.0*atan(1.0);
1608    E = 2.718281828459045091;
[8e91f01]1609
[ae3ce4e]1610    if( L/b > 10.0) {
1611        C = 3.06/pow((L/b),0.44);
1612    } else {
1613        C = 1.0;
1614    }
[8e91f01]1615
[ae3ce4e]1616    C1 = 1.22;
1617    C2 = 0.4288;
1618    C3 = -1.651;
1619    C4 = 1.523;
1620    C5 = 0.1477;
1621    miu = 0.585;
[8e91f01]1622
[ae3ce4e]1623    Rg2 = Rgsquare(q,L,b);
1624    Rg22 = Rg2*Rg2;
1625    b2 = b*b;
1626    b3 = b*b*b;
1627    b4 = b3*b;
1628    q02 = q0*q0;
1629    q03 = q0*q0*q0;
1630    q04 = q03*q0;
1631    q05 = q04*q0;
[8e91f01]1632
[ae3ce4e]1633    t1 = (b*C*((4.0/15.0 - pow(E,(-((q02*Rg2)/b2)))*((11.0/15.0 + (7.0*b2)/(15.0*q02*Rg2))) + (7.0*b2)/(15.0*q02*Rg2))));
[8e91f01]1634
[ae3ce4e]1635    t2 = (2.0*b4*(((-1.0) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*((1.0 + 1.0/2.0*(((-1.0) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))));
[8e91f01]1636
[ae3ce4e]1637    t3 = ((C3*pow((((sqrt(Rg2)*q0)/b)),((-3.0)/miu)) + C2*pow((((sqrt(Rg2)*q0)/b)),((-2.0)/miu)) + C1*pow((((sqrt(Rg2)*q0)/b)),((-1.0)/miu))));
[8e91f01]1638
[ae3ce4e]1639    t4 = ((1.0 + tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5)));
[8e91f01]1640
[ae3ce4e]1641    t5 = (1.0/(b*p1*pow(q0,((-1.0) - p1 - p2)) - b*p2*pow(q0,((-1.0) - p1 - p2))));
[8e91f01]1642
[ae3ce4e]1643    t6 = (b*C*(((-((14.0*b3)/(15.0*q03*Rg2))) + (14.0*b3*pow(E,(-((q02*Rg2)/b2))))/(15.0*q03*Rg2) + (2.0*pow(E,(-((q02*Rg2)/b2)))*q0*((11.0/15.0 + (7.0*b2)/(15.0*q02*Rg2)))*Rg2)/b)));
[8e91f01]1644
[ae3ce4e]1645    t7 = (sqrt(Rg2)*((C3*pow((((sqrt(Rg2)*q0)/b)),((-3.0)/miu)) + C2*pow((((sqrt(Rg2)*q0)/b)),((-2.0)/miu)) + C1*pow((((sqrt(Rg2)*q0)/b)),((-1.0)/miu))))*pow(sech_WR(((-C4) + (sqrt(Rg2)*q0)/b)/C5),2));
[8e91f01]1646
[ae3ce4e]1647    t8 = (b4*sqrt(Rg2)*(((-1.0) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*pow(sech_WR(((-C4) + (sqrt(Rg2)*q0)/b)/C5),2));
[8e91f01]1648
[ae3ce4e]1649    t9 = (2.0*b4*(((2.0*q0*Rg2)/b - (2.0*pow(E,(-((q02*Rg2)/b2)))*q0*Rg2)/b))*((1.0 + 1.0/2.0*(((-1.0) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))));
[8e91f01]1650
[ae3ce4e]1651    t10 = (8.0*b4*b*(((-1.0) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*((1.0 + 1.0/2.0*(((-1.0) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))));
[8e91f01]1652
[ae3ce4e]1653    t11 = (((-((3.0*C3*sqrt(Rg2)*pow((((sqrt(Rg2)*q0)/b)),((-1.0) - 3.0/miu)))/miu)) - (2.0*C2*sqrt(Rg2)*pow((((sqrt(Rg2)*q0)/b)),((-1.0) - 2.0/miu)))/miu - (C1*sqrt(Rg2)*pow((((sqrt(Rg2)*q0)/b)),((-1.0) - 1.0/miu)))/miu));
[8e91f01]1654
[ae3ce4e]1655    t12 = ((1.0 + tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5)));
[8e91f01]1656
[ae3ce4e]1657    t13 = (b*C*((4.0/15.0 - pow(E,(-((q02*Rg2)/b2)))*((11.0/15.0 + (7.0*b2)/(15.0*q02* Rg2))) + (7.0*b2)/(15.0*q02*Rg2))));
[8e91f01]1658
[ae3ce4e]1659    t14 = (2.0*b4*(((-1.0) + pow(E,(-((q02*Rg2)/b2))) + (q02*Rg2)/b2))*((1.0 + 1.0/2.0*(((-1.0) - tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5))))));
[8e91f01]1660
[ae3ce4e]1661    t15 = ((C3*pow((((sqrt(Rg2)*q0)/b)),((-3.0)/miu)) + C2*pow((((sqrt(Rg2)*q0)/b)),((-2.0)/miu)) + C1*pow((((sqrt(Rg2)*q0)/b)),((-1.0)/miu))));
[8e91f01]1662
1663
[ae3ce4e]1664    yy = (pow(q0,p1)*(((-((b*pi)/(L*q0))) +t1/L +t2/(q04*Rg22) + 1.0/2.0*t3*t4)) + (t5*((pow(q0,(p1 - p2))*(((-pow(q0,(-p1)))*(((b2*pi)/(L*q02) +t6/L +t7/(2.0*C5) -t8/(C5*q04*Rg22) +t9/(q04*Rg22) -t10/(q05*Rg22) + 1.0/2.0*t11*t12)) - b*p1*pow(q0,((-1.0) - p1))*(((-((b*pi)/(L*q0))) +t13/L +t14/(q04*Rg22) + 1.0/2.0*t15*((1.0 + tanh(((-C4) + (sqrt(Rg2)*q0)/b)/C5)))))))))));
[8e91f01]1665
[ae3ce4e]1666    return (yy);
1667}
1668
1669
1670
1671///////////////
1672
1673//
1674//     FUNCTION gfn2:    CONTAINS F(Q,A,B,mu)**2  AS GIVEN
[8e91f01]1675//                       BY (53) AND (56,57) IN CHEN AND
[ae3ce4e]1676//                       KOTLARCHYK REFERENCE
1677//
1678//     <PROLATE ELLIPSOIDS>
1679//
1680double
1681gfn2(double xx, double crmaj, double crmin, double trmaj, double trmin, double delpc, double delps, double qq)
1682{
1683        // local variables
1684        double aa,bb,u2,ut2,uq,ut,vc,vt,gfnc,gfnt,gfn2,pi43,gfn,Pi;
[8e91f01]1685
[ae3ce4e]1686        Pi = 4.0*atan(1.0);
[8e91f01]1687
[ae3ce4e]1688        pi43=4.0/3.0*Pi;
1689        aa = crmaj;
1690        bb = crmin;
1691        u2 = (aa*aa*xx*xx + bb*bb*(1.0-xx*xx));
1692        ut2 = (trmaj*trmaj*xx*xx + trmin*trmin*(1.0-xx*xx));
1693        uq = sqrt(u2)*qq;
1694        ut= sqrt(ut2)*qq;
1695        vc = pi43*aa*bb*bb;
1696        vt = pi43*trmaj*trmin*trmin;
1697        gfnc = 3.0*(sin(uq)/uq/uq - cos(uq)/uq)/uq*vc*delpc;
1698        gfnt = 3.0*(sin(ut)/ut/ut - cos(ut)/ut)/ut*vt*delps;
1699        gfn = gfnc+gfnt;
1700        gfn2 = gfn*gfn;
[8e91f01]1701
[ae3ce4e]1702        return (gfn2);
1703}
1704
1705//
1706//     FUNCTION gfn4:    CONTAINS F(Q,A,B,MU)**2  AS GIVEN
1707//                       BY (53) & (58-59) IN CHEN AND
1708//                       KOTLARCHYK REFERENCE
1709//
1710//       <OBLATE ELLIPSOID>
[8e91f01]1711// function gfn4 for oblate ellipsoids
[ae3ce4e]1712double
1713gfn4(double xx, double crmaj, double crmin, double trmaj, double trmin, double delpc, double delps, double qq)
1714{
1715        // local variables
1716        double aa,bb,u2,ut2,uq,ut,vc,vt,gfnc,gfnt,tgfn,gfn4,pi43,Pi;
[8e91f01]1717
[ae3ce4e]1718        Pi = 4.0*atan(1.0);
1719        pi43=4.0/3.0*Pi;
1720        aa = crmaj;
1721        bb = crmin;
1722        u2 = (bb*bb*xx*xx + aa*aa*(1.0-xx*xx));
1723        ut2 = (trmin*trmin*xx*xx + trmaj*trmaj*(1.0-xx*xx));
1724        uq = sqrt(u2)*qq;
1725        ut= sqrt(ut2)*qq;
1726        vc = pi43*aa*aa*bb;
1727        vt = pi43*trmaj*trmaj*trmin;
1728        gfnc = 3.0*(sin(uq)/uq/uq - cos(uq)/uq)/uq*vc*delpc;
1729        gfnt = 3.0*(sin(ut)/ut/ut - cos(ut)/ut)/ut*vt*delps;
1730        tgfn = gfnc+gfnt;
1731        gfn4 = tgfn*tgfn;
[8e91f01]1732
[ae3ce4e]1733        return (gfn4);
1734}
1735
1736double
1737FlePolyLen_kernel(double q, double radius, double length, double lb, double zz, double delrho, double zi)
1738{
1739    double Pq,vcyl,dl;
1740    double Pi,qr;
[8e91f01]1741
[ae3ce4e]1742    Pi = 4.0*atan(1.0);
1743    qr = q*radius;
[8e91f01]1744
[ae3ce4e]1745    Pq = Sk_WR(q,zi,lb);                //does not have cross section term
1746    Pq *= (2.0*NR_BessJ1(qr)/qr)*(2.0*NR_BessJ1(qr)/qr);
[8e91f01]1747
[ae3ce4e]1748    vcyl=Pi*radius*radius*zi;
1749    Pq *= vcyl*vcyl;
[8e91f01]1750
[ae3ce4e]1751    dl = SchulzPoint_cpr(zi,length,zz);
[8e91f01]1752    return (Pq*dl);
1753
[ae3ce4e]1754}
1755
1756double
1757FlePolyRad_kernel(double q, double ravg, double Lc, double Lb, double zz, double delrho, double zi)
1758{
1759    double Pq,vcyl,dr;
1760    double Pi,qr;
[8e91f01]1761
[ae3ce4e]1762    Pi = 4.0*atan(1.0);
1763    qr = q*zi;
[8e91f01]1764
[ae3ce4e]1765    Pq = Sk_WR(q,Lc,Lb);                //does not have cross section term
1766    Pq *= (2.0*NR_BessJ1(qr)/qr)*(2.0*NR_BessJ1(qr)/qr);
[8e91f01]1767
[ae3ce4e]1768    vcyl=Pi*zi*zi*Lc;
1769    Pq *= vcyl*vcyl;
[8e91f01]1770
[ae3ce4e]1771    dr = SchulzPoint_cpr(zi,ravg,zz);
[8e91f01]1772    return (Pq*dr);
1773
[ae3ce4e]1774}
1775
1776double
1777CSCylIntegration(double qq, double rad, double radthick, double facthick, double rhoc, double rhos, double rhosolv, double length)
1778{
1779        double answer,halfheight,Pi;
1780        double lolim,uplim,summ,yyy,zi;
1781        int nord,i;
[8e91f01]1782
1783        // set up the integration end points
[ae3ce4e]1784        Pi = 4.0*atan(1.0);
1785        nord = 76;
1786        lolim = 0;
1787        uplim = Pi/2;
1788        halfheight = length/2.0;
[8e91f01]1789
[ae3ce4e]1790        summ = 0.0;                             // initialize integral
1791        i=0;
1792        for(i=0;i<nord;i++) {
1793                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1794                yyy = Gauss76Wt[i] * CScyl(qq, rad, radthick, facthick, rhoc,rhos,rhosolv, halfheight, zi);
1795                summ += yyy;
1796        }
[8e91f01]1797
[ae3ce4e]1798        // calculate value of integral to return
1799        answer = (uplim-lolim)/2.0*summ;
1800        return (answer);
1801}
1802
1803double
1804CScyl(double qq, double rad, double radthick, double facthick, double rhoc, double rhos, double rhosolv, double length, double dum)
[8e91f01]1805{
[ae3ce4e]1806        // qq is the q-value for the calculation (1/A)
1807        // radius is the core radius of the cylinder (A)
1808        //  radthick and facthick are the radial and face layer thicknesses
1809        // rho(n) are the respective SLD's
[8e91f01]1810        // length is the *Half* CORE-LENGTH of the cylinder
[ae3ce4e]1811        // dum is the dummy variable for the integration (theta)
[8e91f01]1812
[ae3ce4e]1813        double dr1,dr2,besarg1,besarg2,vol1,vol2,sinarg1,sinarg2,t1,t2,retval;
1814        double Pi;
[8e91f01]1815
1816        Pi = 4.0*atan(1.0);
1817
[ae3ce4e]1818        dr1 = rhoc-rhos;
1819        dr2 = rhos-rhosolv;
1820        vol1 = Pi*rad*rad*(2.0*length);
1821        vol2 = Pi*(rad+radthick)*(rad+radthick)*(2.0*length+2.0*facthick);
[8e91f01]1822
[ae3ce4e]1823        besarg1 = qq*rad*sin(dum);
1824        besarg2 = qq*(rad+radthick)*sin(dum);
1825        sinarg1 = qq*length*cos(dum);
1826        sinarg2 = qq*(length+facthick)*cos(dum);
[8e91f01]1827
[ae3ce4e]1828        t1 = 2.0*vol1*dr1*sin(sinarg1)/sinarg1*NR_BessJ1(besarg1)/besarg1;
1829        t2 = 2.0*vol2*dr2*sin(sinarg2)/sinarg2*NR_BessJ1(besarg2)/besarg2;
[8e91f01]1830
[ae3ce4e]1831        retval = ((t1+t2)*(t1+t2))*sin(dum);
1832        return (retval);
[8e91f01]1833
[ae3ce4e]1834}
1835
1836
1837double
1838CoreShellCylKernel(double qq, double rcore, double thick, double rhoc, double rhos, double rhosolv, double length, double dum)
1839{
[8e91f01]1840
[ae3ce4e]1841    double dr1,dr2,besarg1,besarg2,vol1,vol2,sinarg1,sinarg2,t1,t2,retval;
1842    double Pi;
[8e91f01]1843
[ae3ce4e]1844    Pi = 4.0*atan(1.0);
[8e91f01]1845
[ae3ce4e]1846    dr1 = rhoc-rhos;
1847    dr2 = rhos-rhosolv;
1848    vol1 = Pi*rcore*rcore*(2.0*length);
1849    vol2 = Pi*(rcore+thick)*(rcore+thick)*(2.0*length+2.0*thick);
[8e91f01]1850
[ae3ce4e]1851    besarg1 = qq*rcore*sin(dum);
1852    besarg2 = qq*(rcore+thick)*sin(dum);
1853    sinarg1 = qq*length*cos(dum);
1854    sinarg2 = qq*(length+thick)*cos(dum);
[8e91f01]1855
[ae3ce4e]1856    t1 = 2.0*vol1*dr1*sin(sinarg1)/sinarg1*NR_BessJ1(besarg1)/besarg1;
1857    t2 = 2.0*vol2*dr2*sin(sinarg2)/sinarg2*NR_BessJ1(besarg2)/besarg2;
[8e91f01]1858
[ae3ce4e]1859    retval = ((t1+t2)*(t1+t2))*sin(dum);
[8e91f01]1860
[ae3ce4e]1861    return (retval);
1862}
1863
1864double
1865Cyl_PolyLenKernel(double q, double radius, double len_avg, double zz, double delrho, double dumLen)
1866{
[8e91f01]1867
[ae3ce4e]1868    double halfheight,uplim,lolim,zi,summ,yyy,Pi;
1869    double answer,dr,Vcyl;
1870    int i,nord;
[8e91f01]1871
[ae3ce4e]1872    Pi = 4.0*atan(1.0);
1873    lolim = 0;
1874    uplim = Pi/2.0;
1875    halfheight = dumLen/2.0;
1876    nord=20;
1877    summ = 0.0;
[8e91f01]1878
[ae3ce4e]1879    //do the cylinder orientational average
1880    for(i=0;i<nord;i++) {
1881                zi = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1882                yyy = Gauss20Wt[i] * CylKernel(q, radius, halfheight, zi);
1883                summ += yyy;
1884    }
1885    answer = (uplim-lolim)/2.0*summ;
1886    // Multiply by contrast^2
1887    answer *= delrho*delrho;
1888    // don't do the normal scaling to volume here
1889    // instead, multiply by VCyl^2 to get rid of the normalization for this radius of cylinder
1890    Vcyl = Pi*radius*radius*dumLen;
1891    answer *= Vcyl*Vcyl;
[8e91f01]1892
[ae3ce4e]1893    dr = SchulzPoint_cpr(dumLen,len_avg,zz);
1894    return(dr*answer);
1895}
1896
1897
1898double
1899Stackdisc_kern(double qq, double rcore, double rhoc, double rhol, double rhosolv, double length, double thick, double dum, double gsd, double d, double N)
[8e91f01]1900{
[ae3ce4e]1901        // qq is the q-value for the calculation (1/A)
1902        // rcore is the core radius of the cylinder (A)
1903        // rho(n) are the respective SLD's
1904        // length is the *Half* CORE-LENGTH of the cylinder = L (A)
1905        // dum is the dummy variable for the integration (x in Feigin's notation)
[8e91f01]1906
1907        //Local variables
[ae3ce4e]1908        double totald,dr1,dr2,besarg1,besarg2,area,sinarg1,sinarg2,t1,t2,retval,sqq,dexpt;
1909        double Pi;
1910        int kk;
[8e91f01]1911
[ae3ce4e]1912        Pi = 4.0*atan(1.0);
[8e91f01]1913
[ae3ce4e]1914        dr1 = rhoc-rhosolv;
1915        dr2 = rhol-rhosolv;
1916        area = Pi*rcore*rcore;
1917        totald=2.0*(thick+length);
[8e91f01]1918
[ae3ce4e]1919        besarg1 = qq*rcore*sin(dum);
1920        besarg2 = qq*rcore*sin(dum);
[8e91f01]1921
[ae3ce4e]1922        sinarg1 = qq*length*cos(dum);
1923        sinarg2 = qq*(length+thick)*cos(dum);
[8e91f01]1924
[ae3ce4e]1925        t1 = 2*area*(2*length)*dr1*(sin(sinarg1)/sinarg1)*(NR_BessJ1(besarg1)/besarg1);
1926        t2 = 2*area*dr2*(totald*sin(sinarg2)/sinarg2-2*length*sin(sinarg1)/sinarg1)*(NR_BessJ1(besarg2)/besarg2);
[8e91f01]1927
[ae3ce4e]1928        retval =((t1+t2)*(t1+t2))*sin(dum);
[8e91f01]1929
[ae3ce4e]1930        // loop for the structure facture S(q)
1931        sqq=0.0;
1932        for(kk=1;kk<N;kk+=1) {
1933                dexpt=qq*cos(dum)*qq*cos(dum)*d*d*gsd*gsd*kk/2.0;
1934                sqq=sqq+(N-kk)*cos(qq*cos(dum)*d*kk)*exp(-1.*dexpt);
[8e91f01]1935        }
1936
[ae3ce4e]1937        // end of loop for S(q)
1938        sqq=1.0+2.0*sqq/N;
1939        retval *= sqq;
[8e91f01]1940
[ae3ce4e]1941        return(retval);
1942}
1943
1944
1945double
1946Cyl_PolyRadKernel(double q, double radius, double length, double zz, double delrho, double dumRad)
1947{
[8e91f01]1948
[ae3ce4e]1949    double halfheight,uplim,lolim,zi,summ,yyy,Pi;
1950    double answer,dr,Vcyl;
1951    int i,nord;
[8e91f01]1952
[ae3ce4e]1953    Pi = 4.0*atan(1.0);
1954    lolim = 0;
1955    uplim = Pi/2.0;
1956    halfheight = length/2.0;
1957        //    nord=20;
1958    nord=76;
1959    summ = 0.0;
[8e91f01]1960
[ae3ce4e]1961    //do the cylinder orientational average
1962        //    for(i=0;i<nord;i++) {
1963        //            zi = ( Gauss20Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1964        //            yyy = Gauss20Wt[i] * CylKernel(q, dumRad, halfheight, zi);
1965        //            summ += yyy;
1966        //    }
1967    for(i=0;i<nord;i++) {
1968                zi = ( Gauss76Z[i]*(uplim-lolim) + uplim + lolim )/2.0;
1969                yyy = Gauss76Wt[i] * CylKernel(q, dumRad, halfheight, zi);
1970                summ += yyy;
1971    }
1972    answer = (uplim-lolim)/2.0*summ;
1973    // Multiply by contrast^2
1974    answer *= delrho*delrho;
1975    // don't do the normal scaling to volume here
1976    // instead, multiply by VCyl^2 to get rid of the normalization for this radius of cylinder
1977    Vcyl = Pi*dumRad*dumRad*length;
1978    answer *= Vcyl*Vcyl;
[8e91f01]1979
[ae3ce4e]1980    dr = SchulzPoint_cpr(dumRad,radius,zz);
1981    return(dr*answer);
1982}
1983
1984double
1985SchulzPoint_cpr(double dumRad, double radius, double zz)
1986{
1987    double dr;
[8e91f01]1988
[ae3ce4e]1989    dr = zz*log(dumRad) - gammaln(zz+1.0) + (zz+1.0)*log((zz+1.0)/radius)-(dumRad/radius*(zz+1.0));
1990    return(exp(dr));
1991}
1992
1993static double
1994gammaln(double xx)
1995{
1996        double x,y,tmp,ser;
1997        static double cof[6]={76.18009172947146,-86.50532032941677,
1998                24.01409824083091,-1.231739572450155,
1999                0.1208650973866179e-2,-0.5395239384953e-5};
2000        int j;
[8e91f01]2001
[ae3ce4e]2002        y=x=xx;
2003        tmp=x+5.5;
2004        tmp -= (x+0.5)*log(tmp);
2005        ser=1.000000000190015;
2006        for (j=0;j<=5;j++) ser += cof[j]/++y;
2007        return -tmp+log(2.5066282746310005*ser/x);
2008}
2009
2010
2011double
2012EllipsoidKernel(double qq, double a, double nua, double dum)
2013{
2014    double arg,nu,retval;               //local variables
[8e91f01]2015
[ae3ce4e]2016    nu = nua/a;
2017    arg = qq*a*sqrt(1+dum*dum*(nu*nu-1));
[8e91f01]2018
[ae3ce4e]2019    retval = (sin(arg)-arg*cos(arg))/(arg*arg*arg);
2020    retval *= retval;
2021    retval *= 9;
[8e91f01]2022
[ae3ce4e]2023    return(retval);
2024}//Function EllipsoidKernel()
2025
2026double
2027HolCylKernel(double qq, double rcore, double rshell, double length, double dum)
2028{
2029    double gamma,arg1,arg2,lam1,lam2,psi,sinarg,t2,retval;              //local variables
[8e91f01]2030
[ae3ce4e]2031    gamma = rcore/rshell;
2032    arg1 = qq*rshell*sqrt(1-dum*dum);           //1=shell (outer radius)
2033    arg2 = qq*rcore*sqrt(1-dum*dum);                    //2=core (inner radius)
2034    lam1 = 2*NR_BessJ1(arg1)/arg1;
2035    lam2 = 2*NR_BessJ1(arg2)/arg2;
2036    psi = 1/(1-gamma*gamma)*(lam1 -  gamma*gamma*lam2);         //SRK 10/19/00
[8e91f01]2037
[ae3ce4e]2038    sinarg = qq*length*dum/2;
2039    t2 = sin(sinarg)/sinarg;
[8e91f01]2040
[ae3ce4e]2041    retval = psi*psi*t2*t2;
[8e91f01]2042
[ae3ce4e]2043    return(retval);
2044}//Function HolCylKernel()
2045
2046double
2047PPKernel(double aa, double mu, double uu)
2048{
2049    // mu passed in is really mu*sqrt(1-sig^2)
2050    double arg1,arg2,Pi,tmp1,tmp2;                      //local variables
[8e91f01]2051
[ae3ce4e]2052    Pi = 4.0*atan(1.0);
[8e91f01]2053
[ae3ce4e]2054    //handle arg=0 separately, as sin(t)/t -> 1 as t->0
2055    arg1 = (mu/2)*cos(Pi*uu/2);
2056    arg2 = (mu*aa/2)*sin(Pi*uu/2);
2057    if(arg1==0) {
2058                tmp1 = 1;
2059        } else {
2060                tmp1 = sin(arg1)*sin(arg1)/arg1/arg1;
2061    }
[8e91f01]2062
[ae3ce4e]2063    if (arg2==0) {
2064                tmp2 = 1;
2065        } else {
2066                tmp2 = sin(arg2)*sin(arg2)/arg2/arg2;
2067    }
[8e91f01]2068
[ae3ce4e]2069    return (tmp1*tmp2);
[8e91f01]2070
[ae3ce4e]2071}//Function PPKernel()
2072
2073
2074double
2075TriaxialKernel(double q, double aa, double bb, double cc, double dx, double dy)
2076{
[8e91f01]2077
[ae3ce4e]2078    double arg,val,pi;                  //local variables
[8e91f01]2079
[ae3ce4e]2080    pi = 4.0*atan(1.0);
[8e91f01]2081
[ae3ce4e]2082    arg = aa*aa*cos(pi*dx/2)*cos(pi*dx/2);
2083    arg += bb*bb*sin(pi*dx/2)*sin(pi*dx/2)*(1-dy*dy);
2084    arg += cc*cc*dy*dy;
2085    arg = q*sqrt(arg);
2086    val = 9 * ( (sin(arg) - arg*cos(arg))/(arg*arg*arg) ) * ( (sin(arg) - arg*cos(arg))/(arg*arg*arg) );
[8e91f01]2087
[ae3ce4e]2088    return (val);
[8e91f01]2089
[ae3ce4e]2090}//Function TriaxialKernel()
2091
2092
2093double
2094CylKernel(double qq, double rr,double h, double theta)
2095{
[8e91f01]2096
[ae3ce4e]2097        // qq is the q-value for the calculation (1/A)
2098        // rr is the radius of the cylinder (A)
2099        // h is the HALF-LENGTH of the cylinder = L/2 (A)
[8e91f01]2100
2101    double besarg,bj,retval,d1,t1,b1,t2,b2;              //Local variables
2102
2103
[ae3ce4e]2104    besarg = qq*rr*sin(theta);
[8e91f01]2105
[ae3ce4e]2106    bj =NR_BessJ1(besarg);
[8e91f01]2107
[ae3ce4e]2108        //* Computing 2nd power */
2109    d1 = sin(qq * h * cos(theta));
2110    t1 = d1 * d1;
2111        //* Computing 2nd power */
2112    d1 = bj;
2113    t2 = d1 * d1 * 4.0 * sin(theta);
2114        //* Computing 2nd power */
2115    d1 = qq * h * cos(theta);
2116    b1 = d1 * d1;
2117        //* Computing 2nd power */
2118    d1 = qq * rr * sin(theta);
2119    b2 = d1 * d1;
2120    retval = t1 * t2 / b1 / b2;
[8e91f01]2121
[ae3ce4e]2122    return (retval);
[8e91f01]2123
[ae3ce4e]2124}//Function CylKernel()
2125
2126double
2127EllipCylKernel(double qq, double ra,double nu, double theta)
2128{
[8e91f01]2129        //this is the function LAMBDA1^2 in Feigin's notation
[ae3ce4e]2130        // qq is the q-value for the calculation (1/A)
2131        // ra is the transformed radius"a" in Feigin's notation
2132        // nu is the ratio (major radius)/(minor radius) of the Ellipsoid [=] ---
2133        // theta is the dummy variable of the integration
[8e91f01]2134
2135        double retval,arg;               //Local variables
2136
[ae3ce4e]2137        arg = qq*ra*sqrt((1+nu*nu)/2+(1-nu*nu)*cos(theta)/2);
[8e91f01]2138
[ae3ce4e]2139        retval = 2*NR_BessJ1(arg)/arg;
[8e91f01]2140
[ae3ce4e]2141        //square it
2142        retval *= retval;
[8e91f01]2143
[ae3ce4e]2144    return(retval);
[8e91f01]2145
[ae3ce4e]2146}//Function EllipCylKernel()
2147
2148double NR_BessJ1(double x)
2149{
2150        double ax,z;
2151        double xx,y,ans,ans1,ans2;
[8e91f01]2152
[ae3ce4e]2153        if ((ax=fabs(x)) < 8.0) {
2154                y=x*x;
2155                ans1=x*(72362614232.0+y*(-7895059235.0+y*(242396853.1
2156                                                                                                  +y*(-2972611.439+y*(15704.48260+y*(-30.16036606))))));
2157                ans2=144725228442.0+y*(2300535178.0+y*(18583304.74
2158                                                                                           +y*(99447.43394+y*(376.9991397+y*1.0))));
2159                ans=ans1/ans2;
2160        } else {
2161                z=8.0/ax;
2162                y=z*z;
2163                xx=ax-2.356194491;
2164                ans1=1.0+y*(0.183105e-2+y*(-0.3516396496e-4
2165                                                                   +y*(0.2457520174e-5+y*(-0.240337019e-6))));
2166                ans2=0.04687499995+y*(-0.2002690873e-3
2167                                                          +y*(0.8449199096e-5+y*(-0.88228987e-6
2168                                                                                                         +y*0.105787412e-6)));
2169                ans=sqrt(0.636619772/ax)*(cos(xx)*ans1-z*sin(xx)*ans2);
2170                if (x < 0.0) ans = -ans;
2171        }
[8e91f01]2172
[ae3ce4e]2173        return(ans);
2174}
Note: See TracBrowser for help on using the repository browser.