8080#define PHONON_SIMPLE $Revision$
8181#define T2E (1/11.605) /* Kelvin to meV */
8282
83- struct neutron_and_phonon_params {
83+ struct phonon_params {
84+ double a_; // d spacing of the cubic lattice
85+ double c_; // Speed of sound in the material
86+ double gap_; // optional spin gap
87+ double ah; // Half of a
88+ int e_steps_high_;
89+ int e_steps_low_;
90+ };
91+ struct neutron_params {
8492 // Statically allocate vectors that are always 3
8593 double vf; // Final velocity size
8694 double vi; // Initial velocity size
9098 double vi_x; // vi is the initial velocity vector
9199 double vi_y;
92100 double vi_z;
93- double a_; // d spacing of the cubic lattice
94- double c_; // Speed of sound in the material
95- double gap_; // optional spin gap
96- double ah; // Half of a
97- int e_steps_high_;
98- int e_steps_low_;
99101 };
100102
101103#pragma acc routine
@@ -126,26 +128,26 @@ void fatalerror(char *s)
126128 }
127129
128130 #pragma acc routine
129- double omega_q(struct neutron_and_phonon_params *parms )
131+ double omega_q(struct neutron_params *neutron, struct phonon_params *phonon )
130132 {
131133 /* dispersion in units of meV */
132134 double vi, vf, vv_x, vv_y, vv_z, vi_x, vi_y, vi_z;
133135 double q, qx, qy, qz, Jq, res_phonon, res_neutron;
134136 double ah, a, c;
135137 double gap;
136138
137- vf=parms ->vf;
138- vi=parms ->vi;
139- vv_x=parms ->vv_x;
140- vv_y=parms ->vv_y;
141- vv_z=parms ->vv_z;
142- vi_x=parms ->vi_x;
143- vi_y=parms ->vi_y;
144- vi_z=parms ->vi_z;
145- a =parms ->a_;
146- c =parms ->c_;
147- gap =parms ->gap_;
148- ah =parms ->ah;
139+ vf=neutron ->vf;
140+ vi=neutron ->vi;
141+ vv_x=neutron ->vv_x;
142+ vv_y=neutron ->vv_y;
143+ vv_z=neutron ->vv_z;
144+ vi_x=neutron ->vi_x;
145+ vi_y=neutron ->vi_y;
146+ vi_z=neutron ->vi_z;
147+ a =phonon ->a_;
148+ c =phonon ->c_;
149+ gap =phonon ->gap_;
150+ ah =phonon ->ah;
149151
150152 qx=V2K*(vi_x-vf*vv_x);
151153 qy=V2K*(vi_y-vf*vv_y);
@@ -164,15 +166,17 @@ void fatalerror(char *s)
164166 }
165167
166168
167- double zridd(double (*func)(struct neutron_and_phonon_params*), double x1, double x2, struct neutron_and_phonon_params *parms, double xacc)
169+ double zridd(double (*func)(struct neutron_params*, struct phonon_params*),
170+ double x1, double x2, struct neutron_params *neutron,
171+ struct phonon_params *phonon, double xacc)
168172 {
169173 int j;
170174 double ans, fh, fl, fm, fnew, s, xh, xl, xm, xnew;
171175
172- parms ->vf=x1;
173- fl=func(parms );
174- parms ->vf=x2;
175- fh=func(parms );
176+ neutron ->vf=x1;
177+ fl=func(neutron, phonon );
178+ neutron ->vf=x2;
179+ fh=func(neutron, phonon );
176180 if (fl*fh >= 0)
177181 {
178182 if (fl==0) return x1;
@@ -187,17 +191,17 @@ double zridd(double (*func)(struct neutron_and_phonon_params*), double x1, doubl
187191 for (j=1; j<MAXRIDD; j++)
188192 {
189193 xm=0.5*(xl+xh);
190- parms ->vf=xm;
191- fm=func(parms );
194+ neutron ->vf=xm;
195+ fm=func(neutron,phonon );
192196 s=sqrt(fm*fm-fl*fh);
193197 if (s == 0.0)
194198 return ans;
195199 xnew=xm+(xm-xl)*((fl >= fh ? 1.0 : -1.0)*fm/s);
196200 if (fabs(xnew-ans) <= xacc)
197201 return ans;
198202 ans=xnew;
199- parms ->vf=ans;
200- fnew=func(parms );
203+ neutron ->vf=ans;
204+ fnew=func(neutron,phonon );
201205 if (fnew == 0.0) return ans;
202206 if (fabs(fm)*SIGN(fnew) != fm)
203207 {
@@ -229,15 +233,15 @@ double zridd(double (*func)(struct neutron_and_phonon_params*), double x1, doubl
229233 }
230234
231235#pragma acc routine
232- double zridd_gpu(double x1, double x2, struct neutron_and_phonon_params *parms , double xacc)
236+ double zridd_gpu(double x1, double x2, struct neutron_params *neutron, struct phonon_params* phonon , double xacc)
233237 {
234238 int j;
235239 double ans, fh, fl, fm, fnew, s, xh, xl, xm, xnew;
236240
237- parms ->vf=x1;
238- fl=omega_q(parms );
239- parms ->vf=x2;
240- fh=omega_q(parms );
241+ neutron ->vf=x1;
242+ fl=omega_q(neutron, phonon );
243+ neutron ->vf=x2;
244+ fh=omega_q(neutron, phonon );
241245 if (fl*fh >= 0)
242246 {
243247 if (fl==0) return x1;
@@ -252,17 +256,17 @@ double zridd_gpu(double x1, double x2, struct neutron_and_phonon_params *parms,
252256 for (j=1; j<MAXRIDD; j++)
253257 {
254258 xm=0.5*(xl+xh);
255- parms ->vf=xm;
256- fm=omega_q(parms );
259+ neutron ->vf=xm;
260+ fm=omega_q(neutron, phonon );
257261 s=sqrt(fm*fm-fl*fh);
258262 if (s == 0.0)
259263 return ans;
260264 xnew=xm+(xm-xl)*((fl >= fh ? 1.0 : -1.0)*fm/s);
261265 if (fabs(xnew-ans) <= xacc)
262266 return ans;
263267 ans=xnew;
264- parms ->vf=ans;
265- fnew=omega_q(parms );
268+ neutron ->vf=ans;
269+ fnew=omega_q(neutron, phonon );
266270 if (fnew == 0.0) return ans;
267271 if (fabs(fm)*SIGN(fnew) != fm)
268272 {
@@ -297,30 +301,30 @@ double zridd_gpu(double x1, double x2, struct neutron_and_phonon_params *parms,
297301#define ROOTACC 1e-8
298302
299303 void findroots(double brack_low, double brack_mid, double brack_high,
300- double *list, int* index, double (*f)(struct neutron_and_phonon_params *),
301- struct neutron_and_phonon_params *parms )
304+ double *list, int* index, double (*f)(struct neutron_params*, struct phonon_params *),
305+ struct neutron_params *neutron, struct phonon_params *phonon )
302306 {
303307 double root;
304308 // Energy gain and energy loss spaces are not equally big. We check uniformly
305309 // So we use two different ranges
306310 double range_low = brack_mid - brack_low;
307311 double range_high = brack_high - brack_mid;
308312 // First in energy loss for the neutron
309- for (int i=0; i<parms ->e_steps_low_; i++){
310- root = zridd(f, brack_low+range_low*i/ parms ->e_steps_low_,
311- brack_low+range_low*(i+1)/ parms ->e_steps_low_,
312- parms , ROOTACC);
313+ for (int i=0; i<phonon ->e_steps_low_; i++){
314+ root = zridd(f, brack_low+range_low*i/ phonon ->e_steps_low_,
315+ brack_low+range_low*(i+1)/ phonon ->e_steps_low_,
316+ neutron, phonon , ROOTACC);
313317 if (root != UNUSED)
314318 {
315319 list[(*index)++]=root;
316320 }
317321 }
318322
319323 // Then in energy gain for the neutron
320- for (int i=0; i<parms ->e_steps_high_; i++){
321- root = zridd(f, brack_low+range_high*i/ parms ->e_steps_high_,
322- brack_low+range_high*(i+1)/ parms ->e_steps_high_,
323- parms , ROOTACC);
324+ for (int i=0; i<phonon ->e_steps_high_; i++){
325+ root = zridd(f, brack_low+range_high*i/ phonon ->e_steps_high_,
326+ brack_low+range_high*(i+1)/ phonon ->e_steps_high_,
327+ neutron, phonon , ROOTACC);
324328 if (root != UNUSED){
325329 list[(*index)++]=root;
326330 }
@@ -329,7 +333,7 @@ double zridd_gpu(double x1, double x2, struct neutron_and_phonon_params *parms,
329333
330334#pragma acc routine
331335 void findroots_gpu(double brack_low, double brack_mid, double brack_high,
332- double *list, int* index, struct neutron_and_phonon_params *parms )
336+ double *list, int* index, struct neutron_params *neutron, struct phonon_params *phonon )
333337 {
334338 double root,range=brack_mid-brack_low;
335339 int i, steps=100;
@@ -338,13 +342,13 @@ double zridd_gpu(double x1, double x2, struct neutron_and_phonon_params *parms,
338342 {
339343 root = zridd_gpu(brack_low+range*i/(int)steps,
340344 brack_low+range*(i+1)/(int)steps,
341- parms , ROOTACC);
345+ neutron,phonon , ROOTACC);
342346 if (root != UNUSED)
343347 {
344348 list[(*index)++]=root;
345349 }
346350 }
347- root = zridd_gpu(brack_mid, brack_high, parms , ROOTACC);
351+ root = zridd_gpu(brack_mid, brack_high, neutron,phonon , ROOTACC);
348352 if (root != UNUSED)
349353 {
350354 list[(*index)++]=root;
@@ -363,7 +367,8 @@ DECLARE
363367 double V_my_a_v;
364368 double DV;
365369 double* vf_list;// List of allowed final velocities. Has length of scan_steps
366- struct neutron_and_phonon_params parms;
370+ struct neutron_params neutron;
371+ struct phonon_params phonon;
367372
368373%}
369374INITIALIZE
@@ -375,12 +380,12 @@ INITIALIZE
375380 DV = 0.001; /* Velocity change used for numerical derivative */
376381
377382 // Set constant parameters for parms object
378- parms .a_ = a;
379- parms .c_ = c;
380- parms .gap_ = gap;
381- parms .ah = a/2.0;
382- parms .e_steps_high_ = e_steps_high;
383- parms .e_steps_low_ = e_steps_low;
383+ phonon .a_ = a;
384+ phonon .c_ = c;
385+ phonon .gap_ = gap;
386+ phonon .ah = a/2.0;
387+ phonon .e_steps_high_ = e_steps_high;
388+ phonon .e_steps_low_ = e_steps_low;
384389
385390 /* now compute target coords if a component index is supplied */
386391 if (!target_index && !target_x && !target_y && !target_z) target_index=1;
@@ -448,27 +453,27 @@ TRACE
448453 }
449454 NORM(vx, vy, vz);
450455 nf=0;
451- parms .vf = -1;
452- parms .vi = v_i;
453- parms .vv_x = vx;
454- parms .vv_y = vy;
455- parms .vv_z = vz;
456- parms .vi_x = vx_i;
457- parms .vi_y = vy_i;
458- parms .vi_z = vz_i;
456+ neutron .vf = -1;
457+ neutron .vi = v_i;
458+ neutron .vv_x = vx;
459+ neutron .vv_y = vy;
460+ neutron .vv_z = vz;
461+ neutron .vi_x = vx_i;
462+ neutron .vi_y = vy_i;
463+ neutron .vi_z = vz_i;
459464
460465 #ifndef OPENACC
461- findroots(0, v_i, v_i+2*c*V2K/VS2E, vf_list, &nf, omega_q, &parms );
466+ findroots(0, v_i, v_i+2*c*V2K/VS2E, vf_list, &nf, omega_q, &neutron, &phonon );
462467 #else
463- findroots_gpu(0, v_i, v_i+2*c*V2K/VS2E, vf_list, &nf, &parms );
468+ findroots_gpu(0, v_i, v_i+2*c*V2K/VS2E, vf_list, &nf, &neutron, &phonon );
464469 #endif
465470 index=(int)floor(rand01()*nf);
466471
467472 v_f=vf_list[index];
468- parms .vf=v_f-DV;
469- f1=omega_q(&parms );
470- parms .vf=v_f+DV;
471- f2=omega_q(&parms );
473+ neutron .vf=v_f-DV;
474+ f1=omega_q(&neutron, &phonon );
475+ neutron .vf=v_f+DV;
476+ f2=omega_q(&neutron, &phonon );
472477 J_factor = fabs(f2-f1)/(2*DV);
473478 omega=VS2E*(v_i*v_i-v_f*v_f);
474479 vx *= v_f;
@@ -497,11 +502,17 @@ TRACE
497502 p4 = 2*VS2E*v_f/J_factor; /* Jacobian of delta functions in cross section */
498503 p5 = b*b/M; /* Cross section factor 2 */
499504 p *= p1*p2*p3*p4*p5;
500-
505+ // Finally, set vf_list to zero again
506+ memset(vf_list, 0, nf * sizeof(double));
501507 } /* else transmit: Neutron did not hit the sample */
502508
503- // Finally, set vf_list to zero again
504- memset(vf_list, 0, nf * sizeof(double));
509+
510+ %}
511+
512+ FINALLY
513+ %{
514+ free(vf_list);
515+
505516%}
506517
507518MCDISPLAY
0 commit comments