source: sasview/src/sas/sascalc/calculator/c_extensions/sld2i.c @ 7e82256

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 7e82256 was 7e82256, checked in by Paul Kienzle <pkienzle@…>, 6 years ago

declare all variables at the start of the block so C89 compilers don't complain

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/**
2Computes the (magnetic) scattering form sld (n and m) profile
3 */
4#include <stdio.h>
5#include <math.h>
6#include "sld2i.h"
7#include "libfunc.h"
8#include "librefl.h"
9/**
10 * Constructor for GenI
11 *
12 * binning
13 * //@param qx: array of Qx values
14 * //@param qy: array of Qy values
15 * //@param qz: array of Qz values
16 * @param x: array of x values
17 * @param y: array of y values
18 * @param z: array of z values
19 * @param sldn: array of sld n
20 * @param mx: array of sld mx
21 * @param my: array of sld my
22 * @param mz: array of sld mz
23 * @param in_spin: ratio of up spin in Iin
24 * @param out_spin: ratio of up spin in Iout
25 * @param s_theta: angle (from x-axis) of the up spin in degree
26 */
27void initGenI(GenI* this, int is_avg, int npix, double* x, double* y, double* z, double* sldn,
28                        double* mx, double* my, double* mz, double* voli,
29                        double in_spin, double out_spin,
30                        double s_theta) {
31        this->is_avg = is_avg;
32        this->n_pix = npix;
33        this->x_val = x;
34        this->y_val = y;
35        this->z_val = z;
36        this->sldn_val = sldn;
37        this->mx_val = mx;
38        this->my_val = my;
39        this->mz_val = mz;
40        this->vol_pix = voli;
41        this->inspin = in_spin;
42        this->outspin = out_spin;
43        this->stheta = s_theta;
44}
45
46/**
47 * Compute 2D anisotropic
48 */
49void genicomXY(GenI* this, int npoints, double *qx, double *qy, double *I_out){
50        //npoints is given negative for angular averaging
51        // Assumes that q doesn't have qz component and sld_n is all real
52        //double q = 0.0;
53        //double Pi = 4.0*atan(1.0);
54        polar_sld b_sld;
55        double qr = 0.0;
56        complex iqr = cassign(0.0, 0.0);
57        complex ephase = cassign(0.0, 0.0);
58        complex comp_sld = cassign(0.0, 0.0);
59
60        complex sumj_uu;
61        complex sumj_ud;
62        complex sumj_du;
63        complex sumj_dd;
64        complex temp_fi;
65
66        double count = 0.0;
67        int i, j;
68
69        //Assume that pixel volumes are given in vol_pix in A^3 unit
70        //int x_size = 0; //in Ang
71        //int y_size = 0; //in Ang
72        //int z_size = 0; //in Ang
73
74        // Loop over q-values and multiply apply matrix
75
76        //printf("npoints: %d, npix: %d\n", npoints, this->n_pix);
77        for(i=0; i<npoints; i++){
78                //I_out[i] = 0.0;
79                sumj_uu = cassign(0.0, 0.0);
80                sumj_ud = cassign(0.0, 0.0);
81                sumj_du = cassign(0.0, 0.0);
82                sumj_dd = cassign(0.0, 0.0);
83                //printf ("%d ", i);
84                //q = sqrt(qx[i]*qx[i] + qy[i]*qy[i]); // + qz[i]*qz[i]);
85
86                for(j=0; j<this->n_pix; j++){
87                        if (this->sldn_val[j]!=0.0
88                                ||this->mx_val[j]!=0.0
89                                ||this->my_val[j]!=0.0
90                                ||this->mz_val[j]!=0.0)
91                        {
92                                //anisotropic
93                                temp_fi = cassign(0.0, 0.0);
94                                b_sld = cal_msld(0, qx[i], qy[i], this->sldn_val[j],
95                                                         this->mx_val[j], this->my_val[j], this->mz_val[j],
96                                                         this->inspin, this->outspin, this->stheta);
97                                qr = (qx[i]*this->x_val[j] + qy[i]*this->y_val[j]);
98                                iqr = cassign(0.0, qr);
99                                ephase = cplx_exp(iqr);
100
101                                //Let's multiply pixel(atomic) volume here
102                                ephase = rcmult(this->vol_pix[j], ephase);
103                                //up_up
104                                if (this->inspin > 0.0 && this->outspin > 0.0){
105                                        comp_sld = cassign(b_sld.uu, 0.0);
106                                        temp_fi = cplx_mult(comp_sld, ephase);
107                                        sumj_uu = cplx_add(sumj_uu, temp_fi);
108                                }
109                                //down_down
110                                if (this->inspin < 1.0 && this->outspin < 1.0){
111                                        comp_sld = cassign(b_sld.dd, 0.0);
112                                        temp_fi = cplx_mult(comp_sld, ephase);
113                                        sumj_dd = cplx_add(sumj_dd, temp_fi);
114                                }
115                                //up_down
116                                if (this->inspin > 0.0 && this->outspin < 1.0){
117                                        comp_sld = cassign(b_sld.re_ud, b_sld.im_ud);
118                                        temp_fi = cplx_mult(comp_sld, ephase);
119                                        sumj_ud = cplx_add(sumj_ud, temp_fi);
120                                }
121                                //down_up
122                                if (this->inspin < 1.0 && this->outspin > 0.0){
123                                        comp_sld = cassign(b_sld.re_du, b_sld.im_du);
124                                        temp_fi = cplx_mult(comp_sld, ephase);
125                                        sumj_du = cplx_add(sumj_du, temp_fi);
126                                }
127
128
129                                if (i == 0){
130                                        count += this->vol_pix[j];
131                                }
132                        }
133                }
134                //printf("aa%d=%g %g %d\n", i, (sumj_uu.re*sumj_uu.re + sumj_uu.im*sumj_uu.im), (sumj_dd.re*sumj_dd.re + sumj_dd.im*sumj_dd.im), count);
135
136                I_out[i] = (sumj_uu.re*sumj_uu.re + sumj_uu.im*sumj_uu.im);
137                I_out[i] += (sumj_ud.re*sumj_ud.re + sumj_ud.im*sumj_ud.im);
138                I_out[i] += (sumj_du.re*sumj_du.re + sumj_du.im*sumj_du.im);
139                I_out[i] += (sumj_dd.re*sumj_dd.re + sumj_dd.im*sumj_dd.im);
140
141                I_out[i] *= (1.0E+8 / count); //in cm (unit) / number; //to be multiplied by vol_pix
142        }
143        //printf ("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]);
144}
145/**
146 * Compute 1D isotropic
147 * Isotropic: Assumes all slds are real (no magnetic)
148 * Also assumes there is no polarization: No dependency on spin
149 */
150void genicom(GenI* this, int npoints, double *q, double *I_out){
151        //npoints is given negative for angular averaging
152        // Assumes that q doesn't have qz component and sld_n is all real
153        //double Pi = 4.0*atan(1.0);
154        double qr = 0.0;
155        double sumj;
156        double sld_j = 0.0;
157        double count = 0.0;
158        int i, j, k;
159
160        //Assume that pixel volumes are given in vol_pix in A^3 unit
161        // Loop over q-values and multiply apply matrix
162        for(i=0; i<npoints; i++){
163                sumj =0.0;
164                for(j=0; j<this->n_pix; j++){
165                        //Isotropic: Assumes all slds are real (no magnetic)
166                        //Also assumes there is no polarization: No dependency on spin
167                        if (this->is_avg == 1){
168                                // approximation for a spherical symmetric particle
169                                qr = sqrt(this->x_val[j]*this->x_val[j]+this->y_val[j]*this->y_val[j]+this->z_val[j]*this->z_val[j])*q[i];
170                                if (qr > 0.0){
171                                        qr = sin(qr) / qr;
172                                        sumj += this->sldn_val[j] * this->vol_pix[j] * qr;
173                                }
174                                else{
175                                        sumj += this->sldn_val[j] * this->vol_pix[j];
176                                }
177                        }
178                        else{
179                                //full calculation
180                                //pragma omp parallel for
181                                for(k=0; k<this->n_pix; k++){
182                                        sld_j =  this->sldn_val[j] * this->sldn_val[k] * this->vol_pix[j] * this->vol_pix[k];
183                                        qr = (this->x_val[j]-this->x_val[k])*(this->x_val[j]-this->x_val[k])+
184                                                      (this->y_val[j]-this->y_val[k])*(this->y_val[j]-this->y_val[k])+
185                                                      (this->z_val[j]-this->z_val[k])*(this->z_val[j]-this->z_val[k]);
186                                        qr = sqrt(qr) * q[i];
187                                        if (qr > 0.0){
188                                                sumj += sld_j*sin(qr)/qr;
189                                        }
190                                        else{
191                                                sumj += sld_j;
192                                        }
193                                }
194                        }
195                        if (i == 0){
196                                count += this->vol_pix[j];
197                        }
198                }
199                I_out[i] = sumj;
200                if (this->is_avg == 1) {
201                        I_out[i] *= sumj;
202                }
203                I_out[i] *= (1.0E+8 / count); //in cm (unit) / number; //to be multiplied by vol_pix
204        }
205        //printf ("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]);
206}
Note: See TracBrowser for help on using the repository browser.