source: sasview/sansmodels/src/libigor/libCylinder.c @ 222d75c7

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 222d75c7 was 222d75c7, checked in by Jae Cho <jhjcho@…>, 15 years ago

reverted added lamellar_kernel

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