Changes in sasmodels/kernel_iq.c [70530778:c57ee9e] in sasmodels


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernel_iq.c

    r70530778 rc57ee9e  
    2727//      parameters in the parameter table. 
    2828//  CALL_VOLUME(table) : call the form volume function 
     29//  CALL_EFFECTIVE_RADIUS(type, table) : call the R_eff function 
    2930//  CALL_IQ(q, table) : call the Iq function for 1D calcs. 
    3031//  CALL_IQ_A(q, table) : call the Iq function with |q| for 2D data. 
     32//  CALL_FQ(q, F1, F2, table) : call the Fq function for 1D calcs. 
     33//  CALL_FQ_A(q, F1, F2, table) : call the Iq function with |q| for 2D data. 
    3134//  CALL_IQ_AC(qa, qc, table) : call the Iqxy function for symmetric shapes 
    3235//  CALL_IQ_ABC(qa, qc, table) : call the Iqxy function for asymmetric shapes 
     
    3639//  PROJECTION : equirectangular=1, sinusoidal=2 
    3740//      see explore/jitter.py for definitions. 
     41 
    3842 
    3943#ifndef _PAR_BLOCK_ // protected block so we can include this code twice. 
     
    188192    QACRotation *rotation, 
    189193    double qx, double qy, 
    190     double *qab_out, double *qc_out) 
     194    double *qa_out, double *qc_out) 
    191195{ 
     196    const double dqc = rotation->R31*qx + rotation->R32*qy; 
    192197    // Indirect calculation of qab, from qab^2 = |q|^2 - qc^2 
    193     const double dqc = rotation->R31*qx + rotation->R32*qy; 
    194     const double dqab_sq = -dqc*dqc + qx*qx + qy*qy; 
    195     //*qab_out = sqrt(fabs(dqab_sq)); 
    196     *qab_out = dqab_sq > 0.0 ? sqrt(dqab_sq) : 0.0; 
     198    const double dqa = sqrt(-dqc*dqc + qx*qx + qy*qy); 
     199 
     200    *qa_out = dqa; 
    197201    *qc_out = dqc; 
    198202} 
     
    270274#endif // _QABC_SECTION 
    271275 
    272  
    273276// ==================== KERNEL CODE ======================== 
    274  
     277#define COMPUTE_F1_F2 defined(CALL_FQ) 
    275278kernel 
    276279void KERNEL_NAME( 
     
    282285    global const double *q, // nq q values, with padding to boundary 
    283286    global double *result,  // nq+1 return values, again with padding 
    284     const double cutoff     // cutoff in the dispersity weight product 
     287    const double cutoff,     // cutoff in the dispersity weight product 
     288    int32_t effective_radius_type // which effective radius to compute 
    285289    ) 
    286290{ 
     
    341345  // version must loop over all q. 
    342346  #ifdef USE_OPENCL 
    343     double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
    344     double this_result = (pd_start == 0 ? 0.0 : result[q_index]); 
     347    #if COMPUTE_F1_F2 
     348      double weight_norm = (pd_start == 0 ? 0.0 : result[2*nq]); 
     349      double weighted_volume = (pd_start == 0 ? 0.0 : result[2*nq+1]); 
     350      double weighted_radius = (pd_start == 0 ? 0.0 : result[2*nq+2]); 
     351      double this_F2 = (pd_start == 0 ? 0.0 : result[2*q_index+0]); 
     352      double this_F1 = (pd_start == 0 ? 0.0 : result[2*q_index+1]); 
     353    #else 
     354      double weight_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     355      double weighted_volume = (pd_start == 0 ? 0.0 : result[nq+1]); 
     356      double weighted_radius = (pd_start == 0 ? 0.0 : result[nq+2]); 
     357      double this_result = (pd_start == 0 ? 0.0 : result[q_index]); 
     358    #endif 
    345359  #else // !USE_OPENCL 
    346     double pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     360    #if COMPUTE_F1_F2 
     361      double weight_norm = (pd_start == 0 ? 0.0 : result[2*nq]); 
     362      double weighted_volume = (pd_start == 0 ? 0.0 : result[2*nq+1]); 
     363      double weighted_radius = (pd_start == 0 ? 0.0 : result[2*nq+2]); 
     364    #else 
     365      double weight_norm = (pd_start == 0 ? 0.0 : result[nq]); 
     366      double weighted_volume = (pd_start == 0 ? 0.0 : result[nq+1]); 
     367      double weighted_radius = (pd_start == 0 ? 0.0 : result[nq+2]); 
     368    #endif 
    347369    if (pd_start == 0) { 
    348370      #ifdef USE_OPENMP 
    349371      #pragma omp parallel for 
    350372      #endif 
    351       for (int q_index=0; q_index < nq; q_index++) result[q_index] = 0.0; 
     373      #if COMPUTE_F1_F2 
     374          // 2*nq for F^2,F pairs 
     375          for (int q_index=0; q_index < 2*nq; q_index++) result[q_index] = 0.0; 
     376      #else 
     377          for (int q_index=0; q_index < nq; q_index++) result[q_index] = 0.0; 
     378      #endif 
    352379    } 
    353     //if (q_index==0) printf("start %d %g %g\n", pd_start, pd_norm, result[0]); 
     380    //if (q_index==0) printf("start %d %g %g\n", pd_start, weighted_volume, result[0]); 
    354381#endif // !USE_OPENCL 
    355382 
     
    442469// inner loop and defines the macros that use them. 
    443470 
    444 #if defined(CALL_IQ) 
    445   // unoriented 1D 
     471 
     472#if defined(CALL_FQ) // COMPUTE_F1_F2 is true 
     473  // unoriented 1D returning <F> and <F^2> 
     474  double qk; 
     475  double F1, F2; 
     476  #define FETCH_Q() do { qk = q[q_index]; } while (0) 
     477  #define BUILD_ROTATION() do {} while(0) 
     478  #define APPLY_ROTATION() do {} while(0) 
     479  #define CALL_KERNEL() CALL_FQ(qk,F1,F2,local_values.table) 
     480 
     481#elif defined(CALL_FQ_A) 
     482  // unoriented 2D return <F> and <F^2> 
     483  double qx, qy; 
     484  double F1, F2; 
     485  #define FETCH_Q() do { qx = q[2*q_index]; qy = q[2*q_index+1]; } while (0) 
     486  #define BUILD_ROTATION() do {} while(0) 
     487  #define APPLY_ROTATION() do {} while(0) 
     488  #define CALL_KERNEL() CALL_FQ_A(sqrt(qx*qx+qy*qy),F1,F2,local_values.table) 
     489 
     490#elif defined(CALL_IQ) 
     491  // unoriented 1D return <F^2> 
    446492  double qk; 
    447493  #define FETCH_Q() do { qk = q[q_index]; } while (0) 
    448494  #define BUILD_ROTATION() do {} while(0) 
    449495  #define APPLY_ROTATION() do {} while(0) 
    450   #define CALL_KERNEL() CALL_IQ(qk, local_values.table) 
     496  #define CALL_KERNEL() CALL_IQ(qk,local_values.table) 
    451497 
    452498#elif defined(CALL_IQ_A) 
     
    482528  #define APPLY_ROTATION() qabc_apply(&rotation, qx, qy, &qa, &qb, &qc) 
    483529  #define CALL_KERNEL() CALL_IQ_ABC(qa, qb, qc, local_values.table) 
     530 
    484531#elif defined(CALL_IQ_XY) 
    485532  // direct call to qx,qy calculator 
     
    495542// logic in the IQ_AC and IQ_ABC branches.  This will become more important 
    496543// if we implement more projections, or more complicated projections. 
    497 #if defined(CALL_IQ) || defined(CALL_IQ_A)  // no orientation 
     544#if defined(CALL_IQ) || defined(CALL_IQ_A) || defined(CALL_FQ) || defined(CALL_FQ_A) 
     545  // no orientation 
    498546  #define APPLY_PROJECTION() const double weight=weight0 
    499547#elif defined(CALL_IQ_XY) // pass orientation to the model 
     
    645693    // Note: weight==0 must always be excluded 
    646694    if (weight > cutoff) { 
    647       pd_norm += weight * CALL_VOLUME(local_values.table); 
     695      weighted_volume += weight * CALL_VOLUME(local_values.table); 
     696      #if COMPUTE_F1_F2 
     697      weight_norm += weight; 
     698      #endif 
     699      if (effective_radius_type != 0) { 
     700        weighted_radius += weight * CALL_EFFECTIVE_RADIUS(effective_radius_type, local_values.table); 
     701      } 
    648702      BUILD_ROTATION(); 
    649703 
     
    693747          } 
    694748        #else  // !MAGNETIC 
    695           const double scattering = CALL_KERNEL(); 
     749          #if COMPUTE_F1_F2 
     750            CALL_KERNEL(); // sets F1 and F2 by reference 
     751          #else 
     752            const double scattering = CALL_KERNEL(); 
     753          #endif 
    696754        #endif // !MAGNETIC 
    697755//printf("q_index:%d %g %g %g %g\n", q_index, scattering, weight0); 
    698756 
    699757        #ifdef USE_OPENCL 
    700           this_result += weight * scattering; 
     758          #if COMPUTE_F1_F2 
     759            this_F2 += weight * F2; 
     760            this_F1 += weight * F1; 
     761          #else 
     762            this_result += weight * scattering; 
     763          #endif 
    701764        #else // !USE_OPENCL 
    702           result[q_index] += weight * scattering; 
     765          #if COMPUTE_F1_F2 
     766            result[2*q_index+0] += weight * F2; 
     767            result[2*q_index+1] += weight * F1; 
     768          #else 
     769            result[q_index] += weight * scattering; 
     770          #endif 
    703771        #endif // !USE_OPENCL 
    704772      } 
    705773    } 
    706774  } 
    707  
    708775// close nested loops 
    709776++step; 
     
    726793// Remember the current result and the updated norm. 
    727794#ifdef USE_OPENCL 
    728   result[q_index] = this_result; 
    729   if (q_index == 0) result[nq] = pd_norm; 
    730 //if (q_index == 0) printf("res: %g/%g\n", result[0], pd_norm); 
     795  #if COMPUTE_F1_F2 
     796    result[2*q_index+0] = this_F2; 
     797    result[2*q_index+1] = this_F1; 
     798    if (q_index == 0) { 
     799      result[2*nq+0] = weight_norm; 
     800      result[2*nq+1] = weighted_volume; 
     801      result[2*nq+2] = weighted_radius; 
     802    } 
     803  #else 
     804    result[q_index] = this_result; 
     805    if (q_index == 0) { 
     806      result[nq+0] = weight_norm; 
     807      result[nq+1] = weighted_volume; 
     808      result[nq+2] = weighted_radius; 
     809    } 
     810  #endif 
     811 
     812//if (q_index == 0) printf("res: %g/%g\n", result[0], weigthed_volume); 
    731813#else // !USE_OPENCL 
    732   result[nq] = pd_norm; 
    733 //printf("res: %g/%g\n", result[0], pd_norm); 
     814  #if COMPUTE_F1_F2 
     815    result[2*nq] = weight_norm; 
     816    result[2*nq+1] = weighted_volume; 
     817    result[2*nq+2] = weighted_radius; 
     818  #else 
     819    result[nq] = weight_norm; 
     820    result[nq+1] = weighted_volume; 
     821    result[nq+2] = weighted_radius; 
     822  #endif 
     823//printf("res: %g/%g\n", result[0], weighted_volume); 
    734824#endif // !USE_OPENCL 
    735825 
    736826// ** clear the macros in preparation for the next kernel ** 
     827#undef COMPUTE_F1_F2 
    737828#undef PD_INIT 
    738829#undef PD_OPEN 
Note: See TracChangeset for help on using the changeset viewer.