Solving partial differential equations on the computer with finite difference techniques requires that we sample our solutions to these equations on numerical grids. We call all sampled functions that are stored on our numerical grid gridfunctions. NRPy+'s grid module adds the capability of registering gridfunctions in NRPy, setting basic parameters of a numerical grid, and providing functions to other modules regarding reading and writing of gridfunctions to memory in the C code.
Parameters in this module include:
Functions in this module include:
RK_Allocate_Memory.h
), MoL updates (RK_MoL.h
), and memory deallocation (RK_Free_Memory.h
).*diagnostic_gfs
pointer. "auxiliary"/"diagnostic" gridfunctions therefore cannot be used with "Euler" timestepping, and one cannot use more "auxiliary"/"diagnostic" gridfunctions than the number of "evolved" gridfunctions.#define
'd in "outdir/gridfunction_defines.h" are meant to be human-friendly, so that accessing each gridfunction in C code can be done by its human-friendly alias (e.g., test_gfs[IDX4(VVGF,i0,i1,i2] instead of the less-friendly test_gfs[IDX4(1,i0,i1,i2])./* This file is automatically generated by NRPy+. Do not edit. */
/* EVOLVED VARIABLES: */
#define NUM_EVOL_GFS 2
#define UUGF 0
#define VVGF 1
/* AUXILIARY VARIABLES: */
#define NUM_AUX_GFS 0
/* AUXEVOL VARIABLES: */
#define NUM_AUXEVOL_GFS 0
Let's now register a gridfunction called "phi" in the "in_gfs" gridfunction array, then print C code that specifies how to access the gridfunction from the single point in memory (i0,i1,i2). Next, we will demonstrate that phi is a normal SymPy variable, and finally, we will confirm that its type is "gridfunction" using variable_type():
import grid as gri
import NRPy_param_funcs as par
import cmdline_helper as cmd
# Register gridfunction phi, as type "AUX".
# WARNING: register_gridfunctions can only be run once on a given gridfunction;
# you'll need to reset the Jupyter kernel before trying again:
phi = gri.register_gridfunctions("AUX","phi")
print("Here's how to access the gridfunction phi, in grid array in_gfs, at point (i0,i1,i2):")
print("SENR-like memory access: "+gri.gfaccess("in_gfs","phi","i0,i1,i2"))
par.set_paramsvals_value("grid::GridFuncMemAccess = ETK")
print("ETK memory access: "+gri.gfaccess("in_gfs","phi","i0,i1,i2"))
# Note that phi can now be used as a usual SymPy variable:
print("\n\nTo demonstrate that phi is just a regular SymPy variable, we will now print its square:")
print(phi**2)
print("\n\n\"phi\" is of type \""+ gri.variable_type(phi)+"\"")
evolved_variables_list,auxiliary_variables_list, auxevol_variables_list = \
gri.gridfunction_lists()[0:3]
print("\n\n")
print("Here is the list of registered evolved variables: ",evolved_variables_list)
print("... and here is the list of registered auxiliary variables: ",auxiliary_variables_list)
print("... and here is the list of registered auxevol variables: ",auxevol_variables_list)
print("\n\n ... and here is the output of gridfunction_defines():")
print(gri.gridfunction_defines())
Here's how to access the gridfunction phi, in grid array in_gfs, at point (i0,i1,i2): SENR-like memory access: aux_gfs[IDX4S(PHIGF, i0,i1,i2)] ETK memory access: phiGF[CCTK_GFINDEX3D(cctkGH, i0,i1,i2)] To demonstrate that phi is just a regular SymPy variable, we will now print its square: phi**2 "phi" is of type "gridfunction" Here is the list of registered evolved variables: [] ... and here is the list of registered auxiliary variables: ['phi'] ... and here is the list of registered auxevol variables: [] ... and here is the output of gridfunction_defines(): // EVOLVED VARIABLES: #define NUM_EVOL_GFS 0 // AUXILIARY VARIABLES: #define NUM_AUX_GFS 1 #define PHIGF 0 // AUXEVOL VARIABLES: #define NUM_AUXEVOL_GFS 0 // EXTERNAL VARIABLES: #define NUM_EXTERNAL_GFS 0