aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/documentation.tex2
-rw-r--r--param.ccl4
-rw-r--r--src/GRHydro_Con2Prim.F9060
3 files changed, 55 insertions, 11 deletions
diff --git a/doc/documentation.tex b/doc/documentation.tex
index b6f3ff9..1a8d6c2 100644
--- a/doc/documentation.tex
+++ b/doc/documentation.tex
@@ -1991,7 +1991,7 @@ GRAstro\_Hydro} codes gave an essential benchmark to aim for, and
encouragement that it was possible!
Thirdly, the support of the Cactus team, especially Tom Goodale,
-Gabrielle Allen and Thomas Radke made (and, especially Thomas, continue to make) life a
+Gabrielle Allen and Thomas Radke made (and continues to make) life a
lot easier.
Finally, for their work in coding, ideas and suggestions, or just
diff --git a/param.ccl b/param.ccl
index cd9756e..7ce3eb9 100644
--- a/param.ccl
+++ b/param.ccl
@@ -314,6 +314,10 @@ real c2p_reset_pressure_to_value "The value to which the pressure is reset to wh
0: :: "greater than zero"
} 1.e-20
+boolean c2p_resort_to_bisection "If the pressure guess is unphysical, should we try with bisection (slower, but more robust)"
+{
+} no
+
real GRHydro_eps_min "Minimum value of specific internal energy - this is now only used in GRHydro_InitData's GRHydro_Only_Atmo routine"
{
0: :: "Positive"
diff --git a/src/GRHydro_Con2Prim.F90 b/src/GRHydro_Con2Prim.F90
index f61eea7..0916852 100644
--- a/src/GRHydro_Con2Prim.F90
+++ b/src/GRHydro_Con2Prim.F90
@@ -319,8 +319,6 @@ subroutine Conservative2Primitive(CCTK_ARGUMENTS)
endif
#endif
-
-
end do
end do
end do
@@ -368,7 +366,7 @@ subroutine Con2Prim_pt(handle, dens, sx, sy, sz, tau, rho, velx, vely, &
! begin EOS Omni vars
integer :: n,keytemp,anyerr,keyerr(1)
- real*8 :: xpress,xtemp,xye
+ real*8 :: xpress,xtemp,xye,tmp,plow
n=1;keytemp=0;anyerr=0;keyerr(1)=0
xpress=0.0d0;xtemp=0.0d0;xye=0.0d0
! end EOS Omni vars
@@ -387,6 +385,10 @@ subroutine Con2Prim_pt(handle, dens, sx, sy, sz, tau, rho, velx, vely, &
call EOS_Omni_press(handle,keytemp,GRHydro_eos_rf_prec,n,&
rho,epsilon,xtemp,xye,xpress,keyerr,anyerr)
pold = max(1.d-10,xpress)
+ ! This is the lowest admissible pressure, otherwise we are off the physical regime
+ ! Sometimes, we may end up with bad initial guesses. In that case we need to start off with something
+ ! reasonable at least
+ plow = max(pmin, sqrt(s2) - utau - udens)
!!$ Check that the variables have a chance of being physical
@@ -398,10 +400,10 @@ subroutine Con2Prim_pt(handle, dens, sx, sy, sz, tau, rho, velx, vely, &
else
!$OMP CRITICAL
!!!! call CCTK_WARN(GRHydro_NaN_verbose, "c2p failed and being told not to reset the pressure")
+ !call CCTK_WARN(0, "c2p failed and being told not to reset the pressure")
GRHydro_C2P_failed = 1
!$OMP END CRITICAL
endif
-
endif
!!$ Calculate rho and epsilon
@@ -477,14 +479,52 @@ subroutine Con2Prim_pt(handle, dens, sx, sy, sz, tau, rho, velx, vely, &
pold = pnew
- pnew = max(pold - f/df, pmin)
+
+ ! Try to obtain new pressure via Newton-Raphson.
+
+ pnew = pold - f/df
+
+ ! Check if Newton-Raphson resulted in something reasonable!
+
+ if (c2p_resort_to_bisection) then
+
+ tmp = (utau + pnew + udens)**2 - s2
+ plow = max(pmin, sqrt(s2) - utau - udens)
+
+ if ((pnew .lt. plow .or. tmp .le. 0.0d0) .and. c2p_resort_to_bisection) then
+
+ ! Ok, Newton-Raphson ended up finding something unphysical.
+ ! Let's try to find our root via bisection (which converges slower but is more robust)
+
+ pnew = (plow + pold) / 2
+ tmp = (utau + pnew + udens)**2 - s2
+
+ end if
+
+ else
+
+ ! This is the standard algorithm without resorting to bisection.
+
+ pnew = max(pmin, pnew)
+ tmp = (utau + pnew + udens)**2 - s2
+
+ endif
+
+ ! Check if we are still in the physical range now.
+ ! If not, we set the C2P failed mask, and set pnew = pold (which will exit the loop).
+
+ if ((tmp .le. 0.0d0) .and. GRHydro_C2P_failed .eq. 0) then
+ GRHydro_C2P_failed = 1
+ pnew = pold
+ endif
+
!!$ Recalculate primitive variables and function
-
- rho = udens * sqrt( (utau + pnew + udens)**2 - s2)/(utau + pnew + udens)
- w_lorentz = (utau + pnew + udens) / sqrt( (utau + pnew + udens)**2 - &
- s2)
- epsilon = (sqrt( (utau + pnew + udens)**2 - s2) - pnew * w_lorentz - &
+
+ rho = udens * sqrt( tmp)/(utau + pnew + udens)
+
+ w_lorentz = (utau + pnew + udens) / sqrt( tmp)
+ epsilon = (sqrt( tmp) - pnew * w_lorentz - &
udens)/udens
call EOS_Omni_press(handle,keytemp,GRHydro_eos_rf_prec,n,&