Notebook Status: Self-Validated
Validation Notes: This tutorial notebook has been confirmed to be self-consistent with its corresponding NRPy+ module, as documented below. Additional validation tests may have been performed, but are as yet, undocumented. (TODO)
This tutorial notebook constructs all quantities in the ADM formalism (see also Chapter 2 in Baumgarte & Shapiro's book Numerical Relativity) in terms of quantities in our adopted (covariant, tensor-rescaled) BSSN formalism. That is to say, we will write the ADM quantities {γij,Kij,α,βi} and their derivatives in terms of the BSSN quantities {ˉγij,cf,ˉAij,trK,α,βi} and their derivatives.
As is standard in NRPy+,
As a corollary, any expressions in NRPy+ involving mixed Greek and Latin indices will need to offset one set of indices by one; a Latin index in a four-vector will be incremented and a Greek index in a three-vector will be decremented (however, the latter case does not occur in this tutorial notebook).
This notebook is organized as follows
BSSN.ADM_in_terms_of_BSSN
NRPy+ module# Step 1.a: Import all needed modules from NRPy+
import NRPy_param_funcs as par # NRPy+: parameter interface
import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends
import indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support
import reference_metric as rfm # NRPy+: Reference metric support
import sys # Standard Python module for multiplatform OS-level functions
# Step 1.b: Set the coordinate system for the numerical grid
par.set_parval_from_str("reference_metric::CoordSystem","Spherical")
# Step 1.c: Given the chosen coordinate system, set up
# corresponding reference metric and needed
# reference metric quantities
# The following function call sets up the reference metric
# and related quantities, including rescaling matrices ReDD,
# ReU, and hatted quantities.
rfm.reference_metric()
# Step 1.d: Set spatial dimension (must be 3 for BSSN, as BSSN is
# a 3+1-dimensional decomposition of the general
# relativistic field equations)
DIM = 3
# Step 1.e: Import all basic (unrescaled) BSSN scalars & tensors
import BSSN.BSSN_quantities as Bq
Bq.BSSN_basic_tensors()
gammabarDD = Bq.gammabarDD
cf = Bq.cf
AbarDD = Bq.AbarDD
trK = Bq.trK
Bq.gammabar__inverse_and_derivs()
gammabarDD_dD = Bq.gammabarDD_dD
gammabarDD_dDD = Bq.gammabarDD_dDD
Bq.AbarUU_AbarUD_trAbar_AbarDD_dD()
AbarDD_dD = Bq.AbarDD_dD
The ADM three-metric is written in terms of the covariant BSSN three-metric tensor as (Eqs. 2 and 3 of Ruchlin et al.): γij=(γˉγ)1/3ˉγij,
The "standard" BSSN conformal factor ϕ is given by (Eq. 3 of Ruchlin et al.):
ϕ=112log(γˉγ)⟹eϕ=(γˉγ)1/12⟹e4ϕ=(γˉγ)1/3Thus the ADM three-metric may be written in terms of the BSSN three-metric and conformal factor ϕ as
γij=e4ϕˉγij.NRPy+'s implementation of BSSN allows for ϕ and two other alternative conformal factors to be defined:
χ=e−4ϕW=e−2ϕ,Thus if "BSSN_quantities::EvolvedConformalFactor_cf"
is set to "chi"
, then
and if "BSSN_quantities::EvolvedConformalFactor_cf"
is set to "W"
, then
γij=1W2ˉγij=1cf2ˉγij.
# Step 2: The ADM three-metric gammaDD and its
# derivatives in terms of BSSN quantities.
gammaDD = ixp.zerorank2()
exp4phi = sp.sympify(0)
if par.parval_from_str("EvolvedConformalFactor_cf") == "phi":
exp4phi = sp.exp(4*cf)
elif par.parval_from_str("EvolvedConformalFactor_cf") == "chi":
exp4phi = (1 / cf)
elif par.parval_from_str("EvolvedConformalFactor_cf") == "W":
exp4phi = (1 / cf**2)
else:
print("Error EvolvedConformalFactor_cf type = \""+par.parval_from_str("EvolvedConformalFactor_cf")+"\" unknown.")
sys.exit(1)
for i in range(DIM):
for j in range(DIM):
gammaDD[i][j] = exp4phi*gammabarDD[i][j]
To compute derivatives of γij in terms of BSSN variables and their derivatives, we will first need derivatives of e4ϕ in terms of the conformal BSSN variable cf
.
Thus computing first and second derivatives of e4ϕ in terms of the BSSN quantity cf
requires only that we evaluate ϕ,i and ϕ,ij in terms of e4ϕ (computed above in terms of cf
) and derivatives of cf
:
If "BSSN_quantities::EvolvedConformalFactor_cf"
is set to "phi"
, then
ϕ,i=cf,iϕ,ij=cf,ij
If "BSSN_quantities::EvolvedConformalFactor_cf"
is set to "chi"
, then
cf=e−4ϕ⟹cf,i=−4e−4ϕϕ,i⟹ϕ,i=−e4ϕ4cf,i⟹ϕ,ij=−e4ϕϕ,jcf,i−e4ϕ4cf,ij=−e4ϕ(−e4ϕ4cf,j)cf,i−e4ϕ4cf,ij=14[(e4ϕ)2cf,icf,j−e4ϕcf,ij]
If "BSSN_quantities::EvolvedConformalFactor_cf"
is set to "W"
, then
cf=e−2ϕ⟹cf,i=−2e−2ϕϕ,i⟹ϕ,i=−e2ϕ2cf,i⟹ϕ,ij=−e2ϕϕ,jcf,i−e2ϕ2cf,ij=−e2ϕ(−e2ϕ2cf,j)cf,i−e2ϕ2cf,ij=12[e4ϕcf,icf,j−e2ϕcf,ij]
# Step 2.a: Derivatives of $e^{4\phi}$
phidD = ixp.zerorank1()
phidDD = ixp.zerorank2()
cf_dD = ixp.declarerank1("cf_dD")
cf_dDD = ixp.declarerank2("cf_dDD","sym01")
if par.parval_from_str("EvolvedConformalFactor_cf") == "phi":
for i in range(DIM):
phidD[i] = cf_dD[i]
for j in range(DIM):
phidDD[i][j] = cf_dDD[i][j]
elif par.parval_from_str("EvolvedConformalFactor_cf") == "chi":
for i in range(DIM):
phidD[i] = -sp.Rational(1,4)*exp4phi*cf_dD[i]
for j in range(DIM):
phidDD[i][j] = sp.Rational(1,4)*( exp4phi**2*cf_dD[i]*cf_dD[j] - exp4phi*cf_dDD[i][j] )
elif par.parval_from_str("EvolvedConformalFactor_cf") == "W":
exp2phi = (1 / cf)
for i in range(DIM):
phidD[i] = -sp.Rational(1,2)*exp2phi*cf_dD[i]
for j in range(DIM):
phidDD[i][j] = sp.Rational(1,2)*( exp4phi*cf_dD[i]*cf_dD[j] - exp2phi*cf_dDD[i][j] )
else:
print("Error EvolvedConformalFactor_cf type = \""+par.parval_from_str("EvolvedConformalFactor_cf")+"\" unknown.")
sys.exit(1)
exp4phidD = ixp.zerorank1()
exp4phidDD = ixp.zerorank2()
for i in range(DIM):
exp4phidD[i] = 4*exp4phi*phidD[i]
for j in range(DIM):
exp4phidDD[i][j] = 16*exp4phi*phidD[i]*phidD[j] + 4*exp4phi*phidDD[i][j]
Recall the relation between the ADM three-metric γij, the BSSN conformal three-metric ˉγij, and the BSSN conformal factor ϕ:
γij=e4ϕˉγij.Now that we have constructed derivatives of e4ϕ in terms of the chosen BSSN conformal factor cf
, and the BSSN.BSSN_quantities module (tutorial) defines derivatives of ˉγij in terms of rescaled BSSN variables, derivatives of γij can be immediately constructed using the product rule:
# Step 2.b: Derivatives of gammaDD, the ADM three-metric
gammaDDdD = ixp.zerorank3()
gammaDDdDD = ixp.zerorank4()
for i in range(DIM):
for j in range(DIM):
for k in range(DIM):
gammaDDdD[i][j][k] = exp4phidD[k]*gammabarDD[i][j] + exp4phi*gammabarDD_dD[i][j][k]
for l in range(DIM):
gammaDDdDD[i][j][k][l] = exp4phidDD[k][l]*gammabarDD[i][j] + \
exp4phidD[k]*gammabarDD_dD[i][j][l] + \
exp4phidD[l]*gammabarDD_dD[i][j][k] + \
exp4phi*gammabarDD_dDD[i][j][k][l]
# Step 2.c: 3-Christoffel symbols associated with ADM 3-metric gammaDD
# Step 2.c.i: First compute the inverse 3-metric gammaUU:
gammaUU, detgamma = ixp.symm_matrix_inverter3x3(gammaDD)
GammaUDD = ixp.zerorank3()
for i in range(DIM):
for j in range(DIM):
for k in range(DIM):
for l in range(DIM):
GammaUDD[i][j][k] += sp.Rational(1,2)*gammaUU[i][l]* \
(gammaDDdD[l][j][k] + gammaDDdD[l][k][j] - gammaDDdD[j][k][l])
The ADM extrinsic curvature may be written in terms of the BSSN trace-free extrinsic curvature tensor ˉAij and the trace of the ADM extrinsic curvature K:
Kij=(γˉγ)1/3ˉAij+13γijK=e4ϕˉAij+13γijKWe only compute first spatial derivatives of Kij, as higher-derivatives are generally not needed: Kij,k=(e4ϕ),kˉAij+e4ϕˉAij,k+13(γij,kK+γijK,k)
# Step 3: Define ADM extrinsic curvature KDD and
# its first spatial derivatives KDDdD
# in terms of BSSN quantities
KDD = ixp.zerorank2()
for i in range(DIM):
for j in range(DIM):
KDD[i][j] = exp4phi*AbarDD[i][j] + sp.Rational(1,3)*gammaDD[i][j]*trK
KDDdD = ixp.zerorank3()
trK_dD = ixp.declarerank1("trK_dD")
for i in range(DIM):
for j in range(DIM):
for k in range(DIM):
KDDdD[i][j][k] = exp4phidD[k]*AbarDD[i][j] + exp4phi*AbarDD_dD[i][j][k] + \
sp.Rational(1,3)*(gammaDDdD[i][j][k]*trK + gammaDD[i][j]*trK_dD[k])
BSSN.ADM_in_terms_of_BSSN
NRPy+ module [Back to top]¶Here, as a code validation check, we verify agreement in the SymPy expressions between
def comp_func(expr1,expr2,basename,prefixname2="Bq."):
if str(expr1-expr2)!="0":
print(basename+" - "+prefixname2+basename+" = "+ str(expr1-expr2))
return 1
return 0
def gfnm(basename,idx1,idx2=None,idx3=None,idx4=None):
if idx2 is None:
return basename+"["+str(idx1)+"]"
if idx3 is None:
return basename+"["+str(idx1)+"]["+str(idx2)+"]"
if idx4 is None:
return basename+"["+str(idx1)+"]["+str(idx2)+"]["+str(idx3)+"]"
return basename+"["+str(idx1)+"]["+str(idx2)+"]["+str(idx3)+"]["+str(idx4)+"]"
expr_list = []
exprcheck_list = []
namecheck_list = []
import BSSN.ADM_in_terms_of_BSSN as AB
AB.ADM_in_terms_of_BSSN()
namecheck_list.extend(["detgamma"])
exprcheck_list.extend([AB.detgamma])
expr_list.extend([detgamma])
for i in range(DIM):
for j in range(DIM):
namecheck_list.extend([gfnm("gammaDD",i,j),gfnm("gammaUU",i,j),gfnm("KDD",i,j)])
exprcheck_list.extend([AB.gammaDD[i][j],AB.gammaUU[i][j],AB.KDD[i][j]])
expr_list.extend([gammaDD[i][j],gammaUU[i][j],KDD[i][j]])
for k in range(DIM):
namecheck_list.extend([gfnm("gammaDDdD",i,j,k),gfnm("GammaUDD",i,j,k),gfnm("KDDdD",i,j,k)])
exprcheck_list.extend([AB.gammaDDdD[i][j][k],AB.GammaUDD[i][j][k],AB.KDDdD[i][j][k]])
expr_list.extend([gammaDDdD[i][j][k],GammaUDD[i][j][k],KDDdD[i][j][k]])
for l in range(DIM):
namecheck_list.extend([gfnm("gammaDDdDD",i,j,k,l)])
exprcheck_list.extend([AB.gammaDDdDD[i][j][k][l]])
expr_list.extend([gammaDDdDD[i][j][k][l]])
num_failures = 0
for i in range(len(expr_list)):
num_failures += comp_func(expr_list[i],exprcheck_list[i],namecheck_list[i])
if num_failures == 0:
print("ALL TESTS PASSED!")
else:
print("ERROR. " + str(num_failures) + " TESTS FAILED")
sys.exit(1)
ALL TESTS PASSED!
The following code cell converts this Jupyter notebook into a proper, clickable LATEX-formatted PDF file. After the cell is successfully run, the generated PDF may be found in the root NRPy+ tutorial directory, with filename Tutorial-ADM_in_terms_of_BSSN.pdf (Note that clicking on this link may not work; you may need to open the PDF file through another means.)
import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface
cmd.output_Jupyter_notebook_to_LaTeXed_PDF("Tutorial-ADM_in_terms_of_BSSN")
Created Tutorial-ADM_in_terms_of_BSSN.tex, and compiled LaTeX file to PDF file Tutorial-ADM_in_terms_of_BSSN.pdf