Example #1
0
def vc_contra_y_edge(vc: FloatField, cosa_v: FloatFieldIJ,
                     uc_contra: FloatField, vc_contra: FloatField):
    from __externals__ import i_end, i_start, j_end, j_start, local_je, local_js

    # This works for 6 ranks, but not 54:
    # with horizontal(region[i_start - 1: i_start + 1, j_start + 2:j_end], \
    #                region[i_end : i_end + 2, j_start+2:j_end]):
    #    vt = vc - 0.25 * cosa_v * (
    #        ut[0, -1, 0] + ut[1, -1, 0] + ut + ut[1, 0, 0]
    #    )
    # original bounds with stencil calls
    # j1 = grid().js + 2 if grid().south_edge else grid().js
    # j2 = grid().je if grid().north_edge else grid().je + 2
    # TODO: this is a hack, copying vt to vtmp to 'correct' the edges
    # Can we *just* apply edge calculations in the correct regions without overcomputing
    # rank 0, 1, 2: local_js + 2:local_je + 2
    # rank 3, 4, 5: local_js:local_je + 2
    # rank 6, 7, 8: local_js:local_je
    with computation(PARALLEL), interval(...):
        vtmp = vc_contra
        with horizontal(
                region[i_start - 1:i_start + 1, local_js:local_je + 2],
                region[i_end:i_end + 2, local_js:local_je + 2],
        ):
            u_contra = 0.25 * (uc_contra[0, -1, 0] + uc_contra[1, -1, 0] +
                               uc_contra + uc_contra[1, 0, 0])
            vc_contra = contravariant(vc, u_contra, cosa_v, 1.0)
        with horizontal(
                region[i_start - 1:i_start + 1, j_start:j_start + 2],
                region[i_end:i_end + 2, j_start:j_start + 2],
                region[i_start - 1:i_start + 1, j_end:j_end + 2],
                region[i_end:i_end + 2, j_end:j_end + 2],
        ):
            vc_contra = vtmp
Example #2
0
def main_uc_contra(
    uc: FloatField,
    vc: FloatField,
    cosa_u: FloatFieldIJ,
    rsin_u: FloatFieldIJ,
    uc_contra: FloatField,
):
    """
    Args:
        uc: covariant c-grid x-wind (in)
        vc: covariant c-grid y-wind (in)
        cosa_u: ??? (in)
        rsin_u: ??? (in)
        uc_contra: contravariant c-grid x-wind (out)
    """
    from __externals__ import j_end, j_start, local_ie, local_is

    with computation(PARALLEL), interval(...):
        utmp = uc_contra
        with horizontal(region[local_is - 1:local_ie + 3, :]):
            # for C-grid, v must be regridded to lie at the same point as u
            v = 0.25 * (vc[-1, 0, 0] + vc + vc[-1, 1, 0] + vc[0, 1, 0])
            uc_contra = contravariant(uc, v, cosa_u, rsin_u)
        with horizontal(region[:, j_start - 1:j_start + 1],
                        region[:, j_end:j_end + 2]):
            uc_contra = utmp
Example #3
0
def interpolate_uc_vc_to_cell_corners(
    uc_cov, vc_cov, cosa, rsina, uc_contra, vc_contra
):
    """
    Convert covariant C-grid winds to contravariant B-grid (cell-corner) winds.
    """
    from __externals__ import i_end, i_start, j_end, j_start

    # In the original Fortran, this routine was given dt4 (0.25 * dt)
    # and dt5 (0.5 * dt), and its outputs were wind times timestep. This has
    # been refactored so the timestep is later explicitly multiplied, when
    # the wind is integrated forward in time.
    # TODO: ask Lucas why we interpolate then convert to contravariant in tile center,
    # but convert to contravariant and then interpolate on tile edges.
    ub_cov = 0.5 * (uc_cov[0, -1, 0] + uc_cov)
    vb_cov = 0.5 * (vc_cov[-1, 0, 0] + vc_cov)
    ub_contra = contravariant(ub_cov, vb_cov, cosa, rsina)
    vb_contra = contravariant(vb_cov, ub_cov, cosa, rsina)
    # ASSUME : if __INLINED(namelist.grid_type < 3):
    with horizontal(region[:, j_start], region[:, j_end + 1]):
        ub_contra = 0.25 * (
            -uc_contra[0, -2, 0]
            + 3.0 * (uc_contra[0, -1, 0] + uc_contra)
            - uc_contra[0, 1, 0]
        )
    with horizontal(region[i_start, :], region[i_end + 1, :]):
        ub_contra = 0.5 * (uc_contra[0, -1, 0] + uc_contra)
    with horizontal(region[i_start, :], region[i_end + 1, :]):
        vb_contra = 0.25 * (
            -vc_contra[-2, 0, 0]
            + 3.0 * (vc_contra[-1, 0, 0] + vc_contra)
            - vc_contra[1, 0, 0]
        )
    with horizontal(region[:, j_start], region[:, j_end + 1]):
        vb_contra = 0.5 * (vc_contra[-1, 0, 0] + vc_contra)

    return ub_contra, vb_contra
Example #4
0
def main_vc_contra(
    uc: FloatField,
    vc: FloatField,
    cosa_v: FloatFieldIJ,
    rsin_v: FloatFieldIJ,
    vc_contra: FloatField,
):
    from __externals__ import j_end, j_start, local_je, local_js

    with computation(PARALLEL), interval(...):
        vtmp = vc_contra
        with horizontal(region[:, local_js - 1:local_je + 3]):
            # for C-grid, u must be regridded to lie at same point as v
            u = 0.25 * (uc[0, -1, 0] + uc[1, -1, 0] + uc + uc[1, 0, 0])
            vc_contra = contravariant(vc, u, cosa_v, rsin_v)
        with horizontal(region[:, j_start], region[:, j_end + 1]):
            vc_contra = vtmp
Example #5
0
def uc_contra_x_edge(uc: FloatField, cosa_u: FloatFieldIJ,
                     vc_contra: FloatField, uc_contra: FloatField):
    from __externals__ import i_end, i_start, j_end, j_start, local_ie, local_is

    with computation(PARALLEL), interval(...):
        # TODO: parallel to what done for the vt_y_edge section
        utmp = uc_contra
        with horizontal(
                region[local_is:local_ie + 2, j_start - 1:j_start + 1],
                region[local_is:local_ie + 2, j_end:j_end + 2],
        ):
            v_contra = 0.25 * (vc_contra[-1, 0, 0] + vc_contra +
                               vc_contra[-1, 1, 0] + vc_contra[0, 1, 0])
            uc_contra = contravariant(uc, v_contra, cosa_u, 1.0)
        with horizontal(
                region[i_start:i_start + 2, j_start - 1:j_start + 1],
                region[i_start:i_start + 2, j_end:j_end + 2],
                region[i_end:i_end + 2, j_start - 1:j_start + 1],
                region[i_end:i_end + 2, j_end:j_end + 2],
        ):
            uc_contra = utmp
def get_delpc(
    u: FloatField,
    v: FloatField,
    ua: FloatField,
    va: FloatField,
    cosa_u: FloatFieldIJ,
    sina_u: FloatFieldIJ,
    dxc: FloatFieldIJ,
    dyc: FloatFieldIJ,
    uc: FloatField,
    vc: FloatField,
    sin_sg1: FloatFieldIJ,
    sin_sg2: FloatFieldIJ,
    sin_sg3: FloatFieldIJ,
    sin_sg4: FloatFieldIJ,
    cosa_v: FloatFieldIJ,
    sina_v: FloatFieldIJ,
    rarea_c: FloatFieldIJ,
    delpc: FloatField,
    u_contra_dyc: FloatField,
    v_contra_dxc: FloatField,
):
    from __externals__ import i_end, i_start, j_end, j_start

    # in the Fortran, u_contra_dyc is called ke and v_contra_dxc is called vort

    with computation(PARALLEL), interval(...):
        # TODO: why does vc_from_va sometimes have different sign than vc?
        vc_from_va = 0.5 * (va[0, -1, 0] + va)
        # TODO: why do we use vc_from_va and not just vc?
        u_contra = contravariant(u, vc_from_va, cosa_v, sina_v)
        with horizontal(region[:, j_start], region[:, j_end + 1]):
            u_contra = u * sin_sg4[0, -1] if vc > 0 else u * sin_sg2
        u_contra_dyc = u_contra * dyc

        # TODO: why does uc_from_ua sometimes have different sign than uc?
        uc_from_ua = 0.5 * (ua[-1, 0, 0] + ua)
        # TODO: why do we use uc_from_ua and not just uc?
        v_contra = contravariant(v, uc_from_ua, cosa_u, sina_u)
        with horizontal(region[i_start, :], region[i_end + 1, :]):
            v_contra = v * sin_sg3[-1, 0] if uc > 0 else v * sin_sg1
        v_contra_dxc = v_contra * dxc
        with horizontal(
            region[i_start, j_end + 1],
            region[i_end + 1, j_end + 1],
            region[i_start, j_start - 1],
            region[i_end + 1, j_start - 1],
        ):
            # TODO: seems odd that this adjustment is only needed for `v_contra_dxc`
            # but is not needed for `u_contra_dyc`. Is this a bug? Add a comment
            # describing what this adjustment is doing and why.
            v_contra_dxc = 0.0

    with computation(PARALLEL), interval(...):
        delpc = (
            v_contra_dxc[0, -1, 0]
            - v_contra_dxc
            + u_contra_dyc[-1, 0, 0]
            - u_contra_dyc
        )
        delpc = rarea_c * delpc