aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbmundim <bmundim@c83d129a-5a75-4d5a-9c4d-ed3a5855bf45>2010-09-29 21:47:21 +0000
committerbmundim <bmundim@c83d129a-5a75-4d5a-9c4d-ed3a5855bf45>2010-09-29 21:47:21 +0000
commitd95f7bc4e19ff9d991e17417b63318ea63d18491 (patch)
tree66e5076c45f9755c76392ce7b9e1151cbca39c80
parent2a6108bcba664c662dde90c1893d87a6f5e7211d (diff)
Current RIT GRMHD code contributions:
Add the magnetized counterparts for several GRHydro routines. Adjust interface.ccl, param.ccl and schedule.ccl appropriately. git-svn-id: http://svn.einsteintoolkit.org/cactus/EinsteinEvolve/GRHydro/trunk@158 c83d129a-5a75-4d5a-9c4d-ed3a5855bf45
-rw-r--r--interface.ccl43
-rw-r--r--param.ccl2
-rw-r--r--schedule.ccl590
-rw-r--r--src/GRHydro_BoundariesM.F90333
-rw-r--r--src/GRHydro_CalcUpdateM.F90247
-rw-r--r--src/GRHydro_Con2PrimM.F90912
-rw-r--r--src/GRHydro_Con2PrimM_pt.c690
-rw-r--r--src/GRHydro_EigenproblemM.F90241
-rw-r--r--src/GRHydro_FluxM.F9067
-rw-r--r--src/GRHydro_HLLEM.F90642
-rw-r--r--src/GRHydro_HLLEPolyM.F90606
-rw-r--r--src/GRHydro_InterfacesM.h84
-rw-r--r--src/GRHydro_Macros.h15
-rw-r--r--src/GRHydro_PPMM.F90820
-rw-r--r--src/GRHydro_ParamCheck.F9015
-rw-r--r--src/GRHydro_ParamCheckM.F9052
-rw-r--r--src/GRHydro_Prim2Con.F9024
-rw-r--r--src/GRHydro_Prim2ConM.F90637
-rw-r--r--src/GRHydro_ReconstructM.F90621
-rw-r--r--src/GRHydro_ReconstructPolyM.F90593
-rw-r--r--src/GRHydro_RegisterGZM.cc92
-rw-r--r--src/GRHydro_RegisterVarsM.cc107
-rw-r--r--src/GRHydro_RiemannSolveM.F90457
-rw-r--r--src/GRHydro_SourceM.F90436
-rw-r--r--src/GRHydro_TmunuM.F90166
-rw-r--r--src/GRHydro_UpdateMaskM.F90227
-rw-r--r--src/GRHydro_UtilsM.F9058
-rw-r--r--src/make.code.defn23
28 files changed, 8614 insertions, 186 deletions
diff --git a/interface.ccl b/interface.ccl
index 4cc35be..03f3c10 100644
--- a/interface.ccl
+++ b/interface.ccl
@@ -97,12 +97,40 @@ void FUNCTION Prim2ConPoly(CCTK_INT IN handle, \
CCTK_REAL IN velz, CCTK_REAL OUT epsilon, \
CCTK_REAL OUT press, CCTK_REAL OUT w_lorentz)
+void FUNCTION Prim2ConGenM(CCTK_INT IN handle, \
+ CCTK_REAL IN gxx, CCTK_REAL IN gxy, \
+ CCTK_REAL IN gxz, CCTK_REAL IN gyy, \
+ CCTK_REAL IN gyz, CCTK_REAL IN gzz, \
+ CCTK_REAL IN det, CCTK_REAL OUT dens, \
+ CCTK_REAL OUT sx, CCTK_REAL OUT sy, \
+ CCTK_REAL OUT sz, CCTK_REAL OUT tau, \
+ CCTK_REAL IN Bvecx, CCTK_REAL IN Bvecy, \
+ CCTK_REAL IN Bvecz, CCTK_REAL IN rho, CCTK_REAL IN velx, \
+ CCTK_REAL IN vely, \
+ CCTK_REAL IN velz, CCTK_REAL IN epsilon, \
+ CCTK_REAL OUT press, CCTK_REAL OUT w_lorentz)
+
+void FUNCTION Prim2ConPolyM(CCTK_INT IN handle, \
+ CCTK_REAL IN gxx, CCTK_REAL IN gxy, \
+ CCTK_REAL IN gxz, CCTK_REAL IN gyy, \
+ CCTK_REAL IN gyz, CCTK_REAL IN gzz, \
+ CCTK_REAL IN det, CCTK_REAL OUT dens, \
+ CCTK_REAL OUT sx, CCTK_REAL OUT sy, \
+ CCTK_REAL OUT sz, CCTK_REAL OUT tau, \
+ CCTK_REAL IN Bvecx, CCTK_REAL IN Bvecy, \
+ CCTK_REAL IN Bvecz, CCTK_REAL IN rho, CCTK_REAL IN velx, \
+ CCTK_REAL IN vely, \
+ CCTK_REAL IN velz, CCTK_REAL OUT epsilon, \
+ CCTK_REAL OUT press, CCTK_REAL OUT w_lorentz)
+
PROVIDES FUNCTION SpatialDet WITH SpatialDeterminant LANGUAGE Fortran
PROVIDES FUNCTION UpperMet WITH UpperMetric LANGUAGE Fortran
#PROVIDES FUNCTION Con2Prim WITH Con2Prim_pt LANGUAGE Fortran
PROVIDES FUNCTION Con2PrimPoly WITH Con2Prim_ptPolytype LANGUAGE Fortran
PROVIDES FUNCTION Prim2ConGen WITH prim2con LANGUAGE Fortran
PROVIDES FUNCTION Prim2ConPoly WITH prim2conpolytype LANGUAGE Fortran
+PROVIDES FUNCTION Prim2ConGenM WITH prim2conM LANGUAGE Fortran
+PROVIDES FUNCTION Prim2ConPolyM WITH prim2conpolytypeM LANGUAGE Fortran
####################################################
### Functions provided by MoL for registration ###
@@ -274,9 +302,9 @@ real tau type = GF Timelevels = 3 tags='ProlongationParameter="HydroBase::prolo
real scon[3] type = GF Timelevels = 3 tags='ProlongationParameter="HydroBase::prolongation_type" tensortypealias="D" tensorweight=+1.0 interpolator="matter"' "generalized momenta"
-real bcom[3] type = GF Timelevels = 3 tags='Prolongation="none" tensortypealias="D" tensorweight=+1.0 interpolator="matter"' "comoving magnetic field components"
+#real bcom[3] type = GF Timelevels = 3 tags='Prolongation="none" tensortypealias="D" tensorweight=+1.0 interpolator="matter"' "comoving magnetic field components"
-real bcom0 type = GF Timelevels = 3 tags='Prolongation="none" tensortypealias="Scalar"' "0 component of the comoving magnetic field"
+#real bcom0 type = GF Timelevels = 3 tags='Prolongation="none" tensortypealias="Scalar"' "0 component of the comoving magnetic field"
real GRHydro_tracers[number_of_tracers] type = GF Timelevels = 3 tags='ProlongationParameter="HydroBase::prolongation_type" tensortypealias="Scalar"'
{
@@ -288,6 +316,7 @@ real w_lorentz type = GF Timelevels = 3 tags='ProlongationParameter="HydroBase::
real densrhs type = GF Timelevels = 1 tags='Prolongation="None" checkpoint="no"' "Update term for dens"
real taurhs type = GF Timelevels = 1 tags='Prolongation="None" checkpoint="no"' "Update term for tau"
real srhs[3] type = GF Timelevels = 1 tags='Prolongation="None" checkpoint="no"' "Update term for s"
+real Bvecrhs[3] type = GF Timelevels = 1 tags='Prolongation="None" checkpoint="no"' "Update term for Bvec"
##################################################
### These variables are only protected so that ###
@@ -344,6 +373,11 @@ real GRHydro_fluxes type = GF Timelevels = 1 tags='Prolongation="None" checkpoin
densflux, sxflux, syflux, szflux, tauflux
} "Fluxes for each conserved variable"
+real GRHydro_Bfluxes type = GF Timelevels = 1 tags='Prolongation="None" checkpoint="no"'
+{
+ Bvecxflux, Bvecyflux, Bveczflux
+} "Fluxes for each B-field variable"
+
private:
int MHD type = SCALAR tags='checkpoint="no"' "Are we doing MHD? Set in ParamCheck"
@@ -356,6 +390,11 @@ real GRHydro_con_bext type = GF Timelevels = 1 tags='Prolongation="None" checkpo
densminus, sxminus, syminus, szminus, tauminus
} "Conservative variables extended to the cell boundaries"
+real GRHydro_MHD_con_bext type = GF Timelevels = 1 tags='Prolongation="None" checkpoint="no"'
+{
+ Bvecxplus,Bvecyplus,Bveczplus,Bvecxminus,Bvecyminus,Bveczminus
+} "Conservative variables extended to the cell boundaries"
+
# real fluxweightvolume type = GF Timelevels = 1
# {
# cell_volume
diff --git a/param.ccl b/param.ccl
index 4a501ed..5ed8382 100644
--- a/param.ccl
+++ b/param.ccl
@@ -68,7 +68,7 @@ CCTK_INT GRHydro_hydro_excision "Turns excision automatically on in HydroBase" A
CCTK_INT GRHydro_MaxNumEvolvedVars "The maximum number of evolved variables used by GRHydro" ACCUMULATOR-BASE=MethodofLines::MoL_Num_Evolved_Vars
{
- 5:8 :: "dens scon[3] tau"
+ 5:8 :: "dens scon[3] tau Bvec[3]"
} 5
CCTK_INT GRHydro_MaxNumConstrainedVars "The maximum number of constrained variables used by GRHydro" ACCUMULATOR-BASE=MethodofLines::MoL_Num_Constrained_Vars
diff --git a/schedule.ccl b/schedule.ccl
index 798bb05..8f17354 100644
--- a/schedule.ccl
+++ b/schedule.ccl
@@ -25,8 +25,7 @@ if (timelevels == 3)
STORAGE: ADMBase::lapse[3]
if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- STORAGE:bcom0[3]
- STORAGE:bcom[3]
+ STORAGE: HydroBase::Bvec[3]
}
}
else
@@ -43,8 +42,7 @@ else
STORAGE: ADMBase::lapse[2]
if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- STORAGE:bcom0[2]
- STORAGE:bcom[2]
+ STORAGE: HydroBase::Bvec[2]
}
}
STORAGE:MHD
@@ -52,6 +50,7 @@ STORAGE:GRHydro_reflevel
STORAGE:densrhs
STORAGE:taurhs
STORAGE:srhs
+STORAGE:Bvecrhs
STORAGE:GRHydro_eos_scalars
STORAGE:GRHydro_minima
STORAGE:GRHydro_scalars
@@ -165,14 +164,30 @@ schedule GRHydro_ParamCheck AT PARAMCHECK
LANG: Fortran
} "Check parameters"
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
+{
+ schedule GRHydro_ParamCheckM AT PARAMCHECK AFTER GRHydro_ParamCheck
+ {
+ LANG: Fortran
+ } "Check parameters - MHD version"
+}
+
######################################
### Standard symmetry registration ###
######################################
-schedule GRHydro_InitSymBound AT BASEGRID
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
-} "Schedule symmetries"
+ schedule GRHydro_InitSymBoundM AT BASEGRID
+ {
+ LANG: Fortran
+ } "Schedule symmetries - MHD version"
+} else {
+ schedule GRHydro_InitSymBound AT BASEGRID
+ {
+ LANG: Fortran
+ } "Schedule symmetries"
+}
##########################################################
### Schedule the flux weighting calculation at initial ###
@@ -191,11 +206,21 @@ SCHEDULE GROUP GZPatchSystem_register
{
} "Tell Cactus that this group exists, but is not scheduled from here"
-SCHEDULE GRHydro_register_GZPatchSystem IN GZPatchSystem_register
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: C
- OPTIONS: meta
-} "register to-be-interpatch-synchronized variables with GZPatchSystem"
+ SCHEDULE GRHydro_register_GZPatchSystemM IN GZPatchSystem_register
+ {
+ LANG: C
+ OPTIONS: meta
+ } "register to-be-interpatch-synchronized variables with GZPatchSystem - MHD version"
+
+} else {
+ SCHEDULE GRHydro_register_GZPatchSystem IN GZPatchSystem_register
+ {
+ LANG: C
+ OPTIONS: meta
+ } "register to-be-interpatch-synchronized variables with GZPatchSystem"
+}
##################################
### Set the handle for the EOS ###
@@ -228,27 +253,57 @@ if (rho_abs_min_after_recovery > 0.0)
} "Set up minimum for the rest-mass density in the atmosphere (before intial data)"
}
-if (CCTK_IsThornActive("PUGH" ))
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- schedule GRHydro_Rho_Minima_Setup_Final_PUGH AT CCTK_PostInitial BEFORE MoL_PostStep
- {
- LANG: C
- } "Set the value of the rest-mass density of the atmosphere which will be used during the evolution (PUGH)"
- schedule GRHydro_InitialAtmosphereReset AT CCTK_PostInitial BEFORE MoL_PostStep AFTER GRHydro_Rho_Minima_Setup_Final_PUGH
- {
- LANG: Fortran
- } "Use mask to enforce atmosphere at initial time"
-}
-else if (CCTK_IsThornActive("Carpet"))
-{
- schedule GRHydro_Rho_Minima_Setup_Final AT CCTK_PostPostInitial BEFORE Con2Prim
- {
- LANG: C
- } "Set the value of the rest-mass density of the atmosphere which will be used during the evolution"
- schedule GRHydro_InitialAtmosphereReset AT CCTK_PostPostInitial BEFORE Con2Prim AFTER GRHydro_Rho_Minima_Setup_Final
- {
- LANG: Fortran
- } "Use mask to enforce atmosphere at initial time"
+
+ if (CCTK_IsThornActive("PUGH" ))
+ {
+ schedule GRHydro_Rho_Minima_Setup_Final_PUGH AT CCTK_PostInitial BEFORE MoL_PostStep
+ {
+ LANG: C
+ } "Set the value of the rest-mass density of the atmosphere which will be used during the evolution (PUGH)"
+ schedule GRHydro_InitialAtmosphereResetM AT CCTK_PostInitial BEFORE MoL_PostStep AFTER GRHydro_Rho_Minima_Setup_Final_PUGH
+ {
+ LANG: Fortran
+ } "Use mask to enforce atmosphere at initial time"
+ }
+ else if (CCTK_IsThornActive("Carpet"))
+ {
+ schedule GRHydro_Rho_Minima_Setup_Final AT CCTK_PostPostInitial BEFORE Con2Prim
+ {
+ LANG: C
+ } "Set the value of the rest-mass density of the atmosphere which will be used during the evolution"
+ schedule GRHydro_InitialAtmosphereResetM AT CCTK_PostPostInitial BEFORE Con2Prim AFTER GRHydro_Rho_Minima_Setup_Final
+ {
+ LANG: Fortran
+ } "Use mask to enforce atmosphere at initial time"
+ }
+
+} else {
+
+ if (CCTK_IsThornActive("PUGH" ))
+ {
+ schedule GRHydro_Rho_Minima_Setup_Final_PUGH AT CCTK_PostInitial BEFORE MoL_PostStep
+ {
+ LANG: C
+ } "Set the value of the rest-mass density of the atmosphere which will be used during the evolution (PUGH)"
+ schedule GRHydro_InitialAtmosphereReset AT CCTK_PostInitial BEFORE MoL_PostStep AFTER GRHydro_Rho_Minima_Setup_Final_PUGH
+ {
+ LANG: Fortran
+ } "Use mask to enforce atmosphere at initial time"
+ }
+ else if (CCTK_IsThornActive("Carpet"))
+ {
+ schedule GRHydro_Rho_Minima_Setup_Final AT CCTK_PostPostInitial BEFORE Con2Prim
+ {
+ LANG: C
+ } "Set the value of the rest-mass density of the atmosphere which will be used during the evolution"
+ schedule GRHydro_InitialAtmosphereReset AT CCTK_PostPostInitial BEFORE Con2Prim AFTER GRHydro_Rho_Minima_Setup_Final
+ {
+ LANG: Fortran
+ } "Use mask to enforce atmosphere at initial time"
+ }
+
}
@@ -334,10 +389,18 @@ if (EoS_Change)
### Standard registration of variables to MoL ###
#################################################
-schedule GRHydro_Register IN MoL_Register
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: C
-} "Register variables for MoL"
+ schedule GRHydro_RegisterM IN MoL_Register
+ {
+ LANG: C
+ } "Register variables for MoL - MHD version"
+} else {
+ schedule GRHydro_Register IN MoL_Register
+ {
+ LANG: C
+ } "Register variables for MoL"
+}
####################################################
### Setup of any scalars for efficiency purposes ###
@@ -423,17 +486,33 @@ schedule group GRHydroRHS IN HydroBase_RHS
# TRIGGERS: densrhs
# TRIGGERS: srhs
# TRIGGERS: taurhs
+# if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
+# {
+# TRIGGERS: Bvecrhs
+# }
# } "Calculate the update terms"
#
# STORAGE:GRHydro_fluxes
# STORAGE:GRHydro_con_bext
# STORAGE:GRHydro_prim_bext
+# if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
+# {
+# STORAGE:GRHydro_MHD_con_bext
+# }
# STORAGE:EOS_temps
#
-# schedule Primitive2ConservativeCells AT CCTK_POSTINITIAL AFTER GZPatchSystem_cxform BEFORE MoL_PostStep
-# {
-# LANG: Fortran
-# } "Convert to conserved variables"
+# if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
+# {
+# schedule Primitive2ConservativeCellsM AT CCTK_POSTINITIAL AFTER GZPatchSystem_cxform BEFORE MoL_PostStep
+# {
+# LANG: Fortran
+# } "Convert to conserved variables - MHD version"
+# } else {
+# schedule Primitive2ConservativeCells AT CCTK_POSTINITIAL AFTER GZPatchSystem_cxform BEFORE MoL_PostStep
+# {
+# LANG: Fortran
+# } "Convert to conserved variables"
+# }
#
#==============================================
@@ -457,11 +536,18 @@ if (number_of_particles)
### over the different directions ###
####################################################################
-schedule SourceTerms IN GRHydroRHS BEFORE FluxTerms
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
-} "Source term calculation"
-
+ schedule SourceTermsM IN GRHydroRHS BEFORE FluxTerms
+ {
+ LANG: Fortran
+ } "Source term calculation - MHD version"
+} else {
+ schedule SourceTerms IN GRHydroRHS BEFORE FluxTerms
+ {
+ LANG: Fortran
+ } "Source term calculation"
+}
#################################################################
### Initial setup for the loop over the different directions. ###
#################################################################
@@ -487,27 +573,56 @@ schedule GRHydroStartLoop IN GRHydroRHS BEFORE FluxTerms
if (CCTK_Equals(method_type, "RSA FV"))
{
-
+
if (evolve_tracer)
{
- schedule group FluxTerms IN GRHydroRHS WHILE GRHydro::flux_direction
- {
- STORAGE:GRHydro_prim_bext
- STORAGE:GRHydro_con_bext
- STORAGE:GRHydro_fluxes
- STORAGE:GRHydro_tracer_cons_bext
- STORAGE:GRHydro_tracer_prim_bext
- STORAGE:GRHydro_tracer_flux
- } "Calculation of intercell fluxes"
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
+ {
+
+ schedule group FluxTerms IN GRHydroRHS WHILE GRHydro::flux_direction
+ {
+ STORAGE:GRHydro_prim_bext
+ STORAGE:GRHydro_con_bext
+ STORAGE:GRHydro_fluxes
+ STORAGE:GRHydro_MHD_con_bext
+ STORAGE:GRHydro_Bfluxes
+ STORAGE:GRHydro_tracer_cons_bext
+ STORAGE:GRHydro_tracer_prim_bext
+ STORAGE:GRHydro_tracer_flux
+ } "Calculation of intercell fluxes"
+ } else {
+ schedule group FluxTerms IN GRHydroRHS WHILE GRHydro::flux_direction
+ {
+ STORAGE:GRHydro_prim_bext
+ STORAGE:GRHydro_con_bext
+ STORAGE:GRHydro_fluxes
+ STORAGE:GRHydro_tracer_cons_bext
+ STORAGE:GRHydro_tracer_prim_bext
+ STORAGE:GRHydro_tracer_flux
+ } "Calculation of intercell fluxes"
+
+ }
}
else
{
- schedule group FluxTerms IN GRHydroRHS WHILE GRHydro::flux_direction
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- STORAGE:GRHydro_prim_bext
- STORAGE:GRHydro_con_bext
- STORAGE:GRHydro_fluxes
- } "Calculation of intercell fluxes"
+ schedule group FluxTerms IN GRHydroRHS WHILE GRHydro::flux_direction
+ {
+ STORAGE:GRHydro_prim_bext
+ STORAGE:GRHydro_con_bext
+ STORAGE:GRHydro_fluxes
+ STORAGE:GRHydro_MHD_con_bext
+ STORAGE:GRHydro_Bfluxes
+ } "Calculation of intercell fluxes"
+ } else {
+ schedule group FluxTerms IN GRHydroRHS WHILE GRHydro::flux_direction
+ {
+ STORAGE:GRHydro_prim_bext
+ STORAGE:GRHydro_con_bext
+ STORAGE:GRHydro_fluxes
+ } "Calculation of intercell fluxes"
+ }
}
##############################################################
@@ -516,19 +631,34 @@ if (CCTK_Equals(method_type, "RSA FV"))
if (CCTK_Equals(GRHydro_eos_type,"General")) {
- schedule Reconstruction IN FluxTerms AS Reconstruct
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- } "Reconstruct the functions at the cell boundaries"
+ schedule ReconstructionM IN FluxTerms AS Reconstruct
+ {
+ LANG: Fortran
+ } "Reconstruct the functions at the cell boundaries - MHD version"
+ } else {
+ schedule Reconstruction IN FluxTerms AS Reconstruct
+ {
+ LANG: Fortran
+ } "Reconstruct the functions at the cell boundaries"
+ }
}
else if (CCTK_Equals(GRHydro_eos_type,"Polytype")) {
- schedule ReconstructionPolytype IN FluxTerms AS Reconstruct
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- } "Reconstruct the functions at the cell boundaries"
-
+ schedule ReconstructionPolytypeM IN FluxTerms AS Reconstruct
+ {
+ LANG: Fortran
+ } "Reconstruct the functions at the cell boundaries - MHD version"
+ } else {
+ schedule ReconstructionPolytype IN FluxTerms AS Reconstruct
+ {
+ LANG: Fortran
+ } "Reconstruct the functions at the cell boundaries"
+ }
}
if (set_trivial_rp_grid_function)
@@ -547,21 +677,38 @@ if (CCTK_Equals(method_type, "RSA FV"))
if (use_eosgeneral)
{
- schedule RiemannSolveGeneral IN FluxTerms AFTER Reconstruct AS Riemann
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- STORAGE: EOS_temps
- STORAGE: RoeAverage_temps
- } "Solve the local Riemann problems"
+ schedule RiemannSolveGeneralM IN FluxTerms AFTER Reconstruct AS Riemann
+ {
+ LANG: Fortran
+ STORAGE: EOS_temps
+ STORAGE: RoeAverage_temps
+ } "Solve the local Riemann problems - MHD Version"
+ } else {
+ schedule RiemannSolveGeneral IN FluxTerms AFTER Reconstruct AS Riemann
+ {
+ LANG: Fortran
+ STORAGE: EOS_temps
+ STORAGE: RoeAverage_temps
+ } "Solve the local Riemann problems"
+ }
}
else if (CCTK_Equals(GRHydro_eos_type,"General")) {
-
- schedule RiemannSolve IN FluxTerms AFTER Reconstruct AS Riemann
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- STORAGE: EOS_temps
- } "Solve the local Riemann problems"
-
+ schedule RiemannSolve IN FluxTerms AFTER Reconstruct AS Riemann
+ {
+ LANG: Fortran
+ STORAGE: EOS_temps
+ } "Solve the local Riemann problems - MHD version"
+ } else {
+ schedule RiemannSolve IN FluxTerms AFTER Reconstruct AS Riemann
+ {
+ LANG: Fortran
+ STORAGE: EOS_temps
+ } "Solve the local Riemann problems"
+ }
}
else if (CCTK_Equals(GRHydro_eos_type,"Polytype")) {
@@ -576,6 +723,10 @@ if (CCTK_Equals(method_type, "RSA FV"))
else if (CCTK_Equals(method_type, "Flux split FD"))
{
+
+##########################################3
+### MHD not implemented yet for Flux split FD !!!
+##########################################
STORAGE:fs_alpha
if (evolve_tracer)
@@ -629,16 +780,24 @@ else if (CCTK_Equals(method_type, "Flux split FD"))
### After calculating the fluxes, calculate the update. ###
###########################################################
-schedule UpdateCalculation IN FluxTerms AFTER Riemann
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
-} "Calculate the update term from the fluxes"
+ schedule UpdateCalculationM IN FluxTerms AFTER Riemann AS UpdateCalcul
+ {
+ LANG: Fortran
+ } "Calculate the update term from the fluxes - MHD version"
+} else {
+ schedule UpdateCalculation IN FluxTerms AFTER Riemann AS UpdateCalcul
+ {
+ LANG: Fortran
+ } "Calculate the update term from the fluxes"
+}
#################################
### Advance the loop counter. ###
#################################
-schedule GRHydroAdvanceLoop IN FluxTerms AFTER UpdateCalculation
+schedule GRHydroAdvanceLoop IN FluxTerms AFTER UpdateCalcul
{
LANG: Fortran
OPTIONS: level
@@ -715,64 +874,117 @@ if (use_eosgeneral)
SYNC: metric_temps
} "Set the temporary metric terms"
-
- if (CCTK_Equals(GRHydro_eos_type,"General"))
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
-
- schedule Conservative2PrimitiveGeneral IN HydroBase_Con2Prim AS Con2Prim
+ if (CCTK_Equals(GRHydro_eos_type,"General"))
{
- LANG: Fortran
- STORAGE: Con2Prim_temps
- } "Convert back to primitive variables (general)"
-
- schedule Primitive2ConservativeCellsGeneral IN HydroBase_Prim2ConInitial
+ schedule Conservative2PrimitiveGeneralM IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ STORAGE: Con2Prim_temps
+ } "Convert back to primitive variables (general) - MHD version"
+
+ schedule Primitive2ConservativeCellsGeneralM IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables - MHD version"
+ }
+ else if (CCTK_Equals(GRHydro_eos_type,"Polytype"))
{
- LANG: Fortran
- } "Convert initial data given in primive variables to conserved variables"
- }
- else if (CCTK_Equals(GRHydro_eos_type,"Polytype"))
- {
-
- schedule Con2PrimPolytypeGeneral IN HydroBase_Con2Prim AS Con2Prim
+ schedule Con2PrimPolytypeGeneralM IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ STORAGE: Con2Prim_temps
+ } "Convert back to primitive variables (polytype) - MHD version"
+
+ schedule Primitive2ConservativeCellsGeneralM IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables - MHD version"
+ }
+ } else {
+ if (CCTK_Equals(GRHydro_eos_type,"General"))
{
- LANG: Fortran
- STORAGE: Con2Prim_temps
- } "Convert back to primitive variables (polytype)"
+ schedule Conservative2PrimitiveGeneral IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ STORAGE: Con2Prim_temps
+ } "Convert back to primitive variables (general)"
+
+ schedule Primitive2ConservativeCellsGeneral IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables"
- schedule Primitive2ConservativeCellsGeneral IN HydroBase_Prim2ConInitial
+ }
+ else if (CCTK_Equals(GRHydro_eos_type,"Polytype"))
{
- LANG: Fortran
- } "Convert initial data given in primive variables to conserved variables"
- }
+ schedule Con2PrimPolytypeGeneral IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ STORAGE: Con2Prim_temps
+ } "Convert back to primitive variables (polytype)"
+
+ schedule Primitive2ConservativeCellsGeneral IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables"
+ }
+ }
}
else if (CCTK_Equals(GRHydro_eos_type,"General"))
{
- schedule Conservative2Primitive IN HydroBase_Con2Prim AS Con2Prim
- {
- LANG: Fortran
- } "Convert back to primitive variables (general)"
-
- schedule Primitive2ConservativeCells IN HydroBase_Prim2ConInitial
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- } "Convert initial data given in primive variables to conserved variables"
+ schedule Conservative2PrimitiveM IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ } "Convert back to primitive variables (general) - MHD version"
+
+ schedule Primitive2ConservativeCellsM IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables - MHD version"
+ } else {
+ schedule Conservative2Primitive IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ } "Convert back to primitive variables (general)"
+
+ schedule Primitive2ConservativeCells IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables"
+ }
}
else if (CCTK_Equals(GRHydro_eos_type,"Polytype"))
{
- schedule Conservative2PrimitivePolytype IN HydroBase_Con2Prim AS Con2Prim
- {
- LANG: Fortran
- } "Convert back to primitive variables (polytype)"
-
-
- schedule Primitive2ConservativePolyCells IN HydroBase_Prim2ConInitial
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- } "Convert initial data given in primive variables to conserved variables"
+ schedule Conservative2PrimitivePolytypeM IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ } "Convert back to primitive variables (polytype) - MHD version"
+
+ schedule Primitive2ConservativePolyCellsM IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables - MHD version"
+ } else {
+ schedule Conservative2PrimitivePolytype IN HydroBase_Con2Prim AS Con2Prim
+ {
+ LANG: Fortran
+ } "Convert back to primitive variables (polytype)"
+
+ schedule Primitive2ConservativePolyCells IN HydroBase_Prim2ConInitial
+ {
+ LANG: Fortran
+ } "Convert initial data given in primive variables to conserved variables"
+ }
}
#################################################################
@@ -794,10 +1006,18 @@ if (evolve_tracer)
if (outflow_boundaries)
{
- schedule GRHydro_OutflowBoundaries IN HydroBase_PostStep BEFORE GRHydro_Boundaries
+ if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
- } "Outflow boundaries over only some of the domain"
+ schedule GRHydro_OutflowBoundariesM IN HydroBase_PostStep BEFORE GRHydro_Bound
+ {
+ LANG: Fortran
+ } "Outflow boundaries over only some of the domain - MHD version"
+ } else {
+ schedule GRHydro_OutflowBoundaries IN HydroBase_PostStep BEFORE GRHydro_Bound
+ {
+ LANG: Fortran
+ } "Outflow boundaries over only some of the domain"
+ }
}
# This should not be used anymore and should be removed after some time
@@ -805,38 +1025,77 @@ schedule group Do_GRHydro_Boundaries IN HydroBase_Boundaries
{
} "GRHydro Boundary conditions group"
-if (evolve_tracer)
+
+if(CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- schedule GRHydro_Boundaries IN HydroBase_Select_Boundaries
+ if (evolve_tracer)
{
- LANG: Fortran
- OPTIONS: LEVEL
- SYNC: dens
- SYNC: tau
- SYNC: scon
- SYNC: w_lorentz
- SYNC: HydroBase::rho
- SYNC: HydroBase::press
- SYNC: HydroBase::eps
- SYNC: HydroBase::vel
- SYNC: GRHydro_cons_tracers
- SYNC: GRHydro_tracers
- } "Select GRHydro boundary conditions"
-} else
-{
- schedule GRHydro_Boundaries IN HydroBase_Select_Boundaries
+ schedule GRHydro_BoundariesM IN HydroBase_Select_Boundaries AS GRHydro_Bound
+ {
+ LANG: Fortran
+ OPTIONS: LEVEL
+ SYNC: dens
+ SYNC: tau
+ SYNC: scon
+ SYNC: w_lorentz
+ SYNC: HydroBase::rho
+ SYNC: HydroBase::press
+ SYNC: HydroBase::eps
+ SYNC: HydroBase::vel
+ SYNC: HydroBase::Bvec
+ SYNC: GRHydro_cons_tracers
+ SYNC: GRHydro_tracers
+ } "Select GRHydro boundary conditions - MHD version"
+ } else {
+ schedule GRHydro_BoundariesM IN HydroBase_Select_Boundaries AS GRHydro_Bound
+ {
+ LANG: Fortran
+ OPTIONS: LEVEL
+ SYNC: dens
+ SYNC: tau
+ SYNC: scon
+ SYNC: w_lorentz
+ SYNC: HydroBase::rho
+ SYNC: HydroBase::press
+ SYNC: HydroBase::eps
+ SYNC: HydroBase::vel
+ SYNC: HydroBase::Bvec
+ } "Select GRHydro boundary conditions - MHD version"
+ }
+} else {
+ if (evolve_tracer)
{
- LANG: Fortran
- OPTIONS: LEVEL
- SYNC: dens
- SYNC: tau
- SYNC: scon
- SYNC: w_lorentz
- SYNC: HydroBase::rho
- SYNC: HydroBase::press
- SYNC: HydroBase::eps
- SYNC: HydroBase::vel
- } "Select GRHydro boundary conditions"
+ schedule GRHydro_Boundaries IN HydroBase_Select_Boundaries AS GRHydro_Bound
+ {
+ LANG: Fortran
+ OPTIONS: LEVEL
+ SYNC: dens
+ SYNC: tau
+ SYNC: scon
+ SYNC: w_lorentz
+ SYNC: HydroBase::rho
+ SYNC: HydroBase::press
+ SYNC: HydroBase::eps
+ SYNC: HydroBase::vel
+ SYNC: GRHydro_cons_tracers
+ SYNC: GRHydro_tracers
+ } "Select GRHydro boundary conditions"
+ } else
+ {
+ schedule GRHydro_Boundaries IN HydroBase_Select_Boundaries AS GRHydro_Bound
+ {
+ LANG: Fortran
+ OPTIONS: LEVEL
+ SYNC: dens
+ SYNC: tau
+ SYNC: scon
+ SYNC: w_lorentz
+ SYNC: HydroBase::rho
+ SYNC: HydroBase::press
+ SYNC: HydroBase::eps
+ SYNC: HydroBase::vel
+ } "Select GRHydro boundary conditions"
+ }
}
############################################################
@@ -866,10 +1125,18 @@ if (evolve_tracer)
### move along. ###
################################################################
-schedule GRHydro_AtmosphereReset IN MoL_Evolution AFTER MoL_Step BEFORE HydroBase_Boundaries AFTER MoL_RestoreSandR
+if (CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
-} "Reset the atmosphere"
+ schedule GRHydro_AtmosphereResetM IN MoL_Evolution AFTER MoL_Step BEFORE HydroBase_Boundaries AFTER MoL_RestoreSandR
+ {
+ LANG: Fortran
+ } "Reset the atmosphere - MHD version"
+} else {
+ schedule GRHydro_AtmosphereReset IN MoL_Evolution AFTER MoL_Step BEFORE HydroBase_Boundaries AFTER MoL_RestoreSandR
+ {
+ LANG: Fortran
+ } "Reset the atmosphere"
+}
schedule group HydroBase_Boundaries IN MoL_Evolution AFTER MoL_Step
{
@@ -932,10 +1199,19 @@ schedule check_GRHydro_C2P_failed AT CCTK_POSTSTEP AFTER GRHydro_RefinementLevel
LANG: Fortran
} "Check the mask function that contains the points where C2P has failed and report an error in case a failure is found"
-schedule GRHydro_Tmunu IN AddToTmunu
+
+if (CCTK_Equals(Bvec_evolution_method,"GRHydro"))
{
- LANG: Fortran
-} "Compute the energy-momentum tensor"
+ schedule GRHydro_TmunuM IN AddToTmunu
+ {
+ LANG: Fortran
+ } "Compute the energy-momentum tensor - MHD version"
+} else {
+ schedule GRHydro_Tmunu IN AddToTmunu
+ {
+ LANG: Fortran
+ } "Compute the energy-momentum tensor"
+}
#the following is necessary because TmunuBase does not have enough schedule
diff --git a/src/GRHydro_BoundariesM.F90 b/src/GRHydro_BoundariesM.F90
new file mode 100644
index 0000000..42c2055
--- /dev/null
+++ b/src/GRHydro_BoundariesM.F90
@@ -0,0 +1,333 @@
+ /*@@
+ @file GRHydro_BoundariesM.F90
+ @date Aug 30, 2010
+ @author
+ @desc
+ The two routines for dealing with boundary conditions.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+#include "GRHydro_Macros.h"
+
+#include "util_Table.h"
+
+#define velx(i,j,k) vel(i,j,k,1)
+#define vely(i,j,k) vel(i,j,k,2)
+#define velz(i,j,k) vel(i,j,k,3)
+#define sx(i,j,k) scon(i,j,k,1)
+#define sy(i,j,k) scon(i,j,k,2)
+#define sz(i,j,k) scon(i,j,k,3)
+#define Bvecx(i,j,k) Bvec(i,j,k,1)
+#define Bvecy(i,j,k) Bvec(i,j,k,2)
+#define Bvecz(i,j,k) Bvec(i,j,k,3)
+
+ /*@@
+ @routine GRHydro_InitSymBoundM
+ @date Aug 30, 2010
+ @author Joshua Faber, Ian Hawke
+ @desc
+ Sets up the symmetries at the boundaries of the hydrodynamical variables.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Direct translation of routines from GR3D, GRAstro_Hydro,
+ written by Mark Miller, or WaveToy routines, or...
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_InitSymBoundM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer, dimension(3) :: sym
+ integer :: ierr
+ integer :: itracer
+
+ character(len=100) tracername
+ character(len=100) tracerindex
+
+ sym(1) = 1
+ sym(2) = 1
+ sym(3) = 1
+
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::rho")
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::press")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::dens")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::tau")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::w_lorentz")
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::eps")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::GRHydro_C2P_failed")
+
+!!$ handle multiple tracer variables
+ if(evolve_tracer.eq.1) then
+ call SetCartSymGN(ierr, cctkGH, sym, "GRHydro::GRHydro_tracers")
+ call SetCartSymGN(ierr, cctkGH, sym, "GRHydro::GRHydro_cons_tracers")
+ endif
+
+ sym(1) = -1
+ sym(2) = 1
+ sym(3) = 1
+
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::vel[0]")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::scon[0]")
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::Bvec[0]")
+
+
+ sym(1) = 1
+ sym(2) = -1
+ sym(3) = 1
+
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::vel[1]")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::scon[1]")
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::Bvec[1]")
+
+ sym(1) = 1
+ sym(2) = 1
+ sym(3) = -1
+
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::vel[2]")
+ call SetCartSymVN(ierr, cctkGH, sym, "GRHydro::scon[2]")
+ call SetCartSymVN(ierr, cctkGH, sym, "HydroBase::Bvec[2]")
+
+end subroutine GRHydro_InitSymBoundM
+
+ /*@@
+ @routine GRHydro_BoundariesM
+ @date Aug 30, 2010
+ @author
+ @desc
+ Calls the appropriate boundary routines
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_BoundariesM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ integer, dimension(3) :: sw
+ integer :: ierr
+ CCTK_REAL :: pi = 3.141569d0
+ integer :: i,j,k
+
+ CCTK_INT, parameter :: faces=CCTK_ALL_FACES
+ CCTK_INT, parameter :: ione=1
+
+ sw = GRHydro_stencil
+
+!!$Flat boundaries if required
+
+ if (CCTK_EQUALS(bound,"flat")) then
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::dens", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::tau", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::scon", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::w_lorentz", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::rho", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::press", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::eps", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::vel", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::Bvec", "Flat")
+
+
+ if(evolve_tracer .ne. 0) then
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::GRHydro_tracers", "Flat")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::GRHydro_cons_tracers", "Flat")
+ endif
+
+ endif
+
+ if (CCTK_EQUALS(bound,"none")) then
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::dens", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::tau", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::scon", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::w_lorentz", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::rho", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::press", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::eps", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::vel", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "HydroBase::Bvec", "None")
+
+ if(evolve_tracer .ne. 0) then
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::GRHydro_tracers", "None")
+ ierr = Boundary_SelectGroupForBC(cctkGH, faces, GRHydro_stencil, -ione, &
+ "GRHydro::GRHydro_cons_tracers", "None")
+ endif
+
+ end if
+
+ if (CCTK_EQUALS(bound,"scalar")) then
+ call CCTK_WARN(0, "Until somebody uses this I see no reason to support it")
+ end if
+
+ if (ierr < 0) call CCTK_WARN(0, "problems with applying the chosen boundary condition")
+
+end subroutine GRHydro_BoundariesM
+
+
+ /*@@
+ @routine GRHydro_OutflowBoundariesM
+ @date Aug 30, 2010
+ @author Joshua Faber, Ian Hawke
+ @desc
+ Set outflow boundaries over only part of the domain.
+ This is designed to be used with GZPatchSystem.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_OutflowBoundariesM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ integer, dimension(3) :: sw
+ integer :: ierr
+ integer :: i,j,k
+
+ CCTK_REAL, dimension(3) :: posn
+
+ CCTK_REAL :: det,psi4pt
+
+ sw = GRHydro_stencil
+
+ if (r(1,1,1) < r(1,1,cctk_lsh(3))) then
+
+ if (cctk_bbox(6) .ne. 0) then
+
+ do k = cctk_lsh(3) - sw(3), cctk_lsh(3)
+ do j = 1, cctk_lsh(2)
+ do i = 1, cctk_lsh(1)
+
+ posn(1) = x(i,j,k)
+ posn(2) = y(i,j,k)
+ posn(3) = z(i,j,k)
+
+ if (dot_product(outflowboundary_normal, posn) > 0.d0) then
+
+ rho(i,j,k) = rho(i,j,k-1)
+ velx(i,j,k) = velx(i,j,k-1)
+ vely(i,j,k) = vely(i,j,k-1)
+ velz(i,j,k) = velz(i,j,k-1)
+ eps(i,j,k) = eps(i,j,k-1)
+ press(i,j,k) = press(i,j,k-1)
+ w_lorentz(i,j,k) = w_lorentz(i,j,k-1)
+ Bvecx(i,j,k) = Bvecx(i,j,k-1)
+ Bvecy(i,j,k) = Bvecy(i,j,k-1)
+ Bvecz(i,j,k) = Bvecz(i,j,k-1)
+
+ psi4pt = 1.d0
+ det=SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+
+ call prim2conM(GRHydro_eos_handle,psi4pt*gxx(i,j,k),&
+ psi4pt*gxy(i,j,k),psi4pt*gxz(i,j,k),&
+ psi4pt*gyy(i,j,k),psi4pt*gyz(i,j,k),psi4pt*gzz(i,j,k),&
+ det, dens(i,j,k),sx(i,j,k),sy(i,j,k),sz(i,j,k),&
+ tau(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k),&
+ rho(i,j,k),velx(i,j,k),vely(i,j,k),velz(i,j,k),&
+ eps(i,j,k),press(i,j,k),w_lorentz(i,j,k))
+
+ end if
+
+ end do
+ end do
+ end do
+
+ end if
+
+ else
+
+ if (cctk_bbox(5) .ne. 0) then
+
+ do k = sw(3), 1, -1
+ do j = 1, cctk_lsh(2)
+ do i = 1, cctk_lsh(1)
+
+ posn(1) = x(i,j,k)
+ posn(2) = y(i,j,k)
+ posn(3) = z(i,j,k)
+
+ if (dot_product(outflowboundary_normal, posn) > 0.d0) then
+
+ rho(i,j,k) = rho(i,j,k+1)
+ velx(i,j,k) = velx(i,j,k+1)
+ vely(i,j,k) = vely(i,j,k+1)
+ velz(i,j,k) = velz(i,j,k+1)
+ eps(i,j,k) = eps(i,j,k+1)
+ press(i,j,k) = press(i,j,k+1)
+ w_lorentz(i,j,k) = w_lorentz(i,j,k+1)
+ Bvecx(i,j,k) = Bvecx(i,j,k-1)
+ Bvecy(i,j,k) = Bvecy(i,j,k-1)
+ Bvecz(i,j,k) = Bvecz(i,j,k-1)
+
+ psi4pt = 1.d0
+ det=SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+
+ call prim2con(GRHydro_eos_handle,psi4pt*gxx(i,j,k),&
+ psi4pt*gxy(i,j,k),psi4pt*gxz(i,j,k),&
+ psi4pt*gyy(i,j,k),psi4pt*gyz(i,j,k),psi4pt*gzz(i,j,k),&
+ det, dens(i,j,k),sx(i,j,k),sy(i,j,k),sz(i,j,k),&
+ tau(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k),&
+ rho(i,j,k),velx(i,j,k),vely(i,j,k),velz(i,j,k),&
+ eps(i,j,k),press(i,j,k),w_lorentz(i,j,k))
+
+ end if
+
+ end do
+ end do
+ end do
+
+ end if
+
+ end if
+
+end subroutine GRHydro_OutflowBoundariesM
+
+
+
diff --git a/src/GRHydro_CalcUpdateM.F90 b/src/GRHydro_CalcUpdateM.F90
new file mode 100644
index 0000000..fab2b55
--- /dev/null
+++ b/src/GRHydro_CalcUpdateM.F90
@@ -0,0 +1,247 @@
+ /*@@
+ @file GRHydro_CalcUpdateM.F90
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ Calculates the update terms given the fluxes. Moved to here so that
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "cctk_Functions.h"
+#include "SpaceMask.h"
+
+ /*@@
+ @routine UpdateCalculationM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ Calculates the update terms from the fluxes.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Moved out of the Riemann solver routines to make the FishEye /
+ weighted flux calculation easier.
+ @endhistory
+
+@@*/
+
+
+subroutine UpdateCalculationM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i,j,k,itracer
+ CCTK_REAL :: idx, alp_l, alp_r
+
+ CCTK_INT :: type_bits, atmosphere, not_atmosphere
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere",&
+ "in_atmosphere")
+ call SpaceMask_GetStateBits(not_atmosphere, "Hydro_Atmosphere",&
+ "not_in_atmosphere")
+
+ idx = 1.d0 / CCTK_DELTA_SPACE(flux_direction)
+
+ if (CCTK_EQUALS(method_type, "RSA FV")) then
+
+ if (use_weighted_fluxes == 0) then
+
+ !$OMP PARALLEL DO PRIVATE(i,j,itracer,alp_l, alp_r)
+ do k = GRHydro_stencil + 1, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil + 1, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil + 1, cctk_lsh(1) - GRHydro_stencil
+
+ alp_l = 0.5d0 * (alp(i,j,k) + &
+ alp(i-xoffset,j-yoffset,k-zoffset))
+ alp_r = 0.5d0 * (alp(i,j,k) + &
+ alp(i+xoffset,j+yoffset,k+zoffset))
+
+ densrhs(i,j,k) = densrhs(i,j,k) + &
+ (alp_l * densflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * densflux(i,j,k)) * idx
+ srhs(i,j,k,1) = srhs(i,j,k,1) + &
+ (alp_l * sxflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * sxflux(i,j,k)) * idx
+ srhs(i,j,k,2) = srhs(i,j,k,2) + &
+ (alp_l * syflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * syflux(i,j,k)) * idx
+ srhs(i,j,k,3) = srhs(i,j,k,3) + &
+ (alp_l * szflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * szflux(i,j,k)) * idx
+ taurhs(i,j,k) = taurhs(i,j,k) + &
+ (alp_l * tauflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * tauflux(i,j,k)) * idx
+ Bvecrhs(i,j,k,1) = Bvecrhs(i,j,k,1) + &
+ (alp_l * Bvecxflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * Bvecxflux(i,j,k)) * idx
+ Bvecrhs(i,j,k,2) = Bvecrhs(i,j,k,2) + &
+ (alp_l * Bvecyflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * Bvecyflux(i,j,k)) * idx
+ Bvecrhs(i,j,k,3) = Bvecrhs(i,j,k,3) + &
+ (alp_l * Bveczflux(i-xoffset,j-yoffset,k-zoffset) - &
+ alp_r * Bveczflux(i,j,k)) * idx
+
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ cons_tracerrhs(i,j,k,itracer) = cons_tracerrhs(i,j,k,itracer) + &
+ (alp_l * cons_tracerflux(i-xoffset,j-yoffset,k-zoffset,itracer) - &
+ alp_r * cons_tracerflux(i,j,k,itracer)) * idx
+ enddo
+!!$ if ( ((flux_direction.eq.3).and.(i.eq.4).and.(j.eq.4)).or.&
+!!$ ((flux_direction.eq.2).and.(i.eq.4).and.(k.eq.4)).or.&
+!!$ ((flux_direction.eq.1).and.(j.eq.4).and.(k.eq.4))&
+!!$ ) then
+!!$ write(*,*) flux_direction, i, j, k, cons_tracerrhs(i,j,k)
+!!$ end if
+
+ end if
+
+ if (wk_atmosphere .eq. 1) then
+
+ if ( (atmosphere_mask(i,j,k) .eq. 1) .or. &
+ (SpaceMask_CheckStateBitsF90(space_mask,i,j,k,type_bits,atmosphere)) ) then
+
+!!$ We are in the atmosphere so the momentum flux must vanish
+
+ srhs(i,j,k,:) = 0.d0
+
+ if ( ( (atmosphere_mask(i-1,j ,k ) .eq. 1) .and. &
+ (atmosphere_mask(i+1,j ,k ) .eq. 1) .and. &
+ (atmosphere_mask(i ,j-1,k ) .eq. 1) .and. &
+ (atmosphere_mask(i ,j+1,k ) .eq. 1) .and. &
+ (atmosphere_mask(i ,j ,k-1) .eq. 1) .and. &
+ (atmosphere_mask(i ,j ,k+1) .eq. 1) &
+ ) .or. &
+ ( (SpaceMask_CheckStateBitsF90(space_mask,i-1,j ,k ,type_bits,atmosphere)) .and. &
+ (SpaceMask_CheckStateBitsF90(space_mask,i+1,j ,k ,type_bits,atmosphere)) .and. &
+ (SpaceMask_CheckStateBitsF90(space_mask,i ,j-1,k ,type_bits,atmosphere)) .and. &
+ (SpaceMask_CheckStateBitsF90(space_mask,i ,j+1,k ,type_bits,atmosphere)) .and. &
+ (SpaceMask_CheckStateBitsF90(space_mask,i ,j ,k-1,type_bits,atmosphere)) .and. &
+ (SpaceMask_CheckStateBitsF90(space_mask,i ,j ,k+1,type_bits,atmosphere)) &
+ ) &
+ ) then
+
+!!$ All neighbours are also atmosphere so all rhs vanish
+
+ densrhs(i,j,k) = 0.d0
+ taurhs(i,j,k) = 0.d0
+!!$
+!!$ We should still evolve the B-field in the atmosphere
+!!$
+
+ end if
+ end if
+
+ end if
+
+ enddo
+ enddo
+ enddo
+ !$OMP END PARALLEL DO
+
+ else
+
+ call CCTK_WARN(0, "Not supported")
+
+!!$ do k = GRHydro_stencil + 1, cctk_lsh(3) - GRHydro_stencil
+!!$ do j = GRHydro_stencil + 1, cctk_lsh(2) - GRHydro_stencil
+!!$ do i = GRHydro_stencil + 1, cctk_lsh(1) - GRHydro_stencil
+!!$
+!!$ alp_l = 0.5d0 * (alp(i,j,k) + &
+!!$ alp(i-xoffset,j-yoffset,k-zoffset))
+!!$ alp_r = 0.5d0 * (alp(i,j,k) + &
+!!$ alp(i+xoffset,j+yoffset,k+zoffset))
+!!$
+!!$ densrhs(i,j,k) = densrhs(i,j,k) + &
+!!$ (alp_l * &
+!!$ &cell_surface(i-xoffset,j-yoffset,k-zoffset,flux_direction) * &
+!!$ &densflux(i-xoffset,j-yoffset,k-zoffset) - &
+!!$ alp_r * &
+!!$ &cell_surface(i,j,k,flux_direction) * &
+!!$ &densflux(i,j,k)) * idx / cell_volume(i,j,k)
+!!$ sxrhs(i,j,k) = sxrhs(i,j,k) + &
+!!$ (alp_l * &
+!!$ &cell_surface(i-xoffset,j-yoffset,k-zoffset,flux_direction) * &
+!!$ &sxflux(i-xoffset,j-yoffset,k-zoffset) - &
+!!$ alp_r * &
+!!$ &cell_surface(i,j,k,flux_direction) * &
+!!$ &sxflux(i,j,k)) * idx / cell_volume(i,j,k)
+!!$ syrhs(i,j,k) = syrhs(i,j,k) + &
+!!$ (alp_l * &
+!!$ &cell_surface(i-xoffset,j-yoffset,k-zoffset,flux_direction) * &
+!!$ &syflux(i-xoffset,j-yoffset,k-zoffset) - &
+!!$ alp_r * &
+!!$ &cell_surface(i,j,k,flux_direction) * &
+!!$ &syflux(i,j,k)) * idx / cell_volume(i,j,k)
+!!$ szrhs(i,j,k) = szrhs(i,j,k) + &
+!!$ (alp_l * &
+!!$ &cell_surface(i-xoffset,j-yoffset,k-zoffset,flux_direction) * &
+!!$ &szflux(i-xoffset,j-yoffset,k-zoffset) - &
+!!$ alp_r * &
+!!$ &cell_surface(i,j,k,flux_direction) * &
+!!$ &szflux(i,j,k)) * idx / cell_volume(i,j,k)
+!!$ taurhs(i,j,k) = taurhs(i,j,k) + &
+!!$ (alp_l * &
+!!$ &cell_surface(i-xoffset,j-yoffset,k-zoffset,flux_direction) * &
+!!$ &tauflux(i-xoffset,j-yoffset,k-zoffset) - &
+!!$ alp_r * &
+!!$ &cell_surface(i,j,k,flux_direction) * &
+!!$ &tauflux(i,j,k)) * idx / cell_volume(i,j,k)
+!!$
+!!$ enddo
+!!$ enddo
+!!$ enddo
+
+ end if
+
+ else if (CCTK_EQUALS(method_type, "Flux split FD")) then
+
+ do k = GRHydro_stencil + 1, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil + 1, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil + 1, cctk_lsh(1) - GRHydro_stencil
+
+ densrhs(i,j,k) = densrhs(i,j,k) + &
+ (densflux(i-xoffset,j-yoffset,k-zoffset) - &
+ densflux(i,j,k)) * idx
+ srhs(i,j,k,1) = srhs(i,j,k,1) + &
+ (sxflux(i-xoffset,j-yoffset,k-zoffset) - &
+ sxflux(i,j,k)) * idx
+ srhs(i,j,k,2) = srhs(i,j,k,2) + &
+ (syflux(i-xoffset,j-yoffset,k-zoffset) - &
+ syflux(i,j,k)) * idx
+ srhs(i,j,k,3) = srhs(i,j,k,3) + &
+ (szflux(i-xoffset,j-yoffset,k-zoffset) - &
+ szflux(i,j,k)) * idx
+ taurhs(i,j,k) = taurhs(i,j,k) + &
+ (tauflux(i-xoffset,j-yoffset,k-zoffset) - &
+ tauflux(i,j,k)) * idx
+ Bvecrhs(i,j,k,1) = Bvecrhs(i,j,k,1) + &
+ (Bvecxflux(i-xoffset,j-yoffset,k-zoffset) - &
+ Bvecxflux(i,j,k)) * idx
+ Bvecrhs(i,j,k,2) = Bvecrhs(i,j,k,2) + &
+ (Bvecyflux(i-xoffset,j-yoffset,k-zoffset) - &
+ Bvecyflux(i,j,k)) * idx
+ Bvecrhs(i,j,k,3) = Bvecrhs(i,j,k,3) + &
+ (Bveczflux(i-xoffset,j-yoffset,k-zoffset) - &
+ Bveczflux(i,j,k)) * idx
+
+ enddo
+ enddo
+ enddo
+
+ end if
+
+ return
+
+end subroutine UpdateCalculationM
+
diff --git a/src/GRHydro_Con2PrimM.F90 b/src/GRHydro_Con2PrimM.F90
index 482cd5c..401fa4d 100644
--- a/src/GRHydro_Con2PrimM.F90
+++ b/src/GRHydro_Con2PrimM.F90
@@ -1,18 +1,928 @@
+/*@@
+ @file GRHydro_Con2PrimM.F90
+ @date Sep 3, 2010
+ @author Scott Noble, Joshua Faber, Bruno Mundim
+ @desc
+ The routines for converting conservative to primitive variables.
+ @enddesc
+ @@*/
+
#include "cctk.h"
#include "cctk_Parameters.h"
#include "cctk_Arguments.h"
#include "cctk_Functions.h"
#include "SpaceMask.h"
+#include "GRHydro_InterfacesM.h"
+#include "GRHydro_Macros.h"
+
+ /*@@
+ @routine Conservative2PrimitiveM
+ @date Sep 3, 2010
+ @author Scott Noble, Joshua Faber, Bruno Mundim, Ian Hawke
+ @desc
+ Wrapper routine that converts from conserved to primitive variables
+ at every grid cell centre.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Trimmed and altered from the GR3D routines, original author Mark Miller.
+ 2007?: Bruno excluded the points in the atmosphere and excision region from the computation.
+ Aug. 2008: Luca added a check on whether a failure at a given point may be disregarded,
+ because that point will then be restricted from a finer level. This should be completely
+ safe only if *regridding happens at times when all levels are evolved.*
+ Feb. 2009: The above procedure proved to be wrong, so Luca implemented another one.
+ When a failure occurs, it is temporarily ignored, except for storing the location of where
+ it occured in a mask. At the end, after a Carpet restriction, the mask is checked and if
+ it still contains failures, the run is aborted with an error message. Only used routines
+ have been updated to use this procedure.
+ @endhistory
+@@*/
subroutine Conservative2PrimitiveM(CCTK_ARGUMENTS)
- implicit none
+ use Con2PrimM_fortran_interfaces
+ implicit none
+
DECLARE_CCTK_ARGUMENTS
DECLARE_CCTK_PARAMETERS
+
+#if !USE_EOS_OMNI
+#ifdef _EOS_BASE_INC_
+#undef _EOS_BASE_INC_
+#endif
+#include "EOS_Base.inc"
+#endif
+ integer :: i, j, k, itracer, nx, ny, nz
+ CCTK_REAL :: uxx, uxy, uxz, uyy, uyz, uzz, det, pmin, epsmin
+ CCTK_REAL :: b2
+ CCTK_INT :: epsnegative
+ character(len=100) warnline
+ CCTK_INT :: type_bits, atmosphere
+ CCTK_INT :: type2_bits
+
+ CCTK_REAL :: local_min_tracer
+#if USE_EOS_OMNI
+! begin EOS Omni vars
+ integer :: n = 1
+ integer :: keytemp = 0
+ integer :: anyerr = 0
+ integer :: keyerr(1) = 0
+ real*8 :: xpress = 0.0d0
+ real*8 :: xeps = 0.0d0
+ real*8 :: xtemp = 0.0d0
+ real*8 :: xye = 0.0d0
+! end EOS Omni vars
+#endif
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere", "in_atmosphere")
+ type2_bits = -1
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+#if USE_EOS_OMNI
+ ! this is a poly call
+ call EOS_Omni_press(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ GRHydro_rho_min,xeps,xtemp,xye,pmin,keyerr,anyerr)
+ call EOS_Omni_EpsFromPress(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ GRHydro_rho_min,xeps,xtemp,xye,pmin,epsmin,keyerr,anyerr)
+#else
+ pmin = EOS_Pressure(GRHydro_polytrope_handle, GRHydro_rho_min, 1.0d0)
+ epsmin = EOS_SpecificIntEnergy(GRHydro_polytrope_handle, GRHydro_rho_min, pmin)
+#endif
+
+ !$OMP PARALLEL DO PRIVATE(i,j,itracer,&
+ !$OMP uxx, uxy, uxz, uyy, uyz, uzz, det, epsnegative)
+ do k = 1, nz
+ do j = 1, ny
+ do i = 1, nx
+
+ !do not compute if in atmosphere or in excised region
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, atmosphere) .or. &
+ (hydro_excision_mask(i,j,k) .ne. 0)) cycle
+
+ epsnegative = 0
+
+ det = SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+ call UpperMetric(uxx,uxy,uxz,uyy,uyz,uzz,det,&
+ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),&
+ gyz(i,j,k),gzz(i,j,k))
+
+!!$ Tracers don't need an MHD treatment!
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call Con2Prim_ptTracer(cons_tracer(i,j,k,itracer), tracer(i,j,k,itracer), &
+ dens(i,j,k))
+
+ if (use_min_tracer .ne. 0) then
+ if (tracer(i,j,k,itracer) .le. local_min_tracer) then
+ tracer(i,j,k,itracer) = local_min_tracer
+ end if
+ end if
+
+ enddo
+
+ endif
+
+ if ( dens(i,j,k) .le. sqrt(det)*GRHydro_rho_min*(1.d0+GRHydro_atmo_tolerance) ) then
+
+ b2=gxx(i,j,k)*Bvec(i,j,k,1)**2+gyy(i,j,k)*Bvec(i,j,k,2)**2+gzz(i,j,k)*Bvec(i,j,k,3)**2+ &
+ 2.0*(gxy(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,2)+gxz(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,3)+ &
+ gyz(i,j,k)*Bvec(i,j,k,2)*Bvec(i,j,k,3))
+
+ dens(i,j,k) = sqrt(det)*GRHydro_rho_min !/(1.d0+GRHydro_atmo_tolerance)
+ rho(i,j,k) = GRHydro_rho_min
+ scon(i,j,k,:) = 0.d0
+ vel(i,j,k,:) = 0.d0
+ w_lorentz(i,j,k) = 1.d0
+#if USE_EOS_OMNI
+ call EOS_Omni_press(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho(i,j,k),eps(i,j,k),xtemp,xye,press(i,j,k),keyerr,anyerr)
+
+ call EOS_Omni_EpsFromPress(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho(i,j,k),eps(i,j,k),xtemp,xye,press(i,j,k),eps(i,j,k),keyerr,anyerr)
+#else
+ press(i,j,k) = EOS_Pressure(GRHydro_polytrope_handle, rho(i,j,k), eps(i,j,k))
+ eps(i,j,k) = EOS_SpecificIntEnergy(GRHydro_polytrope_handle, rho(i,j,k), press(i,j,k))
+#endif
+ ! w_lorentz=1, so the expression for tau reduces to:
+
+!!$ tau does need to take into account the existing B-field
+!!$ with w_lorentz=1, we find tau = sqrtdet*(rho (1+eps+b^2/2)) - dens [Press drops out]
+ tau(i,j,k) = sqrt(det) * (rho(i,j,k)*(1.0+eps(i,j,k)+b2/2.0)) - dens(i,j,k)
+
+ cycle
+
+ end if
+
+
+ call GRHydro_Con2PrimM_pt(GRHydro_eos_handle, dens(i,j,k), &
+ scon(i,j,k,1),scon(i,j,k,2),scon(i,j,k,3), tau(i,j,k), &
+ rho(i,j,k),&
+ vel(i,j,k,1),vel(i,j,k,2),vel(i,j,k,3),eps(i,j,k),press(i,j,k),w_lorentz(i,j,k),&
+ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k), &
+ uxx,uxy,uxz,uyy,uyz,uzz,det, &
+ Bvec(i,j,k,1), Bvec(i,j,k,2),Bvec(i,j,k,3),b2,&
+ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+
+ if (epsnegative .ne. 0) then
+
+#if 0
+ ! cott 2010/03/30:
+ ! Set point to atmosphere, but continue evolution -- this is better than using
+ ! the poly EOS -- it will lead the code to crash if this happens inside a (neutron) star,
+ ! but will allow the job to continue if it happens in the atmosphere or in a
+ ! zone that contains garbage (i.e. boundary, buffer zones)
+ ! Ultimately, we want this fixed via a new carpet mask presently under development
+ ! GRHydro_C2P_failed(i,j,k) = 1
+
+ !$OMP CRITICAL
+ call CCTK_WARN(GRHydro_NaN_verbose+2, 'Specific internal energy just went below 0! ')
+ write(warnline,'(a28,i2)') 'on carpet reflevel: ',GRHydro_reflevel
+ call CCTK_WARN(GRHydro_NaN_verbose+2,warnline)
+ write(warnline,'(a20,3g16.7)') 'xyz location: ',&
+ x(i,j,k),y(i,j,k),z(i,j,k)
+ call CCTK_WARN(GRHydro_NaN_verbose+2,warnline)
+ write(warnline,'(a20,g16.7)') 'radius: ',r(i,j,k)
+ call CCTK_WARN(GRHydro_NaN_verbose+2,warnline)
+ call CCTK_WARN(GRHydro_NaN_verbose+2,"Setting the point to atmosphere")
+ !$OMP END CRITICAL
+
+ ! for safety, let's set the point to atmosphere
+ dens(i,j,k) = sqrt(det)*GRHydro_rho_min !/(1.d0+GRHydro_atmo_tolerance)
+ rho(i,j,k) = GRHydro_rho_min
+ scon(i,j,k,:) = 0.d0
+ vel(i,j,k,:) = 0.d0
+ w_lorentz(i,j,k) = 1.d0
+#if USE_EOS_OMNI
+ call EOS_Omni_press(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho(i,j,k),eps(i,j,k),xtemp,xye,press(i,j,k),keyerr,anyerr)
+
+ call EOS_Omni_EpsFromPress(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho(i,j,k),eps(i,j,k),xtemp,xye,press(i,j,k),eps(i,j,k),keyerr,anyerr)
+#else
+ press(i,j,k) = EOS_Pressure(GRHydro_polytrope_handle, rho(i,j,k), eps(i,j,k))
+ eps(i,j,k) = EOS_SpecificIntEnergy(GRHydro_polytrope_handle, rho(i,j,k), press(i,j,k))
+#endif
+ b2=gxx(i,j,k)*Bvec(i,j,k,1)**2+gyy(i,j,k)*Bvec(i,j,k,2)**2+gzz(i,j,k)*Bvec(i,j,k,3)**2+ &
+ 2.0*(gxy(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,2)+gxz(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,3)+ &
+ gyz(i,j,k)*Bvec(i,j,k,2)*Bvec(i,j,k,3))
+
+
+ ! w_lorentz=1, so the expression for tau reduces to [see above]:
+ tau(i,j,k) = sqrt(det) * (rho(i,j,k)*(1.0+eps(i,j,k)+b2/2.0)) - dens(i,j,k)
+#else
+ ! cott 2010/03/27:
+ ! Honestly, this should never happen. We need to flag the point where
+ ! this happened as having led to failing con2prim.
+
+ !$OMP CRITICAL
+ call CCTK_WARN(GRHydro_NaN_verbose+2, 'Specific internal energy just went below 0, trying polytype.')
+ !$OMP END CRITICAL
+
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, dens(i,j,k), &
+!!$ scon(i,j,k,1),scon(i,j,k,2),scon(i,j,k,3), tau(i,j,k), &
+!!$ rho(i,j,k),&
+!!$ vel(i,j,k,1),vel(i,j,k,2),vel(i,j,k,3),eps(i,j,k),press(i,j,k),w_lorentz(i,j,k),&
+!!$ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k), &
+!!$ uxx,uxy,uxz,uyy,uyz,uzz,det, &
+!!$ Bvec(i,j,k,1), Bvec(i,j,k,2),Bvec(i,j,k,3),b2,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+#endif
+
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+
+ return
+
end subroutine Conservative2PrimitiveM
+
+
+ /*@@
+ @routine Conservative2PrimitiveBoundariesM
+ @date Sep 15, 2010
+ @author Scott Noble, Joshua Faber, Bruno Mundim, The GRHydro Developers
+ @desc
+ This routine is used only if the reconstruction is performed on the conserved variables.
+ It computes the primitive variables on cell boundaries.
+ Since reconstruction on conservative had not proved to be very successful,
+ some of the improvements to the C2P routines (e.g. the check about
+ whether a failure happens in a point that will be restriced anyway)
+ are not implemented here yet.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+subroutine Conservative2PrimitiveBoundsM(CCTK_ARGUMENTS)
+
+ use Con2PrimM_fortran_interfaces
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k, itracer, nx, ny, nz
+ CCTK_REAL :: uxxl, uxyl, uxzl, uyyl, uyzl, uzzl,&
+ uxxr, uxyr, uxzr, uyyr, uyzr, uzzr, pmin, epsmin
+ CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
+ CCTK_REAL :: b2minus, b2plus
+ CCTK_INT :: epsnegative
+ character(len=100) warnline
+
+ CCTK_INT :: type_bits, atmosphere
+ CCTK_INT :: type2_bits
+
+ CCTK_REAL :: local_min_tracer
+
+#if !USE_EOS_OMNI
+#ifdef _EOS_BASE_INC_
+#undef _EOS_BASE_INC_
+#endif
+#include "EOS_Base.inc"
+#endif
+
+
+#if USE_EOS_OMNI
+! begin EOS omni
+ CCTK_INT :: keyerr(1) = 0
+ CCTK_INT :: anyerr = 0
+ CCTK_INT :: keytemp = 0
+ CCTK_INT :: n = 1
+ CCTK_REAL :: xye = 0.0d0
+ CCTK_REAL :: xeps = 0.0d0
+ CCTK_REAL :: xtemp = 0.0d0
+! end EOS omni
+#endif
+
+
+#if USE_EOS_OMNI
+ ! this is a poly call
+ call EOS_Omni_press(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ GRHydro_rho_min,1.0d0,xtemp,xye,pmin,keyerr,anyerr)
+
+ call EOS_Omni_EpsFromPress(GRHydro_polytrope_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ GRHydro_rho_min,epsmin,xtemp,xye,pmin,epsmin,keyerr,anyerr)
+#else
+ pmin=EOS_Pressure(GRHydro_polytrope_handle, GRHydro_rho_min, 1.0d0)
+ epsmin = EOS_SpecificIntEnergy(GRHydro_polytrope_handle, GRHydro_rho_min, pmin)
+#endif
+
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere", "in_atmosphere")
+ type2_bits = -1
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+ do j = GRHydro_stencil, ny - GRHydro_stencil + 1
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+
+ !do not compute if in atmosphere or in an excised region
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, atmosphere) .or. &
+ GRHydro_enable_internal_excision /= 0 .and. (hydro_excision_mask(i,j,k) .ne. 0)) cycle
+
+ gxxl = 0.5d0 * (gxx(i,j,k) + gxx(i-xoffset,j-yoffset,k-zoffset))
+ gxyl = 0.5d0 * (gxy(i,j,k) + gxy(i-xoffset,j-yoffset,k-zoffset))
+ gxzl = 0.5d0 * (gxz(i,j,k) + gxz(i-xoffset,j-yoffset,k-zoffset))
+ gyyl = 0.5d0 * (gyy(i,j,k) + gyy(i-xoffset,j-yoffset,k-zoffset))
+ gyzl = 0.5d0 * (gyz(i,j,k) + gyz(i-xoffset,j-yoffset,k-zoffset))
+ gzzl = 0.5d0 * (gzz(i,j,k) + gzz(i-xoffset,j-yoffset,k-zoffset))
+ gxxr = 0.5d0 * (gxx(i,j,k) + gxx(i+xoffset,j+yoffset,k+zoffset))
+ gxyr = 0.5d0 * (gxy(i,j,k) + gxy(i+xoffset,j+yoffset,k+zoffset))
+ gxzr = 0.5d0 * (gxz(i,j,k) + gxz(i+xoffset,j+yoffset,k+zoffset))
+ gyyr = 0.5d0 * (gyy(i,j,k) + gyy(i+xoffset,j+yoffset,k+zoffset))
+ gyzr = 0.5d0 * (gyz(i,j,k) + gyz(i+xoffset,j+yoffset,k+zoffset))
+ gzzr = 0.5d0 * (gzz(i,j,k) + gzz(i+xoffset,j+yoffset,k+zoffset))
+
+ epsnegative = 0
+
+ avg_detl = SPATIAL_DETERMINANT(gxxl,gxyl,gxzl,gyyl, gyzl,gzzl)
+ avg_detr = SPATIAL_DETERMINANT(gxxr,gxyr,gxzr,gyyr, gyzr,gzzr)
+ call UpperMetric(uxxl,uxyl,uxzl,uyyl,uyzl,uzzl,avg_detl,&
+ gxxl,gxyl,gxzl,gyyl,gyzl,gzzl)
+ call UpperMetric(uxxr,uxyr,uxzr,uyyr,uyzr,uzzr,avg_detr,&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr)
+
+!!$ Tracers get no update for MHD!
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call Con2Prim_ptTracer(cons_tracer(i,j,k,itracer), &
+ tracer(i,j,k,itracer), dens(i,j,k))
+ enddo
+
+ if (use_min_tracer .ne. 0) then
+ if (tracer(i,j,k,itracer) .le. local_min_tracer) then
+ tracer(i,j,k,itracer) = local_min_tracer
+ end if
+ end if
+
+ endif
+
+ call GRHydro_Con2PrimM_pt(GRHydro_eos_handle, densminus(i,j,k), &
+ sxminus(i,j,k),syminus(i,j,k),szminus(i,j,k), tauminus(i,j,k), &
+ rhominus(i,j,k),&
+ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k),epsminus(i,j,k),pressminus(i,j,k),w_lorentzminus(i,j,k),&
+ gxxl,gxyl,gxzl,gyyl,gyzl,gzzl, &
+ uxxl,uxyl,uxzl,uyyl,uyzl,uzzl,avg_detl, &
+ Bvecxminus(i,j,k), Bvecyminus(i,j,k),Bveczminus(i,j,k),b2minus,&
+ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+ if (epsnegative .ne. 0) then
+ !$OMP CRITICAL
+ call CCTK_WARN(GRHydro_NaN_verbose+2, 'Specific internal energy just went below 0, trying polytype!')
+ !$OMP END CRITICAL
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, densminus(i,j,k), &
+!!$ sxminus(i,j,k),syminus(i,j,k),szminus(i,j,k), tauminus(i,j,k), &
+!!$ rhominus(i,j,k),&
+!!$ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k),epsminus(i,j,k),pressminus(i,j,k),w_lorentzminus(i,j,k),&
+!!$ gxxl,gxyl,gxzl,gyyl,gyzl,gzzl, &
+!!$ uxxl,uxyl,uxzl,uyyl,uyzl,uzzl,avg_detl, &
+!!$ Bvecxminus(i,j,k), Bvecyminus(i,j,k),Bveczminus(i,j,k),b2minus,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+ end if
+
+ if (epsminus(i,j,k) .lt. 0.0d0) then
+ if (GRHydro_reflevel.ge.GRHydro_c2p_warn_from_reflevel) then
+ !$OMP CRITICAL
+ call CCTK_WARN(1,'Con2Prim: stopping the code.')
+ call CCTK_WARN(1, ' specific internal energy just went below 0! ')
+ write(warnline,'(a28,i2)') 'on carpet reflevel: ',GRHydro_reflevel
+ call CCTK_WARN(1,warnline)
+ write(warnline,'(a20,3g16.7)') 'xyz location: ',&
+ x(i,j,k),y(i,j,k),z(i,j,k)
+ call CCTK_WARN(1,warnline)
+ write(warnline,'(a20,g16.7)') 'radius: ',r(i,j,k)
+ call CCTK_WARN(1,warnline)
+ write(warnline,'(a20,3g16.7)') 'velocities: ',&
+ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k)
+ call CCTK_WARN(1,warnline)
+ call CCTK_WARN(GRHydro_c2p_warnlevel, "Specific internal energy negative")
+ !$OMP END CRITICAL
+ exit
+ endif
+ endif
+
+ epsnegative = 0
+ call GRHydro_Con2PrimM_pt(GRHydro_eos_handle, densplus(i,j,k), &
+ sxplus(i,j,k),syplus(i,j,k),szplus(i,j,k), tauplus(i,j,k),&
+ rhoplus(i,j,k),&
+ velxplus(i,j,k),velyplus(i,j,k),velzplus(i,j,k),epsplus(i,j,k),pressplus(i,j,k),w_lorentzplus(i,j,k),&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr, &
+ uxxr,uxyr,uxzr,uyyr,uyzr,uzzr,avg_detr, &
+ Bvecxplus(i,j,k), Bvecyplus(i,j,k),Bveczplus(i,j,k),b2plus,&
+ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+ if (epsnegative .ne. 0) then
+ !$OMP CRITICAL
+ call CCTK_WARN(GRHydro_NaN_verbose+2, 'Specific internal energy just went below 0, trying polytype!!')
+ !$OMP END CRITICAL
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, densplus(i,j,k), &
+!!$ sxplus(i,j,k),syplus(i,j,k),szplus(i,j,k), tauplus(i,j,k),&
+!!$ rhoplus(i,j,k),&
+!!$ velxplus(i,j,k),velyplus(i,j,k),velzplus(i,j,k),epsplus(i,j,k),pressplus(i,j,k),w_lorentzplus(i,j,k),&
+!!$ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr, &
+!!$ uxxr,uxyr,uxzr,uyyr,uyzr,uzzr,avg_detr, &
+!!$ Bvecxplus(i,j,k), Bvecyplus(i,j,k),Bveczplus(i,j,k),b2plus,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+ end if
+
+ if (epsplus(i,j,k) .lt. 0.0d0) then
+ if (GRHydro_reflevel.ge.GRHydro_c2p_warn_from_reflevel) then
+ !$OMP CRITICAL
+ call CCTK_WARN(1,'Con2Prim: stopping the code.')
+ call CCTK_WARN(1, ' specific internal energy just went below 0! ')
+ write(warnline,'(a28,i2)') 'on carpet reflevel: ',GRHydro_reflevel
+ call CCTK_WARN(1,warnline)
+ write(warnline,'(a20,3g16.7)') 'xyz location: ',&
+ x(i,j,k),y(i,j,k),z(i,j,k)
+ call CCTK_WARN(1,warnline)
+ write(warnline,'(a20,g16.7)') 'radius: ',r(i,j,k)
+ call CCTK_WARN(1,warnline)
+ write(warnline,'(a20,3g16.7)') 'velocities: ',&
+ velxplus(i,j,k),velyplus(i,j,k),velzplus(i,j,k)
+ call CCTK_WARN(1,warnline)
+ call CCTK_WARN(GRHydro_c2p_warnlevel, "Specific internal energy negative")
+ write(warnline,'(a25,4g15.6)') 'coordinates: x,y,z,r:',&
+ x(i,j,k),y(i,j,k),z(i,j,k),r(i,j,k)
+ call CCTK_WARN(1,warnline)
+ !$OMP END CRITICAL
+ endif
+ endif
+
+ end do
+ end do
+ end do
+
+end subroutine Conservative2PrimitiveBoundsM
+
+
+/*@@
+@routine Con2PrimPolytypeM
+@date Sep 16, 2010
+@author SCott Noble, Joshua Faber, Bruno Mundim, Ian Hawke
+@desc
+All routines below are identical to those above, just
+specialised from polytropic type EOS.
+@enddesc
+@calls
+@calledby
+@history
+
+@endhistory
+
+@@*/
+
+subroutine Conservative2PrimitivePolytypeM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k, itracer, nx, ny, nz
+ CCTK_REAL :: uxx, uxy, uxz, uyy, uyz, uzz, det,b2
+
+ CCTK_INT :: type_bits, atmosphere
+ CCTK_INT :: type2_bits
+
+ CCTK_INT :: epsnegative
+
+ CCTK_REAL :: local_min_tracer
+ ! character(len=400) :: warnline
+
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere", "in_atmosphere")
+ type2_bits = -1
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+!!$ do k = GRHydro_stencil + 1, nz - GRHydro_stencil
+!!$ do j = GRHydro_stencil + 1, ny - GRHydro_stencil
+!!$ do i = GRHydro_stencil + 1, nx - GRHydro_stencil
+ !$OMP PARALLEL DO PRIVATE(i,j,itracer,&
+ !$OMP uxx, uxy, uxz, uyy, uyz, uzz, det)
+ do k = 1, nz
+ do j = 1, ny
+ do i = 1, nx
+
+ !do not compute if in atmosphere or in an excised region
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, atmosphere) .or. &
+ GRHydro_enable_internal_excision /= 0 .and. (hydro_excision_mask(i,j,k) .ne. 0)) cycle
+
+ det = SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+ call UpperMetric(uxx,uxy,uxz,uyy,uyz,uzz,det,&
+ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),&
+ gyz(i,j,k),gzz(i,j,k))
+
+!!$ No MHD changes to tracers
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call Con2Prim_ptTracer(cons_tracer(i,j,k,itracer), &
+ tracer(i,j,k,itracer), dens(i,j,k))
+ enddo
+
+ if (use_min_tracer .ne. 0) then
+ if (tracer(i,j,k,itracer) .le. local_min_tracer) then
+ tracer(i,j,k,itracer) = local_min_tracer
+ end if
+ end if
+
+ endif
+
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, dens(i,j,k), &
+!!$ scon(i,j,k,1),scon(i,j,k,2),scon(i,j,k,3), tau(i,j,k),&
+!!$ rho(i,j,k),&
+!!$ vel(i,j,k,1),vel(i,j,k,2),vel(i,j,k,3),eps(i,j,k),press(i,j,k),w_lorentz(i,j,k),&
+!!$ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k), &
+!!$ uxx,uxy,uxz,uyy,uyz,uzz,det, &
+!!$ Bvec(i,j,k,1), Bvec(i,j,k,2),Bvec(i,j,k,3),b2,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+ end do
+ end do
+ end do
+
+ !$OMP END PARALLEL DO
+
+ return
+
+end subroutine Conservative2PrimitivePolytypeM
+
+
+ /*@@
+ @routine Cons2PrimBoundsPolytypeM
+ @date Sep 16, 2010
+ @author Scott Noble, Joshua Faber, Bruno Mundim, The GRHydro Developers
+ @desc
+ This routine is used only if the reconstruction is performed on the conserved variables.
+ It computes the primitive variables on cell boundaries.
+ Since reconstruction on conservative had not proved to be very successful,
+ some of the improvements to the C2P routines (e.g. the check about
+ whether a failure happens in a point that will be restriced anyway) are not implemented here yet.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine Con2PrimBoundsPolytypeM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k, nx, ny, nz
+ CCTK_REAL :: uxxl, uxyl, uxzl, uyyl, uyzl, uzzl,&
+ uxxr, uxyr, uxzr, uyyr, uyzr, uzzr
+ CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
+ CCTK_REAL :: b2minus, b2plus
+
+ CCTK_INT :: type_bits, atmosphere
+ CCTK_INT :: type2_bits, epsnegative
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere", "in_atmosphere")
+ type2_bits = -1
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+ do j = GRHydro_stencil, ny - GRHydro_stencil + 1
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+
+ !do not compute if in atmosphere or in an excised region
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, atmosphere) .or. &
+ GRHydro_enable_internal_excision /= 0 .and. (hydro_excision_mask(i,j,k) .ne. 0)) cycle
+
+ gxxl = 0.5d0 * (gxx(i,j,k) + gxx(i-xoffset,j-yoffset,k-zoffset))
+ gxyl = 0.5d0 * (gxy(i,j,k) + gxy(i-xoffset,j-yoffset,k-zoffset))
+ gxzl = 0.5d0 * (gxz(i,j,k) + gxz(i-xoffset,j-yoffset,k-zoffset))
+ gyyl = 0.5d0 * (gyy(i,j,k) + gyy(i-xoffset,j-yoffset,k-zoffset))
+ gyzl = 0.5d0 * (gyz(i,j,k) + gyz(i-xoffset,j-yoffset,k-zoffset))
+ gzzl = 0.5d0 * (gzz(i,j,k) + gzz(i-xoffset,j-yoffset,k-zoffset))
+ gxxr = 0.5d0 * (gxx(i,j,k) + gxx(i+xoffset,j+yoffset,k+zoffset))
+ gxyr = 0.5d0 * (gxy(i,j,k) + gxy(i+xoffset,j+yoffset,k+zoffset))
+ gxzr = 0.5d0 * (gxz(i,j,k) + gxz(i+xoffset,j+yoffset,k+zoffset))
+ gyyr = 0.5d0 * (gyy(i,j,k) + gyy(i+xoffset,j+yoffset,k+zoffset))
+ gyzr = 0.5d0 * (gyz(i,j,k) + gyz(i+xoffset,j+yoffset,k+zoffset))
+ gzzr = 0.5d0 * (gzz(i,j,k) + gzz(i+xoffset,j+yoffset,k+zoffset))
+
+ avg_detl = SPATIAL_DETERMINANT(gxxl,gxyl,gxzl,gyyl, gyzl,gzzl)
+ avg_detr = SPATIAL_DETERMINANT(gxxr,gxyr,gxzr,gyyr, gyzr,gzzr)
+ call UpperMetric(uxxl,uxyl,uxzl,uyyl,uyzl,uzzl,avg_detl,&
+ gxxl,gxyl,gxzl,gyyl,gyzl,gzzl)
+ call UpperMetric(uxxr,uxyr,uxzr,uyyr,uyzr,uzzr,avg_detr,&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr)
+
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, densminus(i,j,k), &
+!!$ sxminus(i,j,k),syminus(i,j,k),szminus(i,j,k), tauminus(i,j,k),&
+!!$ rhominus(i,j,k),&
+!!$ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k),epsminus(i,j,k),pressminus(i,j,k),w_lorentzminus(i,j,k),&
+!!$ gxxl,gxyl,gxzl,gyyl,gyzl,gzzl, &
+!!$ uxxl,uxyl,uxzl,uyyl,uyzl,uzzl,avg_detl, &
+!!$ Bvecxminus(i,j,k), Bvecyminus(i,j,k),Bveczminus(i,j,k),b2minus,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, densplus(i,j,k), &
+!!$ sxplus(i,j,k),syplus(i,j,k),szplus(i,j,k), tauplus(i,j,k),&
+!!$ rhoplus(i,j,k),&
+!!$ velxplus(i,j,k),velyplus(i,j,k),velzplus(i,j,k),epsplus(i,j,k),pressplus(i,j,k),w_lorentzplus(i,j,k),&
+!!$ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr, &
+!!$ uxxr,uxyr,uxzr,uyyr,uyzr,uzzr,avg_detr, &
+!!$ Bvecxplus(i,j,k), Bvecyplus(i,j,k),Bveczplus(i,j,k),b2plus,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+ end do
+ end do
+ end do
+
+end subroutine Con2PrimBoundsPolytypeM
+
+!!$ Con2Prim_ptTracer, Con2Prim_BoundsTracer, and Con2Prim_ptBoundsTracer need not be rewritten!
+
+ /*@@
+ @routine Conservative2PrimitiveGeneralM
+ @date Sep 16, 2010
+ @author Scott Noble, Joshua Faber, Bruno Mundim, Ian Hawke
+ @desc
+ Wrapper routine that converts from conserved to primitive variables
+ at every grid cell centre. Converted to the EOSGeneral format
+ @enddesc
+ @calls
+ @calledby
+ @history
+ @endhistory
+
+@@*/
+
+subroutine Conservative2PrimitiveGeneralM(CCTK_ARGUMENTS)
+
+ USE GRHydro_Scalars
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i, j, k, itracer, nx, ny, nz
+ character(len=100) warnline
+
+ integer :: maxerrloc(3)
+ integer :: ii,jj,kk
+ CCTK_REAL :: maxerr
+
+
+ CCTK_INT :: count
+ CCTK_REAL :: b2,det
+ CCTK_REAL :: uxx,uxy,uxz,uyy,uyz,uzz
+
+ CCTK_INT :: type_bits, atmosphere
+ CCTK_INT :: type2_bits,epsnegative
+
+ CCTK_REAL :: local_min_tracer
+
+ CCTK_INT, dimension(3) :: loc, loc2
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere", "in_atmosphere")
+ type2_bits = -1
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ count = 0
+ press_old = max(eosgeneral_pmin, press)
+
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+!!$ Set up rho and epsilon
+
+ do k = 1, nz
+ do j = 1, ny
+ do i = 1, nx
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call Con2Prim_ptTracer(cons_tracer(i,j,k,itracer), &
+ tracer(i,j,k,itracer), dens(i,j,k))
+ if (use_min_tracer .ne. 0) then
+ if (tracer(i,j,k,itracer) .le. local_min_tracer) then
+ tracer(i,j,k,itracer) = local_min_tracer
+ end if
+ end if
+ enddo
+ endif
+
+ if ( (dens(i,j,k).le.sqrt(GRHydro_Det(i,j,k)) * &
+ GRHydro_rho_min*(1.0d0+GRHydro_atmo_tolerance)) &
+ .or.(tau(i,j,k) .le. 0d0)) then
+
+ b2=gxx(i,j,k)*Bvec(i,j,k,1)**2+gyy(i,j,k)*Bvec(i,j,k,2)**2+gzz(i,j,k)*Bvec(i,j,k,3)**2+ &
+ 2.0*(gxy(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,2)+gxz(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,3)+ &
+ gyz(i,j,k)*Bvec(i,j,k,2)*Bvec(i,j,k,3))
+
+
+ rho(i,j,k) = GRHydro_rho_min
+ dens(i,j,k) = sqrt(GRHydro_det(i,j,k)) * rho(i,j,k)
+ scon(i,j,k,:) = 0.d0
+ w_lorentz(i,j,k) = 1.d0
+ press(i,j,k) = 0.1d0 * eosgeneral_pmin
+ ! eps(i,j,k) = press(i,j,k) / rho(i,j,k) ! Note that this should be improved
+ eps(i,j,k) = 1.0e-12
+ tau(i,j,k) = sqrt(GRHydro_det(i,j,k)) * rho(i,j,k) * (1.0+eps(i,j,k)+b2/2.0) - dens(i,j,k)
+
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bits, atmosphere)
+ atmosphere_mask(i,j,k) = 1
+
+ end if
+
+ det=SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+ call UpperMetric(uxx,uxy,uxz,uyy,uyz,uzz,det,&
+ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),&
+ gyz(i,j,k),gzz(i,j,k))
+
+ call GRHydro_Con2PrimM_pt(GRHydro_eos_handle, dens(i,j,k), &
+ scon(i,j,k,1),scon(i,j,k,2),scon(i,j,k,3), tau(i,j,k),&
+ rho(i,j,k),&
+ vel(i,j,k,1),vel(i,j,k,2),vel(i,j,k,3),eps(i,j,k),press(i,j,k),w_lorentz(i,j,k),&
+ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k), &
+ uxx,uxy,uxz,uyy,uyz,uzz,det, &
+ Bvec(i,j,k,1), Bvec(i,j,k,2),Bvec(i,j,k,3),b2,&
+ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+ end do
+ end do
+ end do
+
+
+end subroutine Conservative2PrimitiveGeneralM
+
+
+ /*@@
+ @routine Conservative2PrimitivePolytypeGeneralM
+ @date Sep 16, 2010
+ @author Scott Noble, Joshua Faber, Bruno Mundim, Ian Hawke
+ @desc
+ Wrapper routine that converts from conserved to primitive variables
+ at every grid cell centre. Converted to the EOSGeneral format
+ @enddesc
+ @calls
+ @calledby
+ @history
+ @endhistory
+
+@@*/
+
+subroutine Con2PrimPolytypeGeneralM(CCTK_ARGUMENTS)
+
+ USE GRHydro_Scalars
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i, j, k, itracer, nx, ny, nz
+ character(len=100) warnline
+
+ CCTK_REAL :: b2, det
+ CCTK_REAL :: uxx,uxy,uxz,uyy,uyz,uzz
+
+ CCTK_INT :: type_bits
+ CCTK_INT :: atmosphere
+ CCTK_INT :: type2_bits,epsnegative
+
+ CCTK_REAL :: local_min_tracer
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere", "in_atmosphere")
+ type2_bits = -1
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+!!$ In what follows press_temp is really rho_temp
+
+ do k = 1, nz
+ do j = 1, ny
+ do i = 1, nx
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call Con2Prim_ptTracer(cons_tracer(i,j,k,itracer), &
+ tracer(i,j,k,itracer), dens(i,j,k))
+
+ if (use_min_tracer .ne. 0) then
+ if (tracer(i,j,k,itracer) .le. local_min_tracer) then
+ tracer(i,j,k,itracer) = local_min_tracer
+ end if
+ end if
+ enddo
+ end if
+
+ if (dens(i,j,k).le.sqrt(GRHydro_Det(i,j,k)) * &
+ GRHydro_rho_min*(1.0d0+GRHydro_atmo_tolerance)) then
+
+ b2=gxx(i,j,k)*Bvec(i,j,k,1)**2+gyy(i,j,k)*Bvec(i,j,k,2)**2+gzz(i,j,k)*Bvec(i,j,k,3)**2+ &
+ 2.0*(gxy(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,2)+gxz(i,j,k)*Bvec(i,j,k,1)*Bvec(i,j,k,3)+ &
+ gyz(i,j,k)*Bvec(i,j,k,2)*Bvec(i,j,k,3))
+
+
+ rho(i,j,k) = GRHydro_rho_min
+ dens(i,j,k) = sqrt(GRHydro_det(i,j,k)) * rho(i,j,k)
+ scon(i,j,k,:) = 0.d0
+ w_lorentz(i,j,k) = 1.d0
+ press(i,j,k) = 0.1d0 * eosgeneral_pmin
+ ! eps(i,j,k) = press(i,j,k) / rho(i,j,k) ! Note that this should be improved
+ eps(i,j,k) = 1.0e-12
+ tau(i,j,k) = sqrt(GRHydro_det(i,j,k)) * rho(i,j,k) * (1.0+eps(i,j,k)+b2/2.0) - dens(i,j,k)
+
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bits, atmosphere)
+ atmosphere_mask(i,j,k) = 1
+
+ end if
+
+ det=SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+ call UpperMetric(uxx,uxy,uxz,uyy,uyz,uzz,det,&
+ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),&
+ gyz(i,j,k),gzz(i,j,k))
+
+!!$ call GRHydro_Con2PrimM_Polytype_pt(GRHydro_eos_handle, dens(i,j,k), &
+!!$ scon(i,j,k,1),scon(i,j,k,2),scon(i,j,k,3), tau(i,j,k),&
+!!$ rho(i,j,k),&
+!!$ vel(i,j,k,1),vel(i,j,k,2),vel(i,j,k,3),eps(i,j,k),press(i,j,k),w_lorentz(i,j,k),&
+!!$ gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k), &
+!!$ uxx,uxy,uxz,uyy,uyz,uzz,det, &
+!!$ Bvec(i,j,k,1), Bvec(i,j,k,2),Bvec(i,j,k,3),b2,&
+!!$ epsnegative,GRHydro_C2P_failed(i,j,k))
+
+ end do
+ end do
+end do
+
+
+end subroutine Con2PrimPolytypeGeneralM
diff --git a/src/GRHydro_Con2PrimM_pt.c b/src/GRHydro_Con2PrimM_pt.c
new file mode 100644
index 0000000..d9ba2a6
--- /dev/null
+++ b/src/GRHydro_Con2PrimM_pt.c
@@ -0,0 +1,690 @@
+/***********************************************************************************
+ Copyright 2006 Scott C. Noble, Charles F. Gammie, Jonathan C. McKinney,
+ and Luca Del Zanna.
+
+ PVS_GRMHD
+
+ This file was derived from PVS_GRMHD. The authors of PVS_GRMHD include
+ Scott C. Noble, Charles F. Gammie, Jonathan C. McKinney, and Luca Del Zanna.
+ PVS_GRMHD is available under the GPL from:
+ http://rainman.astro.uiuc.edu/codelib/
+
+ You are morally obligated to cite the following paper in his/her
+ scientific literature that results from use of this file:
+
+ [1] Noble, S. C., Gammie, C. F., McKinney, J. C., \& Del Zanna, L. \ 2006,
+ Astrophysical Journal, 641, 626.
+
+ PVS_GRMHD is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ PVS_GRMHD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with PVS_GRMHD; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ If the user has any questions, please direct them to Scott C. Noble at
+ scn@astro.rit.edu .
+
+***********************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <complex.h>
+
+#include "cctk.h"
+
+/* Set this to be 1 if you want debug output */
+#define DEBUG_CON2PRIMM (0)
+
+
+/* Adiabatic index used for the state equation */
+
+#define MAX_NEWT_ITER (30) /* Max. # of Newton-Raphson iterations for find_root_2D(); */
+#define NEWT_TOL (1.0e-10) /* Min. of tolerance allowed for Newton-Raphson iterations */
+#define MIN_NEWT_TOL (1.0e-10) /* Max. of tolerance allowed for Newton-Raphson iterations */
+#define EXTRA_NEWT_ITER (2)
+
+#define NEWT_TOL2 (1.0e-15) /* TOL of new 1D^*_{v^2} gnr2 method */
+#define MIN_NEWT_TOL2 (1.0e-10) /* TOL of new 1D^*_{v^2} gnr2 method */
+
+#define W_TOO_BIG (1.e20) /* \gamma^2 (\rho_0 + u + p) is assumed
+ to always be smaller than this. This
+ is used to detect solver failures */
+
+#define FAIL_VAL (1.e30) /* Generic value to which we set variables when a problem arises */
+
+/**************************************************
+ The following functions assume a Gamma-law EOS:
+***************************************************/
+
+/* Local Globals */
+static CCTK_REAL Bsq,QdotBsq,Qtsq,Qdotn,D,half_Bsq ;
+
+// Declarations:
+static CCTK_REAL vsq_calc(CCTK_REAL W);
+
+static CCTK_INT twod_newton_raphson( CCTK_REAL x[],
+ void (*funcd) (CCTK_REAL [], CCTK_REAL [],
+ CCTK_REAL [], CCTK_REAL [][2],
+ CCTK_REAL *, CCTK_REAL *) );
+
+static void func_vsq( CCTK_REAL [], CCTK_REAL [], CCTK_REAL [], CCTK_REAL [][2],
+ CCTK_REAL *f, CCTK_REAL *df);
+static CCTK_REAL x1_of_x0(CCTK_REAL x0 ) ;
+
+
+// EOS STUFF:
+#define gam (5./3.)
+#define GAMMA (gam)
+static CCTK_REAL gam_m1_o_gam = ((GAMMA-1.)/GAMMA);
+static CCTK_REAL eos_info(CCTK_REAL W, CCTK_REAL vsq, CCTK_REAL *dpdw, CCTK_REAL *dpdvsq);
+/* pressure as a function of rho0 and u */
+static CCTK_REAL pressure_rho0_u(CCTK_REAL rho0, CCTK_REAL u)
+{
+ return((GAMMA - 1.)*u) ;
+}
+
+/* Pressure as a function of rho0 and w = rho0 + u + p */
+static CCTK_REAL pressure_rho0_w(CCTK_REAL rho0, CCTK_REAL w)
+{
+ return((GAMMA-1.)*(w - rho0)/GAMMA) ;
+}
+
+
+void CCTK_FCALL CCTK_FNAME(GRHydro_Con2PrimM_pt) (
+ CCTK_INT *handle,
+ CCTK_REAL *dens_in,
+ CCTK_REAL *sx_in, CCTK_REAL *sy_in, CCTK_REAL *sz_in,
+ CCTK_REAL *tau_in,
+ CCTK_REAL *rho,
+ CCTK_REAL *velx, CCTK_REAL *vely, CCTK_REAL *velz,
+ CCTK_REAL *epsilon, CCTK_REAL *pressure,
+ CCTK_REAL *w_lorentz,
+ CCTK_REAL *gxx, CCTK_REAL *gxy, CCTK_REAL *gxz,
+ CCTK_REAL *gyy, CCTK_REAL *gyz, CCTK_REAL *gzz,
+ CCTK_REAL *uxx, CCTK_REAL *uxy, CCTK_REAL *uxz,
+ CCTK_REAL *uyy, CCTK_REAL *uyz, CCTK_REAL *uzz,
+ CCTK_REAL *det,
+ CCTK_REAL *Bx, CCTK_REAL *By, CCTK_REAL *Bz,
+ CCTK_REAL *bsq,
+ CCTK_INT *epsnegative,
+ CCTK_REAL *retval);
+
+/**********************************************************************/
+/**********************************************************************************
+
+ Con2PrimM_pt():
+ -----------------------------
+
+ -- Attempts an inversion from GRMHD conserved variables to primitive variables assuming a guess.
+
+ -- Uses the 2D method of Noble et al. (2006):
+ -- Solves for two independent variables (W,v^2) via a 2D
+ Newton-Raphson method
+ -- Can be used (in principle) with a general equation of state.
+
+ -- Minimizes two residual functions using a homemade Newton-Raphson routine.
+ -- It is homemade so that it can catch exceptions and handle them correctly, plus it is
+ optimized for this particular problem.
+
+ -- Note that the notation used herein is that of Noble et al. (2006) except for the argument
+ list.
+
+
+INPUT: (using GRHydro variable defintions)
+
+ s[x,y,z] = scons[0,1,2] = \alpha \sqrt(\gamma) T^0_i
+ dens, tau = as defined in GRHydro and are assumed to be densitized (i.e. with sqrt(\gamma))
+ dens = D = \sqrt(\gamma) W \rho
+ tau = \alpha^2 \sqrt(\gamma) T^{00} - D
+ g[x,y,z][x,y,x] = spatial metric corresponding to \gamma
+ u[x,y,z][x,y,z] = inverse of the spatial metric, g[x,y,z][x,y,x]
+ det = sqrt(\gamma)
+ B[x,y,z] = Bvec[0,1,2]
+ bsq = b^\mu b_\mu
+
+ epsnegative = (integer)
+ = 0 if rho and epsilon are positive
+ != 0 otherwise
+
+
+ -- (users should set B[x,y,z] = 0 for hydrodynamic runs)
+
+
+OUTPUT: (using GRHydro variable defintions)
+ rho, eps = as defined in GRHydro, primitive variables
+ vel[x,y,z] = as defined in GRHydro, primitive variables
+
+
+RETURN VALUE: of retval = (i*100 + j) where
+ i = 0 -> Newton-Raphson solver either was not called (yet or not used)
+ or returned successfully;
+ 1 -> Newton-Raphson solver did not converge to a solution with the
+ given tolerances;
+ 2 -> Newton-Raphson procedure encountered a numerical divergence
+ (occurrence of "nan" or "+/-inf" ;
+
+ j = 0 -> success
+ 1 -> failure: some sort of failure in Newton-Raphson;
+ 2 -> failure: unphysical vsq = v^2 value at initial guess;
+ 3 -> failure: W<0 or W>W_TOO_BIG
+ 4 -> failure: v^2 > 1
+ ( used to be 5 -> failure: rho,uu <= 0 but now sets epsnegative to non-zero )
+
+**********************************************************************************/
+void CCTK_FCALL CCTK_FNAME(GRHydro_Con2PrimM_pt) (
+ CCTK_INT *handle,
+ CCTK_REAL *dens_in,
+ CCTK_REAL *sx_in, CCTK_REAL *sy_in, CCTK_REAL *sz_in,
+ CCTK_REAL *tau_in,
+ CCTK_REAL *rho,
+ CCTK_REAL *velx, CCTK_REAL *vely, CCTK_REAL *velz,
+ CCTK_REAL *epsilon, CCTK_REAL *pressure,
+ CCTK_REAL *w_lorentz,
+ CCTK_REAL *gxx, CCTK_REAL *gxy, CCTK_REAL *gxz,
+ CCTK_REAL *gyy, CCTK_REAL *gyz, CCTK_REAL *gzz,
+ CCTK_REAL *uxx, CCTK_REAL *uxy, CCTK_REAL *uxz,
+ CCTK_REAL *uyy, CCTK_REAL *uyz, CCTK_REAL *uzz,
+ CCTK_REAL *det,
+ CCTK_REAL *Bx, CCTK_REAL *By, CCTK_REAL *Bz,
+ CCTK_REAL *bsq,
+ CCTK_INT *epsnegative,
+ CCTK_REAL *retval)
+
+{
+ CCTK_REAL x_2d[2];
+ CCTK_REAL sx, sy, sz;
+ CCTK_REAL usx, usy, usz;
+ CCTK_REAL tau, dens;
+ CCTK_REAL QdotB;
+ CCTK_REAL rho0,u,p,w,gammasq,gamma,gtmp,W_last,W,vsq;
+ CCTK_REAL g_o_WBsq, QdB_o_W;
+ CCTK_REAL detg = (*det);
+ CCTK_REAL sqrt_detg = sqrt(detg);
+ CCTK_REAL inv_sqrt_detg = 1./sqrt_detg;
+ CCTK_INT i,j, i_increase ;
+
+ /* Assume ok initially: */
+ *retval = 0.;
+ *epsnegative = 0;
+
+#if(DEBUG_CON2PRIMM)
+ fprintf(stdout," *dens = %26.16e \n", *dens_in );
+ fprintf(stdout," *sx = %26.16e \n", *sx_in );
+ fprintf(stdout," *sy = %26.16e \n", *sy_in );
+ fprintf(stdout," *sz = %26.16e \n", *sz_in );
+ fprintf(stdout," *tau = %26.16e \n", *tau_in );
+ fprintf(stdout," *rho = %26.16e \n", *rho );
+ fprintf(stdout," *velx = %26.16e \n", *velx );
+ fprintf(stdout," *vely = %26.16e \n", *vely );
+ fprintf(stdout," *velz = %26.16e \n", *velz );
+ fprintf(stdout," *epsilon = %26.16e \n", *epsilon );
+ fprintf(stdout," *pressure = %26.16e \n", *pressure );
+ fprintf(stdout," *w_lorentz = %26.16e \n", *w_lorentz );
+ fprintf(stdout," *gxx = %26.16e \n", *gxx );
+ fprintf(stdout," *gxy = %26.16e \n", *gxy );
+ fprintf(stdout," *gxz = %26.16e \n", *gxz );
+ fprintf(stdout," *gyy = %26.16e \n", *gyy );
+ fprintf(stdout," *gyz = %26.16e \n", *gyz );
+ fprintf(stdout," *gzz = %26.16e \n", *gzz );
+ fprintf(stdout," *uxx = %26.16e \n", *uxx );
+ fprintf(stdout," *uxy = %26.16e \n", *uxy );
+ fprintf(stdout," *uxz = %26.16e \n", *uxz );
+ fprintf(stdout," *uyy = %26.16e \n", *uyy );
+ fprintf(stdout," *uyz = %26.16e \n", *uyz );
+ fprintf(stdout," *uzz = %26.16e \n", *uzz );
+ fprintf(stdout," *det = %26.16e \n", *det );
+ fprintf(stdout," *Bx = %26.16e \n", *Bx );
+ fprintf(stdout," *By = %26.16e \n", *By );
+ fprintf(stdout," *Bz = %26.16e \n", *Bz );
+ fprintf(stdout," *bsq = %26.16e \n", *bsq );
+ fprintf(stdout," *epsnegative = %10d \n", *epsnegative );
+ fprintf(stdout," *retval = %26.16e \n", *retval );
+ fflush(stdout);
+#endif
+
+ /* First undensitize all conserved variables : */
+ sx = ( *sx_in) * inv_sqrt_detg;
+ sy = ( *sy_in) * inv_sqrt_detg;
+ sz = ( *sz_in) * inv_sqrt_detg;
+ tau = ( *tau_in) * inv_sqrt_detg;
+ dens = (*dens_in) * inv_sqrt_detg;
+
+ usx = (*uxx)*sx + (*uxy)*sy + (*uxz)*sz;
+ usy = (*uxy)*sx + (*uyy)*sy + (*uyz)*sz;
+ usz = (*uxz)*sx + (*uyz)*sy + (*uzz)*sz;
+
+ // Calculate various scalars (Q.B, Q^2, etc) from the conserved variables:
+
+ Bsq =
+ (*gxx) * (*Bx) * (*Bx) +
+ (*gyy) * (*By) * (*By) +
+ (*gzz) * (*Bz) * (*Bz) +
+ 2*(
+ (*gxy) * (*Bx) * (*By) +
+ (*gxz) * (*Bx) * (*Bz) +
+ (*gyz) * (*By) * (*Bz) );
+
+ QdotB = (sx * (*Bx) + sy * (*By) + sz * (*Bz)) ;
+ QdotBsq = QdotB*QdotB ;
+
+ Qdotn = -(tau + dens) ;
+
+ Qtsq = (usx * sx + usy * sy + usz * sz) ;
+
+ D = dens;
+
+ half_Bsq = 0.5*Bsq;
+
+ /* calculate W from last timestep and use for guess */
+ vsq =
+ (*gxx) * (*velx) * (*velx) +
+ (*gyy) * (*vely) * (*vely) +
+ (*gzz) * (*velz) * (*velz) +
+ 2*(
+ (*gxy) * (*velx) * (*vely) +
+ (*gxz) * (*velx) * (*velz) +
+ (*gyz) * (*vely) * (*velz) );
+
+ if( (vsq < 0.) && (fabs(vsq) < 1.0e-13) ) {
+ vsq = fabs(vsq);
+ }
+ if(vsq < 0. || vsq > 1. ) {
+ *retval = 2.;
+ return;
+ }
+
+ gammasq = 1. / (1. - vsq);
+ gamma = sqrt(gammasq);
+
+ // Always calculate rho from D and gamma so that using D in EOS remains consistent
+ // i.e. you don't get positive values for dP/d(vsq) .
+ rho0 = D / gamma ;
+ u = (*epsilon) * rho0;
+ p = pressure_rho0_u(rho0,u) ; // EOS
+ w = rho0 + u + p ;
+
+ W_last = w*gammasq ;
+
+
+ // Make sure that W is large enough so that v^2 < 1 :
+ i_increase = 0;
+ while( (( W_last*W_last*W_last * ( W_last + 2.*Bsq )
+ - QdotBsq*(2.*W_last + Bsq) ) <= W_last*W_last*(Qtsq-Bsq*Bsq))
+ && (i_increase < 10) ) {
+ W_last *= 10.;
+ i_increase++;
+ }
+
+ // Calculate W and vsq:
+ x_2d[0] = fabs( W_last );
+ x_2d[1] = x1_of_x0( W_last ) ;
+ *retval = 1.0*twod_newton_raphson( x_2d, func_vsq ) ;
+
+ W = x_2d[0];
+ vsq = x_2d[1];
+
+ /* Problem with solver, so return denoting error before doing anything further */
+ if( ((*retval) != 0.) || (W == FAIL_VAL) ) {
+ *retval = *retval*100.+1.;
+ return;
+ }
+ else{
+ if(W <= 0. || W > W_TOO_BIG) {
+ *retval = 3.;
+ return;
+ }
+ }
+
+ // Calculate v^2:
+ if( vsq >= 1. ) {
+ *retval = 4.;
+ return;
+ }
+
+ // Recover the primitive variables from the scalars and conserved variables:
+ gtmp = sqrt(1. - vsq);
+ gamma = 1./gtmp ;
+ rho0 = D * gtmp;
+
+ w = W * (1. - vsq) ;
+ p = pressure_rho0_w(rho0,w) ; // EOS
+ u = w - (rho0 + p) ;
+
+ // User may want to handle this case differently, e.g. do NOT return upon
+ // a negative rho/u, calculate v^i so that rho/u can be floored by other routine:
+ if( (rho0 <= 0.) || (u <= 0.) ) {
+ *epsnegative = 1;
+ return;
+ }
+
+ *rho = rho0;
+ *epsilon = u / rho0;
+ *w_lorentz = gamma;
+ *pressure = p ;
+
+ g_o_WBsq = 1./(W+Bsq);
+ QdB_o_W = QdotB / W;
+ *bsq = Bsq * (1.-vsq) + QdB_o_W*QdB_o_W;
+
+ *velx = g_o_WBsq * ( usx + QdB_o_W*(*Bx) ) ;
+ *vely = g_o_WBsq * ( usy + QdB_o_W*(*By) ) ;
+ *velz = g_o_WBsq * ( usz + QdB_o_W*(*Bz) ) ;
+
+
+#if(DEBUG_CON2PRIMM)
+ fprintf(stdout,"rho = %26.16e \n",*rho );
+ fprintf(stdout,"epsilon = %26.16e \n",*epsilon );
+ fprintf(stdout,"pressure = %26.16e \n",*pressure );
+ fprintf(stdout,"w_lorentz = %26.16e \n",*w_lorentz);
+ fprintf(stdout,"bsq = %26.16e \n",*bsq );
+ fprintf(stdout,"velx = %26.16e \n",*velx );
+ fprintf(stdout,"vely = %26.16e \n",*vely );
+ fprintf(stdout,"velz = %26.16e \n",*velz );
+ fprintf(stdout,"gam = %26.16e \n",gam );
+ fflush(stdout);
+#endif
+
+ /* done! */
+ return;
+
+}
+
+
+/**********************************************************************/
+/****************************************************************************
+ vsq_calc():
+
+ -- evaluate v^2 (spatial, normalized velocity) from
+ W = \gamma^2 w
+
+****************************************************************************/
+static CCTK_REAL vsq_calc(CCTK_REAL W)
+{
+ CCTK_REAL Wsq,Xsq,Bsq_W;
+
+ Wsq = W*W ;
+ Bsq_W = (Bsq + W);
+ Xsq = Bsq_W * Bsq_W;
+
+ return( ( Wsq * Qtsq + QdotBsq * (Bsq_W + W)) / (Wsq*Xsq) );
+}
+
+
+/********************************************************************
+
+ x1_of_x0():
+
+ -- calculates v^2 from W with some physical bounds checking;
+ -- asumes x0 is already physical
+ -- makes v^2 physical if not;
+
+*********************************************************************/
+
+static CCTK_REAL x1_of_x0(CCTK_REAL x0 )
+{
+ CCTK_REAL x1,vsq;
+ CCTK_REAL dv = 1.e-15;
+
+ vsq = fabs(vsq_calc(x0)) ; // guaranteed to be positive
+
+ return( ( vsq > 1. ) ? (1.0 - dv) : vsq );
+
+}
+
+/********************************************************************
+
+ validate_x():
+
+ -- makes sure that x[0,1] have physical values, based upon
+ their definitions:
+
+*********************************************************************/
+
+static void validate_x(CCTK_REAL x[2], CCTK_REAL x0[2] )
+{
+
+ const CCTK_REAL dv = 1.e-15;
+
+ /* Always take the absolute value of x[0] and check to see if it's too big: */
+ x[0] = fabs(x[0]);
+ x[0] = (x[0] > W_TOO_BIG) ? x0[0] : x[0];
+
+ x[1] = (x[1] < 0.) ? 0. : x[1]; /* if it's too small */
+ x[1] = (x[1] > 1.) ? (1. - dv) : x[1]; /* if it's too big */
+
+ return;
+
+}
+
+/************************************************************
+
+ twod_newton_raphson():
+
+ -- performs Newton-Rapshon method on an 2d system.
+
+ -- inspired in part by Num. Rec.'s routine newt();
+
+*****************************************************************/
+static CCTK_INT twod_newton_raphson( CCTK_REAL x[],
+ void (*funcd) (CCTK_REAL [], CCTK_REAL [], CCTK_REAL [],
+ CCTK_REAL [][2], CCTK_REAL *,
+ CCTK_REAL *) )
+{
+ CCTK_REAL f, df, dx[2], x_old[2];
+ CCTK_REAL resid[2], jac[2][2];
+ CCTK_REAL errx, x_orig[2];
+ CCTK_INT n_iter, id, jd, i_extra, doing_extra;
+ CCTK_REAL dW,dvsq,vsq_old,vsq,W,W_old;
+ const CCTK_REAL dv = (1.-1.e-15);
+
+ CCTK_INT keep_iterating;
+
+
+ // Initialize various parameters and variables:
+ errx = 1. ;
+ df = f = 1.;
+ i_extra = doing_extra = 0;
+ x_old[0] = x_orig[0] = x[0] ;
+ x_old[1] = x_orig[1] = x[1] ;
+
+ vsq_old = vsq = W = W_old = 0.;
+ n_iter = 0;
+
+ /* Start the Newton-Raphson iterations : */
+ keep_iterating = 1;
+ while( keep_iterating ) {
+
+ (*funcd) (x, dx, resid, jac, &f, &df); /* returns with new dx, f, df */
+
+
+ /* Save old values before calculating the new: */
+ errx = 0.;
+ x_old[0] = x[0] ;
+ x_old[1] = x[1] ;
+
+ /* Make the newton step: */
+ x[0] += dx[0] ;
+ x[1] += dx[1] ;
+
+ /****************************************/
+ /* Calculate the convergence criterion */
+ /****************************************/
+ errx = (x[0]==0.) ? fabs(dx[0]) : fabs(dx[0]/x[0]);
+
+
+ /****************************************/
+ /* Make sure that the new x[] is physical : */
+ /****************************************/
+ if( x[0] < 0. ) { x[0] = fabs(x[0]); }
+ else {
+ if(x[0] > W_TOO_BIG) { x[0] = x_old[0] ; }
+ }
+
+ if( x[1] < 0. ) { x[1] = 0.; }
+ else {
+ if( x[1] > 1. ) { x[1] = dv; }
+ }
+
+ /*****************************************************************************/
+ /* If we've reached the tolerance level, then just do a few extra iterations */
+ /* before stopping */
+ /*****************************************************************************/
+
+ if( (fabs(errx) <= NEWT_TOL) && (doing_extra == 0) && (EXTRA_NEWT_ITER > 0) ) {
+ doing_extra = 1;
+ }
+
+ if( doing_extra == 1 ) i_extra++ ;
+
+ if( ((fabs(errx) <= NEWT_TOL)&&(doing_extra == 0))
+ || (i_extra > EXTRA_NEWT_ITER) || (n_iter >= (MAX_NEWT_ITER-1)) ) {
+ keep_iterating = 0;
+ }
+
+ n_iter++;
+
+ } // END of while(keep_iterating)
+
+
+ /* Check for bad untrapped divergences : */
+ if( (!finite(f)) || (!finite(df)) ) {
+ return(2);
+ }
+
+
+ if( fabs(errx) <= NEWT_TOL ){
+ return(0);
+ }
+ else if( (fabs(errx) <= MIN_NEWT_TOL) && (fabs(errx) > NEWT_TOL) ){
+ return(0);
+ }
+ else {
+ return(1);
+ }
+
+ return(0);
+
+}
+
+
+
+/**********************************************************************/
+/*********************************************************************************
+ func_vsq():
+
+ -- calculates the residuals, and Newton step for general_newton_raphson();
+ -- for this method, x=W,vsq here;
+
+ Arguments:
+ x = current value of independent var's (on input & output);
+ dx = Newton-Raphson step (on output);
+ resid = residuals based on x (on output);
+ jac = Jacobian matrix based on x (on output);
+ f = resid.resid/2 (on output)
+ df = -2*f; (on output)
+ n = dimension of x[];
+ *********************************************************************************/
+
+static void func_vsq(CCTK_REAL x[], CCTK_REAL dx[], CCTK_REAL resid[],
+ CCTK_REAL jac[][2], CCTK_REAL *f, CCTK_REAL *df)
+{
+
+
+ CCTK_REAL W, vsq, Wsq, p_tmp, dPdvsq, dPdW;
+ CCTK_REAL t11, t16,t18,t2,t21, t23, t24, t25, t3, t35, t36, t4, t40;
+
+
+ W = x[0];
+ vsq = x[1];
+
+ Wsq = W*W;
+
+ p_tmp = eos_info(W, vsq, &dPdW, &dPdvsq);
+
+ // These expressions were calculated using Mathematica, but made into efficient
+ // code using Maple. Since we know the analytic form of the equations, we can
+ // explicitly calculate the Newton-Raphson step:
+
+ t2 = -half_Bsq+dPdvsq;
+ t3 = Bsq+W;
+ t4 = t3*t3;
+ t23 = 1/W;
+ t16 = QdotBsq*t23*t23;
+ t11 = Qtsq-vsq*t4+t16*(Bsq+W+W);
+ t18 = -Qdotn-half_Bsq*(1.0+vsq)+0.5*t16-W+p_tmp;
+ t24 = t16*t23;
+ t25 = -1.0+dPdW-t24;
+ t35 = t25*t3+(Bsq-2.0*dPdvsq)*(t16+vsq*W)*t23;
+ // t21 = 1/t3;
+ // t36 = 1/t35;
+ t21 = 1/(t3*t35);
+ dx[0] = -(t2*t11+t4*t18)*t21;
+ t40 = -2*(vsq+t24)*t3;
+ dx[1] = -(-t25*t11+t40*t18)*t21;
+ // detJ = t3*t35;
+ jac[0][0] = t40;
+ jac[0][1] = -t4;
+ jac[1][0] = t25;
+ jac[1][1] = t2;
+ resid[0] = t11;
+ resid[1] = t18;
+
+ *df = -resid[0]*resid[0] - resid[1]*resid[1];
+
+ *f = -0.5 * ( *df );
+
+}
+
+
+/**********************************************************************
+ **********************************************************************
+
+ The following routines specify the equation of state. All routines
+ above here should be indpendent of EOS. If the user wishes
+ to use another equation of state, the below functions must be replaced
+ by equivalent routines based upon the new EOS.
+
+ **********************************************************************
+**********************************************************************/
+
+/**********************************************************************/
+/**********************************************************************
+ eos_info():
+
+ -- returns with all the EOS-related values needed;
+ **********************************************************************/
+static CCTK_REAL eos_info(CCTK_REAL W, CCTK_REAL vsq, CCTK_REAL *dpdw, CCTK_REAL *dpdvsq)
+{
+ register double ftmp,gtmp;
+
+ ftmp = 1. - vsq;
+ gtmp = sqrt(ftmp);
+
+ *dpdw = gam_m1_o_gam * ftmp ;
+ *dpdvsq = gam_m1_o_gam * ( 0.5 * D/gtmp - W ) ;
+
+ return( gam_m1_o_gam * ( W * ftmp - D * gtmp ) ); // p
+
+}
+
+
+/******************************************************************************
+ END
+ ******************************************************************************/
+
+
+#undef DEBUG_CON2PRIMM
diff --git a/src/GRHydro_EigenproblemM.F90 b/src/GRHydro_EigenproblemM.F90
new file mode 100644
index 0000000..34499e7
--- /dev/null
+++ b/src/GRHydro_EigenproblemM.F90
@@ -0,0 +1,241 @@
+ /*@@
+ @file GRHydro_EigenproblemM.F90
+ @date August 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Pedro Montero, Joachim Frieben
+ @desc
+ Computes the spectral decomposition of a given state.
+ Implements the analytical scheme devised by J. M. Ibanez
+ et al., "Godunov Methods: Theory and Applications", New
+ York, 2001, 485-503. The optimized method for computing
+ the Roe flux in the special relativistic case is due to
+ M. A. Aloy et al., Comput. Phys. Commun. 120 (1999)
+ 115-121, and has been extended to the general relativistic
+ case as employed in this subroutine by J. Frieben, J. M.
+ Ibanez, and J. Pons (in preparation).
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+module GRHydro_EigenproblemM
+ implicit none
+
+
+ /*@@
+ @routine eigenvaluesM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ Computes the eigenvalues of the Jacobian matrix evaluated
+ at the given state.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Culled from the routines in GR3D, author Mark Miller.
+ @endhistory
+
+@@*/
+
+CONTAINS
+
+subroutine eigenvaluesM(handle,rho,velx,vely,velz,eps,w_lorentz,&
+ Bvcx,Bvcy,Bvcz,lam,gxx,gxy,gxz,gyy,gyz,gzz,u,alp,beta)
+ implicit none
+
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_REAL rho,velx,vely,velz,eps,w_lorentz
+ CCTK_REAL Bvcx,Bvcy,Bvcz
+ CCTK_REAL lam(5)
+ CCTK_REAL gxx,gxy,gxz,gyy,gyz,gzz
+ CCTK_REAL alp,beta,u
+
+ CCTK_REAL cs2,one,two,U2
+ CCTK_REAL vlowx,vlowy,vlowz,v2,w
+ CCTK_REAL lam1,lam2,lam3,lamm,lamp,lamm_nobeta,lamp_nobeta
+ CCTK_INT handle
+ CCTK_REAL dpdrho,dpdeps,press
+
+ CCTK_REAL Bvcxlow,Bvcylow,Bvczlow,Bvc2,rhohstar,va2
+ CCTK_REAL Bdotv,b2
+
+#if !USE_EOS_OMNI
+#ifdef _EOS_BASE_INC_
+#undef _EOS_BASE_INC_
+#endif
+#include "EOS_Base.inc"
+#endif
+
+#if USE_EOS_OMNI
+! begin EOS Omni vars
+ integer :: n = 1
+ integer :: keytemp = 0
+ integer :: anyerr = 0
+ integer :: keyerr(1) = 0
+ real*8 :: xpress = 0.0d0
+ real*8 :: xeps = 0.0d0
+ real*8 :: xtemp = 0.0d0
+ real*8 :: xye = 0.0d0
+! end EOS Omni vars
+#endif
+
+ one = 1.0d0
+ two = 2.0d0
+
+!!$ Set required fluid quantities
+
+
+
+#if USE_EOS_OMNI
+! call EOS_Omni_cs2(handle,keytemp,GRHydro_eos_rf_prec,n,&
+! rho,eps,xtemp,xye,cs2,keyerr,anyerr)
+ call EOS_Omni_press(handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho,eps,xtemp,xye,press,keyerr,anyerr)
+
+ call EOS_Omni_DPressByDEps(handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho,eps,xtemp,xye,dpdeps,keyerr,anyerr)
+
+ call EOS_Omni_DPressByDRho(handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho,eps,xtemp,xye,dpdrho,keyerr,anyerr)
+
+ cs2 = (dpdrho + press * dpdeps / (rho**2))/ &
+ (1.0d0 + eps + press/rho)
+#else
+ press = EOS_Pressure(handle,rho,eps)
+ dpdrho = EOS_DPressByDRho(handle,rho,eps)
+ dpdeps = EOS_DPressByDEps(handle,rho,eps)
+ cs2 = (dpdrho + press * dpdeps / (rho**2))/ &
+ (1.0d0 + eps + press/rho)
+#endif
+
+ vlowx = gxx*velx + gxy*vely + gxz*velz
+ vlowy = gxy*velx + gyy*vely + gyz*velz
+ vlowz = gxz*velx + gyz*vely + gzz*velz
+ v2 = vlowx*velx + vlowy*vely + vlowz*velz
+
+!!$ Lower the B-field, and square of the magnitude
+ Bvcxlow = gxx*Bvcx + gxy*Bvcy + gxz*Bvcz
+ Bvcylow = gxy*Bvcx + gyy*Bvcy + gyz*Bvcz
+ Bvczlow = gxz*Bvcx + gyz*Bvcy + gzz*Bvcz
+ Bvc2 = Bvcxlow*Bvcx + Bvcylow*Bvcy + Bvczlow*Bvcz
+
+ Bdotv = Bvcxlow*velx + Bvcylow*vely + Bvczlow*velz
+ w = w_lorentz
+
+ b2=Bvc2/w**2+Bdotv**2
+
+
+!!$ rhohstar is the term that appears in Tmunu as well = rho*enth + b^2
+ rhohstar = rho*(1.0+eps)+press+b2
+
+!!$ Alfven velocity squared
+ va2 = b2/(rhohstar)
+
+!!$ The following combination always comes up in the wavespeed calculation:
+!!$ U2 = v_a^2 + c_s^2(1-v_a^2)
+!!$ In the unmagnetized case, it reduces to cs2
+ U2 = va2+cs2*(1.d0-va2)
+
+!!$ Calculate eigenvalues
+
+ lam1 = velx - beta/alp
+ lam2 = velx - beta/alp
+ lam3 = velx - beta/alp
+ lamp_nobeta = (velx*(one-U2) + sqrt(U2*(one-v2)*&
+ (u*(one-v2*U2) - velx**2*(one-U2))))/(one-v2*U2)
+ lamm_nobeta = (velx*(one-U2) - sqrt(U2*(one-v2)*&
+ (u*(one-v2*U2) - velx**2*(one-U2))))/(one-v2*U2)
+
+ lamp = lamp_nobeta - beta/alp
+ lamm = lamm_nobeta - beta/alp
+
+ lam(1) = lamm
+ lam(2) = lam1
+ lam(3) = lam2
+ lam(4) = lam3
+ lam(5) = lamp
+
+end subroutine eigenvaluesM
+
+
+!!$ WE need to implement eigenproblem and eigenproblem_leftright!!!!
+
+
+ /*@@
+ @routine eigenvalues_generalM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ Computes the eigenvalues of the Jacobian matrix evaluated
+ at the given state.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Culled from the routines in GR3D, author Mark Miller.
+ @endhistory
+
+@@*/
+
+subroutine eigenvalues_generalM(&
+ velx,vely,velz,cs2,va2,&
+ lam,&
+ gxx,gxy,gxz,gyy,gyz,gzz,&
+ u,alp,beta)
+
+ implicit none
+
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_REAL velx,vely,velz
+ CCTK_REAL lam(5)
+ CCTK_REAL gxx,gxy,gxz,gyy,gyz,gzz
+ CCTK_REAL alp,beta,u,U2
+
+ CCTK_REAL cs2,va2,one,two
+ CCTK_REAL vlowx,vlowy,vlowz,v2,w
+ CCTK_REAL lam1,lam2,lam3,lamm,lamp,lamm_nobeta,lamp_nobeta
+
+ one = 1.0d0
+ two = 2.0d0
+
+!!$ Set required fluid quantities
+
+ vlowx = gxx*velx + gxy*vely + gxz*velz
+ vlowy = gxy*velx + gyy*vely + gyz*velz
+ vlowz = gxz*velx + gyz*vely + gzz*velz
+ v2 = vlowx*velx + vlowy*vely + vlowz*velz
+
+ w = one / sqrt(one - v2)
+
+ U2 = va2+cs2*(1-va2)
+
+!!$ Calculate eigenvalues
+
+ lam1 = velx - beta/alp
+ lam2 = velx - beta/alp
+ lam3 = velx - beta/alp
+ lamp_nobeta = (velx*(one-U2) + sqrt(U2*(one-v2)*&
+ (u*(one-v2*U2) - velx**2*(one-U2))))/(one-v2*U2)
+ lamm_nobeta = (velx*(one-U2) - sqrt(U2*(one-v2)*&
+ (u*(one-v2*U2) - velx**2*(one-U2))))/(one-v2*U2)
+
+ lamp = lamp_nobeta - beta/alp
+ lamm = lamm_nobeta - beta/alp
+
+ lam(1) = lamm
+ lam(2) = lam1
+ lam(3) = lam2
+ lam(4) = lam3
+ lam(5) = lamp
+
+end subroutine eigenvalues_generalM
+
+
+!!$ We'll need to implement eigenproblem_general
+
+end module GRHydro_EigenproblemM
+
diff --git a/src/GRHydro_FluxM.F90 b/src/GRHydro_FluxM.F90
new file mode 100644
index 0000000..77bee7a
--- /dev/null
+++ b/src/GRHydro_FluxM.F90
@@ -0,0 +1,67 @@
+/*@@
+@file GRHydro_FluxM.F90
+@date August 30, 2010
+@author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+@desc
+The routine to calculate the numerical flux function given a
+ specific state
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+subroutine num_x_fluxM(dens,sx,sy,sz,tau,Bx,By,Bz,&
+ densf,sxf,syf,szf,tauf,Bxf,Byf,Bzf,vxt,vyt,vzt,pressstar,&
+ bsubx,bsuby,bsubz,ab0,w,det,alp,beta)
+
+ implicit none
+
+ CCTK_REAL :: dens,sx,sy,sz,tau,Bx,By,Bz
+ CCTK_REAL :: densf,sxf,syf,szf,tauf,Bxf,Byf,Bzf
+ CCTK_REAL :: vxt,vyt,vzt,bsubx,bsuby,bsubz,ab0,w
+ CCTK_REAL :: det,alp,beta,pressstar
+ CCTK_REAL :: velm
+ CCTK_REAL :: sdet,psipstar,psiBx,psiBy,psiBz
+
+ sdet=sqrt(det)
+ psipstar=pressstar*sdet
+ psiBx=Bx*sdet
+ psiBy=By*sdet
+ psiBz=Bz*sdet
+
+!!$ We actually need all three values of vtilde = v^i - beta^i/alp, as well as
+ velm=vxt+beta/alp
+
+!!$ GRHydro splits off alpha for later in the calculation, so we have psi^6 * [Anton eq.42]
+!!$ In the notation of Anton et al.: [psi^6 D] vtilde^i
+ densf = dens * vxt
+
+ sxf = sx*vxt+psipstar-bsubx*psiBx/w
+
+ syf = sy*vxt-bsuby*psiBx/w
+
+ szf = sz*vxt-bsubz*psiBx/w
+
+!!$ [psi^6 tau] vtilde^i +p* v^i - alp b^0 B^i/w
+ tauf = tau*vxt + psipstar*velm - ab0*psiBx/w
+
+!!$ [psi^6 (B^k vtilde^i - B^i vtilde^k]
+ bxf = 0.0
+ byf = psiBy * vxt - psiBx*vyt
+ bzf = psiBz * vxt - psiBx*vzt
+
+end subroutine num_x_fluxM
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/GRHydro_HLLEM.F90 b/src/GRHydro_HLLEM.F90
new file mode 100644
index 0000000..98c4874
--- /dev/null
+++ b/src/GRHydro_HLLEM.F90
@@ -0,0 +1,642 @@
+ /*@@
+ @file GRHydro_HLLEM.F90
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Pedro Montero, Toni Font
+ @desc
+ The HLLE solver. Called from the wrapper function, so works in
+ all directions.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+#include "GRHydro_Macros.h"
+#include "SpaceMask.h"
+
+ /*@@
+ @routine GRHydro_HLLEGeneralM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Pedro Montero, Toni Font
+ @desc
+ The HLLE solver. Sufficiently simple that its just one big routine.
+ Rewritten for the new EOS interface.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Altered from Cactus 3 routines originally written by Toni Font.
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_HLLEGeneralM(CCTK_ARGUMENTS)
+ USE GRHydro_EigenproblemM
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ integer :: i, j, k, m
+ CCTK_REAL, dimension(8) :: cons_p,cons_m,fplus,fminus,f1,qdiff
+ CCTK_REAL, dimension(6) :: prim_p, prim_m
+ CCTK_REAL, dimension(5) :: lamminus,lamplus
+ CCTK_REAL :: charmin, charmax, charpm,avg_alp,avg_det
+ CCTK_REAL :: gxxh, gxyh, gxzh, gyyh, gyzh, gzzh, uxxh, uxyh, &
+ uxzh, uyyh, uyzh, uzzh, avg_beta, usendh, alp_l, alp_r, &
+ cs2_p, cs2_m, dpdeps_p, dpdeps_m
+ CCTK_REAL :: rhoenth_p, rhoenth_m, avg_betax, avg_betay, avg_betaz
+ CCTK_REAL :: vxtp,vytp,vztp,vxtm,vytm,vztm,ab0p,ab0m,b2p,b2m,bdotvp,bdotvm
+ CCTK_REAL :: wp,wm,v2p,v2m,bxlowp,bxlowm,bylowp,bylowm,bzlowp,bzlowm,vA2m,vA2p
+ CCTK_REAL :: Bvecxlowp,Bvecxlowm,Bvecylowp,Bvecylowm,Bveczlowp,Bveczlowm
+ CCTK_REAL :: pressstarp,pressstarm,velxlowp,velxlowm,velylowp,velylowm,velzlowp,velzlowm
+
+ CCTK_INT :: type_bits, trivial, not_trivial
+
+ integer tadmor
+
+ if(CCTK_EQUALS(HLLE_type,"Tadmor")) then
+ tadmor = 1
+ else
+ tadmor = 0
+ endif
+
+
+ if (flux_direction == 1) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemX")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemX", &
+ &"trivial")
+ else if (flux_direction == 2) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemY")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemY", &
+ &"trivial")
+ else if (flux_direction == 3) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemZ")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemZ", &
+ &"trivial")
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil
+
+ f1 = 0.d0
+ lamminus = 0.d0
+ lamplus = 0.d0
+ cons_p = 0.d0
+ cons_m = 0.d0
+ fplus = 0.d0
+ fminus = 0.d0
+ qdiff = 0.d0
+
+!!$ Set the left (p for plus) and right (m_i for minus, i+1) states
+
+ cons_p(1) = densplus(i,j,k)
+ cons_p(2) = sxplus(i,j,k)
+ cons_p(3) = syplus(i,j,k)
+ cons_p(4) = szplus(i,j,k)
+ cons_p(5) = tauplus(i,j,k)
+ cons_p(6) = Bvecxplus(i,j,k)
+ cons_p(7) = Bvecyplus(i,j,k)
+ cons_p(8) = Bveczplus(i,j,k)
+
+ cons_m(1) = densminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(2) = sxminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(3) = syminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(4) = szminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(5) = tauminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(6) = Bvecxminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(7) = Bvecyminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(8) = Bveczminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(1) = rhoplus(i,j,k)
+ prim_p(2) = velxplus(i,j,k)
+ prim_p(3) = velyplus(i,j,k)
+ prim_p(4) = velzplus(i,j,k)
+ prim_p(5) = epsplus(i,j,k)
+
+ prim_m(1) = rhominus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(2) = velxminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(3) = velyminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(4) = velzminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(5) = epsminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(6) = pressplus(i,j,k)
+ cs2_p = eos_cs2_p(i,j,k)
+ dpdeps_p = eos_dpdeps_p(i,j,k)
+ rhoenth_p = prim_p(1)*(1.0d0+prim_p(5))+prim_p(6)
+
+ prim_m(6) = pressminus(i+xoffset,j+yoffset,k+zoffset)
+ cs2_m = eos_cs2_m(i+xoffset,j+yoffset,k+zoffset)
+ dpdeps_m = eos_dpdeps_m(i+xoffset,j+yoffset,k+zoffset)
+ rhoenth_m = prim_m(1)*(1.0d0+prim_m(5))+prim_m(6)
+
+!!$ Calculate various metric terms here.
+!!$ Note also need the average of the lapse at the
+!!$ left and right points.
+!!$
+!!$ In MHD, we need all three shift components regardless of the flux direction
+
+ if (shift_state .ne. 0) then
+ avg_betax = 0.5d0 * (betax(i+xoffset,j+yoffset,k+zoffset) + &
+ betax(i,j,k))
+ avg_betay = 0.5d0 * (betay(i+xoffset,j+yoffset,k+zoffset) + &
+ betay(i,j,k))
+ avg_betaz = 0.5d0 * (betaz(i+xoffset,j+yoffset,k+zoffset) + &
+ betaz(i,j,k))
+ if (flux_direction == 1) then
+ avg_beta=avg_betax
+ else if (flux_direction == 2) then
+ avg_beta=avg_betay
+ else if (flux_direction == 3) then
+ avg_beta=avg_betaz
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ avg_beta = 0.d0
+ avg_betax = 0.d0
+ avg_betay = 0.d0
+ avg_betaz = 0.d0
+ end if
+
+ avg_alp = 0.5 * (alp(i,j,k) + alp(i+xoffset,j+yoffset,k+zoffset))
+
+ gxxh = 0.5d0 * (gxx(i+xoffset,j+yoffset,k+zoffset) + gxx(i,j,k))
+ gxyh = 0.5d0 * (gxy(i+xoffset,j+yoffset,k+zoffset) + gxy(i,j,k))
+ gxzh = 0.5d0 * (gxz(i+xoffset,j+yoffset,k+zoffset) + gxz(i,j,k))
+ gyyh = 0.5d0 * (gyy(i+xoffset,j+yoffset,k+zoffset) + gyy(i,j,k))
+ gyzh = 0.5d0 * (gyz(i+xoffset,j+yoffset,k+zoffset) + gyz(i,j,k))
+ gzzh = 0.5d0 * (gzz(i+xoffset,j+yoffset,k+zoffset) + gzz(i,j,k))
+
+ avg_det = SPATIAL_DETERMINANT(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh)
+
+ vxtp = prim_p(2)-avg_betax/avg_alp
+ vytp = prim_p(3)-avg_betay/avg_alp
+ vztp = prim_p(4)-avg_betaz/avg_alp
+ vxtm = prim_m(2)-avg_betax/avg_alp
+ vytm = prim_m(3)-avg_betay/avg_alp
+ vztm = prim_m(4)-avg_betaz/avg_alp
+
+ call calc_vlow_blow(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh, &
+ prim_p(2),prim_p(3),prim_p(4),cons_p(6),cons_p(7),cons_p(8), &
+ velxlowp,velylowp,velzlowp,Bvecxlowp,Bvecylowp,Bveczlowp, &
+ bdotvp,b2p,v2p,wp,bxlowp,bylowp,bzlowp)
+ call calc_vlow_blow(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh, &
+ prim_m(2),prim_m(3),prim_m(4),cons_m(6),cons_m(7),cons_m(8), &
+ velxlowm,velylowm,velzlowm,Bvecxlowm,Bvecylowm,Bveczlowm, &
+ bdotvm,b2m,v2m,wm,bxlowm,bylowm,bzlowm)
+
+ ab0p = wp*bdotvp
+ ab0m = wm*bdotvm
+
+ vA2p = b2p/(rhoenth_p+b2p)
+ vA2m = b2m/(rhoenth_m+b2m)
+
+!!$ p^* = p+b^2/2 in Anton et al.
+ pressstarp = prim_p(6)+0.5d0*b2p
+ pressstarm = prim_m(6)+0.5d0*b2m
+
+
+!!$ If the Riemann problem is trivial, just calculate the fluxes from the
+!!$ left state and skip to the next cell
+
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, trivial)) then
+
+!!$ we now pass in the B-field as conserved and flux, the vtilde's instead of v's,
+!!$ pressstar instead of P, b_i, alp b^0, w, metric determinant,
+!!$ alp, and beta in the flux dir
+
+ if (flux_direction == 1) then
+ call num_x_fluxM(cons_m(1),cons_m(2),cons_m(3),cons_m(4),cons_m(5),&
+ cons_m(6),cons_m(7),cons_m(8),&
+ f1(1),f1(2),f1(3),f1(4),f1(5),f1(6),f1(7),f1(8),&
+ vxtm,vytm,vztm,pressstarm,bxlowm,bylowm,bzlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 2) then
+ call num_x_fluxM(cons_m(1),cons_m(3),cons_m(4),cons_m(2),cons_m(5),&
+ cons_m(7),cons_m(8),cons_m(6),&
+ f1(1),f1(3),f1(4),f1(2),f1(5),f1(7),f1(8),f1(6),&
+ vytm,vztm,vxtm,pressstarm,bylowm,bzlowm,bxlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 3) then
+ call num_x_fluxM(cons_m(1),cons_m(4),cons_m(2),cons_m(3),cons_m(5),&
+ cons_m(8),cons_m(6),cons_m(7),&
+ f1(1),f1(4),f1(2),f1(3),f1(5),f1(8),f1(6),f1(7), &
+ vztm,vxtm,vytm,pressstarm,bzlowm,bxlowm,bylowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ else !!! The end of this branch is right at the bottom of the routine
+
+ call UpperMetric(uxxh, uxyh, uxzh, uyyh, uyzh, uzzh, &
+ avg_det,gxxh, gxyh, gxzh, &
+ gyyh, gyzh, gzzh)
+
+ if (flux_direction == 1) then
+ usendh = uxxh
+ else if (flux_direction == 2) then
+ usendh = uyyh
+ else if (flux_direction == 3) then
+ usendh = uzzh
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!!$ Calculate the jumps in the conserved variables
+
+ qdiff(1) = cons_m(1) - cons_p(1)
+ qdiff(2) = cons_m(2) - cons_p(2)
+ qdiff(3) = cons_m(3) - cons_p(3)
+ qdiff(4) = cons_m(4) - cons_p(4)
+ qdiff(5) = cons_m(5) - cons_p(5)
+ qdiff(6) = cons_m(6) - cons_p(6)
+ qdiff(7) = cons_m(7) - cons_p(7)
+ qdiff(8) = cons_m(8) - cons_p(8)
+
+!!$ Eigenvalues and fluxes either side of the cell interface
+
+ if (flux_direction == 1) then
+ call eigenvalues_generalM(&
+ prim_m(2),prim_m(3),prim_m(4),cs2_m,vA2m, &
+ lamminus,gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvalues_generalM(&
+ prim_p(2),prim_p(3),prim_p(4),cs2_p,vA2p, &
+ lamplus,gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ call num_x_fluxM(cons_p(1),cons_p(2),cons_p(3),cons_p(4),cons_p(5),&
+ cons_p(6),cons_p(7),cons_p(8),&
+ fplus(1),fplus(2),fplus(3),fplus(4),fplus(5),fplus(6),fplus(7),fplus(8),&
+ vxtp,vytp,vztp,pressstarp,bxlowp,bylowp,bzlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ call num_x_fluxM(cons_m(1),cons_m(2),cons_m(3),cons_m(4),cons_m(5),&
+ cons_m(6),cons_m(7),cons_m(8),&
+ fminus(1),fminus(2),fminus(3),fminus(4),fminus(5),&
+ fminus(6),fminus(7),fminus(8),&
+ vxtm,vytm,vztm,pressstarm,bxlowm,bylowm,bzlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 2) then
+ call eigenvalues_generalM(&
+ prim_m(3),prim_m(4),prim_m(2),cs2_m,vA2m, &
+ lamminus,gyyh,gyzh,gxyh,gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvalues_generalM(&
+ prim_p(3),prim_p(4),prim_p(2),cs2_p,vA2p, &
+ lamplus,gyyh,gyzh,gxyh,gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ call num_x_fluxM(cons_p(1),cons_p(3),cons_p(4),cons_p(2),cons_p(5),&
+ cons_p(7),cons_p(8),cons_p(6),&
+ fplus(1),fplus(3),fplus(4),fplus(2),fplus(5),fplus(7),fplus(8),fplus(6),&
+ vytp,vztp,vxtp,pressstarp,bylowp,bzlowp,bxlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ call num_x_fluxM(cons_m(1),cons_m(3),cons_m(4),cons_m(2),cons_m(5),&
+ cons_m(7),cons_m(8),cons_m(6),&
+ fminus(1),fminus(3),fminus(4),fminus(2),fminus(5),&
+ fminus(7),fminus(8),fminus(6),&
+ vytm,vztm,vxtm,pressstarm,bylowm,bzlowm,bxlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 3) then
+ call eigenvalues_generalM(&
+ prim_m(4),prim_m(2),prim_m(3),cs2_m,vA2m, &
+ lamminus,gzzh,gxzh,gyzh,gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvalues_generalM(&
+ prim_p(4),prim_p(2),prim_p(3),cs2_p,vA2p, &
+ lamplus,gzzh,gxzh,gyzh,gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ call num_x_fluxM(cons_p(1),cons_p(4),cons_p(2),cons_p(3),cons_p(5),&
+ cons_p(8),cons_p(6),cons_p(7),&
+ fplus(1),fplus(4),fplus(2),fplus(3),fplus(5),fplus(8),fplus(6),fplus(7), &
+ vztp,vxtp,vytp,pressstarp,bzlowp,bxlowp,bylowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ call num_x_fluxM(cons_m(1),cons_m(4),cons_m(2),cons_m(3),cons_m(5),&
+ cons_m(8),cons_m(6),cons_m(7),&
+ fminus(1),fminus(4),fminus(2),fminus(3),fminus(5), &
+ fminus(8),fminus(6),fminus(7), &
+ vztm,vxtm,vytm,pressstarm,bzlowm,bxlowm,bylowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ if(tadmor.eq.0) then
+
+!!$ Find minimum and maximum wavespeeds
+
+ charmin = min(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charmax = max(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charpm = charmax - charmin
+
+!!$ Calculate flux by standard formula
+
+ do m = 1,8
+
+ qdiff(m) = cons_m(m) - cons_p(m)
+
+ f1(m) = (charmax * fplus(m) - charmin * fminus(m) + &
+ charmax * charmin * qdiff(m)) / charpm
+
+ end do
+
+ else
+ ! Tadmor's semi-discrete scheme: JcP 160, 241 (2000)
+
+ charmax = max(abs(lamplus(1)), abs(lamplus(2)), abs(lamplus(3)), &
+ abs(lamplus(4)),abs(lamplus(5)),abs(lamminus(1)),abs(lamminus(2)), &
+ abs(lamminus(3)),abs(lamminus(4)),abs(lamminus(5)))
+
+ do m = 1,8
+
+ qdiff(m) = cons_m(m) - cons_p(m)
+
+ f1(m) = 0.5d0 * (fplus(m) + fminus(m)) - 0.5d0*charmax* &
+ qdiff(m)
+
+ end do
+
+
+ end if
+
+
+
+ end if !!! The end of the SpaceMask check for a trivial RP.
+
+ densflux(i, j, k) = f1(1)
+ sxflux(i, j, k) = f1(2)
+ syflux(i, j, k) = f1(3)
+ szflux(i, j, k) = f1(4)
+ tauflux(i, j, k) = f1(5)
+ Bvecxflux(i, j, k) = f1(6)
+ Bvecyflux(i, j, k) = f1(7)
+ Bveczflux(i, j, k) = f1(8)
+
+ end do
+ end do
+ end do
+
+end subroutine GRHydro_HLLEGeneralM
+
+
+subroutine GRHydro_HLLE_TracerGeneralM(CCTK_ARGUMENTS)
+
+ USE GRHydro_EigenproblemM
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ integer :: i, j, k, m
+ CCTK_REAL, dimension(number_of_tracers) :: cons_p,cons_m,fplus,fminus,f1
+ CCTK_REAL, dimension(5) :: lamminus,lamplus
+ CCTK_REAL, dimension(number_of_tracers) :: qdiff
+ CCTK_REAL, dimension(6) :: prim_p, prim_m
+ CCTK_REAL, dimension(3) :: mag_p, mag_m
+ CCTK_REAL :: charmin, charmax, charpm,avg_alp,avg_det
+ CCTK_REAL :: gxxh, gxyh, gxzh, gyyh, gyzh, gzzh, uxxh, uxyh, &
+ uxzh, uyyh, uyzh, uzzh, avg_beta, usendh, alp_l, alp_r, &
+ cs2_p, cs2_m, dpdeps_p, dpdeps_m
+ CCTK_REAL :: b2p,b2m,vA2m,vA2p
+
+ integer tadmor
+
+ if(CCTK_EQUALS(HLLE_type,"Tadmor")) then
+ tadmor = 1
+ else
+ tadmor = 0
+ endif
+
+
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil
+
+ f1 = 0.d0
+ lamminus = 0.d0
+ lamplus = 0.d0
+ cons_p = 0.d0
+ cons_m = 0.d0
+ mag_p = 0.d0
+ mag_m = 0.d0
+ fplus = 0.d0
+ fminus = 0.d0
+ qdiff = 0.d0
+
+!!$ Set the left (p for plus) and right (m_i for minus, i+1) states
+
+ cons_p(:) = cons_tracerplus(i,j,k,:)
+ cons_m(:) = cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+
+ mag_p(1) = Bvecxplus(i,j,k)
+ mag_p(2) = Bvecyplus(i,j,k)
+ mag_p(3) = Bveczplus(i,j,k)
+
+ mag_m(1) = Bvecxminus(i+xoffset,j+yoffset,k+zoffset)
+ mag_m(2) = Bvecyminus(i+xoffset,j+yoffset,k+zoffset)
+ mag_m(3) = Bveczminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(1) = rhoplus(i,j,k)
+ prim_p(2) = velxplus(i,j,k)
+ prim_p(3) = velyplus(i,j,k)
+ prim_p(4) = velzplus(i,j,k)
+ prim_p(5) = epsplus(i,j,k)
+
+ prim_m(1) = rhominus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(2) = velxminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(3) = velyminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(4) = velzminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(5) = epsminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(6) = pressplus(i,j,k)
+ cs2_p = eos_cs2_p(i,j,k)
+ dpdeps_p = eos_dpdeps_p(i,j,k)
+
+ prim_m(6) = pressminus(i+xoffset,j+yoffset,k+zoffset)
+ cs2_m = eos_cs2_m(i+xoffset,j+yoffset,k+zoffset)
+ dpdeps_m = eos_dpdeps_m(i+xoffset,j+yoffset,k+zoffset)
+
+!!$ Calculate various metric terms here.
+!!$ Note also need the average of the lapse at the
+!!$ left and right points.
+
+ if (shift_state .ne. 0) then
+ if (flux_direction == 1) then
+ avg_beta = 0.5d0 * (betax(i+xoffset,j+yoffset,k+zoffset) + &
+ betax(i,j,k))
+ else if (flux_direction == 2) then
+ avg_beta = 0.5d0 * (betay(i+xoffset,j+yoffset,k+zoffset) + &
+ betay(i,j,k))
+ else if (flux_direction == 3) then
+ avg_beta = 0.5d0 * (betaz(i+xoffset,j+yoffset,k+zoffset) + &
+ betaz(i,j,k))
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ avg_beta = 0.d0
+ end if
+
+ avg_alp = 0.5 * (alp(i,j,k) + alp(i+xoffset,j+yoffset,k+zoffset))
+
+ gxxh = 0.5d0 * (gxx(i+xoffset,j+yoffset,k+zoffset) + gxx(i,j,k))
+ gxyh = 0.5d0 * (gxy(i+xoffset,j+yoffset,k+zoffset) + gxy(i,j,k))
+ gxzh = 0.5d0 * (gxz(i+xoffset,j+yoffset,k+zoffset) + gxz(i,j,k))
+ gyyh = 0.5d0 * (gyy(i+xoffset,j+yoffset,k+zoffset) + gyy(i,j,k))
+ gyzh = 0.5d0 * (gyz(i+xoffset,j+yoffset,k+zoffset) + gyz(i,j,k))
+ gzzh = 0.5d0 * (gzz(i+xoffset,j+yoffset,k+zoffset) + gzz(i,j,k))
+
+ avg_det = SPATIAL_DETERMINANT(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh)
+
+!!$ If the Riemann problem is trivial, just calculate the fluxes from the
+!!$ left state and skip to the next cell
+
+ call UpperMetric(uxxh, uxyh, uxzh, uyyh, uyzh, uzzh, &
+ avg_det,gxxh, gxyh, gxzh, &
+ gyyh, gyzh, gzzh)
+
+ if (flux_direction == 1) then
+ usendh = uxxh
+ else if (flux_direction == 2) then
+ usendh = uyyh
+ else if (flux_direction == 3) then
+ usendh = uzzh
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!!$ b^2 = (1-v^2)B^2+(B dot v)^2
+ b2p=(1.d0-DOTP2(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,prim_p(2),prim_p(3),prim_p(4)))* &
+ DOTP2(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,mag_p(1),mag_p(2),mag_p(3)) + &
+ (DOTP(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,prim_p(2),prim_p(3),prim_p(4),mag_p(1),mag_p(2),mag_p(3)))**2
+ b2m=(1.d0-DOTP2(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,prim_m(2),prim_m(3),prim_m(4)))* &
+ DOTP2(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,mag_m(1),mag_m(2),mag_m(3)) + &
+ (DOTP(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,prim_m(2),prim_m(3),prim_m(4),mag_m(1),mag_m(2),mag_m(3)))**2
+
+ vA2p = b2p/(prim_p(1)*(1.0d0+prim_p(5))+prim_p(6)+b2p)
+ vA2m = b2m/(prim_m(1)*(1.0d0+prim_m(5))+prim_m(6)+b2m)
+
+!!$ Eigenvalues and fluxes either side of the cell interface
+
+ if (flux_direction == 1) then
+ call eigenvalues_generalM(&
+ prim_m(2),prim_m(3),prim_m(4),cs2_m,vA2m, &
+ lamminus,&
+ gxxh,gxyh,gxzh,&
+ gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvalues_generalM(&
+ prim_p(2),prim_p(3),prim_p(4),cs2_p,vA2p, &
+ lamplus,&
+ gxxh,gxyh,gxzh,&
+ gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ fplus(:) = (velxplus(i,j,k) - avg_beta / avg_alp) * &
+ cons_tracerplus(i,j,k,:)
+ fminus(:) = (velxminus(i+xoffset,j+yoffset,k+zoffset) - avg_beta / avg_alp) * &
+ cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+ else if (flux_direction == 2) then
+ call eigenvalues_generalM(&
+ prim_m(3),prim_m(4),prim_m(2),cs2_m,vA2m, &
+ lamminus,&
+ gyyh,gyzh,gxyh,&
+ gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvalues_generalM(&
+ prim_p(3),prim_p(4),prim_p(2),cs2_p,vA2p, &
+ lamplus,&
+ gyyh,gyzh,gxyh,&
+ gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ fplus(:) = (velyplus(i,j,k) - avg_beta / avg_alp) * &
+ cons_tracerplus(i,j,k,:)
+ fminus(:) = (velyminus(i+xoffset,j+yoffset,k+zoffset) - avg_beta / avg_alp) * &
+ cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+ else if (flux_direction == 3) then
+ call eigenvalues_generalM(&
+ prim_m(4),prim_m(2),prim_m(3),cs2_m,vA2m, &
+ lamminus,&
+ gzzh,gxzh,gyzh,&
+ gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvalues_generalM(&
+ prim_p(4),prim_p(2),prim_p(3),cs2_p,vA2p, &
+ lamplus,&
+ gzzh,gxzh,gyzh,&
+ gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ fplus(:) = (velzplus(i,j,k) - avg_beta / avg_alp) * &
+ cons_tracerplus(i,j,k,:)
+ fminus(:) = (velzminus(i+xoffset,j+yoffset,k+zoffset) - avg_beta / avg_alp) * &
+ cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ if(tadmor.eq.0) then
+
+!!$ Find minimum and maximum wavespeeds
+
+ charmin = min(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charmax = max(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+
+ charpm = charmax - charmin
+
+!!$ Calculate flux by standard formula
+
+ do m = 1,number_of_tracers
+
+ qdiff(m) = cons_m(m) - cons_p(m)
+
+ f1(m) = (charmax * fplus(m) - charmin * fminus(m) + &
+ charmax * charmin * qdiff(m)) / charpm
+ end do
+
+ else
+ ! Tadmor's semi-descrite scheme: JcP 160, 241 (2000)
+
+ charmax = max(abs(lamplus(1)), abs(lamplus(2)), abs(lamplus(3)), &
+ abs(lamplus(4)),abs(lamplus(5)),abs(lamminus(1)),abs(lamminus(2)), &
+ abs(lamminus(3)),abs(lamminus(4)),abs(lamminus(5)))
+
+ do m = 1,number_of_tracers
+
+ qdiff(m) = cons_m(m) - cons_p(m)
+
+ f1(m) = 0.5d0 * (fplus(m) + fminus(m)) - 0.5d0*charmax* &
+ qdiff(m)
+
+ end do
+
+
+ end if
+
+
+ cons_tracerflux(i,j,k,:) = f1(:)
+
+ end do
+ end do
+ end do
+
+end subroutine GRHydro_HLLE_TracerGeneralM
+
diff --git a/src/GRHydro_HLLEPolyM.F90 b/src/GRHydro_HLLEPolyM.F90
new file mode 100644
index 0000000..997375c
--- /dev/null
+++ b/src/GRHydro_HLLEPolyM.F90
@@ -0,0 +1,606 @@
+ /*@@
+ @file GRHydro_HLLEPolyM.F90
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Pedro Montero, Toni Font
+ @desc
+ The HLLE solver. Called from the wrapper function, so works in
+ all directions.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+
+#include "GRHydro_Macros.h"
+#include "SpaceMask.h"
+
+ /*@@
+ @routine GRHydro_HLLEM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Pedro Montero, Toni Font
+ @desc
+ The HLLE solver. Sufficiently simple that its just one big routine.
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Altered from Cactus 3 routines originally written by Toni Font.
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_HLLEM(CCTK_ARGUMENTS)
+ USE GRHydro_EigenproblemM
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k, m
+ CCTK_REAL, dimension(8) :: cons_p,cons_m,fplus,fminus,f1,qdiff
+ CCTK_REAL, dimension(7) :: prim_p, prim_m
+ CCTK_REAL, dimension(5) :: lamminus,lamplus
+ CCTK_REAL :: charmin, charmax, charpm,avg_alp,avg_det
+ CCTK_REAL :: gxxh, gxyh, gxzh, gyyh, gyzh, gzzh, uxxh, uxyh, &
+ uxzh, uyyh, uyzh, uzzh, avg_beta, usendh, alp_l, alp_r, &
+ cs2_p, cs2_m, dpdeps_p, dpdeps_m
+ CCTK_REAL :: rhoenth_p, rhoenth_m, avg_betax, avg_betay, avg_betaz
+ CCTK_REAL :: vxtp,vytp,vztp,vxtm,vytm,vztm,ab0p,ab0m,b2p,b2m,bdotvp,bdotvm
+ CCTK_REAL :: wp,wm,v2p,v2m,bxlowp,bxlowm,bylowp,bylowm,bzlowp,bzlowm,vA2m,vA2p
+ CCTK_REAL :: Bvecxlowp,Bvecxlowm,Bvecylowp,Bvecylowm,Bveczlowp,Bveczlowm
+ CCTK_REAL :: pressstarp,pressstarm,velxlowp,velxlowm,velylowp,velylowm,velzlowp,velzlowm
+
+ CCTK_INT :: type_bits, trivial, not_trivial
+
+ if (flux_direction == 1) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemX")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemX", &
+ &"trivial")
+ else if (flux_direction == 2) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemY")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemY", &
+ &"trivial")
+ else if (flux_direction == 3) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemZ")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemZ", &
+ &"trivial")
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil
+
+ f1 = 0.d0
+ lamminus = 0.d0
+ lamplus = 0.d0
+ cons_p = 0.d0
+ cons_m = 0.d0
+ fplus = 0.d0
+ fminus = 0.d0
+ qdiff = 0.d0
+
+!!$ Set the left (p for plus) and right (m_i for minus, i+1) states
+
+ cons_p(1) = densplus(i,j,k)
+ cons_p(2) = sxplus(i,j,k)
+ cons_p(3) = syplus(i,j,k)
+ cons_p(4) = szplus(i,j,k)
+ cons_p(5) = tauplus(i,j,k)
+ cons_p(6) = Bvecxplus(i,j,k)
+ cons_p(7) = Bvecyplus(i,j,k)
+ cons_p(8) = Bveczplus(i,j,k)
+
+ cons_m(1) = densminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(2) = sxminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(3) = syminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(4) = szminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(5) = tauminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(6) = Bvecxminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(7) = Bvecyminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(8) = Bveczminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(1) = rhoplus(i,j,k)
+ prim_p(2) = velxplus(i,j,k)
+ prim_p(3) = velyplus(i,j,k)
+ prim_p(4) = velzplus(i,j,k)
+ prim_p(5) = epsplus(i,j,k)
+ prim_p(6) = pressplus(i,j,k)
+ prim_p(7) = w_lorentzplus(i,j,k)
+
+ prim_m(1) = rhominus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(2) = velxminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(3) = velyminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(4) = velzminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(5) = epsminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(6) = pressminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(7) = w_lorentzminus(i+xoffset,j+yoffset,k+zoffset)
+
+!!$ Calculate various metric terms here.
+!!$ Note also need the average of the lapse at the
+!!$ left and right points.
+!!$
+!!$ In MHD, we need all three shift components regardless of the flux direction
+
+ if (shift_state .ne. 0) then
+ avg_betax = 0.5d0 * (betax(i+xoffset,j+yoffset,k+zoffset) + &
+ betax(i,j,k))
+ avg_betay = 0.5d0 * (betay(i+xoffset,j+yoffset,k+zoffset) + &
+ betay(i,j,k))
+ avg_betaz = 0.5d0 * (betaz(i+xoffset,j+yoffset,k+zoffset) + &
+ betaz(i,j,k))
+ if (flux_direction == 1) then
+ avg_beta=avg_betax
+ else if (flux_direction == 2) then
+ avg_beta=avg_betay
+ else if (flux_direction == 3) then
+ avg_beta=avg_betaz
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ avg_beta = 0.d0
+ avg_betax = 0.d0
+ avg_betay = 0.d0
+ avg_betaz = 0.d0
+ end if
+
+ avg_alp = 0.5 * (alp(i,j,k) + alp(i+xoffset,j+yoffset,k+zoffset))
+
+ gxxh = 0.5d0 * (gxx(i+xoffset,j+yoffset,k+zoffset) + gxx(i,j,k))
+ gxyh = 0.5d0 * (gxy(i+xoffset,j+yoffset,k+zoffset) + gxy(i,j,k))
+ gxzh = 0.5d0 * (gxz(i+xoffset,j+yoffset,k+zoffset) + gxz(i,j,k))
+ gyyh = 0.5d0 * (gyy(i+xoffset,j+yoffset,k+zoffset) + gyy(i,j,k))
+ gyzh = 0.5d0 * (gyz(i+xoffset,j+yoffset,k+zoffset) + gyz(i,j,k))
+ gzzh = 0.5d0 * (gzz(i+xoffset,j+yoffset,k+zoffset) + gzz(i,j,k))
+
+ avg_det = SPATIAL_DETERMINANT(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh)
+
+ vxtp = prim_p(2)-avg_betax/avg_alp
+ vytp = prim_p(3)-avg_betay/avg_alp
+ vztp = prim_p(4)-avg_betaz/avg_alp
+ vxtm = prim_m(2)-avg_betax/avg_alp
+ vytm = prim_m(3)-avg_betay/avg_alp
+ vztm = prim_m(4)-avg_betaz/avg_alp
+
+ call calc_vlow_blow(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh, &
+ prim_p(2),prim_p(3),prim_p(4),cons_p(6),cons_p(7),cons_p(8), &
+ velxlowp,velylowp,velzlowp,Bvecxlowp,Bvecylowp,Bveczlowp, &
+ bdotvp,b2p,v2p,wp,bxlowp,bylowp,bzlowp)
+ call calc_vlow_blow(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh, &
+ prim_m(2),prim_m(3),prim_m(4),cons_m(6),cons_m(7),cons_m(8), &
+ velxlowm,velylowm,velzlowm,Bvecxlowm,Bvecylowm,Bveczlowm, &
+ bdotvm,b2m,v2m,wm,bxlowm,bylowm,bzlowm)
+
+ ab0p = wp*bdotvp
+ ab0m = wm*bdotvm
+
+ vA2p = b2p/(rhoenth_p+b2p)
+ vA2m = b2m/(rhoenth_m+b2m)
+
+!!$ p^* = p+b^2/2 in Anton et al.
+ pressstarp = prim_p(6)+0.5d0*b2p
+ pressstarm = prim_m(6)+0.5d0*b2m
+
+
+!!$ If the Riemann problem is trivial, just calculate the fluxes from the
+!!$ left state and skip to the next cell
+
+ if (SpaceMask_CheckStateBitsF90(space_mask, i, j, k, type_bits, trivial)) then
+
+!!$ we now pass in the B-field as conserved and flux, the vtilde's instead of v's,
+!!$ pressstar instead of P, b_i, alp b^0, w, metric determinant,
+!!$ alp, and beta in the flux dir
+
+ if (flux_direction == 1) then
+ call num_x_fluxM(cons_p(1),cons_p(2),cons_p(3),cons_p(4),cons_p(5),&
+ cons_p(6),cons_p(7),cons_p(8),&
+ f1(1),f1(2),f1(3),f1(4),f1(5),f1(6),f1(7),f1(8),&
+ vxtp,vytp,vztp,pressstarp,bxlowp,bylowp,bzlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 2) then
+ call num_x_fluxM(cons_p(1),cons_p(3),cons_p(4),cons_p(2),cons_p(5),&
+ cons_p(7),cons_p(8),cons_p(6),&
+ f1(1),f1(3),f1(4),f1(2),f1(5),f1(7),f1(8),f1(6),&
+ vytp,vztp,vxtp,pressstarp,bylowp,bzlowp,bxlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 3) then
+ call num_x_fluxM(cons_p(1),cons_p(4),cons_p(2),cons_p(3),cons_p(5),&
+ cons_p(8),cons_p(6),cons_p(7),&
+ f1(1),f1(4),f1(2),f1(3),f1(5),f1(8),f1(6),f1(7), &
+ vztp,vxtp,vytp,pressstarp,bzlowp,bxlowp,bylowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ else !!! The end of this branch is right at the bottom of the routine
+
+ call UpperMetric(uxxh, uxyh, uxzh, uyyh, uyzh, uzzh, &
+ avg_det,gxxh, gxyh, gxzh, &
+ gyyh, gyzh, gzzh)
+
+ if (flux_direction == 1) then
+ usendh = uxxh
+ else if (flux_direction == 2) then
+ usendh = uyyh
+ else if (flux_direction == 3) then
+ usendh = uzzh
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!!$ Calculate the jumps in the conserved variables
+
+ qdiff(1) = cons_m(1) - cons_p(1)
+ qdiff(2) = cons_m(2) - cons_p(2)
+ qdiff(3) = cons_m(3) - cons_p(3)
+ qdiff(4) = cons_m(4) - cons_p(4)
+ qdiff(5) = cons_m(5) - cons_p(5)
+ qdiff(6) = cons_m(6) - cons_p(6)
+ qdiff(7) = cons_m(7) - cons_p(7)
+ qdiff(8) = cons_m(8) - cons_p(8)
+
+!!$ Eigenvalues and fluxes either side of the cell interface
+
+ if (flux_direction == 1) then
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_m(1),prim_m(2),prim_m(3),prim_m(4),prim_m(5),prim_m(7), &
+ cons_m(6),cons_m(7),cons_m(8),&
+ lamminus,gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvaluesM(GRHydro_eos_handle, &
+ prim_p(1),prim_p(2),prim_p(3),prim_p(4),prim_p(5),prim_p(7), &
+ cons_p(6),cons_p(7),cons_p(8),&
+ lamplus,gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ call num_x_fluxM(cons_p(1),cons_p(2),cons_p(3),cons_p(4),cons_p(5),&
+ cons_p(6),cons_p(7),cons_p(8),&
+ fplus(1),fplus(2),fplus(3),fplus(4),fplus(5),fplus(6),fplus(7),fplus(8),&
+ vxtp,vytp,vztp,pressstarp,bxlowp,bylowp,bzlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ call num_x_fluxM(cons_m(1),cons_m(2),cons_m(3),cons_m(4),cons_m(5),&
+ cons_m(6),cons_m(7),cons_m(8),&
+ fminus(1),fminus(2),fminus(3),fminus(4),fminus(5),&
+ fminus(6),fminus(7),fminus(8),&
+ vxtm,vytm,vztm,pressstarm,bxlowm,bylowm,bzlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 2) then
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_m(1),prim_m(3),prim_m(4),prim_m(2),prim_m(5),prim_m(7), &
+ cons_m(7),cons_m(8),cons_m(6),&
+ lamminus,gyyh,gyzh,gxyh,gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvaluesM(GRHydro_eos_handle, &
+ prim_p(1),prim_p(3),prim_p(4),prim_p(2),prim_p(5),prim_p(7), &
+ cons_p(7),cons_p(8),cons_p(6),&
+ lamplus,gyyh,gyzh,gxyh,gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ call num_x_fluxM(cons_p(1),cons_p(3),cons_p(4),cons_p(2),cons_p(5),&
+ cons_p(7),cons_p(8),cons_p(6),&
+ fplus(1),fplus(3),fplus(4),fplus(2),fplus(5),fplus(7),fplus(8),fplus(6),&
+ vytp,vztp,vxtp,pressstarp,bylowp,bzlowp,bxlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ call num_x_fluxM(cons_m(1),cons_m(3),cons_m(4),cons_m(2),cons_m(5),&
+ cons_m(7),cons_m(8),cons_m(6),&
+ fminus(1),fminus(3),fminus(4),fminus(2),fminus(5),&
+ fminus(7),fminus(8),fminus(6),&
+ vytm,vztm,vxtm,pressstarm,bylowm,bzlowm,bxlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else if (flux_direction == 3) then
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_m(1),prim_m(4),prim_m(2),prim_m(3),prim_m(5),prim_m(7), &
+ cons_m(8),cons_m(6),cons_m(7),&
+ lamminus,gzzh,gxzh,gyzh,gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_p(1),prim_p(4),prim_p(2),prim_p(3),prim_p(5),prim_p(7), &
+ cons_p(8),cons_p(6),cons_p(7),&
+ lamplus,gzzh,gxzh,gyzh,gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ call num_x_fluxM(cons_p(1),cons_p(4),cons_p(2),cons_p(3),cons_p(5),&
+ cons_p(8),cons_p(6),cons_p(7),&
+ fplus(1),fplus(4),fplus(2),fplus(3),fplus(5),fplus(8),fplus(6),fplus(7), &
+ vztp,vxtp,vytp,pressstarp,bzlowp,bxlowp,bylowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+ call num_x_fluxM(cons_m(1),cons_m(4),cons_m(2),cons_m(3),cons_m(5),&
+ cons_m(8),cons_m(6),cons_m(7),&
+ fminus(1),fminus(4),fminus(2),fminus(3),fminus(5), &
+ fminus(8),fminus(6),fminus(7), &
+ vztm,vxtm,vytm,pressstarm,bzlowm,bxlowm,bylowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!!$ Find minimum and maximum wavespeeds
+
+ charmin = min(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charmax = max(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charpm = charmax - charmin
+
+!!$ Calculate flux by standard formula
+
+ do m = 1,8
+
+ qdiff(m) = cons_m(m) - cons_p(m)
+
+ f1(m) = (charmax * fplus(m) - charmin * fminus(m) + &
+ charmax * charmin * qdiff(m)) / charpm
+
+ end do
+
+ end if !!! The end of the SpaceMask check for a trivial RP.
+
+ densflux(i, j, k) = f1(1)
+ sxflux(i, j, k) = f1(2)
+ syflux(i, j, k) = f1(3)
+ szflux(i, j, k) = f1(4)
+ tauflux(i, j, k) = f1(5)
+ Bvecxflux(i, j, k) = f1(6)
+ Bvecyflux(i, j, k) = f1(7)
+ Bveczflux(i, j, k) = f1(8)
+
+ end do
+ end do
+ end do
+
+end subroutine GRHydro_HLLEM
+
+ /*@@
+ @routine GRHydro_HLLE_TracerM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ HLLE just for the tracer.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_HLLE_TracerM(CCTK_ARGUMENTS)
+
+ USE GRHydro_EigenproblemM
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k, m
+ CCTK_REAL, dimension(number_of_tracers) :: cons_p,cons_m,fplus,fminus,f1
+ CCTK_REAL, dimension(5) :: lamminus,lamplus
+ CCTK_REAL, dimension(number_of_tracers) :: qdiff
+ CCTK_REAL, dimension(7) :: prim_p, prim_m
+ CCTK_REAL, dimension(3) :: mag_p, mag_m
+ CCTK_REAL :: charmin, charmax, charpm,avg_alp,avg_det
+ CCTK_REAL :: gxxh, gxyh, gxzh, gyyh, gyzh, gzzh, uxxh, uxyh, &
+ uxzh, uyyh, uyzh, uzzh, avg_beta, usendh, alp_l, alp_r, &
+ cs2_p, cs2_m, dpdeps_p, dpdeps_m
+ CCTK_REAL :: b2p,b2m,vA2m,vA2p
+
+ CCTK_INT :: type_bits, trivial, not_trivial
+
+ if (flux_direction == 1) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemX")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemX", &
+ &"trivial")
+ else if (flux_direction == 2) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemY")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemY", &
+ &"trivial")
+ else if (flux_direction == 3) then
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_RiemannProblemZ")
+ call SpaceMask_GetStateBits(trivial, "Hydro_RiemannProblemZ", &
+ &"trivial")
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil
+
+ f1 = 0.d0
+ lamminus = 0.d0
+ lamplus = 0.d0
+ cons_p = 0.d0
+ cons_m = 0.d0
+ mag_p = 0.d0
+ mag_m = 0.d0
+ fplus = 0.d0
+ fminus = 0.d0
+ qdiff = 0.d0
+
+!!$ Set the left (p for plus) and right (m_i for minus, i+1) states
+
+ cons_p(:) = cons_tracerplus(i,j,k,:)
+ cons_m(:) = cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+
+ mag_p(1) = Bvecxplus(i,j,k)
+ mag_p(2) = Bvecyplus(i,j,k)
+ mag_p(3) = Bveczplus(i,j,k)
+
+ mag_m(1) = Bvecxminus(i+xoffset,j+yoffset,k+zoffset)
+ mag_m(2) = Bvecyminus(i+xoffset,j+yoffset,k+zoffset)
+ mag_m(3) = Bveczminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(1) = rhoplus(i,j,k)
+ prim_p(2) = velxplus(i,j,k)
+ prim_p(3) = velyplus(i,j,k)
+ prim_p(4) = velzplus(i,j,k)
+ prim_p(5) = epsplus(i,j,k)
+ prim_p(6) = pressplus(i,j,k)
+ prim_p(7) = w_lorentzplus(i,j,k)
+
+ prim_m(1) = rhominus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(2) = velxminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(3) = velyminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(4) = velzminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(5) = epsminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(6) = pressminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(7) = w_lorentzminus(i+xoffset,j+yoffset,k+zoffset)
+
+!!$ Calculate various metric terms here.
+!!$ Note also need the average of the lapse at the
+!!$ left and right points.
+
+ if (shift_state .ne. 0) then
+ if (flux_direction == 1) then
+ avg_beta = 0.5d0 * (betax(i+xoffset,j+yoffset,k+zoffset) + &
+ betax(i,j,k))
+ else if (flux_direction == 2) then
+ avg_beta = 0.5d0 * (betay(i+xoffset,j+yoffset,k+zoffset) + &
+ betay(i,j,k))
+ else if (flux_direction == 3) then
+ avg_beta = 0.5d0 * (betaz(i+xoffset,j+yoffset,k+zoffset) + &
+ betaz(i,j,k))
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ avg_beta = 0.d0
+ end if
+
+ avg_alp = 0.5 * (alp(i,j,k) + alp(i+xoffset,j+yoffset,k+zoffset))
+
+ gxxh = 0.5d0 * (gxx(i+xoffset,j+yoffset,k+zoffset) + gxx(i,j,k))
+ gxyh = 0.5d0 * (gxy(i+xoffset,j+yoffset,k+zoffset) + gxy(i,j,k))
+ gxzh = 0.5d0 * (gxz(i+xoffset,j+yoffset,k+zoffset) + gxz(i,j,k))
+ gyyh = 0.5d0 * (gyy(i+xoffset,j+yoffset,k+zoffset) + gyy(i,j,k))
+ gyzh = 0.5d0 * (gyz(i+xoffset,j+yoffset,k+zoffset) + gyz(i,j,k))
+ gzzh = 0.5d0 * (gzz(i+xoffset,j+yoffset,k+zoffset) + gzz(i,j,k))
+
+ avg_det = SPATIAL_DETERMINANT(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh)
+
+ call UpperMetric(uxxh, uxyh, uxzh, uyyh, uyzh, uzzh, &
+ avg_det,gxxh, gxyh, gxzh, &
+ gyyh, gyzh, gzzh)
+
+ if (flux_direction == 1) then
+ usendh = uxxh
+ else if (flux_direction == 2) then
+ usendh = uyyh
+ else if (flux_direction == 3) then
+ usendh = uzzh
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!!$ b^2 = (1-v^2)B^2+(B dot v)^2
+ b2p=DOTP2(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,mag_p(1),mag_p(2),mag_p(3))/prim_p(7)**2 + &
+ (DOTP(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,prim_p(2),prim_p(3),prim_p(4),mag_p(1),mag_p(2),mag_p(3)))**2
+ b2m=DOTP2(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,mag_m(1),mag_m(2),mag_m(3))/prim_m(7)**2 + &
+ (DOTP(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,prim_m(2),prim_m(3),prim_m(4),mag_m(1),mag_m(2),mag_m(3)))**2
+
+ vA2p = b2p/(prim_p(1)*(1.0d0+prim_p(5))+prim_p(6)+b2p)
+ vA2m = b2m/(prim_m(1)*(1.0d0+prim_m(5))+prim_m(6)+b2m)
+
+!!$ Calculate the jumps in the conserved variables
+
+ qdiff = cons_m - cons_p
+
+!!$ Eigenvalues and fluxes either side of the cell interface
+
+ if (flux_direction == 1) then
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_m(1),prim_m(2),prim_m(3),prim_m(4),prim_m(5),prim_m(7), &
+ cons_m(6),cons_m(7),cons_m(8),&
+ lamminus,gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvaluesM(GRHydro_eos_handle, &
+ prim_p(1),prim_p(2),prim_p(3),prim_p(4),prim_p(5),prim_p(7), &
+ cons_p(6),cons_p(7),cons_p(8),&
+ lamplus,gxxh,gxyh,gxzh,gyyh,gyzh,gzzh,&
+ usendh,avg_alp,avg_beta)
+ fplus(:) = (velxplus(i,j,k) - avg_beta / avg_alp) * &
+ cons_tracerplus(i,j,k,:)
+ fminus(:) = (velxminus(i+xoffset,j+yoffset,k+zoffset) - avg_beta / avg_alp) * &
+ cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+ else if (flux_direction == 2) then
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_m(1),prim_m(3),prim_m(4),prim_m(2),prim_m(5),prim_m(7), &
+ cons_m(7),cons_m(8),cons_m(6),&
+ lamminus,gyyh,gyzh,gxyh,gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvaluesM(GRHydro_eos_handle, &
+ prim_p(1),prim_p(3),prim_p(4),prim_p(2),prim_p(5),prim_p(7), &
+ cons_p(7),cons_p(8),cons_p(6),&
+ lamplus,gyyh,gyzh,gxyh,gzzh,gxzh,gxxh,&
+ usendh,avg_alp,avg_beta)
+ fplus(:) = (velyplus(i,j,k) - avg_beta / avg_alp) * &
+ cons_tracerplus(i,j,k,:)
+ fminus(:) = (velyminus(i+xoffset,j+yoffset,k+zoffset) - avg_beta / avg_alp) * &
+ cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+ else if (flux_direction == 3) then
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_m(1),prim_m(4),prim_m(2),prim_m(3),prim_m(5),prim_m(7), &
+ cons_m(8),cons_m(6),cons_m(7),&
+ lamminus,gzzh,gxzh,gyzh,gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ call eigenvaluesM(GRHydro_eos_handle,&
+ prim_p(1),prim_p(4),prim_p(2),prim_p(3),prim_p(5),prim_p(7), &
+ cons_p(8),cons_p(6),cons_p(7),&
+ lamplus,gzzh,gxzh,gyzh,gxxh,gxyh,gyyh,&
+ usendh,avg_alp,avg_beta)
+ fplus(:) = (velzplus(i,j,k) - avg_beta / avg_alp) * &
+ cons_tracerplus(i,j,k,:)
+ fminus(:) = (velzminus(i+xoffset,j+yoffset,k+zoffset) - avg_beta / avg_alp) * &
+ cons_tracerminus(i+xoffset,j+yoffset,k+zoffset,:)
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!!$ Find minimum and maximum wavespeeds
+
+ charmin = min(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charmax = max(0.d0, lamplus(1), lamplus(2), lamplus(3), &
+ lamplus(4),lamplus(5), lamminus(1),lamminus(2),lamminus(3),&
+ lamminus(4),lamminus(5))
+
+ charpm = charmax - charmin
+
+!!$ Calculate flux by standard formula
+
+ do m = 1,number_of_tracers
+
+ qdiff(m) = cons_m(m) - cons_p(m)
+
+ f1(m) = (charmax * fplus(m) - charmin * fminus(m) + &
+ charmax * charmin * qdiff(m)) / charpm
+
+ end do
+
+ cons_tracerflux(i, j, k,:) = f1(:)
+!!$
+!!$ if ( ((flux_direction.eq.3).and.(i.eq.4).and.(j.eq.4)).or.&
+!!$ ((flux_direction.eq.2).and.(i.eq.4).and.(k.eq.4)).or.&
+!!$ ((flux_direction.eq.1).and.(j.eq.4).and.(k.eq.4))&
+!!$ ) then
+!!$ write(*,*) flux_direction, i, j, k, f1(1), cons_m(1), cons_p(1)
+!!$ end if
+
+ end do
+ end do
+end do
+
+
+end subroutine GRHydro_HLLE_TracerM
+
diff --git a/src/GRHydro_InterfacesM.h b/src/GRHydro_InterfacesM.h
new file mode 100644
index 0000000..7479278
--- /dev/null
+++ b/src/GRHydro_InterfacesM.h
@@ -0,0 +1,84 @@
+module Con2PrimM_fortran_interfaces
+ implicit none
+
+ interface
+
+ subroutine GRHydro_Con2PrimM_pt( handle, &
+ dens, &
+ sx, sy, sz, &
+ tau, &
+ rho, &
+ velx, vely, velz,&
+ epsilon, pressure,&
+ w_lorentz, &
+ gxx, gxy, gxz, &
+ gyy, gyz, gzz, &
+ uxx, uxy, uxz,&
+ uyy, uyz, uzz,&
+ det,&
+ Bx, By, Bz, &
+ bsq,&
+ epsnegative, &
+ retval)
+
+ implicit none
+ CCTK_INT handle
+ CCTK_REAL dens
+ CCTK_REAL sx, sy, sz
+ CCTK_REAL tau
+ CCTK_REAL rho
+ CCTK_REAL velx, vely, velz
+ CCTK_REAL epsilon, pressure
+ CCTK_REAL w_lorentz
+ CCTK_REAL gxx, gxy, gxz
+ CCTK_REAL gyy, gyz, gzz
+ CCTK_REAL uxx, uxy, uxz
+ CCTK_REAL uyy, uyz, uzz
+ CCTK_REAL det
+ CCTK_REAL Bx, By, Bz
+ CCTK_REAL bsq
+ CCTK_INT epsnegative
+ CCTK_REAL retval
+ end subroutine GRHydro_Con2PrimM_pt
+
+ subroutine GRHydro_Con2PrimM_Polytype_pt( handle, &
+ dens, &
+ sx, sy, sz, &
+ tau, &
+ rho, &
+ velx, vely, velz,&
+ epsilon, pressure,&
+ w_lorentz, &
+ gxx, gxy, gxz, &
+ gyy, gyz, gzz, &
+ uxx, uxy, uxz,&
+ uyy, uyz, uzz,&
+ det,&
+ Bx, By, Bz, &
+ bsq,&
+ epsnegative, &
+ retval)
+
+ implicit none
+ CCTK_INT handle
+ CCTK_REAL dens
+ CCTK_REAL sx, sy, sz
+ CCTK_REAL tau
+ CCTK_REAL rho
+ CCTK_REAL velx, vely, velz
+ CCTK_REAL epsilon, pressure
+ CCTK_REAL w_lorentz
+ CCTK_REAL gxx, gxy, gxz
+ CCTK_REAL gyy, gyz, gzz
+ CCTK_REAL uxx, uxy, uxz
+ CCTK_REAL uyy, uyz, uzz
+ CCTK_REAL det
+ CCTK_REAL Bx, By, Bz
+ CCTK_REAL bsq
+ CCTK_INT epsnegative
+ CCTK_REAL retval
+ end subroutine GRHydro_Con2PrimM_Polytype_pt
+
+ end interface
+
+end module Con2PrimM_fortran_interfaces
diff --git a/src/GRHydro_Macros.h b/src/GRHydro_Macros.h
index c3cdd69..7009b86 100644
--- a/src/GRHydro_Macros.h
+++ b/src/GRHydro_Macros.h
@@ -1,3 +1,12 @@
-#define SPATIAL_DETERMINANT(gxx,gxy,gxz,gyy,gyz,gzz) \
- (-(gxz)**2*(gyy) + 2*(gxy)*(gxz)*(gyz) - (gxx)*(gyz)**2 - (gxy)**2*(gzz) \
- + (gxx)*(gyy)*(gzz))
+#define SPATIAL_DETERMINANT(gxx_,gxy_,gxz_,gyy_,gyz_,gzz_) \
+ (-(gxz_)**2*(gyy_) + 2*(gxy_)*(gxz_)*(gyz_) - (gxx_)*(gyz_)**2 - (gxy_)**2*(gzz_) \
+ + (gxx_)*(gyy_)*(gzz_))
+
+#define DOTP(gxx_,gxy_,gxz_,gyy_,gyz_,gzz_,x1_,y1_,z1_,x2_,y2_,z2_) \
+ ( (gxx_)*(x1_)*(x2_)+(gyy_)*(y1_)*(y2_)+(gzz_)*(z1_)*(z2_)+ \
+ (gxy_)*( (x1_)*(y2_)+(y1_)*(x2_) )+(gxz_)*( (x1_)*(z2_)+(z1_)*(x2_) )+\
+ (gyz_)*( (y1_)*(z2_)+(z1_)*(y2_) ) )
+
+#define DOTP2(gxx_,gxy_,gxz_,gyy_,gyz_,gzz_,x_,y_,z_) \
+ ( (gxx_)*(x_)**2+(gyy_)*(y_)**2+(gzz_)*(z_)**2+ \
+ 2.0*( (gxy_)*(x_)*(y_)+(gxz_)*(x_)*(z_)+(gyz_)*(y_)*(z_) ) )
diff --git a/src/GRHydro_PPMM.F90 b/src/GRHydro_PPMM.F90
new file mode 100644
index 0000000..0ff4d72
--- /dev/null
+++ b/src/GRHydro_PPMM.F90
@@ -0,0 +1,820 @@
+ /*@@
+ @file GRHydro_PPMM.F90
+ @date Sun Feb 10 16:53:29 2002
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Toni Font, Luca Baiotti, Frank Loeffler
+ @desc
+ Routines to do PPM reconstruction.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "GRHydro_Macros.h"
+
+!!subroutine PPM_TVD(origm, orig, origp, bextm, bextp)
+!! CCTK_REAL :: origm, orig, origp, bextm, bextp
+!! CCTK_REAL :: dloc, dupw, delta
+!!
+!! dupw = orig - origm
+!! dloc = origp - orig
+!! if (dupw*dloc < 0.d0) then
+!! delta=0.d0
+!! else if (abs(dupw) < abs(dloc)) then
+!! delta=dupw
+!! else
+!! delta=dloc
+!! end if
+!! bextm = orig - 0.5d0 * delta
+!! bextp = orig + 0.5d0 * delta
+!!end subroutine PPM_TVD
+
+ /*@@
+ @routine SimplePPM_1dM
+ @date Thu Feb 14 19:08:52 2002
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke, Toni Font
+ @desc
+ The simple PPM reconstruction routine that applies along
+ each one dimensional slice.
+
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Written in frustration when IH couldn''t get Toni''s original code
+ to work.
+ @endhistory
+
+@@*/
+
+#define SpaceMask_CheckStateBitsF90_1D(mask,i,type_bits,state_bits) \
+ (iand(mask((i)),(type_bits)).eq.(state_bits))
+
+
+subroutine SimplePPM_1dM(handle,poly,nx,dx,&
+ rho,velx,vely,velz,Bvcx,Bvcy,Bvcz,eps,press,&
+ rhominus,velxminus,velyminus,velzminus,Bvcxminus,Bvcyminus,Bvczminus,epsminus,&
+ rhoplus,velxplus,velyplus,velzplus,Bvcxplus,Bvcyplus,Bvczplus,epsplus,&
+ trivial_rp, hydro_excision_mask,&
+ gxx, gxy, gxz, gyy, gyz, gzz, psi4, beta, alp, w_lorentz, &
+ dir, ni, nj, nrx, nry, nrz, ev_l, ev_r, xw)
+
+ USE GRHydro_Scalars
+ USE GRHydro_EigenproblemM
+
+ implicit none
+
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_INT :: handle,poly,nx
+ CCTK_REAL :: dx
+ CCTK_REAL, dimension(nx) :: rho,velx,vely,velz,eps
+ CCTK_REAL, dimension(nx) :: Bvcx,Bvcy,Bvcz
+ CCTK_REAL, dimension(nx) :: rhominus,velxminus,velyminus,velzminus,epsminus
+ CCTK_REAL, dimension(nx) :: Bvcxminus,Bvcyminus,Bvczminus
+ CCTK_REAL, dimension(nx) :: rhoplus,velxplus,velyplus,velzplus,epsplus
+ CCTK_REAL, dimension(nx) :: Bvcxplus,Bvcyplus,Bvczplus
+ CCTK_REAL, dimension(nx) :: rhominusl,velxminusl,velyminusl,velzminusl
+ CCTK_REAL, dimension(nx) :: Bvcxminusl,Bvcyminusl,Bvczminusl
+ CCTK_REAL, dimension(nx) :: epsminusl
+ CCTK_REAL, dimension(nx) :: rhoplusl,velxplusl,velyplusl,velzplusl,epsplusl
+ CCTK_REAL, dimension(nx) :: Bvcxplusl,Bvcyplusl,Bvczplusl
+ CCTK_REAL, dimension(nx) :: rhominusr,velxminusr,velyminusr,velzminusr
+ CCTK_REAL, dimension(nx) :: Bvcxminusr,Bvcyminusr,Bvczminusr
+ CCTK_REAL, dimension(nx) :: epsminusr
+ CCTK_REAL, dimension(nx) :: rhoplusr,velxplusr,velyplusr,velzplusr,epsplusr
+ CCTK_REAL, dimension(nx) :: Bvcxplusr,Bvcyplusr,Bvczplusr
+
+ CCTK_INT :: i,s
+ CCTK_REAL, dimension(nx) :: drho,dvelx,dvely,dvelz,deps
+ CCTK_REAL, dimension(nx) :: dBvcx,dBvcy,dBvcz
+ CCTK_REAL, dimension(nx) :: dmrho,dmvelx,dmvely,dmvelz,dmeps
+ CCTK_REAL, dimension(nx) :: dmBvcx,dmBvcy,dmBvcz
+ CCTK_REAL, dimension(nx) :: press,dpress,d2rho,tilde_flatten
+ CCTK_REAL :: dpress2,dvel,w,flatten,eta,etatilde
+
+ logical, dimension(nx) :: trivial_rp
+
+ CCTK_INT, dimension(nx) :: hydro_excision_mask
+
+ CCTK_REAL, dimension(nx) :: gxx, gxy, gxz, gyy, gyz, gzz, &
+ psi4, beta, alp, w_lorentz
+ CCTK_INT :: dir, ni, nj, nrx, nry, nrz
+ CCTK_REAL, dimension(nrx, nry, nrz) :: ev_l, ev_r, xw
+
+ CCTK_REAL :: uxx, uxy, uxz, uyy, uyz, uzz, det
+ CCTK_REAL, dimension(5) :: lam
+ CCTK_REAL :: dupw, dloc, delta
+ CCTK_REAL :: agxx, agxy, agxz, agyy, agyz, agzz
+ CCTK_REAL, dimension(nx) :: xwind, l_ev_l, l_ev_r
+
+ logical :: cond
+
+
+!!$ Initially, all the Riemann problems will be trivial
+
+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))
+ dBvcx(i) = 0.5d0 * (Bvcx(i+1) - Bvcx(i-1))
+ dBvcy(i) = 0.5d0 * (Bvcy(i+1) - Bvcy(i-1))
+ dBvcz(i) = 0.5d0 * (Bvcz(i+1) - Bvcz(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
+
+ 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)
+ STEEP(Bvcx, dBvcx, dmBvcx)
+ STEEP(Bvcy, dBvcy, dmBvcy)
+ STEEP(Bvcz, dBvcz, dmBvcz)
+ 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
+
+ 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)
+
+ Bvcxplus(i) = 0.5d0 * (Bvcx(i) + Bvcx(i+1)) + &
+ (dmBvcx(i) - dmBvcx(i+1)) / 6.d0
+ Bvcxminus(i+1) = Bvcxplus(i)
+ Bvcyplus(i) = 0.5d0 * (Bvcy(i) + Bvcy(i+1)) + &
+ (dmBvcy(i) - dmBvcy(i+1)) / 6.d0
+ Bvcyminus(i+1) = Bvcyplus(i)
+ Bvczplus(i) = 0.5d0 * (Bvcz(i) + Bvcz(i+1)) + &
+ (dmBvcz(i) - dmBvcz(i+1)) / 6.d0
+ Bvczminus(i+1) = Bvczplus(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
+
+!!$Discontinuity steepening. See (1.14-17) of C&W.
+!!$This is the detect routine which mat be activated with the ppm_detect parameter
+!!$Note that this part really also depends on the grid being even.
+!!$Note also that we don''t have access to the gas constant gamma.
+!!$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
+
+ !!$ 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*( psi4(i)*gxx(i) + psi4(i+1)*gxx(i+1) )
+ agxy = 0.5d0*( psi4(i)*gxy(i) + psi4(i+1)*gxy(i+1) )
+ agxz = 0.5d0*( psi4(i)*gxz(i) + psi4(i+1)*gxz(i+1) )
+ agyy = 0.5d0*( psi4(i)*gyy(i) + psi4(i+1)*gyy(i+1) )
+ agyz = 0.5d0*( psi4(i)*gyz(i) + psi4(i+1)*gyz(i+1) )
+ agzz = 0.5d0*( psi4(i)*gzz(i) + psi4(i+1)*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 eigenvaluesM(handle,&
+ D_UPW(rho), D_UPW(velx), D_UPW(vely), D_UPW(velz), &
+ D_UPW(eps), D_UPW(w_lorentz),&
+ D_UPW(Bvcx), D_UPW(Bvcy), D_UPW(Bvcz), 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)
+#define LEFTMINUS(x,xminus) xminus(i+1)= abs(xwind(i)) * LEFT1(x) + \
+ (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)
+#define RIGHTMINUS(x,xminus) xminus(i+1)= abs(xwind(i)) * RIGHT1(x) + \
+ (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)
+ LEFTPLUS(Bvcx, Bvcxplus)
+ LEFTMINUS(Bvcx, Bvcxminus)
+ LEFTPLUS(Bvcy, Bvcyplus)
+ LEFTMINUS(Bvcy, Bvcyminus)
+ LEFTPLUS(Bvcz, Bvczplus)
+ LEFTMINUS(Bvcz, Bvczminus)
+ 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)
+ RIGHTPLUS(Bvcx, Bvcxplus)
+ RIGHTMINUS(Bvcx, Bvcxminus)
+ RIGHTPLUS(Bvcy, Bvcyplus)
+ RIGHTMINUS(Bvcy, Bvcyminus)
+ RIGHTPLUS(Bvcz, Bvczplus)
+ RIGHTMINUS(Bvcz, Bvczminus)
+ 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))
+ CHECK(Bvcx, Bvcxplus(i))
+ CHECK(Bvcx, Bvcxminus(i+1))
+ CHECK(Bvcy, Bvcyplus(i))
+ CHECK(Bvcy, Bvcyminus(i+1))
+ CHECK(Bvcz, Bvczplus(i))
+ CHECK(Bvcz, Bvczminus(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
+ 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)
+ if ( (abs(dpress(i)) > ppm_epsilon * min(press(i-1),press(i+1))) .and. &
+ (dvel < 0.d0) ) then
+ w = 1.d0
+ else
+ w = 0.d0
+ end if
+ if (abs(dpress2) < ppm_small) then
+ tilde_flatten(i) = 1.d0
+ else
+ tilde_flatten(i) = max(0.d0, 1.d0 - w * max(0.d0, ppm_omega2 * &
+ (dpress(i) / dpress2 - ppm_omega1)))
+ end if
+ 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)
+ Bvcxplus(i) = flatten * Bvcxplus(i) + (1.d0 - flatten) * Bvcx(i)
+ Bvcxminus(i) = flatten * Bvcxminus(i) + (1.d0 - flatten) * Bvcx(i)
+ Bvcyplus(i) = flatten * Bvcyplus(i) + (1.d0 - flatten) * Bvcy(i)
+ Bvcyminus(i) = flatten * Bvcyminus(i) + (1.d0 - flatten) * Bvcy(i)
+ Bvczplus(i) = flatten * Bvczplus(i) + (1.d0 - flatten) * Bvcz(i)
+ Bvczminus(i) = flatten * Bvczminus(i) + (1.d0 - flatten) * Bvcz(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)
+ Bvcxplus(i) = flatten * Bvcxplus(i) + (1.d0 - flatten) * Bvcx(i)
+ Bvcxminus(i) = flatten * Bvcxminus(i) + (1.d0 - flatten) * Bvcx(i)
+ Bvcyplus(i) = flatten * Bvcyplus(i) + (1.d0 - flatten) * Bvcy(i)
+ Bvcyminus(i) = flatten * Bvcyminus(i) + (1.d0 - flatten) * Bvcy(i)
+ Bvczplus(i) = flatten * Bvczplus(i) + (1.d0 - flatten) * Bvcz(i)
+ Bvczminus(i) = flatten * Bvczminus(i) + (1.d0 - flatten) * Bvcz(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
+
+
+!!$ 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&&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ xminus(i) = x(i) &&\
+ xplus(i) = x(i) &&\
+ else if (6.d0 * (xplus(i) - xminus(i)) * (x(i) - 0.5d0 * \
+ (xplus(i) + xminus(i))) > \
+ (xplus(i) - xminus(i))**2) then &&\
+ xminus(i) = 3.d0 * x(i) - 2.d0 * xplus(i) &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ else if (6.d0 * (xplus(i) - xminus(i)) * (x(i) - 0.5d0 * \
+ (xplus(i) + xminus(i))) < \
+ -(xplus(i) - xminus(i))**2) then &&\
+ xplus(i) = 3.d0 * x(i) - 2.d0 * xminus(i) &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ end if &&\
+ if (.not.( (xplus(i).eq.x(i)) .and. (x(i).eq.xminus(i)) ) ) then &&\
+ trivial_rp(i-1) = .false. &&\
+ trivial_rp(i) = .false. &&\
+ end if
+
+ MON(rhominus,rho,rhoplus)
+ MON(velxminus,velx,velxplus)
+ MON(velyminus,vely,velyplus)
+ MON(velzminus,velz,velzplus)
+ MON(Bvcxminus,Bvcx,Bvcxplus)
+ MON(Bvcyminus,Bvcy,Bvcyplus)
+ MON(Bvczminus,Bvcz,Bvczplus)
+ end do
+ if (poly .eq. 0) then
+ do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+ MON(epsminus,eps,epsplus)
+ end do
+ end if
+
+ if (check_for_trivial_rp .eq. 0) then
+ trivial_rp = .false.
+ end if
+
+ !!$ excision
+ do i = 1, nx
+ if (GRHydro_enable_internal_excision /= 0 .and. &
+ (hydro_excision_mask(i) .ne. 0)) then
+ if (i .gt. 1) then
+ trivial_rp(i-1)=.true.
+ end if
+ trivial_rp(i)=.true.
+ else
+ !!$ Do not optimize cond away by combining the 'if's. Fortran does not
+ !!$ have to follow the order of sub-expressions given here and might
+ !!$ access outside the array range
+ cond = .false.
+ if (i .gt. 1 .and. GRHydro_enable_internal_excision /= 0) then
+ cond = hydro_excision_mask(i-1) .ne. 0
+ end if
+ if (cond) then
+ rhominus(i)=rho(i)
+ rhoplus(i)=rho(i)
+ velxminus(i)=velx(i)
+ velxplus(i)=velx(i)
+ velyminus(i)=vely(i)
+ velyplus(i)=vely(i)
+ velzminus(i)=velz(i)
+ velzplus(i)=velz(i)
+ Bvcxminus(i)=Bvcx(i)
+ Bvcxplus(i)=Bvcx(i)
+ Bvcyminus(i)=Bvcy(i)
+ Bvcyplus(i)=Bvcy(i)
+ Bvczminus(i)=Bvcz(i)
+ Bvczplus(i)=Bvcz(i)
+ rhominus(i-1)=rho(i)
+ rhoplus(i-1)=rho(i)
+ velxminus(i-1)=velx(i)
+ velxplus(i-1)=velx(i)
+ velyminus(i-1)=vely(i)
+ velyplus(i-1)=vely(i)
+ velzminus(i-1)=velz(i)
+ velzplus(i-1)=velz(i)
+ Bvcxminus(i-1)=Bvcx(i)
+ Bvcxplus(i-1)=Bvcx(i)
+ Bvcyminus(i-1)=Bvcy(i)
+ Bvcyplus(i-1)=Bvcy(i)
+ Bvczminus(i-1)=Bvcz(i)
+ Bvczplus(i-1)=Bvcz(i)
+ if (poly .eq. 0) then
+ epsminus(i)=eps(i)
+ epsplus(i)=eps(i)
+ epsminus(i-1)=eps(i)
+ epsplus(i-1)=eps(i)
+ end if
+ else
+ cond = .false.
+ if ((i.gt.2) .and. (i.lt.nx) .and. GRHydro_enable_internal_excision /= 0) then
+ cond = (ppm_mppm .eq. 0) .and. (hydro_excision_mask(i-2) .ne. 0)
+ end if
+ if (cond) then
+ call PPM_TVD(rho(i-1), rho(i), rho(i+1), rhominus(i), rhoplus(i))
+ call PPM_TVD(velx(i-1), velx(i), velx(i+1), velxminus(i), velxplus(i))
+ call PPM_TVD(vely(i-1), vely(i), vely(i+1), velyminus(i), velyplus(i))
+ call PPM_TVD(velz(i-1), velz(i), velz(i+1), velzminus(i), velzplus(i))
+ call PPM_TVD(Bvcx(i-1), Bvcx(i), Bvcx(i+1), Bvcxminus(i), Bvcxplus(i))
+ call PPM_TVD(Bvcy(i-1), Bvcy(i), Bvcy(i+1), Bvcyminus(i), Bvcyplus(i))
+ call PPM_TVD(Bvcz(i-1), Bvcz(i), Bvcz(i+1), Bvczminus(i), Bvczplus(i))
+ if (poly .eq. 0) then
+ call PPM_TVD(eps(i-1), eps(i), eps(i+1), epsminus(i), epsplus(i))
+ end if
+ end if
+ end if
+ cond = .false.
+ if (i .lt. nx .and. GRHydro_enable_internal_excision /= 0) then
+ cond = hydro_excision_mask(i+1) .ne. 0
+ end if
+ if (cond) then
+ rhominus(i)=rho(i)
+ rhoplus(i)=rho(i)
+ velxminus(i)=velx(i)
+ velxplus(i)=velx(i)
+ velyminus(i)=vely(i)
+ velyplus(i)=vely(i)
+ velzminus(i)=velz(i)
+ velzplus(i)=velz(i)
+ Bvcxminus(i)=Bvcx(i)
+ Bvcxplus(i)=Bvcx(i)
+ Bvcyminus(i)=Bvcy(i)
+ Bvcyplus(i)=Bvcy(i)
+ Bvczminus(i)=Bvcz(i)
+ Bvczplus(i)=Bvcz(i)
+ rhominus(i+1)=rho(i)
+ rhoplus(i+1)=rho(i)
+ velxminus(i+1)=velx(i)
+ velxplus(i+1)=velx(i)
+ velyminus(i+1)=vely(i)
+ velyplus(i+1)=vely(i)
+ velzminus(i+1)=velz(i)
+ velzplus(i+1)=velz(i)
+ Bvcxminus(i+1)=Bvcx(i)
+ Bvcxplus(i+1)=Bvcx(i)
+ Bvcyminus(i+1)=Bvcy(i)
+ Bvcyplus(i+1)=Bvcy(i)
+ Bvczminus(i+1)=Bvcz(i)
+ Bvczplus(i+1)=Bvcz(i)
+ if (poly .eq. 0) then
+ epsminus(i)=eps(i)
+ epsplus(i)=eps(i)
+ epsminus(i+1)=eps(i)
+ epsplus(i+1)=eps(i)
+ endif
+ else
+ cond = .false.
+ if ((i.lt.nx-1) .and. (i.gt.1) .and. GRHydro_enable_internal_excision /= 0) then
+ cond = (ppm_mppm .eq. 0) .and. (hydro_excision_mask(i+2) .ne. 0)
+ end if
+ if (cond) then
+ call PPM_TVD(rho(i-1), rho(i), rho(i+1), rhominus(i), rhoplus(i))
+ call PPM_TVD(velx(i-1), velx(i), velx(i+1), velxminus(i), velxplus(i))
+ call PPM_TVD(vely(i-1), vely(i), vely(i+1), velyminus(i), velyplus(i))
+ call PPM_TVD(velz(i-1), velz(i), velz(i+1), velzminus(i), velzplus(i))
+ call PPM_TVD(Bvcx(i-1), Bvcx(i), Bvcx(i+1), Bvcxminus(i), Bvcxplus(i))
+ call PPM_TVD(Bvcy(i-1), Bvcy(i), Bvcy(i+1), Bvcyminus(i), Bvcyplus(i))
+ call PPM_TVD(Bvcz(i-1), Bvcz(i), Bvcz(i+1), Bvczminus(i), Bvczplus(i))
+ if (poly .eq. 0) then
+ call PPM_TVD(eps(i-1), eps(i), eps(i+1), epsminus(i), epsplus(i))
+ end if
+ end if
+ end if
+ end if
+ end do
+return
+
+end subroutine SimplePPM_1dM
+
+
+
+!!subroutine SimplePPM_tracer_1d(nx,dx,rho,velx,vely,velz, &
+!! tracer,tracerminus,tracerplus,press)
+!!
+!! USE GRHydro_Scalars
+!!
+!! implicit none
+!!
+!! DECLARE_CCTK_PARAMETERS
+!!
+!! CCTK_INT :: nx
+!! CCTK_REAL :: dx
+!! CCTK_REAL, dimension(nx) :: rho,velx,vely,velz
+!! CCTK_REAL, dimension(nx,number_of_tracers) :: tracer,tracerminus,tracerplus
+!! CCTK_REAL :: tracerflatomega
+!!
+!!
+!! CCTK_INT :: i,s,itracer
+!! CCTK_REAL, dimension(nx) :: press,dpress,tilde_flatten
+!! CCTK_REAL, dimension(nx,number_of_tracers) :: dmtracer, dtracer, tracerflat!, d2tracer
+!! 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.
+!!
+!!
+!! do i = 2, nx - 1
+!! dpress(i) = press(i+1) - press(i-1)
+!! end do
+!!
+!! do itracer=1,number_of_tracers
+!! do i = 2, nx - 1
+!! dtracer(i,itracer) = 0.5d0 * (tracer(i+1,itracer) - tracer(i-1,itracer))
+!!! d2tracer(i,itracer) = (tracer(i+1) - 2.d0 * tracer(i) + tracer(i-1))! / 6.d0 / dx / dx
+!!! ! since we use d2tracer only for the condition d2tracer(i+1)*d2tracer(i-1)<0
+!!! ! the denominator is not necessary
+!! enddo
+!! enddo
+!!
+!!!!$ Steepened slope. See (1.8) of Colella and Woodward, p.178
+!!
+!! do itracer=1,number_of_tracers
+!! do i = 2, nx - 1
+!! if( (tracer(i+1,itracer) - tracer(i,itracer)) * &
+!! (tracer(i,itracer) - tracer(i-1,itracer)) > 0.0d0 ) then
+!! dmtracer(i,itracer) = sign(1.0d0,dtracer(i,itracer)) * &
+!! min(abs(dtracer(i,itracer)), 2.0d0 * &
+!! abs(tracer(i,itracer) - tracer(i-1,itracer)), &
+!! 2.0d0 * abs(tracer(i+1,itracer) - tracer(i,itracer)))
+!! else
+!! dmtracer(i,itracer) = 0.0d0
+!! endif
+!! end do
+!! enddo
+!!
+!!!!$ Initial boundary states. See (1.9) of Colella and Woodward, p.178
+!!
+!! do itracer=1,number_of_tracers
+!! do i = 2, nx - 2
+!! tracerplus(i,itracer) = 0.5d0 * (tracer(i,itracer) + tracer(i+1,itracer)) + &
+!! (dmtracer(i,itracer) - dmtracer(i+1,itracer)) / 6.d0
+!! tracerminus(i+1,itracer) = tracerplus(i,itracer)
+!! enddo
+!! enddo
+!!
+!!
+!!!!$Discontinuity steepening. See (1.14-17) of C&W.
+!!!!$This is the detect routine which mat be activated with the ppm_detect parameter
+!!!!$Note that this part really also depends on the grid being even.
+!!!!$Note also that we do not have access to the gas constant gamma.
+!!!!$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).
+!!
+!!!!! We might play around with this for the tracer. CURRENTLY TURNED OFF
+!!
+!!#if 0
+!! if (ppm_detect .eq. 1000) then
+!! do itracer=1,number_of_tracers
+!!
+!! do i = 3, nx - 2
+!! if ( (dtracer(i+1,itracer)*dtracer(i-1,itracer) > 0.d0) & !make sure this is not an extremum
+!! .and.(abs(tracer(i+1,itracer)-tracer(i-1,itracer)) - & !this is to prevent steepening
+!! !of relatively small composition jumps
+!! ppm_epsilon_shock * min(tracer(i+1,itracer), tracer(i-1,itracer)) > 0.d0 ) &
+!! .and. & ! the actual criterion from Plewa & Mueller
+!! ((tracer(i+1,itracer)-tracer(i-1,itracer)) / &
+!! (tracer(i+2,itracer)-tracer(i-2,itracer)) > ppm_omega1 ) ) then
+!!
+!! etatilde = (tracer(i-2,itracer) - tracer(i+2,itracer) + &
+!! 4.d0 * dtracer(i,itracer)) / (dtracer(i,itracer) * 12.d0)
+!!
+!! write(*,*) "Additional Steepening in Zone: ",i
+!!
+!! else
+!! etatilde = 0.d0
+!! end if
+!! eta = max(0.d0, min(1.d0, ppm_eta1 * (etatilde - ppm_eta2)))
+!! if (ppm_k0 * abs(dtracer(i,itracer)) * min(press(i-1),press(i+1)) < &
+!! abs(dpress(i)) * min(tracer(i-1,itracer), tracer(i+1,itracer))) then
+!! eta = 0.d0
+!! end if
+!! tracerminus(i,itracer) = tracerminus(i,itracer) * (1.d0 - eta) + &
+!! (tracer(i-1,itracer) + 0.5d0 * dmtracer(i-1,itracer)) * eta
+!! tracerplus(i,itracer) = tracerplus(i,itracer) * (1.d0 - eta) + &
+!! (tracer(i+1,itracer) - 0.5d0 * dmtracer(i+1,itracer)) * eta
+!! end do
+!!
+!! enddo
+!!
+!! end if
+!!#endif
+!!
+!!!!$ 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)
+!! if ( (abs(dpress(i)) > ppm_epsilon * min(press(i-1),press(i+1))) .and. &
+!! (dvel < 0.d0) ) then
+!! w = 1.d0
+!! else
+!! w = 0.d0
+!! end if
+!! if (abs(dpress2) < ppm_small) then
+!! tilde_flatten(i) = 1.d0
+!! else
+!! tilde_flatten(i) = max(0.d0, 1.d0 - w * max(0.d0, ppm_omega2 * &
+!! (dpress(i) / dpress2 - ppm_omega1)))
+!! end if
+!! end do
+!!
+!! if (PPM3) then
+!! do itracer=1,number_of_tracers
+!! do i = 3, nx - 2
+!! flatten = tilde_flatten(i)
+!! tracerplus(i,itracer) = flatten * tracerplus(i,itracer) &
+!! + (1.d0 - flatten) * tracer(i,itracer)
+!! tracerminus(i,itracer) = flatten * tracerminus(i,itracer) &
+!! + (1.d0 - flatten) * tracer(i,itracer)
+!! end do
+!! enddo
+!! else !!$ Really implement C&W, page 197; which requires stencil 4.
+!! do itracer=1,number_of_tracers
+!! do i = 4, nx - 3
+!! s=sign(1.d0, -dpress(i))
+!! flatten = max(tilde_flatten(i), tilde_flatten(i+s))
+!! tracerplus(i,itracer) = flatten * tracerplus(i,itracer) + &
+!! (1.d0 - flatten) * tracer(i,itracer)
+!! tracerminus(i,itracer) = flatten * tracerminus(i,itracer) &
+!! + (1.d0 - flatten) * tracer(i,itracer)
+!! end do
+!! enddo
+!! end if
+!!
+!!
+!!!! Additional flattening a la Plewa & Mueller
+!!
+!!#if 1
+!! do itracer=1,number_of_tracers
+!! do i = 2, nx - 1
+!! if ( ( tracer(i+1,itracer) - tracer(i,itracer) ) * &
+!! ( tracer(i,itracer) - tracer(i-1,itracer) ) < 0.0d0 ) then
+!! tracerflat(i,itracer) = 1.0d0
+!! else
+!! tracerflat(i,itracer) = 0.0d0
+!! endif
+!! enddo
+!! enddo
+!!
+!! do itracer=1,number_of_tracers
+!! do i = 3, nx -2
+!!
+!! tracerflatomega = 0.5d0 * max(tracerflat(i-1,itracer),2.0d0*tracerflat(i,itracer), &
+!! tracerflat(i+1,itracer)) * ppm_omega_tracer
+!!
+!! tracerplus(i,itracer) = tracerflatomega*tracer(i,itracer) + &
+!! (1.0d0 - tracerflatomega)*tracerplus(i,itracer)
+!!
+!! tracerminus(i,itracer) = tracerflatomega*tracer(i,itracer) + &
+!! (1.0d0 - tracerflatomega)*tracerminus(i,itracer)
+!!
+!! enddo
+!! enddo
+!!
+!!
+!!#endif
+!!
+!!!!$ Monotonicity. See (1.10) of C&W.
+!!
+!!
+!! do itracer=1,number_of_tracers
+!! do i = GRHydro_stencil, nx - GRHydro_stencil + 1
+!! if (((tracerplus(i,itracer)-tracer(i,itracer))* &
+!! (tracer(i,itracer)-tracerminus(i,itracer)) .le. 0.d0)) then
+!! tracerminus(i,itracer) = tracer(i,itracer)
+!! tracerplus(i,itracer) = tracer(i,itracer)
+!! else if ((tracerplus(i,itracer) - tracerminus(i,itracer)) * (tracer(i,itracer) - 0.5d0 * &
+!! (tracerplus(i,itracer) + tracerminus(i,itracer))) > &
+!! (tracerplus(i,itracer) - tracerminus(i,itracer))**2 / 6.d0) then
+!! tracerminus(i,itracer) = 3.d0 * tracer(i,itracer) - 2.d0 * tracerplus(i,itracer)
+!! else if ((tracerplus(i,itracer) - tracerminus(i,itracer)) * (tracer(i,itracer) - 0.5d0 * &
+!! (tracerplus(i,itracer) + tracerminus(i,itracer))) < &
+!! -(tracerplus(i,itracer) - tracerminus(i,itracer))**2 / 6.d0 ) then
+!! tracerplus(i,itracer) = 3.d0 * tracer(i,itracer) - 2.d0 * tracerminus(i,itracer)
+!! end if
+!! end do
+!! enddo
+!!
+!!
+!!
+!!end subroutine SimplePPM_tracer_1d
+!!
diff --git a/src/GRHydro_ParamCheck.F90 b/src/GRHydro_ParamCheck.F90
index f192071..132569c 100644
--- a/src/GRHydro_ParamCheck.F90
+++ b/src/GRHydro_ParamCheck.F90
@@ -86,13 +86,14 @@ subroutine GRHydro_ParamCheck(CCTK_ARGUMENTS)
call CCTK_PARAMWARN("GRHydro::bound = 'static' is no longer supported, use 'none' instead");
end if
- if (CCTK_EQUALS(Bvec_evolution_method,"GRHydro")) then
- MHD = 1
- ! issue a fatal warning, since MHD is not implemented yet
- call CCTK_PARAMWARN("MHD is not yet implemented. Please run with GRHydro::Bvec_evolution_method='none'.");
- else
- MHD = 0
- endif
+!!$ AU CONTRAIRE, MON FRERE!!! WE DO MHD NOW!!!!
+!!$ if (CCTK_EQUALS(Bvec_evolution_method,"GRHydro")) then
+!!$ MHD = 1
+!!$ ! issue a fatal warning, since MHD is not implemented yet
+!!$ call CCTK_PARAMWARN("MHD is not yet implemented. Please run with GRHydro::Bvec_evolution_method='none'.");
+!!$ else
+!!$ MHD = 0
+!!$ endif
diff --git a/src/GRHydro_ParamCheckM.F90 b/src/GRHydro_ParamCheckM.F90
new file mode 100644
index 0000000..6043ae9
--- /dev/null
+++ b/src/GRHydro_ParamCheckM.F90
@@ -0,0 +1,52 @@
+ /*@@
+ @file GRHydro_ParamCheckM.F90
+ @date Sep 23, 2010
+ @author
+ @desc
+ Parameter checking routine.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+
+ /*@@
+ @routine GRHydro_ParamCheckM
+ @date Sep 23, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim
+ @desc
+ Checks the parameters.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_ParamCheckM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+!! if (CCTK_EQUALS(recon_method,"ppm").and.CCTK_EQUALS(Bvec_evolution_method,"GRHydro")) then
+!! call CCTK_PARAMWARN("PPM is not implemented yet for MHD")
+!! end if
+
+ if (CCTK_EQUALS(riemann_solver,"Roe").and.CCTK_EQUALS(Bvec_evolution_method,"GRHydro")) then
+ call CCTK_PARAMWARN("Roe solver is not implemented yet for MHD")
+ end if
+
+ if (CCTK_EQUALS(riemann_solver,"Marquina").and.CCTK_EQUALS(Bvec_evolution_method,"GRHydro")) then
+ call CCTK_PARAMWARN("Marquina solver is not implemented yet for MHD")
+ end if
+
+
+end subroutine GRHydro_ParamCheckM
+
diff --git a/src/GRHydro_Prim2Con.F90 b/src/GRHydro_Prim2Con.F90
index 268e8e4..af0e661 100644
--- a/src/GRHydro_Prim2Con.F90
+++ b/src/GRHydro_Prim2Con.F90
@@ -45,7 +45,7 @@ subroutine primitive2conservative(CCTK_ARGUMENTS)
integer :: i, j, k
CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
- gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr,psi4l,psi4r
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
@@ -179,19 +179,18 @@ subroutine Primitive2ConservativeCells(CCTK_ARGUMENTS)
DECLARE_CCTK_PARAMETERS
CCTK_INT :: i, j, k
- CCTK_REAL :: det,psi4pt
+ CCTK_REAL :: det
do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
do i = GRHydro_stencil,cctk_lsh(1)-GRHydro_stencil+1
- psi4pt = 1.0d0
det = SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k), \
gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
- call prim2con(GRHydro_eos_handle,psi4pt*gxx(i,j,k),&
- psi4pt*gxy(i,j,k),psi4pt*gxz(i,j,k),&
- psi4pt*gyy(i,j,k),psi4pt*gyz(i,j,k),psi4pt*gzz(i,j,k),&
+ call prim2con(GRHydro_eos_handle,gxx(i,j,k),&
+ gxy(i,j,k),gxz(i,j,k),&
+ gyy(i,j,k),gyz(i,j,k),gzz(i,j,k),&
det, dens(i,j,k),sx(i,j,k),sy(i,j,k),sz(i,j,k),&
tau(i,j,k),rho(i,j,k),velx(i,j,k),vely(i,j,k),velz(i,j,k),&
eps(i,j,k),press(i,j,k),w_lorentz(i,j,k))
@@ -228,11 +227,10 @@ subroutine Prim2ConservativePolytype(CCTK_ARGUMENTS)
integer :: i, j, k
CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
- gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr,psi4r,psi4l
- character(len=200) warnline
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
!$OMP PARALLEL DO PRIVATE(i, j, gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
- !$OMP gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr,psi4r,psi4l)
+ !$OMP gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr)
do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
do i = GRHydro_stencil,cctk_lsh(1)-GRHydro_stencil+1
@@ -437,7 +435,7 @@ subroutine Prim2ConservativeTracer(CCTK_ARGUMENTS)
integer :: i, j, k
CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
- gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr,psi4r,psi4l
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
@@ -510,14 +508,14 @@ subroutine primitive2conservativegeneral(CCTK_ARGUMENTS)
CCTK_INT :: i, j, k, ierr
CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl, &
- gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr,psi4l,psi4r, &
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr, &
vlowx, vlowy, vlowz
ierr = EOS_SetGFs(cctkGH, EOS_Prim2ConBndCallPlus)
ierr = EOS_SetGFs(cctkGH, EOS_Prim2ConBndCallMinus)
!$OMP PARALLEL DO PRIVATE(i, j, gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
- !$OMP gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr,psi4r,psi4l)
+ !$OMP gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr)
do k = GRHydro_stencil , cctk_lsh(3) - GRHydro_stencil + 1
do j = GRHydro_stencil , cctk_lsh(2) - GRHydro_stencil + 1
do i = GRHydro_stencil , cctk_lsh(1) - GRHydro_stencil + 1
@@ -585,7 +583,7 @@ subroutine Primitive2ConservativeCellsGeneral(CCTK_ARGUMENTS)
DECLARE_CCTK_FUNCTIONS
CCTK_INT :: i, j, k, ierr
- CCTK_REAL :: det,psi4pt,gxxpt,gxypt,gxzpt,gyypt,gyzpt,gzzpt, &
+ CCTK_REAL :: det,gxxpt,gxypt,gxzpt,gyypt,gyzpt,gzzpt, &
vlowx, vlowy, vlowz
ierr = EOS_SetGFs(cctkGH, EOS_Prim2ConCellsCall)
diff --git a/src/GRHydro_Prim2ConM.F90 b/src/GRHydro_Prim2ConM.F90
new file mode 100644
index 0000000..162e66f
--- /dev/null
+++ b/src/GRHydro_Prim2ConM.F90
@@ -0,0 +1,637 @@
+ /*@@
+ @file primitive2conservative
+ @date Aug 31, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ Primitive to conservative routine
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "cctk_Functions.h"
+#include "GRHydro_Macros.h"
+
+#define velx(i,j,k) vel(i,j,k,1)
+#define vely(i,j,k) vel(i,j,k,2)
+#define velz(i,j,k) vel(i,j,k,3)
+#define sx(i,j,k) scon(i,j,k,1)
+#define sy(i,j,k) scon(i,j,k,2)
+#define sz(i,j,k) scon(i,j,k,3)
+#define Bvecx(i,j,k) Bvec(i,j,k,1)
+#define Bvecy(i,j,k) Bvec(i,j,k,2)
+#define Bvecz(i,j,k) Bvec(i,j,k,3)
+
+#define DOT(x1,y1,z1,x2,y2,z2) ( DOTP(gxx,gxy,gxz,gyy,gyz,gzz,x1,y1,z1,x2,y2,z2) )
+#define DOT2(x1,y1,z1) ( DOTP2(gxx,gxy,gxz,gyy,gyz,gzz,x1,y1,z1) )
+#define DOTPT(x1,y1,z1,x2,y2,z2) ( DOTP(gxxpt,gxypt,gxzpt,gyypt,gyzpt,gzzpt,x1,y1,z1,x2,y2,z2) )
+#define DOTPT2(x1,y1,z1) ( DOTP2(gxxpt,gxypt,gxzpt,gyypt,gyzpt,gzzpt,x1,y1,z1) )
+
+ /*@@
+ @routine primitive2conservativeM
+ @date Aug 31
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ Converts primitive to conserved variables for the boundary extended data.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine primitive2conservativeM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k
+ CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
+
+ do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
+ do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
+ do i = GRHydro_stencil,cctk_lsh(1)-GRHydro_stencil+1
+
+ gxxl = 0.5d0 * (gxx(i,j,k) + gxx(i-xoffset,j-yoffset,k-zoffset))
+ gxyl = 0.5d0 * (gxy(i,j,k) + gxy(i-xoffset,j-yoffset,k-zoffset))
+ gxzl = 0.5d0 * (gxz(i,j,k) + gxz(i-xoffset,j-yoffset,k-zoffset))
+ gyyl = 0.5d0 * (gyy(i,j,k) + gyy(i-xoffset,j-yoffset,k-zoffset))
+ gyzl = 0.5d0 * (gyz(i,j,k) + gyz(i-xoffset,j-yoffset,k-zoffset))
+ gzzl = 0.5d0 * (gzz(i,j,k) + gzz(i-xoffset,j-yoffset,k-zoffset))
+ gxxr = 0.5d0 * (gxx(i,j,k) + gxx(i+xoffset,j+yoffset,k+zoffset))
+ gxyr = 0.5d0 * (gxy(i,j,k) + gxy(i+xoffset,j+yoffset,k+zoffset))
+ gxzr = 0.5d0 * (gxz(i,j,k) + gxz(i+xoffset,j+yoffset,k+zoffset))
+ gyyr = 0.5d0 * (gyy(i,j,k) + gyy(i+xoffset,j+yoffset,k+zoffset))
+ gyzr = 0.5d0 * (gyz(i,j,k) + gyz(i+xoffset,j+yoffset,k+zoffset))
+ gzzr = 0.5d0 * (gzz(i,j,k) + gzz(i+xoffset,j+yoffset,k+zoffset))
+
+ avg_detl = SPATIAL_DETERMINANT(gxxl,gxyl,gxzl,gyyl, gyzl,gzzl)
+ avg_detr = SPATIAL_DETERMINANT(gxxr,gxyr,gxzr,gyyr, gyzr,gzzr)
+
+ call prim2conM(GRHydro_eos_handle, gxxl,gxyl,gxzl,gyyl,gyzl,gzzl, &
+ avg_detl,densminus(i,j,k),sxminus(i,j,k),&
+ syminus(i,j,k),szminus(i,j,k),tauminus(i,j,k),&
+ Bvecxminus(i,j,k),Bvecyminus(i,j,k),Bveczminus(i,j,k), rhominus(i,j,k), &
+ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k),&
+ epsminus(i,j,k),pressminus(i,j,k),w_lorentzminus(i, j, k))
+
+ call prim2conM(GRHydro_eos_handle, gxxr,gxyr,gxzr,gyyr,gyzr,gzzr, &
+ avg_detr, densplus(i,j,k),sxplus(i,j,k),&
+ syplus(i,j,k),szplus(i,j ,k),tauplus(i,j,k),&
+ Bvecxplus(i,j,k),Bvecyplus(i,j,k),Bveczplus(i,j,k), &
+ rhoplus(i,j,k),velxplus(i,j,k),velyplus(i,j,k),&
+ velzplus(i,j,k),epsplus(i,j,k),pressplus(i,j,k),&
+ w_lorentzplus(i,j,k))
+
+ end do
+ end do
+ end do
+
+end subroutine primitive2conservativeM
+
+ /*@@
+ @routine prim2conM
+ @date Aug 31, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ Converts from primitive to conservative at a single point
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine prim2conM(handle, gxx, gxy, gxz, gyy, gyz, gzz, det, ddens, &
+ dsx, dsy, dsz, dtau , dBvcx, dBvcy, dBvcz, drho, dvelx, dvely, dvelz, deps, dpress, w)
+
+ implicit none
+
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_REAL :: gxx, gxy, gxz, gyy, gyz, gzz, det
+ CCTK_REAL :: ddens, dsx, dsy, dsz, dtau, dBvcx, dBvcy, dBvcz, &
+ drho, dvelx, dvely, dvelz,&
+ deps, dpress, w, vlowx, vlowy, vlowz
+ CCTK_REAL :: Bdotv,ab0,b2,blowx,blowy,blowz
+ CCTK_INT :: handle
+ character(len=256) NaN_WarnLine
+
+#if !USE_EOS_OMNI
+#include "EOS_Base.inc"
+#endif
+
+#if USE_EOS_OMNI
+! begin EOS Omni vars
+ integer :: n = 1
+ integer :: keytemp = 0
+ integer :: anyerr = 0
+ integer :: keyerr(1) = 0
+ real*8 :: xpress = 0.0d0
+ real*8 :: xeps = 0.0d0
+ real*8 :: xtemp = 0.0d0
+ real*8 :: xye = 0.0d0
+! end EOS Omni vars
+#endif
+
+ w = 1.d0 / sqrt(1.d0 - DOT2(dvelx,dvely,dvelz))
+
+!!$ BEGIN: Check for NaN value
+ if (w .ne. w) then
+ !$OMP CRITICAL
+ write(NaN_WarnLine,'(a100,3g15.6)') 'NaN produced in sqrt(): (dvelx,dvely,dvelz)', dvelx, dvely, dvelz
+ call CCTK_WARN(GRHydro_NaN_verbose, NaN_WarnLine)
+ !$OMP END CRITICAL
+ endif
+!!$ END: Check for NaN value
+
+#if USE_EOS_OMNI
+ call EOS_Omni_press(handle,keytemp,GRHydro_eos_rf_prec,n,&
+ drho,deps,xtemp,xye,dpress,keyerr,anyerr)
+#else
+ dpress = EOS_Pressure(handle, drho, deps)
+#endif
+ vlowx = gxx*dvelx + gxy*dvely + gxz*dvelz
+ vlowy = gxy*dvelx + gyy*dvely + gyz*dvelz
+ vlowz = gxz*dvelx + gyz*dvely + gzz*dvelz
+
+ Bdotv=DOT(dvelx,dvely,dvelz,dBvcx,dBvcy,dBvcz)
+ ab0=w*Bdotv
+ b2 = DOT2(dBvcx,dBvcy,dBvcz)/w**2+Bdotv**2
+ blowx = (gxx*dBvcx + gxy*dBvcy + gxz*dBvcz)/w + &
+ w*Bdotv*vlowx
+ blowy = (gxy*dBvcx + gyy*dBvcy + gyz*dBvcz)/w + &
+ w*Bdotv*vlowy
+ blowz = (gxz*dBvcx + gyz*dBvcy + gzz*dBvcz)/w + &
+ w*Bdotv*vlowz
+
+ ddens = sqrt(det) * drho * w
+ dsx = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w * vlowx - &
+ ab0*blowx)
+ dsy = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w * vlowy - &
+ ab0*blowy)
+ dsz = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w * vlowz - &
+ ab0*blowz)
+ dtau = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w - dpress-b2/2.0-ab0**2) - ddens
+
+end subroutine prim2conM
+
+
+ /*@@
+ @routine Primitive2ConservativeCellsM
+ @date Aug 31, 2010
+ @author
+ @desc
+ Wrapper function that converts primitive to conservative at the
+ cell centres.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+subroutine Primitive2ConservativeCellsM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_INT :: i, j, k
+ CCTK_REAL :: det
+
+ do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
+ do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
+ do i = GRHydro_stencil,cctk_lsh(1)-GRHydro_stencil+1
+
+ det = SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k), \
+ gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+
+ call prim2conM(GRHydro_eos_handle,gxx(i,j,k),&
+ gxy(i,j,k),gxz(i,j,k),&
+ gyy(i,j,k),gyz(i,j,k),gzz(i,j,k),&
+ det, dens(i,j,k),sx(i,j,k),sy(i,j,k),sz(i,j,k),&
+ tau(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k),&
+ rho(i,j,k),velx(i,j,k),vely(i,j,k),velz(i,j,k),&
+ eps(i,j,k),press(i,j,k),w_lorentz(i,j,k))
+
+ end do
+ end do
+ end do
+
+end subroutine Primitive2ConservativeCellsM
+
+
+ /*@@
+ @routine Prim2ConservativePolytypeM
+ @date Aug 31, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ Same as first routine, only for polytropes.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+subroutine Prim2ConservativePolytypeM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ integer :: i, j, k
+ CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr
+
+ !$OMP PARALLEL DO PRIVATE(i, j, gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
+ !$OMP gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr)
+ do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
+ do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
+ do i = GRHydro_stencil,cctk_lsh(1)-GRHydro_stencil+1
+
+ gxxl = 0.5d0 * (gxx(i,j,k) + gxx(i-xoffset,j-yoffset,k-zoffset))
+ gxyl = 0.5d0 * (gxy(i,j,k) + gxy(i-xoffset,j-yoffset,k-zoffset))
+ gxzl = 0.5d0 * (gxz(i,j,k) + gxz(i-xoffset,j-yoffset,k-zoffset))
+ gyyl = 0.5d0 * (gyy(i,j,k) + gyy(i-xoffset,j-yoffset,k-zoffset))
+ gyzl = 0.5d0 * (gyz(i,j,k) + gyz(i-xoffset,j-yoffset,k-zoffset))
+ gzzl = 0.5d0 * (gzz(i,j,k) + gzz(i-xoffset,j-yoffset,k-zoffset))
+ gxxr = 0.5d0 * (gxx(i,j,k) + gxx(i+xoffset,j+yoffset,k+zoffset))
+ gxyr = 0.5d0 * (gxy(i,j,k) + gxy(i+xoffset,j+yoffset,k+zoffset))
+ gxzr = 0.5d0 * (gxz(i,j,k) + gxz(i+xoffset,j+yoffset,k+zoffset))
+ gyyr = 0.5d0 * (gyy(i,j,k) + gyy(i+xoffset,j+yoffset,k+zoffset))
+ gyzr = 0.5d0 * (gyz(i,j,k) + gyz(i+xoffset,j+yoffset,k+zoffset))
+ gzzr = 0.5d0 * (gzz(i,j,k) + gzz(i+xoffset,j+yoffset,k+zoffset))
+
+ avg_detl = SPATIAL_DETERMINANT(gxxl,gxyl,gxzl,gyyl, gyzl,gzzl)
+ avg_detr = SPATIAL_DETERMINANT(gxxr,gxyr,gxzr,gyyr, gyzr,gzzr)
+
+ call prim2conpolytypeM(GRHydro_eos_handle, gxxl,gxyl,gxzl,&
+ gyyl,gyzl,gzzl, &
+ avg_detl,densminus(i,j,k),sxminus(i,j,k),&
+ syminus(i,j,k),szminus(i,j,k),tauminus(i,j,k),&
+ Bvecxminus(i,j,k),Bvecyminus(i,j,k),Bveczminus(i,j,k),rhominus(i,j,k), &
+ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k),&
+ epsminus(i,j,k),pressminus(i,j,k),w_lorentzminus(i, j, k))
+
+ call prim2conpolytypeM(GRHydro_eos_handle, gxxr,gxyr,gxzr,&
+ gyyr,gyzr,gzzr, &
+ avg_detr, densplus(i,j,k),sxplus(i,j,k),&
+ syplus(i,j,k),szplus(i,j ,k),tauplus(i,j,k),&
+ Bvecxplus(i,j,k),Bvecyplus(i,j,k),Bveczplus(i,j,k),&
+ rhoplus(i,j,k),epsplus(i,j,k),pressplus(i,j,k),&
+ w_lorentzplus(i,j,k))
+
+ if (densminus(i,j,k) .ne. densminus(i,j,k)) then
+ !$OMP CRITICAL
+ call CCTK_WARN(1, "NaN in densminus(i,j,k) (Prim2Con)")
+ !$OMP END CRITICAL
+ endif
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+end subroutine Prim2ConservativePolytypeM
+
+ /*@@
+ @routine prim2conpolytypeM
+ @date Aug 31, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ Converts from primitive to conservative at a single point
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine prim2conpolytypeM(handle, gxx, gxy, gxz, gyy, gyz, &
+ gzz, det, ddens, dsx, dsy, dsz, dtau, dBvcx, dBvcy, dBvcz, &
+ drho, dvelx, dvely, dvelz, deps, dpress, w)
+
+ implicit none
+
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_REAL :: gxx, gxy, gxz, gyy, gyz, gzz, det
+ CCTK_REAL :: ddens, dsx, dsy, dsz, dtau, dBvcx, dBvcy, dBvcz, &
+ drho, dvelx, dvely, dvelz,&
+ deps, dpress, w_tmp, w, vlowx, vlowy, vlowz, sqrtdet
+ CCTK_INT :: handle
+ CCTK_REAL :: Bdotv,ab0,b2,blowx,blowy,blowz
+ character(len=256) NaN_WarnLine
+
+#if !USE_EOS_OMNI
+#ifdef _EOS_BASE_INC_
+#undef _EOS_BASE_INC_
+#endif
+#include "EOS_Base.inc"
+#endif
+
+#if USE_EOS_OMNI
+! begin EOS Omni vars
+ integer :: n = 1
+ integer :: keytemp = 0
+ integer :: anyerr = 0
+ integer :: keyerr(1) = 0
+ real*8 :: xpress = 0.0d0
+ real*8 :: xeps = 0.0d0
+ real*8 :: xtemp = 0.0d0
+ real*8 :: xye = 0.0d0
+! end EOS Omni vars
+#endif
+
+ w_tmp = DOT2(dvelx,dvely,dvelz)
+
+ if (w_tmp .ge. 1.d0) then
+ ! In theory this should not happen, and even when accepting the fact
+ ! that numerically it can, one might be tempted to set w to some large
+ ! value in that case. However, this would lead to completely bogus
+ ! and hard to trace wrong values below. There is no good value to
+ ! choose in this case, but something small is probably the best of
+ ! all bad choices.
+ !$OMP CRITICAL
+ write(NaN_WarnLine,'(a80,2g15.6)') 'Infinite Lorentz factor reset. rho, w_tmp: ', drho, w_tmp
+ call CCTK_WARN(GRHydro_NaN_verbose, NaN_WarnLine)
+ !$OMP END CRITICAL
+ w = 1.d-20
+ else
+ w = 1.d0 / sqrt(1.d0 - w_tmp)
+ endif
+
+#if USE_EOS_OMNI
+ call EOS_Omni_press(handle,keytemp,GRHydro_eos_rf_prec,n,&
+ drho,xeps,xtemp,xye,dpress,keyerr,anyerr)
+
+ call EOS_Omni_EpsFromPress(handle,keytemp,GRHydro_eos_rf_prec,n,&
+ drho,xeps,xtemp,xye,dpress,deps,keyerr,anyerr)
+#else
+ if (handle .ge. 0) then
+ dpress = EOS_Pressure(handle, drho, deps)
+ deps = EOS_SpecificIntEnergy(handle, drho, dpress)
+ end if
+#endif
+
+ vlowx = gxx*dvelx + gxy*dvely + gxz*dvelz
+ vlowy = gxy*dvelx + gyy*dvely + gyz*dvelz
+ vlowz = gxz*dvelx + gyz*dvely + gzz*dvelz
+
+ Bdotv=DOT(dvelx,dvely,dvelz,dBvcx,dBvcy,dBvcz)
+ ab0=w*Bdotv
+ b2 = DOT2(dBvcx,dBvcy,dBvcz)/w**2+Bdotv**2
+ blowx = (gxx*dBvcx + gxy*dBvcy + gxz*dBvcz)/w + &
+ w*Bdotv*vlowx
+ blowy = (gxy*dBvcx + gyy*dBvcy + gyz*dBvcz)/w + &
+ w*Bdotv*vlowy
+ blowz = (gxz*dBvcx + gyz*dBvcy + gzz*dBvcz)/w + &
+ w*Bdotv*vlowz
+
+ ddens = sqrt(det) * drho * w
+ dsx = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w * vlowx - &
+ ab0*blowx)
+ dsy = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w * vlowy - &
+ ab0*blowy)
+ dsz = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w * vlowz - &
+ ab0*blowz)
+ dtau = sqrt(det) * ((drho*(1+deps)+dpress+b2)*w*w - dpress-b2/2.0-ab0**2) - ddens
+
+end subroutine prim2conpolytypeM
+
+
+ /*@@
+ @routine Primitive2ConservativePolyCellsM
+ @date Aug 31, 2010
+ @author
+ @desc
+ Wrapper function that converts primitive to conservative at the
+ cell centres.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+subroutine Primitive2ConservativePolyCellsM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_INT :: i, j, k
+ CCTK_REAL :: det
+
+ do k = GRHydro_stencil,cctk_lsh(3)-GRHydro_stencil+1
+ do j = GRHydro_stencil,cctk_lsh(2)-GRHydro_stencil+1
+ do i = GRHydro_stencil,cctk_lsh(1)-GRHydro_stencil+1
+
+ det = SPATIAL_DETERMINANT(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),\
+ gyy(i,j,k),gyz(i,j,k),gzz(i,j,k))
+
+ call prim2conpolytypeM(GRHydro_eos_handle,gxx(i,j,k),gxy(i,j,k),&
+ gxz(i,j,k),gyy(i,j,k),gyz(i,j,k),gzz(i,j,k),&
+ det, dens(i,j,k),sx(i,j,k),sy(i,j,k),sz(i,j,k),&
+ tau(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k),&
+ rho(i,j,k),velx(i,j,k),vely(i,j,k),velz(i,j,k),&
+ eps(i,j,k),press(i,j,k),w_lorentz(i,j,k))
+
+ end do
+ end do
+ end do
+
+end subroutine Primitive2ConservativePolyCellsM
+
+!!$
+!!$ Prim2Con doesn't change for tracers with the addition of a B-field!
+!!$
+
+ /*@@
+ @routine primitive2conservativegeneralM
+ @date Aug 31, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ Converts primitive to conserved variables for the boundary extended data.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine primitive2conservativegeneralM(CCTK_ARGUMENTS)
+
+ USE GRHydro_Scalars
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i, j, k, ierr
+ CCTK_REAL :: gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl, &
+ gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr, &
+ vlowx, vlowy, vlowz
+
+ ierr = EOS_SetGFs(cctkGH, EOS_Prim2ConBndCallPlus)
+ ierr = EOS_SetGFs(cctkGH, EOS_Prim2ConBndCallMinus)
+
+ !$OMP PARALLEL DO PRIVATE(i, j, gxxl,gxyl,gxzl,gyyl,gyzl,gzzl,avg_detl,&
+ !$OMP gxxr,gxyr,gxzr,gyyr,gyzr,gzzr,avg_detr)
+ do k = GRHydro_stencil , cctk_lsh(3) - GRHydro_stencil + 1
+ do j = GRHydro_stencil , cctk_lsh(2) - GRHydro_stencil + 1
+ do i = GRHydro_stencil , cctk_lsh(1) - GRHydro_stencil + 1
+
+ gxxl = 0.5d0 * (gxx(i,j,k) + gxx(i-xoffset,j-yoffset,k-zoffset))
+ gxyl = 0.5d0 * (gxy(i,j,k) + gxy(i-xoffset,j-yoffset,k-zoffset))
+ gxzl = 0.5d0 * (gxz(i,j,k) + gxz(i-xoffset,j-yoffset,k-zoffset))
+ gyyl = 0.5d0 * (gyy(i,j,k) + gyy(i-xoffset,j-yoffset,k-zoffset))
+ gyzl = 0.5d0 * (gyz(i,j,k) + gyz(i-xoffset,j-yoffset,k-zoffset))
+ gzzl = 0.5d0 * (gzz(i,j,k) + gzz(i-xoffset,j-yoffset,k-zoffset))
+ gxxr = 0.5d0 * (gxx(i,j,k) + gxx(i+xoffset,j+yoffset,k+zoffset))
+ gxyr = 0.5d0 * (gxy(i,j,k) + gxy(i+xoffset,j+yoffset,k+zoffset))
+ gxzr = 0.5d0 * (gxz(i,j,k) + gxz(i+xoffset,j+yoffset,k+zoffset))
+ gyyr = 0.5d0 * (gyy(i,j,k) + gyy(i+xoffset,j+yoffset,k+zoffset))
+ gyzr = 0.5d0 * (gyz(i,j,k) + gyz(i+xoffset,j+yoffset,k+zoffset))
+ gzzr = 0.5d0 * (gzz(i,j,k) + gzz(i+xoffset,j+yoffset,k+zoffset))
+
+ avg_detl = SPATIAL_DETERMINANT(gxxl,gxyl,gxzl,gyyl, gyzl,gzzl)
+ avg_detr = SPATIAL_DETERMINANT(gxxr,gxyr,gxzr,gyyr, gyzr,gzzr)
+
+ call prim2conpolytypeM(-1, gxxl,gxyl,gxzl,&
+ gyyl,gyzl,gzzl, &
+ avg_detl,densminus(i,j,k),sxminus(i,j,k),&
+ syminus(i,j,k),szminus(i,j,k),tauminus(i,j,k),&
+ Bvecxminus(i,j,k),Bvecyminus(i,j,k),Bveczminus(i,j,k),rhominus(i,j,k), &
+ velxminus(i,j,k),velyminus(i,j,k),velzminus(i,j,k),&
+ epsminus(i,j,k),pressminus(i,j,k),w_lorentzminus(i, j, k))
+
+ call prim2conpolytypeM(-1, gxxr,gxyr,gxzr,&
+ gyyr,gyzr,gzzr, &
+ avg_detr, densplus(i,j,k),sxplus(i,j,k),&
+ syplus(i,j,k),szplus(i,j ,k),tauplus(i,j,k),&
+ Bvecxplus(i,j,k),Bvecyplus(i,j,k),Bveczplus(i,j,k),&
+ rhoplus(i,j,k),velxplus(i,j,k),velyplus(i,j,k),&
+ velzplus(i,j,k),epsplus(i,j,k),pressplus(i,j,k),&
+ w_lorentzplus(i,j,k))
+ if (densminus(i,j,k) .ne. densminus(i,j,k)) then
+ !$OMP CRITICAL
+ call CCTK_WARN(1, "NaN in densminus(i,j,k) (Prim2Con)")
+ !$OMP END CRITICAL
+ endif
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+
+end subroutine primitive2conservativegeneralM
+
+ /*@@
+ @routine Primitive2ConservativeCellsGeneralM
+ @date Ag 31, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ Converts primitive to conserved variables for the boundary extended data.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine Primitive2ConservativeCellsGeneralM(CCTK_ARGUMENTS)
+
+ USE GRHydro_Scalars
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i, j, k, ierr
+ CCTK_REAL :: det,gxxpt,gxypt,gxzpt,gyypt,gyzpt,gzzpt, &
+ vlowx, vlowy, vlowz
+ CCTK_REAL Bdotv,ab0,b2,blowx,blowy,blowz
+
+ ierr = EOS_SetGFs(cctkGH, EOS_Prim2ConCellsCall)
+
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil + 1
+ do i = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil + 1
+
+ gxxpt = gxx(i,j,k)
+ gxypt = gxy(i,j,k)
+ gxzpt = gxz(i,j,k)
+ gyypt = gyy(i,j,k)
+ gyzpt = gyz(i,j,k)
+ gzzpt = gzz(i,j,k)
+
+ det = SPATIAL_DETERMINANT(gxxpt,gxypt,gxzpt,gyypt,gyzpt,gzzpt)
+
+ w_lorentz(i,j,k)=1.d0/sqrt(1.d0-DOTPT2(velx(i,j,k),vely(i,j,k),velz(i,j,k)))
+
+ vlowx = gxxpt * velx(i,j,k) + &
+ gxypt * vely(i,j,k) + &
+ gxzpt * velz(i,j,k)
+ vlowy = gxypt * velx(i,j,k) + &
+ gyypt * vely(i,j,k) + &
+ gyzpt * velz(i,j,k)
+ vlowz = gxzpt * velx(i,j,k) + &
+ gyzpt * vely(i,j,k) + &
+ gzzpt * velz(i,j,k)
+
+ Bdotv=DOTPT(velx(i,j,k),vely(i,j,k),velz(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k))
+ ab0=w_lorentz(i,j,k)*Bdotv
+ b2 = DOTPT2(Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k))/w_lorentz(i,j,k)**2+Bdotv**2
+
+ blowx = (gxx(i,j,k)*Bvecx(i,j,k) + gxy(i,j,k)*Bvecy(i,j,k) + gxz(i,j,k)*Bvecz(i,j,k))/ &
+ w_lorentz(i,j,k) + w_lorentz(i,j,k)*Bdotv*vlowx
+ blowy = (gxy(i,j,k)*Bvecx(i,j,k) + gyy(i,j,k)*Bvecy(i,j,k) + gyz(i,j,k)*Bvecz(i,j,k))/ &
+ w_lorentz(i,j,k) + w_lorentz(i,j,k)*Bdotv*vlowy
+ blowz = (gxz(i,j,k)*Bvecx(i,j,k) + gyz(i,j,k)*Bvecy(i,j,k) + gzz(i,j,k)*Bvecz(i,j,k))/ &
+ w_lorentz(i,j,k) + w_lorentz(i,j,k)*Bdotv*vlowz
+
+ dens(i,j,k) = sqrt(det) * rho(i,j,k) * w_lorentz(i,j,k)
+ sx(i,j,k) = sqrt(det) * ((rho(i,j,k)*(1+eps(i,j,k))+press(i,j,k)+b2)* &
+ w_lorentz(i,j,k)*w_lorentz(i,j,k) * vlowx - ab0*blowx)
+ sy(i,j,k) = sqrt(det) * ((rho(i,j,k)*(1+eps(i,j,k))+press(i,j,k)+b2)* &
+ w_lorentz(i,j,k)*w_lorentz(i,j,k) * vlowy - ab0*blowy)
+ sz(i,j,k) = sqrt(det) * ((rho(i,j,k)*(1+eps(i,j,k))+press(i,j,k)+b2)* &
+ w_lorentz(i,j,k)*w_lorentz(i,j,k) * vlowz - ab0*blowz)
+ tau(i,j,k) = sqrt(det) * ((rho(i,j,k)*(1+eps(i,j,k))+press(i,j,k)+b2)* &
+ w_lorentz(i,j,k)*w_lorentz(i,j,k) - press(i,j,k)-b2/2.0-ab0**2) - dens(i,j,k)
+
+ end do
+ end do
+ end do
+
+end subroutine Primitive2ConservativeCellsGeneralM
diff --git a/src/GRHydro_ReconstructM.F90 b/src/GRHydro_ReconstructM.F90
new file mode 100644
index 0000000..66e433b
--- /dev/null
+++ b/src/GRHydro_ReconstructM.F90
@@ -0,0 +1,621 @@
+ /*@@
+ @file GRHydro_ReconstructM.F90
+ @date Sep 2, 2010
+ @author
+ @desc
+ Wrapper routine to perform the reconstruction.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "cctk_Functions.h"
+
+#include "SpaceMask.h"
+
+#define velx(i,j,k) vel(i,j,k,1)
+#define vely(i,j,k) vel(i,j,k,2)
+#define velz(i,j,k) vel(i,j,k,3)
+#define sx(i,j,k) scon(i,j,k,1)
+#define sy(i,j,k) scon(i,j,k,2)
+#define sz(i,j,k) scon(i,j,k,3)
+#define Bvecx(i,j,k) Bvec(i,j,k,1)
+#define Bvecy(i,j,k) Bvec(i,j,k,2)
+#define Bvecz(i,j,k) Bvec(i,j,k,3)
+
+
+ /*@@
+ @routine ReconstructionM
+ @date Sep 2, 2010
+ @author Joshua Faber, SCott Noble, Bruno Mundim, Luca Baiotti, Ian Hawke
+ @desc
+ A wrapper routine to do reconstruction. Currently just does
+ TVD on the primitive variables.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine ReconstructionM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ integer :: nx, ny, nz, i, j, k, itracer
+
+ logical, dimension(:,:,:), allocatable :: trivial_rp
+!!$ logical, dimension(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)) :: trivial_rp
+
+ CCTK_INT :: type_bitsx, trivialx, not_trivialx, &
+ &type_bitsy, trivialy, not_trivialy, &
+ &type_bitsz, trivialz, not_trivialz
+
+ CCTK_REAL, dimension(:,:,:),allocatable :: &
+ &psi4, lbetax, lbetay, lbetaz
+!!$ CCTK_REAL, dimension(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)) :: &
+!!$ &psi4, lbetax, lbetay, lbetaz
+
+ CCTK_INT :: ierr
+
+ CCTK_REAL :: local_min_tracer
+
+ allocate(trivial_rp(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),STAT=ierr)
+ if (ierr .ne. 0) then
+ call CCTK_WARN(0, "Allocation problems with trivial_rp")
+ end if
+
+ allocate(psi4(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),&
+ lbetax(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),&
+ lbetay(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),&
+ lbetaz(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),STAT=ierr)
+ if (ierr .ne. 0) then
+ call CCTK_WARN(0, "Allocation problems with lbeta")
+ end if
+
+ call SpaceMask_GetTypeBits(type_bitsx, "Hydro_RiemannProblemX")
+ call SpaceMask_GetStateBits(trivialx, "Hydro_RiemannProblemX", &
+ &"trivial")
+ call SpaceMask_GetStateBits(not_trivialx, "Hydro_RiemannProblemX", &
+ &"not_trivial")
+ call SpaceMask_GetTypeBits(type_bitsy, "Hydro_RiemannProblemY")
+ call SpaceMask_GetStateBits(trivialy, "Hydro_RiemannProblemY", &
+ &"trivial")
+ call SpaceMask_GetStateBits(not_trivialy, "Hydro_RiemannProblemY", &
+ &"not_trivial")
+ call SpaceMask_GetTypeBits(type_bitsz, "Hydro_RiemannProblemZ")
+ call SpaceMask_GetStateBits(trivialz, "Hydro_RiemannProblemZ", &
+ &"trivial")
+ call SpaceMask_GetStateBits(not_trivialz, "Hydro_RiemannProblemZ", &
+ &"not_trivial")
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ trivial_rp = .false.
+
+!!$ Currently only option is reconstruction on primitive variables.
+!!$ Should change this.
+
+ psi4 = 1.d0
+
+ if (shift_state .ne. 0) then
+ lbetax = betax
+ lbetay = betay
+ lbetaz = betaz
+ else
+ lbetax = 0.d0
+ lbetay = 0.d0
+ lbetaz = 0.d0
+ end if
+
+!!$ Initialize variables that store reconstructed quantities
+
+ rhoplus = 0.0d0
+ rhominus = 0.0d0
+ epsplus = 0.0d0
+ epsminus = 0.0d0
+ velxplus = 0.0d0
+ velxminus = 0.0d0
+ velyplus = 0.0d0
+ velyminus = 0.0d0
+ velzplus = 0.0d0
+ velzminus = 0.0d0
+ Bvecxplus = 0.0d0
+ Bvecxminus = 0.0d0
+ Bvecyplus = 0.0d0
+ Bvecyminus = 0.0d0
+ Bveczplus = 0.0d0
+ Bveczminus = 0.0d0
+
+ if (evolve_tracer .ne. 0) then
+ tracerplus = 0.0d0
+ tracerminus = 0.0d0
+ endif
+
+ if (CCTK_EQUALS(recon_method,"tvd")) then
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ tracer(:,:,:,itracer), tracerplus(:,:,:,itracer), &
+ tracerminus(:,:,:,itracer), &
+ trivial_rp, hydro_excision_mask)
+ enddo
+ end if
+
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ rho, rhoplus, rhominus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ vel(:,:,:,1), velxplus, velxminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ vel(:,:,:,2), velyplus, velyminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ vel(:,:,:,3), velzplus, velzminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ eps, epsplus, epsminus, trivial_rp, hydro_excision_mask)
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ dens, densplus, densminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ scon(:,:,:,1), sxplus, sxminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ scon(:,:,:,2), syplus, syminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ scon(:,:,:,3), szplus, szminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ tau, tauplus, tauminus, trivial_rp, hydro_excision_mask)
+ else
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ end if
+
+!!$ B-field is both prim and con
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ Bvec(:,:,:,1), Bvecxplus, Bvecxminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ Bvec(:,:,:,2), Bvecyplus, Bvecyminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ Bvec(:,:,:,3), Bveczplus, Bveczminus, trivial_rp, hydro_excision_mask)
+
+
+
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = 1, nz
+ do j = 1, ny
+ do i = 1, nx
+ if (trivial_rp(i,j,k)) then
+ if (flux_direction == 1) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
+ else if (flux_direction == 2) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsy, trivialy)
+ else if (flux_direction == 3) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsz, trivialz)
+ end if
+ else
+ if (flux_direction == 1) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, not_trivialx)
+ else if (flux_direction == 2) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsy, not_trivialy)
+ else if (flux_direction == 3) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsz, not_trivialz)
+ end if
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+
+ else if (CCTK_EQUALS(recon_method,"ppm")) then
+
+ if (flux_direction == 1) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+ do j = GRHydro_stencil, ny - GRHydro_stencil + 1
+ call SimplePPM_1dM(GRHydro_eos_handle,0,nx,CCTK_DELTA_SPACE(1),&
+ rho(:,j,k),velx(:,j,k),vely(:,j,k),velz(:,j,k),&
+ Bvecx(:,j,k),Bvecy(:,j,k),Bvecz(:,j,k),eps(:,j,k),press(:,j,k),&
+ rhominus(:,j,k),velxminus(:,j,k),velyminus(:,j,k),velzminus(:,j,k),&
+ Bvecxminus(:,j,k),Bvecyminus(:,j,k),Bveczminus(:,j,k),epsminus(:,j,k),&
+ rhoplus(:,j,k),velxplus(:,j,k),velyplus(:,j,k),velzplus(:,j,k),&
+ Bvecxplus(:,j,k),Bvecyplus(:,j,k),Bveczplus(:,j,k),epsplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k),&
+ gxx(:,j,k), gxy(:,j,k), gxz(:,j,k), gyy(:,j,k), gyz(:,j,k), &
+ gzz(:,j,k), psi4(:,j,k), lbetax(:,j,k), alp(:,j,k),&
+ w_lorentz(:,j,k), &
+ 1, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_x_left, &
+ GRHydro_mppm_eigenvalue_x_right, &
+ GRHydro_mppm_xwind)
+ do i = 1, nx
+ if (trivial_rp(i,j,k)) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, not_trivialx)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ if(evolve_tracer.ne.0) then
+ !$OMP PARALLEL DO PRIVATE(j)
+ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+ do j = GRHydro_stencil, ny - GRHydro_stencil + 1
+ call SimplePPM_tracer_1d(nx,CCTK_DELTA_SPACE(1),rho(:,j,k), &
+ velx(:,j,k),vely(:,j,k),velz(:,j,k), &
+ tracer(:,j,k,:),tracerminus(:,j,k,:),tracerplus(:,j,k,:), &
+ press(:,j,k))
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ end if
+
+ else if (flux_direction == 2) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+ call SimplePPM_1dM(GRHydro_eos_handle,0,ny,CCTK_DELTA_SPACE(2),&
+ rho(j,:,k),vely(j,:,k),velz(j,:,k),velx(j,:,k),&
+ Bvecy(j,:,k),Bvecz(j,:,k),Bvecx(j,:,k),eps(j,:,k),press(j,:,k),&
+ rhominus(j,:,k),velyminus(j,:,k),velzminus(j,:,k),velxminus(j,:,k),&
+ Bvecyminus(j,:,k),Bveczminus(j,:,k),Bvecxminus(j,:,k),epsminus(j,:,k),&
+ rhoplus(j,:,k),velyplus(j,:,k),velzplus(j,:,k),velxplus(j,:,k),&
+ Bvecyplus(j,:,k),Bveczplus(j,:,k),Bvecxplus(j,:,k),epsplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k),&
+ gyy(j,:,k), gyz(j,:,k), gxy(j,:,k), gzz(j,:,k), gxz(j,:,k), &
+ gxx(j,:,k), psi4(j,:,k), lbetay(j,:,k), alp(j,:,k),&
+ w_lorentz(j,:,k), &
+ 2, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_y_left, &
+ GRHydro_mppm_eigenvalue_y_right, &
+ GRHydro_mppm_xwind)
+ do i = 1, ny
+ if (trivial_rp(j,i,k)) then
+ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, trivialy)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, not_trivialy)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ if(evolve_tracer.ne.0) then
+ !$OMP PARALLEL DO PRIVATE(j)
+ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+ call SimplePPM_tracer_1d(ny,CCTK_DELTA_SPACE(2),rho(j,:,k), &
+ vely(j,:,k),velz(j,:,k),velx(j,:,k), &
+ tracer(j,:,k,:),tracerminus(j,:,k,:),tracerplus(j,:,k,:), &
+ press(j,:,k))
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ end if
+
+ else if (flux_direction == 3) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, ny - GRHydro_stencil + 1
+ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+ call SimplePPM_1dM(GRHydro_eos_handle,0,nz,CCTK_DELTA_SPACE(3),&
+ rho(j,k,:),velz(j,k,:),velx(j,k,:),vely(j,k,:),&
+ Bvecz(j,k,:),Bvecx(j,k,:),Bvecy(j,k,:),eps(j,k,:),press(j,k,:),&
+ rhominus(j,k,:),velzminus(j,k,:),velxminus(j,k,:),velyminus(j,k,:),&
+ Bveczminus(j,k,:),Bvecxminus(j,k,:),Bvecyminus(j,k,:),epsminus(j,k,:),&
+ rhoplus(j,k,:),velzplus(j,k,:),velxplus(j,k,:),velyplus(j,k,:),&
+ Bveczplus(j,k,:),Bvecxplus(j,k,:),Bvecyplus(j,k,:),epsplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:),&
+ gzz(j,k,:), gxz(j,k,:), gyz(j,k,:), gxx(j,k,:), gxy(j,k,:), &
+ gyy(j,k,:), psi4(j,k,:), lbetaz(j,k,:), alp(j,k,:),&
+ w_lorentz(j,k,:), &
+ 3, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_z_left, &
+ GRHydro_mppm_eigenvalue_z_right, &
+ GRHydro_mppm_xwind)
+ do i = 1, nz
+ if (trivial_rp(j,k,i)) then
+ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, trivialz)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, not_trivialz)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ if(evolve_tracer.ne.0) then
+ !$OMP PARALLEL DO PRIVATE(j)
+ do k = GRHydro_stencil, ny - GRHydro_stencil + 1
+ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+
+ call SimplePPM_tracer_1d(nz,CCTK_DELTA_SPACE(3),rho(j,k,:), &
+ velz(j,k,:),velx(j,k,:),vely(j,k,:), &
+ tracer(j,k,:,:),tracerminus(j,k,:,:),tracerplus(j,k,:,:), &
+ press(j,k,:))
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ end if
+
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+
+!! call CCTK_WARN(0, "PPM not implemented in MHD yet!!!")
+
+ else if (CCTK_EQUALS(recon_method,"eno")) then
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ tracer(:,:,:,itracer), tracerplus(:,:,:,itracer), &
+ tracerminus(:,:,:,itracer), trivial_rp, &
+ hydro_excision_mask)
+ enddo
+ end if
+
+ if (flux_direction == 1) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil + 1
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ rho(:,j,k),rhominus(:,j,k),rhoplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ velx(:,j,k),velxminus(:,j,k),velxplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ vely(:,j,k),velyminus(:,j,k),velyplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ velz(:,j,k),velzminus(:,j,k),velzplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ eps(:,j,k),epsminus(:,j,k),epsplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ dens(:,j,k),densminus(:,j,k),densplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ sx(:,j,k),sxminus(:,j,k),sxplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ sy(:,j,k),syminus(:,j,k),syplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ sz(:,j,k),szminus(:,j,k),szplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ tau(:,j,k),tauminus(:,j,k),tauplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ else
+ !$OMP CRITICAL
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ !$OMP END CRITICAL
+ end if
+
+!!$ B-fields are both prim and con
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ Bvecx(:,j,k),Bvecxminus(:,j,k),Bvecxplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ Bvecy(:,j,k),Bvecyminus(:,j,k),Bvecyplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ Bvecz(:,j,k),Bveczminus(:,j,k),Bveczplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+
+
+ do i = 1, cctk_lsh(1)
+ if (trivial_rp(i,j,k)) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, not_trivialx)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ else if (flux_direction == 2) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil + 1
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ rho(j,:,k),rhominus(j,:,k),rhoplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ velx(j,:,k),velxminus(j,:,k),velxplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ vely(j,:,k),velyminus(j,:,k),velyplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ velz(j,:,k),velzminus(j,:,k),velzplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ eps(j,:,k),epsminus(j,:,k),epsplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ dens(j,:,k),densminus(j,:,k),densplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ sx(j,:,k),sxminus(j,:,k),sxplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ sy(j,:,k),syminus(j,:,k),syplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ sz(j,:,k),szminus(j,:,k),szplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ tau(j,:,k),tauminus(j,:,k),tauplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ else
+ !$OMP CRITICAL
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ !$OMP END CRITICAL
+ end if
+
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ Bvecx(j,:,k),Bvecxminus(j,:,k),Bvecxplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ Bvecy(j,:,k),Bvecyminus(j,:,k),Bvecyplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ Bvecz(j,:,k),Bveczminus(j,:,k),Bveczplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+
+ do i = 1, cctk_lsh(2)
+ if (trivial_rp(j,i,k)) then
+ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, trivialy)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, not_trivialy)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ else if (flux_direction == 3) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil + 1
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ rho(j,k,:),rhominus(j,k,:),rhoplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ velx(j,k,:),velxminus(j,k,:),velxplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ vely(j,k,:),velyminus(j,k,:),velyplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ velz(j,k,:),velzminus(j,k,:),velzplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ eps(j,k,:),epsminus(j,k,:),epsplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ dens(j,k,:),densminus(j,k,:),densplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ sx(j,k,:),sxminus(j,k,:),sxplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ sy(j,k,:),syminus(j,k,:),syplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ sz(j,k,:),szminus(j,k,:),szplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ tau(j,k,:),tauminus(j,k,:),tauplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ else
+ !$OMP CRITICAL
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ !$OMP END CRITICAL
+ end if
+
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ Bvecx(j,k,:),Bvecxminus(j,k,:),Bvecxplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ Bvecy(j,k,:),Bvecyminus(j,k,:),Bvecyplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ Bvecz(j,k,:),Bveczminus(j,k,:),Bveczplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+
+ do i = 1, cctk_lsh(3)
+ if (trivial_rp(j,k,i)) then
+ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, trivialz)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, not_trivialz)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ call CCTK_WARN(0, "Reconstruction method not recognized!")
+ end if
+
+ deallocate(trivial_rp)
+ deallocate(psi4, lbetax, lbetay, lbetaz)
+
+ !$OMP WORKSHARE
+ where ( (rhoplus < GRHydro_rho_min).or.(rhominus < GRHydro_rho_min).or.&
+ (epsplus < 0.d0).or.(epsminus < 0.d0) )
+ rhoplus = rho
+ rhominus = rho
+ velxplus = vel(:,:,:,1)
+ velxminus = vel(:,:,:,1)
+ velyplus = vel(:,:,:,2)
+ velyminus = vel(:,:,:,2)
+ velzplus = vel(:,:,:,3)
+ velzminus = vel(:,:,:,3)
+ epsplus = eps
+ epsminus = eps
+ Bvecxplus = Bvec(:,:,:,1)
+ Bvecxminus = Bvec(:,:,:,1)
+ Bvecyplus = Bvec(:,:,:,2)
+ Bvecyminus = Bvec(:,:,:,2)
+ Bveczplus = Bvec(:,:,:,3)
+ Bveczminus = Bvec(:,:,:,3)
+
+ end where
+ !$OMP END WORKSHARE
+
+ if (evolve_tracer .ne. 0) then
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+ !$OMP WORKSHARE
+ where( (tracerplus .le. local_min_tracer).or.&
+ (tracerminus .le. local_min_tracer) )
+ tracerplus = tracer
+ tracerminus = tracer
+ end where
+ !$OMP END WORKSHARE
+ ! Call the conserved tracer routine in any case because (accord. to
+ ! Christian Ott) this is the only way this works
+
+!!$ Tracer routines don't require changes for MHD!
+
+ call Prim2ConservativeTracer(CCTK_PASS_FTOF)
+ endif
+
+ if (CCTK_EQUALS(recon_vars,"primitive")&
+!!$ PPM is not implemented yet in MHD!
+!!$ .or.CCTK_EQUALS(recon_method,"ppm")&
+ ) then
+ if (use_eosgeneral == 0) then
+ call primitive2conservativeM(CCTK_PASS_FTOF)
+ else
+ call primitive2conservativegeneralM(CCTK_PASS_FTOF)
+ end if
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call Conservative2PrimitiveBoundsM(CCTK_PASS_FTOF)
+ else
+ call CCTK_WARN(0,"Variable type to reconstruct not recognized.")
+ end if
+
+ return
+
+end subroutine ReconstructionM
+
diff --git a/src/GRHydro_ReconstructPolyM.F90 b/src/GRHydro_ReconstructPolyM.F90
new file mode 100644
index 0000000..a5b3acd
--- /dev/null
+++ b/src/GRHydro_ReconstructPolyM.F90
@@ -0,0 +1,593 @@
+ /*@@
+ @file GRHydro_ReconstructPolyM.F90
+ @date Sep 2, 2010
+ @author
+ @desc
+ Wrapper routine to perform the reconstruction for polytropes.
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "cctk_Functions.h"
+
+#include "SpaceMask.h"
+
+#define velx(i,j,k) vel(i,j,k,1)
+#define vely(i,j,k) vel(i,j,k,2)
+#define velz(i,j,k) vel(i,j,k,3)
+#define sx(i,j,k) scon(i,j,k,1)
+#define sy(i,j,k) scon(i,j,k,2)
+#define sz(i,j,k) scon(i,j,k,3)
+#define Bvecx(i,j,k) Bvec(i,j,k,1)
+#define Bvecy(i,j,k) Bvec(i,j,k,2)
+#define Bvecz(i,j,k) Bvec(i,j,k,3)
+
+
+ /*@@
+ @routine ReconstructionPolytypeM
+ @date Tue Mar 19 11:36:55 2002
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ If using a polytropic type EOS, we do not have to reconstruct all the
+ variables.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine ReconstructionPolytypeM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ integer :: nx, ny, nz, i, j, k, itracer
+
+ logical, dimension(:,:,:), allocatable :: trivial_rp
+!!$ logical, dimension(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)) :: trivial_rp
+
+ CCTK_INT :: type_bitsx, trivialx, not_trivialx, &
+ &type_bitsy, trivialy, not_trivialy, &
+ &type_bitsz, trivialz, not_trivialz
+
+ CCTK_REAL, dimension(:,:,:),allocatable :: &
+ &psi4, lbetax, lbetay, lbetaz
+!!$ CCTK_REAL, dimension(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)) :: &
+!!$ &psi4, lbetax, lbetay, lbetaz
+
+ CCTK_INT :: ierr
+
+ CCTK_REAL :: local_min_tracer
+
+ allocate(trivial_rp(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),STAT=ierr)
+ if (ierr .ne. 0) then
+ call CCTK_WARN(0, "Allocation problems with trivial_rp")
+ end if
+
+ allocate(psi4(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),&
+ lbetax(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),&
+ lbetay(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),&
+ lbetaz(cctk_lsh(1),cctk_lsh(2),cctk_lsh(3)),STAT=ierr)
+ if (ierr .ne. 0) then
+ call CCTK_WARN(0, "Allocation problems with lbeta")
+ end if
+
+ call SpaceMask_GetTypeBits(type_bitsx, "Hydro_RiemannProblemX")
+ call SpaceMask_GetStateBits(trivialx, "Hydro_RiemannProblemX", &
+ &"trivial")
+ call SpaceMask_GetStateBits(not_trivialx, "Hydro_RiemannProblemX", &
+ &"not_trivial")
+ call SpaceMask_GetTypeBits(type_bitsy, "Hydro_RiemannProblemY")
+ call SpaceMask_GetStateBits(trivialy, "Hydro_RiemannProblemY", &
+ &"trivial")
+ call SpaceMask_GetStateBits(not_trivialy, "Hydro_RiemannProblemY", &
+ &"not_trivial")
+ call SpaceMask_GetTypeBits(type_bitsz, "Hydro_RiemannProblemZ")
+ call SpaceMask_GetStateBits(trivialz, "Hydro_RiemannProblemZ", &
+ &"trivial")
+ call SpaceMask_GetStateBits(not_trivialz, "Hydro_RiemannProblemZ", &
+ &"not_trivial")
+
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+
+ trivial_rp = .false.
+
+!!$ Currently only option is reconstruction on primitive variables.
+!!$ Should change this.
+
+ psi4 = 1.d0
+
+ if (shift_state .ne. 0) then
+ lbetax = betax
+ lbetay = betay
+ lbetaz = betaz
+ else
+ lbetax = 0.d0
+ lbetay = 0.d0
+ lbetaz = 0.d0
+ end if
+
+!!$ Initialize variables that store reconstructed quantities
+
+ rhoplus = 0.0d0
+ rhominus = 0.0d0
+ epsplus = 0.0d0
+ epsminus = 0.0d0
+ velxplus = 0.0d0
+ velxminus = 0.0d0
+ velyplus = 0.0d0
+ velyminus = 0.0d0
+ velzplus = 0.0d0
+ velzminus = 0.0d0
+ Bvecxplus = 0.0d0
+ Bvecxminus = 0.0d0
+ Bvecyplus = 0.0d0
+ Bvecyminus = 0.0d0
+ Bveczplus = 0.0d0
+ Bveczminus = 0.0d0
+
+ if (evolve_tracer .ne. 0) then
+ tracerplus = 0.0d0
+ tracerminus = 0.0d0
+ endif
+
+ if (CCTK_EQUALS(recon_method,"tvd")) then
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ tracer(:,:,:,itracer), tracerplus(:,:,:,itracer), &
+ tracerminus(:,:,:,itracer), &
+ trivial_rp, hydro_excision_mask)
+ enddo
+ end if
+
+
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ rho, rhoplus, rhominus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ vel(:,:,:,1), velxplus, velxminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ vel(:,:,:,2), velyplus, velyminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ vel(:,:,:,3), velzplus, velzminus, trivial_rp, hydro_excision_mask)
+
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ dens, densplus, densminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ scon(:,:,:,1), sxplus, sxminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ scon(:,:,:,2), syplus, syminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ scon(:,:,:,3), szplus, szminus, trivial_rp, hydro_excision_mask)
+
+ else
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ end if
+
+!!$ B-field always needs reconstruction, as it is both prim and con
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ Bvec(:,:,:,1), Bvecxplus, Bvecxminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ Bvec(:,:,:,2), Bvecyplus, Bvecyminus, trivial_rp, hydro_excision_mask)
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ Bvec(:,:,:,3), Bveczplus, Bveczminus, trivial_rp, hydro_excision_mask)
+
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = 1, nz
+ do j = 1, ny
+ do i = 1, nx
+ if (trivial_rp(i,j,k)) then
+ if (flux_direction == 1) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
+ else if (flux_direction == 2) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsy, trivialy)
+ else if (flux_direction == 3) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsz, trivialz)
+ end if
+ else
+ if (flux_direction == 1) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, not_trivialx)
+ else if (flux_direction == 2) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsy, not_trivialy)
+ else if (flux_direction == 3) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsz, not_trivialz)
+ end if
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+
+ else if (CCTK_EQUALS(recon_method,"ppm")) then
+
+!!$ if (flux_direction == 1) then
+!!$ !$OMP PARALLEL DO PRIVATE(i, j)
+!!$ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+!!$ do j = GRHydro_stencil, ny - GRHydro_stencil + 1
+!!$ call SimplePPM_1d(GRHydro_eos_handle,1,nx,CCTK_DELTA_SPACE(1),&
+!!$ rho(:,j,k),velx(:,j,k),vely(:,j,k),velz(:,j,k),eps(:,j,k),&
+!!$ press(:,j,k),rhominus(:,j,k),velxminus(:,j,k),velyminus(:,j,k),&
+!!$ velzminus(:,j,k),epsminus(:,j,k),rhoplus(:,j,k),&
+!!$ velxplus(:,j,k),velyplus(:,j,k),velzplus(:,j,k),epsplus(:,j,k),&
+!!$ trivial_rp(:,j,k), hydro_excision_mask(:,j,k),&
+!!$ gxx(:,j,k), gxy(:,j,k), gxz(:,j,k), gyy(:,j,k), gyz(:,j,k), &
+!!$ gzz(:,j,k), psi4(:,j,k), lbetax(:,j,k), alp(:,j,k),&
+!!$ w_lorentz(:,j,k), &
+!!$ 1, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_x_left, &
+!!$ GRHydro_mppm_eigenvalue_x_right, &
+!!$ GRHydro_mppm_xwind)
+!!$ do i = 1, nx
+!!$ if (trivial_rp(i,j,k)) then
+!!$ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
+!!$ else
+!!$ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, not_trivialx)
+!!$ end if
+!!$ end do
+!!$ end do
+!!$ end do
+!!$ !$OMP END PARALLEL DO
+!!$ if(evolve_tracer.ne.0) then
+!!$ !$OMP PARALLEL DO PRIVATE(j)
+!!$ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+!!$ do j = GRHydro_stencil, ny - GRHydro_stencil + 1
+!!$ call SimplePPM_tracer_1d(nx,CCTK_DELTA_SPACE(1),rho(:,j,k), &
+!!$ velx(:,j,k),vely(:,j,k),velz(:,j,k), &
+!!$ tracer(:,j,k,:),tracerminus(:,j,k,:),tracerplus(:,j,k,:), &
+!!$ press(:,j,k))
+!!$ end do
+!!$ end do
+!!$ !$OMP END PARALLEL DO
+!!$ end if
+!!$
+!!$ else if (flux_direction == 2) then
+!!$ !$OMP PARALLEL DO PRIVATE(i, j)
+!!$ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+!!$ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+!!$ call SimplePPM_1d(GRHydro_eos_handle,1,ny,CCTK_DELTA_SPACE(2),&
+!!$ rho(j,:,k),vely(j,:,k),velz(j,:,k),velx(j,:,k),eps(j,:,k),&
+!!$ press(j,:,k),rhominus(j,:,k),velyminus(j,:,k),velzminus(j,:,k),&
+!!$ velxminus(j,:,k),epsminus(j,:,k),rhoplus(j,:,k),&
+!!$ velyplus(j,:,k),velzplus(j,:,k),velxplus(j,:,k),epsplus(j,:,k),&
+!!$ trivial_rp(j,:,k), hydro_excision_mask(j,:,k),&
+!!$ gyy(j,:,k), gyz(j,:,k), gxy(j,:,k), gzz(j,:,k), gxz(j,:,k), &
+!!$ gxx(j,:,k), psi4(j,:,k), lbetay(j,:,k), alp(j,:,k),&
+!!$ w_lorentz(j,:,k), &
+!!$ 2, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_y_left, &
+!!$ GRHydro_mppm_eigenvalue_y_right, &
+!!$ GRHydro_mppm_xwind)
+!!$ do i = 1, ny
+!!$ if (trivial_rp(j,i,k)) then
+!!$ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, trivialy)
+!!$ else
+!!$ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, not_trivialy)
+!!$ end if
+!!$ end do
+!!$ end do
+!!$ end do
+!!$ !$OMP END PARALLEL DO
+!!$ if(evolve_tracer.ne.0) then
+!!$ !$OMP PARALLEL DO PRIVATE(j)
+!!$ do k = GRHydro_stencil, nz - GRHydro_stencil + 1
+!!$ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+!!$ call SimplePPM_tracer_1d(ny,CCTK_DELTA_SPACE(2),rho(j,:,k), &
+!!$ vely(j,:,k),velz(j,:,k),velx(j,:,k), &
+!!$ tracer(j,:,k,:),tracerminus(j,:,k,:),tracerplus(j,:,k,:), &
+!!$ press(j,:,k))
+!!$ end do
+!!$ end do
+!!$ !$OMP END PARALLEL DO
+!!$ end if
+!!$
+!!$ else if (flux_direction == 3) then
+!!$ !$OMP PARALLEL DO PRIVATE(i, j)
+!!$ do k = GRHydro_stencil, ny - GRHydro_stencil + 1
+!!$ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+!!$ call SimplePPM_1d(GRHydro_eos_handle,1,nz,CCTK_DELTA_SPACE(3),&
+!!$ rho(j,k,:),velz(j,k,:),velx(j,k,:),vely(j,k,:),eps(j,k,:),&
+!!$ press(j,k,:),rhominus(j,k,:),velzminus(j,k,:),velxminus(j,k,:),&
+!!$ velyminus(j,k,:),epsminus(j,k,:),rhoplus(j,k,:),&
+!!$ velzplus(j,k,:),velxplus(j,k,:),velyplus(j,k,:),epsplus(j,k,:),&
+!!$ trivial_rp(j,k,:), hydro_excision_mask(j,k,:),&
+!!$ gzz(j,k,:), gxz(j,k,:), gyz(j,k,:), gxx(j,k,:), gxy(j,k,:), &
+!!$ gyy(j,k,:), psi4(j,k,:), lbetaz(j,k,:), alp(j,k,:),&
+!!$ w_lorentz(j,k,:), &
+!!$ 3, j, k, nx, ny, nz, GRHydro_mppm_eigenvalue_z_left, &
+!!$ GRHydro_mppm_eigenvalue_z_right, &
+!!$ GRHydro_mppm_xwind)
+!!$ do i = 1, nz
+!!$ if (trivial_rp(j,k,i)) then
+!!$ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, trivialz)
+!!$ else
+!!$ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, not_trivialz)
+!!$ end if
+!!$ end do
+!!$ end do
+!!$ end do
+!!$ !$OMP END PARALLEL DO
+!!$ if(evolve_tracer.ne.0) then
+!!$ !$OMP PARALLEL DO PRIVATE(j)
+!!$ do k = GRHydro_stencil, ny - GRHydro_stencil + 1
+!!$ do j = GRHydro_stencil, nx - GRHydro_stencil + 1
+!!$
+!!$ call SimplePPM_tracer_1d(nz,CCTK_DELTA_SPACE(3),rho(j,k,:), &
+!!$ velz(j,k,:),velx(j,k,:),vely(j,k,:), &
+!!$ tracer(j,k,:,:),tracerminus(j,k,:,:),tracerplus(j,k,:,:), &
+!!$ press(j,k,:))
+!!$ end do
+!!$ end do
+!!$ !$OMP END PARALLEL DO
+!!$ end if
+!!$
+!!$ else
+!!$ call CCTK_WARN(0, "Flux direction not x,y,z")
+!!$ end if
+
+ call CCTK_WARN(0, "PPM not implemented in MHD yet!!!")
+
+ else if (CCTK_EQUALS(recon_method,"eno")) then
+
+ if (evolve_tracer .ne. 0) then
+ do itracer=1,number_of_tracers
+ call tvdreconstruct(nx, ny, nz, xoffset, yoffset, zoffset, &
+ tracer(:,:,:,itracer), tracerplus(:,:,:,itracer), &
+ tracerminus(:,:,:,itracer), trivial_rp, &
+ hydro_excision_mask)
+ enddo
+ end if
+
+ if (flux_direction == 1) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil + 1
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ rho(:,j,k),rhominus(:,j,k),rhoplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ velx(:,j,k),velxminus(:,j,k),velxplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ vely(:,j,k),velyminus(:,j,k),velyplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ velz(:,j,k),velzminus(:,j,k),velzplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ dens(:,j,k),densminus(:,j,k),densplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ sx(:,j,k),sxminus(:,j,k),sxplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ sy(:,j,k),syminus(:,j,k),syplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ sz(:,j,k),szminus(:,j,k),szplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ else
+ !$OMP CRITICAL
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ !$OMP END CRITICAL
+ end if
+
+!!$ Always do B-field
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ Bvecx(:,j,k),Bvecxminus(:,j,k),Bvecxplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ Bvecy(:,j,k),Bvecyminus(:,j,k),Bvecyplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(1),&
+ Bvecz(:,j,k),Bveczminus(:,j,k),Bveczplus(:,j,k),&
+ trivial_rp(:,j,k), hydro_excision_mask(:,j,k))
+
+ do i = 1, cctk_lsh(1)
+ if (trivial_rp(i,j,k)) then
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, trivialx)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bitsx, not_trivialx)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ else if (flux_direction == 2) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil + 1
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ rho(j,:,k),rhominus(j,:,k),rhoplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ velx(j,:,k),velxminus(j,:,k),velxplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ vely(j,:,k),velyminus(j,:,k),velyplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ velz(j,:,k),velzminus(j,:,k),velzplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ dens(j,:,k),densminus(j,:,k),densplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ sx(j,:,k),sxminus(j,:,k),sxplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ sy(j,:,k),syminus(j,:,k),syplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ sz(j,:,k),szminus(j,:,k),szplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ else
+ !$OMP CRITICAL
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ !$OMP END CRITICAL
+ end if
+
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ Bvecx(j,:,k),Bvecxminus(j,:,k),Bvecxplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ Bvecy(j,:,k),Bvecyminus(j,:,k),Bvecyplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(2),&
+ Bvecz(j,:,k),Bveczminus(j,:,k),Bveczplus(j,:,k),&
+ trivial_rp(j,:,k), hydro_excision_mask(j,:,k))
+
+ do i = 1, cctk_lsh(2)
+ if (trivial_rp(j,i,k)) then
+ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, trivialy)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, j, i, k, type_bitsy, not_trivialy)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ else if (flux_direction == 3) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil + 1
+ do j = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil + 1
+ if (CCTK_EQUALS(recon_vars,"primitive")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ rho(j,k,:),rhominus(j,k,:),rhoplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ velx(j,k,:),velxminus(j,k,:),velxplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ vely(j,k,:),velyminus(j,k,:),velyplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ velz(j,k,:),velzminus(j,k,:),velzplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ dens(j,k,:),densminus(j,k,:),densplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ sx(j,k,:),sxminus(j,k,:),sxplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ sy(j,k,:),syminus(j,k,:),syplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ sz(j,k,:),szminus(j,k,:),szplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ else
+ !$OMP CRITICAL
+ call CCTK_WARN(0, "Variable type to reconstruct not recognized.")
+ !$OMP END CRITICAL
+ end if
+
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ Bvecx(j,k,:),Bvecxminus(j,k,:),Bvecxplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ Bvecy(j,k,:),Bvecyminus(j,k,:),Bvecyplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+ call GRHydro_ENOReconstruct1d(eno_order,cctk_lsh(3),&
+ Bvecz(j,k,:),Bveczminus(j,k,:),Bveczplus(j,k,:),&
+ trivial_rp(j,k,:), hydro_excision_mask(j,k,:))
+
+ do i = 1, cctk_lsh(3)
+ if (trivial_rp(j,k,i)) then
+ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, trivialz)
+ else
+ SpaceMask_SetStateBitsF90(space_mask, j, k, i, type_bitsz, not_trivialz)
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ call CCTK_WARN(0, "Reconstruction method not recognized!")
+ end if
+
+ deallocate(trivial_rp)
+ deallocate(psi4, lbetax, lbetay, lbetaz)
+
+ !$OMP WORKSHARE
+ where ( (rhoplus < GRHydro_rho_min).or.(rhominus < GRHydro_rho_min).or.&
+ (epsplus < 0.d0).or.(epsminus < 0.d0) )
+ rhoplus = rho
+ rhominus = rho
+ velxplus = vel(:,:,:,1)
+ velxminus = vel(:,:,:,1)
+ velyplus = vel(:,:,:,2)
+ velyminus = vel(:,:,:,2)
+ velzplus = vel(:,:,:,3)
+ velzminus = vel(:,:,:,3)
+ epsplus = eps
+ epsminus = eps
+ Bvecxplus = Bvec(:,:,:,1)
+ Bvecxminus = Bvec(:,:,:,1)
+ Bvecyplus = Bvec(:,:,:,2)
+ Bvecyminus = Bvec(:,:,:,2)
+ Bveczplus = Bvec(:,:,:,3)
+ Bveczminus = Bvec(:,:,:,3)
+
+ end where
+ !$OMP END WORKSHARE
+
+ if (evolve_tracer .ne. 0) then
+ if (use_min_tracer .ne. 0) then
+ local_min_tracer = min_tracer
+ else
+ local_min_tracer = 0d0
+ end if
+
+ !$OMP WORKSHARE
+ where( (tracerplus .le. local_min_tracer).or.&
+ (tracerminus .le. local_min_tracer) )
+ tracerplus = tracer
+ tracerminus = tracer
+ end where
+ !$OMP END WORKSHARE
+ ! Call the conserved tracer routine in any case because (accord. to
+ ! Christian Ott) this is the only way this works
+!!$ No special call in MHD
+
+ call Prim2ConservativeTracer(CCTK_PASS_FTOF)
+ endif
+
+ if (CCTK_EQUALS(recon_vars,"primitive")&
+!!$ PPM not implemented yet
+!!$ .or.CCTK_EQUALS(recon_method,"ppm")&
+ ) then
+
+ if (use_eosgeneral == 0) then
+ call Prim2ConservativePolytypeM(CCTK_PASS_FTOF)
+ else
+ call primitive2conservativegeneralM(CCTK_PASS_FTOF)
+ end if
+ else if (CCTK_EQUALS(recon_vars,"conservative")) then
+ call Con2PrimBoundsPolytypeM(CCTK_PASS_FTOF)
+ else
+ call CCTK_WARN(0,"Variable type to reconstruct not recognized.")
+ end if
+
+ return
+
+end subroutine ReconstructionPolytypeM
+
diff --git a/src/GRHydro_RegisterGZM.cc b/src/GRHydro_RegisterGZM.cc
new file mode 100644
index 0000000..9f4ff93
--- /dev/null
+++ b/src/GRHydro_RegisterGZM.cc
@@ -0,0 +1,92 @@
+// register.cc -- register variables with various thorns that need-to-know
+// $Header$
+//
+// GRHydro_register_GZPatchSystem - register with GZPatchSystem
+//
+// Cut 'n paste job from BackgroundWaveToy, author J Thornburg...
+
+#include <cstdio>
+#include <string>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+
+using namespace std;
+
+//******************************************************************************
+
+//
+// This function is called by the Cactus scheduler to (maybe) register
+// our to-be-interpatch-synchronized variables with GZPatchSystem. It
+// checks if the GZPatchSystem registration function has been provided
+// (which it should be if and only if GZPatchSystem is active), and if so,
+// does the registration.
+//
+// If we're using Carpet, this function must be called in meta mode.
+//
+extern "C"void GRHydro_register_GZPatchSystemM(CCTK_ARGUMENTS)
+{
+
+ if (CCTK_IsFunctionAliased("GZPatchSystem_register_sync"))
+ {
+ CCTK_VInfo(CCTK_THORNSTRING,
+ "registering to-be-interpatch-synchronized variables "
+ "with GZPatchSystem");
+
+ string var[9] = {"HydroBase::rho", "HydroBase::press", "HydroBase::eps",
+ "HydroBase::vel",
+ "GRHydro::dens", "GRHydro::tau", "GRHydro::w_lorentz",
+ "GRHydro::scon", "HydroBase::Bvec"};
+ for (int i = 0; i < 9; i++)
+ {
+ int status =
+ GZPatchSystem_register_sync(var[i].c_str());
+ if (status < 0)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "***** GRHydro_register_GZPatchSystem():\n"
+ " error registering var group %s to be "
+ "interpatch-synchronized!\n"
+ " (GZPatchSystem_register_sync() error code %d)\n",
+ var[i].c_str(), status);
+ }
+ }
+
+ }
+ else
+ {
+ CCTK_WARN(1, "Function GZPatchSystem_register_sync not registered!");
+ }
+
+ if (CCTK_IsFunctionAliased("GZPatchSystem_register_cxform"))
+ {
+ CCTK_VInfo(CCTK_THORNSTRING,
+ "registering to-be-cxformed variables with GZPatchSystem");
+
+ string var[12] = {"HydroBase::rho", "HydroBase::press", "HydroBase::eps",
+ "HydroBase::vel",
+ "GRHydro::dens", "GRHydro::tau", "GRHydro::w_lorentz",
+ "GRHydro::scon", "HydroBase::Bvec",
+ "ADMBase::metric", "ADMBase::curv", "ADMBase::shift"};
+ for (int i = 0; i < 12; i++)
+ for (int j = 0; j < 3; j++)
+ {
+ int ps_status =
+ GZPatchSystem_register_cxform(j, var[i].c_str());
+ if (ps_status < 0)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "***** GRHydro_register_GZPatchSystem():\n"
+ " error registering var group %s to be "
+ "interpatch-cxformhronized!\n"
+ " (GZPatchSystem_register_cxform() error code %d)\n",
+ var[i].c_str(), ps_status);
+ }
+ }
+ }
+ else
+ {
+ CCTK_WARN(1, "Function GZPatchSystem_register_cxform not registered!");
+ }
+
+}
diff --git a/src/GRHydro_RegisterVarsM.cc b/src/GRHydro_RegisterVarsM.cc
new file mode 100644
index 0000000..f17254e
--- /dev/null
+++ b/src/GRHydro_RegisterVarsM.cc
@@ -0,0 +1,107 @@
+// GRHydro_RegisterVars.cc
+//
+// converted from F90 to improve readability and maintainability
+//
+// Frank Loeffler
+
+#include <cstdio>
+#include <string>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+using namespace std;
+
+// Utility functions to register variables with MoL
+// Note: We could check for the return value here, but MoL issues a
+// level 0 warning in that case anyway. If that changes in the
+// future, a check can simply be inserted here.
+static void register_evolved(string v1, string v2)
+{
+ MoLRegisterEvolvedGroup(CCTK_GroupIndex(v1.c_str()), CCTK_GroupIndex(v2.c_str()));
+}
+static void register_constrained(string v1)
+{
+ MoLRegisterConstrainedGroup(CCTK_GroupIndex(v1.c_str()));
+}
+static void register_saveandrestore(string v1)
+{
+ MoLRegisterSaveAndRestoreGroup(CCTK_GroupIndex(v1.c_str()));
+}
+
+// Main function called by Cactus to register variables with MoL
+
+extern "C"void GRHydro_RegisterM(CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ // We need some aliased functions, so we first check if they are available
+ string needed_funs[5] = {"MoLRegisterEvolvedGroup",
+ "MoLRegisterConstrainedGroup",
+ "MoLRegisterSaveAndRestoreGroup",
+ "MoLRegisterEvolved",
+ "MoLRegisterConstrained"};
+ for (int i = 0; i < 5; i++)
+ if (!CCTK_IsFunctionAliased(needed_funs[i].c_str()))
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The function \"%s\" has not been aliased!",
+ needed_funs[i].c_str());
+
+ // Now we can set which variables have to be registered as which type with MoL
+ register_constrained("HydroBase::rho");
+ register_constrained("HydroBase::press");
+ register_constrained("HydroBase::eps");
+ register_constrained("HydroBase::vel");
+ register_constrained("GRHydro::w_lorentz");
+
+ if (CCTK_EQUALS(evolution_method, "GRHydro"))
+ {
+ // dens and scon
+ register_evolved("GRHydro::dens", "GRHydro::densrhs");
+ register_evolved("GRHydro::scon", "GRHydro::srhs");
+ register_evolved("HydroBase::Bvec", "GRHydro::Bvecrhs");
+
+ // tau
+ if (CCTK_EQUALS(GRHydro_eos_type, "General"))
+ register_evolved("GRHydro::tau" , "GRHydro::taurhs");
+ else if (CCTK_EQUALS(GRHydro_eos_type, "Polytype"))
+ register_constrained("GRHydro::tau");
+ else
+ CCTK_WARN(0, "Don't recognize the type of EOS!");
+
+ // lapse, metric, curv
+ register_saveandrestore("admbase::lapse");
+ register_saveandrestore("admbase::metric");
+ register_saveandrestore("admbase::curv");
+
+ // shift
+ if (!CCTK_EQUALS(initial_shift, "none"))
+ {
+ if (CCTK_EQUALS(shift_evolution_method, "Comoving"))
+ {
+ register_constrained("admbase::shift");
+ register_evolved("GRHydro::GRHydro_coords", "GRHydro::GRHydro_coords_rhs");
+ }
+ else
+ register_saveandrestore("admbase::shift");
+ }
+
+ // tracer
+ if (evolve_tracer != 0)
+ register_evolved("GRHydro::GRHydro_cons_tracers", "GRHydro::GRHydro_tracer_rhs");
+
+ // particles
+ if (number_of_particles > 0)
+ register_evolved("GRHydro::particles", "GRHydro::particle_rhs");
+ }
+ else if (CCTK_EQUALS(evolution_method, "none"))
+ {
+ register_constrained("GRHydro::dens");
+ register_constrained("GRHydro::scon");
+ register_constrained("GRHydro::tau");
+ register_constrained("HydroBase::Bvec");
+ }
+}
+
diff --git a/src/GRHydro_RiemannSolveM.F90 b/src/GRHydro_RiemannSolveM.F90
new file mode 100644
index 0000000..46ab310
--- /dev/null
+++ b/src/GRHydro_RiemannSolveM.F90
@@ -0,0 +1,457 @@
+ /*@@
+ @file GRHydro_RiemannSolveM.F90
+ @date Sep 1, 2010
+ @author
+ @desc
+ A wrapper routine to call the correct Riemann solver
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "cctk_Functions.h"
+#include "GRHydro_Macros.h"
+
+ /*@@
+ @routine RiemannSolveM
+ @date Sep 1, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Pedro Montero, Ian Hawke
+ @desc
+ A wrapper routine to switch between the different Riemann solvers.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine RiemannSolveM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i,j,k
+
+ if (CCTK_EQUALS(riemann_solver,"HLLE")) then
+
+ call GRHydro_HLLEM(CCTK_PASS_FTOF)
+
+ if (evolve_tracer .ne. 0) then
+
+!!$ There are no special calls for tracers, which care not one whit about B-fields!
+!!$ Just call the standard version...
+
+ call GRHydro_HLLE_Tracer(CCTK_PASS_FTOF)
+
+ end if
+
+!!$ else if (CCTK_EQUALS(riemann_solver,"Roe")) then
+!!$
+!!$ call GRHydro_RoeSolveM(CCTK_PASS_FTOF)
+!!$
+!!$ if (evolve_tracer .ne. 0) then
+!!$
+!!$ call GRHydro_HLLE_Tracer(CCTK_PASS_FTOF)
+!!$
+!!$ end if
+!!$
+!!$ else if (CCTK_EQUALS(riemann_solver,"Marquina")) then
+!!$
+!!$ call GRHydro_MarquinaM(CCTK_PASS_FTOF)
+
+!!$ Tracers are built directly in to the Marquina solver
+
+ else
+
+ call CCTK_WARN(0, "Roe and Marquina not implemented in MHD yet!!!")
+
+ end if
+
+end subroutine RiemannSolveM
+
+ /*@@
+ @routine RiemannSolvePolytypeM
+ @date Sep 1, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ The same as above, just specializing to polytropic type EOS.
+ Currently there is no point to this routine right now.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+subroutine RiemannSolvePolytypeM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i,j,k
+
+ if (CCTK_EQUALS(riemann_solver,"HLLE")) then
+
+ call GRHydro_HLLEM(CCTK_PASS_FTOF)
+
+ if (evolve_tracer .ne. 0) then
+
+!!$ Call the non-MHD version - see above
+
+ call GRHydro_HLLE_Tracer(CCTK_PASS_FTOF)
+
+ end if
+
+!!$ else if (CCTK_EQUALS(riemann_solver,"Roe")) then
+!!$
+!!$ call GRHydro_RoeSolve(CCTK_PASS_FTOF)
+!!$
+!!$ if (evolve_tracer .ne. 0) then
+!!$
+!!$ call GRHydro_HLLE_Tracer(CCTK_PASS_FTOF)
+!!$
+!!$ end if
+!!$
+!!$ else if (CCTK_EQUALS(riemann_solver,"Marquina")) then
+!!$
+!!$ call GRHydro_Marquina(CCTK_PASS_FTOF)
+
+!!$ Tracers are built directly in to the Marquina solver
+
+ else
+
+ call CCTK_WARN(0, "Roe and Marquina not implemented in MHD yet!!!")
+
+ end if
+
+end subroutine RiemannSolvePolytypeM
+
+
+
+/*@@
+@routine RiemannSolveGeneralM
+@date Tue Mar 19 11:40:20 2002
+@author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+@desc
+The Riemann solvers for the new general EOS routines.
+This sets the fluxes from the left and right reconstructed
+states, so that after this routine they are effectively
+scratch space.
+@enddesc
+@calls
+@calledby
+@history
+
+@endhistory
+
+@@*/
+
+
+subroutine RiemannSolveGeneralM(CCTK_ARGUMENTS)
+
+ USE GRHydro_Scalars
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+ DECLARE_CCTK_FUNCTIONS
+
+ CCTK_INT :: i,j,k, ierr
+ CCTK_REAL, dimension(8) :: tmp_flux, cons_p, cons_m
+ CCTK_REAL, dimension(6) :: prim_p, prim_m
+ CCTK_REAL :: avg_det, avg_alp, avg_beta
+ CCTK_REAL :: gxxh, gyyh, gzzh, gxyh, gxzh, gyzh
+ CCTK_REAL :: avg_betax, avg_betay, avg_betaz
+ CCTK_REAL :: vxtp,vytp,vztp,vxtm,vytm,vztm,ab0p,ab0m,b2p,b2m,bdotvp,bdotvm
+ CCTK_REAL :: wp,wm,v2p,v2m,bxlowp,bxlowm,bylowp,bylowm,bzlowp,bzlowm,vA2m,vA2p
+ CCTK_REAL :: Bvecxlowp,Bvecxlowm,Bvecylowp,Bvecylowm,Bveczlowp,Bveczlowm
+ CCTK_REAL :: pressstarp,pressstarm,rhoenth_p,rhoenth_m
+ CCTK_REAL :: velxlowp,velxlowm,velylowp,velylowm,velzlowp,velzlowm
+
+ densflux = 0.d0
+ sxflux = 0.d0
+ syflux = 0.d0
+ szflux = 0.d0
+ tauflux = 0.d0
+ Bvecxflux = 0.d0
+ Bvecyflux = 0.d0
+ Bveczflux = 0.d0
+
+!!$ Do the EOS call to set the pressure, derivative and cs2
+
+ ierr = EOS_SetGFs(cctkGH, EOS_RiemannCallPlus)
+ ierr = EOS_SetGFs(cctkGH, EOS_RiemannCallMinus)
+
+
+ if (CCTK_EQUALS(riemann_solver,"HLLE")) then
+
+ call GRHydro_HLLEGeneralM(CCTK_PASS_FTOF)
+
+ if (evolve_tracer .ne. 0) then
+
+!!$ No b-field component for tracers!
+ call GRHydro_HLLE_TracerGeneral(CCTK_PASS_FTOF)
+
+ end if
+
+ else
+
+ do k = GRHydro_stencil, cctk_lsh(3) - GRHydro_stencil
+ do j = GRHydro_stencil, cctk_lsh(2) - GRHydro_stencil
+ do i = GRHydro_stencil, cctk_lsh(1) - GRHydro_stencil
+
+!!$ Set the left (p for plus) and right (m for minus, i+1) states
+
+ cons_p(1) = densplus(i,j,k)
+ cons_p(2) = sxplus(i,j,k)
+ cons_p(3) = syplus(i,j,k)
+ cons_p(4) = szplus(i,j,k)
+ cons_p(5) = tauplus(i,j,k)
+ cons_p(6) = Bvecxplus(i,j,k)
+ cons_p(7) = Bvecyplus(i,j,k)
+ cons_p(8) = Bveczplus(i,j,k)
+
+ cons_m(1) = densminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(2) = sxminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(3) = syminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(4) = szminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(5) = tauminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(6) = Bvecxminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(7) = Bvecyminus(i+xoffset,j+yoffset,k+zoffset)
+ cons_m(8) = Bveczminus(i+xoffset,j+yoffset,k+zoffset)
+
+ prim_p(1) = rhoplus(i,j,k)
+ prim_p(2) = velxplus(i,j,k)
+ prim_p(3) = velyplus(i,j,k)
+ prim_p(4) = velzplus(i,j,k)
+ prim_p(5) = epsplus(i,j,k)
+ prim_p(6) = pressplus(i,j,k)
+ rhoenth_p = prim_p(1)*(1.0d0+prim_p(5))+prim_p(6)
+
+ prim_m(1) = rhominus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(2) = velxminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(3) = velyminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(4) = velzminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(5) = epsminus(i+xoffset,j+yoffset,k+zoffset)
+ prim_m(6) = pressminus(i+xoffset,j+yoffset,k+zoffset)
+ rhoenth_m = prim_m(1)*(1.0d0+prim_m(5))+prim_m(6)
+
+!!$ Set metric terms at interface
+
+ if (shift_state .ne. 0) then
+ avg_betax = 0.5d0*(betax(i+xoffset,j+yoffset,k+zoffset)+betax(i,j,k))
+ avg_betay = 0.5d0*(betay(i+xoffset,j+yoffset,k+zoffset)+betay(i,j,k))
+ avg_betaz = 0.5d0*(betaz(i+xoffset,j+yoffset,k+zoffset)+betaz(i,j,k))
+ if (flux_direction == 1) then
+ avg_beta = avg_betax
+ else if (flux_direction == 2) then
+ avg_beta = avg_betay
+ else if (flux_direction == 3) then
+ avg_beta = avg_betaz
+ else
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+ end if
+ else
+ avg_beta = 0.d0
+ avg_betax = 0.d0
+ avg_betay = 0.d0
+ avg_betaz = 0.d0
+ end if
+
+ avg_alp = 0.5 * (alp(i,j,k) + alp(i+xoffset,j+yoffset,k+zoffset))
+
+ gxxh = 0.5d0 * (gxx(i+xoffset,j+yoffset,k+zoffset) + &
+ gxx(i,j,k))
+ gxyh = 0.5d0 * (gxy(i+xoffset,j+yoffset,k+zoffset) + &
+ gxy(i,j,k))
+ gxzh = 0.5d0 * (gxz(i+xoffset,j+yoffset,k+zoffset) + &
+ gxz(i,j,k))
+ gyyh = 0.5d0 * (gyy(i+xoffset,j+yoffset,k+zoffset) + &
+ gyy(i,j,k))
+ gyzh = 0.5d0 * (gyz(i+xoffset,j+yoffset,k+zoffset) + &
+ gyz(i,j,k))
+ gzzh = 0.5d0 * (gzz(i+xoffset,j+yoffset,k+zoffset) + &
+ gzz(i,j,k))
+
+ avg_det = SPATIAL_DETERMINANT(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh)
+
+ vxtp = prim_p(2)-avg_betax/avg_alp
+ vytp = prim_p(3)-avg_betay/avg_alp
+ vztp = prim_p(4)-avg_betaz/avg_alp
+ vxtm = prim_m(2)-avg_betax/avg_alp
+ vytm = prim_m(3)-avg_betay/avg_alp
+ vztm = prim_m(4)-avg_betaz/avg_alp
+
+ call calc_vlow_blow(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh, &
+ prim_p(2),prim_p(3),prim_p(4),cons_p(6),cons_p(7),cons_p(8), &
+ velxlowp,velylowp,velzlowp,Bvecxlowp,Bvecylowp,Bveczlowp, &
+ bdotvp,b2p,v2p,wp,bxlowp,bylowp,bzlowp)
+ call calc_vlow_blow(gxxh,gxyh,gxzh,gyyh,gyzh,gzzh, &
+ prim_m(2),prim_m(3),prim_m(4),cons_m(6),cons_m(7),cons_m(8), &
+ velxlowm,velylowm,velzlowm,Bvecxlowm,Bvecylowm,Bveczlowm, &
+ bdotvm,b2m,v2m,wm,bxlowm,bylowm,bzlowm)
+
+ ab0p = wp*bdotvp
+ ab0m = wm*bdotvm
+
+ vA2p = b2p/(rhoenth_p+b2p)
+ vA2m = b2m/(rhoenth_m+b2m)
+
+!!$ p^* = p+b^2/2 in Anton et al.
+ pressstarp = prim_p(6)+0.5d0*b2p
+ pressstarm = prim_m(6)+0.5d0*b2m
+
+ if (flux_direction == 1) then
+
+ call num_x_fluxM(cons_p(1),cons_p(2),cons_p(3),cons_p(4),cons_p(5),&
+ cons_p(6),cons_p(7),cons_p(8),&
+ tmp_flux(1),tmp_flux(2),tmp_flux(3),tmp_flux(4),tmp_flux(5), &
+ tmp_flux(6),tmp_flux(7),tmp_flux(8), &
+ vxtp,vytp,vztp,pressstarp,bxlowp,bylowp,bzlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+
+ densflux(i,j,k) = 0.5d0 * tmp_flux(1)
+ sxflux(i,j,k) = 0.5d0 * tmp_flux(2)
+ syflux(i,j,k) = 0.5d0 * tmp_flux(3)
+ szflux(i,j,k) = 0.5d0 * tmp_flux(4)
+ tauflux(i,j,k) = 0.5d0 * tmp_flux(5)
+ Bvecxflux(i,j,k) = 0.5d0 * tmp_flux(6)
+ Bvecyflux(i,j,k) = 0.5d0 * tmp_flux(7)
+ Bveczflux(i,j,k) = 0.5d0 * tmp_flux(8)
+
+ call num_x_fluxM(cons_m(1),cons_m(2),cons_m(3),cons_m(4),cons_m(5),&
+ cons_m(6),cons_m(7),cons_m(8),&
+ tmp_flux(1),tmp_flux(2),tmp_flux(3),tmp_flux(4),tmp_flux(5),&
+ tmp_flux(6),tmp_flux(7),tmp_flux(8),&
+ vxtm,vytm,vztm,pressstarm,bxlowm,bylowm,bzlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+
+ densflux(i,j,k) = densflux(i,j,k) + 0.5d0 * tmp_flux(1)
+ sxflux(i,j,k) = sxflux(i,j,k) + 0.5d0 * tmp_flux(2)
+ syflux(i,j,k) = syflux(i,j,k) + 0.5d0 * tmp_flux(3)
+ szflux(i,j,k) = szflux(i,j,k) + 0.5d0 * tmp_flux(4)
+ tauflux(i,j,k) = tauflux(i,j,k) + 0.5d0 * tmp_flux(5)
+ Bvecxflux(i,j,k)= Bvecxflux(i,j,k)+ 0.5d0 * tmp_flux(6)
+ Bvecyflux(i,j,k)= Bvecyflux(i,j,k)+ 0.5d0 * tmp_flux(7)
+ Bveczflux(i,j,k)= Bveczflux(i,j,k)+ 0.5d0 * tmp_flux(8)
+
+ else if (flux_direction == 2) then
+
+ call num_x_fluxM(cons_p(1),cons_p(3),cons_p(4),cons_p(2),cons_p(5),&
+ cons_p(7),cons_p(8),cons_p(6),&
+ tmp_flux(1),tmp_flux(3),tmp_flux(4),tmp_flux(2),tmp_flux(5),&
+ tmp_flux(7),tmp_flux(8),tmp_flux(6),&
+ vytp,vztp,vxtp,pressstarp,bylowp,bzlowp,bxlowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+
+ densflux(i,j,k) = 0.5d0 * tmp_flux(1)
+ sxflux(i,j,k) = 0.5d0 * tmp_flux(2)
+ syflux(i,j,k) = 0.5d0 * tmp_flux(3)
+ szflux(i,j,k) = 0.5d0 * tmp_flux(4)
+ tauflux(i,j,k) = 0.5d0 * tmp_flux(5)
+ Bvecxflux(i,j,k)= Bvecxflux(i,j,k)+ 0.5d0 * tmp_flux(6)
+ Bvecyflux(i,j,k)= Bvecyflux(i,j,k)+ 0.5d0 * tmp_flux(7)
+ Bveczflux(i,j,k)= Bveczflux(i,j,k)+ 0.5d0 * tmp_flux(8)
+
+ call num_x_fluxM(cons_m(1),cons_m(3),cons_m(4),cons_m(2),cons_m(5),&
+ cons_m(7),cons_m(8),cons_m(6),&
+ tmp_flux(1),tmp_flux(3),tmp_flux(4),tmp_flux(2),tmp_flux(5),&
+ tmp_flux(7),tmp_flux(8),tmp_flux(6),&
+ vytm,vztm,vxtm,pressstarm,bylowm,bzlowm,bxlowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+
+ densflux(i,j,k) = densflux(i,j,k) + 0.5d0 * tmp_flux(1)
+ sxflux(i,j,k) = sxflux(i,j,k) + 0.5d0 * tmp_flux(2)
+ syflux(i,j,k) = syflux(i,j,k) + 0.5d0 * tmp_flux(3)
+ szflux(i,j,k) = szflux(i,j,k) + 0.5d0 * tmp_flux(4)
+ tauflux(i,j,k) = tauflux(i,j,k) + 0.5d0 * tmp_flux(5)
+ Bvecxflux(i,j,k)= Bvecxflux(i,j,k)+ 0.5d0 * tmp_flux(6)
+ Bvecyflux(i,j,k)= Bvecyflux(i,j,k)+ 0.5d0 * tmp_flux(7)
+ Bveczflux(i,j,k)= Bveczflux(i,j,k)+ 0.5d0 * tmp_flux(8)
+
+ else if (flux_direction == 3) then
+
+ call num_x_fluxM(cons_p(1),cons_p(4),cons_p(2),cons_p(3),cons_p(5),&
+ cons_p(8),cons_p(6),cons_p(7),&
+ tmp_flux(1),tmp_flux(4),tmp_flux(2),tmp_flux(3),tmp_flux(5),&
+ tmp_flux(8),tmp_flux(6),tmp_flux(7), &
+ vztp,vxtp,vytp,pressstarp,bzlowp,bxlowp,bylowp,ab0p,wp, &
+ avg_det,avg_alp,avg_beta)
+
+ densflux(i,j,k) = 0.5d0 * tmp_flux(1)
+ sxflux(i,j,k) = 0.5d0 * tmp_flux(2)
+ syflux(i,j,k) = 0.5d0 * tmp_flux(3)
+ szflux(i,j,k) = 0.5d0 * tmp_flux(4)
+ tauflux(i,j,k) = 0.5d0 * tmp_flux(5)
+ Bvecxflux(i,j,k)= Bvecxflux(i,j,k)+ 0.5d0 * tmp_flux(6)
+ Bvecyflux(i,j,k)= Bvecyflux(i,j,k)+ 0.5d0 * tmp_flux(7)
+ Bveczflux(i,j,k)= Bveczflux(i,j,k)+ 0.5d0 * tmp_flux(8)
+
+ call num_x_fluxM(cons_m(1),cons_m(4),cons_m(2),cons_m(3),cons_m(5),&
+ cons_m(8),cons_m(6),cons_m(7),&
+ tmp_flux(1),tmp_flux(4),tmp_flux(2),tmp_flux(3),tmp_flux(5), &
+ tmp_flux(8),tmp_flux(6),tmp_flux(7), &
+ vztm,vxtm,vytm,pressstarm,bzlowm,bxlowm,bylowm,ab0m,wm, &
+ avg_det,avg_alp,avg_beta)
+
+ densflux(i,j,k) = densflux(i,j,k) + 0.5d0 * tmp_flux(1)
+ sxflux(i,j,k) = sxflux(i,j,k) + 0.5d0 * tmp_flux(2)
+ syflux(i,j,k) = syflux(i,j,k) + 0.5d0 * tmp_flux(3)
+ szflux(i,j,k) = szflux(i,j,k) + 0.5d0 * tmp_flux(4)
+ tauflux(i,j,k) = tauflux(i,j,k) + 0.5d0 * tmp_flux(5)
+ Bvecxflux(i,j,k)= Bvecxflux(i,j,k)+ 0.5d0 * tmp_flux(6)
+ Bvecyflux(i,j,k)= Bvecyflux(i,j,k)+ 0.5d0 * tmp_flux(7)
+ Bveczflux(i,j,k)= Bveczflux(i,j,k)+ 0.5d0 * tmp_flux(8)
+
+ else
+
+ call CCTK_WARN(0, "Flux direction not x,y,z")
+
+ end if
+
+ end do
+ end do
+ end do
+
+ if (CCTK_EQUALS(riemann_solver,"Roe")) then
+
+ call CCTK_WARN(0, "Roe and Marquina not implemented in MHD yet!!!")
+
+!!$
+!!$ call GRHydro_RoeSolveGeneral(CCTK_PASS_FTOF)
+!!$
+!!$ if (evolve_tracer .ne. 0) then
+!!$
+!!$ call GRHydro_HLLE_TracerGeneral(CCTK_PASS_FTOF)
+!!$
+!!$ end if
+!!$
+ else if (CCTK_EQUALS(riemann_solver,"Marquina")) then
+
+ call CCTK_WARN(0, "Roe and Marquina not implemented in MHD yet!!!")
+
+!!$
+!!$ call GRHydro_MarquinaGeneral(CCTK_PASS_FTOF)
+!!$
+!!$ Tracers are built directly in to the Marquina solver
+
+ end if
+
+ end if
+
+end subroutine RiemannSolveGeneralM
+
+
diff --git a/src/GRHydro_SourceM.F90 b/src/GRHydro_SourceM.F90
new file mode 100644
index 0000000..27f39e4
--- /dev/null
+++ b/src/GRHydro_SourceM.F90
@@ -0,0 +1,436 @@
+ /*@@
+ @file GRHydro_SourceM.F90
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ The geometric source terms for the matter evolution
+ @enddesc
+ @@*/
+
+! Second order f.d.
+
+#define DIFF_X_2(q) 0.5d0 * (q(i+1,j,k) - q(i-1,j,k)) * idx
+#define DIFF_Y_2(q) 0.5d0 * (q(i,j+1,k) - q(i,j-1,k)) * idy
+#define DIFF_Z_2(q) 0.5d0 * (q(i,j,k+1) - q(i,j,k-1)) * idz
+
+! Fourth order f.d.
+
+#define DIFF_X_4(q) (-q(i+2,j,k) + 8.d0 * q(i+1,j,k) - 8.d0 * q(i-1,j,k) + \
+ q(i-2,j,k)) / 12.d0 * idx
+#define DIFF_Y_4(q) (-q(i,j+2,k) + 8.d0 * q(i,j+1,k) - 8.d0 * q(i,j-1,k) + \
+ q(i,j-2,k)) / 12.d0 * idy
+#define DIFF_Z_4(q) (-q(i,j,k+2) + 8.d0 * q(i,j,k+1) - 8.d0 * q(i,j,k-1) + \
+ q(i,j,k-2)) / 12.d0 * idz
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "GRHydro_Macros.h"
+
+#define velx(i,j,k) vel(i,j,k,1)
+#define vely(i,j,k) vel(i,j,k,2)
+#define velz(i,j,k) vel(i,j,k,3)
+#define Bvecx(i,j,k) Bvec(i,j,k,1)
+#define Bvecy(i,j,k) Bvec(i,j,k,2)
+#define Bvecz(i,j,k) Bvec(i,j,k,3)
+
+ /*@@
+ @routine SourceTermsM
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ Calculate the geometric source terms and add to the update GFs
+ @enddesc
+ @calls
+ @calledby
+ @history
+ Minor alterations of routine from GR3D.
+ @endhistory
+
+@@*/
+
+subroutine SourceTermsM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_INT :: i, j, k, nx, ny, nz
+ CCTK_REAL :: one, two, half
+ CCTK_REAL :: t00, t0x, t0y, t0z, txx, txy, txz, tyy, tyz, tzz
+ CCTK_REAL :: sqrtdet, det, uxx, uxy, uxz, uyy, uyz, uzz
+ CCTK_REAL :: shiftx, shifty, shiftz, velxshift, velyshift, velzshift
+ CCTK_REAL :: vlowx, vlowy, vlowz
+ CCTK_REAL :: dx_betax, dx_betay, dx_betaz, dy_betax, dy_betay,&
+ dy_betaz, dz_betax, dz_betay, dz_betaz
+ CCTK_REAL :: dx_alp, dy_alp, dz_alp
+ CCTK_REAL :: tau_source, sx_source, sy_source, sz_source
+ CCTK_REAL :: localgxx,localgxy,localgxz,localgyy,localgyz,localgzz
+ CCTK_REAL :: dx_gxx, dx_gxy, dx_gxz, dx_gyy, dx_gyz, dx_gzz
+ CCTK_REAL :: dy_gxx, dy_gxy, dy_gxz, dy_gyy, dy_gyz, dy_gzz
+ CCTK_REAL :: dz_gxx, dz_gxy, dz_gxz, dz_gyy, dz_gyz, dz_gzz
+ CCTK_REAL :: dx, dy, dz, idx, idy, idz
+ CCTK_REAL :: shiftshiftk, shiftkx, shiftky, shiftkz
+ CCTK_REAL :: sumTK
+ CCTK_REAL :: halfshiftdgx, halfshiftdgy, halfshiftdgz
+ CCTK_REAL :: halfTdgx, halfTdgy, halfTdgz
+ CCTK_REAL :: invalp, invalp2
+
+ CCTK_REAL :: Bvecxlow,Bvecylow,Bveczlow,bdotv,b2,dum,bxlow,bylow,bzlow
+ CCTK_REAL :: bt,bx,by,bz,rhohstarW2,pstar
+
+ logical, allocatable, dimension (:,:,:) :: force_spatial_second_order
+
+ one = 1.0d0
+ two = 2.0d0
+ half = 0.5d0
+ nx = cctk_lsh(1)
+ ny = cctk_lsh(2)
+ nz = cctk_lsh(3)
+ dx = CCTK_DELTA_SPACE(1)
+ dy = CCTK_DELTA_SPACE(2)
+ dz = CCTK_DELTA_SPACE(3)
+ idx = 1.d0/dx
+ idy = 1.d0/dy
+ idz = 1.d0/dz
+
+!!$ Initialize the update terms to be zero.
+!!$ This will guarantee that no garbage in the boundaries is updated.
+
+ densrhs = 0.d0
+ srhs = 0.d0
+ taurhs = 0.d0
+
+ if (evolve_tracer .ne. 0) then
+
+ cons_tracerrhs = 0.d0
+
+ end if
+
+!!$ Set up the array for checking the order. We switch to second order
+!!$ differencing at boundaries and near excision regions.
+!!$ Copied straight from BSSN.
+
+ allocate (force_spatial_second_order(nx,ny,nz))
+ force_spatial_second_order = .FALSE.
+
+ if (spatial_order > 2) then
+ !$OMP PARALLEL DO PRIVATE(i, j)
+ do k = 1 + GRHydro_stencil, nz - GRHydro_stencil
+ do j = 1 + GRHydro_stencil, ny - GRHydro_stencil
+ do i = 1 + GRHydro_stencil, nx - GRHydro_stencil
+ if ((i < 3).or.(i > cctk_lsh(1) - 2).or. &
+ (j < 3).or.(j > cctk_lsh(2) - 2).or. &
+ (k < 3).or.(k > cctk_lsh(3) - 2) ) then
+ force_spatial_second_order(i,j,k) = .TRUE.
+ else if ( use_mask > 0 ) then
+ if (minval(emask(i-2:i+2,j-2:j+2,k-2:k+2)) < 0.75d0) then
+ force_spatial_second_order(i,j,k) = .TRUE.
+ end if
+ end if
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+ end if
+
+ !$OMP PARALLEL DO PRIVATE(i, j, local_spatial_order,&
+ !$OMP localgxx,localgxy,localgxz,localgyy,localgyz,localgzz,&
+ !$OMP det,sqrtdet,shiftx,shifty,shiftz,&
+ !$OMP dx_betax,dx_betay,dx_betaz,dy_betax,dy_betay,dy_betaz,&
+ !$OMP dz_betax,dz_betay,dz_betaz,velxshift,velyshift,velzshift,&
+ !$OMP vlowx,vlowy,vlowz,Bvecxlow,Bvecylow,Bveczlow, &
+ !$OMP bdotv,b2,dum,bxlow,bylow,bzlow,bt,bx,by,bz,rhohstarW2,pstar,&
+ !$OMP t00,t0x,t0y,t0z,txx,txy,txz,tyy,tyz,tzz,&
+ !$OMP dx_alp,dy_alp,dz_alp,tau_source,sx_source,sy_source,sz_source,&
+ !$OMP uxx, uxy, uxz, uyy, uyz, uzz,&
+ !$OMP dx_gxx, dx_gxy, dx_gxz, dx_gyy, dx_gyz, dx_gzz,&
+ !$OMP dy_gxx, dy_gxy, dy_gxz, dy_gyy, dy_gyz, dy_gzz,&
+ !$OMP dz_gxx, dz_gxy, dz_gxz, dz_gyy, dz_gyz, dz_gzz,&
+ !$OMP shiftshiftk,shiftkx,shiftky,shiftkz,&
+ !$OMP sumTK,halfshiftdgx,halfshiftdgy,halfshiftdgz,&
+ !$OMP halfTdgx,halfTdgy,halfTdgz,invalp,invalp2)
+ do k=1 + GRHydro_stencil,nz - GRHydro_stencil
+ do j=1 + GRHydro_stencil,ny - GRHydro_stencil
+ do i=1 + GRHydro_stencil,nx - GRHydro_stencil
+
+ local_spatial_order = spatial_order
+ if (force_spatial_second_order(i,j,k)) then
+ local_spatial_order = 2
+ end if
+
+!!$ Set the metric terms.
+
+ localgxx = gxx(i,j,k)
+ localgxy = gxy(i,j,k)
+ localgxz = gxz(i,j,k)
+ localgyy = gyy(i,j,k)
+ localgyz = gyz(i,j,k)
+ localgzz = gzz(i,j,k)
+
+ det = SPATIAL_DETERMINANT(localgxx, localgxy, localgxz,\
+ localgyy, localgyz, localgzz)
+ sqrtdet = sqrt(det)
+ call UpperMetric(uxx, uxy, uxz, uyy, uyz, uzz, det, localgxx,&
+ localgxy, localgxz, localgyy, localgyz, localgzz)
+
+
+ if (shift_state .ne. 0) then
+
+ shiftx = betax(i,j,k)
+ shifty = betay(i,j,k)
+ shiftz = betaz(i,j,k)
+
+ if (local_spatial_order .eq. 2) then
+
+ dx_betax = DIFF_X_2(betax)
+ dx_betay = DIFF_X_2(betay)
+ dx_betaz = DIFF_X_2(betaz)
+
+ dy_betax = DIFF_Y_2(betax)
+ dy_betay = DIFF_Y_2(betay)
+ dy_betaz = DIFF_Y_2(betaz)
+
+ dz_betax = DIFF_Z_2(betax)
+ dz_betay = DIFF_Z_2(betay)
+ dz_betaz = DIFF_Z_2(betaz)
+
+ else
+
+ dx_betax = DIFF_X_4(betax)
+ dx_betay = DIFF_X_4(betay)
+ dx_betaz = DIFF_X_4(betaz)
+
+ dy_betax = DIFF_Y_4(betax)
+ dy_betay = DIFF_Y_4(betay)
+ dy_betaz = DIFF_Y_4(betaz)
+
+ dz_betax = DIFF_Z_4(betax)
+ dz_betay = DIFF_Z_4(betay)
+ dz_betaz = DIFF_Z_4(betaz)
+
+ end if
+
+ else
+
+ shiftx = 0.0d0
+ shifty = 0.0d0
+ shiftz = 0.0d0
+
+ dx_betax = 0.0d0
+ dx_betay = 0.0d0
+ dx_betaz = 0.0d0
+
+ dy_betax = 0.0d0
+ dy_betay = 0.0d0
+ dy_betaz = 0.0d0
+
+ dz_betax = 0.0d0
+ dz_betay = 0.0d0
+ dz_betaz = 0.0d0
+
+ endif
+
+ invalp = 1.0d0 / alp(i,j,k)
+ invalp2 = invalp**2
+ velxshift = velx(i,j,k) - shiftx*invalp
+ velyshift = vely(i,j,k) - shifty*invalp
+ velzshift = velz(i,j,k) - shiftz*invalp
+
+ call calc_vlow_blow(localgxx,localgxy,localgxz,localgyy,localgyz,localgzz, &
+ velx(i,j,k),vely(i,j,k),velz(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k), &
+ vlowx,vlowy,vlowz,Bvecxlow,Bvecylow,Bveczlow, &
+ bdotv,b2,dum,dum,bxlow,bylow,bzlow)
+
+!!$ These are the contravariant components
+ bt = w_lorentz(i,j,k)/alp(i,j,k)*bdotv
+ bx = Bvecx(i,j,k)/w_lorentz(i,j,k)+w_lorentz(i,j,k)*bdotv*velxshift
+ by = Bvecy(i,j,k)/w_lorentz(i,j,k)+w_lorentz(i,j,k)*bdotv*velyshift
+ bz = Bvecz(i,j,k)/w_lorentz(i,j,k)+w_lorentz(i,j,k)*bdotv*velzshift
+
+ rhohstarW2 = (rho(i,j,k)*(one + eps(i,j,k)) + press(i,j,k)+ b2)*&
+ w_lorentz(i,j,k)**2
+ pstar = press(i,j,k)+b2/2.d0
+
+!!$ For a change, these are T^{ij}
+
+ t00 = (rhohstarW2 - pstar)*invalp2-bt**2
+ t0x = rhohstarW2*velxshift*invalp +&
+ pstar*shiftx*invalp2-bt*bx
+ t0y = rhohstarW2*velyshift*invalp +&
+ pstar*shifty*invalp2-bt*by
+ t0z = rhohstarW2*velzshift*invalp +&
+ pstar*shiftz*invalp2-bt*bz
+ txx = rhohstarW2*velxshift*velxshift +&
+ pstar*(uxx - shiftx*shiftx*invalp2)-bx**2
+ txy = rhohstarW2*velxshift*velyshift +&
+ pstar*(uxy - shiftx*shifty*invalp2)-bx*by
+ txz = rhohstarW2*velxshift*velzshift +&
+ pstar*(uxz - shiftx*shiftz*invalp2)-bx*bz
+ tyy = rhohstarW2*velyshift*velyshift +&
+ pstar*(uyy - shifty*shifty*invalp2)-by**2
+ tyz = rhohstarW2*velyshift*velzshift +&
+ pstar*(uyz - shifty*shiftz*invalp2)-by*bz
+ tzz = rhohstarW2*velzshift*velzshift +&
+ pstar*(uzz - shiftz*shiftz*invalp2)-bz**2
+
+!!$ Derivatives of the lapse, metric and shift
+
+ if (local_spatial_order .eq. 2) then
+
+ dx_alp = DIFF_X_2(alp)
+ dy_alp = DIFF_Y_2(alp)
+ dz_alp = DIFF_Z_2(alp)
+
+ else
+
+ dx_alp = DIFF_X_4(alp)
+ dy_alp = DIFF_Y_4(alp)
+ dz_alp = DIFF_Z_4(alp)
+
+ end if
+
+ if (local_spatial_order .eq. 2) then
+
+ dx_gxx = DIFF_X_2(gxx)
+ dx_gxy = DIFF_X_2(gxy)
+ dx_gxz = DIFF_X_2(gxz)
+ dx_gyy = DIFF_X_2(gyy)
+ dx_gyz = DIFF_X_2(gyz)
+ dx_gzz = DIFF_X_2(gzz)
+ dy_gxx = DIFF_Y_2(gxx)
+ dy_gxy = DIFF_Y_2(gxy)
+ dy_gxz = DIFF_Y_2(gxz)
+ dy_gyy = DIFF_Y_2(gyy)
+ dy_gyz = DIFF_Y_2(gyz)
+ dy_gzz = DIFF_Y_2(gzz)
+ dz_gxx = DIFF_Z_2(gxx)
+ dz_gxy = DIFF_Z_2(gxy)
+ dz_gxz = DIFF_Z_2(gxz)
+ dz_gyy = DIFF_Z_2(gyy)
+ dz_gyz = DIFF_Z_2(gyz)
+ dz_gzz = DIFF_Z_2(gzz)
+
+ else
+
+ dx_gxx = DIFF_X_4(gxx)
+ dx_gxy = DIFF_X_4(gxy)
+ dx_gxz = DIFF_X_4(gxz)
+ dx_gyy = DIFF_X_4(gyy)
+ dx_gyz = DIFF_X_4(gyz)
+ dx_gzz = DIFF_X_4(gzz)
+ dy_gxx = DIFF_Y_4(gxx)
+ dy_gxy = DIFF_Y_4(gxy)
+ dy_gxz = DIFF_Y_4(gxz)
+ dy_gyy = DIFF_Y_4(gyy)
+ dy_gyz = DIFF_Y_4(gyz)
+ dy_gzz = DIFF_Y_4(gzz)
+ dz_gxx = DIFF_Z_4(gxx)
+ dz_gxy = DIFF_Z_4(gxy)
+ dz_gxz = DIFF_Z_4(gxz)
+ dz_gyy = DIFF_Z_4(gyy)
+ dz_gyz = DIFF_Z_4(gyz)
+ dz_gzz = DIFF_Z_4(gzz)
+
+ end if
+
+!!$ Contract the shift with the extrinsic curvature
+
+ shiftshiftk = shiftx*shiftx*kxx(i,j,k) + &
+ shifty*shifty*kyy(i,j,k) + &
+ shiftz*shiftz*kzz(i,j,k) + &
+ two*(shiftx*shifty*kxy(i,j,k) + &
+ shiftx*shiftz*kxz(i,j,k) + &
+ shifty*shiftz*kyz(i,j,k))
+
+ shiftkx = shiftx*kxx(i,j,k) + shifty*kxy(i,j,k) + shiftz*kxz(i,j,k)
+ shiftky = shiftx*kxy(i,j,k) + shifty*kyy(i,j,k) + shiftz*kyz(i,j,k)
+ shiftkz = shiftx*kxz(i,j,k) + shifty*kyz(i,j,k) + shiftz*kzz(i,j,k)
+
+!!$ Contract the matter terms with the extrinsic curvature
+
+ sumTK = txx*kxx(i,j,k) + tyy*kyy(i,j,k) + tzz*kzz(i,j,k) &
+ + two*(txy*kxy(i,j,k) + txz*kxz(i,j,k) + tyz*kyz(i,j,k))
+
+!!$ Update term for tau
+
+ tau_source = t00* &
+ (shiftshiftk - (shiftx*dx_alp + shifty*dy_alp + shiftz*dz_alp) )&
+ + t0x*(-dx_alp + two*shiftkx) &
+ + t0y*(-dy_alp + two*shiftky) &
+ + t0z*(-dz_alp + two*shiftkz) &
+ + sumTK
+
+!!$ The following looks very little like the terms in the
+!!$ standard papers. Take a look in the ThornGuide to see why
+!!$ it is really the same thing.
+
+!!$ Contract the shift with derivatives of the metric
+
+ halfshiftdgx = half*(shiftx*shiftx*dx_gxx + &
+ shifty*shifty*dx_gyy + shiftz*shiftz*dx_gzz) + &
+ shiftx*shifty*dx_gxy + shiftx*shiftz*dx_gxz + &
+ shifty*shiftz*dx_gyz
+ halfshiftdgy = half*(shiftx*shiftx*dy_gxx + &
+ shifty*shifty*dy_gyy + shiftz*shiftz*dy_gzz) + &
+ shiftx*shifty*dy_gxy + shiftx*shiftz*dy_gxz + &
+ shifty*shiftz*dy_gyz
+ halfshiftdgz = half*(shiftx*shiftx*dz_gxx + &
+ shifty*shifty*dz_gyy + shiftz*shiftz*dz_gzz) + &
+ shiftx*shifty*dz_gxy + shiftx*shiftz*dz_gxz + &
+ shifty*shiftz*dz_gyz
+
+!!$ Contract the matter with derivatives of the metric
+
+ halfTdgx = half*(txx*dx_gxx + tyy*dx_gyy + tzz*dx_gzz) +&
+ txy*dx_gxy + txz*dx_gxz + tyz*dx_gyz
+ halfTdgy = half*(txx*dy_gxx + tyy*dy_gyy + tzz*dy_gzz) +&
+ txy*dy_gxy + txz*dy_gxz + tyz*dy_gyz
+ halfTdgz = half*(txx*dz_gxx + tyy*dz_gyy + tzz*dz_gzz) +&
+ txy*dz_gxy + txz*dz_gxz + tyz*dz_gyz
+
+ sx_source = t00*&
+ (halfshiftdgx - alp(i,j,k)*dx_alp) + halfTdgx + &
+ t0x*(shiftx*dx_gxx + shifty*dx_gxy + shiftz*dx_gxz) +&
+ t0y*(shiftx*dx_gxy + shifty*dx_gyy + shiftz*dx_gyz) +&
+ t0z*(shiftx*dx_gxz + shifty*dx_gyz + shiftz*dx_gzz) +&
+ rhohstarW2*invalp*(vlowx*dx_betax + vlowy*dx_betay + vlowz*dx_betaz) -&
+ bt*(bxlow*dx_betax + bylow*dx_betay + bzlow*dx_betaz)
+
+ sy_source = t00*&
+ (halfshiftdgy - alp(i,j,k)*dy_alp) + halfTdgy + &
+ t0x*(shiftx*dy_gxx + shifty*dy_gxy + shiftz*dy_gxz) +&
+ t0y*(shiftx*dy_gxy + shifty*dy_gyy + shiftz*dy_gyz) +&
+ t0z*(shiftx*dy_gxz + shifty*dy_gyz + shiftz*dy_gzz) +&
+ rhohstarW2*invalp*(vlowx*dy_betax + vlowy*dy_betay + vlowz*dy_betaz) -&
+ bt*(bxlow*dy_betax + bylow*dy_betay + bzlow*dy_betaz)
+
+ sz_source = t00*&
+ (halfshiftdgz - alp(i,j,k)*dz_alp) + halfTdgy + &
+ t0x*(shiftx*dz_gxx + shifty*dz_gxy + shiftz*dz_gxz) +&
+ t0y*(shiftx*dz_gxy + shifty*dz_gyy + shiftz*dz_gyz) +&
+ t0z*(shiftx*dz_gxz + shifty*dz_gyz + shiftz*dz_gzz) +&
+ rhohstarW2*invalp*(vlowx*dz_betax + vlowy*dz_betay + vlowz*dz_betaz) -&
+ bt*(bxlow*dz_betax + bylow*dz_betay + bzlow*dz_betaz)
+
+ densrhs(i,j,k) = 0.d0
+ srhs(i,j,k,1) = alp(i,j,k)*sqrtdet*sx_source
+ srhs(i,j,k,2) = alp(i,j,k)*sqrtdet*sy_source
+ srhs(i,j,k,3) = alp(i,j,k)*sqrtdet*sz_source
+ taurhs(i,j,k) = alp(i,j,k)*sqrtdet*tau_source
+ Bvecrhs(i,j,k,1) = 0.d0
+ Bvecrhs(i,j,k,2) = 0.d0
+ Bvecrhs(i,j,k,3) = 0.d0
+
+ enddo
+ enddo
+ enddo
+ !$OMP END PARALLEL DO
+
+ deallocate(force_spatial_second_order)
+
+end subroutine SourceTermsM
+
+
+
diff --git a/src/GRHydro_TmunuM.F90 b/src/GRHydro_TmunuM.F90
new file mode 100644
index 0000000..5464e45
--- /dev/null
+++ b/src/GRHydro_TmunuM.F90
@@ -0,0 +1,166 @@
+ /*@@
+ @file GRHydro_Tmunu.F90
+ @date Aug 30, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @histpry
+ Apr. 2009: Luca Baiotti copied and adapted for the Tmunu-thorn mechanism the original include file
+ @desc
+ The calculation of the stress energy tensor.
+ The version used here was worked out by Miguel Alcubierre. I
+ think it was an extension of the routine from GR3D, written
+ by Mark Miller.
+ C version added by Ian Hawke.
+
+ Lower components of the stress-energy tensor obtained from
+ the hydro variables. The components are given by:
+
+ T = (rho h +b^2) u u + (P+b^2/2) g - b b
+ mu nu mu nu mu nu mu nu
+
+ where rho is the energy density of the fluid, h the enthalpy
+ and P the pressure. The enthalpy is given in terms of the
+ basic variables as:
+
+ h = 1 + e + P/rho
+
+ with e the internal energy (eps here).
+
+ In the expresion for T_{mu,nu} we also have the four-velocity
+ of the fluid given by (v_i is the 3-velocity field):
+
+ i
+ u = W ( - alpha + v beta )
+ 0 i
+
+ u = W v
+ i i
+ i -1/2
+ with W the Lorentz factor: W = ( 1 - v v )
+ i
+
+ and where alpha and beta are the lapse and shift vector.
+
+ Finally, the 4 metric is given by
+
+ 2 i
+ g = - alpha + beta beta
+ 00 i
+
+ g = beta
+ 0i i
+
+
+ g = gamma (the spatial metric)
+ ij ij
+
+
+ @enddesc
+ @@*/
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "SpaceMask.h"
+
+#define velx(i,j,k) vel(i,j,k,1)
+#define vely(i,j,k) vel(i,j,k,2)
+#define velz(i,j,k) vel(i,j,k,3)
+#define Bvecx(i,j,k) Bvec(i,j,k,1)
+#define Bvecy(i,j,k) Bvec(i,j,k,2)
+#define Bvecz(i,j,k) Bvec(i,j,k,3)
+
+ subroutine GRHydro_TmunuM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+
+ CCTK_REAL velxlow, velylow, velzlow
+ CCTK_REAL betaxlow, betaylow, betazlow, beta2
+ CCTK_REAL Bvecxlow,Bvecylow,Bveczlow
+ CCTK_REAL bdotv,b2,bxlow,bylow,bzlow,btlow,dum
+ CCTK_REAL utlow,rhohstarw2,pstar
+ CCTK_REAL bdotbeta,vdotbeta
+ CCTK_INT i,j,k
+
+
+ !$OMP PARALLEL DO PRIVATE(i,j,velxlow, velylow, velzlow,&
+ !$OMP betaxlow, betaylow, betazlow, beta2, bdotbeta,vdotbeta,utlow, btlow,&
+ !$OMP rhohstarw2,pstar)
+
+ do k = 1, cctk_lsh(3)
+ do j = 1, cctk_lsh(2)
+ do i = 1, cctk_lsh(1)
+
+ call calc_vlow_blow(gxx(i,j,k),gxy(i,j,k),gxz(i,j,k),&
+ gyy(i,j,k),gyz(i,j,k),gzz(i,j,k), &
+ velx(i,j,k),vely(i,j,k),velz(i,j,k),Bvecx(i,j,k),Bvecy(i,j,k),Bvecz(i,j,k), &
+ velxlow,velylow,velzlow,Bvecxlow,Bvecylow,Bveczlow, &
+ bdotv,dum,dum,b2,bxlow,bylow,bzlow)
+
+!!$ Calculate lower components and square of shift vector.
+
+ if (shift_state .ne. 0) then
+
+ betaxlow = gxx(i,j,k)*betax(i,j,k) + gxy(i,j,k)*betay(i,j,k) + gxz(i,j,k)*betaz(i,j,k)
+ betaylow = gxy(i,j,k)*betax(i,j,k) + gyy(i,j,k)*betay(i,j,k) + gyz(i,j,k)*betaz(i,j,k)
+ betazlow = gxz(i,j,k)*betax(i,j,k) + gyz(i,j,k)*betay(i,j,k) + gzz(i,j,k)*betaz(i,j,k)
+ beta2 = betax(i,j,k)*betaxlow + betay(i,j,k)*betaylow + betaz(i,j,k)*betazlow
+
+ bdotbeta = betaxlow*Bvecx(i,j,k)+betaylow*Bvecy(i,j,k)+betazlow*Bvecz(i,j,k)
+ vdotbeta = betaxlow*velx(i,j,k)+betaylow*vely(i,j,k)+betazlow*velz(i,j,k)
+
+!!$ u0 low is missing the w_lorentz factor (see below)!!
+ utlow = -1.d0*alp(i,j,k) + vdotbeta
+
+ btlow = -1.0d0*w_lorentz(i,j,k)*alp(i,j,k)*bdotv + &
+ bdotbeta/w_lorentz(i,j,k) + w_lorentz(i,j,k)*bdotv*vdotbeta
+
+
+ else
+
+ betaxlow = 0.0D0
+ betaylow = 0.0D0
+ betazlow = 0.0D0
+ beta2 = 0.0D0
+
+!!$ u0 low is missing the w_lorentz factor (see below)!!
+ utlow = -1.0*alp(i,j,k)
+ btlow = utlow*w_lorentz(i,j,k)*bdotv
+
+ end if
+
+!!$ Calculate the specific relativistic enthalpy times rho + the mag. field contribution times the
+!!$ square of the lorentz factor.
+
+ rhohstarw2 = w_lorentz(i,j,k)**2*(rho(i,j,k)*(1.0D0 + eps(i,j,k)) + press(i,j,k) + b2)
+ pstar = press(i,j,k)+b2/2.d0
+
+!!$ Calculate lower components of 4-velocity (without the Lorent factor).
+!!$ uxlow = velxlow
+!!$ uylow = velylow
+!!$ uzlow = velzlow
+
+!!$ Calculate Tmunu (the lower components!).
+
+ eTtt(i,j,k) = eTtt(i,j,k) + rhohstarw2*utlow**2 + pstar*(beta2 - alp(i,j,k)**2) - btlow**2
+
+ eTtx(i,j,k) = eTtx(i,j,k) + rhohstarw2*utlow*velxlow + pstar*betaxlow - btlow*bxlow
+ eTty(i,j,k) = eTty(i,j,k) + rhohstarw2*utlow*velylow + pstar*betaylow - btlow*bylow
+ eTtz(i,j,k) = eTtz(i,j,k) + rhohstarw2*utlow*velzlow + pstar*betazlow - btlow*bzlow
+
+ eTxx(i,j,k) = eTxx(i,j,k) + rhohstarw2*velxlow**2 + pstar*gxx(i,j,k) - bxlow**2
+ eTyy(i,j,k) = eTyy(i,j,k) + rhohstarw2*velylow**2 + pstar*gyy(i,j,k) - bylow**2
+ eTzz(i,j,k) = eTzz(i,j,k) + rhohstarw2*velzlow**2 + pstar*gzz(i,j,k) - bzlow**2
+
+ eTxy(i,j,k) = eTxy(i,j,k) + rhohstarw2*velxlow*velylow + pstar*gxy(i,j,k) - bxlow*bylow
+ eTxz(i,j,k) = eTxz(i,j,k) + rhohstarw2*velxlow*velzlow + pstar*gxz(i,j,k) - bxlow*bzlow
+ eTyz(i,j,k) = eTyz(i,j,k) + rhohstarw2*velylow*velzlow + pstar*gyz(i,j,k) - bylow*bzlow
+
+ end do
+ end do
+ end do
+ !$OMP END PARALLEL DO
+
+ return
+
+ end subroutine GRHydro_TmunuM
diff --git a/src/GRHydro_UpdateMaskM.F90 b/src/GRHydro_UpdateMaskM.F90
new file mode 100644
index 0000000..5e46380
--- /dev/null
+++ b/src/GRHydro_UpdateMaskM.F90
@@ -0,0 +1,227 @@
+ /*@@
+ @file GRHydro_UpdateMaskM.F90
+ @date Sep 2, 2010
+ @author
+ @desc
+ Alter the update terms if inside the atmosphere or excision region
+ @enddesc
+ @@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+#include "GRHydro_Macros.h"
+#include "SpaceMask.h"
+
+!!$ We don't need to adapt GRHydroUpdateAtmosphereMask, GRHydro_SetupMask, or
+!!$ since we need to evolve Bvec in the atmosphere
+
+!!$ In GRHydro_AtmosphereResetM, we just need to switch the P2C calls to MHD
+
+ /*@@
+ @routine GRHydro_AtmosphereResetM
+ @date Sep 2, 2010
+ @author Joshua Faber, Scott Noble, Bruno Mundim, Ian Hawke
+ @desc
+ After MoL has evolved, if a point is supposed to be reset then do so.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+subroutine GRHydro_AtmosphereResetM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_INT :: i, j, k
+ CCTK_REAL :: det, psi4pt
+
+ CCTK_INT :: type_bits, atmosphere, not_atmosphere
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere",&
+ "in_atmosphere")
+ call SpaceMask_GetStateBits(not_atmosphere, "Hydro_Atmosphere",&
+ "not_in_atmosphere")
+
+ do k = 1, cctk_lsh(3)
+ do j = 1, cctk_lsh(2)
+ do i = 1, cctk_lsh(1)
+
+ if ( (atmosphere_mask(i, j, k) .eq. 1) &
+ &.or. (SpaceMask_CheckStateBitsF90(space_mask,i, j, k, type_bits,\
+ atmosphere)) &
+ &) then
+
+!!$ write(*,*) 'Resetting at ',i,j,k, atmosphere_mask(i, j, k), &
+!!$ & (SpaceMask_CheckStateBitsF90(space_mask,i, j, k, type_bits,\
+!!$ atmosphere))
+
+ rho(i,j,k) = GRHydro_rho_min
+ vel(i,j,k,1) = 0.0d0
+ vel(i,j,k,2) = 0.0d0
+ vel(i,j,k,3) = 0.0d0
+ det = SPATIAL_DETERMINANT(gxx(i,j,k), gxy(i,j,k), gxz(i,j,k), \
+ gyy(i,j,k), gyz(i,j,k), gzz(i,j,k))
+ call prim2conpolytypeM(GRHydro_polytrope_handle, &
+ gxx(i,j,k), gxy(i,j,k), gxz(i,j,k), &
+ gyy(i,j,k), gyz(i,j,k), gzz(i,j,k), det, &
+ dens(i,j,k), scon(i,j,k,1), scon(i,j,k,2), scon(i,j,k,3), &
+ tau(i,j,k), Bvec(i,j,k,1),Bvec(i,j,k,2),Bvec(i,j,k,3),&
+ rho(i,j,k), vel(i,j,k,1), vel(i,j,k,2), &
+ vel(i,j,k,3), eps(i,j,k), press(i,j,k), w_lorentz(i,j,k))
+ if (wk_atmosphere .eq. 0) then
+ atmosphere_mask(i, j, k) = 0
+ SpaceMask_SetStateBitsF90(space_mask, i, j, k, type_bits,\
+ not_atmosphere)
+ end if
+
+ end if
+
+ end do
+ end do
+ end do
+
+!!$ call GRHydro_BoundariesM(CCTK_PASS_FTOF)
+
+end subroutine GRHydro_AtmosphereResetM
+
+subroutine GRHydro_InitialAtmosphereResetM(CCTK_ARGUMENTS)
+
+ implicit none
+
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ CCTK_INT :: i, j, k
+ CCTK_REAL :: det, psi4pt
+
+ CCTK_INT :: type_bits, atmosphere, not_atmosphere
+ CCTK_INT :: eos_handle
+
+#if !USE_EOS_OMNI
+#ifdef _EOS_BASE_INC_
+#undef _EOS_BASE_INC_
+#endif
+#include "EOS_Base.inc"
+#endif
+
+#if USE_EOS_OMNI
+! begin EOS Omni vars
+ integer :: n = 1
+ integer :: keytemp = 0
+ integer :: anyerr = 0
+ integer :: keyerr(1) = 0
+ real*8 :: xpress = 0.0d0
+ real*8 :: xeps = 0.0d0
+ real*8 :: xtemp = 0.0d0
+ real*8 :: xye = 0.0d0
+! end EOS Omni vars
+#endif
+
+ eos_handle = GRHydro_polytrope_handle
+
+ call SpaceMask_GetTypeBits(type_bits, "Hydro_Atmosphere")
+ call SpaceMask_GetStateBits(atmosphere, "Hydro_Atmosphere",&
+ "in_atmosphere")
+ call SpaceMask_GetStateBits(not_atmosphere, "Hydro_Atmosphere",&
+ "not_in_atmosphere")
+
+ do k = 1, cctk_lsh(3)
+ do j = 1, cctk_lsh(2)
+ do i = 1, cctk_lsh(1)
+
+ if (rho(i,j,k) .le. GRHydro_rho_min) then
+ rho(i,j,k) = GRHydro_rho_min
+ vel(i,j,k,1) = 0.0d0
+ vel(i,j,k,2) = 0.0d0
+ vel(i,j,k,3) = 0.0d0
+#if USE_EOS_OMNI
+ call EOS_Omni_press(eos_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho(i,j,k),eps(i,j,k),xtemp,xye,press(i,j,k),keyerr,anyerr)
+ call EOS_Omni_EpsFromPress(eos_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho(i,j,k),xeps,xtemp,xye,press(i,j,k),eps(i,j,k),keyerr,anyerr)
+#else
+ press(i,j,k) = EOS_Pressure(eos_handle, GRHydro_rho_min, eps(i,j,k))
+ eps(i,j,k) = EOS_SpecificIntEnergy(eos_handle, GRHydro_rho_min, press(i,j,k))
+#endif
+ det = SPATIAL_DETERMINANT(gxx(i,j,k), gxy(i,j,k), gxz(i,j,k), \
+ gyy(i,j,k), gyz(i,j,k), gzz(i,j,k))
+ call prim2conpolytypeM(eos_handle, &
+ gxx(i,j,k), gxy(i,j,k), gxz(i,j,k), &
+ gyy(i,j,k), gyz(i,j,k), gzz(i,j,k), det, &
+ dens(i,j,k), scon(i,j,k,1), scon(i,j,k,2), scon(i,j,k,3), &
+ tau(i,j,k), Bvec(i,j,k,1),Bvec(i,j,k,2),Bvec(i,j,k,3),&
+ rho(i,j,k), vel(i,j,k,1), vel(i,j,k,2), &
+ vel(i,j,k,3), eps(i,j,k), press(i,j,k), w_lorentz(i,j,k))
+ end if
+ if (timelevels .gt. 1) then
+ if (rho_p(i,j,k) .le. GRHydro_rho_min) then
+ rho_p(i,j,k) = GRHydro_rho_min
+ vel_p(i,j,k,1) = 0.0d0
+ vel_p(i,j,k,2) = 0.0d0
+ vel_p(i,j,k,3) = 0.0d0
+#if USE_EOS_OMNI
+ call EOS_Omni_press(eos_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho_p(i,j,k),eps_p(i,j,k),xtemp,xye,press_p(i,j,k),keyerr,anyerr)
+ call EOS_Omni_EpsFromPress(eos_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho_p(i,j,k),xeps,xtemp,xye,press_p(i,j,k),eps_p(i,j,k),keyerr,anyerr)
+#else
+ press_p(i,j,k) = EOS_Pressure(eos_handle, GRHydro_rho_min, eps_p(i,j,k))
+ eps_p(i,j,k) = EOS_SpecificIntEnergy(eos_handle, GRHydro_rho_min, press_p(i,j,k))
+#endif
+ det = SPATIAL_DETERMINANT(gxx_p(i,j,k), gxy_p(i,j,k), gxz_p(i,j,k), \
+ gyy_p(i,j,k), gyz_p(i,j,k), gzz_p(i,j,k))
+ call prim2conpolytypeM(eos_handle, &
+ gxx_p(i,j,k), gxy_p(i,j,k), gxz_p(i,j,k), &
+ gyy_p(i,j,k), gyz_p(i,j,k), gzz_p(i,j,k), det, &
+ dens_p(i,j,k), scon_p(i,j,k,1), scon_p(i,j,k,2), scon_p(i,j,k,3), &
+ tau_p(i,j,k), Bvec_p(i,j,k,1),Bvec_p(i,j,k,2),Bvec_p(i,j,k,3),&
+ rho_p(i,j,k), vel_p(i,j,k,1), vel_p(i,j,k,2), &
+ vel_p(i,j,k,3), eps_p(i,j,k), press_p(i,j,k), w_lorentz_p(i,j,k))
+ endif
+ end if
+ if (timelevels .gt. 2) then
+ if (rho_p_p(i,j,k) .le. GRHydro_rho_min) then
+ rho_p_p(i,j,k) = GRHydro_rho_min
+ vel_p_p(i,j,k,1) = 0.0d0
+ vel_p_p(i,j,k,2) = 0.0d0
+ vel_p_p(i,j,k,3) = 0.0d0
+#if USE_EOS_OMNI
+ call EOS_Omni_press(eos_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho_p_p(i,j,k),eps_p_p(i,j,k),xtemp,xye,press_p_p(i,j,k),keyerr,anyerr)
+ call EOS_Omni_EpsFromPress(eos_handle,keytemp,GRHydro_eos_rf_prec,n,&
+ rho_p_p(i,j,k),xeps,xtemp,xye,press_p_p(i,j,k),eps_p_p(i,j,k),keyerr,anyerr)
+#else
+ press_p_p(i,j,k) = EOS_Pressure(eos_handle, GRHydro_rho_min, eps_p_p(i,j,k))
+ eps_p_p(i,j,k) = EOS_SpecificIntEnergy(eos_handle, GRHydro_rho_min, press_p_p(i,j,k))
+#endif
+ det = SPATIAL_DETERMINANT(gxx_p_p(i,j,k), gxy_p_p(i,j,k), gxz_p_p(i,j,k), \
+ gyy_p_p(i,j,k), gyz_p_p(i,j,k), gzz_p_p(i,j,k))
+ call prim2conpolytypeM(eos_handle, &
+ gxx_p_p(i,j,k), gxy_p_p(i,j,k), gxz_p_p(i,j,k), &
+ gyy_p_p(i,j,k), gyz_p_p(i,j,k), gzz_p_p(i,j,k), det, &
+ dens_p_p(i,j,k), scon_p_p(i,j,k,1), scon_p_p(i,j,k,2), scon_p_p(i,j,k,3), &
+ tau_p_p(i,j,k), Bvec_p_p(i,j,k,1),Bvec_p_p(i,j,k,2),Bvec_p_p(i,j,k,3),&
+ rho_p_p(i,j,k), vel_p_p(i,j,k,1), vel_p_p(i,j,k,2), &
+ vel_p_p(i,j,k,3), eps_p_p(i,j,k), press_p_p(i,j,k), w_lorentz_p_p(i,j,k))
+ endif
+ endif
+
+ end do
+ end do
+ end do
+
+ write(*,*) " GRHydro_InitialAtmosphereReset"
+!!$ call GRHydro_BoundariesM(CCTK_PASS_FTOF)
+
+end subroutine GRHydro_InitialAtmosphereResetM
+
diff --git a/src/GRHydro_UtilsM.F90 b/src/GRHydro_UtilsM.F90
new file mode 100644
index 0000000..d3239f8
--- /dev/null
+++ b/src/GRHydro_UtilsM.F90
@@ -0,0 +1,58 @@
+/*@@
+@file UtilsM.F
+@date Aug 30, 2010
+@author Joshua Faber, Scott Noble, Bruno Mundim
+@desc
+Utility functions for other thorns.
+@enddesc
+@@*/
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+
+subroutine calc_vlow_blow(gxx,gxy,gxz,gyy,gyz,gzz, &
+ velx,vely,velz,Bvecx,Bvecy,Bvecz, &
+ velxlow,velylow,velzlow,Bvecxlow,Bvecylow,Bveczlow, &
+ Bdotv,b2,v2,w,bxlow,bylow,bzlow)
+
+!!$ Calculates v_i (see Anton Eq. 5) and B_i (Bvecxlow)- undensitized!
+!!$ calculates B^i v_i [Anton eq. 44] and b^2 [LHS of Anton eq. 46]
+!!$ Calculates w (Lorentz factor) as (1-v^i v_i)^{-1/2}
+!!$ Calculates b_i (bxlow)
+
+ CCTK_REAL :: gxx,gxy,gxz,gyy,gyz,gzz
+ CCTK_REAL :: velx,vely,velz,Bvecx,Bvecy,Bvecz
+ CCTK_REAL :: velxlow,velylow,velzlow
+ CCTK_REAL :: Bvecxlow,Bvecylow,Bveczlow
+ CCTK_REAL :: Bdotv,v2,w,b2,bxlow,bylow,bzlow
+
+!!$ vel_i = g_ij v^j
+!!$ B_i = g_ij B^i
+
+ velxlow = gxx*velx + gxy*vely + gxz*velz
+ velylow = gxy*velx + gyy*vely + gyz*velz
+ velzlow = gxz*velx + gyz*vely + gzz*velz
+ Bvecxlow = gxx*Bvecx + gxy*Bvecy + gxz*Bvecz
+ Bvecylow = gxy*Bvecx + gyy*Bvecy + gyz*Bvecz
+ Bveczlow = gxz*Bvecx + gyz*Bvecy + gzz*Bvecz
+
+!!$ B^i v_i (= b^0/u^0)
+ Bdotv = velxlow*Bvecx+velylow*Bvecy+velzlow*Bvecz
+
+!!$v^2 = v_i v^i; w=(1-v^2)^{-1/2}
+
+ v2 = velxlow*velx + velylow*vely + velzlow*velz
+ w = 1.d0/sqrt(1.d0-v2)
+
+!!$b^2 = B^i B_i / w^2 + (b^0/u^0)^2
+
+ b2=(Bvecx*Bvecxlow+Bvecy*Bvecylow+Bvecz*Bveczlow)/w**2+Bdotv**2
+
+!!$ b_i = B_i/w +w*(B dot v)*v_i
+ bxlow = Bvecxlow/w+w*Bdotv*velxlow
+ bylow = Bvecylow/w+w*Bdotv*velylow
+ bzlow = Bveczlow/w+w*Bdotv*velzlow
+
+end subroutine calc_vlow_blow
diff --git a/src/make.code.defn b/src/make.code.defn
index c7dadf2..53fe17c 100644
--- a/src/make.code.defn
+++ b/src/make.code.defn
@@ -7,7 +7,6 @@ SRCS = Utils.F90 \
GRHydro_Boundaries.F90 \
GRHydro_CalcUpdate.F90 \
GRHydro_Con2Prim.F90 \
- GRHydro_Con2PrimM.F90 \
GRHydro_Eigenproblem.F90 \
GRHydro_Eigenproblem_Marquina.F90 \
GRHydro_ENOReconstruct.F90 \
@@ -44,7 +43,27 @@ SRCS = Utils.F90 \
GRHydro_Set_TP_GF.c \
GRHydro_Differences.F90 \
GRHydro_EoSChangeGamma.F90 \
- GRHydro_Tmunu.F90
+ GRHydro_Tmunu.F90 \
+ GRHydro_RegisterGZM.cc \
+ GRHydro_RegisterVarsM.cc \
+ GRHydro_BoundariesM.F90 \
+ GRHydro_CalcUpdateM.F90 \
+ GRHydro_Con2PrimM.F90 \
+ GRHydro_Con2PrimM_pt.c \
+ GRHydro_EigenproblemM.F90 \
+ GRHydro_FluxM.F90 \
+ GRHydro_HLLEM.F90 \
+ GRHydro_HLLEPolyM.F90 \
+ GRHydro_PPMM.F90 \
+ GRHydro_ParamCheckM.F90 \
+ GRHydro_Prim2ConM.F90 \
+ GRHydro_RiemannSolveM.F90 \
+ GRHydro_ReconstructM.F90 \
+ GRHydro_ReconstructPolyM.F90 \
+ GRHydro_SourceM.F90 \
+ GRHydro_TmunuM.F90 \
+ GRHydro_UpdateMaskM.F90 \
+ GRHydro_UtilsM.F90
### GRHydro_Weights.c \