aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--param.ccl21
-rw-r--r--src/GRHydro_PPM.F901121
-rw-r--r--src/GRHydro_PPMReconstruct_drv.F9012
-rw-r--r--src/GRHydro_Reconstruct.F9026
4 files changed, 844 insertions, 336 deletions
diff --git a/param.ccl b/param.ccl
index a4f037c..537c2a8 100644
--- a/param.ccl
+++ b/param.ccl
@@ -193,6 +193,27 @@ int ppm_mppm_debug_eigenvalues "write eigenvalues into debug grid variables"
0:1 :: "0 (off, default) or 1 (on)"
} 0
+
+boolean use_enhanced_ppm "Use the enhanced ppm reconstruction method proposed by Colella & Sekora 2008 and McCorquodale & Colella 2011" STEERABLE=RECOVER
+{
+} no
+
+real enhanced_ppm_C2 "Parameter for enhancecd ppm limiter. Default from McCorquodale & Colella 2011"
+{
+ *:* :: "must be greater than 1. According to Colella&Sekora 2008, enhanced ppm is insensitive to C in [1.25,5]"
+} 1.25
+
+real enhanced_ppm_C3 "Parameter for enhancecd ppm limiter. Default from McCorquodale & Colella 2011"
+{
+ 0:* :: "must be greater than 0."
+} 0.1
+
+real GRHydro_ppm_atmo_tolerance "A relative value for rho below which we switch to standard ppm. This may be necessary for very sharp transitions in the density to atmosphere values." STEERABLE=RECOVER
+{
+ 0:* :: "anything positive"
+} 1e4
+
+
int eno_order "The order of accuracy of the ENO reconstruction"
{
1:* :: "Anything above 1, but above 5 is pointless"
diff --git a/src/GRHydro_PPM.F90 b/src/GRHydro_PPM.F90
index c5754a0..99e0371 100644
--- a/src/GRHydro_PPM.F90
+++ b/src/GRHydro_PPM.F90
@@ -32,7 +32,7 @@ end subroutine PPM_TVD
/*@@
@routine SimplePPM_1d
@date Thu Feb 14 19:08:52 2002
- @author Ian Hawke, Toni Font
+ @author Ian Hawke, Toni Font, Christian Reisswig
@desc
The simple PPM reconstruction routine that applies along
each one dimensional slice.
@@ -43,16 +43,21 @@ end subroutine PPM_TVD
@history
Written in frustration when IH couldn''t get Toni''s original code
to work.
+ Later extended to enhanced PPM scheme by CR.
@endhistory
@@*/
+#define SpaceMask_CheckStateBitsF90_1D(mask,i,type_bits,state_bits) \
+ (iand(mask((i)),(type_bits)).eq.(state_bits))
+
+
subroutine SimplePPM_1d(handle,poly,&
nx,dx,rho,velx,vely,velz,eps,press,rhominus,&
velxminus,velyminus,velzminus,epsminus,rhoplus,velxplus,velyplus,&
velzplus,epsplus,trivial_rp, hydro_excision_mask,&
gxx, gxy, gxz, gyy, gyz, gzz, beta, alp, w_lorentz, &
- dir, ni, nj, nrx, nry, nrz, ev_l, ev_r, xw)
+ dir, ni, nj, nrx, nry, nrz, ev_l, ev_r, xw, rho_min)
USE GRHydro_Scalars
USE GRHydro_Eigenproblem
@@ -72,6 +77,7 @@ subroutine SimplePPM_1d(handle,poly,&
CCTK_REAL, dimension(nx) :: rhominusr,velxminusr,velyminusr,velzminusr
CCTK_REAL, dimension(nx) :: epsminusr
CCTK_REAL, dimension(nx) :: rhoplusr,velxplusr,velyplusr,velzplusr,epsplusr
+ CCTK_REAL, dimension(nx) :: atmosphere_mask
CCTK_INT :: i,s
CCTK_REAL, dimension(nx) :: drho,dvelx,dvely,dvelz,deps
@@ -94,6 +100,8 @@ subroutine SimplePPM_1d(handle,poly,&
CCTK_REAL :: agxx, agxy, agxz, agyy, agyz, agzz
CCTK_REAL, dimension(nx) :: xwind, l_ev_l, l_ev_r
+ CCTK_REAL :: D2a, D2aL, D2aR, D2aC, D2aLim, rhi, threshold, rho_min, daplus, daminus, D3a, D3aLL, D3aL, D3aR, D2aLL, D2aRR, D3aMin, D3aMax
+
logical :: cond
@@ -101,70 +109,175 @@ subroutine SimplePPM_1d(handle,poly,&
trivial_rp = .true.
-!!$ Average slopes delta_m(a). See (1.7) of Colella and Woodward, p.178
-!!$ This is the expression for an even grid.
- do i = 2, nx - 1
- drho(i) = 0.5d0 * (rho(i+1) - rho(i-1))
- dvelx(i) = 0.5d0 * (velx(i+1) - velx(i-1))
- dvely(i) = 0.5d0 * (vely(i+1) - vely(i-1))
- dvelz(i) = 0.5d0 * (velz(i+1) - velz(i-1))
- dpress(i) = press(i+1) - press(i-1)
- d2rho(i) = (rho(i+1) - 2.d0 * rho(i) + rho(i-1))! / 6.d0 / dx / dx
- ! since we use d2rho only for the condition d2rho(i+1)*d2rhoi(i-1)<0
- ! the denominator is not necessary
- end do
- if (poly .eq. 0) then
- do i = 2, nx - 1
- deps(i) = 0.5d0 * (eps(i+1) - eps(i-1))
- end do
- end if
+#define STEEP(x,dx,dmx) \
+ if ( (x(i+1) - x(i)) * (x(i) - x(i-1)) > 0.d0 ) then &&\
+ dmx(i) = sign(1.d0, dx(i)) * \
+ min(abs(dx(i)), 2.d0 * abs(x(i) - x(i-1)), \
+ 2.d0 * abs(x(i+1) - x(i))) &&\
+ else &&\
+ dmx(i) = 0.d0 &&\
+ end if
+
+
+ if (use_enhanced_ppm .eq. 0) then
+ !! This is the original PPM algorithm by Colella & Woodward 1984.
+
+ !!$ Average slopes delta_m(a). See (1.7) of Colella and Woodward, p.178
+ !!$ This is the expression for an even grid.
+
+ do i = 2, nx - 1
+ drho(i) = 0.5d0 * (rho(i+1) - rho(i-1))
+ dvelx(i) = 0.5d0 * (velx(i+1) - velx(i-1))
+ dvely(i) = 0.5d0 * (vely(i+1) - vely(i-1))
+ dvelz(i) = 0.5d0 * (velz(i+1) - velz(i-1))
+ dpress(i) = press(i+1) - press(i-1)
+ d2rho(i) = (rho(i+1) - 2.d0 * rho(i) + rho(i-1))! / 6.d0 / dx / dx
+ ! since we use d2rho only for the condition d2rho(i+1)*d2rhoi(i-1)<0
+ ! the denominator is not necessary
+ end do
+ if (poly .eq. 0) then
+ do i = 2, nx - 1
+ deps(i) = 0.5d0 * (eps(i+1) - eps(i-1))
+ end do
+ end if
-!!$ Steepened slope. See (1.8) of Colella and Woodward, p.178
+ !!$ Steepened slope. See (1.8) of Colella and Woodward, p.178
- do i = 2, nx - 1
-#define STEEP(x,dx,dmx) \
- if ( (x(i+1) - x(i)) * (x(i) - x(i-1)) > 0.d0 ) then &&\
- dmx(i) = sign(1.d0, dx(i)) * \
- min(abs(dx(i)), 2.d0 * abs(x(i) - x(i-1)), \
- 2.d0 * abs(x(i+1) - x(i))) &&\
- else &&\
- dmx(i) = 0.d0 &&\
- end if
- STEEP(rho, drho, dmrho)
- STEEP(velx, dvelx, dmvelx)
- STEEP(vely, dvely, dmvely)
- STEEP(velz, dvelz, dmvelz)
- end do
- if (poly .eq. 0) then
- do i = 2, nx - 1
- STEEP(eps, deps, dmeps)
- end do
- end if
+ do i = 2, nx - 1
+ STEEP(rho, drho, dmrho)
+ STEEP(velx, dvelx, dmvelx)
+ STEEP(vely, dvely, dmvely)
+ STEEP(velz, dvelz, dmvelz)
+ end do
+ if (poly .eq. 0) then
+ do i = 2, nx - 1
+ STEEP(eps, deps, dmeps)
+ end do
+ end if
-!!$ Initial boundary states. See (1.9) of Colella and Woodward, p.178
+ !!$ Initial boundary states. See (1.9) of Colella and Woodward, p.178
+
+ do i = 2, nx-2
+ rhoplus(i) = 0.5d0 * (rho(i) + rho(i+1)) + &
+ (dmrho(i) - dmrho(i+1)) / 6.d0
+ rhominus(i+1) = rhoplus(i)
+ velxplus(i) = 0.5d0 * (velx(i) + velx(i+1)) + &
+ (dmvelx(i) - dmvelx(i+1)) / 6.d0
+ velxminus(i+1) = velxplus(i)
+ velyplus(i) = 0.5d0 * (vely(i) + vely(i+1)) + &
+ (dmvely(i) - dmvely(i+1)) / 6.d0
+ velyminus(i+1) = velyplus(i)
+ velzplus(i) = 0.5d0 * (velz(i) + velz(i+1)) + &
+ (dmvelz(i) - dmvelz(i+1)) / 6.d0
+ velzminus(i+1) = velzplus(i)
+ end do
+ if (poly .eq. 0) then
+ do i = 2, nx-2
+ epsplus(i) = 0.5d0 * (eps(i) + eps(i+1)) + &
+ (dmeps(i) - dmeps(i+1)) / 6.d0
+ epsminus(i+1) = epsplus(i)
+ end do
+ end if
+ else
+!! This is the modified PPM algorithm by Colella & Sekora 2008 and McCorquodale & Colella 2011.
+!! This uses a better limiter based on second derivatives that preserves
+!! accuracy at local extrema. It also uses a higher-order interpolation polynomial.
+
+ !!$ Initial boundary states (sixth order accurate). See (17) of Colella and Sekora 2008, p.7071
+#define APPROX_AT_CELL_INTERFACE_STENCIL4(a, ah) \
+ ah = 37.0d0/60.0d0*(a(i)+a(i+1)) - 2.0d0/15.0d0*(a(i-1)+a(i+2)) + 1.0d0/60.0d0*(a(i-2)+a(i+3))
+
+ !!$ Initial boundary states (4th order accurate). See (16) of Colella and Sekora 2008, p.7071
+#define APPROX_AT_CELL_INTERFACE(a, ah) \
+ ah = 7.0d0/12.0d0*(a(i)+a(i+1)) - 1.0d0/12.0d0*(a(i-1)+a(i+2))
+
+ !! A threshold value of rho
+ threshold = rho_min * GRHydro_ppm_atmo_tolerance
+
+#define LIMIT(a,ah,C, alim) \
+ if ((min(a(i),a(i+1)) .le. ah) .and. (ah .le. max(a(i),a(i+1)))) then &&\
+ alim = ah &&\
+ else &&\
+ D2a = 3.0d0 * (a(i) - 2.0d0*ah + a(i+1)) &&\
+ D2aL = (a(i-1) - 2.0d0*a(i) + a(i+1)) &&\
+ D2aR = (a(i) - 2.0d0*a(i+1) + a(i+2)) &&\
+ if (D2a*D2aR .ge. 0 .and. D2a*D2aL .ge. 0 .and. rho(i) .gt. threshold .and. rho(i+1) .gt. threshold .and. rho(i-1) .gt. threshold .and. rho(i+2) .gt. threshold) then &&\
+ alim = 0.5d0*(a(i)+a(i+1)) - sign(1.0d0, D2a)*min(C*abs(D2aL), C*abs(D2aR), abs(D2a))/3.0d0 &&\
+ else &&\
+ alim = 0.5d0*(a(i)+a(i+1)) &&\
+ end if &&\
+ endif
+
+
+ if (PPM3) then
+
+ !! We initialize "plus" \equiv a_j+1/2 with (16) via APPROX_AT_CELL_INTERFACE,
+ !! then checking for (13) of Colella & Sekora 2008 and applying
+ !! (18) and (19) if (13) is not satisfied. This is done with LIMIT.
+ !! There, we also switch to lower order if we are near atmosphere values.
+ do i = 2, nx-2
+ APPROX_AT_CELL_INTERFACE(rho, rhoplus(i))
+ LIMIT(rho, rhoplus(i), enhanced_ppm_C2, rhoplus(i))
+ rhominus(i+1) = rhoplus(i)
+
+ APPROX_AT_CELL_INTERFACE(velxplus, velxplus(i))
+ LIMIT(velx, velxplus(i), enhanced_ppm_C2, velxplus(i))
+ velxminus(i+1) = velxplus(i)
+
+ APPROX_AT_CELL_INTERFACE(velyplus, velyplus(i))
+ LIMIT(vely, velyplus(i), enhanced_ppm_C2, velyplus(i))
+ velyminus(i+1) = velyplus(i)
+
+ APPROX_AT_CELL_INTERFACE(velzplus, velzplus(i))
+ LIMIT(velz, velzplus(i), enhanced_ppm_C2, velzplus(i))
+ velzminus(i+1) = velzplus(i)
+ end do
+ if (poly .eq. 0) then
+ do i = 2, nx-2
+ APPROX_AT_CELL_INTERFACE(eps, epsplus(i))
+ LIMIT(eps, epsplus(i), enhanced_ppm_C2, epsplus(i))
+ epsminus(i+1) = epsplus(i)
+ end do
+ end if
+
+ else
- do i = 2, nx-2
- rhoplus(i) = 0.5d0 * (rho(i) + rho(i+1)) + &
- (dmrho(i) - dmrho(i+1)) / 6.d0
- rhominus(i+1) = rhoplus(i)
- velxplus(i) = 0.5d0 * (velx(i) + velx(i+1)) + &
- (dmvelx(i) - dmvelx(i+1)) / 6.d0
- velxminus(i+1) = velxplus(i)
- velyplus(i) = 0.5d0 * (vely(i) + vely(i+1)) + &
- (dmvely(i) - dmvely(i+1)) / 6.d0
- velyminus(i+1) = velyplus(i)
- velzplus(i) = 0.5d0 * (velz(i) + velz(i+1)) + &
- (dmvelz(i) - dmvelz(i+1)) / 6.d0
- velzminus(i+1) = velzplus(i)
- end do
- if (poly .eq. 0) then
- do i = 2, nx-2
- epsplus(i) = 0.5d0 * (eps(i) + eps(i+1)) + &
- (dmeps(i) - dmeps(i+1)) / 6.d0
- epsminus(i+1) = epsplus(i)
+ !! Same as above but for 4 stencil points using (17) of Colella & Sekora 2008 as
+ !! initial states.
+ do i = 3, nx-3
+ APPROX_AT_CELL_INTERFACE_STENCIL4(rho, rhoplus(i))
+ LIMIT(rho, rhoplus(i), enhanced_ppm_C2, rhoplus(i))
+ rhominus(i+1) = rhoplus(i)
+
+ APPROX_AT_CELL_INTERFACE_STENCIL4(velxplus, velxplus(i))
+ LIMIT(velx, velxplus(i), enhanced_ppm_C2, velxplus(i))
+ velxminus(i+1) = velxplus(i)
+
+ APPROX_AT_CELL_INTERFACE_STENCIL4(velyplus, velyplus(i))
+ LIMIT(vely, velyplus(i), enhanced_ppm_C2, velyplus(i))
+ velyminus(i+1) = velyplus(i)
+
+ APPROX_AT_CELL_INTERFACE_STENCIL4(velzplus, velzplus(i))
+ LIMIT(velz, velzplus(i), enhanced_ppm_C2, velzplus(i))
+ velzminus(i+1) = velzplus(i)
+ end do
+ if (poly .eq. 0) then
+ do i = 3, nx-3
+ APPROX_AT_CELL_INTERFACE_STENCIL4(eps, epsplus(i))
+ LIMIT(eps, epsplus(i), enhanced_ppm_C2, epsplus(i))
+ epsminus(i+1) = epsplus(i)
+ end do
+ end if
+ endif
+
+ !! Finally compute pressure gradient needed for flattening and shock detection
+ do i = 2, nx-1
+ dpress(i) = press(i+1) - press(i-1)
end do
- end if
+
+ endif
+
!!$Discontinuity steepening. See (1.14-17) of C&W.
!!$This is the detect routine which mat be activated with the ppm_detect parameter
@@ -173,135 +286,148 @@ trivial_rp = .true.
!!$So this is just dropped from eq. (3.2) of C&W.
!!$We can get around this by just rescaling the constant k0 (ppm_k0 here).
- if (ppm_detect .ne. 0) then
-
- do i = 3, nx - 2
- if ( (d2rho(i+1)*d2rho(i-1) < 0.d0).and.(abs(rho(i+1)-rho(i-1)) - &
- ppm_epsilon_shock * min(abs(rho(i+1)), abs(rho(i-1))) > 0.d0) ) then
- etatilde = (rho(i-2) - rho(i+2) + 4.d0 * drho(i)) / (drho(i) * 12.d0)
- else
- etatilde = 0.d0
- end if
- eta = max(0.d0, min(1.d0, ppm_eta1 * (etatilde - ppm_eta2)))
- if (ppm_k0 * abs(drho(i)) * min(press(i-1),press(i+1)) < &
- abs(dpress(i)) * min(rho(i-1), rho(i+1))) then
- eta = 0.d0
- end if
- if (eta > 0.d0) then
- trivial_rp(i-1) = .false.
- trivial_rp(i) = .false.
- end if
- rhominus(i) = rhominus(i) * (1.d0 - eta) + &
- (rho(i-1) + 0.5d0 * dmrho(i-1)) * eta
- rhoplus(i) = rhoplus(i) * (1.d0 - eta) + &
- (rho(i+1) - 0.5d0 * dmrho(i+1)) * eta
- end do
-
- end if
-
+ if (use_enhanced_ppm .eq. 0) then
+ ! Only for 1984 PPM scheme!
+ if (ppm_detect .ne. 0) then
+
+ if (use_enhanced_ppm .eq. 1) then
+ ! make sure drho, d2rho and dmrho are computed everywhere!
+ do i = 2, nx-1
+ drho(i) = 0.5d0 * (rho(i+1) - rho(i-1))
+ d2rho(i) = (rho(i+1) - 2.d0 * rho(i) + rho(i-1))
+ end do
+ do i = 2, nx-1
+ STEEP(rho, drho, dmrho)
+ end do
+ endif
+
+ do i = 3, nx - 2
+ if ( (d2rho(i+1)*d2rho(i-1) < 0.d0).and.(abs(rho(i+1)-rho(i-1)) - &
+ ppm_epsilon_shock * min(abs(rho(i+1)), abs(rho(i-1))) > 0.d0) ) then
+ etatilde = (rho(i-2) - rho(i+2) + 4.d0 * drho(i)) / (drho(i) * 12.d0)
+ else
+ etatilde = 0.d0
+ end if
+ eta = max(0.d0, min(1.d0, ppm_eta1 * (etatilde - ppm_eta2)))
+ if (ppm_k0 * abs(drho(i)) * min(press(i-1),press(i+1)) < &
+ abs(dpress(i)) * min(rho(i-1), rho(i+1))) then
+ eta = 0.d0
+ end if
+ if (eta > 0.d0) then
+ trivial_rp(i-1) = .false.
+ trivial_rp(i) = .false.
+ end if
+ rhominus(i) = rhominus(i) * (1.d0 - eta) + &
+ (rho(i-1) + 0.5d0 * dmrho(i-1)) * eta
+ rhoplus(i) = rhoplus(i) * (1.d0 - eta) + &
+ (rho(i+1) - 0.5d0 * dmrho(i+1)) * eta
+ end do
+
+ end if
+
!!$ mppm
#define D_UPW(x) (0.5d0 * (x(i) + x(i+1)))
#define LEFT1(x) (13.d0*x(i+1)-5.d0*x(i+2)+x(i+3)+3.d0*x(i ))/12.d0
#define RIGHT1(x) (13.d0*x(i )-5.d0*x(i-1)+x(i-2)+3.d0*x(i+1))/12.d0
- if (ppm_mppm .gt. 0) then
- l_ev_l=0.d0
- l_ev_r=0.d0
- xwind=0.d0
- do i=3, nx - 3
- agxx = 0.5d0*( gxx(i) + gxx(i+1) )
- agxy = 0.5d0*( gxy(i) + gxy(i+1) )
- agxz = 0.5d0*( gxz(i) + gxz(i+1) )
- agyy = 0.5d0*( gyy(i) + gyy(i+1) )
- agyz = 0.5d0*( gyz(i) + gyz(i+1) )
- agzz = 0.5d0*( gzz(i) + gzz(i+1) )
- det = SPATIAL_DETERMINANT(agxx, agxy, agxz, \
- agyy, agyz, agzz)
- call UpperMetric (uxx, uxy, uxz, uyy, uyz, uzz, &
- det, agxx, agxy, agxz, agyy, agyz, agzz)
- call eigenvalues(handle,&
- D_UPW(rho), D_UPW(velx), D_UPW(vely), D_UPW(velz), &
- D_UPW(eps), D_UPW(w_lorentz), lam, &
- agxx, agxy, agxz, agyy, agyz, agzz, &
- uxx, D_UPW(alp), D_UPW(beta))
- l_ev_l(i)=lam(1)
- l_ev_r(i)=lam(5)
- xwind(i) = (lam(1) + lam(5)) / (abs(lam(1)) + abs(lam(5)))
- xwind(i) = min(1.d0, max(-1.d0, xwind(i)))
+ if (ppm_mppm .gt. 0) then
+ l_ev_l=0.d0
+ l_ev_r=0.d0
+ xwind=0.d0
+ do i=3, nx - 3
+ agxx = 0.5d0*( gxx(i) + gxx(i+1) )
+ agxy = 0.5d0*( gxy(i) + gxy(i+1) )
+ agxz = 0.5d0*( gxz(i) + gxz(i+1) )
+ agyy = 0.5d0*( gyy(i) + gyy(i+1) )
+ agyz = 0.5d0*( gyz(i) + gyz(i+1) )
+ agzz = 0.5d0*( gzz(i) + gzz(i+1) )
+ det = SPATIAL_DETERMINANT(agxx, agxy, agxz, \
+ agyy, agyz, agzz)
+ call UpperMetric (uxx, uxy, uxz, uyy, uyz, uzz, &
+ det, agxx, agxy, agxz, agyy, agyz, agzz)
+ call eigenvalues(handle,&
+ D_UPW(rho), D_UPW(velx), D_UPW(vely), D_UPW(velz), &
+ D_UPW(eps), D_UPW(w_lorentz), lam, &
+ agxx, agxy, agxz, agyy, agyz, agzz, &
+ uxx, D_UPW(alp), D_UPW(beta))
+ l_ev_l(i)=lam(1)
+ l_ev_r(i)=lam(5)
+ xwind(i) = (lam(1) + lam(5)) / (abs(lam(1)) + abs(lam(5)))
+ xwind(i) = min(1.d0, max(-1.d0, xwind(i)))
#define LEFTPLUS(x,xplus) xplus(i) = abs(xwind(i)) * LEFT1(x) + \
- (1.d0-abs(xwind(i))) * xplus(i)
+ (1.d0-abs(xwind(i))) * xplus(i)
#define LEFTMINUS(x,xminus) xminus(i+1)= abs(xwind(i)) * LEFT1(x) + \
- (1.d0-abs(xwind(i))) * xminus(i+1)
+ (1.d0-abs(xwind(i))) * xminus(i+1)
#define RIGHTPLUS(x,xplus) xplus(i) = abs(xwind(i)) * RIGHT1(x) + \
- (1.d0-abs(xwind(i))) * xplus(i)
+ (1.d0-abs(xwind(i))) * xplus(i)
#define RIGHTMINUS(x,xminus) xminus(i+1)= abs(xwind(i)) * RIGHT1(x) + \
- (1.d0-abs(xwind(i))) * xminus(i+1)
+ (1.d0-abs(xwind(i))) * xminus(i+1)
#define CHECK(x,xc) if (x(i+1) .gt. x(i)) then && xc=min(x(i+1),max(x(i),xc)) && else && xc=min(x(i),max(x(i+1),xc)) && endif
-!!$ xwind(i)=0.d0
- if (xwind(i) .lt. 0.0d0) then
- LEFTPLUS(rho, rhoplus)
- LEFTMINUS(rho, rhominus)
- LEFTPLUS(velx, velxplus)
- LEFTMINUS(velx, velxminus)
- LEFTPLUS(vely, velyplus)
- LEFTMINUS(vely, velyminus)
- LEFTPLUS(velz, velzplus)
- LEFTMINUS(velz, velzminus)
- if (poly .eq. 0) then
- LEFTPLUS(eps, epsplus)
- LEFTMINUS(eps, epsminus)
- end if
- else
- RIGHTPLUS(rho, rhoplus)
- RIGHTMINUS(rho, rhominus)
- RIGHTPLUS(velx, velxplus)
- RIGHTMINUS(velx, velxminus)
- RIGHTPLUS(vely, velyplus)
- RIGHTMINUS(vely, velyminus)
- RIGHTPLUS(velz, velzplus)
- RIGHTMINUS(velz, velzminus)
- if (poly .eq. 0) then
- RIGHTPLUS(eps, epsplus)
- RIGHTMINUS(eps, epsminus)
- end if
- end if
- CHECK(rho, rhoplus(i))
- CHECK(rho, rhominus(i+1))
- CHECK(velx, velxplus(i))
- CHECK(velx, velxminus(i+1))
- CHECK(vely, velyplus(i))
- CHECK(vely, velyminus(i+1))
- CHECK(velz, velzplus(i))
- CHECK(velz, velzminus(i+1))
- if (poly .eq. 0) then
- CHECK(eps, epsplus(i))
- CHECK(eps, epsminus(i+1))
+ !!$ xwind(i)=0.d0
+ if (xwind(i) .lt. 0.0d0) then
+ LEFTPLUS(rho, rhoplus)
+ LEFTMINUS(rho, rhominus)
+ LEFTPLUS(velx, velxplus)
+ LEFTMINUS(velx, velxminus)
+ LEFTPLUS(vely, velyplus)
+ LEFTMINUS(vely, velyminus)
+ LEFTPLUS(velz, velzplus)
+ LEFTMINUS(velz, velzminus)
+ if (poly .eq. 0) then
+ LEFTPLUS(eps, epsplus)
+ LEFTMINUS(eps, epsminus)
+ end if
+ else
+ RIGHTPLUS(rho, rhoplus)
+ RIGHTMINUS(rho, rhominus)
+ RIGHTPLUS(velx, velxplus)
+ RIGHTMINUS(velx, velxminus)
+ RIGHTPLUS(vely, velyplus)
+ RIGHTMINUS(vely, velyminus)
+ RIGHTPLUS(velz, velzplus)
+ RIGHTMINUS(velz, velzminus)
+ if (poly .eq. 0) then
+ RIGHTPLUS(eps, epsplus)
+ RIGHTMINUS(eps, epsminus)
+ end if
+ end if
+ CHECK(rho, rhoplus(i))
+ CHECK(rho, rhominus(i+1))
+ CHECK(velx, velxplus(i))
+ CHECK(velx, velxminus(i+1))
+ CHECK(vely, velyplus(i))
+ CHECK(vely, velyminus(i+1))
+ CHECK(velz, velzplus(i))
+ CHECK(velz, velzminus(i+1))
+ if (poly .eq. 0) then
+ CHECK(eps, epsplus(i))
+ CHECK(eps, epsminus(i+1))
+ end if
+ !!$ if ((dir .eq. 1) .and. (ni .eq. 4) .and. (nj .eq. 4)) then
+ !!$ write (*,*) rhoplus(i), rhominus(i+1)
+ !!$ end if
+ end do
+ !!$ mppm debug output
+ if (ppm_mppm_debug_eigenvalues .gt. 0) then
+ if (dir .eq. 1) then
+ ev_l(:,ni,nj) = l_ev_l
+ ev_r(:,ni,nj) = l_ev_r
+ xw(:,ni,nj) = xwind
+ else if (dir .eq. 2) then
+ ev_l(ni,:,nj) = l_ev_l
+ ev_r(ni,:,nj) = l_ev_r
+ xw(ni,:,nj) = xwind
+ else if (dir .eq. 3) then
+ ev_l(ni,nj,:) = l_ev_l
+ ev_r(ni,nj,:) = l_ev_r
+ xw(ni,nj,:) = xwind
+ else
+ write (*,*) "flux direction not 1 to 3 ?"
+ end if
end if
-!!$ if ((dir .eq. 1) .and. (ni .eq. 4) .and. (nj .eq. 4)) then
-!!$ write (*,*) rhoplus(i), rhominus(i+1)
-!!$ end if
- end do
- !!$ mppm debug output
- if (ppm_mppm_debug_eigenvalues .gt. 0) then
- if (dir .eq. 1) then
- ev_l(:,ni,nj) = l_ev_l
- ev_r(:,ni,nj) = l_ev_r
- xw(:,ni,nj) = xwind
- else if (dir .eq. 2) then
- ev_l(ni,:,nj) = l_ev_l
- ev_r(ni,:,nj) = l_ev_r
- xw(ni,:,nj) = xwind
- else if (dir .eq. 3) then
- ev_l(ni,nj,:) = l_ev_l
- ev_r(ni,nj,:) = l_ev_r
- xw(ni,nj,:) = xwind
- else
- write (*,*) "flux direction not 1 to 3 ?"
- end if
- end if
+ end if
end if
!!$ Zone flattening. See appendix of C&W, p. 197-8.
-
do i = 3, nx - 2
dpress2 = press(i+2) - press(i-2)
dvel = velx(i+1) - velx(i-1)
@@ -320,54 +446,53 @@ trivial_rp = .true.
end do
-
- if (PPM3) then !!$ Implement C&W, page 197, but with a workaround which allows to use stencil=3.
- do i = 3, nx - 2
- flatten = tilde_flatten(i)
- if (abs(1.d0 - flatten) > 0.d0) then
- trivial_rp(i-1) = .false.
- trivial_rp(i) = .false.
- end if
- rhoplus(i) = flatten * rhoplus(i) + (1.d0 - flatten) * rho(i)
- rhominus(i) = flatten * rhominus(i) + (1.d0 - flatten) * rho(i)
- velxplus(i) = flatten * velxplus(i) + (1.d0 - flatten) * velx(i)
- velxminus(i) = flatten * velxminus(i) + (1.d0 - flatten) * velx(i)
- velyplus(i) = flatten * velyplus(i) + (1.d0 - flatten) * vely(i)
- velyminus(i) = flatten * velyminus(i) + (1.d0 - flatten) * vely(i)
- velzplus(i) = flatten * velzplus(i) + (1.d0 - flatten) * velz(i)
- velzminus(i) = flatten * velzminus(i) + (1.d0 - flatten) * velz(i)
- if (poly .eq. 0) then
- epsplus(i) = flatten * epsplus(i) + (1.d0 - flatten) * eps(i)
- epsminus(i) = flatten * epsminus(i) + (1.d0 - flatten) * eps(i)
+ if (use_enhanced_ppm .eq. 0) then
+ ! In 1984 PPM, flattening is applied before constraining parabolic profiles.
+ if (PPM3) then !!$ Implement C&W, page 197, but with a workaround which allows to use stencil=3.
+ do i = 3, nx - 2
+ flatten = tilde_flatten(i)
+ if (abs(1.d0 - flatten) > 0.d0) then
+ trivial_rp(i-1) = .false.
+ trivial_rp(i) = .false.
+ end if
+ rhoplus(i) = flatten * rhoplus(i) + (1.d0 - flatten) * rho(i)
+ rhominus(i) = flatten * rhominus(i) + (1.d0 - flatten) * rho(i)
+ velxplus(i) = flatten * velxplus(i) + (1.d0 - flatten) * velx(i)
+ velxminus(i) = flatten * velxminus(i) + (1.d0 - flatten) * velx(i)
+ velyplus(i) = flatten * velyplus(i) + (1.d0 - flatten) * vely(i)
+ velyminus(i) = flatten * velyminus(i) + (1.d0 - flatten) * vely(i)
+ velzplus(i) = flatten * velzplus(i) + (1.d0 - flatten) * velz(i)
+ velzminus(i) = flatten * velzminus(i) + (1.d0 - flatten) * velz(i)
+ if (poly .eq. 0) then
+ epsplus(i) = flatten * epsplus(i) + (1.d0 - flatten) * eps(i)
+ epsminus(i) = flatten * epsminus(i) + (1.d0 - flatten) * eps(i)
+ end if
+ end do
+ else !!$ Really implement C&W, page 197; which requires stencil 4.
+ do i = 4, nx - 3
+ s=sign(1.d0, -dpress(i))
+ flatten = max(tilde_flatten(i), tilde_flatten(i+s))
+ if (abs(1.d0 - flatten) > 0.d0) then
+ trivial_rp(i-1) = .false.
+ trivial_rp(i) = .false.
+ end if
+ rhoplus(i) = flatten * rhoplus(i) + (1.d0 - flatten) * rho(i)
+ rhominus(i) = flatten * rhominus(i) + (1.d0 - flatten) * rho(i)
+ velxplus(i) = flatten * velxplus(i) + (1.d0 - flatten) * velx(i)
+ velxminus(i) = flatten * velxminus(i) + (1.d0 - flatten) * velx(i)
+ velyplus(i) = flatten * velyplus(i) + (1.d0 - flatten) * vely(i)
+ velyminus(i) = flatten * velyminus(i) + (1.d0 - flatten) * vely(i)
+ velzplus(i) = flatten * velzplus(i) + (1.d0 - flatten) * velz(i)
+ velzminus(i) = flatten * velzminus(i) + (1.d0 - flatten) * velz(i)
+ if (poly .eq. 0) then
+ epsplus(i) = flatten * epsplus(i) + (1.d0 - flatten) * eps(i)
+ epsminus(i) = flatten * epsminus(i) + (1.d0 - flatten) * eps(i)
+ end if
+ end do
end if
- end do
- else !!$ Really implement C&W, page 197; which requires stencil 4.
- do i = 4, nx - 3
- s=sign(1.d0, -dpress(i))
- flatten = max(tilde_flatten(i), tilde_flatten(i+s))
- if (abs(1.d0 - flatten) > 0.d0) then
- trivial_rp(i-1) = .false.
- trivial_rp(i) = .false.
- end if
- rhoplus(i) = flatten * rhoplus(i) + (1.d0 - flatten) * rho(i)
- rhominus(i) = flatten * rhominus(i) + (1.d0 - flatten) * rho(i)
- velxplus(i) = flatten * velxplus(i) + (1.d0 - flatten) * velx(i)
- velxminus(i) = flatten * velxminus(i) + (1.d0 - flatten) * velx(i)
- velyplus(i) = flatten * velyplus(i) + (1.d0 - flatten) * vely(i)
- velyminus(i) = flatten * velyminus(i) + (1.d0 - flatten) * vely(i)
- velzplus(i) = flatten * velzplus(i) + (1.d0 - flatten) * velz(i)
- velzminus(i) = flatten * velzminus(i) + (1.d0 - flatten) * velz(i)
- if (poly .eq. 0) then
- epsplus(i) = flatten * epsplus(i) + (1.d0 - flatten) * eps(i)
- epsminus(i) = flatten * epsminus(i) + (1.d0 - flatten) * eps(i)
- end if
- end do
- end if
-
+ endif
!!$ Monotonicity. See (1.10) of C&W.
-
-do i = GRHydro_stencil, nx - GRHydro_stencil + 1
#define MON(xminus,x,xplus) \
if (.not.( (xplus(i).eq.x(i)) .and. (x(i).eq.xminus(i)) ) \
.and. ((xplus(i)-x(i))*(x(i)-xminus(i)) .le. 0.d0)) then&&\
@@ -393,16 +518,197 @@ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
trivial_rp(i) = .false. &&\
end if
- MON(rhominus,rho,rhoplus)
- MON(velxminus,velx,velxplus)
- MON(velyminus,vely,velyplus)
- MON(velzminus,velz,velzplus)
- end do
- if (poly .eq. 0) then
- do i = GRHydro_stencil, nx - GRHydro_stencil + 1
- MON(epsminus,eps,epsplus)
- end do
- end if
+!! Monotonicity of PPM 2011 (McCorquodale & Colella 2011), Sec. 2.4.1, Eq. 23-34
+!! This requires 4 stencil points.
+#define MON_WITH_LOCAL_EXTREMUM_STENCIL4(aminus, a, aplus, C, C3) \
+ daplus = aplus(i)-a(i) &&\
+ daminus = a(i)-aminus(i) &&\
+ if (daplus*daminus .le. 0 .or. (a(i-2)-a(i))*(a(i)-a(i+2)) .le. 0) then &&\
+ D2a = - (12.0d0*a(i) - 6.0d0*(aminus(i)+aplus(i))) && \
+ D2aC = a(i-1) - 2.0d0*a(i) + a(i+1) &&\
+ D2aL = a(i-2) - 2.0d0*a(i-1) + a(i) &&\
+ D2aLL = a(i-3) - 2.0d0*a(i-2) + a(i-1) &&\
+ D2aR = a(i) - 2.0d0*a(i+1) + a(i+2) &&\
+ D2aRR = a(i+1) - 2.0d0*a(i+2) + a(i+3) &&\
+ D3a = D2aR - D2aC &&\
+ D3aL = D2aC - D2aL &&\
+ D3aR = D2aRR - D2aR &&\
+ D3aLL = D2aL - D2aLL &&\
+ if (sign(1.0d0, D2a) .eq. sign(1.0d0, D2aC) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aL) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aR)) then &&\
+ D2aLim = sign(1.0d0, D2a) * min(C*abs(D2aL), C*abs(D2aR), C*abs(D2aC), abs(D2a)) &&\
+ else &&\
+ D2aLim = 0 &&\
+ end if &&\
+ if (abs(D2a) .le. 1.d-12*max(abs(a(i-2)), abs(a(i-1)), abs(a(i)), abs(a(i+1)), abs(a(i+2)))) then &&\
+ rhi = 0 &&\
+ else &&\
+ rhi = D2aLim / D2a &&\
+ endif &&\
+ if (.not. (rhi .ge. 1.0d0 - 1.d-12)) then &&\
+ D3aMin = min(D3aLL, D3aL, D3a, D3aR) &&\
+ D3aMax = max(D3aLL, D3aL, D3a, D3aR) &&\
+ if (C3 * max(abs(D3aMin), abs(D3aMax)) .le. D3aMax-D3aMin) then &&\
+ if (daplus*daminus .lt. 0) then &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(1.0d0-rhi)*daplus - rhi*daminus &&\
+ else if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) + 2.0d0*(1.0d0-rhi)*daminus + rhi*daplus &&\
+ else &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ endif &&\
+ endif &&\
+ endif &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ else &&\
+ if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) - 2.0d0*(aminus(i) - a(i)) &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(aplus(i) - a(i)) &&\
+ end if &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ endif
+
+
+!! Monotonicity of PPM 2011 (McCorquodale & Colella 2011), Sec. 2.4.1, Eq. 23-34.
+!! This does not use the check for deviations from a cubic. Thus, it gets away with only 3 stencil points!
+#define MON_WITH_LOCAL_EXTREMUM(aminus, a, aplus, C) \
+ daplus = aplus(i)-a(i) &&\
+ daminus = a(i)-aminus(i) &&\
+ if (daplus*daminus .le. 0 .or. (a(i-2)-a(i))*(a(i)-a(i+2)) .le. 0) then &&\
+ D2a = - (12.0d0*a(i) - 6.0d0*(aminus(i)+aplus(i))) && \
+ D2aC = a(i-1) - 2.0d0*a(i) + a(i+1) &&\
+ D2aL = a(i-2) - 2.0d0*a(i-1) + a(i) &&\
+ D2aR = a(i) - 2.0d0*a(i+1) + a(i+2) &&\
+ if (sign(1.0d0, D2a) .eq. sign(1.0d0, D2aC) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aL) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aR)) then &&\
+ D2aLim = sign(1.0d0, D2a) * min(C*abs(D2aL), C*abs(D2aR), C*abs(D2aC), abs(D2a)) &&\
+ else &&\
+ D2aLim = 0 &&\
+ end if &&\
+ if (abs(D2a) .le. 1.d-12*max(abs(a(i-2)), abs(a(i-1)), abs(a(i)), abs(a(i+1)), abs(a(i+2)))) then &&\
+ rhi = 0 &&\
+ else &&\
+ rhi = D2aLim / D2a &&\
+ endif &&\
+ if (.not. (rhi .ge. 1.0d0 - 1.d-12)) then &&\
+ if (daplus*daminus .lt. 0) then &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(1.0d0-rhi)*daplus - rhi*daminus &&\
+ else if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) + 2.0d0*(1.0d0-rhi)*daminus + rhi*daplus &&\
+ else &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ endif &&\
+ endif &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ else &&\
+ if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) - 2.0d0*(aminus(i) - a(i)) &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(aplus(i) - a(i)) &&\
+ end if &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ endif
+
+ if (use_enhanced_ppm .eq. 1) then
+ !! Constrain parabolic profiles, PPM 2011/2008
+ if (PPM3) then
+ do i = 3, nx - 2
+ MON_WITH_LOCAL_EXTREMUM(rhominus,rho,rhoplus, enhanced_ppm_C2)
+ MON_WITH_LOCAL_EXTREMUM(velxminus,velx,velxplus, enhanced_ppm_C2)
+ MON_WITH_LOCAL_EXTREMUM(velyminus,vely,velyplus, enhanced_ppm_C2)
+ MON_WITH_LOCAL_EXTREMUM(velzminus,velz,velzplus, enhanced_ppm_C2)
+ end do
+ if (poly .eq. 0) then
+ do i = 3, nx - 2
+ MON_WITH_LOCAL_EXTREMUM(epsminus,eps,epsplus, enhanced_ppm_C2)
+ end do
+ end if
+
+ else
+ do i = 4, nx - 3
+ MON_WITH_LOCAL_EXTREMUM_STENCIL4(rhominus,rho,rhoplus, enhanced_ppm_C2, enhanced_ppm_C3)
+ MON_WITH_LOCAL_EXTREMUM_STENCIL4(velxminus,velx,velxplus, enhanced_ppm_C2, enhanced_ppm_C3)
+ MON_WITH_LOCAL_EXTREMUM_STENCIL4(velyminus,vely,velyplus, enhanced_ppm_C2, enhanced_ppm_C3)
+ MON_WITH_LOCAL_EXTREMUM_STENCIL4(velzminus,velz,velzplus, enhanced_ppm_C2, enhanced_ppm_C3)
+ end do
+ if (poly .eq. 0) then
+ do i = 4, nx - 3
+ MON_WITH_LOCAL_EXTREMUM_STENCIL4(epsminus,eps,epsplus, enhanced_ppm_C2, enhanced_ppm_C3)
+ end do
+ endif
+
+ ! Apply flattening after constraining the parabolic profiles
+ if (PPM3) then !!$ Implement C&W, page 197, but with a workaround which allows to use stencil=3.
+ do i = 3, nx - 2
+ flatten = tilde_flatten(i)
+ if (abs(1.d0 - flatten) > 0.d0) then
+ trivial_rp(i-1) = .false.
+ trivial_rp(i) = .false.
+ end if
+ rhoplus(i) = flatten * rhoplus(i) + (1.d0 - flatten) * rho(i)
+ rhominus(i) = flatten * rhominus(i) + (1.d0 - flatten) * rho(i)
+ velxplus(i) = flatten * velxplus(i) + (1.d0 - flatten) * velx(i)
+ velxminus(i) = flatten * velxminus(i) + (1.d0 - flatten) * velx(i)
+ velyplus(i) = flatten * velyplus(i) + (1.d0 - flatten) * vely(i)
+ velyminus(i) = flatten * velyminus(i) + (1.d0 - flatten) * vely(i)
+ velzplus(i) = flatten * velzplus(i) + (1.d0 - flatten) * velz(i)
+ velzminus(i) = flatten * velzminus(i) + (1.d0 - flatten) * velz(i)
+ if (poly .eq. 0) then
+ epsplus(i) = flatten * epsplus(i) + (1.d0 - flatten) * eps(i)
+ epsminus(i) = flatten * epsminus(i) + (1.d0 - flatten) * eps(i)
+ end if
+ end do
+ else !!$ Really implement C&W, page 197; which requires stencil 4.
+ do i = 4, nx - 3
+ s=sign(1.d0, -dpress(i))
+ flatten = max(tilde_flatten(i), tilde_flatten(i+s))
+ if (abs(1.d0 - flatten) > 0.d0) then
+ trivial_rp(i-1) = .false.
+ trivial_rp(i) = .false.
+ end if
+ rhoplus(i) = flatten * rhoplus(i) + (1.d0 - flatten) * rho(i)
+ rhominus(i) = flatten * rhominus(i) + (1.d0 - flatten) * rho(i)
+ velxplus(i) = flatten * velxplus(i) + (1.d0 - flatten) * velx(i)
+ velxminus(i) = flatten * velxminus(i) + (1.d0 - flatten) * velx(i)
+ velyplus(i) = flatten * velyplus(i) + (1.d0 - flatten) * vely(i)
+ velyminus(i) = flatten * velyminus(i) + (1.d0 - flatten) * vely(i)
+ velzplus(i) = flatten * velzplus(i) + (1.d0 - flatten) * velz(i)
+ velzminus(i) = flatten * velzminus(i) + (1.d0 - flatten) * velz(i)
+ if (poly .eq. 0) then
+ epsplus(i) = flatten * epsplus(i) + (1.d0 - flatten) * eps(i)
+ epsminus(i) = flatten * epsminus(i) + (1.d0 - flatten) * eps(i)
+ end if
+ end do
+ end if
+
+ endif
+ endif
+
+ if (use_enhanced_ppm .eq. 0) then
+ !! Constrain parabolic profiles, PPM 1984
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+ ! original Colella&Woodward monotonicity preservation
+ MON(rhominus,rho,rhoplus)
+ MON(velxminus,velx,velxplus)
+ MON(velyminus,vely,velyplus)
+ MON(velzminus,velz,velzplus)
+ end do
+ if (poly .eq. 0) then
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+ MON(epsminus,eps,epsplus)
+ end do
+ end if
+ endif
if (check_for_trivial_rp .eq. 0) then
trivial_rp = .false.
@@ -747,45 +1053,107 @@ subroutine SimplePPM_ye_1d(nx,dx,rho,velx,vely,velz, &
CCTK_REAL :: dpress2,w,flatten,dvel
CCTK_REAL :: eta, etatilde
-!!$ Average slopes delta_m(a). See (1.7) of Colella and Woodward, p.178
-!!$ This is the expression for an even grid.
-
+ CCTK_REAL :: D2a, D2aL, D2aR, D2aC, D2aLim, rhi, threshold, rho_min, daplus, daminus, D3a, D3aLL, D3aL, D3aR, D2aLL, D2aRR, D3aMin, D3aMax
+
do i = 2, nx - 1
- dpress(i) = press(i+1) - press(i-1)
+ dpress(i) = press(i+1) - press(i-1)
end do
- do i = 2, nx - 1
- dY_e(i) = 0.5d0 * (Y_e(i+1) - Y_e(i-1))
-! d2Y_e(i,iY_e) = (Y_e(i+1) - 2.d0 * Y_e(i) + Y_e(i-1))! / 6.d0 / dx / dx
-! ! since we use d2Y_e only for the condition d2Y_e(i+1)*d2Y_e(i-1)<0
-! ! the denominator is not necessary
- enddo
-
-
-!!$ Steepened slope. See (1.8) of Colella and Woodward, p.178
-
- do i = 2, nx - 1
- if( (Y_e(i+1) - Y_e(i)) * &
- (Y_e(i) - Y_e(i-1)) > 0.0d0 ) then
- dmY_e(i) = sign(1.0d0,dY_e(i)) * &
- min(abs(dY_e(i)), 2.0d0 * &
- abs(Y_e(i) - Y_e(i-1)), &
- 2.0d0 * abs(Y_e(i+1) - Y_e(i)))
- else
- dmY_e(i) = 0.0d0
- endif
- end do
+
+ if (use_enhanced_PPM .eq. 0) then
+
+ !!$ Average slopes delta_m(a). See (1.7) of Colella and Woodward, p.178
+ !!$ This is the expression for an even grid.
+
+
+ do i = 2, nx - 1
+ dY_e(i) = 0.5d0 * (Y_e(i+1) - Y_e(i-1))
+ ! d2Y_e(i,iY_e) = (Y_e(i+1) - 2.d0 * Y_e(i) + Y_e(i-1))! / 6.d0 / dx / dx
+ ! ! since we use d2Y_e only for the condition d2Y_e(i+1)*d2Y_e(i-1)<0
+ ! ! the denominator is not necessary
+ enddo
+
+
+ !!$ Steepened slope. See (1.8) of Colella and Woodward, p.178
+
+ do i = 2, nx - 1
+ if( (Y_e(i+1) - Y_e(i)) * &
+ (Y_e(i) - Y_e(i-1)) > 0.0d0 ) then
+ dmY_e(i) = sign(1.0d0,dY_e(i)) * &
+ min(abs(dY_e(i)), 2.0d0 * &
+ abs(Y_e(i) - Y_e(i-1)), &
+ 2.0d0 * abs(Y_e(i+1) - Y_e(i)))
+ else
+ dmY_e(i) = 0.0d0
+ endif
+ end do
+
+ !!$ Initial boundary states. See (1.9) of Colella and Woodward, p.178
+
+ do i = 2, nx - 2
+ Y_e_plus(i) = 0.5d0 * (Y_e(i) + Y_e(i+1)) + &
+ (dmY_e(i) - dmY_e(i+1)) / 6.d0
+ Y_e_minus(i+1) = Y_e_plus(i)
+ enddo
+ else
+!! This is the modified PPM algorithm by Colella & Sekora 2008.
+!! This uses a better limiter based on second derivatives that preserves
+!! accuracy at local extrema. It also uses a higher-order interpolation polynomial.
+
+
+ !!$ Initial boundary states (sixth order accurate). See (17) of Colella and Sekora, p.7071
+#undef APPROX_AT_CELL_INTERFACE_STENCIL4
+!!$ Initial boundary states (sixth order accurate). See (17) of Colella and Sekora 2008, p.7071
+#define APPROX_AT_CELL_INTERFACE_STENCIL4(a, ah) \
+ ah = 37.0d0/60.0d0*(a(i)+a(i+1)) - 2.0d0/15.0d0*(a(i-1)+a(i+2)) + 1.0d0/60.0d0*(a(i-2)+a(i+3))
+
+#undef APPROX_AT_CELL_INTERFACE
+ !!$ Initial boundary states (4th order accurate). See (16) of Colella and Sekora 2008, p.7071
+#define APPROX_AT_CELL_INTERFACE(a, ah) \
+ ah = 7.0d0/12.0d0*(a(i)+a(i+1)) - 1.0d0/12.0d0*(a(i-1)+a(i+2))
+
+
+#undef LIMIT
+#define LIMIT(a,ah,C, alim) \
+ if ((min(a(i),a(i+1)) .le. ah) .and. (ah .le. max(a(i),a(i+1)))) then &&\
+ alim = ah &&\
+ else &&\
+ D2a = 3.0d0 * (a(i) - 2.0d0*ah + a(i+1)) &&\
+ D2aL = (a(i-1) - 2.0d0*a(i) + a(i+1)) &&\
+ D2aR = (a(i) - 2.0d0*a(i+1) + a(i+2)) &&\
+ if (D2a*D2aR .ge. 0 .and. D2a*D2aL .ge. 0) then &&\
+ alim = 0.5d0*(a(i)+a(i+1)) - sign(1.0d0, D2a)*min(C*abs(D2aL), C*abs(D2aR), abs(D2a))/3.0d0 &&\
+ else &&\
+ alim = 0.5d0*(a(i)+a(i+1)) &&\
+ end if &&\
+ endif
+
+ if (PPM3) then
+ !! We initialize "plus" \equiv a_j+1/2 with (16) via APPROX_AT_CELL_INTERFACE,
+ !! then checking for (13) of Colella & Sekora 2008 and applying
+ !! (18) and (19) if (13) is not satisfied. This is done with LIMIT.
+ !! There, we also switch to lower order if we are near atmosphere values.
+ do i = 2, nx-2
+ APPROX_AT_CELL_INTERFACE(Y_e, Y_e_plus(i))
+ LIMIT(Y_e, Y_e_plus(i), enhanced_ppm_C2, Y_e_plus(i))
+ Y_e_minus(i+1) = Y_e_plus(i)
+ end do
+
+ else
-!!$ Initial boundary states. See (1.9) of Colella and Woodward, p.178
+ !! Same as above but for 4 stencil points using (17) of Colella & Sekora 2008 as
+ !! initial states.
+ do i = 3, nx-3
+ APPROX_AT_CELL_INTERFACE_STENCIL4(Y_e, Y_e_plus(i))
+ LIMIT(Y_e, Y_e_plus(i), enhanced_ppm_C2, Y_e_plus(i))
+ Y_e_minus(i+1) = Y_e_plus(i)
+ end do
+ endif
+
+ end if
- do i = 2, nx - 2
- Y_e_plus(i) = 0.5d0 * (Y_e(i) + Y_e(i+1)) + &
- (dmY_e(i) - dmY_e(i+1)) / 6.d0
- Y_e_minus(i+1) = Y_e_plus(i)
- enddo
-
!!$Discontinuity steepening. See (1.14-17) of C&W.
!!$This is the detect routine which mat be activated with the ppm_detect parameter
@@ -814,68 +1182,173 @@ subroutine SimplePPM_ye_1d(nx,dx,rho,velx,vely,velz, &
end if
end do
- if (PPM3) then
- do i = 3, nx - 2
- flatten = tilde_flatten(i)
- Y_e_plus(i) = flatten * Y_e_plus(i) &
- + (1.d0 - flatten) * Y_e(i)
- Y_e_minus(i) = flatten * Y_e_minus(i) &
- + (1.d0 - flatten) * Y_e(i)
- end do
- else !!$ Really implement C&W, page 197; which requires stencil 4.
- do i = 4, nx - 3
- s=sign(1.d0, -dpress(i))
- flatten = max(tilde_flatten(i), tilde_flatten(i+s))
- Y_e_plus(i) = flatten * Y_e_plus(i) + &
- (1.d0 - flatten) * Y_e(i)
- Y_e_minus(i) = flatten * Y_e_minus(i) &
- + (1.d0 - flatten) * Y_e(i)
- end do
+ if (use_enhanced_ppm .eq. 0) then
+ if (PPM3) then
+ do i = 3, nx - 2
+ flatten = tilde_flatten(i)
+ Y_e_plus(i) = flatten * Y_e_plus(i) &
+ + (1.d0 - flatten) * Y_e(i)
+ Y_e_minus(i) = flatten * Y_e_minus(i) &
+ + (1.d0 - flatten) * Y_e(i)
+ end do
+ else !!$ Really implement C&W, page 197; which requires stencil 4.
+ do i = 4, nx - 3
+ s=sign(1.d0, -dpress(i))
+ flatten = max(tilde_flatten(i), tilde_flatten(i+s))
+ Y_e_plus(i) = flatten * Y_e_plus(i) + &
+ (1.d0 - flatten) * Y_e(i)
+ Y_e_minus(i) = flatten * Y_e_minus(i) &
+ + (1.d0 - flatten) * Y_e(i)
+ end do
+ end if
+ endif
+
+#undef MON_WITH_LOCAL_EXTREMUM_STENCIL4
+!! Monotonicity of PPM 2011 (McCorquodale & Colella 2011), Sec. 2.4.1, Eq. 23-34
+!! This requires 4 stencil points.
+#define MON_WITH_LOCAL_EXTREMUM_STENCIL4(aminus, a, aplus, C, C3) \
+ daplus = aplus(i)-a(i) &&\
+ daminus = a(i)-aminus(i) &&\
+ if (daplus*daminus .le. 0 .or. (a(i-2)-a(i))*(a(i)-a(i+2)) .le. 0) then &&\
+ D2a = - (12.0d0*a(i) - 6.0d0*(aminus(i)+aplus(i))) && \
+ D2aC = a(i-1) - 2.0d0*a(i) + a(i+1) &&\
+ D2aL = a(i-2) - 2.0d0*a(i-1) + a(i) &&\
+ D2aLL = a(i-3) - 2.0d0*a(i-2) + a(i-1) &&\
+ D2aR = a(i) - 2.0d0*a(i+1) + a(i+2) &&\
+ D2aRR = a(i+1) - 2.0d0*a(i+2) + a(i+3) &&\
+ D3a = D2aR - D2aC &&\
+ D3aL = D2aC - D2aL &&\
+ D3aR = D2aRR - D2aR &&\
+ D3aLL = D2aL - D2aLL &&\
+ if (sign(1.0d0, D2a) .eq. sign(1.0d0, D2aC) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aL) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aR)) then &&\
+ D2aLim = sign(1.0d0, D2a) * min(C*abs(D2aL), C*abs(D2aR), C*abs(D2aC), abs(D2a)) &&\
+ else &&\
+ D2aLim = 0 &&\
+ end if &&\
+ if (abs(D2a) .le. 1.d-12*max(abs(a(i-2)), abs(a(i-1)), abs(a(i)), abs(a(i+1)), abs(a(i+2)))) then &&\
+ rhi = 0 &&\
+ else &&\
+ rhi = D2aLim / D2a &&\
+ endif &&\
+ if (.not. (rhi .ge. 1.0d0 - 1.d-12)) then &&\
+ D3aMin = min(D3aLL, D3aL, D3a, D3aR) &&\
+ D3aMax = max(D3aLL, D3aL, D3a, D3aR) &&\
+ if (C3 * max(abs(D3aMin), abs(D3aMax)) .le. D3aMax-D3aMin) then &&\
+ if (daplus*daminus .lt. 0) then &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(1.0d0-rhi)*daplus - rhi*daminus &&\
+ else if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) + 2.0d0*(1.0d0-rhi)*daminus + rhi*daplus &&\
+ else &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ endif &&\
+ endif &&\
+ endif &&\
+ else &&\
+ if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) - 2.0d0*(aminus(i) - a(i)) &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(aplus(i) - a(i)) &&\
+ end if &&\
+ endif
+
+
+#undef MON_WITH_LOCAL_EXTREMUM
+!! Monotonicity of PPM 2011 (McCorquodale & Colella 2011), Sec. 2.4.1, Eq. 23-34.
+!! This does not use the check for deviations from a cubic. Thus, it gets away with only 3 stencil points!
+#define MON_WITH_LOCAL_EXTREMUM(aminus, a, aplus, C) \
+ daplus = aplus(i)-a(i) &&\
+ daminus = a(i)-aminus(i) &&\
+ if (daplus*daminus .le. 0 .or. (a(i-2)-a(i))*(a(i)-a(i+2)) .le. 0) then &&\
+ D2a = - (12.0d0*a(i) - 6.0d0*(aminus(i)+aplus(i))) && \
+ D2aC = a(i-1) - 2.0d0*a(i) + a(i+1) &&\
+ D2aL = a(i-2) - 2.0d0*a(i-1) + a(i) &&\
+ D2aR = a(i) - 2.0d0*a(i+1) + a(i+2) &&\
+ if (sign(1.0d0, D2a) .eq. sign(1.0d0, D2aC) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aL) .and. sign(1.0d0, D2a) .eq. sign(1.0d0, D2aR)) then &&\
+ D2aLim = sign(1.0d0, D2a) * min(C*abs(D2aL), C*abs(D2aR), C*abs(D2aC), abs(D2a)) &&\
+ else &&\
+ D2aLim = 0 &&\
+ end if &&\
+ if (abs(D2a) .le. 1.d-12*max(abs(a(i-2)), abs(a(i-1)), abs(a(i)), abs(a(i+1)), abs(a(i+2)))) then &&\
+ rhi = 0 &&\
+ else &&\
+ rhi = D2aLim / D2a &&\
+ endif &&\
+ if (.not. (rhi .ge. 1.0d0 - 1.d-12)) then &&\
+ if (daplus*daminus .lt. 0) then &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(1.0d0-rhi)*daplus - rhi*daminus &&\
+ else if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) + 2.0d0*(1.0d0-rhi)*daminus + rhi*daplus &&\
+ else &&\
+ aplus(i) = a(i) + daplus * rhi &&\
+ aminus(i) = a(i) - daminus * rhi &&\
+ endif &&\
+ endif &&\
+ else &&\
+ if (abs(daplus) .ge. 2.0d0*abs(daminus)) then &&\
+ aplus(i) = a(i) - 2.0d0*(aminus(i) - a(i)) &&\
+ else if (abs(daminus) .ge. 2.0d0*abs(daplus)) then &&\
+ aminus(i) = a(i) - 2.0d0*(aplus(i) - a(i)) &&\
+ end if &&\
+ endif
+
+
+ if (use_enhanced_ppm .eq. 1) then
+ ! Constrain parabolic profiles
+ if (PPM3) then
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+ MON_WITH_LOCAL_EXTREMUM(Y_e_minus,Y_e,Y_e_plus, enhanced_ppm_C2)
+ end do
+ else
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+ MON_WITH_LOCAL_EXTREMUM_STENCIL4(Y_e_minus,Y_e,Y_e_plus, enhanced_ppm_C2, enhanced_ppm_C3)
+ end do
+ endif
+
+ ! In PPM 2011/2008, flattening is applied after constraining parabolic profiles.
+ if (PPM3) then
+ do i = 3, nx - 2
+ flatten = tilde_flatten(i)
+ Y_e_plus(i) = flatten * Y_e_plus(i) &
+ + (1.d0 - flatten) * Y_e(i)
+ Y_e_minus(i) = flatten * Y_e_minus(i) &
+ + (1.d0 - flatten) * Y_e(i)
+ end do
+ else !!$ Really implement C&W, page 197; which requires stencil 4.
+ do i = 4, nx - 3
+ s=sign(1.d0, -dpress(i))
+ flatten = max(tilde_flatten(i), tilde_flatten(i+s))
+ Y_e_plus(i) = flatten * Y_e_plus(i) + &
+ (1.d0 - flatten) * Y_e(i)
+ Y_e_minus(i) = flatten * Y_e_minus(i) &
+ + (1.d0 - flatten) * Y_e(i)
+ end do
+ end if
+
+ else
+ !!$ Monotonicity. See (1.10) of C&W.
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+ if (((Y_e_plus(i)-Y_e(i))* &
+ (Y_e(i)-Y_e_minus(i)) .le. 0.d0)) then
+ Y_e_minus(i) = Y_e(i)
+ Y_e_plus(i) = Y_e(i)
+ else if ((Y_e_plus(i) - Y_e_minus(i)) * (Y_e(i) - 0.5d0 * &
+ (Y_e_plus(i) + Y_e_minus(i))) > &
+ (Y_e_plus(i) - Y_e_minus(i))**2 / 6.d0) then
+ Y_e_minus(i) = 3.d0 * Y_e(i) - 2.0d0 * Y_e_plus(i)
+ else if ((Y_e_plus(i) - Y_e_minus(i)) * (Y_e(i) - 0.5d0 * &
+ (Y_e_plus(i) + Y_e_minus(i))) < &
+ -(Y_e_plus(i) - Y_e_minus(i))**2 / 6.0d0 ) then
+ Y_e_plus(i) = 3.d0 * Y_e(i) - 2.d0 * Y_e_minus(i)
+ end if
+ end do
end if
-!! Additional flattening a la Plewa & Mueller
- do i = 2, nx - 1
- if ( ( Y_e(i+1) - Y_e(i) ) * &
- ( Y_e(i) - Y_e(i-1) ) < 0.0d0 ) then
- Y_eflat(i) = 1.0d0
- else
- Y_eflat(i) = 0.0d0
- endif
- enddo
-
- do i = 3, nx -2
-
- Y_eflatomega = 0.5d0 * max(Y_eflat(i-1),2.0d0*Y_eflat(i), &
- Y_eflat(i+1)) * ppm_omega_tracer
-
- Y_e_plus(i) = Y_eflatomega*Y_e(i) + &
- (1.0d0 - Y_eflatomega)*Y_e_plus(i)
-
- Y_e_minus(i) = Y_eflatomega*Y_e(i) + &
- (1.0d0 - Y_eflatomega)*Y_e_minus(i)
-
- enddo
-
-
-!!$ Monotonicity. See (1.10) of C&W.
- do i = GRHydro_stencil, nx - GRHydro_stencil + 1
- if (((Y_e_plus(i)-Y_e(i))* &
- (Y_e(i)-Y_e_minus(i)) .le. 0.d0)) then
- Y_e_minus(i) = Y_e(i)
- Y_e_plus(i) = Y_e(i)
- else if ((Y_e_plus(i) - Y_e_minus(i)) * (Y_e(i) - 0.5d0 * &
- (Y_e_plus(i) + Y_e_minus(i))) > &
- (Y_e_plus(i) - Y_e_minus(i))**2 / 6.d0) then
- Y_e_minus(i) = 3.d0 * Y_e(i) - 2.d0 * Y_e_plus(i)
- else if ((Y_e_plus(i) - Y_e_minus(i)) * (Y_e(i) - 0.5d0 * &
- (Y_e_plus(i) + Y_e_minus(i))) < &
- -(Y_e_plus(i) - Y_e_minus(i))**2 / 6.d0 ) then
- Y_e_plus(i) = 3.d0 * Y_e(i) - 2.d0 * Y_e_minus(i)
- end if
- end do
-
-
-
end subroutine SimplePPM_ye_1d
-
diff --git a/src/GRHydro_PPMReconstruct_drv.F90 b/src/GRHydro_PPMReconstruct_drv.F90
index 02ab359..b074bec 100644
--- a/src/GRHydro_PPMReconstruct_drv.F90
+++ b/src/GRHydro_PPMReconstruct_drv.F90
@@ -168,7 +168,7 @@ subroutine GRHydro_PPMReconstruct_drv(CCTK_ARGUMENTS)
w_lorentz(:,j,k), &
1, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_x_left, &
GRHydro_mppm_eigenvalue_x_right, &
- GRHydro_mppm_xwind)
+ GRHydro_mppm_xwind, GRHydro_rho_min)
do i = 1, nx
if (trivial_rp(i,j,k)) then
SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
@@ -198,7 +198,7 @@ subroutine GRHydro_PPMReconstruct_drv(CCTK_ARGUMENTS)
call SimplePPM_ye_1d(nx,CCTK_DELTA_SPACE(1),rho(:,j,k), &
velx(:,j,k),vely(:,j,k),velz(:,j,k), &
Y_e(:,j,k),Y_e_minus(:,j,k),Y_e_plus(:,j,k), &
- press(:,j,k))
+ press(:,j,k), GRHydro_rho_min)
end do
end do
!$OMP END PARALLEL DO
@@ -219,7 +219,7 @@ subroutine GRHydro_PPMReconstruct_drv(CCTK_ARGUMENTS)
w_lorentz(j,:,k), &
2, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_y_left, &
GRHydro_mppm_eigenvalue_y_right, &
- GRHydro_mppm_xwind)
+ GRHydro_mppm_xwind, GRHydro_rho_min)
do i = 1, ny
if (trivial_rp(j,i,k)) then
SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, trivialy)
@@ -249,7 +249,7 @@ subroutine GRHydro_PPMReconstruct_drv(CCTK_ARGUMENTS)
call SimplePPM_ye_1d(ny,CCTK_DELTA_SPACE(2),rho(j,:,k), &
velx(j,:,k),vely(j,:,k),velz(j,:,k), &
Y_e(j,:,k),Y_e_minus(j,:,k),Y_e_plus(j,:,k), &
- press(j,:,k))
+ press(j,:,k), GRHydro_rho_min)
end do
end do
!$OMP END PARALLEL DO
@@ -270,7 +270,7 @@ subroutine GRHydro_PPMReconstruct_drv(CCTK_ARGUMENTS)
w_lorentz(j,k,:), &
3, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_z_left, &
GRHydro_mppm_eigenvalue_z_right, &
- GRHydro_mppm_xwind)
+ GRHydro_mppm_xwind, GRHydro_rho_min)
do i = 1, nz
if (trivial_rp(j,k,i)) then
SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, trivialz)
@@ -301,7 +301,7 @@ subroutine GRHydro_PPMReconstruct_drv(CCTK_ARGUMENTS)
call SimplePPM_ye_1d(nz,CCTK_DELTA_SPACE(3),rho(j,k,:), &
velx(j,k,:),vely(j,k,:),velz(j,k,:), &
Y_e(j,k,:),Y_e_minus(j,k,:),Y_e_plus(j,k,:), &
- press(j,k,:))
+ press(j,k,:), GRHydro_rho_min)
end do
end do
!$OMP END PARALLEL DO
diff --git a/src/GRHydro_Reconstruct.F90 b/src/GRHydro_Reconstruct.F90
index cbcfd48..974d320 100644
--- a/src/GRHydro_Reconstruct.F90
+++ b/src/GRHydro_Reconstruct.F90
@@ -41,6 +41,20 @@ subroutine Reconstruction(CCTK_ARGUMENTS)
CCTK_INT :: i,j,k
CCTK_REAL :: local_min_tracer
+ ! save memory when MP is not used
+ ! TARGET as to be before DECLARE_CCTK_ARGUMENTS for gcc 4.1
+ TARGET lvel, vel
+
+ ! save memory when MP is not used
+ CCTK_INT :: GRHydro_UseGeneralCoordinates
+ CCTK_REAL, DIMENSION(:,:,:,:), POINTER :: vup
+
+ if (GRHydro_UseGeneralCoordinates(cctkGH).ne.0) then
+ vup => lvel
+ else
+ vup => vel
+ end if
+
if (CCTK_EQUALS(recon_method,"tvd")) then
! this handles MHD and non-MHD
call GRHydro_TVDReconstruct_drv(CCTK_PASS_FTOF)
@@ -79,12 +93,12 @@ subroutine Reconstruction(CCTK_ARGUMENTS)
rhominus(i,j,k) = rho(i,j,k)
epsplus(i,j,k) = eps(i,j,k)
epsminus(i,j,k) = eps(i,j,k)
- velxplus(i,j,k) = vel(i,j,k,1)
- velyplus(i,j,k) = vel(i,j,k,2)
- velzplus(i,j,k) = vel(i,j,k,3)
- velxminus(i,j,k) = vel(i,j,k,1)
- velyminus(i,j,k) = vel(i,j,k,2)
- velzminus(i,j,k) = vel(i,j,k,3)
+ velxplus(i,j,k) = vup(i,j,k,1)
+ velyplus(i,j,k) = vup(i,j,k,2)
+ velzplus(i,j,k) = vup(i,j,k,3)
+ velxminus(i,j,k) = vup(i,j,k,1)
+ velyminus(i,j,k) = vup(i,j,k,2)
+ velzminus(i,j,k) = vup(i,j,k,3)
end if
if(evolve_tracer.ne.0) then
where(tracerplus(i,j,k,:).le.local_min_tracer .or. &