Ejemplo n.º 1
0
def PlaneWave(CoordSystem="Cartesian",
              default_time=0,
              default_k0=1,
              default_k1=1,
              default_k2=1):
    # Step 1: Set parameters defined in other modules
    DIM = par.parval_from_str("grid::DIM")

    # Step 2: Set up Cartesian coordinates in terms of the native CoordSystem we have chosen.
    #         E.g., if CoordSystem="Cartesian", then xxCart = [xx[0],xx[1],xx[2]]
    #         or if CoordSystem="Spherical", then xxCart = [xx[0]*sp.sin(xx[1])*sp.cos(xx[2]),
    #                                                       xx[0]*sp.sin(xx[1])*sp.sin(xx[2]),
    #                                                       xx[0]*sp.cos(xx[1])]
    par.set_parval_from_str("reference_metric::CoordSystem", CoordSystem)
    rfm.reference_metric()
    xxCart = rfm.xxCart

    # Step 3: Declare free parameters intrinsic to these initial data
    time = par.Cparameters("REAL", thismodule, "time", default_time)
    kk = par.Cparameters("REAL", thismodule, ["kk0", "kk1", "kk2"],
                         [default_k0, default_k1, default_k2])

    # Step 4: Normalize the k vector
    kk_norm_factor = sp.sqrt(kk[0]**2 + kk[1]**2 + kk[2]**2)

    # Step 5: Compute k_norm.x
    dot_product = sp.sympify(0)
    for i in range(DIM):
        dot_product += kk[i] * xxCart[i]
    dot_product /= kk_norm_factor

    # Step 6: Set initial data for uu and vv, where vv_ID = \partial_t uu_ID.
    global uu_ID, vv_ID
    uu_ID = sp.sin(dot_product - wavespeed * time) + 2
    vv_ID = sp.diff(uu_ID, time)
Ejemplo n.º 2
0
def SphericalGaussian(CoordSystem="Cartesian",
                      default_time=0,
                      default_sigma=3):
    # Step 1: Set parameters for the wave
    DIM = par.parval_from_str("grid::DIM")

    # Step 2: Set up Cartesian coordinates in terms of the native CoordSystem we have chosen.
    #         E.g., if CoordSystem="Cartesian", then xxCart = [xx[0],xx[1],xx[2]]
    #         or if CoordSystem="Spherical", then xxCart = [xx[0]*sp.sin(xx[1])*sp.cos(xx[2]),
    #                                                       xx[0]*sp.sin(xx[1])*sp.sin(xx[2]),
    #                                                       xx[0]*sp.cos(xx[1])]
    par.set_parval_from_str("reference_metric::CoordSystem", CoordSystem)
    rfm.reference_metric()  # Must call this function to specify rfm.xxCart
    xxCart = rfm.xxCart

    # Step 3: Declare free parameters intrinsic to these initial data
    time = par.Cparameters("REAL", thismodule, "time", default_time)
    sigma = par.Cparameters("REAL", thismodule, "sigma", default_sigma)

    # Step 4: Compute r
    r = sp.sympify(0)
    for i in range(DIM):
        r += xxCart[i]**2
    r = sp.sqrt(r)

    # Step 5: Set initial data for uu and vv, where vv_ID = \partial_t uu_ID.
    global uu_ID, vv_ID
    # uu_ID = (r - wavespeed*time)/r * sp.exp(- (r - wavespeed*time)**2 / (2*sigma**2) )
    uu_ID = (+(r - wavespeed * time) / r * sp.exp(-(r - wavespeed * time)**2 /
                                                  (2 * sigma**2)) +
             (r + wavespeed * time) / r * sp.exp(-(r + wavespeed * time)**2 /
                                                 (2 * sigma**2)))
    vv_ID = sp.diff(uu_ID, time)
Ejemplo n.º 3
0
def u4U_in_terms_of_ValenciavU__rescale_ValenciavU_by_applying_speed_limit(
        alpha, betaU, gammaDD, ValenciavU):
    # Inputs:  Metric lapse alpha, shift betaU, 3-metric gammaDD, Valencia 3-velocity ValenciavU
    # Outputs (as globals): u4U_ito_ValenciavU, rescaledValenciavU

    # R = gamma_{ij} v^i v^j
    R = sp.sympify(0)
    for i in range(3):
        for j in range(3):
            R += gammaDD[i][j] * ValenciavU[i] * ValenciavU[j]

    thismodule = __name__
    # The default value isn't terribly important here, since we can overwrite in the main C code
    GAMMA_SPEED_LIMIT = par.Cparameters("REAL", thismodule,
                                        "GAMMA_SPEED_LIMIT",
                                        10.0)  # Default value based on
    # IllinoisGRMHD.
    # GiRaFFE default = 2000.0
    Rmax = 1 - 1 / (GAMMA_SPEED_LIMIT * GAMMA_SPEED_LIMIT)
    # Now, we set Rstar = min(Rmax,R):
    # If R <  Rmax, then Rstar = 0.5*(Rmax+R-Rmax+R) = R
    # If R >= Rmax, then Rstar = 0.5*(Rmax+R+Rmax-R) = Rmax
    Rstar = sp.Rational(1, 2) * (Rmax + R - nrpyAbs(Rmax - R))

    # We add TINYDOUBLE to R below to avoid a 0/0, which occurs when
    #    ValenciavU == 0 for all Valencia 3-velocity components.
    # "Those tiny *doubles* make me warm all over
    #  with a feeling that I'm gonna love you till the end of time."
    #    - Adapted from Connie Francis' "Tiny Bubbles"
    TINYDOUBLE = par.Cparameters("#define", thismodule, "TINYDOUBLE", 1e-100)

    # The rescaled (speed-limited) Valencia 3-velocity
    #     is given by, v_{(n)}^i = sqrt{Rstar/R} v^i
    global rescaledValenciavU
    rescaledValenciavU = ixp.zerorank1()
    for i in range(3):
        # If R == 0, then Rstar == 0, so sqrt( Rstar/(R+TINYDOUBLE) )=sqrt(0/1e-100) = 0
        #   If your velocities are of order 1e-100 and this is physically
        #   meaningful, there must be something wrong with your unit conversion.
        rescaledValenciavU[i] = ValenciavU[i] * sp.sqrt(Rstar /
                                                        (R + TINYDOUBLE))

    # Finally compute u^mu in terms of Valenciav^i
    # u^0 = 1/(alpha-sqrt(1-R^*))
    global u4U_ito_ValenciavU
    u4U_ito_ValenciavU = ixp.zerorank1(DIM=4)
    u4U_ito_ValenciavU[0] = 1 / (alpha * sp.sqrt(1 - Rstar))
    # u^i = u^0 ( alpha v^i_{(n)} - beta^i ), where v^i_{(n)} is the Valencia 3-velocity
    for i in range(3):
        u4U_ito_ValenciavU[i + 1] = u4U_ito_ValenciavU[0] * (
            alpha * rescaledValenciavU[i] - betaU[i])
Ejemplo n.º 4
0
def BrillLindquist(ComputeADMGlobalsOnly=False):
    global Cartxyz, gammaCartDD, KCartDD, alphaCart, betaCartU, BCartU

    # Step 2: Setting up Brill-Lindquist initial data
    thismodule = "Brill-Lindquist"
    BH1_posn_x, BH1_posn_y, BH1_posn_z = par.Cparameters(
        "REAL", thismodule, ["BH1_posn_x", "BH1_posn_y", "BH1_posn_z"])
    BH1_mass = par.Cparameters("REAL", thismodule, ["BH1_mass"])
    BH2_posn_x, BH2_posn_y, BH2_posn_z = par.Cparameters(
        "REAL", thismodule, ["BH2_posn_x", "BH2_posn_y", "BH2_posn_z"])
    BH2_mass = par.Cparameters("REAL", thismodule, ["BH2_mass"])

    # Step 2.a: Set spatial dimension (must be 3 for BSSN)
    DIM = 3
    par.set_parval_from_str("grid::DIM", DIM)

    global Cartxyz, gammaCartDD, KCartDD, alphaCart, betaCartU, BCartU
    Cartxyz = ixp.declarerank1("Cartxyz")

    # Step 2.b: Set psi, the conformal factor:
    psi = sp.sympify(1)
    psi += BH1_mass / (2 * sp.sqrt((Cartxyz[0] - BH1_posn_x)**2 +
                                   (Cartxyz[1] - BH1_posn_y)**2 +
                                   (Cartxyz[2] - BH1_posn_z)**2))
    psi += BH2_mass / (2 * sp.sqrt((Cartxyz[0] - BH2_posn_x)**2 +
                                   (Cartxyz[1] - BH2_posn_y)**2 +
                                   (Cartxyz[2] - BH2_posn_z)**2))

    # Step 2.c: Set all needed ADM variables in Cartesian coordinates
    gammaCartDD = ixp.zerorank2()
    KCartDD = ixp.zerorank2()  # K_{ij} = 0 for these initial data
    for i in range(DIM):
        gammaCartDD[i][i] = psi**4

    alphaCart = 1 / psi**2
    betaCartU = ixp.zerorank1(
    )  # We generally choose \beta^i = 0 for these initial data
    BCartU = ixp.zerorank1(
    )  # We generally choose B^i = 0 for these initial data

    if ComputeADMGlobalsOnly == True:
        return

    cf,hDD,lambdaU,aDD,trK,alpha,vetU,betU = \
        AtoB.Convert_Spherical_or_Cartesian_ADM_to_BSSN_curvilinear("Cartesian",Cartxyz,
                                                                    gammaCartDD,KCartDD,alphaCart,betaCartU,BCartU)

    global returnfunction
    returnfunction = bIDf.BSSN_ID_function_string(cf, hDD, lambdaU, aDD, trK,
                                                  alpha, vetU, betU)
Ejemplo n.º 5
0
def MaxwellCartesian_ID():
    DIM = par.parval_from_str("grid::DIM")

    x, y, z = gri.register_gridfunctions("AUX", ["x", "y", "z"])
    gammaDD = ixp.register_gridfunctions_for_single_rank2("AUX","gammaDD", "sym01") # The AUX or EVOL designation is *not*
                                                                                    # used in diagnostic modules.

    # Step 1: Declare free parameters intrinsic to these initial data
    amp,lam = par.Cparameters("REAL",__name__,["amp","lam"], [1.0,1.0]) # __name__ = "MaxwellCartesian_ID", this module's name

    # Step 2: Set the initial data
    system = par.parval_from_str("System_to_use")
    if system == "System_I" or system == "System_II":
        global AidD,EidD,psi_ID
        AidD = ixp.zerorank1()

        EidD = ixp.zerorank1()
        EidU = ixp.zerorank1()
        # Set the coordinate transformations:
        radial = sp.sqrt(x*x + y*y + z*z)
        polar = sp.atan2(sp.sqrt(x*x + y*y),z)
        EU_phi = 8*amp*radial*sp.sin(polar)*lam*lam*sp.exp(-lam*radial*radial)
        EidU[0] = -(y * EU_phi)/sp.sqrt(x*x + y*y)
        EidU[1] = (x * EU_phi)/sp.sqrt(x*x + y*y)
        # The z component (2)is zero.
        for i in range(DIM):
            for j in range(DIM):
                EidD[i] += gammaDD[i][j] * EidU[j]

        psi_ID = sp.sympify(0)
        if system == "System_II":
            global Gamma_ID
            Gamma_ID = sp.sympify(0)
    else:
        print("Invalid choice of system: System_to_use must be either System_I or System_II")
Ejemplo n.º 6
0
def BSSN_source_terms_for_BSSN_constraints(custom_T4UU=None):
    global sourceterm_H, sourceterm_MU

    # Step 4.a: Call BSSN_source_terms_ito_T4UU to get SDD, SD, S, & rho
    if custom_T4UU == "unrescaled BSSN source terms already given":
        SDD = ixp.declarerank2("SDD", "sym01")
        SD = ixp.declarerank1("SD")
        S = sp.symbols("S", real=True)
        rho = sp.symbols("rho", real=True)
    else:
        SDD, SD, S, rho = stress_energy_source_terms_ito_T4UU_and_ADM_or_BSSN_metricvars(
            "BSSN", custom_T4UU)
    PI = par.Cparameters("REAL", thismodule, ["PI"],
                         "3.14159265358979323846264338327950288")

    # Step 4.b: Add source term to the Hamiltonian constraint H
    sourceterm_H = -16 * PI * rho

    # Step 4.c: Add source term to the momentum constraint M^i
    # Step 4.c.i: Compute gammaUU in terms of BSSN quantities
    import BSSN.ADM_in_terms_of_BSSN as AitoB
    AitoB.ADM_in_terms_of_BSSN()  # Provides gammaUU
    # Step 4.c.ii: Raise S_i
    SU = ixp.zerorank1()
    for i in range(3):
        for j in range(3):
            SU[i] += AitoB.gammaUU[i][j] * SD[j]
    # Step 4.c.iii: Add source term to momentum constraint & rescale:
    sourceterm_MU = ixp.zerorank1()
    for i in range(3):
        sourceterm_MU[i] = -8 * PI * SU[i] / rfm.ReU[i]
Ejemplo n.º 7
0
def TOV_ADM_T4UUmunu(ComputeADMT4UUmunuGlobalsOnly=False):
    global Sph_r_th_ph, r, th, ph, gammaSphDD, KSphDD, alphaSph, betaSphU, BSphU, T4UU

    # All gridfunctions will be written in terms of spherical coordinates (r, th, ph):
    r, th, ph = sp.symbols('r th ph', real=True)

    thismodule = "TOV"

    DIM = 3
    par.set_parval_from_str("grid::DIM", DIM)

    # Input parameters read in from the TOV data file:
    rbar, expnu, exp4phi, P, rho = par.Cparameters(
        "REAL", thismodule, ["rbar", "expnu", "exp4phi", "P", "rho"],
        [1e300, 1e300, 1e300, 1e300, 1e300])  # Must be read from TOV data
    # file; set to crazy values to ensure this
    # Step 4.2: Construct ADM quantities:

    # *** The physical spatial metric in spherical basis ***
    # In isotropic coordinates,
    #  gamma_{ij} = e^{4 phi} eta_{ij},
    # where eta is the flat-space 3-metric in spherical coordinates
    gammaSphDD = ixp.zerorank2()
    gammaSphDD[0][0] = exp4phi
    gammaSphDD[1][1] = exp4phi * rbar**2
    gammaSphDD[2][2] = exp4phi * rbar**2 * sp.sin(th)**2

    # *** The extrinsic curvature in spherical basis ***
    # K_{ij} = 0 for the TOV solution
    KSphDD = ixp.zerorank2()

    # *** The lapse and shift in spherical basis ***
    # alpha = exp^{nu/2} for the TOV solution
    # \beta^i = 0 for the TOV solution
    alphaSph = sp.sqrt(expnu)
    betaSphU = ixp.zerorank1()
    BSphU = ixp.zerorank1()

    # Step 4.3: Construct T^{mu nu}:
    T4UU = ixp.zerorank2(DIM=4)

    # T^tt = e^(-nu) * rho
    T4UU[0][0] = rho / expnu
    # T^{ii} = P / gamma_{ii}
    for i in range(3):
        T4UU[i + 1][i + 1] = P / gammaSphDD[i][i]

    if ComputeADMT4UUmunuGlobalsOnly == True:
        return

    Sph_r_th_ph = [r, th, ph]
    cf, hDD, lambdaU, aDD, trK, alpha, vetU, betU = \
        AtoB.Convert_Spherical_or_Cartesian_ADM_to_BSSN_curvilinear("Spherical", Sph_r_th_ph,
                                                                    gammaSphDD, KSphDD, alphaSph, betaSphU, BSphU)
    sDD, sD, S, rho = \
        AtoB.Convert_Spherical_or_Cartesian_T4UUmunu_to_BSSN_curvilinear("Spherical", Sph_r_th_ph, T4UU)

    global returnfunction
    returnfunction = bIDf.BSSN_ID_function_string(cf, hDD, lambdaU, aDD, trK,
                                                  alpha, vetU, betU)
Ejemplo n.º 8
0
def compute_u0_noif(gammaDD, alpha, ValenciavU):
    # Inputs:  Metric gammaDD, lapse alpha, Valencia 3-velocity ValenciavU
    # Outputs: u^0, speed-limited ValenciavU

    # R = gamma_{ij} v^i v^j
    R = par.Cparameters("#define", thismodule, "TINYDOUBLE", 1e-100)
    # We initialize R to TINYDOUBLE instead of 0 to avoid a 0/0 below,
    #    in the case that ValenciavU == 0 for all Valencia 3-velocities.
    # "Those tiny *doubles* make me warm all over
    #  with a feeling that I'm gonna love you till the end of time."
    #    - Adapted from Connie Francis' "Tiny Bubbles"
    for i in range(DIM):
        for j in range(DIM):
            R += gammaDD[i][j] * ValenciavU[i] * ValenciavU[j]

    # The default value isn't terribly important here, since we'll overwrite in the main C code
    GAMMA_SPEED_LIMIT = par.Cparameters("REAL", thismodule,
                                        "GAMMA_SPEED_LIMIT",
                                        10.0)  # Default value based on
    # IllinoisGRMHD.
    # GiRaFFE default = 2000.0
    # Rmax = 1 - 1/Gamma_{\max}^2
    Rmax = 1 - 1 / (GAMMA_SPEED_LIMIT * GAMMA_SPEED_LIMIT)
    # Now, we set Rmax = min(Rmax,R):
    # If Rmax>R, then Rmax = 0.5*(Rmax+R-Rmax+R) = R
    # If R>Rmax, then Rmax = 0.5*(Rmax+R+Rmax-R) = Rmax
    # If R==TINYDOUBLE, then Rmax = 0.5*(Rmax-Rmax) = 0, since, e.g., 10 +/- 1e-100 = 10 exactly in double precision
    Rmax = sp.Rational(1, 2) * (Rmax + R - sp.Abs(Rmax - R))

    # With our rescaled Rmax, v^i = sqrt{Rmax/R} v^i
    global rescaledValenciavU, rescaledu0

    rescaledValenciavU = ixp.zerorank1()
    for i in range(DIM):
        # If R == TINYDOUBLE, then Rmax=0,R=1e-100, and we get Rmax/R=0.
        #   If your velocities are of order 1e-100 and this is physically
        #   meaningful, there must be something wrong with your unit conversion.
        rescaledValenciavU[i] = ValenciavU[i] * sp.sqrt(Rmax / R)

    # We stick with the "rescaled" version since we redefine Rmax as detailed above
    # u^0 = 1/(alpha-sqrt(1-R_{\max}))
    rescaledu0 = 1 / (alpha * sp.sqrt(1 - Rmax))
Ejemplo n.º 9
0
def BSSN_source_terms_for_BSSN_RHSs(custom_T4UU=None):
    global sourceterm_trK_rhs, sourceterm_a_rhsDD, sourceterm_lambda_rhsU, sourceterm_Lambdabar_rhsU

    # Step 3.a: Call BSSN_source_terms_ito_T4UU to get SDD, SD, S, & rho

    if custom_T4UU == "unrescaled BSSN source terms already given":
        SDD = ixp.declarerank2("SDD", "sym01")
        SD = ixp.declarerank1("SD")
        S = sp.symbols("S", real=True)
        rho = sp.symbols("rho", real=True)
    else:
        SDD, SD, S, rho = stress_energy_source_terms_ito_T4UU_and_ADM_or_BSSN_metricvars(
            "BSSN", custom_T4UU)
    PI = par.Cparameters("REAL", thismodule, ["PI"],
                         "3.14159265358979323846264338327950288")
    alpha = sp.symbols("alpha", real=True)

    # Step 3.b: trK_rhs
    sourceterm_trK_rhs = 4 * PI * alpha * (rho + S)

    # Step 3.c: Abar_rhsDD:
    # Step 3.c.i: Compute trace-free part of S_{ij}:
    import BSSN.BSSN_quantities as Bq
    Bq.BSSN_basic_tensors()  # Sets gammabarDD
    gammabarUU, dummydet = ixp.symm_matrix_inverter3x3(
        Bq.gammabarDD)  # Set gammabarUU
    tracefree_SDD = ixp.zerorank2()
    for i in range(3):
        for j in range(3):
            tracefree_SDD[i][j] = SDD[i][j]
    for i in range(3):
        for j in range(3):
            for k in range(3):
                for m in range(3):
                    tracefree_SDD[i][j] += -sp.Rational(1, 3) * Bq.gammabarDD[
                        i][j] * gammabarUU[k][m] * SDD[k][m]
    # Step 3.c.ii: Define exp_m4phi = e^{-4 phi}
    Bq.phi_and_derivs()
    # Step 3.c.iii: Evaluate stress-energy part of AbarDD's RHS
    sourceterm_a_rhsDD = ixp.zerorank2()
    for i in range(3):
        for j in range(3):
            Abar_rhsDDij = -8 * PI * alpha * Bq.exp_m4phi * tracefree_SDD[i][j]
            sourceterm_a_rhsDD[i][j] = Abar_rhsDDij / rfm.ReDD[i][j]

    # Step 3.d: Stress-energy part of Lambdabar_rhsU = stressenergy_Lambdabar_rhsU
    sourceterm_Lambdabar_rhsU = ixp.zerorank1()
    for i in range(3):
        for j in range(3):
            sourceterm_Lambdabar_rhsU[
                i] += -16 * PI * alpha * gammabarUU[i][j] * SD[j]
    sourceterm_lambda_rhsU = ixp.zerorank1()
    for i in range(3):
        sourceterm_lambda_rhsU[i] = sourceterm_Lambdabar_rhsU[i] / rfm.ReU[i]
Ejemplo n.º 10
0
def generate_C_code_for_Stilde_flux(out_dir,inputs_provided = False, alpha_face=None, gamma_faceDD=None, beta_faceU=None,
                                    Valenciav_rU=None, B_rU=None, Valenciav_lU=None, B_lU=None, sqrt4pi=None,
                                    outCparams = "outCverbose=False,CSE_sorting=none"):
    if not inputs_provided:
        # We will pass values of the gridfunction on the cell faces into the function. This requires us
        # to declare them as C parameters in NRPy+. We will denote this with the _face infix/suffix.
        alpha_face = gri.register_gridfunctions("AUXEVOL","alpha_face")
        gamma_faceDD = ixp.register_gridfunctions_for_single_rank2("AUXEVOL","gamma_faceDD","sym01")
        beta_faceU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL","beta_faceU")

        # We'll need some more gridfunctions, now, to represent the reconstructions of BU and ValenciavU
        # on the right and left faces
        Valenciav_rU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL","Valenciav_rU",DIM=3)
        B_rU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL","B_rU",DIM=3)
        Valenciav_lU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL","Valenciav_lU",DIM=3)
        B_lU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL","B_lU",DIM=3)
        sqrt4pi = par.Cparameters("REAL",thismodule,"sqrt4pi","sqrt(4.0*M_PI)")

    for flux_dirn in range(3):
        calculate_Stilde_flux(flux_dirn,alpha_face,gamma_faceDD,beta_faceU,\
                              Valenciav_rU,B_rU,Valenciav_lU,B_lU,sqrt4pi)
        Stilde_flux_to_print = [\
                                Stilde_fluxD[0],\
                                Stilde_fluxD[1],\
                                Stilde_fluxD[2],\
                               ]
        Stilde_flux_names = [\
                             "Stilde_fluxD0",\
                             "Stilde_fluxD1",\
                             "Stilde_fluxD2",\
                            ]

        desc = "Compute the flux of all 3 components of tilde{S}_i on the right face in the " + str(flux_dirn) + "."
        name = "calculate_Stilde_flux_D" + str(flux_dirn) + "_right"
        outCfunction(
            outfile  = os.path.join(out_dir,name+".h"), desc=desc, name=name,
            params   ="const paramstruct *params,const REAL *auxevol_gfs,REAL *rhs_gfs",
            body     =  Memory_Read \
                       +outputC(Stilde_flux_to_print,Stilde_flux_names,"returnstring",params=outCparams).replace("IDX4","IDX4S")\
                       +Memory_Write.replace(invdx[0],invdx[flux_dirn]),
            loopopts ="InteriorPoints",
            rel_path_for_Cparams=os.path.join("../"))

        desc = "Compute the flux of all 3 components of tilde{S}_i on the left face in the " + str(flux_dirn) + "."
        name = "calculate_Stilde_flux_D" + str(flux_dirn) + "_left"
        outCfunction(
            outfile  = os.path.join(out_dir,name+".h"), desc=desc, name=name,
            params   ="const paramstruct *params,const REAL *auxevol_gfs,REAL *rhs_gfs",
            body     =  Memory_Read.replace(indices[flux_dirn],indicesp1[flux_dirn]) \
                       +outputC(Stilde_flux_to_print,Stilde_flux_names,"returnstring",params=outCparams).replace("IDX4","IDX4S")\
                       +Memory_Write.replace(invdx[0],invdx[flux_dirn]).replace(assignment,assignmentp1),
            loopopts ="InteriorPoints",
            rel_path_for_Cparams=os.path.join("../"))
Ejemplo n.º 11
0
def InitialData_PlaneWave():
    # Step 1: Set parameters defined in other modules
    wavespeed = swrhs.wavespeed
    DIM = par.parval_from_str("grid::DIM")
    xx = gri.xx

    # Step 2: Declare free parameters intrinsic to these initial data
    time = par.Cparameters("REAL", thismodule, "time")
    kk = par.Cparameters("REAL", thismodule, ["kk0", "kk1", "kk2"])

    #  Step 3: Normalize the k vector
    kk_norm = sp.sqrt(kk[0]**2 + kk[1]**2 + kk[2]**2)

    # Step 4: Compute k.x
    dot_product = sp.sympify(0)
    for i in range(DIM):
        dot_product += xx[i] * kk[i]
    dot_product /= kk_norm

    # Step 5: Set initial data for uu and vv, where vv_ID = \partial_t uu_ID.
    global uu_ID, vv_ID
    uu_ID = sp.sin(dot_product - wavespeed * time) + 2
    vv_ID = sp.diff(uu_ID, time)
def GiRaFFEfood_NRPy_1D_tests(ID_type="DegenAlfvenWave", stagger_enable=False):
    global AD, ValenciaVU
    AD = ixp.zerorank1()
    if ID_type == "DegenAlfvenWave":
        mu_DAW = par.Cparameters("REAL", thismodule, ["mu_DAW"],
                                 -0.5)  # The wave speed
        AD = Axyz_func(Ax_DAW,
                       Ay_DAW,
                       Az_DAW,
                       stagger_enable,
                       gammamu=sp.sympify(1) /
                       sp.sqrt(sp.sympify(1) - mu_AW**2))
        ValenciaVU = ValenciavU_DAW(mu_DAW=mu_DAW, gammamu=gammamu)
    elif ID_type == "FastWave":
        AD = Axyz_func(Ax_FW, Ay_FW, Az_FW, stagger_enable)
        ValenciaVU = ValenciavU_FW()
def add_to_Cfunction_dict__AD_gauge_term_psi6Phi_fin_diff(includes=None):
    xi_damping = par.Cparameters("REAL",thismodule,"xi_damping",0.1)
    GRFFE.compute_psi6Phi_rhs_damping_term(alpha,psi6Phi,xi_damping)

    AevolParen_dD = ixp.declarerank1("AevolParen_dD",DIM=3)
    PhievolParenU_dD = ixp.declarerank2("PhievolParenU_dD","nosym",DIM=3)

    A_rhsD = ixp.zerorank1()
    psi6Phi_rhs = GRFFE.psi6Phi_damping

    for i in range(3):
        A_rhsD[i] += -AevolParen_dD[i]
        psi6Phi_rhs += -PhievolParenU_dD[i][i]

    # Add Kreiss-Oliger dissipation to the GRFFE RHSs:
    # psi6Phi_dKOD = ixp.declarerank1("psi6Phi_dKOD")
    # AD_dKOD    = ixp.declarerank2("AD_dKOD","nosym")
    # for i in range(3):
    #     psi6Phi_rhs += diss_strength*psi6Phi_dKOD[i]*rfm.ReU[i] # ReU[i] = 1/scalefactor_orthog_funcform[i]
    #     for j in range(3):
    #         A_rhsD[j] += diss_strength*AD_dKOD[j][i]*rfm.ReU[i] # ReU[i] = 1/scalefactor_orthog_funcform[i]

    RHSs_to_print = [
                     lhrh(lhs=gri.gfaccess("rhs_gfs","AD0"),rhs=A_rhsD[0]),
                     lhrh(lhs=gri.gfaccess("rhs_gfs","AD1"),rhs=A_rhsD[1]),
                     lhrh(lhs=gri.gfaccess("rhs_gfs","AD2"),rhs=A_rhsD[2]),
                     lhrh(lhs=gri.gfaccess("rhs_gfs","psi6Phi"),rhs=psi6Phi_rhs),
                    ]

    desc = "Calculate AD gauge term and psi6Phi RHSs"
    name = "calculate_AD_gauge_psi6Phi_RHSs"
    params ="const paramstruct *params,const REAL *in_gfs,const REAL *auxevol_gfs,REAL *rhs_gfs"
    body     = fin.FD_outputC("returnstring",RHSs_to_print,params=outCparams)
    loopopts ="InteriorPoints"
    add_to_Cfunction_dict(
        includes=includes,
        desc=desc,
        name=name, params=params,
        body=body, loopopts=loopopts)
    outC_function_dict[name] = outC_function_dict[name].replace("= NGHOSTS","= NGHOSTS_A2B").replace("NGHOSTS+Nxx0","Nxx_plus_2NGHOSTS0-NGHOSTS_A2B").replace("NGHOSTS+Nxx1","Nxx_plus_2NGHOSTS1-NGHOSTS_A2B").replace("NGHOSTS+Nxx2","Nxx_plus_2NGHOSTS2-NGHOSTS_A2B")
Ejemplo n.º 14
0
def calculate_Stilde_flux(flux_dirn,inputs_provided=True,alpha_face=None,gamma_faceDD=None,beta_faceU=None,\
                          Valenciav_rU=None,B_rU=None,Valenciav_lU=None,B_lU=None,sqrt4pi=None):
    if not inputs_provided:
        # We will pass values of the gridfunction on the cell faces into the function. This requires us
        # to declare them as C parameters in NRPy+. We will denote this with the _face infix/suffix.
        alpha_face = gri.register_gridfunctions("AUXEVOL", "alpha_face")
        gamma_faceDD = ixp.register_gridfunctions_for_single_rank2(
            "AUXEVOL", "gamma_faceDD", "sym01")
        beta_faceU = ixp.register_gridfunctions_for_single_rank1(
            "AUXEVOL", "beta_faceU")

        # We'll need some more gridfunctions, now, to represent the reconstructions of BU and ValenciavU
        # on the right and left faces
        Valenciav_rU = ixp.register_gridfunctions_for_single_rank1(
            "AUXEVOL", "Valenciav_rU", DIM=3)
        B_rU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                           "B_rU",
                                                           DIM=3)
        Valenciav_lU = ixp.register_gridfunctions_for_single_rank1(
            "AUXEVOL", "Valenciav_lU", DIM=3)
        B_lU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                           "B_lU",
                                                           DIM=3)
        sqrt4pi = par.Cparameters("REAL", thismodule, "sqrt4pi",
                                  "sqrt(4.0*M_PI)")

    find_cmax_cmin(flux_dirn, gamma_faceDD, beta_faceU, alpha_face)

    global Stilde_fluxD
    Stilde_fluxD = ixp.zerorank3()
    for mom_comp in range(3):
        calculate_GRFFE_Tmunu_and_contractions(flux_dirn, mom_comp, gamma_faceDD,beta_faceU,alpha_face,\
                                               Valenciav_rU,B_rU,sqrt4pi)
        Fr = F
        Ur = U
        calculate_GRFFE_Tmunu_and_contractions(flux_dirn, mom_comp, gamma_faceDD,beta_faceU,alpha_face,\
                                               Valenciav_lU,B_lU,sqrt4pi)
        Fl = F
        Ul = U
        Stilde_fluxD[mom_comp] = HLLE_solver(cmax, cmin, Fr, Fl, Ur, Ul)
Ejemplo n.º 15
0
# License: BSD 2-Clause

# COMPLETE DOCUMENTATION (JUPYTER NOTEBOOKS):
# START PAGE (start here!):  ../NRPy+_Tutorial.ipynb
# THIS MODULE: ../Tutorial-VacuumMaxwell_Flat_Cartesian_ID.ipynb

# Step P1: Import needed NRPy+ core modules:
import NRPy_param_funcs as par  # NRPy+: Parameter interface

# The name of this module ("CommonParams") is given by __name__:
thismodule = __name__

# Parameters common to/needed by all VacuumMaxwell Python modules

# Step P2: Define the C parameters amp, lam, time, and wavespeed.
#          These variables proper SymPy variables, so they can be
#          used in SymPy expressions. In the C code, it acts
#          just like a usual parameter, whose value is
#          specified in the parameter file.

# amplitude
amp = par.Cparameters("REAL", thismodule, "amp", default_vals=1.0)

# lambda
lam = par.Cparameters("REAL", thismodule, "lam", default_vals=1.0)

time = par.Cparameters("REAL", thismodule, "time", default_vals=0.0)

wavespeed = par.Cparameters("REAL", thismodule, "wavespeed", default_vals=1.0)
Ejemplo n.º 16
0
def GiRaFFE_NRPy_Main_Driver_generate_all(out_dir):
    cmd.mkdir(out_dir)

    gammaDD = ixp.register_gridfunctions_for_single_rank2("AUXEVOL",
                                                          "gammaDD",
                                                          "sym01",
                                                          DIM=3)
    betaU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                        "betaU",
                                                        DIM=3)
    alpha = gri.register_gridfunctions("AUXEVOL", "alpha")
    AD = ixp.register_gridfunctions_for_single_rank1("EVOL", "AD")
    BU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL", "BU")
    ValenciavU = ixp.register_gridfunctions_for_single_rank1(
        "AUXEVOL", "ValenciavU")
    psi6Phi = gri.register_gridfunctions("EVOL", "psi6Phi")
    StildeD = ixp.register_gridfunctions_for_single_rank1("EVOL", "StildeD")

    ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                "PhievolParenU",
                                                DIM=3)
    gri.register_gridfunctions("AUXEVOL", "AevolParen")

    # Declare this symbol:
    sqrt4pi = par.Cparameters("REAL", thismodule, "sqrt4pi", "sqrt(4.0*M_PI)")

    GRHD.compute_sqrtgammaDET(gammaDD)
    GRFFE.compute_AD_source_term_operand_for_FD(GRHD.sqrtgammaDET, betaU,
                                                alpha, psi6Phi, AD)
    GRFFE.compute_psi6Phi_rhs_flux_term_operand(gammaDD, GRHD.sqrtgammaDET,
                                                betaU, alpha, AD, psi6Phi)

    parens_to_print = [\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","AevolParen"),rhs=GRFFE.AevolParen),\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","PhievolParenU0"),rhs=GRFFE.PhievolParenU[0]),\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","PhievolParenU1"),rhs=GRFFE.PhievolParenU[1]),\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","PhievolParenU2"),rhs=GRFFE.PhievolParenU[2]),\
                      ]

    subdir = "RHSs"
    cmd.mkdir(os.path.join(out_dir, subdir))
    desc = "Calculate quantities to be finite-differenced for the GRFFE RHSs"
    name = "calculate_AD_gauge_term_psi6Phi_flux_term_for_RHSs"
    outCfunction(
        outfile=os.path.join(out_dir, subdir, name + ".h"),
        desc=desc,
        name=name,
        params=
        "const paramstruct *restrict params,const REAL *restrict in_gfs,REAL *restrict auxevol_gfs",
        body=fin.FD_outputC("returnstring", parens_to_print,
                            params=outCparams).replace("IDX4", "IDX4S"),
        loopopts="AllPoints",
        rel_path_for_Cparams=os.path.join("../"))

    xi_damping = par.Cparameters("REAL", thismodule, "xi_damping", 0.1)
    GRFFE.compute_psi6Phi_rhs_damping_term(alpha, psi6Phi, xi_damping)

    AevolParen_dD = ixp.declarerank1("AevolParen_dD", DIM=3)
    PhievolParenU_dD = ixp.declarerank2("PhievolParenU_dD", "nosym", DIM=3)

    A_rhsD = ixp.zerorank1()
    psi6Phi_rhs = GRFFE.psi6Phi_damping

    for i in range(3):
        A_rhsD[i] += -AevolParen_dD[i]
        psi6Phi_rhs += -PhievolParenU_dD[i][i]

    # Add Kreiss-Oliger dissipation to the GRFFE RHSs:
#     psi6Phi_dKOD = ixp.declarerank1("psi6Phi_dKOD")
#     AD_dKOD    = ixp.declarerank2("AD_dKOD","nosym")
#     for i in range(3):
#         psi6Phi_rhs += diss_strength*psi6Phi_dKOD[i]*rfm.ReU[i] # ReU[i] = 1/scalefactor_orthog_funcform[i]
#         for j in range(3):
#             A_rhsD[j] += diss_strength*AD_dKOD[j][i]*rfm.ReU[i] # ReU[i] = 1/scalefactor_orthog_funcform[i]

    RHSs_to_print = [\
                     lhrh(lhs=gri.gfaccess("rhs_gfs","AD0"),rhs=A_rhsD[0]),\
                     lhrh(lhs=gri.gfaccess("rhs_gfs","AD1"),rhs=A_rhsD[1]),\
                     lhrh(lhs=gri.gfaccess("rhs_gfs","AD2"),rhs=A_rhsD[2]),\
                     lhrh(lhs=gri.gfaccess("rhs_gfs","psi6Phi"),rhs=psi6Phi_rhs),\
                    ]

    desc = "Calculate AD gauge term and psi6Phi RHSs"
    name = "calculate_AD_gauge_psi6Phi_RHSs"
    source_Ccode = outCfunction(
        outfile="returnstring",
        desc=desc,
        name=name,
        params=
        "const paramstruct *params,const REAL *in_gfs,const REAL *auxevol_gfs,REAL *rhs_gfs",
        body=fin.FD_outputC("returnstring", RHSs_to_print,
                            params=outCparams).replace("IDX4", "IDX4S"),
        loopopts="InteriorPoints",
        rel_path_for_Cparams=os.path.join("../")).replace(
            "= NGHOSTS", "= NGHOSTS_A2B").replace(
                "NGHOSTS+Nxx0", "Nxx_plus_2NGHOSTS0-NGHOSTS_A2B").replace(
                    "NGHOSTS+Nxx1", "Nxx_plus_2NGHOSTS1-NGHOSTS_A2B").replace(
                        "NGHOSTS+Nxx2", "Nxx_plus_2NGHOSTS2-NGHOSTS_A2B")
    # Note the above .replace() functions. These serve to expand the loop range into the ghostzones, since
    # the second-order FD needs fewer than some other algorithms we use do.
    with open(os.path.join(out_dir, subdir, name + ".h"), "w") as file:
        file.write(source_Ccode)

    source.write_out_functions_for_StildeD_source_term(
        os.path.join(out_dir, subdir), outCparams, gammaDD, betaU, alpha,
        ValenciavU, BU, sqrt4pi)

    subdir = "FCVAL"
    cmd.mkdir(os.path.join(out_dir, subdir))
    FCVAL.GiRaFFE_NRPy_FCVAL(os.path.join(out_dir, subdir))

    subdir = "PPM"
    cmd.mkdir(os.path.join(out_dir, subdir))
    PPM.GiRaFFE_NRPy_PPM(os.path.join(out_dir, subdir))

    # We will pass values of the gridfunction on the cell faces into the function. This requires us
    # to declare them as C parameters in NRPy+. We will denote this with the _face infix/suffix.
    alpha_face = gri.register_gridfunctions("AUXEVOL", "alpha_face")
    gamma_faceDD = ixp.register_gridfunctions_for_single_rank2(
        "AUXEVOL", "gamma_faceDD", "sym01")
    beta_faceU = ixp.register_gridfunctions_for_single_rank1(
        "AUXEVOL", "beta_faceU")

    # We'll need some more gridfunctions, now, to represent the reconstructions of BU and ValenciavU
    # on the right and left faces
    Valenciav_rU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                               "Valenciav_rU",
                                                               DIM=3)
    B_rU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                       "B_rU",
                                                       DIM=3)
    Valenciav_lU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                               "Valenciav_lU",
                                                               DIM=3)
    B_lU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                       "B_lU",
                                                       DIM=3)

    subdir = "RHSs"
    Af.GiRaFFE_NRPy_Afield_flux(os.path.join(out_dir, subdir))
    Sf.generate_C_code_for_Stilde_flux(os.path.join(out_dir,
                                                    subdir), True, alpha_face,
                                       gamma_faceDD, beta_faceU, Valenciav_rU,
                                       B_rU, Valenciav_lU, B_lU, sqrt4pi)

    subdir = "boundary_conditions"
    cmd.mkdir(os.path.join(out_dir, subdir))
    BC.GiRaFFE_NRPy_BCs(os.path.join(out_dir, subdir))

    subdir = "A2B"
    cmd.mkdir(os.path.join(out_dir, subdir))
    A2B.GiRaFFE_NRPy_A2B(os.path.join(out_dir, subdir), gammaDD, AD, BU)

    C2P_P2C.GiRaFFE_NRPy_C2P(StildeD, BU, gammaDD, betaU, alpha)

    values_to_print = [\
                       lhrh(lhs=gri.gfaccess("in_gfs","StildeD0"),rhs=C2P_P2C.outStildeD[0]),\
                       lhrh(lhs=gri.gfaccess("in_gfs","StildeD1"),rhs=C2P_P2C.outStildeD[1]),\
                       lhrh(lhs=gri.gfaccess("in_gfs","StildeD2"),rhs=C2P_P2C.outStildeD[2]),\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","ValenciavU0"),rhs=C2P_P2C.ValenciavU[0]),\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","ValenciavU1"),rhs=C2P_P2C.ValenciavU[1]),\
                       lhrh(lhs=gri.gfaccess("auxevol_gfs","ValenciavU2"),rhs=C2P_P2C.ValenciavU[2])\
                      ]

    subdir = "C2P"
    cmd.mkdir(os.path.join(out_dir, subdir))
    desc = "Apply fixes to \tilde{S}_i and recompute the velocity to match with current sheet prescription."
    name = "GiRaFFE_NRPy_cons_to_prims"
    outCfunction(
        outfile=os.path.join(out_dir, subdir, name + ".h"),
        desc=desc,
        name=name,
        params=
        "const paramstruct *params,REAL *xx[3],REAL *auxevol_gfs,REAL *in_gfs",
        body=fin.FD_outputC("returnstring", values_to_print,
                            params=outCparams).replace("IDX4", "IDX4S"),
        loopopts="AllPoints,Read_xxs",
        rel_path_for_Cparams=os.path.join("../"))

    C2P_P2C.GiRaFFE_NRPy_P2C(gammaDD, betaU, alpha, ValenciavU, BU, sqrt4pi)

    values_to_print = [\
                       lhrh(lhs=gri.gfaccess("in_gfs","StildeD0"),rhs=C2P_P2C.StildeD[0]),\
                       lhrh(lhs=gri.gfaccess("in_gfs","StildeD1"),rhs=C2P_P2C.StildeD[1]),\
                       lhrh(lhs=gri.gfaccess("in_gfs","StildeD2"),rhs=C2P_P2C.StildeD[2]),\
                      ]

    desc = "Recompute StildeD after current sheet fix to Valencia 3-velocity to ensure consistency between conservative & primitive variables."
    name = "GiRaFFE_NRPy_prims_to_cons"
    outCfunction(
        outfile=os.path.join(out_dir, subdir, name + ".h"),
        desc=desc,
        name=name,
        params="const paramstruct *params,REAL *auxevol_gfs,REAL *in_gfs",
        body=fin.FD_outputC("returnstring", values_to_print,
                            params=outCparams).replace("IDX4", "IDX4S"),
        loopopts="AllPoints",
        rel_path_for_Cparams=os.path.join("../"))

    # Write out the main driver itself:
    with open(os.path.join(out_dir, "GiRaFFE_NRPy_Main_Driver.h"),
              "w") as file:
        file.write(r"""// Structure to track ghostzones for PPM:
typedef struct __gf_and_gz_struct__ {
  REAL *gf;
  int gz_lo[4],gz_hi[4];
} gf_and_gz_struct;
// Some additional constants needed for PPM:
const int VX=0,VY=1,VZ=2,BX=3,BY=4,BZ=5;
const int NUM_RECONSTRUCT_GFS = 6;

// Include ALL functions needed for evolution
#include "RHSs/calculate_AD_gauge_term_psi6Phi_flux_term_for_RHSs.h"
#include "RHSs/calculate_AD_gauge_psi6Phi_RHSs.h"
#include "PPM/reconstruct_set_of_prims_PPM_GRFFE_NRPy.c"
#include "FCVAL/interpolate_metric_gfs_to_cell_faces.h"
#include "RHSs/calculate_StildeD0_source_term.h"
#include "RHSs/calculate_StildeD1_source_term.h"
#include "RHSs/calculate_StildeD2_source_term.h"
#include "../calculate_E_field_flat_all_in_one.h"
#include "RHSs/calculate_Stilde_flux_D0.h"
#include "RHSs/calculate_Stilde_flux_D1.h"
#include "RHSs/calculate_Stilde_flux_D2.h"
#include "boundary_conditions/GiRaFFE_boundary_conditions.h"
#include "A2B/driver_AtoB.h"
#include "C2P/GiRaFFE_NRPy_cons_to_prims.h"
#include "C2P/GiRaFFE_NRPy_prims_to_cons.h"

void override_BU_with_old_GiRaFFE(const paramstruct *restrict params,REAL *restrict auxevol_gfs,const int n) {
#include "set_Cparameters.h"
    char filename[100];
    sprintf(filename,"BU0_override-%08d.bin",n);
    FILE *out2D = fopen(filename, "rb");
    fread(auxevol_gfs+BU0GF*Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2,
          sizeof(double),Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2,out2D);
    fclose(out2D);
    sprintf(filename,"BU1_override-%08d.bin",n);
    out2D = fopen(filename, "rb");
    fread(auxevol_gfs+BU1GF*Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2,
          sizeof(double),Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2,out2D);
    fclose(out2D);
    sprintf(filename,"BU2_override-%08d.bin",n);
    out2D = fopen(filename, "rb");
    fread(auxevol_gfs+BU2GF*Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2,
          sizeof(double),Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2,out2D);
    fclose(out2D);
}

void GiRaFFE_NRPy_RHSs(const paramstruct *restrict params,REAL *restrict auxevol_gfs,const REAL *restrict in_gfs,REAL *restrict rhs_gfs) {
#include "set_Cparameters.h"
    // First thing's first: initialize the RHSs to zero!
#pragma omp parallel for
    for(int ii=0;ii<Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2*NUM_EVOL_GFS;ii++) {
        rhs_gfs[ii] = 0.0;
    }
    // Next calculate the easier source terms that don't require flux directions
    // This will also reset the RHSs for each gf at each new timestep.
    calculate_AD_gauge_term_psi6Phi_flux_term_for_RHSs(params,in_gfs,auxevol_gfs);
    calculate_AD_gauge_psi6Phi_RHSs(params,in_gfs,auxevol_gfs,rhs_gfs);

    // Now, we set up a bunch of structs of pointers to properly guide the PPM algorithm.
    // They also count the number of ghostzones available.
    gf_and_gz_struct in_prims[NUM_RECONSTRUCT_GFS], out_prims_r[NUM_RECONSTRUCT_GFS], out_prims_l[NUM_RECONSTRUCT_GFS];
    int which_prims_to_reconstruct[NUM_RECONSTRUCT_GFS],num_prims_to_reconstruct;
    const int Nxxp2NG012 = Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2;

    REAL *temporary = auxevol_gfs + Nxxp2NG012*AEVOLPARENGF; //We're not using this anymore
    // This sets pointers to the portion of auxevol_gfs containing the relevant gridfunction.
    int ww=0;
    in_prims[ww].gf      = auxevol_gfs + Nxxp2NG012*VALENCIAVU0GF;
      out_prims_r[ww].gf = auxevol_gfs + Nxxp2NG012*VALENCIAV_RU0GF;
      out_prims_l[ww].gf = auxevol_gfs + Nxxp2NG012*VALENCIAV_LU0GF;
    ww++;
    in_prims[ww].gf      = auxevol_gfs + Nxxp2NG012*VALENCIAVU1GF;
      out_prims_r[ww].gf = auxevol_gfs + Nxxp2NG012*VALENCIAV_RU1GF;
      out_prims_l[ww].gf = auxevol_gfs + Nxxp2NG012*VALENCIAV_LU1GF;
    ww++;
    in_prims[ww].gf      = auxevol_gfs + Nxxp2NG012*VALENCIAVU2GF;
      out_prims_r[ww].gf = auxevol_gfs + Nxxp2NG012*VALENCIAV_RU2GF;
      out_prims_l[ww].gf = auxevol_gfs + Nxxp2NG012*VALENCIAV_LU2GF;
    ww++;
    in_prims[ww].gf      = auxevol_gfs + Nxxp2NG012*BU0GF;
      out_prims_r[ww].gf = auxevol_gfs + Nxxp2NG012*B_RU0GF;
      out_prims_l[ww].gf = auxevol_gfs + Nxxp2NG012*B_LU0GF;
    ww++;
    in_prims[ww].gf      = auxevol_gfs + Nxxp2NG012*BU1GF;
      out_prims_r[ww].gf = auxevol_gfs + Nxxp2NG012*B_RU1GF;
      out_prims_l[ww].gf = auxevol_gfs + Nxxp2NG012*B_LU1GF;
    ww++;
    in_prims[ww].gf      = auxevol_gfs + Nxxp2NG012*BU2GF;
      out_prims_r[ww].gf = auxevol_gfs + Nxxp2NG012*B_RU2GF;
      out_prims_l[ww].gf = auxevol_gfs + Nxxp2NG012*B_LU2GF;
    ww++;

    // Prims are defined AT ALL GRIDPOINTS, so we set the # of ghostzones to zero:
    for(int i=0;i<NUM_RECONSTRUCT_GFS;i++) for(int j=1;j<=3;j++) { in_prims[i].gz_lo[j]=0; in_prims[i].gz_hi[j]=0; }
    // Left/right variables are not yet defined, yet we set the # of gz's to zero by default:
    for(int i=0;i<NUM_RECONSTRUCT_GFS;i++) for(int j=1;j<=3;j++) { out_prims_r[i].gz_lo[j]=0; out_prims_r[i].gz_hi[j]=0; }
    for(int i=0;i<NUM_RECONSTRUCT_GFS;i++) for(int j=1;j<=3;j++) { out_prims_l[i].gz_lo[j]=0; out_prims_l[i].gz_hi[j]=0; }

    ww=0;
    which_prims_to_reconstruct[ww]=VX; ww++;
    which_prims_to_reconstruct[ww]=VY; ww++;
    which_prims_to_reconstruct[ww]=VZ; ww++;
    which_prims_to_reconstruct[ww]=BX; ww++;
    which_prims_to_reconstruct[ww]=BY; ww++;
    which_prims_to_reconstruct[ww]=BZ; ww++;
    num_prims_to_reconstruct=ww;

    // In each direction, perform the PPM reconstruction procedure.
    // Then, add the fluxes to the RHS as appropriate.
    for(int flux_dirn=0;flux_dirn<3;flux_dirn++) {
        // In each direction, interpolate the metric gfs (gamma,beta,alpha) to cell faces.
        interpolate_metric_gfs_to_cell_faces(params,auxevol_gfs,flux_dirn+1);
        // Then, reconstruct the primitive variables on the cell faces.
        // This function is housed in the file: "reconstruct_set_of_prims_PPM_GRFFE_NRPy.c"
        reconstruct_set_of_prims_PPM_GRFFE_NRPy(params, auxevol_gfs, flux_dirn+1, num_prims_to_reconstruct,
                                                which_prims_to_reconstruct, in_prims, out_prims_r, out_prims_l, temporary);
        // For example, if flux_dirn==0, then at gamma_faceDD00(i,j,k) represents gamma_{xx}
        // at (i-1/2,j,k), Valenciav_lU0(i,j,k) is the x-component of the velocity at (i-1/2-epsilon,j,k),
        // and Valenciav_rU0(i,j,k) is the x-component of the velocity at (i-1/2+epsilon,j,k).

        if(flux_dirn==0) {
            // Next, we calculate the source term for StildeD. Again, this also resets the rhs_gfs array at
            // each new timestep.
            calculate_StildeD0_source_term(params,auxevol_gfs,rhs_gfs);
            // Now, compute the electric field on each face of a cell and add it to the RHSs as appropriate
            //calculate_E_field_D0_right(params,auxevol_gfs,rhs_gfs);
            //calculate_E_field_D0_left(params,auxevol_gfs,rhs_gfs);
            // Finally, we calculate the flux of StildeD and add the appropriate finite-differences
            // to the RHSs.
            calculate_Stilde_flux_D0(params,auxevol_gfs,rhs_gfs);
        }
        else if(flux_dirn==1) {
            calculate_StildeD1_source_term(params,auxevol_gfs,rhs_gfs);
            //calculate_E_field_D1_right(params,auxevol_gfs,rhs_gfs);
            //calculate_E_field_D1_left(params,auxevol_gfs,rhs_gfs);
            calculate_Stilde_flux_D1(params,auxevol_gfs,rhs_gfs);
        }
        else {
            calculate_StildeD2_source_term(params,auxevol_gfs,rhs_gfs);
            //calculate_E_field_D2_right(params,auxevol_gfs,rhs_gfs);
            //calculate_E_field_D2_left(params,auxevol_gfs,rhs_gfs);
            calculate_Stilde_flux_D2(params,auxevol_gfs,rhs_gfs);
        }
        for(int count=0;count<=1;count++) {
            // This function is written to be general, using notation that matches the forward permutation added to AD2,
            // i.e., [F_HLL^x(B^y)]_z corresponding to flux_dirn=0, count=1.
            // The SIGN parameter is necessary because
            // -E_z(x_i,y_j,z_k) = 0.25 ( [F_HLL^x(B^y)]_z(i+1/2,j,k)+[F_HLL^x(B^y)]_z(i-1/2,j,k)
            //                           -[F_HLL^y(B^x)]_z(i,j+1/2,k)-[F_HLL^y(B^x)]_z(i,j-1/2,k) )
            // Note the negative signs on the reversed permutation terms!

            // By cyclically permuting with flux_dirn, we
            // get contributions to the other components, and by incrementing count, we get the backward permutations:
            // Let's suppose flux_dirn = 0. Then we will need to update Ay (count=0) and Az (count=1):
            //     flux_dirn=count=0 -> AD0GF+(flux_dirn+1+count)%3 = AD0GF + (0+1+0)%3=AD1GF <- Updating Ay!
            //        (flux_dirn)%3 = (0)%3 = 0               Vx
            //        (flux_dirn-count+2)%3 = (0-0+2)%3 = 2   Vz .  Inputs Vx, Vz -> SIGN = -1 ; 2.0*((REAL)count)-1.0=-1 check!
            //     flux_dirn=0,count=1 -> AD0GF+(flux_dirn+1+count)%3 = AD0GF + (0+1+1)%3=AD2GF <- Updating Az!
            //        (flux_dirn)%3 = (0)%3 = 0               Vx
            //        (flux_dirn-count+2)%3 = (0-1+2)%3 = 1   Vy .  Inputs Vx, Vy -> SIGN = +1 ; 2.0*((REAL)count)-1.0=2-1=+1 check!
            // Let's suppose flux_dirn = 1. Then we will need to update Az (count=0) and Ax (count=1):
            //     flux_dirn=1,count=0 -> AD0GF+(flux_dirn+1+count)%3 = AD0GF + (1+1+0)%3=AD2GF <- Updating Az!
            //        (flux_dirn)%3 = (1)%3 = 1               Vy
            //        (flux_dirn-count+2)%3 = (1-0+2)%3 = 0   Vx .  Inputs Vy, Vx -> SIGN = -1 ; 2.0*((REAL)count)-1.0=-1 check!
            //     flux_dirn=count=1 -> AD0GF+(flux_dirn+1+count)%3 = AD0GF + (1+1+1)%3=AD0GF <- Updating Ax!
            //        (flux_dirn)%3 = (1)%3 = 1               Vy
            //        (flux_dirn-count+2)%3 = (1-1+2)%3 = 2   Vz .  Inputs Vy, Vz -> SIGN = +1 ; 2.0*((REAL)count)-1.0=2-1=+1 check!
            // Let's suppose flux_dirn = 2. Then we will need to update Ax (count=0) and Ay (count=1):
            //     flux_dirn=2,count=0 -> AD0GF+(flux_dirn+1+count)%3 = AD0GF + (2+1+0)%3=AD0GF <- Updating Ax!
            //        (flux_dirn)%3 = (2)%3 = 2               Vz
            //        (flux_dirn-count+2)%3 = (2-0+2)%3 = 1   Vy .  Inputs Vz, Vy -> SIGN = -1 ; 2.0*((REAL)count)-1.0=-1 check!
            //     flux_dirn=2,count=1 -> AD0GF+(flux_dirn+1+count)%3 = AD0GF + (2+1+1)%3=AD1GF <- Updating Ay!
            //        (flux_dirn)%3 = (2)%3 = 2               Vz
            //        (flux_dirn-count+2)%3 = (2-1+2)%3 = 0   Vx .  Inputs Vz, Vx -> SIGN = +1 ; 2.0*((REAL)count)-1.0=2-1=+1 check!
            calculate_E_field_flat_all_in_one(params,
              &auxevol_gfs[IDX4ptS(VALENCIAV_RU0GF+(flux_dirn)%3, 0)],&auxevol_gfs[IDX4ptS(VALENCIAV_RU0GF+(flux_dirn-count+2)%3, 0)],
              &auxevol_gfs[IDX4ptS(VALENCIAV_LU0GF+(flux_dirn)%3, 0)],&auxevol_gfs[IDX4ptS(VALENCIAV_LU0GF+(flux_dirn-count+2)%3, 0)],
              &auxevol_gfs[IDX4ptS(B_RU0GF        +(flux_dirn)%3, 0)],&auxevol_gfs[IDX4ptS(B_RU0GF        +(flux_dirn-count+2)%3, 0)],
              &auxevol_gfs[IDX4ptS(B_LU0GF        +(flux_dirn)%3, 0)],&auxevol_gfs[IDX4ptS(B_LU0GF        +(flux_dirn-count+2)%3, 0)],
              &auxevol_gfs[IDX4ptS(B_RU0GF        +(flux_dirn-count+2)%3, 0)],
              &auxevol_gfs[IDX4ptS(B_LU0GF        +(flux_dirn-count+2)%3, 0)],
              &rhs_gfs[IDX4ptS(AD0GF+(flux_dirn+1+count)%3,0)], 2.0*((REAL)count)-1.0, flux_dirn);
        }
    }
}

void GiRaFFE_NRPy_post_step(const paramstruct *restrict params,REAL *xx[3],REAL *restrict auxevol_gfs,REAL *restrict evol_gfs,const int n) {
    // First, apply BCs to AD and psi6Phi. Then calculate BU from AD
    apply_bcs_potential(params,evol_gfs);
    driver_A_to_B(params,evol_gfs,auxevol_gfs);
    //override_BU_with_old_GiRaFFE(params,auxevol_gfs,n);
    // Apply fixes to StildeD, then recompute the velocity at the new timestep.
    // Apply the current sheet prescription to the velocities
    GiRaFFE_NRPy_cons_to_prims(params,xx,auxevol_gfs,evol_gfs);
    // Then, recompute StildeD to be consistent with the new velocities
    //GiRaFFE_NRPy_prims_to_cons(params,auxevol_gfs,evol_gfs);
    // Finally, apply outflow boundary conditions to the velocities.
    apply_bcs_velocity(params,auxevol_gfs);
}
""")
Ejemplo n.º 17
0
import GiRaFFE_NRPy.GiRaFFE_NRPy_C2P_P2C as C2P_P2C
import GiRaFFE_NRPy.GiRaFFE_NRPy_Source_Terms as source

thismodule = "GiRaFFE_NRPy_Main_Driver"

CoordSystem = "Cartesian"

outCparams = "outCverbose=False,CSE_sorting=none"

par.set_parval_from_str("reference_metric::CoordSystem", CoordSystem)
rfm.reference_metric(
)  # Create ReU, ReDD needed for rescaling B-L initial data, generating BSSN RHSs, etc.

# Default Kreiss-Oliger dissipation strength
default_KO_strength = 0.1
diss_strength = par.Cparameters("REAL", thismodule, "diss_strength",
                                default_KO_strength)


def GiRaFFE_NRPy_Main_Driver_generate_all(out_dir):
    cmd.mkdir(out_dir)

    gammaDD = ixp.register_gridfunctions_for_single_rank2("AUXEVOL",
                                                          "gammaDD",
                                                          "sym01",
                                                          DIM=3)
    betaU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                        "betaU",
                                                        DIM=3)
    alpha = gri.register_gridfunctions("AUXEVOL", "alpha")
    AD = ixp.register_gridfunctions_for_single_rank1("EVOL", "AD")
    BU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL", "BU")
Ejemplo n.º 18
0
    def BSSN_RHSs__generate_symbolic_expressions():
        ######################################
        # START: GENERATE SYMBOLIC EXPRESSIONS
        print("Generating symbolic expressions for BSSN RHSs...")
        start = time.time()
        # Enable rfm_precompute infrastructure, which results in
        #   BSSN RHSs that are free of transcendental functions,
        #   even in curvilinear coordinates, so long as
        #   ConformalFactor is set to "W" (default).
        par.set_parval_from_str("reference_metric::enable_rfm_precompute","True")
        par.set_parval_from_str("reference_metric::rfm_precompute_Ccode_outdir",os.path.join(outdir,"rfm_files/"))

        # Evaluate BSSN + BSSN gauge RHSs with rfm_precompute enabled:
        import BSSN.BSSN_quantities as Bq
        par.set_parval_from_str("BSSN.BSSN_quantities::LeaveRicciSymbolic","True")

        rhs.BSSN_RHSs()

        if T4UU != None:
            import BSSN.BSSN_stress_energy_source_terms as Bsest
            Bsest.BSSN_source_terms_for_BSSN_RHSs(T4UU)
            rhs.trK_rhs += Bsest.sourceterm_trK_rhs
            for i in range(3):
                # Needed for Gamma-driving shift RHSs:
                rhs.Lambdabar_rhsU[i] += Bsest.sourceterm_Lambdabar_rhsU[i]
                # Needed for BSSN RHSs:
                rhs.lambda_rhsU[i]    += Bsest.sourceterm_lambda_rhsU[i]
                for j in range(3):
                    rhs.a_rhsDD[i][j] += Bsest.sourceterm_a_rhsDD[i][j]

        gaugerhs.BSSN_gauge_RHSs()

        # Add Kreiss-Oliger dissipation to the BSSN RHSs:
        thismodule = "KO_Dissipation"
        diss_strength = par.Cparameters("REAL", thismodule, "diss_strength", default_KO_strength)

        alpha_dKOD = ixp.declarerank1("alpha_dKOD")
        cf_dKOD    = ixp.declarerank1("cf_dKOD")
        trK_dKOD   = ixp.declarerank1("trK_dKOD")
        betU_dKOD    = ixp.declarerank2("betU_dKOD","nosym")
        vetU_dKOD    = ixp.declarerank2("vetU_dKOD","nosym")
        lambdaU_dKOD = ixp.declarerank2("lambdaU_dKOD","nosym")
        aDD_dKOD = ixp.declarerank3("aDD_dKOD","sym01")
        hDD_dKOD = ixp.declarerank3("hDD_dKOD","sym01")
        for k in range(3):
            gaugerhs.alpha_rhs += diss_strength*alpha_dKOD[k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
            rhs.cf_rhs         += diss_strength*   cf_dKOD[k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
            rhs.trK_rhs        += diss_strength*  trK_dKOD[k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
            for i in range(3):
                if "2ndOrder" in ShiftCondition:
                    gaugerhs.bet_rhsU[i] += diss_strength*   betU_dKOD[i][k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
                gaugerhs.vet_rhsU[i]     += diss_strength*   vetU_dKOD[i][k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
                rhs.lambda_rhsU[i]       += diss_strength*lambdaU_dKOD[i][k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
                for j in range(3):
                    rhs.a_rhsDD[i][j] += diss_strength*aDD_dKOD[i][j][k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]
                    rhs.h_rhsDD[i][j] += diss_strength*hDD_dKOD[i][j][k]*rfm.ReU[k] # ReU[k] = 1/scalefactor_orthog_funcform[k]

        # We use betaU as our upwinding control vector:
        Bq.BSSN_basic_tensors()
        betaU = Bq.betaU

        # Now that we are finished with all the rfm hatted
        #           quantities in generic precomputed functional
        #           form, let's restore them to their closed-
        #           form expressions.
        par.set_parval_from_str("reference_metric::enable_rfm_precompute","False") # Reset to False to disable rfm_precompute.
        rfm.ref_metric__hatted_quantities()
        par.set_parval_from_str("BSSN.BSSN_quantities::LeaveRicciSymbolic","False")
        end = time.time()
        print("(BENCH) Finished BSSN RHS symbolic expressions in "+str(end-start)+" seconds.")
        # END: GENERATE SYMBOLIC EXPRESSIONS
        ######################################

        BSSN_RHSs_SymbExpressions = [lhrh(lhs=gri.gfaccess("rhs_gfs","aDD00"),   rhs=rhs.a_rhsDD[0][0]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","aDD01"),   rhs=rhs.a_rhsDD[0][1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","aDD02"),   rhs=rhs.a_rhsDD[0][2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","aDD11"),   rhs=rhs.a_rhsDD[1][1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","aDD12"),   rhs=rhs.a_rhsDD[1][2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","aDD22"),   rhs=rhs.a_rhsDD[2][2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","alpha"),   rhs=gaugerhs.alpha_rhs),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","betU0"),   rhs=gaugerhs.bet_rhsU[0]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","betU1"),   rhs=gaugerhs.bet_rhsU[1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","betU2"),   rhs=gaugerhs.bet_rhsU[2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","cf"),      rhs=rhs.cf_rhs),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","hDD00"),   rhs=rhs.h_rhsDD[0][0]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","hDD01")   ,rhs=rhs.h_rhsDD[0][1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","hDD02"),   rhs=rhs.h_rhsDD[0][2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","hDD11"),   rhs=rhs.h_rhsDD[1][1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","hDD12"),   rhs=rhs.h_rhsDD[1][2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","hDD22"),   rhs=rhs.h_rhsDD[2][2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","lambdaU0"),rhs=rhs.lambda_rhsU[0]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","lambdaU1"),rhs=rhs.lambda_rhsU[1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","lambdaU2"),rhs=rhs.lambda_rhsU[2]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","trK"),     rhs=rhs.trK_rhs),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","vetU0"),   rhs=gaugerhs.vet_rhsU[0]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","vetU1"),   rhs=gaugerhs.vet_rhsU[1]),
                                     lhrh(lhs=gri.gfaccess("rhs_gfs","vetU2"),   rhs=gaugerhs.vet_rhsU[2]) ]

        return [betaU,BSSN_RHSs_SymbExpressions]
Ejemplo n.º 19
0
# 
# **Additional variables needed for spacetime evolution**:
# 
# * Desired coordinate system
# * Desired initial lapse $\alpha$ and shift $\beta^i$. We will choose our gauge conditions as $\alpha=1$ and $\beta^i=B^i=0$. $\alpha = \psi^{-2}$ will yield much better behavior, but the conformal factor $\psi$ depends on the desired *destination* coordinate system (which may not be spherical coordinates).

# Step 1: Initialize core Python/NRPy+ modules
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 BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear as AtoB

thismodule = __name__

# Input parameters:
M = par.Cparameters("REAL", thismodule, ["M"], [1.0])

# ComputeADMGlobalsOnly == True will only set up the ADM global quantities.
#                       == False will perform the full ADM SphorCart->BSSN Curvi conversion
def StaticTrumpet(ComputeADMGlobalsOnly = False):
    global Sph_r_th_ph,r,th,ph, gammaSphDD, KSphDD, alphaSph, betaSphU, BSphU
    
    # All gridfunctions will be written in terms of spherical coordinates (r, th, ph):
    r,th,ph = sp.symbols('r th ph', real=True)

    # Step 0: Set spatial dimension (must be 3 for BSSN)
    DIM = 3
    par.set_parval_from_str("grid::DIM",DIM)

    # Step 1: Set psi, the conformal factor:
Ejemplo n.º 20
0
def generate_C_code_for_Stilde_flux(
        out_dir,
        inputs_provided=False,
        alpha_face=None,
        gamma_faceDD=None,
        beta_faceU=None,
        Valenciav_rU=None,
        B_rU=None,
        Valenciav_lU=None,
        B_lU=None,
        sqrt4pi=None,
        outCparams="outCverbose=False,CSE_sorting=none",
        write_cmax_cmin=False):
    if not inputs_provided:
        # We will pass values of the gridfunction on the cell faces into the function. This requires us
        # to declare them as C parameters in NRPy+. We will denote this with the _face infix/suffix.
        alpha_face = gri.register_gridfunctions("AUXEVOL", "alpha_face")
        gamma_faceDD = ixp.register_gridfunctions_for_single_rank2(
            "AUXEVOL", "gamma_faceDD", "sym01")
        beta_faceU = ixp.register_gridfunctions_for_single_rank1(
            "AUXEVOL", "beta_faceU")

        # We'll need some more gridfunctions, now, to represent the reconstructions of BU and ValenciavU
        # on the right and left faces
        Valenciav_rU = ixp.register_gridfunctions_for_single_rank1(
            "AUXEVOL", "Valenciav_rU", DIM=3)
        B_rU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                           "B_rU",
                                                           DIM=3)
        Valenciav_lU = ixp.register_gridfunctions_for_single_rank1(
            "AUXEVOL", "Valenciav_lU", DIM=3)
        B_lU = ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                           "B_lU",
                                                           DIM=3)
        sqrt4pi = par.Cparameters("REAL", thismodule, "sqrt4pi",
                                  "sqrt(4.0*M_PI)")

        # We'll also need to store the results of the HLLE step between functions.
        ixp.register_gridfunctions_for_single_rank1("AUXEVOL",
                                                    "Stilde_flux_HLLED")

    input_params_for_Stilde_flux = "const paramstruct *params,REAL *auxevol_gfs,REAL *rhs_gfs"

    if write_cmax_cmin:
        name_suffixes = ["_x", "_y", "_z"]

    for flux_dirn in range(3):
        calculate_Stilde_flux(flux_dirn,alpha_face,gamma_faceDD,beta_faceU,\
                              Valenciav_rU,B_rU,Valenciav_lU,B_lU,sqrt4pi)

        Stilde_flux_to_print = [
            lhrh(lhs=gri.gfaccess("out_gfs", "Stilde_flux_HLLED0"),
                 rhs=Stilde_fluxD[0]),
            lhrh(lhs=gri.gfaccess("out_gfs", "Stilde_flux_HLLED1"),
                 rhs=Stilde_fluxD[1]),
            lhrh(lhs=gri.gfaccess("out_gfs", "Stilde_flux_HLLED2"),
                 rhs=Stilde_fluxD[2])
        ]

        if write_cmax_cmin:
            Stilde_flux_to_print = Stilde_flux_to_print \
                                  +[
                                    lhrh(lhs=gri.gfaccess("out_gfs","cmax"+name_suffixes[flux_dirn]),rhs=chsp.cmax),
                                    lhrh(lhs=gri.gfaccess("out_gfs","cmin"+name_suffixes[flux_dirn]),rhs=chsp.cmin)
                                   ]

        desc = "Compute the flux term of all 3 components of tilde{S}_i on the left face in the " + str(
            flux_dirn) + "direction for all components."
        name = "calculate_Stilde_flux_D" + str(flux_dirn)
        Ccode_function = outCfunction(
            outfile="returnstring",
            desc=desc,
            name=name,
            params=input_params_for_Stilde_flux,
            body=fin.FD_outputC("returnstring",
                                Stilde_flux_to_print,
                                params=outCparams),
            loopopts="InteriorPoints",
            rel_path_to_Cparams=os.path.join("../")).replace(
                "NGHOSTS+Nxx0", "NGHOSTS+Nxx0+1").replace(
                    "NGHOSTS+Nxx1",
                    "NGHOSTS+Nxx1+1").replace("NGHOSTS+Nxx2", "NGHOSTS+Nxx2+1")

        with open(os.path.join(out_dir, name + ".h"), "w") as file:
            file.write(Ccode_function)

    pre_body = """// Notice in the loop below that we go from 3 to cctk_lsh-3 for i, j, AND k, even though
    //   we are only computing the flux in one direction. This is because in the end,
    //   we only need the rhs's from 3 to cctk_lsh-3 for i, j, and k.
    const REAL invdxi[4] = {1e100,invdx0,invdx1,invdx2};
    const REAL invdx = invdxi[flux_dirn];"""

    FD_body = """const int index = IDX3S(i0,i1,i2);
const int indexp1 = IDX3S(i0+kronecker_delta[flux_dirn][0],i1+kronecker_delta[flux_dirn][1],i2+kronecker_delta[flux_dirn][2]);

rhs_gfs[IDX4ptS(STILDED0GF,index)] += (auxevol_gfs[IDX4ptS(STILDE_FLUX_HLLED0GF,index)]     - auxevol_gfs[IDX4ptS(STILDE_FLUX_HLLED0GF,indexp1)]    ) * invdx;
rhs_gfs[IDX4ptS(STILDED1GF,index)] += (auxevol_gfs[IDX4ptS(STILDE_FLUX_HLLED1GF,index)]     - auxevol_gfs[IDX4ptS(STILDE_FLUX_HLLED1GF,indexp1)]    ) * invdx;
rhs_gfs[IDX4ptS(STILDED2GF,index)] += (auxevol_gfs[IDX4ptS(STILDE_FLUX_HLLED2GF,index)]     - auxevol_gfs[IDX4ptS(STILDE_FLUX_HLLED2GF,indexp1)]    ) * invdx;"""

    desc = "Compute the difference in the flux of StildeD on the opposite faces in flux_dirn for all components."
    name = "calculate_Stilde_rhsD"
    outCfunction(
        outfile=os.path.join(out_dir, name + ".h"),
        desc=desc,
        name=name,
        params=
        "const int flux_dirn,const paramstruct *params,const REAL *auxevol_gfs,REAL *rhs_gfs",
        preloop=pre_body,
        body=FD_body,
        loopopts="InteriorPoints",
        rel_path_to_Cparams=os.path.join("../"))
from outputC import nrpyAbs  # NRPy+: Core C code output module
import NRPy_param_funcs as par  # NRPy+: parameter interface
import sympy as sp  # SymPy: The Python computer algebra package upon which NRPy+ depends

thismodule = __name__

TINYDOUBLE = par.Cparameters("REAL", thismodule, "TINYDOUBLE", 1e-100)


def min_noif(a, b):
    # Returns the minimum of a and b
    if a == sp.sympify(0):
        return sp.Rational(1, 2) * (b - nrpyAbs(b))
    if b == sp.sympify(0):
        return sp.Rational(1, 2) * (a - nrpyAbs(a))
    return sp.Rational(1, 2) * (a + b - nrpyAbs(a - b))


def max_noif(a, b):
    # Returns the maximum of a and b
    if a == sp.sympify(0):
        return sp.Rational(1, 2) * (b + nrpyAbs(b))
    if b == sp.sympify(0):
        return sp.Rational(1, 2) * (a + nrpyAbs(a))
    return sp.Rational(1, 2) * (a + b + nrpyAbs(a - b))


def coord_leq_bound(x, xstar):
    # Returns 1.0 if x <= xstar, 0.0 otherwise.
    # Requires appropriately defined TINYDOUBLE
    return min_noif(x - xstar - TINYDOUBLE, 0.0) / (x - xstar - TINYDOUBLE)
Ejemplo n.º 22
0
# grid.py: functions & parameters related to numerical grids:
# functions: Automatic loop output, output C code needed for gridfunction memory I/O, gridfunction registration

# Initialize globals related to the grid
glb_gridfcs_list = []
glb_gridfc = namedtuple('gridfunction', 'gftype name')

thismodule = __name__
par.initialize_param(
    par.glb_param("char", thismodule, "GridFuncMemAccess", "SENRlike"))
par.initialize_param(par.glb_param("char", thismodule, "MemAllocStyle", "210"))
par.initialize_param(par.glb_param("INT", thismodule, "DIM", 3))
par.initialize_param(
    par.glb_param("INT", thismodule, "Nx[DIM]", "SetAtCRuntime"))

xx = par.Cparameters("REALARRAY", thismodule, ["xx0", "xx1", "xx2", "xx3"])


def variable_type(var):
    var_is_gf = False
    for gf in range(len(glb_gridfcs_list)):
        if str(var) == glb_gridfcs_list[gf].name:
            var_is_gf = True
    var_is_parameter = False
    for paramname in range(len(par.glb_params_list)):
        if str(var) == par.glb_params_list[paramname].parname:
            var_is_parameter = True
    if var_is_parameter and var_is_gf:
        print("Error: variable " + str(var) +
              " is registered both as a gridfunction and as a Cparameter.")
        exit(1)
Ejemplo n.º 23
0

# <a id='step2'></a>
# ### Set the vector $A_k$
# The vector potential is given as
# \begin{align}
# A_x &= 0 \\
# A_y &= \left \{ \begin{array}{lll}\gamma_\mu x - 0.015 & \mbox{if} & x \leq -0.1/\gamma_\mu \\
# 1.15 \gamma_\mu x - 0.03g(x) & \mbox{if} & -0.1/\gamma_\mu \leq x \leq 0.1/\gamma_\mu \\ 
# 1.3 \gamma_\mu x - 0.015 & \mbox{if} & x \geq 0.1/\gamma_\mu \end{array} \right. , \\
# A_z &= y - \gamma_\mu (1-\mu)x .
# \end{align}
# First, however, we must set $$\gamma_\mu = (1-\mu^2)^{-1/2}$$ and $$g(x) = \cos (5\pi \gamma_\mu x)/\pi$$.
# $$\label{step2}$$

mu_AW = par.Cparameters("REAL",thismodule,["mu_AW"], -0.5) # The wave speed
M_PI  = par.Cparameters("#define",thismodule,["M_PI"], "")

def GiRaFFEfood_HO_1D_tests():
    gammamu = 1/sp.sqrt(1-mu_AW**2)

    # We'll use reference_metric.py to define x and y
    x = rfm.xxCart[0]
    y = rfm.xxCart[1]

    g_AW = sp.cos(5*M_PI*gammamu*x)/M_PI


    # Now, we can define the vector potential. We will create three copies of this variable, because the potential is uniquely defined in three zones. Data for $x \leq -0.1/\gamma_\mu$ shall be referred to as "left", data for $-0.1/\gamma_\mu \leq x \leq 0.1/\gamma_\mu$ as "center", and data for $x \geq 0.1/\gamma_\mu$ as "right".
    # 
    # Starting on the left, 
Ejemplo n.º 24
0
# * The black hole mass, M
# * The black hole spin parameter, a

# Step P0: Load needed modules
import sympy as sp
import NRPy_param_funcs as par
from outputC import *
import indexedexp as ixp
import reference_metric as rfm
import BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear as AtoB
import BSSN.BSSN_ID_function_string as bIDf

thismodule = __name__

# Input parameters:
M, a, r0 = par.Cparameters("REAL", thismodule, ["M", "a", "r0"],
                           [1.0, 0.9, 1.0])


# ComputeADMGlobalsOnly == True will only set up the ADM global quantities.
#                       == False will perform the full ADM SphorCart->BSSN Curvi conversion
def ShiftedKerrSchild(ComputeADMGlobalsOnly=False):
    global Sph_r_th_ph, r, th, ph, rho2, gammaSphDD, KSphDD, alphaSph, betaSphU, BSphU

    # All gridfunctions will be written in terms of spherical coordinates (r, th, ph):
    r, th, ph = sp.symbols('r th ph', real=True)

    DIM = 3
    par.set_parval_from_str("grid::DIM", DIM)

    # Auxiliary variables:
    rho2 = sp.symbols('rho2', real=True)
Ejemplo n.º 25
0
import loop

import reference_metric as rfm
par.set_parval_from_str("reference_metric::CoordSystem", "Cartesian")
rfm.reference_metric()

# Step 1a: Set commonly used parameters.
thismodule = "GiRaFFEfood_NRPy_Aligned_Rotator"
# Set the spatial dimension parameter to 3.
par.set_parval_from_str("grid::DIM", 3)
DIM = par.parval_from_str("grid::DIM")

B_p_aligned_rotator, R_NS_aligned_rotator = par.Cparameters(
    "REAL",
    thismodule,
    # B_p_aligned_rotator = the intensity of the magnetic field and
    # R_NS_aligned_rotator= "Neutron star" radius
    ["B_p_aligned_rotator", "R_NS_aligned_rotator"],
    [1e-5, 1.0])

# The angular velocity of the "neutron star"
Omega_aligned_rotator = par.Cparameters("REAL", thismodule,
                                        "Omega_aligned_rotator", 1e3)

# <a id='step2'></a>
#
# ### Step 2: Set the vectors A in Spherical coordinates
# $$\label{step2}$$
#
# \[Back to [top](#top)\]
#
Ejemplo n.º 26
0
def BSSN_constraints(add_T4UUmunu_source_terms=False):
    # Step 1.a: 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.b: 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 2: Hamiltonian constraint.
    # First declare all needed variables
    Bq.declare_BSSN_gridfunctions_if_not_declared_already()  # Sets trK
    Bq.BSSN_basic_tensors()  # Sets AbarDD
    Bq.gammabar__inverse_and_derivs()  # Sets gammabarUU
    Bq.AbarUU_AbarUD_trAbar_AbarDD_dD()  # Sets AbarUU and AbarDD_dD
    Bq.RicciBar__gammabarDD_dHatD__DGammaUDD__DGammaU()  # Sets RbarDD
    Bq.phi_and_derivs()  # Sets phi_dBarD & phi_dBarDD

    ###############################
    ###############################
    #  HAMILTONIAN CONSTRAINT
    ###############################
    ###############################

    # Term 1: 2/3 K^2
    global H
    H = sp.Rational(2, 3) * Bq.trK**2

    # Term 2: -A_{ij} A^{ij}
    for i in range(DIM):
        for j in range(DIM):
            H += -Bq.AbarDD[i][j] * Bq.AbarUU[i][j]

    # Term 3a: trace(Rbar)
    Rbartrace = sp.sympify(0)
    for i in range(DIM):
        for j in range(DIM):
            Rbartrace += Bq.gammabarUU[i][j] * Bq.RbarDD[i][j]

    # Term 3b: -8 \bar{\gamma}^{ij} \bar{D}_i \phi \bar{D}_j \phi = -8*phi_dBar_times_phi_dBar
    # Term 3c: -8 \bar{\gamma}^{ij} \bar{D}_i \bar{D}_j \phi      = -8*phi_dBarDD_contraction
    phi_dBar_times_phi_dBar = sp.sympify(0)  # Term 3b
    phi_dBarDD_contraction = sp.sympify(0)  # Term 3c
    for i in range(DIM):
        for j in range(DIM):
            phi_dBar_times_phi_dBar += Bq.gammabarUU[i][j] * Bq.phi_dBarD[
                i] * Bq.phi_dBarD[j]
            phi_dBarDD_contraction += Bq.gammabarUU[i][j] * Bq.phi_dBarDD[i][j]

    # Add Term 3:
    H += Bq.exp_m4phi * (Rbartrace - 8 *
                         (phi_dBar_times_phi_dBar + phi_dBarDD_contraction))

    if add_T4UUmunu_source_terms:
        M_PI = par.Cparameters("#define", thismodule, "M_PI",
                               "")  # M_PI is pi as defined in C
        BTmunu.define_BSSN_T4UUmunu_rescaled_source_terms()
        rho = BTmunu.rho
        H += -16 * M_PI * rho

    # FIXME: ADD T4UUmunu SOURCE TERMS TO MOMENTUM CONSTRAINT!

    # Step 3: M^i, the momentum constraint

    ###############################
    ###############################
    #  MOMENTUM CONSTRAINT
    ###############################
    ###############################

    # SEE Tutorial-BSSN_constraints.ipynb for full documentation.
    global MU
    MU = ixp.zerorank1()

    # Term 2: 6 A^{ij} \partial_j \phi:
    for i in range(DIM):
        for j in range(DIM):
            MU[i] += 6 * Bq.AbarUU[i][j] * Bq.phi_dD[j]

    # Term 3: -2/3 \bar{\gamma}^{ij} K_{,j}
    trK_dD = ixp.declarerank1(
        "trK_dD")  # Not defined in BSSN_RHSs; only trK_dupD is defined there.
    for i in range(DIM):
        for j in range(DIM):
            MU[i] += -sp.Rational(2, 3) * Bq.gammabarUU[i][j] * trK_dD[j]

    # First define aDD_dD:
    aDD_dD = ixp.declarerank3("aDD_dD", "sym01")

    # Then evaluate the conformal covariant derivative \bar{D}_j \bar{A}_{lm}
    AbarDD_dBarD = ixp.zerorank3()
    for i in range(DIM):
        for j in range(DIM):
            for k in range(DIM):
                AbarDD_dBarD[i][j][k] = Bq.AbarDD_dD[i][j][k]
                for l in range(DIM):
                    AbarDD_dBarD[i][j][
                        k] += -Bq.GammabarUDD[l][k][i] * Bq.AbarDD[l][j]
                    AbarDD_dBarD[i][j][
                        k] += -Bq.GammabarUDD[l][k][j] * Bq.AbarDD[i][l]

    # Term 1: Contract twice with the metric to make \bar{D}_{j} \bar{A}^{ij}
    for i in range(DIM):
        for j in range(DIM):
            for k in range(DIM):
                for l in range(DIM):
                    MU[i] += Bq.gammabarUU[i][k] * Bq.gammabarUU[j][
                        l] * AbarDD_dBarD[k][l][j]

    # Finally, we multiply by e^{-4 phi} and rescale the momentum constraint:
    for i in range(DIM):
        MU[i] *= Bq.exp_m4phi / rfm.ReU[i]
Ejemplo n.º 27
0
def ShiftedKerrSchild(ComputeADMGlobalsOnly = False):
    global Sph_r_th_ph,r,th,ph, rho2, gammaSphDD, KSphDD, alphaSph, betaSphU, BSphU
    
    # All gridfunctions will be written in terms of spherical coordinates (r, th, ph):
    r,th,ph = sp.symbols('r th ph', real=True)

    thismodule = "ShiftedKerrSchild"

    DIM = 3
    par.set_parval_from_str("grid::DIM",DIM)

    # Input parameters:
    M, a, r0 = par.Cparameters("REAL", thismodule, ["M", "a", "r0"])

    # Auxiliary variables:
    rho2 = sp.symbols('rho2', real=True)
    
    # r_{KS} = r + r0
    rKS = r+r0

    # rho^2 = rKS^2 + a^2*cos^2(theta)
    rho2 = rKS*rKS + a*a*sp.cos(th)**2

    # alpha = 1/sqrt{1 + M*rKS/rho^2}
    alphaSph = 1/(sp.sqrt(1 + 2*M*rKS/rho2))

    # Initialize the shift vector, \beta^i, to zero.
    betaSphU = ixp.zerorank1()
    # beta^r = alpha^2*2Mr/rho^2
    betaSphU[0] = alphaSph*alphaSph*2*M*rKS/rho2

    # Time derivative of shift vector beta^i, B^i, is zero.
    BSphU = ixp.zerorank1()

    # Initialize \gamma_{ij} to zero.
    gammaSphDD = ixp.zerorank2()

    # gammaDD{rKS rKS} = 1 +2M*rKS/rho^2
    gammaSphDD[0][0] = 1 + 2*M*rKS/rho2

    # gammaDD{rKS phi} = -a*gammaDD{r r}*sin^2(theta)
    gammaSphDD[0][2] = gammaSphDD[2][0] = -a*gammaSphDD[0][0]*sp.sin(th)**2

    # gammaDD{theta theta} = rho^2
    gammaSphDD[1][1] = rho2

    # gammaDD{phi phi} = (rKS^2 + a^2 + 2Mr/rho^2*a^2*sin^2(theta))*sin^2(theta)
    gammaSphDD[2][2] = (rKS*rKS + a*a + 2*M*rKS*a*a*sp.sin(th)**2/rho2)*sp.sin(th)**2
    
    # *** Define Useful Quantities A, B, D ***
    # A = (a^2*cos^2(2theta) + a^2 + 2r^2)
    A = (a*a*sp.cos(2*th) + a*a + 2*rKS*rKS)

    # B = A + 4M*rKS
    B = A + 4*M*rKS

    # D = \sqrt(2M*rKS/(a^2cos^2(theta) + rKS^2) + 1)
    D = sp.sqrt(2*M*rKS/(a*a*sp.cos(th)**2 + rKS*rKS) + 1)
                
    
    # *** The extrinsic curvature in spherical polar coordinates ***

    # Establish the 3x3 zero-matrix
    KSphDD = ixp.zerorank2()

    # *** Fill in the nonzero components ***
    # *** This will create an upper-triangular matrix ***
    # K_{r r} = D(A+2Mr)/(A^2*B)[4M(a^2*cos(2theta) + a^2 - 2r^2)]
    KSphDD[0][0] = D*(A+2*M*rKS)/(A*A*B)*(4*M*(a*a*sp.cos(2*th)+a*a-2*rKS*rKS))

    # K_{r theta} = D/(AB)[8a^2*Mr*sin(theta)cos(theta)]
    KSphDD[0][1] = KSphDD[1][0] = D/(A*B)*(8*a*a*M*rKS*sp.sin(th)*sp.cos(th))

    # K_{r phi} = D/A^2[-2aMsin^2(theta)(a^2cos(2theta)+a^2-2r^2)]
    KSphDD[0][2] = KSphDD[2][0] =  D/(A*A)*(-2*a*M*sp.sin(th)**2*(a*a*sp.cos(2*th)+a*a-2*rKS*rKS))

    # K_{theta theta} = D/B[4Mr^2]
    KSphDD[1][1] = D/B*(4*M*rKS*rKS)

    # K_{theta phi} = D/(AB)*(-8*a^3*Mr*sin^3(theta)cos(theta))
    KSphDD[1][2] = KSphDD[2][1] = D/(A*B)*(-8*a**3*M*rKS*sp.sin(th)**3*sp.cos(th))

    # K_{phi phi} = D/(A^2*B)[2Mr*sin^2(theta)(a^4(M+3r)
    #   +4a^2r^2(2r-M)+4a^2r*cos(2theta)(a^2+r(M+2r))+8r^5)]
    KSphDD[2][2] = D/(A*A*B)*(2*M*rKS*sp.sin(th)**2*(a**4*(rKS-M)*sp.cos(4*th)\
                            + a**4*(M+3*rKS)+4*a*a*rKS*rKS*(2*rKS-M)\
                            + 4*a*a*rKS*sp.cos(2*th)*(a*a + rKS*(M + 2*rKS)) + 8*rKS**5))          
    
    
    if ComputeADMGlobalsOnly == True:
        return
    
    # Validated against original SENR: 
    #print(sp.mathematica_code(gammaSphDD[1][1]))

    Sph_r_th_ph = [r,th,ph]
    cf,hDD,lambdaU,aDD,trK,alpha,vetU,betU = \
        AtoB.Convert_Spherical_or_Cartesian_ADM_to_BSSN_curvilinear("Spherical", Sph_r_th_ph, 
                                                                    gammaSphDD,KSphDD,alphaSph,betaSphU,BSphU)

    global returnfunction
    returnfunction = bIDf.BSSN_ID_function_string(cf,hDD,lambdaU,aDD,trK,alpha,vetU,betU)
Ejemplo n.º 28
0
# * Desired initial lapse $\alpha$ and shift $\beta^i$. We will choose our gauge conditions as $\alpha=1$ and $\beta^i=B^i=0$. $\alpha = \psi^{-2}$ will yield much better behavior, but the conformal factor $\psi$ depends on the desired *destination* coordinate system (which may not be spherical coordinates).

# Step P0: Load needed modules
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 sys  # Standard Python module for multiplatform OS-level functions
from pickling import pickle_NRPy_env  # NRPy+: Pickle/unpickle NRPy+ environment, for parallel codegen
import BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear as AtoB
thismodule = __name__

# The UIUC initial data represent a Kerr black hole with mass M
#  and dimensionless spin chi in UIUC quasi-isotropic coordinates,
#   see https://arxiv.org/abs/1001.4077
# Input parameters:
M, chi = par.Cparameters("REAL", thismodule, ["M", "chi"], [1.0, 0.99])


# ComputeADMGlobalsOnly == True will only set up the ADM global quantities.
#                       == False will perform the full ADM SphorCart->BSSN Curvi conversion
def UIUCBlackHole(ComputeADMGlobalsOnly=False,
                  include_NRPy_basic_defines_and_pickle=False):
    global Sph_r_th_ph, r, th, ph, gammaSphDD, KSphDD, alphaSph, betaSphU, BSphU

    # All gridfunctions will be written in terms of spherical coordinates (r, th, ph):
    r, th, ph = sp.symbols('r th ph', real=True)

    # Step 0: Set spatial dimension (must be 3 for BSSN)
    DIM = 3
    par.set_parval_from_str("grid::DIM", DIM)
Ejemplo n.º 29
0
# * Desired initial lapse $\alpha$ and shift $\beta^i$
#
# **Transformation to curvilinear coordinates**:
# * Once the above variables have been set in Cartesian coordinates, we will apply the appropriate coordinate transformations and tensor rescalings ([described in the BSSN NRPy+ tutorial module](Tutorial-BSSNCurvilinear.ipynb))

# Step 1: Initialize core Python/NRPy+ modules
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
from pickling import pickle_NRPy_env  # NRPy+: Pickle/unpickle NRPy+ environment, for parallel codegen
import BSSN.ADM_Exact_Spherical_or_Cartesian_to_BSSNCurvilinear as AtoB

thismodule = __name__

BH1_posn_x, BH1_posn_y, BH1_posn_z = par.Cparameters("REAL", thismodule,
                                                     ["BH1_posn_x", "BH1_posn_y", "BH1_posn_z"],
                                                     [0.0, 0.0, +0.5])
BH1_mass = par.Cparameters("REAL", thismodule, ["BH1_mass"], 1.0)
BH2_posn_x, BH2_posn_y, BH2_posn_z = par.Cparameters("REAL", thismodule,
                                                     ["BH2_posn_x", "BH2_posn_y", "BH2_posn_z"],
                                                     [0.0, 0.0, -0.5])
BH2_mass = par.Cparameters("REAL", thismodule, ["BH2_mass"], 1.0)


# ComputeADMGlobalsOnly == True will only set up the ADM global quantities.
#                       == False will perform the full ADM SphorCart->BSSN Curvi conversion
def BrillLindquist(ComputeADMGlobalsOnly = False, include_NRPy_basic_defines_and_pickle=False):
    # Step 2: Setting up Brill-Lindquist initial data

    # Step 2.a: Set spatial dimension (must be 3 for BSSN)
    DIM = 3
import reference_metric as rfm
par.set_parval_from_str("reference_metric::CoordSystem", "Cartesian")
rfm.reference_metric()

# Step 1a: Set commonly used parameters.
thismodule = "GiRaFFEfood_HO"
# Set the spatial dimension parameter to 3.
par.set_parval_from_str("grid::DIM", 3)
DIM = par.parval_from_str("grid::DIM")

# Create a parameter to control the initial data choice. For now, this will only have Exact Wald as an option.
par.initialize_param(
    par.glb_param("char", thismodule, "IDchoice", "Exact_Wald"))

# Step 1b: Set needed Cparameters
M = par.Cparameters("REAL", thismodule, ["M"],
                    1.0)  # The mass of the black hole
M_PI = par.Cparameters("#define", thismodule, ["M_PI"], "")  # pi, 3.141592...
KerrSchild_radial_shift = par.Cparameters("REAL", thismodule,
                                          "KerrSchild_radial_shift",
                                          0.4)  # Default value for ExactWald


def GiRaFFEfood_HO_Exact_Wald():

    # <a id='step2'></a>
    #
    # ### Step 2: Set the vectors A and E in Spherical coordinates
    # $$\label{step2}$$
    #
    # \[Back to [top](#top)\]
    #