source: sasview/sansmodels/src/sans/models/c_extensions/elliptical_cylinder.c @ d734a3b1

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 d734a3b1 was f10063e, checked in by Jae Cho <jhjcho@…>, 14 years ago

Updated the definition of SLD params according to new libigor functions

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/**
2 * Scattering model for a cylinder with elliptical cross-section
3 */
4
5#include "elliptical_cylinder.h"
6#include <math.h>
7#include "libCylinder.h"
8#include <stdio.h>
9#include <stdlib.h>
10
11
12/**
13 * Function to evaluate 1D scattering function
14 * @param pars: parameters of the cylinder
15 * @param q: q-value
16 * @return: function value
17 */
18double elliptical_cylinder_analytical_1D(EllipticalCylinderParameters *pars, double q) {
19        double dp[7];
20
21        // Fill paramater array
22        dp[0] = pars->scale;
23        dp[1] = pars->r_minor;
24        dp[2] = pars->r_ratio;
25        dp[3] = pars->length;
26        dp[4] = pars->sldCyl;
27        dp[5] = pars->sldSolv;
28        dp[6] = pars->background;
29
30        // Call library function to evaluate model
31        return EllipCyl20(dp, q);
32}
33
34double elliptical_cylinder_kernel(EllipticalCylinderParameters *pars, double q, double alpha, double nu) {
35        double qr;
36        double qL;
37        double Be,Si;
38        double r_major;
39        double kernel;
40
41        r_major = pars->r_ratio * pars->r_minor;
42
43        qr = q*sin(alpha)*sqrt( r_major*r_major*sin(nu)*sin(nu) + pars->r_minor*pars->r_minor*cos(nu)*cos(nu) );
44        qL = q*pars->length*cos(alpha)/2.0;
45
46        if (qr==0){
47                Be = 0.5;
48        }else{
49                Be = NR_BessJ1(qr)/qr;
50        }
51        if (qL==0){
52                Si = 1.0;
53        }else{
54                Si = sin(qL)/qL;
55        }
56
57
58        kernel = 2.0*Be * Si;
59        return kernel*kernel;
60}
61
62/**
63 * Function to evaluate 2D scattering function
64 * @param pars: parameters of the cylinder
65 * @param q: q-value
66 * @return: function value
67 */
68double elliptical_cylinder_analytical_2DXY(EllipticalCylinderParameters *pars, double qx, double qy) {
69        double q;
70        q = sqrt(qx*qx+qy*qy);
71    return elliptical_cylinder_analytical_2D_scaled(pars, q, qx/q, qy/q);
72}
73
74/**
75 * Function to evaluate 2D scattering function
76 * @param pars: parameters of the cylinder
77 * @param q: q-value
78 * @param theta: angle theta = angle wrt z axis
79 * @param phi: angle phi = angle around y axis (starting from the x+-direction as phi = 0)
80 * @return: function value
81 */
82double elliptical_cylinder_analytical_2D(EllipticalCylinderParameters *pars, double q, double phi) {
83    return elliptical_cylinder_analytical_2D_scaled(pars, q, cos(phi), sin(phi));
84}
85
86/**
87 * Function to evaluate 2D scattering function
88 * @param pars: parameters of the cylinder
89 * @param q: q-value
90 * @param q_x: q_x / q
91 * @param q_y: q_y / q
92 * @return: function value
93 */
94double elliptical_cylinder_analytical_2D_scaled(EllipticalCylinderParameters *pars, double q, double q_x, double q_y) {
95        double cyl_x, cyl_y, cyl_z;
96        double ell_x, ell_y;
97        double q_z;
98        double alpha, vol, cos_val;
99        double nu, cos_nu;
100        double answer;
101
102    //Cylinder orientation
103    cyl_x = sin(pars->cyl_theta) * cos(pars->cyl_phi);
104    cyl_y = sin(pars->cyl_theta) * sin(pars->cyl_phi);
105    cyl_z = cos(pars->cyl_theta);
106
107    // q vector
108    q_z = 0;
109
110    // Compute the angle btw vector q and the
111    // axis of the cylinder
112    cos_val = cyl_x*q_x + cyl_y*q_y + cyl_z*q_z;
113
114    // The following test should always pass
115    if (fabs(cos_val)>1.0) {
116        printf("cyl_ana_2D: Unexpected error: cos(alpha)>1\n");
117        return 0;
118    }
119
120    // Note: cos(alpha) = 0 and 1 will get an
121    // undefined value from CylKernel
122        alpha = acos( cos_val );
123
124    //ellipse orientation:
125        // the elliptical corss section was transformed and projected
126        // into the detector plane already through sin(alpha)and furthermore psi remains as same
127        // on the detector plane.
128        // So, all we need is to calculate the angle (nu) of the minor axis of the ellipse wrt
129        // the wave vector q.
130
131        //x- y- component on the detector plane.
132    ell_x =  cos(pars->cyl_psi);
133    ell_y =  sin(pars->cyl_psi);
134
135    // calculate the axis of the ellipse wrt q-coord.
136    cos_nu = ell_x*q_x + ell_y*q_y;
137    nu = acos(cos_nu);
138
139    // The following test should always pass
140    if (fabs(cos_nu)>1.0) {
141        printf("cyl_ana_2D: Unexpected error: cos(nu)>1\n");
142        return 0;
143    }
144
145        answer = elliptical_cylinder_kernel(pars, q, alpha,nu);
146
147        // Multiply by contrast^2
148        answer *= (pars->sldCyl - pars->sldSolv) * (pars->sldCyl - pars->sldSolv);
149
150        //normalize by cylinder volume
151        //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
152    vol = acos(-1.0) * pars->r_minor * pars->r_minor * pars->r_ratio * pars->length;
153        answer *= vol;
154
155        //convert to [cm-1]
156        answer *= 1.0e8;
157
158        //Scale
159        answer *= pars->scale;
160
161        // add in the background
162        answer += pars->background;
163
164        return answer;
165}
166
Note: See TracBrowser for help on using the repository browser.