13 #define BOUNDARYSMOOTHER 0
16 #define SMOOTHFACTOR 2.0
18 #define IGNORECOURANT 0
36 FTYPE vgmax,vgmin,ctsq;
37 FTYPE bsq, WW, EF, va2, cs2, cms2, rho, u, P;
39 int realfast(
int dir,
struct of_geom *geom,
struct of_state *q,
FTYPE EF,
FTYPE cs2,
FTYPE cms2,
FTYPE va2,
FTYPE *
ucon,
FTYPE *
bcon,
FTYPE *
gcon,
FTYPE *vmin,
FTYPE *vmax);
40 int boundary_smoother(
struct of_geom *ptrgeom,
FTYPE *vmax,
FTYPE *vmin,
int *ignorecourant);
82 cs2 = cs2_compute_simple(i,j,k,loc,rho,u);
89 else if(cs2<=0.0) cs2=
SMALL;
95 EF =
SMALL + fabs(bsq + WW);
102 cms2 = cs2 + va2 - cs2 * va2;
116 PLOOP(pliter,pl) dualfprintf(
fail_file,
"pr[%d]=%21.15g\n", pl, pr[pl] );
118 dualfprintf(
fail_file,
"cms2=NaN: dir=%d :\n bsq=%21.15g\n rho=%21.15g\n u=%21.15g\n WW=%21.15g\n EF=%21.15g\n va2=%21.15g\n cs2=%21.15g\n cms2=%21.15g\n",dir,bsq,rho,u,WW,EF,va2,cs2,cms2);
124 if (cms2/(cs2+va2) > -
NUMEPSILON*100.0) cms2=0.0;
127 dualfprintf(
fail_file,
"cms2<0.0 : dir=%d :\n bsq=%21.15g\n rho=%21.15g\n u=%21.15g\n WW=%21.15g\n EF=%21.15g\n va2=%21.15g\n cs2=%21.15g\n cms2=%21.15g\n",dir,bsq,rho,u,WW,EF,va2,cs2,cms2);
135 else if (rho<0.0) cms2=1.0;
137 dualfprintf(
fail_file,
"cms2>1.0 : dir=%d :\n bsq=%21.15g\n rho=%21.15g\n u=%21.15g\n WW=%21.15g\n EF=%21.15g\n va2=%21.15g\n cs2=%21.15g\n cms2=%21.15g\n",dir,bsq,rho,u,WW,EF,va2,cs2,cms2);
147 if((ilocal==32)&&(jlocal==40)&&(klocal==32)){
148 stderrfprintf(
"%d %21.15g %21.15g %21.15g %21.15g\n",dir,EF,cs2,cms2,va2);
149 for(i=0;i<
NDIM;i++) stderrfprintf(
"%21.15g ",ucon[i]); stderrfprintf(
"\n");
150 for(i=0;i<
NDIM;i++) stderrfprintf(
"%21.15g ",bcon[i]); stderrfprintf(
"\n");
151 for(i=0;i<
NDIM;i++){
for(j=0;j<
NDIM;j++) stderrfprintf(
"%21.15g ",gcon[
GIND(i,j)]); stderrfprintf(
"\n");}
155 if(realfast(dir,geom,q,EF,cs2,cms2,va2,q->
ucon,q->
bcon,geom->gcon,vmin,vmax)>=1){
156 dualfprintf(
fail_file,
"vchar.c: truefast() failed\n");
157 dualfprintf(
fail_file,
"truefast() failed : dir=%d :\n bsq=%21.15g\n rho=%21.15g\n u=%21.15g\n WW=%21.15g\n EF=%21.15g\n va2=%21.15g\n cs2=%21.15g\n cms2=%21.15g\n",dir,bsq,rho,u,WW,EF,va2,cs2,cms2);
162 if(
simplefast(0, dir,geom, q, cms2,vmin,vmax)>=1){
163 dualfprintf(
fail_file,
"vchar.c: simplefast() failed\n");
164 dualfprintf(
fail_file,
"simplefast() failed : dir=%d :\n bsq=%21.15g\n rho=%21.15g\n u=%21.15g\n WW=%21.15g\n EF=%21.15g\n va2=%21.15g\n cs2=%21.15g\n cms2=%21.15g\n",dir,bsq,rho,u,WW,EF,va2,cs2,cms2);
172 if(realfast(dir,geom,q,EF,cs2,cms2,va2,q->
ucon,q->
bcon,geom->gcon,vmin,vmax)>=1)
return(1);
173 stderrfprintf(
"%d %d\n",geom->i,geom->j);
174 stderrfprintf(
"rf: vmax=%21.15g vmin=%21.15g\n",*vmax,*vmin);
175 if(
simplefast(0, dir,geom, q, cms2,vmin,vmax)>=1)
return(1);
176 stderrfprintf(
"sf: vmax=%21.15g vmin=%21.15g\n",*vmax,*vmin);
184 #if(BOUNDARYSMOOTHER)
185 boundary_smoother(geom,vmax,vmin,ignorecourant);
204 ctsq=(va2+cs2*(1.0-va2))/(1.0-(va2+cs2*(1.0-va2)));
205 groupvel(pr,q,dir,geom,vmax,vmin,ctsq,&vgmax,&vgmin);
213 limitv3(pr,q,dir,geom,vmax);
214 limitv3(pr,q,dir,geom,vmin);
223 int boundary_smoother(
struct of_geom *geom,
FTYPE *vmax,
FTYPE *vmin,
int *ignorecourant)
261 #define USESASHAREWRITE 1 // whether to use WHAM form that avoids catastrophic cancellation in non-rel and ultra-rel regimes.
267 FTYPE Asq, Bsq, Au, Bu, AB, Au2, Bu2, AuBu, A, B,
C;
288 raise_vec(Acov, geom, Acon);
292 raise_vec(Bcov, geom, Bcon);
301 Asq =
dot(Acon, Acov);
302 Bsq =
dot(Bcon, Bcov);
305 AB =
dot(Acon, Bcov);
313 B = 2. * (AuBu * (1.0-cms2) - AB*cms2);
315 A = Bu2 * (1.0 - cms2) - Bsq * cms2;
319 #if(USESASHAREWRITE==0)
320 C = Au2*(1.0-cms2) - Asq * cms2;
324 discr = B * B - 4.0 * A *
C;
329 (AB * AB - Asq * Bsq) * cms2
330 + (2.0 * AB * Au * Bu - Asq * Bu2 - Bsq * Au2) * (cms2 - 1.0)
344 if((discr<0.0)&&(discr> -1
E-10)) discr=0.0;
346 dualfprintf(
fail_file,
"simplefast discr=%21.15g, nstep = %ld, steppart == %d, i = %d, j = %d, k = %d, p = %d\n",
347 discr,
nstep,
steppart, geom->i, geom->j, geom->k, geom->p );
350 dualfprintf(
fail_file,
"geom->gcov[%d][%d]=%21.15g\n",j,k,geom->gcov[
GIND(j,k)]);
354 dualfprintf(
fail_file,
"geom->gcon[%d][%d]=%21.15g\n",j,k,geom->gcon[
GIND(j,k)]);
357 #if(USESASHAREWRITE==0)
358 dualfprintf(
fail_file,
"\n\t A=%21.15g B=%21.15g C=%21.15g discr=%21.15g cms2=%21.15g\n", A, B, C, discr, cms2);
360 dualfprintf(
fail_file,
"\n\t A=%21.15g discr=%21.15g cms2=%21.15g\n", A, discr, cms2);
362 dualfprintf(
fail_file,
"\n\t q->ucon: %21.15g %21.15g %21.15g %21.15g\n", q->
ucon[0],
364 dualfprintf(
fail_file,
"\n\t q->bcon: %21.15g %21.15g %21.15g %21.15g\n", q->
bcon[0],
366 dualfprintf(
fail_file,
"\n\t Acon: %21.15g %21.15g %21.15g %21.15g\n", Acon[0], Acon[1],
368 dualfprintf(
fail_file,
"\n\t Bcon: %21.15g %21.15g %21.15g %21.15g\n", Bcon[0], Bcon[1],
393 vm = -(-B + discr) / (2. * A);
394 vp = -(-B - discr) / (2. * A);
404 #if(USESASHAREWRITE==0)
405 dualfprintf(
fail_file,
"vm=%21.15g vp=%21.15g discr=%21.15g A=%21.15g B=%21.15g C=%21.15g\n",vm,vp,discr,A,B,C);
407 dualfprintf(
fail_file,
"vm=%21.15g vp=%21.15g discr=%21.15g A=%21.15g B=%21.15g\n",vm,vp,discr,A,B);
409 dualfprintf(
fail_file,
"i=%d j=%d k=%d p=%d nstep=%ld steppart=%d\n",geom->i,geom->j,geom->k,geom->p,
nstep,
steppart);
410 dualfprintf(
fail_file,
"cms2=%21.15g\n",cms2);
412 dualfprintf(
fail_file,
"vmin=%21.15g vmax=%21.15g\n",vm,vp);
415 if(finite(cms2) && whichcall==0){
418 set_zamo_velocity(
WHICHVEL,geom,prbackup);
421 simplefast(1, dir,geom, &qbackup, cms2,vmin, vmax);
423 dualfprintf(
fail_file,
"Backup vchar still failed\n");
463 int realfast(
int dir,
struct of_geom *geom,
struct of_state *q,
FTYPE EF,
FTYPE cs2,
FTYPE cms2,
FTYPE va2,
FTYPE *
ucon,
FTYPE *
bcon,
FTYPE *
gcon,
FTYPE *vmin,
FTYPE *vmax)
465 FTYPE va02,vax2,va0x2,uux;
467 FTYPE gn300,gn3xx,gn30x;
469 FTYPE AA,BB,CC,DD,EE;
470 FTYPE uuxsq,uux3,uux4,uu0sq,uu03,uu04;
476 gn300=gcon[
GIND(0,0)];
477 va02=bcon[0]*bcon[0]*oEF;
480 vax2=bcon[dir]*bcon[dir]*oEF;
481 va0x2=bcon[0]*bcon[dir]*oEF;
483 gn3xx=gcon[
GIND(dir,dir)];
484 gn30x=gcon[
GIND(0,dir)];
494 EE=uux4 - cms2*uuxsq*(gn3xx + uuxsq) + cs2*gn3xx*vax2;
495 DD=2.*(-2.*uu0*uux3 + cms2*uux*(gn3xx*uu0 + uux*(gn30x + 2.*uu0*uux)) - cs2*gn3xx*va0x2 - cs2*gn30x*vax2);
496 CC=6.*uu0sq*uuxsq - cms2*(gn3xx*uu0sq + uux*(4.*gn30x*uu0 + gn300*uux + 6.*uu0sq*uux)) + cs2*(4.*gn30x*va0x2 + gn3xx*va02 + gn300*vax2);
497 BB=2.*(-2.*uu03*uux + cms2*uu0*(gn300*uux + uu0*(gn30x + 2.*uu0*uux)) - cs2*gn300*va0x2 - cs2*gn30x*va02);
498 AA=uu04 - cms2*uu0sq*(gn300 + uu0sq) + cs2*gn300*va02;
504 BB=0.953704334932897;
505 CC=0.00501787191044863;
506 DD=-0.0036931214344023;
507 EE=3.97410207658954e-05;
510 *vmax=quarticsol(1.0,1.0,AA,BB,CC,DD,EE);
511 *vmin=quarticsol(-1.0,-1.0,AA,BB,CC,DD,EE);
521 FTYPE unit1,unit2,unit3,newradius,newphi,unit4;
522 FTYPE part1,part2,part25,part3;
523 FTYPE AAAsq,AAAcu,BBBsq,BBBcu,CCCsq,CCCcu,DDDsq,unit1sq,unit2sq,unit2cu;
534 unit1=2.*CCCcu - 9.*BBB*CCC*DDD + 27.*AAA*DDDsq + 27.*BBBsq*EEE - 72.*AAA*CCC*EEE;
536 unit2=CCCsq - 3.*BBB*DDD + 12.*AAA*EEE;
539 unit2cu=unit2sq*unit2;
543 unit3=-4.*unit2cu + unit1sq;
544 if((unit3>0.0)&&(unit3<1
E-3)) unit3=0.0;
546 dualfprintf(
fail_file,
"unit3=%21.15g\n",unit3);
550 newradius=sqrt(unit1sq+fabs(-unit3));
552 newphi=atan2(sqrt(-unit3),unit1);
554 unit4=(1./(3.*
AAA))*pow(2.,(2./3.))*pow(newradius,(1./3.))*cos(newphi/3.);
557 part1 = -BBB/(4.*
AAA);
560 disc=BBBsq/(4.*AAAsq) - 2./3.*CCC/AAA + unit4;
569 dualfprintf(
fail_file,
"part2 disc=%21.15g\n",disc);
577 part25 = (-BBBcu/AAAcu + 4.*BBB*CCC/AAAsq - 8.*DDD/
AAA)/(4.*part2);
580 disc=BBBsq/(2.*AAAsq) - 4./3.*CCC/AAA - unit4 +sign1*part25;
586 dualfprintf(
fail_file,
"part3 disc=%21.15g\n",disc);
594 return(part1 +sign1* 0.5*part2 +sign2* 0.5*part3);
625 ctrat=ctsq/(uu0*uu0);
646 *vgmax=numerator/denominator;
650 *vgmin=numerator/denominator;
658 raise_vec(kd,geom,ku);
659 omega=0.0;
DLOOPA(j) omega+=-kd[j]*uu[j];
660 DLOOPA(j) vg[j]=(-omega*uu[j]-ctsq*ku[j]);
661 *vgmax=vg[dir]/vg[TT];
665 lower_vec(vg,geom,vgd);
667 DLOOPA(j) isone1+=vg[j]*vgd[j];
668 isone1/=(omega*omega*(1.0+ctsq));
671 dualfprintf(
fail_file,"vmax: vfx=%21.15g vgx=%21.15g : vfy=%21.15g vgy=%21.15g : vfz=%21.15g vgz=%21.15g\n",q->
ucon[1]/q->
ucon[0],vg[1]/vg[0],q->ucon[2]/q->ucon[0],vg[2]/vg[0],q->ucon[3]/q->ucon[0],vg[3]/vg[0]);
677 raise_vec(kd,geom,ku);
678 omega=0.0;
DLOOPA(j) omega+=-kd[j]*uu[j];
679 DLOOPA(j) vg[j]=(-omega*uu[j]-ctsq*ku[j]);
680 *vgmin=vg[dir]/vg[TT];
684 lower_vec(vg,geom,vgd);
686 DLOOPA(j) isone2+=vg[j]*vgd[j];
687 isone2/=(omega*omega*(1.0+ctsq));
690 dualfprintf(fail_file,"%d %d : isone: %21.15g %21.15g\n",geom->
i,geom->j,isone1,isone2);
695 dualfprintf(fail_file,"vmin: vfx=%21.15g vgx=%21.15g : vfy=%21.15g vgy=%21.15g : vfz=%21.15g vgz=%21.15g\n",q->ucon[1]/q->ucon[0],vg[1]/vg[0],q->ucon[2]/q->ucon[0],vg[2]/vg[0],q->ucon[3]/q->ucon[0],vg[3]/vg[0]);