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 Ar_SM(r, theta, phi, **params):
    M = params["M"]
    a = params["a"]
    # A_r = -aC/8 * cos \theta ( 1 + 4M/r ) \sqrt{1 + 2M/r}
    return -a * C_SM * sp.Rational(1, 8) * nrpyAbs(
        sp.cos(theta)) * (sp.sympify(1) + sp.sympify(4) * M /
                          r) * sp.sqrt(sp.sympify(1) + sp.sympify(2) * M / r)
Example #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])
def Enforce_Detgammabar_Constraint_symb_expressions():
    # Set spatial dimension (must be 3 for BSSN)
    DIM = 3

    # Then we set the coordinate system for the numerical grid
    rfm.reference_metric(
    )  # Create ReU, ReDD needed for rescaling B-L initial data, generating BSSN RHSs, etc.

    # We will need the h_{ij} quantities defined within BSSN_RHSs
    #    below when we enforce the gammahat=gammabar constraint
    # Step 1: All barred quantities are defined in terms of BSSN rescaled gridfunctions,
    #         which we declare here in case they haven't yet been declared elsewhere.

    Bq.declare_BSSN_gridfunctions_if_not_declared_already()
    hDD = Bq.hDD
    Bq.BSSN_basic_tensors()
    gammabarDD = Bq.gammabarDD

    # First define the Kronecker delta:
    KroneckerDeltaDD = ixp.zerorank2()
    for i in range(DIM):
        KroneckerDeltaDD[i][i] = sp.sympify(1)

    # The detgammabar in BSSN_RHSs is set to detgammahat when BSSN_RHSs::detgbarOverdetghat_equals_one=True (default),
    #    so we manually compute it here:
    dummygammabarUU, detgammabar = ixp.symm_matrix_inverter3x3(gammabarDD)

    # Next apply the constraint enforcement equation above.
    hprimeDD = ixp.zerorank2()
    for i in range(DIM):
        for j in range(DIM):
            hprimeDD[i][j] = \
                (nrpyAbs(rfm.detgammahat) / detgammabar) ** (sp.Rational(1, 3)) * (KroneckerDeltaDD[i][j] + hDD[i][j]) \
                - KroneckerDeltaDD[i][j]

    enforce_detg_constraint_symb_expressions = [
        lhrh(lhs=gri.gfaccess("in_gfs", "hDD00"), rhs=hprimeDD[0][0]),
        lhrh(lhs=gri.gfaccess("in_gfs", "hDD01"), rhs=hprimeDD[0][1]),
        lhrh(lhs=gri.gfaccess("in_gfs", "hDD02"), rhs=hprimeDD[0][2]),
        lhrh(lhs=gri.gfaccess("in_gfs", "hDD11"), rhs=hprimeDD[1][1]),
        lhrh(lhs=gri.gfaccess("in_gfs", "hDD12"), rhs=hprimeDD[1][2]),
        lhrh(lhs=gri.gfaccess("in_gfs", "hDD22"), rhs=hprimeDD[2][2])
    ]

    return enforce_detg_constraint_symb_expressions
def Aph_SM(r, theta, phi, **params):
    M = params["M"]
    a = params["a"]
    # A_\phi = M^2 C [1-\cos \theta + a^2 f(r) cos \theta sin^2 \theta]
    return M * M * C_SM * (sp.sympify(1) - nrpyAbs(sp.cos(theta)) + a * a *
                           f_of_r(r, M) * sp.cos(theta) * sp.sin(theta)**2)
def GiRaFFE_NRPy_C2P(StildeD,BU,gammaDD,betaU,alpha):
    GRHD.compute_sqrtgammaDET(gammaDD)
    gammaUU,unusedgammadet = ixp.symm_matrix_inverter3x3(gammaDD)
    BtildeU = ixp.zerorank1()
    for i in range(3):
        # \tilde{B}^i = B^i \sqrt{\gamma}
        BtildeU[i] = GRHD.sqrtgammaDET*BU[i]

    BtildeD = ixp.zerorank1()
    for i in range(3):
        for j in range(3):
            BtildeD[j] += gammaDD[i][j]*BtildeU[i]

    Btilde2 = sp.sympify(0)
    for i in range(3):
        Btilde2 += BtildeU[i]*BtildeD[i]

    global outStildeD
    outStildeD = StildeD
    # Then, enforce the orthogonality:
    if par.parval_from_str("enforce_orthogonality_StildeD_BtildeU"):
        StimesB = sp.sympify(0)
        for i in range(3):
            StimesB += StildeD[i]*BtildeU[i]

        for i in range(3):
            # {\tilde S}_i = {\tilde S}_i - ({\tilde S}_j {\tilde B}^j) {\tilde B}_i/{\tilde B}^2
            outStildeD[i] -= StimesB*BtildeD[i]/Btilde2

    # Calculate \tilde{S}^2:
    Stilde2 = sp.sympify(0)
    for i in range(3):
        for j in range(3):
            Stilde2 += gammaUU[i][j]*outStildeD[i]*outStildeD[j]

    # First we need to compute the factor f:
    # f = \sqrt{(1-\Gamma_{\max}^{-2}){\tilde B}^4/(16 \pi^2 \gamma {\tilde S}^2)}
    speed_limit_factor = sp.sqrt((sp.sympify(1)-GAMMA_SPEED_LIMIT**(-2.0))*Btilde2*Btilde2*sp.Rational(1,16)/\
                                 (M_PI*M_PI*GRHD.sqrtgammaDET*GRHD.sqrtgammaDET*Stilde2))

    import Min_Max_and_Piecewise_Expressions as noif

    # Calculate B^2
    B2 = sp.sympify(0)
    for i in range(3):
        for j in range(3):
            B2 += gammaDD[i][j]*BU[i]*BU[j]

    # Enforce the speed limit on StildeD:
    if par.parval_from_str("enforce_speed_limit_StildeD"):
        for i in range(3):
            outStildeD[i] *= noif.min_noif(sp.sympify(1),speed_limit_factor)

    global ValenciavU
    ValenciavU = ixp.zerorank1()
    # Recompute 3-velocity:
    for i in range(3):
        for j in range(3):
            # \bar{v}^i = 4 \pi \gamma^{ij} {\tilde S}_j / (\sqrt{\gamma} B^2)
            ValenciavU[i] += sp.sympify(4)*M_PI*gammaUU[i][j]*outStildeD[j]/(GRHD.sqrtgammaDET*B2)

    # This number determines how far away (in grid points) we will apply the fix.
    grid_points_from_z_plane = par.Cparameters("REAL",thismodule,"grid_points_from_z_plane",4.0)

    if par.parval_from_str("enforce_current_sheet_prescription"):
        # Calculate the drift velocity
        driftvU = ixp.zerorank1()
        for i in range(3):
            driftvU[i] = alpha*ValenciavU[i] - betaU[i]

        # The direct approach, used by the original GiRaFFE:
        # v^z = -(\gamma_{xz} v^x + \gamma_{yz} v^y) / \gamma_{zz}
        newdriftvU2 = -(gammaDD[0][2]*driftvU[0] + gammaDD[1][2]*driftvU[1])/gammaDD[2][2]
        # Now that we have the z component, it's time to substitute its Valencia form in.
        # Remember, we only do this if abs(z) < (k+0.01)*dz. Note that we add 0.01; this helps
        # avoid floating point errors and division by zero. This is the same as abs(z) - (k+0.01)*dz<0
        coord = nrpyAbs(rfm.xx[2])
        bound =(grid_points_from_z_plane+sp.Rational(1,100))*gri.dxx[2]
        ValenciavU[2] = noif.coord_leq_bound(coord,bound)*(newdriftvU2+betaU[2])/alpha \
                      + noif.coord_greater_bound(coord,bound)*ValenciavU[2]