Changeset 03cac08 in sasmodels for sasmodels/kernel_iq.c
- Timestamp:
- Mar 20, 2016 9:44:11 PM (8 years ago)
- 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:
- 303d8d6
- Parents:
- d5ac45f
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/kernel_iq.c
rd5ac45f r03cac08 12 12 */ 13 13 14 #ifndef _PAR_BLOCK_ // protected block so we can include this code twice. 15 #define _PAR_BLOCK_ 14 16 15 17 #define MAX_PD 4 // MAX_PD is the max number of polydisperse parameters 16 #define PD_2N 16 // PD_2N is the size of the coordination step table17 18 18 19 typedef struct { … … 31 32 32 33 typedef struct { 33 PARAMETER_ DECL;34 PARAMETER_TABLE; 34 35 } ParameterBlock; 35 36 #define FULL_KERNEL_NAME KERNEL_NAME ## _ ## IQ_FUNC 37 KERNEL 38 void FULL_KERNEL_NAME( 36 #endif 37 38 39 kernel 40 void KERNEL_NAME( 39 41 int nq, // number of q values 40 42 global const ProblemDetails *problem, … … 42 44 global const double *pars, 43 45 global const double *q, // nq q values, with padding to boundary 44 global double *result, // nq return values, again with padding46 global double *result, // nq+3 return values, again with padding 45 47 const double cutoff, // cutoff in the polydispersity weight product 46 48 const int pd_start, // where we are in the polydispersity loop 47 const int pd_stop ,// where we are stopping in the polydispersity loop49 const int pd_stop // where we are stopping in the polydispersity loop 48 50 ) 49 51 { … … 52 54 // walk the polydispersity cube. 53 55 local ParameterBlock local_pars; // current parameter values 54 const double *parvec = &local_pars; // Alias named parameters with a vector56 double *pvec = (double *)(&local_pars); // Alias named parameters with a vector 55 57 56 58 local int offset[NPARS-2]; … … 60 62 // Shouldn't need to copy!! 61 63 for (int k=0; k < NPARS; k++) { 62 p arvec[k] = pars[k+2]; // skip scale and background64 pvec[k] = pars[k+2]; // skip scale and background 63 65 } 64 66 … … 68 70 for (int i=0; i < nq; i++) { 69 71 { 70 const double scattering = IQ_FUNC(IQ_PARS, IQ_PARAMETERS);72 const double scattering = CALL_IQ(q, i, local_pars); 71 73 result[i] += pars[0]*scattering + pars[1]; 72 74 } … … 99 101 norm = result[nq]; 100 102 vol = result[nq+1]; 101 norm_vol = result s[nq+2];103 norm_vol = result[nq+2]; 102 104 } 103 105 104 106 // Location in the polydispersity hypercube, one index per dimension. 105 local int pd_index[ PD_MAX];107 local int pd_index[MAX_PD]; 106 108 107 109 // Trigger the reset behaviour that happens at the end the fast loop 108 110 // by setting the initial index >= weight vector length. 109 pd_index[0] = pd_length[0]; 111 pd_index[0] = problem->pd_length[0]; 112 110 113 111 114 // need product of weights at every Iq calc, so keep product of … … 120 123 for (int loop_index=pd_start; loop_index < pd_stop; loop_index++) { 121 124 // check if indices need to be updated 122 if (pd_index[0] >= p d_length[0]) {125 if (pd_index[0] >= problem->pd_length[0]) { 123 126 124 127 // RESET INDICES 125 pd_index[0] = loop_index%p d_length[0];128 pd_index[0] = loop_index%problem->pd_length[0]; 126 129 partial_weight = 1.0; 127 130 partial_volweight = 1.0; 128 131 for (int k=1; k < MAX_PD; k++) { 129 pd_index[k] = (loop_index%p d_length[k])/pd_stride[k];130 const double wi = weights[p d_offset[0]+pd_index[0]];132 pd_index[k] = (loop_index%problem->pd_length[k])/problem->pd_stride[k]; 133 const double wi = weights[problem->pd_offset[0]+pd_index[0]]; 131 134 partial_weight *= wi; 132 if (p d_isvol[k]) partial_volweight *= wi;135 if (problem->pd_isvol[k]) partial_volweight *= wi; 133 136 } 134 137 for (int k=0; k < NPARS; k++) { 135 int coord = p ar_coord[k];136 int this_offset = p ar_offset[k];138 int coord = problem->par_coord[k]; 139 int this_offset = problem->par_offset[k]; 137 140 int block_size = 1; 138 141 for (int bit=0; bit < MAX_PD && coord != 0; bit++) { 139 142 if (coord&1) { 140 143 this_offset += block_size * pd_index[bit]; 141 block_size *= p d_length[bit];144 block_size *= problem->pd_length[bit]; 142 145 } 143 146 coord /= 2; 144 147 } 145 148 offset[k] = this_offset; 146 parvec[k] = pars[this_offset]; 147 } 148 weight = partial_weight * weights[pd_offset[0]+pd_index[0]] 149 if (theta_var >= 0) { 150 spherical_correction = fabs(cos(M_PI_180*parvec[theta_var])); 151 } 152 if (!fast_theta) weight *= spherical_correction; 149 pvec[k] = pars[this_offset]; 150 } 151 weight = partial_weight * weights[problem->pd_offset[0]+pd_index[0]]; 152 if (problem->theta_var >= 0) { 153 spherical_correction = fabs(cos(M_PI_180*pvec[problem->theta_var])); 154 } 155 if (!problem->fast_theta) { 156 weight *= spherical_correction; 157 } 153 158 154 159 } else { … … 156 161 // INCREMENT INDICES 157 162 pd_index[0] += 1; 158 const double wi = weights[p d_offset[0]+pd_index[0]];163 const double wi = weights[problem->pd_offset[0]+pd_index[0]]; 159 164 weight = partial_weight*wi; 160 if (p d_isvol[0]) vol_weight *= wi;165 if (problem->pd_isvol[0]) vol_weight *= wi; 161 166 for (int k=0; k < problem->fast_coord_count; k++) { 162 parvec[ fast_coord_index[k]] 163 = pars[offset[fast_coord_index[k]] + pd_index[0]]; 164 } 165 if (fast_theta) weight *= fabs(cos(M_PI_180*parvec[theta_var])); 166 167 pvec[problem->fast_coord_index[k]] 168 = pars[offset[problem->fast_coord_index[k]]++]; 169 } 170 if (problem->fast_theta) { 171 weight *= fabs(cos(M_PI_180*pvec[problem->theta_var])); 172 } 167 173 } 168 174 … … 180 186 #endif 181 187 for (int i=0; i < nq; i++) { 182 { 183 const double scattering = CALL_IQ(q, nq, i, local_pars); 188 const double scattering = CALL_IQ(q, i, local_pars); 184 189 result[i] += weight*scattering; 185 190 } 191 } 186 192 } 187 193 //Makes a normalization avialable for the next round … … 191 197 192 198 //End of the PD loop we can normalize 193 if (pd_stop == pd_stride[MAX_PD-1]) {}199 if (pd_stop >= problem->pd_stride[MAX_PD-1]) { 194 200 #ifdef USE_OPENMP 195 201 #pragma omp parallel for
Note: See TracChangeset
for help on using the changeset viewer.