HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
wavespeeds.c
Go to the documentation of this file.
1 
7 #include "decs.h"
8 
9 
10 
16 int vchar_all(FTYPE *pr, struct of_state *q, int dir, struct of_geom *geom, FTYPE *vmaxall, FTYPE *vminall,int *ignorecourant)
17 {
18  FTYPE vminmhd,vmaxmhd;
19  FTYPE vminrad,vmaxrad;
20  FTYPE vminrad2,vmaxrad2;
21 
22  vchar_each(pr, q, dir, geom, &vmaxmhd, &vminmhd, &vmaxrad, &vminrad, &vmaxrad2, &vminrad2, ignorecourant);
23  // below correct even if EOMRADTYPE==EOMRADNONE because vchar_each() sets both mhd and rad to be mhd and so below always chooses the mhd values.
24  *vminall=MIN(vminmhd,vminrad2); // vminrad2 for dt
25  *vmaxall=MAX(vmaxmhd,vmaxrad2); // vmaxrad2 for dt
26 
27 
28  return(0);
29 }
30 
31 int vchar_each(FTYPE *pr, struct of_state *q, int dir, struct of_geom *geom, FTYPE *vmaxmhd, FTYPE *vminmhd, FTYPE *vmaxrad, FTYPE *vminrad, FTYPE *vmaxrad2, FTYPE *vminrad2,int *ignorecourant)
32 {
33 
34  vchar(pr, q, dir, geom, vmaxmhd, vminmhd,ignorecourant);
36  vchar_rad(pr, q, dir, geom, vmaxrad, vminrad, vmaxrad2, vminrad2, ignorecourant);
37  }
38  else{// default as if no other values for wave speeds
39  *vmaxrad2=*vmaxrad=*vmaxmhd;
40  *vminrad2=*vminrad=*vminmhd;
41  }
42 
43  // dualfprintf(fail_file,"SPEEDS: %g %g : %g %g\n",*vmaxmhd,*vminmhd,*vmaxrad2,*vminrad2);
44 
45  return(0);
46 }
47 
48 
50 int get_wavespeeds(int dir, struct of_geom *ptrgeom, FTYPE *p_l, FTYPE *p_r, FTYPE *U_l, FTYPE *U_r, FTYPE *F_l, FTYPE *F_r, struct of_state *state_l, struct of_state * state_r, FTYPE *cminmax_l, FTYPE *cminmax_r, FTYPE *cminmax, FTYPE *ctopptr, FTYPE *cminmaxrad_l, FTYPE *cminmaxrad_r, FTYPE *cminmaxrad, FTYPE *ctopradptr, FTYPE *cminmaxrad2_l, FTYPE *cminmaxrad2_r, FTYPE *cminmaxrad2, FTYPE *ctoprad2ptr)
51 {
52  int cminmax_calc(FTYPE cmin_l,FTYPE cmin_r,FTYPE cmax_l,FTYPE cmax_r,FTYPE *cmin,FTYPE *cmax,FTYPE *ctop);
53  int cminmax_calc_1(FTYPE cmin_l,FTYPE cmin_r,FTYPE cmax_l,FTYPE cmax_r,FTYPE *cmin,FTYPE *cmax);
54  int cminmax_calc_2(FTYPE *cmin,FTYPE *cmax,FTYPE *ctop);
55  int failreturn;
56  FTYPE ftemp;
57  FTYPE p_roe[NPR],cminmax_roe[NUMCS];
58  struct of_state state_roe;
59  FTYPE cminmax_o[NUMCS];
60  FTYPE Hroe,cminmaxnonrel_roe[NUMCS];
61  void get_roe_averaged_state(int dir, FTYPE *p_l, struct of_state *state_l, FTYPE *Ul, FTYPE * p_r, struct of_state *state_r, FTYPE *Ur, struct of_geom *geom, FTYPE * p_roe, FTYPE *Hroe, FTYPE *cminnonrel_roe, FTYPE*cmaxnonrel_roe);
62  int q;
63  int ignorecourant;
64  int i,j,k,loc;
65 
66  i=ptrgeom->i;
67  j=ptrgeom->j;
68  k=ptrgeom->k;
69  loc=ptrgeom->p;
70 
71 
72 
73 #if(USEGLOBALWAVE==0 || STOREWAVESPEEDS==2)
74 
75  // characteristic based upon t^n level for 1/2 step and t^{n+1/2} level for the full step.
76  MYFUN(vchar_each(p_l, state_l, dir, ptrgeom, &cminmax_l[CMAX], &cminmax_l[CMIN], &cminmaxrad_l[CMAX], &cminmaxrad_l[CMIN], &cminmaxrad2_l[CMAX], &cminmaxrad2_l[CMIN],&ignorecourant),"step_ch.c:fluxcalc()", "vchar() dir=1or2", 1);
77  MYFUN(vchar_each(p_r, state_r, dir, ptrgeom, &cminmax_r[CMAX], &cminmax_r[CMIN], &cminmaxrad_r[CMAX], &cminmaxrad_r[CMIN], &cminmaxrad2_r[CMAX], &cminmaxrad2_r[CMIN],&ignorecourant),"step_ch.c:fluxcalc()", "vchar() dir=1or2", 2);
78 
79  cminmax_calc(cminmax_l[CMIN],cminmax_r[CMIN],cminmax_l[CMAX],cminmax_r[CMAX],&cminmax[CMIN],&cminmax[CMAX],ctopptr);
80  // cminmax_calc_1(cminmax_l[CMIN],cminmax_r[CMIN],cminmax_l[CMAX],cminmax_r[CMAX],&cminmax[CMIN],&cminmax[CMAX]);
82  cminmax_calc(cminmaxrad_l[CMIN],cminmaxrad_r[CMIN],cminmaxrad_l[CMAX],cminmaxrad_r[CMAX],&cminmaxrad[CMIN],&cminmaxrad[CMAX],ctopradptr);
83 
84  cminmax_calc(cminmaxrad2_l[CMIN],cminmaxrad2_r[CMIN],cminmaxrad2_l[CMAX],cminmaxrad2_r[CMAX],&cminmaxrad2[CMIN],&cminmaxrad2[CMAX],ctoprad2ptr);
85  // cminmax_calc_1(cminmaxrad_l[CMIN],cminmaxrad_r[CMIN],cminmaxrad_l[CMAX],cminmaxrad_r[CMAX],&cminmaxrad[CMIN],&cminmaxrad[CMAX]);
86  }
87  // have cmin,cmax,ctop here
88 
89 #if(STOREWAVESPEEDS==2)
90  // Use fact that always compute flux before need wspeed [GODMARK: Not sure for old interpline use of wspeed, but that's deprecated code]
91  // remove sign information for wspeed by calling cminmax_calc() above already
92  GLOBALMACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k)=cminmax[CMIN];
93  GLOBALMACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k)=cminmax[CMAX];
95  GLOBALMACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k)=cminmaxrad[CMIN];
96  GLOBALMACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k)=cminmaxrad[CMAX];
97 
98  GLOBALMACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k)=cminmaxrad2[CMIN];
99  GLOBALMACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k)=cminmaxrad2[CMAX];
100  }
101 #endif
102 
103  // cminmax_calc_2(&cminmax[CMIN],&cminmax[CMAX],ctopptr);
104 
105 #else
106  // other non-local estimate
107  cminmax_l[CMIN]=cminmax_r[CMIN]=cminmax[CMIN]=GLOBALMACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k);
108  cminmax_l[CMAX]=cminmax_r[CMAX]=cminmax[CMAX]=GLOBALMACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k);
109  if(EOMRADTYPE!=EOMRADNONE){
110  cminmaxrad_l[CMIN]=cminmaxrad_r[CMIN]=cminmaxrad[CMIN]=GLOBALMACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k);
111  cminmaxrad_l[CMAX]=cminmaxrad_r[CMAX]=cminmaxrad[CMAX]=GLOBALMACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k);
112 
113  cminmaxrad2_l[CMIN]=cminmaxrad2_r[CMIN]=cminmaxrad2[CMIN]=GLOBALMACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k);
114  cminmaxrad2_l[CMAX]=cminmaxrad2_r[CMAX]=cminmaxrad2[CMAX]=GLOBALMACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k);
115  }
116  // change so feeds into Riemann solver with "standard" sign
117  cminmax[CMIN] = fabs(max(0., -cminmax[CMIN]));
118  cminmax[CMAX] = fabs(max(0., cminmax[CMAX]));
119  *ctopptr=max(cminmax[CMIN],cminmax[CMAX]);
120 
121  if(EOMRADTYPE!=EOMRADNONE){
122  cminmaxrad[CMIN] = fabs(max(0., -cminmaxrad[CMIN]));
123  cminmaxrad[CMAX] = fabs(max(0., cminmaxrad[CMAX]));
124  *ctopradptr=max(cminmaxrad[CMIN],cminmaxrad[CMAX]);
125 
126  cminmaxrad2[CMIN] = fabs(max(0., -cminmaxrad2[CMIN]));
127  cminmaxrad2[CMAX] = fabs(max(0., cminmaxrad2[CMAX]));
128  *ctoprad2ptr=max(cminmaxrad2[CMIN],cminmaxrad2[CMAX]);
129  }
130  // have cmin,cmax,ctop here
131 #endif
132 
133 
134 
136  //
137  // get Roe-averaged versions of wave speed for flux calculation and for dt calculation
138  //
140 
141 #if(ROEAVERAGEDWAVESPEED)
142 
143  if(EOMRADTYPE!=EOMRADNONE){
144  dualfprintf(fail_file,"ROEAVERAGE not setup for radiation\n");
145  myexit(1);
146  }
147 
148  // get Roe-averaged primitive state
149  get_roe_averaged_state(dir, p_l, state_l, U_l, p_r, state_r, U_r, ptrgeom, p_roe, &Hroe, &cminmaxnonrel_roe[CMIN], &cminmaxnonrel_roe[CMAX]);
150 
151 
152 #if(ATHENAROE==0) // doing Jon method
153 
154  // get HARM state
155  MYFUN(get_state(p_roe, ptrgeom, &state_roe),"flux.c:p2SFUevolve", "get_state()", 1);
156  // get Roe-averaged state's wavespeeds
157  MYFUN(vchar(p_roe, &state_roe, dir, ptrgeom, &cminmax_roe[CMAX], &cminmax_roe[CMIN],&ignorecourant),"step_ch.c:fluxcalc()", "vchar() dir=1or2", 3);
158 
159 
160 #if(1) // Jon's version of MIN/MAXing
161 
162  for(q=0;q<NUMCS;q++){
163  // fastest left-going wave (q=0) and then fastest right-going wave (q=1)
164  cminmax[q]=MINMAX(q,cminmax_roe[q],MINMAX(q,cminmax_l[q],cminmax_r[q]));
165  }
166 
167 
168 #else // doing Athena-like method of min/maxing (fails to work for some tests)
169 
170  // New version of cminmax
171  /*
172  for(q=0;q<NUMCS;q++){
173  cminmax_l[q] = MINMAX(q,cminmax_l[q],0.0);
174  cminmax_r[q] = MINMAX(q,cminmax_r[q],0.0);
175  cminmax[q]=2.0*cminmax_l[q]*cminmax_r[q]/(cminmax_l[q]+cminmax_r[q]+SMALL);
176  }
177  */
178 
179  cminmax[CMIN] = cminmax_l[CMIN];
180  cminmax[CMAX] = cminmax_r[CMAX];
181  for(q=0;q<NUMCS;q++){
182  cminmax[q]=MINMAX(q,cminmax_roe[q],cminmax[q]);
183  }
184 #endif
185 
186 
187 
188 
189 #else // else if ATHENAROE==1 (fails to work for some tests)
190 
191  // non-rel HD version
192  for(q=0;q<NUMCS;q++){
193  cminmax_roe[q]=cminmaxnonrel_roe[q];
194  }
195 
196 
197 #if(1) // Athena way
198  // This is Athena's way of min/maxing
199  cminmax[CMAX]=MAX(cminmax_roe[CMAX],cminmax_r[CMAX]);
200  cminmax[CMIN]=MIN(cminmax_roe[CMIN],cminmax_l[CMIN]);
201 
202 #else // testing way (same as Athena right now)
203 
204  // New version of cmin/cmax
205  /*
206  for(q=0;q<NUMCS;q++){
207  cminmax_l[q] = MINMAX(q,cminmax_l[q],0.0);
208  cminmax_r[q] = MINMAX(q,cminmax_r[q],0.0);
209  cminmax[q] = 2.0*cminmax_l[q]*cminmax_r[q]/(cminmax_l[q] + cminmax_r[q] + SMALL);
210  }
211  */
212 
213  // Jon's way even with ATHENAROE==1
214  for(q=0;q<NUMCS;q++){
215  // fastest left-going wave (q=0) and then fastest right-going wave (q=1)
216  cminmax[q]=MINMAX(q,cminmax_roe[q],MINMAX(q,cminmax_l[q],cminmax_r[q]));
217  }
218 #endif
219 
220 
221 
222 #endif // end over ATHENAROE=0/1
223 
224 
225 
226  // fastest eigenvalue
227  // Athena sets this, but never uses it apparently
228  //ctop_roe=MAX(fabs(cminmax_roe[CMAX]),fabs(cminmax_roe[CMIN]));
229 
230 
231  // change so feeds into Riemann solver with "standard" sign
232  cminmax[CMIN] = fabs(max(0., -cminmax[CMIN]));
233  cminmax[CMAX] = fabs(max(0., cminmax[CMAX]));
234  *ctopptr=max(cminmax[CMIN],cminmax[CMAX]);
235 
236  // have Roe versions of cmin,cmax,ctop here
237 #endif // end over ROEAVERAGEDWAVESPEED=1
238 
239  return(0);
240 
241 }
242 
243 
244 
245 
248 void get_roe_averaged_state(int dir, FTYPE *p_l, struct of_state *state_l, FTYPE *Ul, FTYPE * p_r, struct of_state *state_r, FTYPE *Ur, struct of_geom *geom, FTYPE * p_roe, FTYPE *Hroe, FTYPE *cminnonrel_roe, FTYPE*cmaxnonrel_roe)
249 {
250  FTYPE sqrtrhol,sqrtrhor,isqrtrholr;
251  int j,k;
252  FTYPE Pl, Pr, Hl, Hr; // specific enthalpy
253  FTYPE bsql,bsqr;
254  FTYPE vsqroe;
255  FTYPE croe;
256  int ii=geom->i;
257  int jj=geom->j;
258  int kk=geom->k;
259  int loc=geom->p;
260 
261  Pl=pressure_rho0_u_simple(ii,jj,kk,loc,p_l[RHO],p_l[UU]);
262  Pr=pressure_rho0_u_simple(ii,jj,kk,loc,p_r[RHO],p_r[UU]);
263 
264 
265  // get weighted density
266  sqrtrhol=sqrt(p_l[RHO]);
267  sqrtrhor=sqrt(p_r[RHO]);
268  isqrtrholr=1.0/(sqrtrhol+sqrtrhor);
269 
270  // Roe-averaged density
271  p_roe[RHO] = sqrtrhol*sqrtrhor;
272 
273  // Roe-averaged internal energy (no consideration of geometry)
274  p_roe[UU] = p_roe[RHO] * ( p_l[UU] / sqrtrhol + p_r[UU] / sqrtrhor ) * isqrtrholr;
275 
276  // Roe-averaged velocity (no consideration of geometry)
277  SLOOPA(j) p_roe[UU+j] = (sqrtrhol*p_l[UU+j] + sqrtrhor*p_r[UU+j])*isqrtrholr;
278 
279  // Roe-averaged magnetic field (no consideration of geometry)
280  SLOOPA(j) p_roe[B1-1+j] = (sqrtrhor*p_l[B1-1+j] + sqrtrhol*p_r[B1-1+j])*isqrtrholr;
281 
282 
283  // b^2
284  bsql = dot(state_l->bcon, state_l->bcov);
285  bsqr = dot(state_r->bcon, state_r->bcov);
286 
287 
288 #if(!ATHENAROE)
289  // Jon version (relativistically correct)
290  Hl = (p_l[UU] + Pl + 0.5*bsql)/p_l[RHO];
291  Hr = (p_r[UU] + Pr + 0.5*bsqr)/p_r[RHO];
292  *Hroe=(sqrtrhol*Hl + sqrtrhor*Hr)*isqrtrholr;
293 #else
294  // Athena version (relativistically correct)
295  *Hroe = ((Ul[UU] + Pl + 0.5*bsql)/sqrtrhol + (Ur[UU] + Pr + 0.5*bsqr)/sqrtrhor)*isqrtrholr;
296 #endif
297 
299  // GET NON-REL CASE wave speeds
300  // try Einfeldt (1988) 5.1a - 5.3 for non-rel HD
301  // non-rel HD Roe-averaged version of wavespeeds
302 
303  // v^2 in non-rel case
304  vsqroe=0.0;
305  SLOOP(j,k) vsqroe += p_roe[UU+j]*p_roe[UU+k] * geom->gcov[GIND(j,k)];
306 
307  // ideal gas only GODMARK (gam)
308  croe=sqrt( (gam-1.0)*(*Hroe - 0.5*vsqroe));
309  *cminnonrel_roe = p_roe[UU+dir] - croe;
310  *cmaxnonrel_roe = p_roe[UU+dir] + croe;
311 
312 
313 
314 
315 
316 }
317 
318 
319 
322 int get_global_wavespeeds_full(int dir, int is, int ie, int js, int je, int ks, int ke, int idel, int jdel, int kdel, FTYPE (*prim)[NSTORE2][NSTORE3][NPR],FTYPE (*finalwspeed)[COMPDIM][NUMCS][NSTORE1][NSTORE2][NSTORE3])
323 {
324 
325 
326  // OPTMARK: bit excessive
327  // COMPFULLLOOP{
328 #if(STOREFLUXSTATE)
329  // if stored state, then don't need EOS stuff
330 #pragma omp parallel
331 #else
332 #pragma omp parallel OPENMPGLOBALPRIVATEFORSTATEANDGEOM
333 #endif
334  {
335 
336  int i,j,k;
337  struct of_geom geomdontuse;
338  struct of_geom *ptrgeom=&geomdontuse;
340 
341  // generally ptr's are different inside parallel block
342  ptrgeom=&geomdontuse;
343 
344 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize))
346  OPENMP3DLOOPBLOCK2IJK(i,j,k);
347 
348  // get geometry for center pre-interpolated values
349  get_geometry(i, j, k, CENT, ptrgeom);
350 
351  MYFUN(get_global_wavespeeds(dir,ptrgeom, MAC(prim,i,j,k),GLOBALMACP1A0(wspeedtemp,EOMSETMHD,i,j,k),GLOBALMACP1A0(wspeedtemp,EOMSETRAD,i,j,k),GLOBALMACP1A0(wspeedtemp,EOMSETRADFORDT,i,j,k)),"flux.c:fluxcalc_standard()", "get_global_wavespeeds()", 0);
352  }
353  }// end parallel region
354 
355 
356 
357  // get char. velocity estimate as some average over local or global zones
358  global_vchar(GLOBALPOINT(wspeedtemp), dir, is, ie, js, je, ks, ke, idel, jdel, kdel, POINT(finalwspeed));
359  // now wspeed contains left/right fastest wave speed (with sign preserved)
360 
361  return(0);
362 
363 }
364 
365 
366 
367 
369 int get_global_wavespeeds(int dir, struct of_geom *ptrgeom, FTYPE *pr,FTYPE *output,FTYPE *outputrad,FTYPE *outputrad2)
370 {
371  struct of_state qdontuse;
372  struct of_state *qptr=&qdontuse;
373  int ignorecourant;
374 
375  // wave speed for cell centered value
376  // uses b^\mu b_\mu so need full state
377  // OPTMARK: Should avoid use of b^\mu and b_\mu in vchar and if STOREFLUXSTATE, then use that data instead of recomputing.
378  MYFUN(get_stateforglobalwavespeeds(pr, ptrgeom, &qptr),"step_ch.c:fluxcalc()", "get_state()", 0);
379  MYFUN(vchar_each(pr, qptr, dir, ptrgeom, &output[CMAX], &output[CMIN], &outputrad[CMAX], &outputrad[CMIN], &outputrad2[CMAX], &outputrad2[CMIN],&ignorecourant),"wavespeeds.c:get_global_wavespeeds()", "vchar() dir=1or2", 0);
380 
381  // uses output as temporary space since not yet needed and not used before global_vchar() below
382 
383  return(0);
384 }
385 
386 
387 
394 int global_vchar(FTYPE (*pointspeed)[NSTORE1][NSTORE2][NSTORE3][NUMCS], int dir, int is, int ie, int js, int je, int ks, int ke, int idel, int jdel, int kdel, FTYPE (*wspeed)[COMPDIM][NUMCS][NSTORE1][NSTORE2][NSTORE3])
395 {
396 
397 
398 #pragma omp parallel
399  {
400  int i,j,k;
401  int reallim;
402  int m;
403  FTYPE ftemp[NUMCS];
404  FTYPE ctop,ctoprad,ctoprad2;
405  extern int choose_limiter(int dir, int i, int j, int k, int pl);
406  int cminmax_calc_2(FTYPE *cmin,FTYPE *cmax,FTYPE *ctop);
407  OPENMP3DLOOPVARSDEFINE; OPENMP3DLOOPSETUP( is-idel, ie+idel, js-jdel, je+jdel, ks-kdel, ke+kdel ); // due to averaging of this face quantity to get centered i/j/k=0 back
408 
409 
410  // initialize ftemp if needed
411  ftemp[CMIN]=+BIG;
412  ftemp[CMAX]=-BIG;
413 
414 
415  // COMPZSLOOP( is-idel, ie+idel, js-jdel, je+jdel, ks-kdel, ke+kdel ) { // due to averaging of this face quantity to get centered i/j/k=0 back
416 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize))
418  OPENMP3DLOOPBLOCK2IJK(i,j,k);
419 
420 
421 #if(VCHARTYPE==VERYLOCALVCHAR) // then get maximum around interface
422 
423  // get minimum/maximum wspeed over this stencil (but centered on edge, not zone center)
424  MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k)=+BIG; // assume all zones are smaller than this
425  MACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k)=-BIG; // assume all zones are larger than this
426  if(EOMRADTYPE!=EOMRADNONE){
427  MACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k)=+BIG; // assume all zones are smaller than this
428  MACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k)=-BIG; // assume all zones are larger than this
429  MACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k)=+BIG; // assume all zones are smaller than this
430  MACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k)=-BIG; // assume all zones are larger than this
431  }
432  // GODMARK: 1D, could do multi-D stencil even if interpolation is 1D
433  for(m=-1;m<=0;m++){
434  MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k)=MIN(MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k),MACP1A1(pointspeed,EOMSETMHD,i+idel*m,j+jdel*m,k+kdel*m,CMIN));
435  MACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k)=MAX(MACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k),MACP1A1(pointspeed,EOMSETMHD,i+idel*m,j+jdel*m,k+kdel*m,CMAX));
436  }
437  if(EOMRADTYPE!=EOMRADNONE){
438  for(m=-1;m<=0;m++){
439  MACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k)=MIN(MACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k),MACP1A1(pointspeed,EOMSETRAD,i+idel*m,j+jdel*m,k+kdel*m,CMIN));
440  MACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k)=MAX(MACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k),MACP1A1(pointspeed,EOMSETRAD,i+idel*m,j+jdel*m,k+kdel*m,CMAX));
441  MACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k)=MIN(MACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k),MACP1A1(pointspeed,EOMSETRADFORDT,i+idel*m,j+jdel*m,k+kdel*m,CMIN));
442  MACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k)=MAX(MACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k),MACP1A1(pointspeed,EOMSETRADFORDT,i+idel*m,j+jdel*m,k+kdel*m,CMAX));
443  }
444  }
445 
446 #elif(VCHARTYPE==LOCALVCHAR)
447 
448  reallim=choose_limiter(dir,i,j,k,RHO); // base stencil size on density limiter GODMARK
449 
450  // get minimum/maximum wspeed over this stencil (but centered on edge, not zone center)
451  MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k)=+BIG; // assume all zones are smaller than this
452  MACP2A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k)=-BIG; // assume all zones are larger than this
453  // GODMARK: 1D, could do multi-D stencil even if interpolation is 1D
454  // e.g. if dir=1, then expandi=0 and so COMPFZLOOP from i=0..N inclusive. So can grab from (relative to i) -2 .. 1 inclusive for average centered on i edge
455  for(m=-reallim/2;m<=reallim/2-1;m++){
456  MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k)=MIN(MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k),MACP1A1(pointspeed,EOMSETMHD,i+idel*m,j+jdel*m,k+kdel*m,CMIN));
457  MACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k)=MAX(MACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k),MACP1A1(pointspeed,EOMSETMHD,i+idel*m,j+jdel*m,k+kdel*m,CMAX));
458  }
459  if(EOMRADTYPE!=EOMRADNONE){
460  for(m=-reallim/2;m<=reallim/2-1;m++){
461  MACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k)=MIN(MACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k),MACP1A1(pointspeed,EOMSETRAD,i+idel*m,j+jdel*m,k+kdel*m,CMIN));
462  MACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k)=MAX(MACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k),MACP1A1(pointspeed,EOMSETRAD,i+idel*m,j+jdel*m,k+kdel*m,CMAX));
463  MACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k)=MIN(MACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k),MACP1A1(pointspeed,EOMSETRADFORDT,i+idel*m,j+jdel*m,k+kdel*m,CMIN));
464  MACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k)=MAX(MACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k),MACP1A1(pointspeed,EOMSETRADFORDT,i+idel*m,j+jdel*m,k+kdel*m,CMAX));
465  }
466  }
467 
468 #elif(VCHARTYPE==GLOBALVCHAR)
469 
470  dualfprintf(fail_file,"VCHARTYPE==GLOBALVCHAR deprecated\n");
471  myexit(346983);
472 
473  // COMPZSLOOP( is-idel, ie+idel, js-jdel, je+jdel, ks-kdel, ke+kdel ) { // due to averaging of this face quantity to get centered i/j/k=0 back
474  // // get minimum/maximum wspeed over entire grid containing the fluxes
475  // ftemp[CMIN]=MIN(ftemp[CMIN],MACP1A1(pointspeed,i,j,k,CMIN));
476  // ftemp[CMAX]=MAX(ftemp[CMAX],MACP1A1(pointspeed,i,j,k,CMAX));
477  // }
478  // COMPZSLOOP( is-idel, ie+idel, js-jdel, je+jdel, ks-kdel, ke+kdel ) {
479  // MACP2A0(wspeed,dir,CMIN,i,j,k)=ftemp[CMIN];
480  // MACP2A0(wspeed,dir,CMAX,i,j,k)=ftemp[CMAX];
481  // }
482 #endif
483 
484  // go ahead and also restrict cmin and cmax
485  cminmax_calc_2(&MACP3A0(wspeed,EOMSETMHD,dir,CMIN,i,j,k),&MACP3A0(wspeed,EOMSETMHD,dir,CMAX,i,j,k),&ctop); // ctop not used
486  if(EOMRADTYPE!=EOMRADNONE){
487  cminmax_calc_2(&MACP3A0(wspeed,EOMSETRAD,dir,CMIN,i,j,k),&MACP3A0(wspeed,EOMSETRAD,dir,CMAX,i,j,k),&ctoprad); // ctoprad not used
488  cminmax_calc_2(&MACP3A0(wspeed,EOMSETRADFORDT,dir,CMIN,i,j,k),&MACP3A0(wspeed,EOMSETRADFORDT,dir,CMAX,i,j,k),&ctoprad2); // ctoprad2 not used
489  }
490 
491  }// end 3D loop
492  }// end parallel region
493 
494 
495  return(0);
496 
497 }
498 
499 
500 
501 
505 int cminmax_calc(FTYPE cmin_l,FTYPE cmin_r,FTYPE cmax_l,FTYPE cmax_r,FTYPE *cmin,FTYPE *cmax,FTYPE *ctop)
506 {
507  int cminmax_calc_1(FTYPE cmin_l,FTYPE cmin_r,FTYPE cmax_l,FTYPE cmax_r,FTYPE *cmin,FTYPE *cmax);
508  int cminmax_calc_2(FTYPE *cmin,FTYPE *cmax,FTYPE *ctop);
509 
510 
511  cminmax_calc_1(cmin_l,cmin_r,cmax_l,cmax_r,cmin,cmax);
512  cminmax_calc_2(cmin,cmax,ctop);
513 
514  return(0);
515 
516 }
517 
519 int cminmax_calc_1(FTYPE cmin_l,FTYPE cmin_r,FTYPE cmax_l,FTYPE cmax_r,FTYPE *cmin,FTYPE *cmax)
520 {
521  FTYPE lmin,lmax,ltop;
522 
523  // need to make use of ROE averages
524 
525 
526  // As per the HLLE method, one must use the wave speed at the interface. The below is arbitrarily choosing the largest of the interpolated states.
527 
528  // Apparently one should use Roe's linearisation to compare
529  // against, not the left/right interpolations. Then compare the
530  // left most going and right most going Rho linearisation
531  // eigenvalues with the left and right numerical approximations
532  // and choose the minimum and maximum values as cmin and cmax,
533  // all respectively.
534  // Then one defines the new cmin as the minumum of cmin and 0, and new cmax as maximum of cmax and 0.
535  // Thus this is slightly different and doesn't avoid negative mass/ie densities like HLLE.
536 
537 
538  // LAXF here is really the Rusanov flux. Lax-Friedrichs would say ctop->dx/dt
539 
540 
541 #if(1)
542  lmin=min(cmin_l,cmin_r);
543  lmax=max(cmax_l,cmax_r);
544 #elif(0)
545  lmin=cmin_l;
546  lmax=cmax_r;
547 #else
548  lmin=2.0*cmin_l*cmin_r/(cmin_l+cmin_r);
549  lmax=2.0*cmax_l*cmax_r/(cmax_l+cmax_r);
550 #endif
551 
552  // returns signed speed still
553  *cmin=lmin;
554  *cmax=lmax;
555 
556  return(0);
557 
558 
559 
560 }
561 
562 
563 
564 
566 int cminmax_calc_2(FTYPE *cmin,FTYPE *cmax,FTYPE *ctop)
567 {
568  FTYPE lmin=*cmin;
569  FTYPE lmax=*cmax;
570 
571 #if(HYPERHLL==0)
572  // sharp change at c=0
573  lmin = fabs(max(0., -lmin));
574  lmax = fabs(max(0., lmax));
575 #else
576 
577 #define HYPERFUN(c,x0) (0.5*( (c)+(M_SQRT2l-1.0)*sqrt(2.0*(M_SQRT2l+1.0)*(x0)*(x0)+(3.0+2.0*M_SQRT2l)*(c)*(c)) ) )
578  // GODMARK
579  // need a good way to set x0 based upon fraction of local light speed
580  // or something...
581 
582  // function is always positive for given lmin/lmax as original sign
583  lmin=HYPERFUN(-lmin,1E-4);
584  lmax=HYPERFUN(lmax,1E-4);
585 #endif
586 
587  // returns positive cmin,cmax,ctop
588  *cmin=lmin;
589  *cmax=lmax;
590  *ctop=max(lmax,lmin);
591 
592 
593  return(0);
594 
595 
596 
597 }
598