Changeset 9eb3632 in sasmodels for sasmodels/kernel_iq.c


Ignore:
Timestamp:
Jul 23, 2016 12:54:17 AM (8 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
7b7da6b
Parents:
6a0d6aa
Message:

restructure kernels using fixed PD loops

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/kernel_iq.c

    rb966a96 r9eb3632  
    2929 
    3030typedef struct { 
    31     PARAMETER_TABLE 
     31    PARAMETER_TABLE; 
    3232} ParameterBlock; 
    33 #endif 
    34  
    35 #ifdef MAGNETIC 
    36 const int32_t magnetic[] = { MAGNETIC_PARS }; 
    37 #endif 
     33#endif // _PAR_BLOCK_ 
     34 
    3835 
    3936#ifdef MAGNETIC 
     
    6158} 
    6259 
    63 // Convert polar to rectangular coordinates. 
    64 static void polrec(double r, double theta, double phi, 
    65   double *x, double *y, double *z) 
    66 { 
    67   double cos_theta, sin_theta, cos_phi, sin_phi; 
    68   SINCOS(theta*M_PI_180, sin_theta, cos_theta); 
    69   SINCOS(phi*M_PI_180, sin_phi, cos_phi); 
    70   *x = r * cos_theta * cos_phi; 
    71   *y = r * sin_theta; 
    72   *z = -r * cos_theta * sin_phi; 
    73 } 
    74 #endif 
     60#endif // MAGNETIC 
    7561 
    7662kernel 
     
    8066    const int32_t pd_stop,      // where we are stopping in the polydispersity loop 
    8167    global const ProblemDetails *details, 
    82    // global const  // TODO: make it const again! 
    83     double *values, 
     68    global const double *values, 
    8469    global const double *q, // nq q values, with padding to boundary 
    85     global double *result,  // nq+3 return values, again with padding 
     70    global double *result,  // nq+1 return values, again with padding 
    8671    const double cutoff     // cutoff in the polydispersity weight product 
    8772    ) 
    8873{ 
     74 
    8975  // Storage for the current parameter values.  These will be updated as we 
    90   // walk the polydispersity cube. 
    91   ParameterBlock local_values;  // current parameter values 
    92   double *pvec = (double *)(&local_values);  // Alias named parameters with a vector 
     76  // walk the polydispersity cube.  local_values will be aliased to pvec. 
     77  ParameterBlock local_values; 
     78  double *pvec = (double *)&local_values; 
     79 
     80#ifdef MAGNETIC 
     81  // Location of the sld parameters in the parameter pvec. 
     82  // These parameters are updated with the effective sld due to magnetism. 
     83  const int32_t slds[] = { MAGNETIC_PARS }; 
     84 
     85  const double up_frac_i = values[NPARS+2]; 
     86  const double up_frac_f = values[NPARS+3]; 
     87  const double up_angle = values[NPARS+4]; 
     88  #define MX(_k) (values[NPARS+5+3*_k]) 
     89  #define MY(_k) (values[NPARS+6+3*_k]) 
     90  #define MZ(_k) (values[NPARS+7+3*_k]) 
     91 
     92  // TODO: could precompute these outside of the kernel. 
     93  // Interpret polarization cross section. 
     94  double uu, dd, ud, du; 
     95  double cos_mspin, sin_mspin; 
     96  spins(up_frac_i, up_frac_f, &uu, &dd, &ud, &du); 
     97  SINCOS(-up_angle*M_PI_180, sin_mspin, cos_mspin); 
     98#endif // MAGNETIC 
    9399 
    94100  // Fill in the initial variables 
     
    98104  #pragma omp parallel for 
    99105  #endif 
    100   for (int k=0; k < NPARS; k++) { 
    101     pvec[k] = values[k+2]; 
    102   } 
    103 #ifdef MAGNETIC 
    104   const double up_frac_i = values[NPARS+2]; 
    105   const double up_frac_f = values[NPARS+3]; 
    106   const double up_angle = values[NPARS+4]; 
    107   #define MX(_k) (values[NPARS+5+3*_k]) 
    108   #define MY(_k) (values[NPARS+6+3*_k]) 
    109   #define MZ(_k) (values[NPARS+7+3*_k]) 
    110  
    111   // TODO: precompute this on the python side 
    112   // Convert polar to rectangular coordinates in place. 
    113   if (pd_start == 0) {  // Update in place; only do this for the first hunk! 
    114 //printf("spin: %g %g %g\n", up_frac_i, up_frac_f, up_angle); 
    115     for (int mag=0; mag < NUM_MAGNETIC; mag++) { 
    116 //printf("mag %d: %g %g %g\n", mag, MX(mag), MY(mag), MZ(mag)); 
    117         polrec(MX(mag), MY(mag), MZ(mag), &MX(mag), &MY(mag), &MZ(mag)); 
    118 //printf("   ==>: %g %g %g\n", MX(mag), MY(mag), MZ(mag)); 
    119     } 
    120   } 
    121   // Interpret polarization cross section. 
    122   double uu, dd, ud, du; 
    123   double cos_mspin, sin_mspin; 
    124   spins(up_frac_i, up_frac_f, &uu, &dd, &ud, &du); 
    125   SINCOS(-up_angle*M_PI_180, sin_mspin, cos_mspin); 
    126 #endif 
    127  
    128   // Monodisperse computation 
    129   if (details->num_active == 0) { 
    130     double norm, scale, background; 
    131     #ifdef INVALID 
    132     if (INVALID(local_values)) { return; } 
    133     #endif 
    134  
    135     norm = CALL_VOLUME(local_values); 
    136     scale = values[0]; 
    137     background = values[1]; 
    138  
     106  for (int i=0; i < NPARS; i++) { 
     107    pvec[i] = values[2+i]; 
     108//printf("p%d = %g\n",i, pvec[i]); 
     109  } 
     110 
     111  double pd_norm; 
     112//printf("start: %d %d\n",pd_start, pd_stop); 
     113  if (pd_start == 0) { 
     114    pd_norm = 0.0; 
    139115    #ifdef USE_OPENMP 
    140116    #pragma omp parallel for 
    141117    #endif 
    142     for (int q_index=0; q_index < nq; q_index++) { 
     118    for (int q_index=0; q_index < nq; q_index++) result[q_index] = 0.0; 
     119//printf("initializing %d\n", nq); 
     120  } else { 
     121    pd_norm = result[nq]; 
     122  } 
     123//printf("start %d %g %g\n", pd_start, pd_norm, result[0]); 
     124 
     125  global const double *pd_value = values + NUM_VALUES + 2; 
     126  global const double *pd_weight = pd_value + details->pd_sum; 
     127 
     128  // Jump into the middle of the polydispersity loop 
     129#if MAX_PD>4 
     130  int n4=details->pd_length[4]; 
     131  int i4=(pd_start/details->pd_stride[4])%n4; 
     132  const int p4=details->pd_par[4]; 
     133  global const double *v4 = pd_value + details->pd_offset[4]; 
     134  global const double *w4 = pd_weight + details->pd_offset[4]; 
     135#endif 
     136#if MAX_PD>3 
     137  int n3=details->pd_length[3]; 
     138  int i3=(pd_start/details->pd_stride[3])%n3; 
     139  const int p3=details->pd_par[3]; 
     140  global const double *v3 = pd_value + details->pd_offset[3]; 
     141  global const double *w3 = pd_weight + details->pd_offset[3]; 
     142//printf("offset %d: %d %d\n", 3, details->pd_offset[3], NUM_VALUES); 
     143#endif 
     144#if MAX_PD>2 
     145  int n2=details->pd_length[2]; 
     146  int i2=(pd_start/details->pd_stride[2])%n2; 
     147  const int p2=details->pd_par[2]; 
     148  global const double *v2 = pd_value + details->pd_offset[2]; 
     149  global const double *w2 = pd_weight + details->pd_offset[2]; 
     150#endif 
     151#if MAX_PD>1 
     152  int n1=details->pd_length[1]; 
     153  int i1=(pd_start/details->pd_stride[1])%n1; 
     154  const int p1=details->pd_par[1]; 
     155  global const double *v1 = pd_value + details->pd_offset[1]; 
     156  global const double *w1 = pd_weight + details->pd_offset[1]; 
     157#endif 
     158#if MAX_PD>0 
     159  int n0=details->pd_length[0]; 
     160  int i0=(pd_start/details->pd_stride[0])%n0; 
     161  const int p0=details->pd_par[0]; 
     162  global const double *v0 = pd_value + details->pd_offset[0]; 
     163  global const double *w0 = pd_weight + details->pd_offset[0]; 
     164//printf("w0:%p, values:%p, diff:%d, %d\n",w0,values,(w0-values),NUM_VALUES); 
     165#endif 
     166 
     167 
     168  double spherical_correction=1.0; 
     169  const int theta_par = details->theta_par; 
     170#if MAX_PD>0 
     171  const int fast_theta = (theta_par == p0); 
     172  const int slow_theta = (theta_par >= 0 && !fast_theta); 
     173#else 
     174  const int slow_theta = (theta_par >= 0); 
     175#endif 
     176 
     177  int step = pd_start; 
     178 
     179 
     180#if MAX_PD>4 
     181  const double weight5 = 1.0; 
     182  while (i4 < n4) { 
     183    pvec[p4] = v4[i4]; 
     184    double weight4 = w4[i4] * weight5; 
     185//printf("step:%d level %d: p:%d i:%d n:%d value:%g weight:%g\n", step, 4, p4, i4, n4, pvec[p4], weight4); 
     186#elif MAX_PD>3 
     187    const double weight4 = 1.0; 
     188#endif 
     189#if MAX_PD>3 
     190  while (i3 < n3) { 
     191    pvec[p3] = v3[i3]; 
     192    double weight3 = w3[i3] * weight4; 
     193//printf("step:%d level %d: p:%d i:%d n:%d value:%g weight:%g\n", step, 3, p3, i3, n3, pvec[p3], weight3); 
     194#elif MAX_PD>2 
     195    const double weight3 = 1.0; 
     196#endif 
     197#if MAX_PD>2 
     198  while (i2 < n2) { 
     199    pvec[p2] = v2[i2]; 
     200    double weight2 = w2[i2] * weight3; 
     201//printf("step:%d level %d: p:%d i:%d n:%d value:%g weight:%g\n", step, 2, p2, i2, n2, pvec[p2], weight2); 
     202#elif MAX_PD>1 
     203    const double weight2 = 1.0; 
     204#endif 
     205#if MAX_PD>1 
     206  while (i1 < n1) { 
     207    pvec[p1] = v1[i1]; 
     208    double weight1 = w1[i1] * weight2; 
     209//printf("step:%d level %d: p:%d i:%d n:%d value:%g weight:%g\n", step, 1, p1, i1, n1, pvec[p1], weight1); 
     210#elif MAX_PD>0 
     211    const double weight1 = 1.0; 
     212#endif 
     213    if (slow_theta) { // Theta is not in inner loop 
     214      spherical_correction = fmax(fabs(cos(M_PI_180*pvec[theta_par])), 1.e-6); 
     215    } 
     216#if MAX_PD>0 
     217  while(i0 < n0) { 
     218    pvec[p0] = v0[i0]; 
     219    double weight0 = w0[i0] * weight1; 
     220//printf("step:%d level %d: p:%d i:%d n:%d value:%g weight:%g\n", step, 0, p0, i0, n0, pvec[p0], weight0); 
     221    if (fast_theta) { // Theta is in inner loop 
     222      spherical_correction = fmax(fabs(cos(M_PI_180*pvec[p0])), 1.e-6); 
     223    } 
     224#else 
     225    const double weight0 = 1.0; 
     226#endif 
     227 
     228//printf("step:%d of %d, pars:",step,pd_stop); for (int i=0; i < NPARS; i++) printf("p%d=%g ",i, pvec[i]); printf("\n"); 
     229//printf("sphcor: %g\n", spherical_correction); 
     230 
     231    #ifdef INVALID 
     232    if (!INVALID(local_values)) 
     233    #endif 
     234    { 
     235      // Accumulate I(q) 
     236      // Note: weight==0 must always be excluded 
     237      if (weight0 > cutoff) { 
     238        // spherical correction has some nasty effects when theta is +90 or -90 
     239        // where it becomes zero. 
     240        const double weight = weight0 * spherical_correction; 
     241        pd_norm += weight * CALL_VOLUME(local_values); 
     242 
     243        #ifdef USE_OPENMP 
     244        #pragma omp parallel for 
     245        #endif 
     246        for (int q_index=0; q_index<nq; q_index++) { 
    143247#ifdef MAGNETIC 
    144       const double qx = q[2*q_index]; 
    145       const double qy = q[2*q_index+1]; 
    146       const double qsq = qx*qx + qy*qy; 
    147  
    148       // Constant across orientation, polydispersity for given qx, qy 
    149       double px, py, pz; 
    150       if (qsq > 1e-16) { 
    151         px = (qy*cos_mspin + qx*sin_mspin)/qsq; 
    152         py = (qy*sin_mspin - qx*cos_mspin)/qsq; 
    153         pz = 1.0; 
    154       } else { 
    155         px = py = pz = 0.0; 
    156       } 
    157  
    158       double scattering = 0.0; 
    159       if (uu > 1e-8) { 
    160         for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    161             const double perp = (qy*MX(mag) - qx*MY(mag)); 
    162             pvec[magnetic[mag]] = (values[magnetic[mag]+2] - perp*px)*uu; 
    163         } 
    164         scattering += CALL_IQ(q, q_index, local_values); 
    165       } 
    166       if (dd > 1e-8){ 
    167         for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    168             const double perp = (qy*MX(mag) - qx*MY(mag)); 
    169             pvec[magnetic[mag]] = (values[magnetic[mag]+2] + perp*px)*dd; 
    170         } 
    171         scattering += CALL_IQ(q, q_index, local_values); 
    172       } 
    173       if (ud > 1e-8){ 
    174         for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    175             const double perp = (qy*MX(mag) - qx*MY(mag)); 
    176             pvec[magnetic[mag]] = perp*py*ud; 
    177         } 
    178         scattering += CALL_IQ(q, q_index, local_values); 
    179         for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    180             pvec[magnetic[mag]] = MZ(mag)*pz*ud; 
    181         } 
    182         scattering += CALL_IQ(q, q_index, local_values); 
    183       } 
    184       if (du > 1e-8) { 
    185         for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    186             const double perp = (qy*MX(mag) - qx*MY(mag)); 
    187             pvec[magnetic[mag]] = perp*py*du; 
    188         } 
    189         scattering += CALL_IQ(q, q_index, local_values); 
    190         for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    191             pvec[magnetic[mag]] = -MZ(mag)*pz*du; 
    192         } 
    193         scattering += CALL_IQ(q, q_index, local_values); 
    194       } 
    195 #else 
    196       double scattering = CALL_IQ(q, q_index, local_values); 
    197 #endif 
    198       result[q_index] = (norm>0. ? scale*scattering/norm + background : background); 
    199     } 
    200     return; 
    201   } 
    202  
    203 #if MAX_PD > 0 
    204  
    205 #if MAGNETIC 
    206   const double *pd_value = values+2+NPARS+3+3*NUM_MAGNETIC; 
    207 #else 
    208   const double *pd_value = values+2+NPARS; 
    209 #endif 
    210   const double *pd_weight = pd_value+details->pd_sum; 
    211  
    212   // need product of weights at every Iq calc, so keep product of 
    213   // weights from the outer loops so that weight = partial_weight * fast_weight 
    214   double pd_norm; 
    215   double partial_weight; // product of weight w4*w3*w2 but not w1 
    216   double spherical_correction; // cosine correction for latitude variation 
    217   double weight; // product of partial_weight*w1*spherical_correction 
    218  
    219   // Number of elements in the longest polydispersity loop 
    220   const int p0_par = details->pd_par[0]; 
    221   const int p0_length = details->pd_length[0]; 
    222   const int p0_offset = details->pd_offset[0]; 
    223   const int p0_is_theta = (p0_par == details->theta_par); 
    224   int p0_index; 
    225  
    226   // Trigger the reset behaviour that happens at the end the fast loop 
    227   // by setting the initial index >= weight vector length. 
    228   p0_index = p0_length; 
    229  
    230   // Default the spherical correction to 1.0 in case it is not otherwise set 
    231   spherical_correction = 1.0; 
    232  
    233   // Since we are no longer looping over the entire polydispersity hypercube 
    234   // for each q, we need to track the result and normalization values between 
    235   // calls.  This means initializing them to 0 at the start and accumulating 
    236   // them between calls. 
    237   pd_norm = (pd_start == 0 ? 0.0 : result[nq]); 
    238  
    239   if (pd_start == 0) { 
    240     #ifdef USE_OPENMP 
    241     #pragma omp parallel for 
    242     #endif 
    243     for (int q_index=0; q_index < nq; q_index++) { 
    244       result[q_index] = 0.0; 
    245     } 
    246   } 
    247  
    248   // Loop over the weights then loop over q, accumulating values 
    249   for (int loop_index=pd_start; loop_index < pd_stop; loop_index++) { 
    250     // check if fast loop needs to be reset 
    251     if (p0_index == p0_length) { 
    252  
    253       // Compute position in polydispersity hypercube and partial weight 
    254       partial_weight = 1.0; 
    255       for (int k=1; k < details->num_active; k++) { 
    256         int pk = details->pd_par[k]; 
    257         int index = details->pd_offset[k] + (loop_index/details->pd_stride[k])%details->pd_length[k]; 
    258         pvec[pk] = pd_value[index]; 
    259         partial_weight *= pd_weight[index]; 
    260         if (pk == details->theta_par) { 
    261           spherical_correction = fmax(fabs(cos(M_PI_180*pvec[pk])), 1.e-6); 
     248          const double qx = q[2*q_index]; 
     249          const double qy = q[2*q_index+1]; 
     250          const double qsq = qx*qx + qy*qy; 
     251 
     252          // Constant across orientation, polydispersity for given qx, qy 
     253          double px, py, pz; 
     254          if (qsq > 1.e-16) { 
     255            px = (qy*cos_mspin + qx*sin_mspin)/qsq; 
     256            py = (qy*sin_mspin - qx*cos_mspin)/qsq; 
     257            pz = 1.0; 
     258          } else { 
     259            px = py = pz = 0.0; 
     260          } 
     261 
     262          double scattering = 0.0; 
     263          if (uu > 1.e-8) { 
     264            for (int sk=0; sk<NUM_MAGNETIC; sk++) { 
     265                const double perp = (qy*MX(sk) - qx*MY(sk)); 
     266                pvec[slds[sk]] = (values[slds[sk]+2] - perp*px)*uu; 
     267            } 
     268            scattering += CALL_IQ(q, q_index, local_values); 
     269          } 
     270          if (dd > 1.e-8){ 
     271            for (int sk=0; sk<NUM_MAGNETIC; sk++) { 
     272                const double perp = (qy*MX(sk) - qx*MY(sk)); 
     273                pvec[slds[sk]] = (values[slds[sk]+2] + perp*px)*dd; 
     274            } 
     275            scattering += CALL_IQ(q, q_index, local_values); 
     276          } 
     277          if (ud > 1.e-8){ 
     278            for (int sk=0; sk<NUM_MAGNETIC; sk++) { 
     279                const double perp = (qy*MX(sk) - qx*MY(sk)); 
     280                pvec[slds[sk]] = perp*py*ud; 
     281            } 
     282            scattering += CALL_IQ(q, q_index, local_values); 
     283            for (int sk=0; sk<NUM_MAGNETIC; sk++) { 
     284                pvec[slds[sk]] = MZ(sk)*pz*ud; 
     285            } 
     286            scattering += CALL_IQ(q, q_index, local_values); 
     287          } 
     288          if (du > 1.e-8) { 
     289            for (int sk=0; sk<NUM_MAGNETIC; sk++) { 
     290                const double perp = (qy*MX(sk) - qx*MY(sk)); 
     291                pvec[slds[sk]] = perp*py*du; 
     292            } 
     293            scattering += CALL_IQ(q, q_index, local_values); 
     294            for (int sk=0; sk<NUM_MAGNETIC; sk++) { 
     295                pvec[slds[sk]] = -MZ(sk)*pz*du; 
     296            } 
     297            scattering += CALL_IQ(q, q_index, local_values); 
     298          } 
     299#else  // !MAGNETIC 
     300          const double scattering = CALL_IQ(q, q_index, local_values); 
     301#endif // !MAGNETIC 
     302//printf("q_index:%d %g %g %g %g\n",q_index, scattering, weight, spherical_correction, weight0); 
     303          result[q_index] += weight * scattering; 
    262304        } 
    263305      } 
    264       p0_index = loop_index%p0_length; 
    265306    } 
    266  
    267     // Update parameter p0 
    268     weight = partial_weight*pd_weight[p0_offset + p0_index]; 
    269     pvec[p0_par] = pd_value[p0_offset + p0_index]; 
    270     if (p0_is_theta) { 
    271       spherical_correction = fmax(fabs(cos(M_PI_180*pvec[p0_par])), 1.e-6); 
    272     } 
    273     p0_index++; 
    274  
    275     #ifdef INVALID 
    276     if (INVALID(local_values)) continue; 
    277     #endif 
    278  
    279     // Accumulate I(q) 
    280     // Note: weight==0 must always be excluded 
    281     if (weight > cutoff) { 
    282       // spherical correction has some nasty effects when theta is +90 or -90 
    283       // where it becomes zero.  If the entirety of the correction 
    284       weight *= spherical_correction; 
    285       pd_norm += weight * CALL_VOLUME(local_values); 
    286  
    287       #ifdef USE_OPENMP 
    288       #pragma omp parallel for 
    289       #endif 
    290       for (int q_index=0; q_index < nq; q_index++) { 
    291 #ifdef MAGNETIC 
    292         const double qx = q[2*q_index]; 
    293         const double qy = q[2*q_index+1]; 
    294         const double qsq = qx*qx + qy*qy; 
    295  
    296         // Constant across orientation, polydispersity for given qx, qy 
    297         double px, py, pz; 
    298         if (qsq > 1e-16) { 
    299           px = (qy*cos_mspin + qx*sin_mspin)/qsq; 
    300           py = (qy*sin_mspin - qx*cos_mspin)/qsq; 
    301           pz = 1.0; 
    302         } else { 
    303           px = py = pz = 0.0; 
    304         } 
    305  
    306         double scattering = 0.0; 
    307         if (uu > 1e-8) { 
    308           for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    309               const double perp = (qy*MX(mag) - qx*MY(mag)); 
    310               pvec[magnetic[mag]] = (values[magnetic[mag]+2] - perp*px)*uu; 
    311           } 
    312           scattering += CALL_IQ(q, q_index, local_values); 
    313         } 
    314         if (dd > 1e-8){ 
    315           for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    316               const double perp = (qy*MX(mag) - qx*MY(mag)); 
    317               pvec[magnetic[mag]] = (values[magnetic[mag]+2] + perp*px)*dd; 
    318           } 
    319           scattering += CALL_IQ(q, q_index, local_values); 
    320         } 
    321         if (ud > 1e-8){ 
    322           for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    323               const double perp = (qy*MX(mag) - qx*MY(mag)); 
    324               pvec[magnetic[mag]] = perp*py*ud; 
    325           } 
    326           scattering += CALL_IQ(q, q_index, local_values); 
    327           for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    328               pvec[magnetic[mag]] = MZ(mag)*pz*ud; 
    329           } 
    330           scattering += CALL_IQ(q, q_index, local_values); 
    331         } 
    332         if (du > 1e-8) { 
    333           for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    334               const double perp = (qy*MX(mag) - qx*MY(mag)); 
    335               pvec[magnetic[mag]] = perp*py*du; 
    336           } 
    337           scattering += CALL_IQ(q, q_index, local_values); 
    338           for (int mag=0; mag<NUM_MAGNETIC; mag++) { 
    339               pvec[magnetic[mag]] = -MZ(mag)*pz*du; 
    340           } 
    341           scattering += CALL_IQ(q, q_index, local_values); 
    342         } 
    343 #else 
    344         double scattering = CALL_IQ(q, q_index, local_values); 
    345 #endif 
    346         result[q_index] += weight*scattering; 
    347       } 
    348     } 
    349   } 
    350  
    351   if (pd_stop >= details->pd_prod) { 
    352     // End of the PD loop we can normalize 
    353     double scale, background; 
    354     scale = values[0]; 
    355     background = values[1]; 
    356     #ifdef USE_OPENMP 
    357     #pragma omp parallel for 
    358     #endif 
    359     for (int q_index=0; q_index < nq; q_index++) { 
    360       result[q_index] = (pd_norm>0. ? scale*result[q_index]/pd_norm + background : background); 
    361     } 
    362   } 
    363  
     307    ++step; 
     308#if MAX_PD>0 
     309    if (step >= pd_stop) break; 
     310    ++i0; 
     311  } 
     312  i0 = 0; 
     313#endif 
     314#if MAX_PD>1 
     315    if (step >= pd_stop) break; 
     316    ++i1; 
     317  } 
     318  i1 = 0; 
     319#endif 
     320#if MAX_PD>2 
     321    if (step >= pd_stop) break; 
     322    ++i2; 
     323  } 
     324  i2 = 0; 
     325#endif 
     326#if MAX_PD>3 
     327    if (step >= pd_stop) break; 
     328    ++i3; 
     329  } 
     330  i3 = 0; 
     331#endif 
     332#if MAX_PD>4 
     333    if (step >= pd_stop) break; 
     334    ++i4; 
     335  } 
     336  i4 = 0; 
     337#endif 
     338 
     339//printf("res: %g/%g\n", result[0], pd_norm); 
    364340  // Remember the updated norm. 
    365341  result[nq] = pd_norm; 
    366 #endif // MAX_PD > 0 
    367342} 
Note: See TracChangeset for help on using the changeset viewer.