source: sasview/sansmodels/src/sans/models/c_extensions/barbell.c @ 830622f

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 830622f was 6e24633, checked in by Mathieu Doucet <doucetm@…>, 13 years ago

Re #5 fixing samsmodels compilation on MSVC

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 * Scattering model for a BarBell
3 */
4#include "barbell.h"
5#include <math.h>
6#include "GaussWeights.h"
7#include "libCylinder.h"
8
9/**
10 * Function to evaluate 1D scattering function
11 * @param pars: parameters of the BarBell
12 * @param q: q-value
13 * @return: function value
14 */
15double barbell_analytical_1D(BarBellParameters *pars, double q) {
16        double dp[7];
17        double result;
18
19        dp[0] = pars->scale;
20        dp[1] = pars->rad_bar;
21        dp[2] = pars->len_bar;
22        dp[3] = pars->rad_bell;
23        dp[4] = pars->sld_barbell;
24        dp[5] = pars->sld_solv;
25        dp[6] = pars->background;
26
27        result = Barbell(dp, q);
28        // Make Sure it never goes to inf/nan.
29        if ( result == INFINITY || result == NAN){
30                result = pars->background;
31        }
32        return result;
33}
34
35
36double bar2d_kernel(double dp[], double q, double alpha) {
37        int i,j;
38        double Pi;
39        double scale,contr,bkg,sldc,slds;
40        double len,rad,hDist,endRad;
41        int nordj=76;
42        double zi=alpha,yyy,answer;                     //running tally of integration
43        double summj,vaj,vbj,zij;                       //for the inner integration
44        double arg1,arg2,inner,be;
45
46
47        scale = dp[0];
48        rad = dp[1];
49        len = dp[2];
50        endRad = dp[3];
51        sldc = dp[4];
52        slds = dp[5];
53        bkg = dp[6];
54
55        hDist = sqrt(fabs(endRad*endRad-rad*rad));              //by definition for this model
56
57        contr = sldc-slds;
58
59        Pi = 4.0*atan(1.0);
60        vaj = -1.0*hDist/endRad;
61        vbj = 1.0;              //endpoints of inner integral
62
63        summj=0.0;
64
65        for(j=0;j<nordj;j++) {
66                //20 gauss points for the inner integral
67                zij = ( Gauss76Z[j]*(vbj-vaj) + vaj + vbj )/2.0;                //the "t" dummy
68                yyy = Gauss76Wt[j] * Dumb_kernel(dp,q,zij,zi);          //uses the same Kernel as the Dumbbell, here L>0
69                summj += yyy;
70        }
71        //now calculate the value of the inner integral
72        inner = (vbj-vaj)/2.0*summj;
73        inner *= 4.0*Pi*endRad*endRad*endRad;
74
75        //now calculate outer integrand
76        arg1 = q*len/2.0*cos(zi);
77        arg2 = q*rad*sin(zi);
78        yyy = inner;
79
80        if(arg2 == 0) {
81                be = 0.5;
82        } else {
83                be = NR_BessJ1(arg2)/arg2;
84        }
85
86        if(arg1 == 0.0) {               //limiting value of sinc(0) is 1; sinc is not defined in math.h
87                yyy += Pi*rad*rad*len*2.0*be;
88        } else {
89                yyy += Pi*rad*rad*len*sin(arg1)/arg1*2.0*be;
90        }
91        yyy *= yyy;   //sin(zi);
92        answer = yyy;
93
94
95        answer /= Pi*rad*rad*len + 2.0*Pi*(2.0*endRad*endRad*endRad/3.0+endRad*endRad*hDist-hDist*hDist*hDist/3.0);             //divide by volume
96        answer *= 1.0e8;                //convert to cm^-1
97        answer *= contr*contr;
98        answer *= scale;
99        answer += bkg;
100
101        return answer;
102}
103
104
105/**
106 * Function to evaluate 2D scattering function
107 * @param pars: parameters of the BarBell
108 * @param q: q-value
109 * @return: function value
110 */
111double barbell_analytical_2DXY(BarBellParameters *pars, double qx, double qy){
112        double q;
113        q = sqrt(qx*qx+qy*qy);
114        return barbell_analytical_2D_scaled(pars, q, qx/q, qy/q);
115}
116
117double barbell_analytical_2D(BarBellParameters *pars, double q, double phi) {
118        return barbell_analytical_2D_scaled(pars, q, cos(phi), sin(phi));
119}
120
121/**
122 * Function to evaluate 2D scattering function
123 * @param pars: parameters of the BarBell
124 * @param q: q-value
125 * @param q_x: q_x / q
126 * @param q_y: q_y / q
127 * @return: function value
128 */
129double barbell_analytical_2D_scaled(BarBellParameters *pars, double q, double q_x, double q_y) {
130        double cyl_x, cyl_y, cyl_z;
131        double q_z;
132        double alpha, vol, cos_val;
133        double answer;
134        double dp[7];
135  //convert angle degree to radian
136  double pi = 4.0*atan(1.0);
137  double theta = pars->theta * pi/180.0;
138  double phi = pars->phi * pi/180.0;
139
140        dp[0] = pars->scale;
141        dp[1] = pars->rad_bar;
142        dp[2] = pars->len_bar;
143        dp[3] = pars->rad_bell;
144        dp[4] = pars->sld_barbell;
145        dp[5] = pars->sld_solv;
146        dp[6] = pars->background;
147
148        //double Pi = 4.0*atan(1.0);
149    // Cylinder orientation
150    cyl_x = sin(theta) * cos(phi);
151    cyl_y = sin(theta) * sin(phi);
152    cyl_z = cos(theta);
153
154    // q vector
155    q_z = 0;
156
157    // Compute the angle btw vector q and the
158    // axis of the cylinder
159    cos_val = cyl_x*q_x + cyl_y*q_y + cyl_z*q_z;
160
161    // The following test should always pass
162    if (fabs(cos_val)>1.0) {
163        return 0;
164    }
165
166    // Note: cos(alpha) = 0 and 1 will get an
167    // undefined value from CylKernel
168        alpha = acos( cos_val );
169
170        // Call the IGOR library function to get the kernel
171        answer = bar2d_kernel(dp, q, alpha)/sin(alpha);
172
173
174        return answer;
175
176}
Note: See TracBrowser for help on using the repository browser.