GiRaFFEfood
Initial Data for GiRaFFE
¶GiRaFFE
, drawn from this paper .¶Notebook Status: Validated
Validation Notes: This tutorial notebook has been confirmed to be self-consistent with its corresponding NRPy+ module, as documented below. The initial data has validated against the original GiRaFFE
, as documented here.
This is a flat-spacetime test with initial data \begin{align} A_x &= 0,\ A_y = 0 \\ A_z &= y+\left \{ \begin{array}{lll} -x-0.0075 & \mbox{if} & x \leq -0.1\ \\ 0.75x^2 - 0.85x & \mbox{if} & -0.1 \leq x \leq 0.1 \\ -0.7x-0.0075 & \mbox{if} & x \geq 0.1 \end{array} \right. , \\ \end{align} which generates the magnetic field \begin{align} B^x(0,x) &= 1.0 \\ B^y(0,x) &= \left \{ \begin{array}{lll} 1.0 & \mbox{if} & x \leq -0.1 \\ 1.0-1.5(x+0.1) & \mbox{if} & -0.1 \leq x \leq 0.1 \\ 0.7 & \mbox{if} & x \geq 0.1 \end{array} \right. \\ B^z(0,x) &= 0\ . \end{align} The electric field is then given by $$E^x(0,x) = 0.0 \ \ , \ \ E^y(x) = 0.0 \ \ , \ \ E^z(x) = -B^y(0,x) .$$
and the velocity is given by $$\mathbf{v} = \frac{\mathbf{E} \times \mathbf{B}}{B^2}$$ in flat spacetime.
For the eventual purpose of testing convergence, any quantity $Q$ evolves as $Q(t,x) = Q(0,x - t)$
See the Tutorial-GiRaFFEfood_NRPy tutorial notebook for more general detail on how this is used.
This notebook is organized as follows
Here, we will import the NRPy+ core modules, set the reference metric to Cartesian, and set commonly used NRPy+ parameters. We will also set up a parameter to determine what initial data is set up, although it won't do much yet.
# Step 0: Add NRPy's directory to the path
# https://stackoverflow.com/questions/16780014/import-file-from-parent-directory
import os,sys
nrpy_dir_path = os.path.join("..")
if nrpy_dir_path not in sys.path:
sys.path.append(nrpy_dir_path)
# Step 0.a: Import the NRPy+ core modules and set the reference metric to Cartesian
import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends
import NRPy_param_funcs as par # NRPy+: Parameter interface
import indexedexp as ixp # NRPy+: Symbolic indexed expression (e.g., tensors, vectors, etc.) support
import GiRaFFEfood_NRPy.GiRaFFEfood_NRPy_Common_Functions as gfcf # Some useful functions for GiRaFFE initial data.
import reference_metric as rfm # NRPy+: Reference metric support
par.set_parval_from_str("reference_metric::CoordSystem","Cartesian")
rfm.reference_metric()
# Step 1a: Set commonly used parameters.
thismodule = "GiRaFFEfood_NRPy_1D"
The vector potential is given as \begin{align} A_x &= 0,\ A_y = 0 \\ A_z &= y+\left \{ \begin{array}{lll} -x-0.0075 & \mbox{if} & x \leq -0.1 \\ 0.75x^2 - 0.85x & \mbox{if} & -0.1 \leq x \leq 0.1 \\ -0.7x-0.0075 & \mbox{if} & x \geq 0.1 \end{array} \right. . \\ \end{align}
However, to take full advantage of NRPy+'s automated function generation capabilities, we want to write this without the if
statements, replacing them with calls to fabs()
. To do so, we will use the NRPy+ module Min_Max_and_Piecewise_Expressions
.
We will rewrite $A_y$ to make use of the functions provided by Min_Max_and_Piecewise_Expressions
. As shown below, we make sure that at each boundary, each $\leq$ is paired with a $>$. (This choice is arbitrary, we could just as easily choose $<$ and $\geq$.) This does not change the data since the function is continuous. However, it is necessary for the functions in Min_Max_and_Piecewise_Expressions
to output the correct results:
import Min_Max_and_Piecewise_Expressions as noif
bound = sp.Rational(1,10)
def Ax_FW(x,y,z, **params):
return sp.sympify(0)
def Ay_FW(x,y,z, **params):
return sp.sympify(0)
def Az_FW(x,y,z, **params):
# A_z = y+ (-x-0.0075) if x <= -0.1
# (0.75x^2 - 0.85x) if -0.1 < x <= 0.1
# (-0.7x-0.0075) if x > 0.1
Azleft = y - x - sp.Rational(75,10000)
Azcenter = y + sp.Rational(75,100)*x*x - sp.Rational(85,100)*x
Azright = y - sp.Rational(7,10)*x - sp.Rational(75,10000)
out = noif.coord_leq_bound(x,-bound)*Azleft\
+noif.coord_greater_bound(x,-bound)*noif.coord_leq_bound(x,bound)*Azcenter\
+noif.coord_greater_bound(x,bound)*Azright
return out
Now, we will set the magnetic and electric fields that we will need to define the initial velocities.
We will first set the magnetic field, once again rewriting $B^z(x)$ to be compatible with Min_Max_and_Piecewise_Expressions
:
\begin{align}
B^x(0,x) &= 1.0 \\
B^y(0,x) &= \left \{ \begin{array}{lll} 1.0 & \mbox{if} & x \leq -0.1 \\
1.0-1.5(x+0.1) & \mbox{if} & -0.1 < x \leq 0.1 \\
0.7 & \mbox{if} & x > 0.1 \end{array} \right. \\
B^z(0,x) &= 0\ .
\end{align}
Then, we will set the electric field: $$E^x(0,x) = 0.0 \ \ , \ \ E^y(x) = 0.0 \ \ , \ \ E^z(x) = -B^y(0,x) .$$
def ValenciavU_func_FW(**params):
# B^x(0,x) = 1.0
# B^y(0,x) = 1.0 if x <= -0.1
# 1.0-1.5(x+0.1) if -0.1 < x <= 0.1
# 0.7 if x > 0.1
# B^z(0,x) = 0
x = rfm.xx_to_Cart[0]
y = rfm.xx_to_Cart[1]
Byleft = sp.sympify(1)
Bycenter = sp.sympify(1) - sp.Rational(15,10)*(x+sp.Rational(1,10))
Byright = sp.Rational(7,10)
BU = ixp.zerorank1()
BU[0] = sp.sympify(1)
BU[1] = noif.coord_leq_bound(x,-bound)*Byleft\
+noif.coord_greater_bound(x,-bound)*noif.coord_leq_bound(x,bound)*Bycenter\
+noif.coord_greater_bound(x,bound)*Byright
BU[2] = 0
# E^x(0,x) = 0.0 , E^y(x) = 0.0 , E^z(x) = -B^y(0,x)
EU = ixp.zerorank1()
EU[0] = sp.sympify(0)
EU[1] = sp.sympify(0)
EU[2] = -BU[1]
# In flat space, ED and EU are identical, so we can still use this function.
return gfcf.compute_ValenciavU_from_ED_and_BU(EU, BU)
GiRaFFEfood_NRPy.GiRaFFEfood_NRPy
NRPy+ Module [Back to top]¶Here, as a code validation check, we verify agreement in the SymPy expressions for the GiRaFFE
Aligned Rotator initial data equations we intend to use between
GiRaFFEfood_NRPy/GiRaFFEfood_NRPy_1D_tests_fast_wave.py
module.import GiRaFFEfood_NRPy.GiRaFFEfood_NRPy as gf
A_fwD = gfcf.Axyz_func_Cartesian(Ax_FW,Ay_FW,Az_FW,stagger_enable = True,)
Valenciav_fwD = ValenciavU_func_FW()
gf.GiRaFFEfood_NRPy_generate_initial_data(ID_type = "FastWave", stagger_enable = True)
def consistency_check(quantity1,quantity2,string):
if quantity1-quantity2==0:
print(string+" is in agreement!")
else:
print(string+" does not agree!")
sys.exit(1)
print("Consistency check between GiRaFFEfood_NRPy tutorial and NRPy+ module:")
for i in range(3):
consistency_check(Valenciav_fwD[i],gf.ValenciavU[i],"ValenciavU"+str(i))
consistency_check(A_fwD[i],gf.AD[i],"AD"+str(i))
Consistency check between GiRaFFEfood_NRPy tutorial and NRPy+ module: ValenciavU0 is in agreement! AD0 is in agreement! ValenciavU1 is in agreement! AD1 is in agreement! ValenciavU2 is in agreement! AD2 is in agreement!
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-GiRaFFEfood_NRPy_1D_tests.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-GiRaFFEfood_NRPy-Fast_Wave",location_of_template_file=os.path.join(".."))
Created Tutorial-GiRaFFEfood_NRPy-Fast_Wave.tex, and compiled LaTeX file to PDF file Tutorial-GiRaFFEfood_NRPy-Fast_Wave.pdf