Changeset 9624cda in sasview for sansmodels


Ignore:
Timestamp:
Mar 13, 2013 11:10:51 AM (12 years ago)
Author:
Jae Cho <jhjcho@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
49a8843
Parents:
5f248f6
Message:

fixed debye averging in gensans

Location:
sansmodels/src/c_gen
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • sansmodels/src/c_gen/sld2i.cpp

    r5917637 r9624cda  
    5050 
    5151/** 
    52  * Compute 
    53  */ 
    54 void GenI :: genicom(int npoints, double *qx, double *qy, double *I_out){ 
     52 * Compute 2D anisotropic 
     53 */ 
     54void GenI :: genicomXY(int npoints, double *qx, double *qy, double *I_out){ 
    5555        //npoints is given negative for angular averaging  
    5656        // Assumes that q doesn't have qz component and sld_n is all real 
    57         double q = 0.0; 
    58         int is_avg = 0; 
     57        //double q = 0.0; 
    5958        //double Pi = 4.0*atan(1.0); 
    6059        polar_sld b_sld; 
     
    6362        complex ephase = cassign(0.0, 0.0); 
    6463        complex comp_sld = cassign(0.0, 0.0); 
    65         complex sumj; 
     64 
    6665        complex sumj_uu; 
    6766        complex sumj_ud; 
     
    7271        double count = 0.0; 
    7372        //check if this computation is for averaging 
    74         if (n_pix < 0 ){ 
    75                 is_avg = 1; 
    76                 n_pix = fabs(n_pix); 
    77         } 
     73 
    7874        //Assume that pixel volumes are given in vol_pix in A^3 unit 
    7975        //int x_size = 0; //in Ang 
    8076        //int y_size = 0; //in Ang 
    8177        //int z_size = 0; //in Ang 
     78         
    8279        // Loop over q-values and multiply apply matrix 
    83  
     80         
    8481        for(int i=0; i<npoints; i++){ 
    8582                //I_out[i] = 0.0; 
    86                 sumj = cassign(0.0, 0.0); 
    8783                sumj_uu = cassign(0.0, 0.0); 
    8884                sumj_ud = cassign(0.0, 0.0); 
     
    9086                sumj_dd = cassign(0.0, 0.0);             
    9187                //printf ("%d ", i); 
    92                 q = sqrt(qx[i]*qx[i] + qy[i]*qy[i]); // + qz[i]*qz[i]); 
     88                //q = sqrt(qx[i]*qx[i] + qy[i]*qy[i]); // + qz[i]*qz[i]); 
    9389 
    9490                for(int j=0; j<n_pix; j++){ 
    95                          
    9691                        if (sldn_val[j]!=0.0||mx_val[j]!=0.0||my_val[j]!=0.0||mz_val[j]!=0.0) 
    9792                        {        
     93                                //anisotropic 
    9894                                temp_fi = cassign(0.0, 0.0); 
    9995                                b_sld = cal_msld(0, qx[i], qy[i], sldn_val[j], 
    100                                                                  mx_val[j], my_val[j], mz_val[j], 
    101                                                                  inspin, outspin, stheta); 
    102                                 if (is_avg < 1){ 
    103                                         //anisotropic 
    104                                         qr = (qx[i]*x_val[j] + qy[i]*y_val[j]); 
    105                                         iqr = cassign(0.0, qr); 
    106                                         ephase = cplx_exp(iqr); 
    107                                         } 
    108                                 else{ 
    109                                         //isotropic 
    110                                         qr = sqrt(x_val[j]*x_val[j]+y_val[j]*y_val[j]+z_val[j]*z_val[j]); 
    111                                         qr *= q; 
    112                                         if (qr == 0.0){ 
    113                                                 ephase = cassign(0.0, 1.0); 
    114                                                 } 
    115                                         else{ 
    116                                                 qr = sin(qr) / qr; 
    117                                                 ephase = cassign(qr, 0.0); 
    118                                                 } 
    119                                         } 
     96                                                         mx_val[j], my_val[j], mz_val[j], 
     97                                                         inspin, outspin, stheta); 
     98                                qr = (qx[i]*x_val[j] + qy[i]*y_val[j]); 
     99                                iqr = cassign(0.0, qr); 
     100                                ephase = cplx_exp(iqr); 
     101                                 
    120102                                //Let's multiply pixel(atomic) volume here 
    121103                                ephase = rcmult(vol_pix[j], ephase); 
     
    125107                                        temp_fi = cplx_mult(comp_sld, ephase); 
    126108                                        sumj_uu = cplx_add(sumj_uu, temp_fi); 
    127                                         } 
     109                                } 
    128110                                //down_down 
    129111                                if (inspin < 1.0 && outspin < 1.0){ 
     
    131113                                        temp_fi = cplx_mult(comp_sld, ephase); 
    132114                                        sumj_dd = cplx_add(sumj_dd, temp_fi); 
    133                                         } 
     115                                } 
    134116                                //up_down 
    135117                                if (inspin > 0.0 && outspin < 1.0){ 
     
    137119                                        temp_fi = cplx_mult(comp_sld, ephase); 
    138120                                        sumj_ud = cplx_add(sumj_ud, temp_fi); 
    139                                         } 
     121                                } 
    140122                                //down_up 
    141123                                if (inspin < 1.0 && outspin > 0.0){ 
     
    143125                                        temp_fi = cplx_mult(comp_sld, ephase); 
    144126                                        sumj_du = cplx_add(sumj_du, temp_fi); 
    145                                         } 
     127                                } 
     128 
     129 
    146130                                if (i == 0){ 
    147131                                        count += vol_pix[j]; 
     
    150134                } 
    151135                //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); 
     136 
    152137                I_out[i] = (sumj_uu.re*sumj_uu.re + sumj_uu.im*sumj_uu.im); 
    153138                I_out[i] += (sumj_ud.re*sumj_ud.re + sumj_ud.im*sumj_ud.im); 
    154139                I_out[i] += (sumj_du.re*sumj_du.re + sumj_du.im*sumj_du.im); 
    155140                I_out[i] += (sumj_dd.re*sumj_dd.re + sumj_dd.im*sumj_dd.im); 
     141 
    156142                I_out[i] *= (1.0E+8 / count); //in cm (unit) / number; //to be multiplied by vol_pix 
    157143        } 
    158144        //printf ("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]); 
    159145} 
     146/** 
     147 * Compute 1D isotropic 
     148 * Isotropic: Assumes all slds are real (no magnetic) 
     149 * Also assumes there is no polarization: No dependency on spin 
     150 */ 
     151void GenI :: genicom(int npoints, double *q, double *I_out){ 
     152        //npoints is given negative for angular averaging  
     153        // Assumes that q doesn't have qz component and sld_n is all real 
     154        //double Pi = 4.0*atan(1.0); 
     155        int is_sym = 0; 
     156        double qr = 0.0; 
     157        double sumj; 
     158        double sld_j = 0.0; 
     159        double count = 0.0; 
     160        if (n_pix < 0 ){ 
     161                is_sym = 1; 
     162                n_pix = n_pix * -1; 
     163        } 
     164        //Assume that pixel volumes are given in vol_pix in A^3 unit 
     165        // Loop over q-values and multiply apply matrix 
     166        for(int i=0; i<npoints; i++){ 
     167                sumj =0.0;               
     168                for(int j=0; j<n_pix; j++){ 
     169                        //Isotropic: Assumes all slds are real (no magnetic) 
     170                        //Also assumes there is no polarization: No dependency on spin 
     171                        if (is_sym == 1){ 
     172                                // approximation for a spherical symmetric particle 
     173                                qr = sqrt(x_val[j]*x_val[j]+y_val[j]*y_val[j]+z_val[j]*z_val[j])*q[i]; 
     174                                if (qr > 0.0){ 
     175                                        qr = sin(qr) / qr; 
     176                                        sumj += sldn_val[j] * vol_pix[j] * qr; 
     177                                } 
     178                                else{ 
     179                                        sumj += sldn_val[j] * vol_pix[j]; 
     180                                } 
     181                        } 
     182                        else{ 
     183                                //full calculation 
     184                                #pragma omp parallel for 
     185                                for(int k=0; k<n_pix; k++){ 
     186                                        sld_j =  sldn_val[j] * sldn_val[k] * vol_pix[j] * vol_pix[k]; 
     187                                        qr = (x_val[j]-x_val[k])*(x_val[j]-x_val[k])+ 
     188                                                      (y_val[j]-y_val[k])*(y_val[j]-y_val[k])+  
     189                                                      (z_val[j]-z_val[k])*(z_val[j]-z_val[k]); 
     190                                        qr = sqrt(qr) * q[i]; 
     191                                        if (qr > 0.0){ 
     192                                                sumj += sld_j*sin(qr)/qr; 
     193                                        } 
     194                                        else{ 
     195                                                sumj += sld_j; 
     196                                        } 
     197                                } 
     198                        } 
     199                        if (i == 0){ 
     200                                count += vol_pix[j]; 
     201                        } 
     202                } 
     203                I_out[i] = sumj; 
     204                if (is_sym == 1){ 
     205                        I_out[i] *= sumj; 
     206                } 
     207                I_out[i] *= (1.0E+8 / count); //in cm (unit) / number; //to be multiplied by vol_pix 
     208        } 
     209        //printf ("count = %d %g %g %g %g\n", count, sldn_val[0],mx_val[0], my_val[0], mz_val[0]); 
     210} 
  • sansmodels/src/c_gen/sld2i.hh

    rb1174ec r9624cda  
    3939                        double s_theta); 
    4040        // compute function 
    41         virtual void genicom(int npoints, double* qx, double* qy, double *I_out); 
     41        virtual void genicomXY(int npoints, double* qx, double* qy, double *I_out); 
     42        virtual void genicom(int npoints, double* q, double *I_out); 
    4243}; 
    4344 
  • sansmodels/src/c_gen/sld2i_module.cpp

    rb1174ec r9624cda  
    7575 
    7676/** 
    77  * GenI the given input according to a given object 
     77 * GenI the given input (2D) according to a given object 
    7878 */ 
    79 PyObject * genicom_input(PyObject *, PyObject *args) { 
     79PyObject * genicom_inputXY(PyObject *, PyObject *args) { 
    8080        int npoints; 
    8181        PyObject *qx_obj; 
     
    100100        GenI* s = static_cast<GenI *>(temp); 
    101101 
    102         s->genicom(npoints, qx, qy, I_out); 
     102        s->genicomXY(npoints, qx, qy, I_out); 
    103103        //return PyCObject_FromVoidPtr(s, del_genicom); 
    104104        return Py_BuildValue("i",1); 
    105105} 
    106106 
     107/** 
     108 * GenI the given 1D input according to a given object 
     109 */ 
     110PyObject * genicom_input(PyObject *, PyObject *args) { 
     111        int npoints; 
     112        PyObject *q_obj; 
     113        double *q; 
     114        PyObject *I_out_obj; 
     115        Py_ssize_t n_out; 
     116        double *I_out; 
     117        PyObject *gen_obj; 
     118 
     119        if (!PyArg_ParseTuple(args, "OiOO",  &gen_obj, &npoints, &q_obj, &I_out_obj)) return NULL; 
     120        OUTVECTOR(q_obj, q, n_out); 
     121        OUTVECTOR(I_out_obj, I_out, n_out); 
     122 
     123        // Sanity check 
     124        //if(n_in!=n_out) return Py_BuildValue("i",-1); 
     125 
     126        // Set the array pointers 
     127        void *temp = PyCObject_AsVoidPtr(gen_obj); 
     128        GenI* s = static_cast<GenI *>(temp); 
     129 
     130        s->genicom(npoints, q, I_out); 
     131        //return PyCObject_FromVoidPtr(s, del_genicom); 
     132        return Py_BuildValue("i",1); 
     133} 
    107134 
    108135/** 
     
    113140                  "Create a new GenI object"}, 
    114141        {"genicom",(PyCFunction)genicom_input, METH_VARARGS, 
    115                   "genicom the given input arrays"}, 
     142                  "genicom the given 1d input arrays"}, 
     143        {"genicomXY",(PyCFunction)genicom_inputXY, METH_VARARGS, 
     144                  "genicomXY the given 2d input arrays"}, 
    116145    {NULL} 
    117146}; 
Note: See TracChangeset for help on using the changeset viewer.