source: sasview/sansmodels/src/sans/models/c_extensions/csparallelepiped.c @ 9f391af

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 9f391af was 4628e31, checked in by Jae Cho <jhjcho@…>, 14 years ago

changed the unit of angles into degrees

  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[18f2ca1]1/**
2 * Scattering model for a csparallelepiped
3 */
4
5#include "csparallelepiped.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 CSparallelepiped
15 * @param q: q-value
16 * @return: function value
17 */
18double csparallelepiped_analytical_1D(CSParallelepipedParameters *pars, double q) {
19        double dp[13];
20
21        // Fill paramater array
22        dp[0] = pars->scale;
23        dp[1] = pars->shortA;
24        dp[2] = pars->midB;
25        dp[3] = pars->longC;
26        dp[4] = pars->rimA;
27        dp[5] = pars->rimB;
28        dp[6] = pars->rimC;
29        dp[7] = pars->sld_rimA;
30        dp[8] = pars->sld_rimB;
31        dp[9] = pars->sld_rimC;
32        dp[10] = pars->sld_pcore;
33        dp[11] = pars->sld_solv;
34        dp[12] = pars->background;
35
36        // Call library function to evaluate model
37        //ToDo: Correct this 1d model, CSParallelepiped in libigor (2D corrected).
38        return CSParallelepiped(dp, q);
39}
40
41
42double cspkernel(double dp[],double q, double ala, double alb, double alc){
43    // mu passed in is really mu*sqrt(1-sig^2)
44    double argA,argB,argC,argtA,argtB,argtC,tmp1,tmp2,tmp3,tmpt1,tmpt2,tmpt3;                   //local variables
45
46        double aa,bb,cc, ta,tb,tc;
47        double Vin,Vot,V1,V2,V3;
48        double rhoA,rhoB,rhoC, rhoP, rhosolv;
49        double dr0, drA,drB, drC;
[4628e31]50        double retVal;
[18f2ca1]51
52        aa = dp[1];
53        bb = dp[2];
54        cc = dp[3];
55        ta = dp[4];
56        tb = dp[5];
57        tc = dp[6];
58        rhoA=dp[7];
59        rhoB=dp[8];
60        rhoC=dp[9];
61        rhoP=dp[10];
62        rhosolv=dp[11];
63        dr0=rhoP-rhosolv;
64        drA=rhoA-rhosolv;
65        drB=rhoB-rhosolv;
66        drC=rhoC-rhosolv;
67        Vin=(aa*bb*cc);
68        Vot=(aa*bb*cc+2.0*ta*bb*cc+2.0*aa*tb*cc+2.0*aa*bb*tc);
69        V1=(2.0*ta*bb*cc);   //  incorrect V1 (aa*bb*cc+2*ta*bb*cc)
70        V2=(2.0*aa*tb*cc);  // incorrect V2(aa*bb*cc+2*aa*tb*cc)
71        V3=(2.0*aa*bb*tc);
72        //aa = aa/bb;
73        ta=(aa+2.0*ta);///bb;
74        tb=(aa+2.0*tb);///bb;
75        tc=(aa+2.0*tc);
76    //handle arg=0 separately, as sin(t)/t -> 1 as t->0
77    argA = q*aa*ala/2.0;
78    argB = q*bb*alb/2.0;
79    argC = q*cc*alc/2.0;
80    argtA = q*ta*ala/2.0;
81        argtB = q*tb*alb/2.0;
82        argtC = q*tc*alc/2.0;
83
84    if(argA==0.0) {
85                tmp1 = 1.0;
86        } else {
87                tmp1 = sin(argA)/argA;
88    }
89    if (argB==0.0) {
90                tmp2 = 1.0;
91        } else {
92                tmp2 = sin(argB)/argB;
93    }
94
95    if (argC==0.0) {
96                tmp3 = 1.0;
97        } else {
98                tmp3 = sin(argC)/argC;
99    }
100    if(argtA==0.0) {
101                tmpt1 = 1.0;
102        } else {
103                tmpt1 = sin(argtA)/argtA;
104    }
105    if (argtB==0.0) {
106                tmpt2 = 1.0;
107        } else {
108                tmpt2 = sin(argtB)/argtB;
109    }
110    if (argtC==0.0) {
111                tmpt3 = 1.0;
112        } else {
113                tmpt3 = sin(argtC)*sin(argtC)/argtC/argtC;
114    }
115    // This expression is different from NIST/IGOR package (I strongly believe the IGOR is wrong!!!). 10/15/2010.
116    retVal =( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3)*
117                                ( dr0*tmp1*tmp2*tmp3*Vin + drA*(tmpt1-tmp1)*tmp2*tmp3*V1+ drB*tmp1*(tmpt2-tmp2)*tmp3*V2 + drC*tmp1*tmp2*(tmpt3-tmp3)*V3);   //  correct FF : square of sum of phase factors
118    //retVal *= (tmp3*tmp3);
119    retVal /= Vot;
120
121    return (retVal);
122
123}//Function cspkernel()
124
125
126
127
128/**
129 * Function to evaluate 2D scattering function
130 * @param pars: parameters of the CSparallelepiped
131 * @param q: q-value
132 * @return: function value
133 */
134double csparallelepiped_analytical_2DXY(CSParallelepipedParameters *pars, double qx, double qy) {
135        double q;
136        q = sqrt(qx*qx+qy*qy);
137    return csparallelepiped_analytical_2D_scaled(pars, q, qx/q, qy/q);
138}
139
140
141/**
142 * Function to evaluate 2D scattering function
143 * @param pars: parameters of the CSParallelepiped
144 * @param q: q-value
145 * @param phi: angle phi
146 * @return: function value
147 */
148double csparallelepiped_analytical_2D(CSParallelepipedParameters *pars, double q, double phi) {
149    return csparallelepiped_analytical_2D_scaled(pars, q, cos(phi), sin(phi));
150}
151
152/**
153 * Function to evaluate 2D scattering function
154 * @param pars: parameters of the CSparallelepiped
155 * @param q: q-value
156 * @param q_x: q_x / q
157 * @param q_y: q_y / q
158 * @return: function value
159 */
160double csparallelepiped_analytical_2D_scaled(CSParallelepipedParameters *pars, double q, double q_x, double q_y) {
161        double dp[13];
162
163        // Fill paramater array
164        dp[0] = 1.0;
165        dp[1] = pars->shortA;
166        dp[2] = pars->midB;
167        dp[3] = pars->longC;
168        dp[4] = pars->rimA;
169        dp[5] = pars->rimB;
170        dp[6] = pars->rimC;
171        dp[7] = pars->sld_rimA;
172        dp[8] = pars->sld_rimB;
173        dp[9] = pars->sld_rimC;
174        dp[10] = pars->sld_pcore;
175        dp[11] = pars->sld_solv;
176        dp[12] = 0.0;
177
178        double cparallel_x, cparallel_y, cparallel_z, bparallel_x, bparallel_y, parallel_x, parallel_y, parallel_z;
179        double q_z;
180        double alpha, vol, cos_val_c, cos_val_b, cos_val_a, edgeA, edgeB, edgeC;
181
182        double answer;
183
184        edgeA = pars->shortA;
185        edgeB = pars->midB;
186        edgeC = pars->longC;
187
[4628e31]188        //convert angle degree to radian
189        double pi = 4.0*atan(1.0);
190        double theta = pars->parallel_theta * pi/180.0;
191        double phi = pars->parallel_phi * pi/180.0;
192        double psi = pars->parallel_psi* pi/180.0;
[18f2ca1]193
194    // parallelepiped c axis orientation
[4628e31]195    cparallel_x = sin(theta) * cos(phi);
196    cparallel_y = sin(theta) * sin(phi);
197    cparallel_z = cos(theta);
[18f2ca1]198
199    // q vector
200    q_z = 0.0;
201
202    // Compute the angle btw vector q and the
203    // axis of the parallelepiped
204    cos_val_c = cparallel_x*q_x + cparallel_y*q_y + cparallel_z*q_z;
205    alpha = acos(cos_val_c);
206
207    // parallelepiped a axis orientation
[4628e31]208    parallel_x = sin(psi);//cos(pars->parallel_theta) * sin(pars->parallel_phi)*sin(pars->parallel_psi);
209    parallel_y = cos(psi);//cos(pars->parallel_theta) * cos(pars->parallel_phi)*cos(pars->parallel_psi);
[18f2ca1]210
211    cos_val_a = parallel_x*q_x + parallel_y*q_y;
212
213
214
215    // parallelepiped b axis orientation
[4628e31]216    bparallel_x = sqrt(1.0-sin(theta)*cos(phi))*cos(psi);//cos(pars->parallel_theta) * cos(pars->parallel_phi)* cos(pars->parallel_psi);
217    bparallel_y = sqrt(1.0-sin(theta)*cos(phi))*sin(psi);//cos(pars->parallel_theta) * sin(pars->parallel_phi)* sin(pars->parallel_psi);
[18f2ca1]218    // axis of the parallelepiped
219    cos_val_b = sin(acos(cos_val_a)) ;
220
221
222
223    // The following test should always pass
224    if (fabs(cos_val_c)>1.0) {
225        printf("parallel_ana_2D: Unexpected error: cos(alpha)>1\n");
226        return 0;
227    }
228
229        // Call the IGOR library function to get the kernel
230        answer = cspkernel( dp,q, sin(alpha)*cos_val_a,sin(alpha)*cos_val_b,cos_val_c);
231
232        //convert to [cm-1]
233        answer *= 1.0e8;
234
235        //Scale
236        answer *= pars->scale;
237
238        // add in the background
239        answer += pars->background;
240
241        return answer;
242}
243
Note: See TracBrowser for help on using the repository browser.