HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
interppoint.c
Go to the documentation of this file.
1 
7 #include "decs.h"
8 
9 
10 
11 
12 
15 #define DOUSEPPMCONTACTSTEEP 1 // used alone is unstable
16 #define DOUSEPARAMONOCHECK 1 // above must be used with this
17 
18 
19 #define DOUSEPARAFLAT 1 // avoids oscillations in strong shocks
20 
21 #define DOINGALLMCSTEEP (DOUSEPPMCONTACTSTEEP&&DOUSEPARAFLAT&&DOUSEPARAMONOCHECK)
22 
23 #define WHICH3POINTLIMT MC
24 
27 #define DQALLOWEXTREMUM 1 // assume USEPARAMONOCHECK enabled if using this!!! (otherwise crazy)
28 
29 
32 #define CONNECTUANDRHO (0 && (DOEVOLVERHO&&DOEVOLVEUU))
33 
37 #define CONNECTBANDRHO (0 && (DOEVOLVERHO) )
38 
39 
40 #if(DQALLOWEXTREMUM==0)
41 #define MCSTEEPMINMOD(a,b) MINMOD(a,b)
42 #else
43 #define MCSTEEPMINMOD(a,b) MINMODB(a,b)
44 #endif
45 
46 
49 //#define YREALISY (RESCALEINTERP==0 || VARTOINTERP==PRIMTOINTERP)
50 
51 
52 
53 
55 void slope_lim_pointtype(int interporflux, int realisinterp, int pl, int dir, int loc, int continuous, int idel, int jdel, int kdel, FTYPE (*primreal)[NSTORE2][NSTORE3][NPR], FTYPE (*p2interp)[NSTORE2][NSTORE3][NPR2INTERP], FTYPE (*dq)[NSTORE2][NSTORE3][NPR2INTERP], FTYPE (*pleft)[NSTORE2][NSTORE3][NPR2INTERP], FTYPE (*pright)[NSTORE2][NSTORE3][NPR2INTERP])
56 {
57  void slope_lim_point_c2e(int i, int j, int k, int loc, int realisinterp, int dir, int reallim, int pl, int startorderi, int endorderi, FTYPE *yreal, FTYPE*y, FTYPE *dq,FTYPE *left,FTYPE *right);
58  void slope_lim_point_e2c_continuous(int i, int j, int k, int loc, int realisinterp, int dir, int reallim, int pl, int startorderi, int endorderi, FTYPE *yreal, FTYPE*y, FTYPE *dq,FTYPE *left,FTYPE *right);
59  void slope_lim_point_allpl(int i, int j, int k, int loc, int realisinterp, int dir, int reallim, int startorderi, int endorderi, FTYPE **yreal, FTYPE **y, FTYPE *dq,FTYPE *left,FTYPE *right);
60  extern int choose_limiter(int dir, int i, int j, int k, int pl);
61  FTYPE interplist[MAXSPACEORDER];
62  FTYPE realinterplist[MAXSPACEORDER];
63  FTYPE interplistpl[NPR2INTERP][MAXSPACEORDER];
64  FTYPE realinterplistpl[NPR2INTERP][MAXSPACEORDER];
65  FTYPE *yin;
66  int ijkshift;
67  int startorderi,endorderi;
68  int reallim;
69  int is,ie,js,je,ks,ke,di,dj,dk;
70 
71 
72 
73 
74  // make sure dq's exist if going to use them
75  if( (DODQMEMORY==0)&&(LIMADJUST==LIMITERFIXED) ){
76  dualfprintf(fail_file,"Must have dq's when using MC or lower second order methods\n");
77  myexit(17);
78  }
79 
80  // set range of positions interpolated to
81  set_interppoint_loop_ranges(interporflux, dir, loc, continuous, &is, &ie, &js, &je, &ks, &ke, &di, &dj, &dk);
82 
83  // loc=CENT;
84  // continuous=0;
85 
86  {
87  int i,j,k;
88  // GODMARK: for now assume not doing per-point choice of limiter (note originally pl didn't actually have correct choice of limiter since pl is fake and pl set to final pl at end of loop
89  i=j=k=0;
90  reallim=choose_limiter(dir, i,j,k,pl);
91  if(continuous==0){
92  // get starting point for stencil, assumed quasi-symmetric (including even/odd size of stencil)
93  // for 2nd order: i-1, i, i+1
94  startorderi = - interporder[reallim]/2;
95  endorderi = - startorderi;
96  }
97  else{
98  // get starting and ending point for stencil centered around face
99  // for 2nd order: i-1, i, i+1, i+2
100  // NOTE: Overall loop range is more limited, so extra i+2 not an issue
101  startorderi = - interporder[reallim]/2;
102  endorderi = - startorderi + 1;
103  }
104  }
105 
106 
108  //
109  // For limiters that use specific information about the equations and need all variables, use slope_lim_point_allpl()
110  //
112  if(reallim==PARAFLAT || reallim == MCSTEEP){
113 
114 
116  //
117  // Loop over points and quantities both
118  //
120 #if( DOUSEPARAFLAT || DOUSEPPMCONTACTSTEEP)
121 #pragma omp parallel OPENMPGLOBALPRIVATEFORSTATEANDGEOMINTERP
122 #else
123  // don't need full copyin() unless pressure needs to be computed as computed if prior conditional holds
124 #pragma omp parallel
125 #endif
126  {
127  int i,j,k,l;
128  int plpl,pliter;
129  FTYPE *ypl[NPR2INTERP];
130  FTYPE *yrealpl[NPR2INTERP];
131 
132  OPENMP3DLOOPVARSDEFINE; OPENMP3DLOOPSETUP(is,ie,js,je,ks,ke);
133 
135  //
136  // pointer shift
137  //
139 
140  PINTERPLOOP(pliter,plpl){
141  // dualfprintf(fail_file,"PLOOPINTERP: plpl=%d\n",plpl);
142  ypl[plpl] = interplistpl[plpl] - startorderi;
143  }
144  PALLREALLOOP(plpl){ // need all variables for real quantity
145  // in general need space to be separate in case modify ypl's in some way during interpolation, so can't have pointer yrealpl->ypl
146  // dualfprintf(fail_file,"PALLREALLOOP: plpl=%d\n",plpl);
147  yrealpl[plpl] = realinterplistpl[plpl] - startorderi;
148  }
149 
150 
151 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize))
153  OPENMP3DLOOPBLOCK2IJK(i,j,k);
154 
155 
156  PINTERPLOOP(pliter,plpl) for(l=startorderi;l<=endorderi;l++){
157  // get interpolation points, where y[0] is point of interest for which interpolation is found.
158  ypl[plpl][l]=MACP0A1(p2interp,i + l*idel,j + l*jdel,k + l*kdel,plpl);
159  }
160 
161  if(realisinterp){
162  // need all quantities for real var
163  // PLOOPINTERP is used because PALLREALLOOP can be different (extra things at end not part of "real" set
164  PINTERPLOOP(pliter,plpl) for(l=startorderi;l<=endorderi;l++){
165  yrealpl[plpl][l]=ypl[plpl][l];// faster to copy from ypl than duplicating primreal access
166  }
167  }
168  else{
169  // need all quantities for real var
170  PALLREALLOOP(plpl) for(l=startorderi;l<=endorderi;l++){
171  yrealpl[plpl][l]=MACP0A1(primreal,i + l*idel,j + l*jdel,k + l*kdel,plpl);
172  }
173  }
174 
175  slope_lim_point_allpl(i, j, k, loc, realisinterp, dir,reallim,startorderi,endorderi,yrealpl,ypl,
176  &MACP0A1(dq,i,j,k,0),&MACP0A1(pleft,i,j,k,0),&MACP0A1(pright,i,j,k,0)
177  );
178  }// end over loop
179  }// end parallel region
180  } // end if doing all plpl at once
181  else{
182 
184  //
185  // Loop over points only
186  //
188 
189  // For limiters that are general, use slope_lim_point()
190  // get interpolation points, where y[0] is point of interest for which interpolation is found.
191 #if( DOUSEPARAFLAT || DOUSEPPMCONTACTSTEEP)
192 #pragma omp parallel OPENMPGLOBALPRIVATEFORSTATEANDGEOMINTERP
193 #else
194  // don't need full copyin() unless pressure needs to be computed as computed if prior conditional holds
195 #pragma omp parallel
196 #endif
197  {
198  int i,j,k,l;
199  FTYPE *y;
200  FTYPE *yreal;
201 
202  OPENMP3DLOOPVARSDEFINE; OPENMP3DLOOPSETUP(is,ie,js,je,ks,ke);
203 
205  //
206  // shift for easy use and clarity of loop and easy of use by slope_lim_point()
207  //
209 
210  y = interplist - startorderi;
211  yreal = realinterplist - startorderi;
212 
213 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize))
215  OPENMP3DLOOPBLOCK2IJK(i,j,k);
216 
217 
218  for(l=startorderi;l<=endorderi;l++){
219  y[l]=MACP0A1(p2interp,i + l*idel,j + l*jdel,k + l*kdel,pl);
220  }
221  if(realisinterp){
222  for(l=startorderi;l<=endorderi;l++){
223  yreal[l]=y[l];
224  }
225  }
226  else{
227  // if loc!=CENT, then because primreal always at CENT, assume use of yreal will be treated as being CENT even if inputted quantity to interpolate does not start (or even end at) CENT
228  for(l=startorderi;l<=endorderi;l++){
229  yreal[l]=MACP0A1(primreal,i + l*idel,j + l*jdel,k + l*kdel,pl);
230  }
231  }
232 
233  // dualfprintf(fail_file,"godpl=%d\n",pl);
234 
235  if(continuous==0){
236  slope_lim_point_c2e(i, j, k, loc, realisinterp, dir, reallim,pl,startorderi,endorderi,yreal,y,
237  &MACP0A1(dq,i,j,k,pl),&MACP0A1(pleft,i,j,k,pl),&MACP0A1(pright,i,j,k,pl)
238  );
239  }
240  else{
241  slope_lim_point_e2c_continuous(i, j, k, loc, realisinterp, dir, reallim,pl,startorderi,endorderi,yreal,y,
242  &MACP0A1(dq,i,j,k,pl),&MACP0A1(pleft,i,j,k,pl),&MACP0A1(pright,i,j,k,pl)
243  );
244  }
245 
246  }// end over loop
247  }// end parallel region
248  }// end if doing per pl
249 
250 
251  if(reallim==PARAFLAT){ // assumes last chosen reallim is constant // SUPERGODMARK
252  pl=NPR2INTERP; // finish the loop outside this function // SPLITNPR ok
253  if(LIMADJUST!=LIMITERFIXED){
254  dualfprintf(fail_file,"Can't use PARAFLAT with LIMADJUST!=LIMITERFIXED\n");
255  myexit(1);
256  }
257  }
258 
259 }
260 
261 
262 
263 
264 
265 
266 
267 
271 int set_interppoint_loop_ranges(int interporflux, int dir, int loc, int continuous, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk)
272 {
273 
274  if(continuous==0){
275  // if(useghostplusactive){
276  set_interppoint_loop_expanded(interporflux, dir, loc, is, ie, js, je, ks, ke, di, dj, dk);
277  // }
278  // else{
279  // set_interppoint_loop(interporflux, dir, loc, is, ie, js, je, ks, ke, di, dj, dk);
280  // }
281  }
282  else{
283  set_interppoint_loop_expanded_face2cent(interporflux, dir, loc, is, ie, js, je, ks, ke, di, dj, dk);
284  }
285 
286 
287  return(0);
288 }
289 
290 
291 
292 int set_interppoint_loop_ranges_3Dextended(int interporflux, int loc, int continuous, int *maxis, int *maxie, int *maxjs, int *maxje, int *maxks, int *maxke, int *di, int *dj, int *dk)
293 {
294  int firsttime;
295  int dimen;
296  int is,ie,js,je,ks,ke;
297 
299  //
300  // define loop range
301  // loop range should be same as where computed fluxes, or where formed primitive interpolation, as in interppoint.c:
302  // since dimension-dependent, and need CENT states in all such cells, expand loop over all dimensions
303  //
305  firsttime=1;
306  DIMENLOOP(dimen){
307 
308  if(firsttime){
309  firsttime=0;
310  // set range of positions interpolated to
311  set_interppoint_loop_ranges(interporflux, dimen, loc, continuous, maxis, maxie, maxjs, maxje, maxks, maxke, di, dj, dk);
312  }
313  else{
314  // max here means largest extent in the direction of that boundary as from interior of domain
315  set_interppoint_loop_ranges(interporflux, dimen, loc, continuous, &is, &ie, &js, &je, &ks, &ke, di, dj, dk);
316  if(is<*maxis) *maxis=is;
317  if(ie>*maxie) *maxie=ie;
318  if(js<*maxjs) *maxjs=js;
319  if(je>*maxje) *maxje=je;
320  if(ks<*maxks) *maxks=ks;
321  if(ke>*maxke) *maxke=ke;
322  }
323  }
324 
325  return(0);
326 
327 }
328 
329 
333 void set_interppoint_loop_ranges_2D_EMF_formerged(int interporflux, int corner, int odir1, int odir2, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk)
334 {
335  int *myUconsloop;
336 
337 
338  if(interporflux==ENOINTERPTYPE4EMF){
339  myUconsloop=emfUconsloop;
340  }
341  else{
342  myUconsloop=Uconsloop;
343  }
344 
345 
346  if(corner==1){
347 
348  *is=0;
349  // *ie=N1-1;
350  *ie=N1;
351 
352  *js=myUconsloop[FJS]-SHIFT2;
353  *je=myUconsloop[FJE]+SHIFT2;
354 
355  *ks=myUconsloop[FKS]-SHIFT3;
356  *ke=myUconsloop[FKE]+SHIFT3;
357 
358  *di=1;
359  *dj=1;
360  *dk=1;
361  }
362  else if(corner==2){
363 
364  *is=myUconsloop[FIS]-SHIFT1;
365  *ie=myUconsloop[FIE]+SHIFT1;
366 
367  *js=0;
368  // *je=N2-1;
369  *je=N2;
370 
371  *ks=myUconsloop[FKS]-SHIFT3;
372  *ke=myUconsloop[FKE]+SHIFT3;
373 
374  *di=1;
375  *dj=1;
376  *dk=1;
377  }
378  else if(corner==3){
379 
380  *is=myUconsloop[FIS]-SHIFT1;
381  *ie=myUconsloop[FIE]+SHIFT1;
382 
383  *js=myUconsloop[FJS]-SHIFT2;
384  *je=myUconsloop[FJE]+SHIFT2;
385 
386  *ks=0;
387  // *ke=N3-1;
388  *ke=N3;
389 
390  *di=1;
391  *dj=1;
392  *dk=1;
393 
394  }
395  else{
396  dualfprintf(fail_file,"No such dir=%d in set_interppoint_loop_ranges_2D_EMF_formerged()\n",corner);
397  myexit(9894387);
398  }
399 
400 
401 
402 }
403 
406 void set_interppoint_loop_ranges_geomcorn_formerged(int interporflux, int corner, int odir1, int odir2, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk)
407 {
408  int *myUconsloop;
409 
410 
411  if(interporflux==ENOINTERPTYPE4EMF){
412  myUconsloop=emfUconsloop;
413  }
414  else{
415  myUconsloop=Uconsloop;
416  }
417 
418 
419  if(corner==1){
420 
421  *is=0;
422  // *ie=N1-1;
423  *ie=N1;
424 
425  *js=myUconsloop[FJS]-SHIFT2;
426  *je=myUconsloop[FJE]+SHIFT2*2;
427 
428  *ks=myUconsloop[FKS]-SHIFT3;
429  *ke=myUconsloop[FKE]+SHIFT3*2;
430 
431  *di=1;
432  *dj=1;
433  *dk=1;
434  }
435  else if(corner==2){
436 
437  *is=myUconsloop[FIS]-SHIFT1;
438  *ie=myUconsloop[FIE]+SHIFT1*2;
439 
440  *js=0;
441  // *je=N2-1;
442  *je=N2;
443 
444  *ks=myUconsloop[FKS]-SHIFT3;
445  *ke=myUconsloop[FKE]+SHIFT3*2;
446 
447  *di=1;
448  *dj=1;
449  *dk=1;
450  }
451  else if(corner==3){
452 
453  *is=myUconsloop[FIS]-SHIFT1;
454  *ie=myUconsloop[FIE]+SHIFT1*2;
455 
456  *js=myUconsloop[FJS]-SHIFT2;
457  *je=myUconsloop[FJE]+SHIFT2*2;
458 
459  *ks=0;
460  // *ke=N3-1;
461  *ke=N3;
462 
463  *di=1;
464  *dj=1;
465  *dk=1;
466 
467  }
468  else{
469  dualfprintf(fail_file,"No such dir=%d in set_interppoint_loop_ranges_geomcorn_formerged()\n",corner);
470  myexit(9894387);
471  }
472 
473 
474 
475 }
476 
477 
485 void set_interppoint_loop(int interporflux, int dir, int loc, int continuous, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk)
486 {
487 
488  // interporflux never matters if ghost+active not used
489 
490  if(dir==1){
491 
492  *is=-SHIFT1;
493  *ie=N1-1+SHIFT1;
494 
495  *js=INFULL2; // 0
496  *je=OUTFULL2; // N2-1;
497 
498  *ks=INFULL3; //0;
499  *ke=OUTFULL3; // N3-1;
500 
501  *di=1;
502  *dj=1;
503  *dk=1;
504  }
505  else if(dir==2){
506  *is=INFULL1; //0;
507  *ie=OUTFULL1; //N1-1;
508 
509  *js=-SHIFT2;
510  *je=N2-1+SHIFT2;
511 
512  *ks=INFULL3; // 0;
513  *ke=OUTFULL3; // N3-1;
514 
515  *di=1;
516  *dj=1;
517  *dk=1;
518  }
519  else if(dir==3){
520  *is=INFULL1; // 0;
521  *ie=OUTFULL1; // N1-1;
522 
523  *js=INFULL2; // 0;
524  *je=OUTFULL2; // N2-1;
525 
526  *ks=-SHIFT3;
527  *ke=N3-1+SHIFT3;
528 
529  *di=1;
530  *dj=1;
531  *dk=1;
532 
533  }
534  else{
535  dualfprintf(fail_file,"No such dir=%d in set_interppoint_loop()\n",dir);
536  myexit(9894386);
537  }
538 
539 
540 }
541 
542 
543 
544 
545 
546 
547 
550 void set_interppoint_loop_expanded(int interporflux, int dir, int loc, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk)
551 {
552  int *myUconsloop;
553 
554 
555  if(interporflux==ENOINTERPTYPE4EMF){
556  myUconsloop=emfUconsloop;
557  }
558  else{
559  myUconsloop=Uconsloop;
560  }
561 
562 
563  if(dir==1){
564 
565  // -1 and +1 so can get flux at face from the obtained primitive
566  *is=myUconsloop[FIS]-SHIFT1;
567  *ie=myUconsloop[FIE]+SHIFT1;
568 
569  *js=fluxloop[dir][FJS];
570  *je=fluxloop[dir][FJE];
571 
572  *ks=fluxloop[dir][FKS];
573  *ke=fluxloop[dir][FKE];
574 
575  *di=1;
576  *dj=1;
577  *dk=1;
578  }
579  else if(dir==2){
580 
581  *is=fluxloop[dir][FIS];
582  *ie=fluxloop[dir][FIE];
583 
584  *js=myUconsloop[FJS]-SHIFT2;
585  *je=myUconsloop[FJE]+SHIFT2;
586 
587  *ks=fluxloop[dir][FKS];
588  *ke=fluxloop[dir][FKE];
589 
590  *di=1;
591  *dj=1;
592  *dk=1;
593  }
594  else if(dir==3){
595 
596  *is=fluxloop[dir][FIS];
597  *ie=fluxloop[dir][FIE];
598 
599  *js=fluxloop[dir][FJS];
600  *je=fluxloop[dir][FJE];
601 
602  *ks=myUconsloop[FKS]-SHIFT3;
603  *ke=myUconsloop[FKE]+SHIFT3;
604 
605  *di=1;
606  *dj=1;
607  *dk=1;
608 
609  }
610  else{
611  dualfprintf(fail_file,"No such dir=%d in set_interppoint_loop_expanded()\n",dir);
612  myexit(9894387);
613  }
614 
615 }
616 
617 
618 
619 
622 void set_interppoint_loop_expanded_face2cent(int interporflux, int dir, int loc, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk)
623 {
624  int *myUconsloop;
625 
626 
627  if(interporflux==ENOINTERPTYPE4EMF){
628  myUconsloop=emfUconsloop;
629  }
630  else{
631  myUconsloop=Uconsloop;
632  }
633 
634  // 0 to N-1 for actual values because others are center boundary cells
635  if(dir==1){
636  *is=myUconsloop[FIS];
637  *ie=myUconsloop[FIE];
638 
639  *js=fluxloop[dir][FJS];
640  *je=fluxloop[dir][FJE];
641 
642  *ks=fluxloop[dir][FKS];
643  *ke=fluxloop[dir][FKE];
644 
645  *di=1;
646  *dj=1;
647  *dk=1;
648  }
649  else if(dir==2){
650 
651  *is=fluxloop[dir][FIS];
652  *ie=fluxloop[dir][FIE];
653 
654  *js=myUconsloop[FJS];
655  *je=myUconsloop[FJE];
656 
657  *ks=fluxloop[dir][FKS];
658  *ke=fluxloop[dir][FKE];
659 
660  *di=1;
661  *dj=1;
662  *dk=1;
663  }
664  else if(dir==3){
665 
666  *is=fluxloop[dir][FIS];
667  *ie=fluxloop[dir][FIE];
668 
669  *js=fluxloop[dir][FJS];
670  *je=fluxloop[dir][FJE];
671 
672  *ks=myUconsloop[FKS];
673  *ke=myUconsloop[FKE];
674 
675  *di=1;
676  *dj=1;
677  *dk=1;
678 
679  }
680  else{
681  dualfprintf(fail_file,"No such dir=%d in set_interppoint_loop_expanded_face2cent()\n",dir);
682  myexit(9894387);
683  }
684 
685 }
686 
687 
688 
689 
690 
691 
692 
693 
694 
696 void slope_lim_point_c2e(int i, int j, int k, int loc, int realisinterp, int dir, int reallim, int pl, int startorderi, int endorderi, FTYPE *yreal, FTYPE*y, FTYPE *dq,FTYPE *left,FTYPE *right)
697 {
698  extern void para(FTYPE *y, FTYPE *lout, FTYPE *rout);
699  extern void para2(FTYPE *y, FTYPE *lout, FTYPE *rout);
700  extern void para3(FTYPE *y, FTYPE *lout, FTYPE *rout);
701  extern void para4(int realisinterp, int pl, FTYPE *y, FTYPE *lout, FTYPE *rout);
702  extern void parajon(int i, int j, int k, int loc, int realisinterp, int dir, int pl, FTYPE *y, FTYPE *lout, FTYPE *rout);
703  void slope_lim_3points(int reallim, FTYPE yl, FTYPE yc, FTYPE yr,FTYPE *dq);
704  void csslope(int pl, FTYPE *y, FTYPE *dq);
705  void mp5(FTYPE *y, FTYPE *lout, FTYPE *rout);
706  void eppm(FTYPE *y, FTYPE *lout, FTYPE *rout);
707  FTYPE mydq = 0.0; //to avoid copying of nan's
708 
709 
710  // parabolic reconstruction
711  switch(reallim){
712 
713  case PARA:
714  // para
715 #if(WHICHPARA==PARA1)
716  para(y,left,right);
717 #elif(WHICHPARA==PARA2)
718  para2(y,left,right);
719 #elif(WHICHPARA==PARA3)
720  para3(y,left,right);
721 #elif(WHICHPARA==PARA4)
722  para4(realisinterp, pl,y,left,right);
723 #elif(WHICHPARA==PARAJON)
724  parajon(i,j,k,loc,realisinterp, dir, pl,y,left,right);
725 #endif
726  break;
727 
728  case CSSLOPE:
729  csslope(pl, y, &mydq);
730  *left =y[0] - 0.5* mydq;
731  *right=y[0] + 0.5* mydq;
732 #if(DODQMEMORY)
733  // for now force both ways always so have information
734  *dq=mydq; // only set to dq if necessary since DODQMEMORY may be 0
735 #endif
736  break;
737 
738  case MP5:
739  mp5(y,left,right);
740  break;
741 
742  case EPPM:
743  eppm(y,left,right);
744  break;
745 
746  default:
747 
748  // if(pl==RHO || pl==U1+dir-1 || pl==UU) slope_lim_3points(MINM, y[-1], y[0], y[1], &mydq);
749  // else slope_lim_3points(reallim, y[-1], y[0], y[1], &mydq);
750  slope_lim_3points(reallim, y[-1], y[0], y[1], &mydq);
751 
752  *left =y[0] - 0.5* mydq;
753  *right=y[0] + 0.5* mydq;
754 #if(DODQMEMORY)
755  // for now force both ways always so have information
756  *dq=mydq; // only set to dq if necessary since DODQMEMORY may be 0
757 #endif
758  break;
759  }
760 
761 
762 }
763 
766 void slope_lim_point_e2c_continuous(int i, int j, int k, int loc, int realisinterp, int dir, int reallim, int pl, int startorderi, int endorderi, FTYPE *yreal, FTYPE*y, FTYPE *dq,FTYPE *left,FTYPE *right)
767 {
768  void slope_lim_4points_e2c_continuous(int reallim, FTYPE yl, FTYPE yc, FTYPE yr, FTYPE yrr, FTYPE *dq);
769  FTYPE ddq = 0.0; //to avoid copying of nan's
770  FTYPE mydq = 0.0; //to avoid copying of nan's
771 
772  FTYPE yl,yc,yr,yrr;
773  yl=y[-1];
774  yc=y[0];
775  yr=y[1];
776  yrr=y[2];
777  if(reallim>MC) reallim=MC; // SUPERGODMARK TODOMARK (just changes local value)
778  slope_lim_4points_e2c_continuous(reallim, yl, yc, yr, yrr, &ddq);
779 
780  if(reallim<=MC || 1){ // || 1 for now SUPERGODMARK
781 
782  // Obtain lower mydq by just setting true Bcenter(x=1/2)=left or =right immediately below and solving for mydq. So fake slope just to get the final value correct for *right
783  // *left can be set, but not actual left value at next cell center. So really only should use *right
784  mydq=2.*(0.25*ddq - 1.*yc + 1.*yl - 0.5*(-1.*yc + yr)); // only for fake left that will just return same Bcenter(x=1/2) as *right
785  *left =yc - 0.5* mydq; // fake, just gives back B(x=1/2) as well
786 
787  // now overwrite mydq with correct value assuming will only use *right as result for centered final value
788  mydq=-2.*(0.25*ddq - 0.5*(-1.*yc + yr));// only for right
789  *right=yc + 0.5* mydq; // B(x=1/2)
790 
791  // dualfprintf(fail_file,"POINT4: ijk=%d %d %d : %g %g %g %g : %g %g\n",i,j,k,yl,yc,yr,yrr,mydq,*right);
792  }
793  else{
794  dualfprintf(fail_file,"NOT SETUP YET FOR slope_lim_point_e2c_continuous\n");
795  myexit(972372252);
796  }
797 
798 #if(DODQMEMORY)
799  // for now force both ways always so have information
800  *dq=mydq; // only set to dq if necessary since DODQMEMORY may be 0
801 #endif
802 
803 
804 }
805 
807 void slope_lim_point_allpl(int i, int j, int k, int loc, int realisinterp, int dir,int reallim, int startorderi, int endorderi, FTYPE **yreal, FTYPE **y, FTYPE *dq,FTYPE *left,FTYPE *right)
808 {
809  extern void parapl(int i, int j, int k, int loc, int realisinterp, int dir, FTYPE **yreal, FTYPE **y, FTYPE *lout, FTYPE *rout);
810  void mcsteeppl(int i, int j, int k, int loc, int realisinterp, int dir, FTYPE **yreal, FTYPE **y, FTYPE *lout, FTYPE *rout);
811 
812  switch(reallim){
813  case PARAFLAT:
814  parapl(i, j, k, loc, realisinterp, dir,yreal,y,left,right);
815  break;
816  case MCSTEEP:
817  mcsteeppl(i, j, k, loc, realisinterp, dir,yreal,y,left,right);
818  break;
819  default:
820  dualfprintf(fail_file,"No such allpl reallim=%d\n",reallim);
821  myexit(189676);
822  break;
823  }
824 
825 
826 
827 }
828 
829 
830 
833 void slope_lim_3points(int reallim, FTYPE yl, FTYPE yc, FTYPE yr,FTYPE *dq)
834 {
835  FTYPE dq1l,dq1r,dq2;
836  extern void get_limit_slopes(int reallim, int extremum, FTYPE *dq1l, FTYPE *dq1r, FTYPE *dq2, FTYPE *dqout);
837 
838 
839  dq1l = 1.0*(yc - yl);
840  dq1r = 1.0*(yr - yc);
841  dq2 = 0.5*(yr - yl);
842 
843  get_limit_slopes(reallim, 0, &dq1l, &dq1r, &dq2, dq);
844 
845 }
846 
847 
850 void slope_lim_4points_e2c_continuous(int reallim, FTYPE yl, FTYPE yc, FTYPE yr, FTYPE yrr, FTYPE *ddq)
851 {
852  FTYPE ddq1l,ddq1r,ddq2;
853  extern void get_limit_slopes(int reallim, int extremum, FTYPE *dq1l, FTYPE *dq1r, FTYPE *dq2, FTYPE *dqout);
854 
855 
856  ddq1l=0.5*(-2.0*yc+yl+yr);
857  ddq1r=0.5*(yc-2.0*yr+yrr);
858  ddq2=SIXTH*(-3.*yc + yl + 3.*yr - 1.*yrr) +
859  SIXTH*(3.*yc - 1.*yl - 3.*yr + yrr) +
860  0.5*(-1.*yc + yl - 1.*yr + yrr);
861 
862 
863  // use same procedure as slope limiter
864  get_limit_slopes(reallim, 0, &ddq1l, &ddq1r, &ddq2, ddq);
865 
866 }
867 
868 
870 void get_limit_slopes(int reallim, int extremum, FTYPE *dq1l, FTYPE *dq1r, FTYPE *dq2, FTYPE *dq)
871 {
872  FTYPE Dqc,Dqp,Dqm,s,theta;
873 
874 
875  switch(reallim){
876 
877  case MC:
878  // monotonized central (Woodward) (Barth-Jespersen)
879  Dqm = 2.0 * dq1l[0];
880  Dqp = 2.0 * dq1r[0];
881  Dqc = dq2[0];
882  *dq=MINMODGEN(extremum,Dqc,MINMODGEN(extremum,Dqm,Dqp));
883  break;
884 
885  case VANL:
886  /* van leer slope limiter */
887  Dqm = dq1l[0];
888  Dqp = dq1r[0];
889  s = Dqm * Dqp;
890  if (s <= 0.) *dq= 0.;
891  else *dq= (2.0 * s / (Dqm + Dqp));
892  break;
893 
894  case MINM:
895  /* minmod slope limiter (crude but robust) */
896  theta = 1.0;
897  Dqm = theta * dq1l[0];
898  Dqp = theta * dq1r[0];
899  Dqc = dq2[0];
900  *dq = MINMODGEN(extremum,MINMODGEN(extremum,Dqm,Dqc),Dqp);
901  break;
902 
903  case NLIMCENT:
904  // Centered slope (Fromm)
905  *dq = dq2[0];
906  break;
907 
908  case NLIMUP:
909  // Upwind slope (Beam-Warming)
910  *dq = dq1l[0];
911  break;
912 
913  case NLIMDOWN:
914  // Downwind slope (Lax-Wendroff)
915  *dq = dq1r[0];
916  break;
917 
918  case DONOR:
919  // no slope
920  *dq=(0.0);
921  break;
922 
923  default:
924  dualfprintf(fail_file, "unknown slope limiter: %d\n",reallim);
925  myexit(10);
926  break;
927  }
928 
929 }
930 
931 
932 void slope_lim_3points_old(int reallim, FTYPE yl, FTYPE yc, FTYPE yr,FTYPE *dq)
933 {
934  FTYPE Dqm, Dqp, Dqc, s;
935 
936  if (reallim == MC) {
937  Dqm = 2.0 * (yc - yl);
938  Dqp = 2.0 * (yr - yc);
939  Dqc = 0.5 * (yr - yl);
940  s = Dqm * Dqp;
941  if (s <= 0.) *dq= 0.;
942  else{
943  if (fabs(Dqm) < fabs(Dqp) && fabs(Dqm) < fabs(Dqc))
944  *dq= (Dqm);
945  else if (fabs(Dqp) < fabs(Dqc))
946  *dq= (Dqp);
947  else
948  *dq= (Dqc);
949  }
950  }
951  /* van leer slope limiter */
952  else if (reallim == VANL) {
953  Dqm = (yc - yl);
954  Dqp = (yr - yc);
955  s = Dqm * Dqp;
956  if (s <= 0.)
957  *dq= 0.;
958  else
959  *dq= (2.0 * s / (Dqm + Dqp));
960  }
961  /* minmod slope limiter (crude but robust) */
962  else if (reallim == MINM) {
963  Dqm = (yc - yl);
964  Dqp = (yr - yc);
965  s = Dqm * Dqp;
966  if (s <= 0.) *dq= 0.;
967  else{
968  if (fabs(Dqm) < fabs(Dqp)) *dq= Dqm;
969  else *dq= Dqp;
970  }
971  }
972  else if (reallim == NLIM) {
973  Dqc = 0.5 * (yr - yl);
974  *dq= (Dqc);
975  }
976  else if (reallim == DONOR) {
977  *dq=(0.0);
978  }
979  else {
980  dualfprintf(fail_file, "unknown slope limiter: %d\n",reallim);
981  myexit(10);
982  }
983 
984 
985 
986 }
987 
988 
989 
993 void csslope(int pl, FTYPE *y, FTYPE *dq)
994 {
995  FTYPE s, sm, sp;
996  FTYPE Dql, Dqlm, Dqlp;
997  FTYPE Dqp, Dqpp;
998  FTYPE Dqm, Dqmm;
999  FTYPE Dqc, Dqcm, Dqcp;
1000  FTYPE Dqbp,Dqbm;
1001  FTYPE alpha;
1002 
1003 
1004  Dqp=(y[1]-y[0]);
1005  Dqpp=(y[2]-y[1]);
1006 
1007  Dqm=(y[0]-y[-1]);
1008  Dqmm=(y[-1]-y[-2]);
1009 
1010  Dqc=0.5*(y[1]-y[-1]);
1011  Dqcm=0.5*(y[0]-y[-2]);
1012  Dqcp=0.5*(y[2]-y[0]);
1013 
1014  // Dqmm Dqm Dqp Dqpp
1015  // Dqcm Dqc Dqcp
1016  // sm q sp
1017  // Dqlm Dql Dqlp
1018  // Dqbm Dqbp
1019 
1020  s=0.5*(sign(Dqp)+sign(Dqm));
1021  sp=0.5*(sign(Dqpp)+sign(Dqp));
1022  sm=0.5*(sign(Dqm)+sign(Dqmm));
1023 
1024  // MB05 use alpha=2 for 1-D and alpha=2,1.25,1 for rho,v,p (respectively) for 2D.
1025  // alpha=[1-2]. alpha=2 more compressive, alpha=1 less compressive.
1026  if(pl==RHO) alpha=2.0;
1027  else if((pl>=U1)&&(pl<=U3)) alpha=1.25;
1028  else if(pl==UU) alpha=1.0;
1029  else if((pl>=B1)&&(pl<=B3)) alpha=1.25;
1030  else alpha=2.0;
1031 
1032  Dql=alpha*min(fabs(Dqp),fabs(Dqm));
1033  Dqlp=alpha*min(fabs(Dqpp),fabs(Dqp));
1034  Dqlm=alpha*min(fabs(Dqm),fabs(Dqmm));
1035 
1036  Dqbp=sp*min(Dqlp,fabs(Dqcp));
1037  Dqbm=sm*min(Dqlm,fabs(Dqcm));
1038 
1039  *dq=s*min(fabs(FOURTHIRD*Dqc-SIXTH*(Dqbp+Dqbm)),Dql);
1040 
1041 
1042 }
1043 
1044 
1045 
1046 
1049 void mcsteeppl(int i, int j, int k, int loc, int realisinterp, int dir, FTYPE **yrealpl, FTYPE **ypl, FTYPE *loutpl, FTYPE *routpl)
1050 {
1051  FTYPE dqpl0[NPR2INTERP][8];
1052  FTYPE *dqpl[NPR2INTERP];
1053  FTYPE *y;
1054  //,*yreal;
1055  FTYPE *dq;
1056  FTYPE a_P[10];
1057  FTYPE *V,*P;
1058  void slope_lim_3points(int reallim, FTYPE yl, FTYPE yc, FTYPE yr,FTYPE *dq);
1059  extern void getPressure(int whicheom, int i, int j, int k, int loc, FTYPE **yrealpl, FTYPE *P);
1060  extern void parasteep(int dir, int pl, FTYPE *V, FTYPE *P, FTYPE *y, FTYPE *dq, FTYPE *l, FTYPE *r);
1061  extern void paraflatten(int dir, int pl, FTYPE *y, FTYPE Fi, FTYPE *l, FTYPE *r);
1062  extern FTYPE Ficalc(int dir, FTYPE *V, FTYPE *P);
1063  extern void checkparamonotonicity(int smooth, int dqrange, int pl, FTYPE *y, FTYPE *ddq, FTYPE *dq, FTYPE *lin, FTYPE *rin, FTYPE *lout, FTYPE *rout);
1064  int pl,pliter;
1065  int dqrange;
1066  FTYPE Fi;
1067  void get_mcsteep_dqs(int dqrange, FTYPE *y, FTYPE *dq);
1068  int mm;
1069  int odir1,odir2;
1070  FTYPE a_ddq[7];
1071  FTYPE *ddq;
1072 
1073  if(EOMRADTYPE!=EOMRADNONE){
1074  dualfprintf(fail_file,"mcsteppl not setup for koral\n");
1075  myexit(3752352523);
1076  }
1077 
1078  // orthogonal to "dir" direction
1079  odir1=dir%3+1;
1080  odir2=(dir+1)%3+1;
1081 
1082 
1083  ddq=a_ddq+3; // shifted sufficiently
1084 
1085 
1086  // consistent with MCSTEEP using 7 points
1087  dqrange = 5; // dq's will exist from -2,-1,0,1,2 @ CENT and ddq computed from -1,0,1,2 @ FACE
1088 
1089  // shift P
1090  P=a_P + 4; // P accessed from -3..3 ( shifted sufficiently)
1091 
1092 
1093  // assume velocity is istelf
1094  V = yrealpl[U1+dir-1];
1095 
1096  // shift dq
1097  PINTERPLOOP(pliter,pl){
1098  dqpl[pl]=dqpl0[pl]+4; // shifted sufficiently
1099  }
1100 
1101 
1102 
1103 
1104 
1105 #if(1 && (CONNECTUANDRHO||CONNECTBANDRHO) )
1106  if(realisinterp){
1107  // convert u to (u/rho)
1108  // When steepening density, if small internal energy, then internal energy will leak out and lead to large u/rho
1109  // so generically interpolate u/rho if steepening to avoid this
1110  // if YREALISY==0 or 1, then assume user knows what they are doing in general since YREALISY is not actually generally correct
1111  // Note that this doesn't change yrealpl since that is stored in separate memory space
1112 
1113  // Problem with this steepening of U is that it can build up a shock and strong dissipation can spontaneously occur in energy equation
1114 
1115  for(mm=-interporder[MCSTEEP]/2;mm<=interporder[MCSTEEP]/2;mm++){
1116 #if(CONNECTUANDRHO)
1117  ypl[UU][mm] /= (fabs(ypl[RHO][mm])+SMALL);
1118 #endif
1119 #if(CONNECTBANDRHO)
1120  ypl[B1+odir1-1][mm] /= (fabs(ypl[RHO][mm])+SMALL);
1121  ypl[B1+odir2-1][mm] /= (fabs(ypl[RHO][mm])+SMALL);
1122 #endif
1123  }
1124  // convert input l,r values
1125 #if(CONNECTUANDRHO)
1126  routpl[UU] /= (fabs(routpl[RHO])+SMALL);
1127  loutpl[UU] /= (fabs(loutpl[RHO])+SMALL);
1128 #endif
1129 #if(CONNECTBANDRHO)
1130  routpl[B1+odir1-1] /= (fabs(routpl[RHO])+SMALL);
1131  loutpl[B1+odir1-1] /= (fabs(loutpl[RHO])+SMALL);
1132  routpl[B1+odir2-1] /= (fabs(routpl[RHO])+SMALL);
1133  loutpl[B1+odir2-1] /= (fabs(loutpl[RHO])+SMALL);
1134 #endif
1135 
1136  // GODMARK: Seems like also want to do this for the perpendicular field components since B/rho is advected
1137  // i.e. Induction equation can be written as:
1138  // D/Dt(B^j/\rho_0) = (B^i/\rho_0 \nabla_i)v^j
1139  // Mass must move with orthogonal field, so need to steepen these consistently
1140  // However, if B^2>>\rho_0, then noise may exist in \rho_0 while want evolution of B^i to be still accurate
1141 
1142  }
1143 #endif
1144 
1146  //
1147  // Loop over variables and get interpolated left/right values within cell
1148  //
1150 
1151 
1152 
1153 
1154  // get pressures for all points since needed for reduction or steepening
1155 #if( DOUSEPARAFLAT || DOUSEPPMCONTACTSTEEP)
1156  getPressure(EOMSETMHD,i,j,k,loc,yrealpl, P);
1157 #endif
1158 
1159  // KORALTODO: Not using EOMSETRAD yet.
1160 
1161 
1162 
1163  // computed only once for all variables
1164 #if( DOUSEPARAFLAT )
1165  Fi = Ficalc(dir,V,P);
1166 #else
1167  Fi = 0.0;
1168 #endif
1169 
1170 
1171  PINTERPLOOP(pliter,pl){
1172 
1173  y=ypl[pl];
1174  // yreal=yrealpl[pl];
1175  dq=dqpl[pl];
1176 
1177 
1179  //
1180  // Get needed slopes
1181  //
1183 
1184 #if(DOINGALLMCSTEEP)
1185  get_mcsteep_dqs(dqrange, y, dq);
1186 #else
1187 
1188  slope_lim_3points(WHICH3POINTLIMT, y[-1], y[0], y[1],&dq[0]);
1189 
1190 #if(DOUSEPPMCONTACTSTEEP)
1191  slope_lim_3points(WHICH3POINTLIMT, y[-2], y[-1], y[0],&dq[-1]);
1192  slope_lim_3points(WHICH3POINTLIMT, y[0], y[1], y[2],&dq[1]);
1193 #endif
1194 
1195 #if(DOUSEPARAMONOCHECK)
1196  slope_lim_3points(WHICH3POINTLIMT, y[-3], y[-2], y[-1],&dq[-2]);
1197  slope_lim_3points(WHICH3POINTLIMT, y[1], y[2], y[3],&dq[2]);
1198 #endif
1199 
1200 #endif
1201 
1202 
1203 
1205  //
1206  // get 3-point solution (only need dq[-1,0,1] for parasteep, but need more for paramonocheck with Duez allowance of non-monotonicity
1207  // get normal centered 3-point result:
1208  //
1210 
1211  loutpl[pl] = y[0] - 0.5* dq[0];
1212  routpl[pl] = y[0] + 0.5* dq[0];
1213 
1214 
1216  //
1217  // Steepen
1218  //
1220 
1221 
1222 #if(DOUSEPPMCONTACTSTEEP)
1223  parasteep(dir,pl,V,P,ypl[pl],dqpl[pl],&loutpl[pl],&routpl[pl]);
1224 #endif
1225 
1227  //
1228  // Flatten
1229  //
1231 
1232 
1233 #if(DOUSEPARAFLAT)
1234  paraflatten(dir,pl,ypl[pl],Fi,&loutpl[pl],&routpl[pl]);
1235 #endif
1236 
1237 
1239  //
1240  // Monotonicity check
1241  //
1243 
1244 #if(DOUSEPARAMONOCHECK)
1245  for(mm=-dqrange/2+1;mm<=dqrange/2;mm++){
1246  ddq[mm] = dq[mm] - dq[mm-1];
1247  }
1248  int smooth=0;
1249  checkparamonotonicity(smooth, dqrange, pl, ypl[pl], ddq, dqpl[pl], &loutpl[pl], &routpl[pl], &loutpl[pl], &routpl[pl]);
1250 #endif
1251 
1252 
1253  }
1254 
1255 
1256 
1257 #if(1 && (CONNECTUANDRHO||CONNECTBANDRHO) )
1258  if(realisinterp){
1259  // convert (u/rho) back to u
1260  for(mm=-interporder[MCSTEEP]/2;mm<=interporder[MCSTEEP]/2;mm++){
1261  // convert back ypl in case use it later for something
1262 #if(CONNECTUANDRHO)
1263  ypl[UU][mm] *= fabs(ypl[RHO][mm]);
1264 #endif
1265 #if(CONNECTBANDRHO)
1266  ypl[B1+odir1-1][mm] *= fabs(ypl[RHO][mm]);
1267  ypl[B1+odir2-1][mm] *= fabs(ypl[RHO][mm]);
1268 #endif
1269  }
1270 #if(CONNECTUANDRHO)
1271  // convert back l,r values
1272  routpl[UU] *= fabs(routpl[RHO]);
1273  loutpl[UU] *= fabs(loutpl[RHO]);
1274 #endif
1275 #if(CONNECTBANDRHO)
1276  routpl[B1+odir1-1] *= fabs(routpl[RHO]);
1277  loutpl[B1+odir1-1] *= fabs(loutpl[RHO]);
1278  routpl[B1+odir2-1] *= fabs(routpl[RHO]);
1279  loutpl[B1+odir2-1] *= fabs(loutpl[RHO]);
1280 #endif
1281 
1282  }
1283 #endif
1284 
1285 
1286 
1287 
1288 
1289 }
1290 
1291 
1292 
1294 void get_mcsteep_dqs(int dqrange, FTYPE *y, FTYPE *dq)
1295 {
1296  int mm;
1297  FTYPE a_dq1[10],a_dq2[10];
1298  FTYPE *dq1,*dq2;
1299  FTYPE Dqp,Dqm,Dqc;
1300  FTYPE Dqvanl;
1301 
1302 
1303  // shifted dq (sufficiently shifted)
1304  dq1=a_dq1+dqrange;
1305  dq2=a_dq2+dqrange;
1306 
1307 
1308  // get slopes
1309  for(mm=-dqrange/2 ; mm<=dqrange/2 ; mm++) {
1310  dq1[mm] = (y[mm]-y[mm-1]); // slope centered at cell face
1311  dq2[mm] = 0.5 *(y[mm+1]-y[mm-1]); // slope centered at cell center
1312  }
1313  mm=dqrange/2+1; // get last dq1 (can't do in loop above since +1 would mean dq2 beyond data range
1314  dq1[mm] = (y[mm]-y[mm-1]); // slope centered at cell face
1315 
1316  // Dqm(0) = 2.0*(dq1[0])
1317  // Dqp(0) = 2.0*(dq1[1]) // so need to go 1 farther to get all needed Dqp's
1318 
1319  for(mm=-dqrange/2 ; mm<=dqrange/2 ; mm++) {
1320  Dqc = dq2[mm]; // normal
1321 
1322  // MC:
1323 #if(WHICH3POINTLIMT==MC)
1324 
1325  Dqm = 2.0 * dq1[mm]; // steepened
1326  Dqp = 2.0 * dq1[mm+1]; // steepened
1327  dq[mm]=MCSTEEPMINMOD(Dqc,MCSTEEPMINMOD(Dqm,Dqp));
1328 
1329 #elif(WHICH3POINTLIMT==MINM)
1330 
1331  Dqm = dq1[mm];
1332  Dqp = dq1[mm+1];
1333  dq[mm] = MCSTEEPMINMOD(Dqm,Dqp);
1334 
1335 #elif(WHICH3POINTLIMT==VANL)
1336 
1337  Dqm = dq1[mm];
1338  Dqp = dq1[mm+1];
1339 
1340  s = Dqm * Dqp;
1341  if (s <= 0.) dq[mm] = 0.;
1342  else dq[mm] = (2.0 * s / (Dqm + Dqp));
1343 
1344 #endif
1345  }
1346 
1347 
1348 }
1349 
1350 
1351 #define MIN3(x,y,z) (min(min(x,y),z))
1352 #define MAX3(x,y,z) (max(max(x,y),z))
1353 
1354 #define MIN4(w,x,y,z) (min(w,MIN3(x,y,z)))
1355 #define MAX4(w,x,y,z) (max(w,MAX3(x,y,z)))
1356 
1357 #define MINMODMP5(x,y) (0.5*(sign(x)+sign(y))*min(fabs(x),fabs(y)))
1358 
1359 #define MINMOD4(w,x,y,z) (0.125*(sign(w)+sign(x))*fabs( (sign(w)+sign(y))*(sign(w)+sign(z)) ) * MIN4(fabs(w),fabs(x),fabs(y),fabs(z)) )
1360 
1361 #define MEDIAN(x,y,z) ((x) + MINMODMP5((y)-(x),(z)-(x)));
1362 
1363 
1369 void mp5(FTYPE *y, FTYPE *lout, FTYPE *rout)
1370 {
1371  void mp5face(FTYPE yll, FTYPE yl, FTYPE yc, FTYPE yr, FTYPE yrr, FTYPE *out);
1372 
1373  FTYPE yll=y[-2];
1374  FTYPE yl=y[-1];
1375  FTYPE yc=y[0];
1376  FTYPE yr=y[1];
1377  FTYPE yrr=y[2];
1378 
1379  mp5face(yll,yl,yc,yr,yrr,rout); // right face relative to center (U^L_{i+1/2})
1380  mp5face(yrr,yr,yc,yl,yll,lout); // left face relative to center (U^R_{i-1/2})
1381 
1382 }
1383 
1387 void mp5face(FTYPE yll, FTYPE yl, FTYPE yc, FTYPE yr, FTYPE yrr, FTYPE *out)
1388 {
1389 
1390  // dualfprintf(fail_file,"yll=%g yl=%g yc=%g yr=%g yrr=%g\n",yll,yl,yc,yr,yrr);
1391 
1392  // original UL eq2.1
1393  FTYPE UL = 0.0078125*(90.*yc - 20.*yl + 3.*yll + 60.*yr - 5.*yrr); // see poly.nb fpr
1394  // FTYPE UL = (1.0/60.0)*(2.0*yll-13.0*yl+47.0*yc+27.0*yr-3.0*yrr);
1395 
1396  // Mosta et al. (2014) uses alpha and \tilde{alpha} for same thing and doesn't define \alpha.
1397  FTYPE alpha=4.0; // see entire paper.
1398  FTYPE UMP = yc + MINMODMP5(yr-yc,alpha*(yc-yl)); // eq 2.12
1399 
1400  FTYPE epsilonmp5=1E-10; // used by Mosta et al. (2014)
1401  FTYPE fabsU=(1.0/5.0)*sqrt(yll*yll + yl*yl + yc*yc + yr*yr + yrr*yrr); // L2 norm
1402  int nolimit=(UL-yc)*(UL-UMP)<=epsilonmp5*fabsU; // eq 2.30
1403 
1404 
1405  // unlimited
1406  *out = UL;
1407 
1408  if(nolimit==0){ // then get limited contribution
1409  // 2nd derivatives based on points or averages gives same 2nd derivative for point or average reconstruction
1410  FTYPE Dm = yll - 2.0*yl + yc; // eq 2.19
1411  FTYPE D0 = yl - 2.0*yc + yr; // eq 2.19
1412  FTYPE Dp = yc - 2.0*yr + yrr; // eq 2.19
1413 
1414  FTYPE DM4p=MINMOD4(4.0*D0-Dp,4.0*Dp-D0,D0,Dp); // eq 2.27
1415  FTYPE DM4m=MINMOD4(4.0*D0-Dm,4.0*Dm-D0,D0,Dm); // eq 2.27 also
1416 
1417  FTYPE UUL = yc + alpha*(yc-yr); // eq 2.8
1418  FTYPE UAV = 0.5*(yc+yr); // eq 2.16
1419  // FTYPE UFL = yc + 0.5*(yc-yl);
1420  // FTYPE UFR = yr + 0.5*(yr-yrr);
1421  //FTYPE UMD = median(UAV,UFL,UFR); // replaced by Eq2.27's DM4
1422  FTYPE UMD = UAV - 0.5*DM4p; // eq 2.28 (correct for points or averages)
1423  FTYPE dd = 4.0*DM4m;
1424  FTYPE ULC = 0.75*yc + 0.375*(dd + 2.*yc - 1.*yl) - 0.125*yl; // see poly3-2.nb fnewright (original eq2.29 for averages->points)
1425  //FTYPE ULC = yc + 0.5*(yc-yl) + (4.0/3.0)*DM4m;
1426 
1427  FTYPE UMIN = max(MIN3(yc,yr,UMD),MIN3(yc,UUL,ULC)); // eq 2.24a
1428  FTYPE UMAX = min(MAX3(yc,yr,UMD),MAX3(yc,UUL,ULC)); // eq 2.24b
1429 
1430  // new limited value
1431  *out += MINMOD(UMIN-UL,UMAX-UL); // eq 2.26 using eq 2.5
1432 
1433  // dualfprintf(fail_file,"UL=%g UMP=%g fabsU=%g nolimit=%d UUL=%g UAV=%g UMD=%g ULC=%g UMIN=%g UMAX=%g\n",UL,UMP,fabsU,nolimit,UUL,UAV,UMD,ULC,UMIN,UMAX);
1434  }
1435  else{
1436  // dualfprintf(fail_file,"UL=%g UMP=%g fabsU=%g nolimit=%d\n",UL,UMP,fabsU,nolimit);
1437  }
1438 
1439 
1440 }
1441 
1442 
1447 void eppm(FTYPE *y, FTYPE *lout, FTYPE *rout)
1448 {
1449 
1450 }