Esempio n. 1
0
    def __init__(self, direction: str,
                 stencil_factory: StencilFactory) -> None:
        """The grid for this stencil"""
        grid_indexing = stencil_factory.grid_indexing

        n_halo = grid_indexing.n_halo
        origin, domain = grid_indexing.get_origin_domain(
            dims=[X_DIM, Y_DIM, Z_INTERFACE_DIM], halos=(n_halo, n_halo))

        ax_offsets = axis_offsets(grid_indexing, origin, domain)
        if direction == "x":
            self._copy_corners = stencil_factory.from_origin_domain(
                func=copy_corners_x_stencil_defn,
                origin=origin,
                domain=domain,
                externals={
                    **ax_offsets,
                },
            )
        elif direction == "y":
            self._copy_corners = stencil_factory.from_origin_domain(
                func=copy_corners_y_stencil_defn,
                origin=origin,
                domain=domain,
                externals={
                    **ax_offsets,
                },
            )
        else:
            raise ValueError("Direction must be either 'x' or 'y'")
Esempio n. 2
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        damping_coefficients: DampingCoefficients,
        grid_data: GridData,
        grid_type: int,
        hord_tm: int,
        dp0: FloatFieldK,
        column_namelist,
        k_bounds,
    ):
        """
        Args:
            grid: fv3core grid object
            namelist: flattened fv3gfs namelist
            dp0: air pressure on interface levels, reference pressure
                can be used as an approximation
            column_namelist: ???
            k_bounds: ???
        """
        grid_indexing = stencil_factory.grid_indexing
        self.grid_indexing = grid_indexing
        self._area = grid_data.area
        self._column_namelist = column_namelist
        self._k_bounds = k_bounds  # d_sw.k_bounds()
        if any(column_namelist["damp_vt"][kstart] <= 1e-5
               for kstart in range(len(k_bounds))):
            raise NotImplementedError(
                "damp <= 1e-5 in column_cols is untested")
        self._dp0 = dp0
        self._allocate_temporary_storages(grid_indexing)
        self._initialize_interpolation_constants(
            stencil_factory=stencil_factory, grid_indexing=grid_indexing)

        self._interpolate_to_layer_interface = stencil_factory.from_origin_domain(
            cubic_spline_interpolation_from_layer_center_to_interfaces,
            origin=grid_indexing.origin_full(),
            domain=grid_indexing.domain_full(add=(0, 0, 1)),
        )
        self._apply_height_fluxes = stencil_factory.from_origin_domain(
            apply_height_fluxes,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(add=(0, 0, 1)),
        )
        self.delnflux = DelnFluxNoSG(
            stencil_factory,
            damping_coefficients,
            grid_data.rarea,
            self._column_namelist["nord_v"],
            nk=grid_indexing.domain[2] + 1,
        )
        self.finite_volume_transport = FiniteVolumeTransport(
            stencil_factory=stencil_factory,
            grid_data=grid_data,
            damping_coefficients=damping_coefficients,
            grid_type=grid_type,
            hord=hord_tm,
        )
Esempio n. 3
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        damping_coefficients: DampingCoefficients,
        rarea,
        nord: FloatFieldK,
        damp_c: FloatFieldK,
    ):
        """
        nord sets the order of damping to apply:
        nord = 0:   del-2
        nord = 1:   del-4
        nord = 2:   del-6

        nord and damp_c define the damping coefficient used in DelnFluxNoSG
        """
        self._no_compute = False
        if (damp_c <= 1e-4).all():
            self._no_compute = True
        elif (damp_c[:-1] <= 1e-4).any():
            raise NotImplementedError(
                "damp_c currently must be always greater than 10^-4 for delnflux"
            )
        grid_indexing = stencil_factory.grid_indexing
        nk = grid_indexing.domain[2]
        self._origin = grid_indexing.origin_full()

        shape = grid_indexing.max_shape
        k_shape = (1, 1, nk)

        self._damp_3d = utils.make_storage_from_shape(k_shape)
        # fields must be 3d to assign to them
        self._fx2 = utils.make_storage_from_shape(shape)
        self._fy2 = utils.make_storage_from_shape(shape)
        self._d2 = utils.make_storage_from_shape(grid_indexing.domain_full())

        damping_factor_calculation = stencil_factory.from_origin_domain(
            calc_damp, origin=(0, 0, 0), domain=k_shape
        )
        self._add_diffusive_stencil = stencil_factory.from_dims_halo(
            func=add_diffusive_component,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
        )
        self._diffusive_damp_stencil = stencil_factory.from_dims_halo(
            func=diffusive_damp, compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM]
        )

        damping_factor_calculation(
            self._damp_3d, nord, damp_c, damping_coefficients.da_min
        )
        self._damp = utils.make_storage_data(self._damp_3d[0, 0, :], (nk,), (0,))

        self.delnflux_nosg = DelnFluxNoSG(
            stencil_factory, damping_coefficients, rarea, nord, nk=nk
        )
Esempio n. 4
0
    def __init__(self, stencil_factory: StencilFactory, grid_data: GridData, grid_type):
        grid_indexing = stencil_factory.grid_indexing
        self.orig = grid_indexing.origin_compute()
        domain_full_k = grid_indexing.domain_compute(add=(1, 1, 0))
        u_domain = grid_indexing.domain_compute(add=(0, 1, 0))
        v_domain = grid_indexing.domain_compute(add=(1, 0, 0))
        self.nk = grid_indexing.domain[2]
        self._rdx = grid_data.rdx
        self._rdy = grid_data.rdy

        self._tmp_wk = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=self.orig
        )  # pk3.shape
        self._tmp_wk1 = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=self.orig
        )  # pp.shape

        self._set_k0_and_calc_wk_stencil = stencil_factory.from_origin_domain(
            set_k0_and_calc_wk,
            origin=self.orig,
            domain=domain_full_k,
        )

        self._calc_u_stencil = stencil_factory.from_origin_domain(
            calc_u,
            origin=self.orig,
            domain=u_domain,
        )

        self._calc_v_stencil = stencil_factory.from_origin_domain(
            calc_v,
            origin=self.orig,
            domain=v_domain,
        )
        self.a2b_k1 = AGrid2BGridFourthOrder(
            stencil_factory.restrict_vertical(k_start=1),
            grid_data,
            grid_type,
            z_dim=Z_INTERFACE_DIM,
            replace=True,
        )
        self.a2b_kbuffer = AGrid2BGridFourthOrder(
            stencil_factory,
            grid_data,
            grid_type,
            z_dim=Z_INTERFACE_DIM,
            replace=True,
        )
        self.a2b_kstandard = AGrid2BGridFourthOrder(
            stencil_factory,
            grid_data,
            grid_type,
            replace=False,
        )
    def __init__(
        self,
        stencil_factory: StencilFactory,
        kord: int,
        mode: int,
        i1: int,
        i2: int,
        j1: int,
        j2: int,
    ):
        # TODO: consider refactoring to take in origin and domain
        grid_indexing = stencil_factory.grid_indexing
        shape = grid_indexing.domain_full(add=(1, 1, 1))
        origin = grid_indexing.origin_compute()

        self._dp1 = utils.make_storage_from_shape(shape, origin=origin)
        self._q4_1 = utils.make_storage_from_shape(shape, origin=origin)
        self._q4_2 = utils.make_storage_from_shape(shape, origin=origin)
        self._q4_3 = utils.make_storage_from_shape(shape, origin=origin)
        self._q4_4 = utils.make_storage_from_shape(shape, origin=origin)
        self._tmp_qs = utils.make_storage_from_shape(shape[0:2], origin=(0, 0))
        self._lev = utils.make_storage_from_shape(
            shape[:-1],
            origin=origin[:-1],
            mask=(True, True, False),
            dtype=int,
        )

        self._extents = (i2 - i1 + 1, j2 - j1 + 1)
        origin = (i1, j1, 0)
        domain = (*self._extents, grid_indexing.domain[2])

        self._lagrangian_contributions = stencil_factory.from_origin_domain(
            lagrangian_contributions,
            origin=origin,
            domain=domain,
        )
        self._remap_profile = RemapProfile(stencil_factory, kord, mode, i1, i2,
                                           j1, j2)

        self._set_dp = stencil_factory.from_origin_domain(set_dp,
                                                          origin=origin,
                                                          domain=domain)
        self._copy_stencil = stencil_factory.from_origin_domain(
            copy_defn,
            origin=(0, 0, 0),
            domain=grid_indexing.domain_full(),
        )
    def __init__(
        self,
        stencil_factory: StencilFactory,
        grid_data: GridData,
        grid_type: int,
        jord: int,
    ):
        if jord not in (5, 6, 7, 8):
            raise NotImplementedError(
                "Currently ytp_v is only supported for hord_mt == 5,6,7,8")
        assert grid_type < 3
        grid_indexing = stencil_factory.grid_indexing

        origin = grid_indexing.origin_compute()
        domain = grid_indexing.domain_compute(add=(1, 1, 0))
        self._dy = grid_data.dy
        self._dya = grid_data.dya
        self._rdy = grid_data.rdy
        ax_offsets = axis_offsets(grid_indexing, origin, domain)

        self.stencil = stencil_factory.from_origin_domain(
            ytp_v_stencil_defn,
            externals={
                "jord": jord,
                "mord": jord,
                "yt_minmax": False,
                **ax_offsets,
            },
            origin=origin,
            domain=domain,
            skip_passes=("GreedyMerging", ),
        )
def get_stencils_with_varied_bounds(
    func: Callable[..., None],
    origins: List[Index3D],
    domains: List[Index3D],
    stencil_factory: StencilFactory,
    externals: Optional[Mapping[str, Any]] = None,
) -> List[FrozenStencil]:
    assert len(origins) == len(domains), (
        "Lists of origins and domains need to have the same length, you provided "
        + str(len(origins))
        + " origins and "
        + str(len(domains))
        + " domains"
    )
    if externals is None:
        externals = {}
    stencils = []
    for origin, domain in zip(origins, domains):
        ax_offsets = fv3core.utils.grid.axis_offsets(spec.grid, origin, domain)
        stencils.append(
            stencil_factory.from_origin_domain(
                func,
                origin=origin,
                domain=domain,
                externals={**externals, **ax_offsets},
            )
        )
    return stencils
Esempio n. 8
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        dims: Sequence[str],
        y_field,
    ) -> None:
        """
        Args:
            stencil_factory: creates stencils
            dims: dimensionality of the data to be copied
            y_field: 3D gt4py storage to use for y-differenceable field
                (x-differenceable field uses same memory as base field)
        """
        grid_indexing = stencil_factory.grid_indexing
        origin, domain = grid_indexing.get_origin_domain(
            dims=dims, halos=(grid_indexing.n_halo, grid_indexing.n_halo))

        self._y_field = y_field

        ax_offsets = axis_offsets(grid_indexing, origin, domain)
        self._copy_corners_xy = stencil_factory.from_origin_domain(
            func=copy_corners_xy_stencil_defn,
            origin=origin,
            domain=domain,
            externals={
                **ax_offsets,
            },
        )
Esempio n. 9
0
 def __init__(
     self,
     stencil_factory: StencilFactory,
     dxa,
     grid_type: int,
     iord,
     origin: Index3D,
     domain: Index3D,
 ):
     # Arguments come from:
     # namelist.grid_type
     # grid.dxa
     assert grid_type < 3
     self._dxa = dxa
     ax_offsets = stencil_factory.grid_indexing.axis_offsets(origin, domain)
     self._compute_flux_stencil = stencil_factory.from_origin_domain(
         func=compute_x_flux,
         externals={
             "iord": iord,
             "mord": abs(iord),
             "xt_minmax": True,
             "i_start": ax_offsets["i_start"],
             "i_end": ax_offsets["i_end"],
         },
         origin=origin,
         domain=domain,
     )
Esempio n. 10
0
 def __init__(
     self, stencil_factory: StencilFactory, grid_data: GridData, order: int
 ):
     """
     Initializes stencils to use either 2nd or 4th order of interpolation
     based on namelist setting
     Args:
         stencil_factory: creates stencils
         grid_data: object with metric terms
         order: Order of interpolation, must be 2 or 4
     """
     grid_indexing = stencil_factory.grid_indexing
     self._n_halo = grid_indexing.n_halo
     self._dx = grid_data.dx
     self._dy = grid_data.dy
     # TODO: define these based on data from grid_data
     self._a11 = spec.grid.a11
     self._a12 = spec.grid.a12
     self._a21 = spec.grid.a21
     self._a22 = spec.grid.a22
     if order == 2:
         self._do_ord4 = False
         halos = (1, 1)
         func = c2l_ord2
     else:
         self._do_ord4 = True
         halos = (0, 0)
         func = ord4_transform
     self._compute_cubed_to_latlon = stencil_factory.from_dims_halo(
         func=func, compute_dims=[X_DIM, Y_DIM, Z_DIM], compute_halos=halos
     )
Esempio n. 11
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        im: int,
        jm: int,
        km: int,
        nq: int,
    ):
        self._nq = nq
        self._fix_tracer_stencil = stencil_factory.from_origin_domain(
            fix_tracer,
            origin=stencil_factory.grid_indexing.origin_compute(),
            domain=(im, jm, km),
        )

        shape = stencil_factory.grid_indexing.domain_full(add=(1, 1, 1))
        shape_ij = shape[0:2]

        self._dm = utils.make_storage_from_shape(shape, origin=(0, 0, 0))
        self._dm_pos = utils.make_storage_from_shape(shape, origin=(0, 0, 0))
        # Setting initial value of upper_fix to zero is only needed for validation.
        # The values in the compute domain are set to zero in the stencil.
        self._zfix = utils.make_storage_from_shape(shape_ij,
                                                   dtype=int,
                                                   origin=(0, 0))
        self._sum0 = utils.make_storage_from_shape(shape_ij, origin=(0, 0))
        self._sum1 = utils.make_storage_from_shape(shape_ij, origin=(0, 0))
Esempio n. 12
0
    def _initialize_interpolation_constants(self,
                                            stencil_factory: StencilFactory,
                                            grid_indexing: GridIndexing):
        # because stencils only work on 3D at the moment, need to compute in 3D
        # and then make these 1D
        gk_3d = utils.make_storage_from_shape(
            (1, 1, grid_indexing.domain[2] + 1), (0, 0, 0))
        gamma_3d = utils.make_storage_from_shape(
            (1, 1, grid_indexing.domain[2] + 1), (0, 0, 0))
        beta_3d = utils.make_storage_from_shape(
            (1, 1, grid_indexing.domain[2] + 1), (0, 0, 0))

        _cubic_spline_interpolation_constants = stencil_factory.from_origin_domain(
            cubic_spline_interpolation_constants,
            origin=(0, 0, 0),
            domain=(1, 1, grid_indexing.domain[2] + 1),
        )

        _cubic_spline_interpolation_constants(self._dp0, gk_3d, beta_3d,
                                              gamma_3d)
        self._gk = utils.make_storage_data(gk_3d[0, 0, :], gk_3d.shape[2:],
                                           (0, ))
        self._beta = utils.make_storage_data(beta_3d[0, 0, :],
                                             beta_3d.shape[2:], (0, ))
        self._gamma = utils.make_storage_data(gamma_3d[0, 0, :],
                                              gamma_3d.shape[2:], (0, ))
        self._copy_corners = PreAllocatedCopiedCornersFactory(
            stencil_factory=stencil_factory,
            dims=[
                fv3gfs.util.X_DIM, fv3gfs.util.Y_DIM,
                fv3gfs.util.Z_INTERFACE_DIM
            ],
            y_temporary=None,
        )
Esempio n. 13
0
 def __init__(
     self,
     stencil_factory: StencilFactory,
     grid_data: GridData,
 ):
     grid_indexing = stencil_factory.grid_indexing
     self._dx = grid_data.dx
     self._dy = grid_data.dy
     self._rdxa = grid_data.rdxa
     self._rdya = grid_data.rdya
     self._cosa_u = grid_data.cosa_u
     self._cosa_v = grid_data.cosa_v
     self._rsin_u = grid_data.rsin_u
     self._rsin_v = grid_data.rsin_v
     self._sin_sg1 = grid_data.sin_sg1
     self._sin_sg2 = grid_data.sin_sg2
     self._sin_sg3 = grid_data.sin_sg3
     self._sin_sg4 = grid_data.sin_sg4
     origin = grid_indexing.origin_full()
     domain = grid_indexing.domain_full()
     ax_offsets = axis_offsets(grid_indexing, origin, domain)
     kwargs = {"externals": ax_offsets, "origin": origin, "domain": domain}
     origin_corners = grid_indexing.origin_full(add=(1, 1, 0))
     domain_corners = grid_indexing.domain_full(add=(-1, -1, 0))
     corner_offsets = axis_offsets(grid_indexing, origin_corners,
                                   domain_corners)
     kwargs_corners = {
         "externals": corner_offsets,
         "origin": origin_corners,
         "domain": domain_corners,
     }
     self._main_uc_contra_stencil = stencil_factory.from_origin_domain(
         main_uc_contra, **kwargs)
     self._main_vc_contra_stencil = stencil_factory.from_origin_domain(
         main_vc_contra, **kwargs)
     self._uc_contra_y_edge_stencil = stencil_factory.from_origin_domain(
         uc_contra_y_edge, **kwargs)
     self._vc_contra_y_edge_stencil = stencil_factory.from_origin_domain(
         vc_contra_y_edge, **kwargs)
     self._uc_contra_x_edge_stencil = stencil_factory.from_origin_domain(
         uc_contra_x_edge, **kwargs)
     self._vc_contra_x_edge_stencil = stencil_factory.from_origin_domain(
         vc_contra_x_edge, **kwargs)
     self._uc_contra_corners_stencil = stencil_factory.from_origin_domain(
         uc_contra_corners, **kwargs_corners)
     self._vc_contra_corners_stencil = stencil_factory.from_origin_domain(
         vc_contra_corners, **kwargs_corners)
     self._fxadv_fluxes_stencil = stencil_factory.from_origin_domain(
         fxadv_fluxes_stencil, **kwargs)
Esempio n. 14
0
 def __init__(self, stencil_factory: StencilFactory, p_fac, istart, iend,
              jstart, jend, nk):
     self._pfac = p_fac
     nic = iend - istart + 1
     njc = jend - jstart + 1
     self._compute_sim1_solve = stencil_factory.from_origin_domain(
         func=sim1_solver,
         origin=(istart, jstart, 0),
         domain=(nic, njc, nk),
     )
Esempio n. 15
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        check_negative: bool,
        hydrostatic: bool,
    ):
        grid_indexing = stencil_factory.grid_indexing
        shape_ij = grid_indexing.domain_full(add=(1, 1, 0))[:2]
        self._sum1 = utils.make_storage_from_shape(shape_ij, origin=(0, 0))
        self._sum2 = utils.make_storage_from_shape(shape_ij, origin=(0, 0))
        if check_negative:
            raise NotImplementedError(
                "Unimplemented namelist value check_negative=True")
        if hydrostatic:
            self._d0_vap = constants.CP_VAP - constants.C_LIQ
            raise NotImplementedError(
                "Unimplemented namelist hydrostatic=True")
        else:
            self._d0_vap = constants.CV_VAP - constants.C_LIQ
        self._lv00 = constants.HLV - self._d0_vap * constants.TICE

        self._fix_neg_water = stencil_factory.from_origin_domain(
            func=fix_neg_water,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )
        self._fillq = stencil_factory.from_origin_domain(
            func=fillq,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )
        self._fix_water_vapor_down = stencil_factory.from_origin_domain(
            func=fix_water_vapor_down,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )
        self._fix_neg_cloud = stencil_factory.from_origin_domain(
            func=fix_neg_cloud,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )
Esempio n. 16
0
    def __init__(self, stencil_factory: StencilFactory, area):
        grid_indexing = stencil_factory.grid_indexing
        self._area = area
        largest_possible_shape = grid_indexing.domain_full(add=(1, 1, 1))
        self._gz_x = gt4py_utils.make_storage_from_shape(
            largest_possible_shape,
            grid_indexing.origin_compute(add=(0, -grid_indexing.n_halo, 0)),
        )
        self._gz_y = gt4py_utils.make_storage_from_shape(
            largest_possible_shape,
            grid_indexing.origin_compute(add=(0, -grid_indexing.n_halo, 0)),
        )
        full_origin = grid_indexing.origin_full()
        full_domain = grid_indexing.domain_full(add=(0, 0, 1))
        self._double_copy_stencil = stencil_factory.from_origin_domain(
            double_copy,
            origin=full_origin,
            domain=full_domain,
        )

        ax_offsets = axis_offsets(grid_indexing, full_origin, full_domain)
        self._fill_corners_x_stencil = stencil_factory.from_origin_domain(
            corners.fill_corners_2cells_x_stencil,
            externals=ax_offsets,
            origin=full_origin,
            domain=full_domain,
        )
        self._fill_corners_y_stencil = stencil_factory.from_origin_domain(
            corners.fill_corners_2cells_y_stencil,
            externals=ax_offsets,
            origin=full_origin,
            domain=full_domain,
        )
        self._update_dz_c = stencil_factory.from_origin_domain(
            update_dz_c,
            origin=grid_indexing.origin_compute(add=(-1, -1, 0)),
            domain=grid_indexing.domain_compute(add=(2, 2, 1)),
        )
Esempio n. 17
0
 def __init__(self, stencil_factory: StencilFactory, config: RiemannConfig):
     grid_indexing = stencil_factory.grid_indexing
     self._sim1_solve = Sim1Solver(
         stencil_factory,
         config.p_fac,
         grid_indexing.isc,
         grid_indexing.iec,
         grid_indexing.jsc,
         grid_indexing.jec,
         grid_indexing.domain[2] + 1,
     )
     if config.a_imp <= 0.999:
         raise NotImplementedError("a_imp <= 0.999 is not implemented")
     riemorigin = grid_indexing.origin_compute()
     domain = grid_indexing.domain_compute(add=(0, 0, 1))
     shape = grid_indexing.max_shape
     self._tmp_dm = utils.make_storage_from_shape(shape, riemorigin)
     self._tmp_pe_init = utils.make_storage_from_shape(shape, riemorigin)
     self._tmp_pm = utils.make_storage_from_shape(shape, riemorigin)
     self._tmp_pem = utils.make_storage_from_shape(shape, riemorigin)
     self._tmp_peln_run = utils.make_storage_from_shape(shape, riemorigin)
     self._tmp_gm = utils.make_storage_from_shape(shape, riemorigin)
     self._precompute_stencil = stencil_factory.from_origin_domain(
         precompute,
         origin=riemorigin,
         domain=domain,
     )
     self._finalize_stencil = stencil_factory.from_origin_domain(
         finalize,
         externals={
             "use_logp": config.use_logp,
             "beta": config.beta
         },
         origin=riemorigin,
         domain=domain,
     )
Esempio n. 18
0
 def __init__(self, stencil_factory: StencilFactory):
     grid_indexing = stencil_factory.grid_indexing
     origin = grid_indexing.origin_full()
     domain = grid_indexing.domain_full(add=(0, 0, 1))
     ax_offsets = axis_offsets(grid_indexing, origin, domain)
     self._edge_pe_update = stencil_factory.from_origin_domain(
         func=edge_pe_update,
         externals={
             **ax_offsets,
         },
         origin=origin,
         domain=domain,
     )
     shape_2D = grid_indexing.domain_full(add=(1, 1, 1))[0:2]
     self._pe_tmp = utils.make_storage_from_shape(
         shape_2D, grid_indexing.origin_full())
Esempio n. 19
0
def get_stencil_factory(backend) -> StencilFactory:
    config = StencilConfig(
        backend=backend,
        rebuild=False,
        validate_args=False,
        format_source=False,
        device_sync=False,
    )
    indexing = GridIndexing(
        domain=(12, 12, 79),
        n_halo=3,
        south_edge=False,
        north_edge=False,
        west_edge=False,
        east_edge=False,
    )
    return StencilFactory(config=config, grid_indexing=indexing)
Esempio n. 20
0
    def __init__(
        self,
        direction: str,
        stencil_factory: StencilFactory,
        temporary_field=None,
        origin=None,
        domain=None,
    ) -> None:

        n_halo = stencil_factory.grid_indexing.n_halo
        (
            default_origin,
            default_domain,
        ) = stencil_factory.grid_indexing.get_origin_domain(
            dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_INTERFACE_DIM],
            halos=(n_halo, n_halo),
        )

        if origin is None:
            origin = default_origin
        """The origin for the corner computation"""
        if domain is None:
            domain = default_domain
        """The full domain required to do corner computation everywhere"""

        if temporary_field is not None:
            self._corner_tmp = temporary_field
        else:
            self._corner_tmp = utils.make_storage_from_shape(
                stencil_factory.grid_indexing.max_shape, origin=origin)

        if direction == "x":
            defn = fill_corners_bgrid_x_defn
        elif direction == "y":
            defn = fill_corners_bgrid_y_defn
        else:
            raise ValueError("Direction must be either 'x' or 'y'")
        externals = axis_offsets(stencil_factory.grid_indexing,
                                 origin=origin,
                                 domain=domain)
        self._fill_corners_bgrid = stencil_factory.from_origin_domain(
            func=defn, origin=origin, domain=domain, externals=externals)
Esempio n. 21
0
    def __init__(self, stencil_factory: StencilFactory, rf_cutoff, tau,
                 hydrostatic):
        grid_indexing = stencil_factory.grid_indexing
        self._rf_cutoff = rf_cutoff
        origin, domain = grid_indexing.get_origin_domain(
            [X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM])

        ax_offsets = axis_offsets(grid_indexing, origin, domain)
        local_axis_offsets = {}
        for axis_offset_name, axis_offset_value in ax_offsets.items():
            if "local" in axis_offset_name:
                local_axis_offsets[axis_offset_name] = axis_offset_value

        self._ray_fast_wind_compute = stencil_factory.from_origin_domain(
            ray_fast_wind_compute,
            origin=origin,
            domain=domain,
            externals={
                "hydrostatic": hydrostatic,
                "rf_cutoff": rf_cutoff,
                "tau": tau,
                **local_axis_offsets,
            },
        )
Esempio n. 22
0
    def __init__(
        self,
        comm: fv3gfs.util.CubedSphereCommunicator,
        stencil_factory: StencilFactory,
        grid_data: GridData,
        damping_coefficients: DampingCoefficients,
        grid_type,
        nested,
        stretched_grid,
        config: AcousticDynamicsConfig,
        # TODO: move ak, bk, pfull, and phis into GridData
        ak: FloatFieldK,
        bk: FloatFieldK,
        pfull: FloatFieldK,
        phis: FloatFieldIJ,
    ):
        """
        Args:
            comm: object for cubed sphere inter-process communication
            stencil_factory: creates stencils
            grid_data: metric terms defining the grid
            damping_coefficients: damping configuration
            grid_type: ???
            nested: ???
            stretched_grid: ???
            config: configuration settings
            ak: atmosphere hybrid a coordinate (Pa)
            bk: atmosphere hybrid b coordinate (dimensionless)
            pfull: atmospheric Eulerian grid reference pressure (Pa)
            phis: surface geopotential height
        """
        grid_indexing = stencil_factory.grid_indexing
        self.comm = comm
        self.config = config
        assert config.d_ext == 0, "d_ext != 0 is not implemented"
        assert config.beta == 0, "beta != 0 is not implemented"
        assert not config.use_logp, "use_logp=True is not implemented"
        self._da_min = damping_coefficients.da_min
        self.grid_data = grid_data
        self._pfull = pfull
        self._nk_heat_dissipation = get_nk_heat_dissipation(
            config.d_grid_shallow_water,
            npz=grid_indexing.domain[2],
        )
        self.nonhydrostatic_pressure_gradient = (
            nh_p_grad.NonHydrostaticPressureGradient(stencil_factory,
                                                     grid_data,
                                                     config.grid_type))
        self._temporaries = dyncore_temporaries(grid_indexing)
        self._temporaries["gz"][:] = HUGE_R
        if not config.hydrostatic:
            self._temporaries["pk3"][:] = HUGE_R

        column_namelist = d_sw.get_column_namelist(config.d_grid_shallow_water,
                                                   grid_indexing.domain[2])
        if not config.hydrostatic:
            # To write lower dimensional storages, these need to be 3D
            # then converted to lower dimensional
            dp_ref_3d = utils.make_storage_from_shape(grid_indexing.max_shape)
            zs_3d = utils.make_storage_from_shape(grid_indexing.max_shape)

            dp_ref_stencil = stencil_factory.from_origin_domain(
                dp_ref_compute,
                origin=grid_indexing.origin_full(),
                domain=grid_indexing.domain_full(add=(0, 0, 1)),
            )
            dp_ref_stencil(
                ak,
                bk,
                phis,
                dp_ref_3d,
                zs_3d,
                1.0 / constants.GRAV,
            )
            # After writing, make 'dp_ref' a K-field and 'zs' an IJ-field
            self._dp_ref = utils.make_storage_data(dp_ref_3d[0, 0, :],
                                                   (dp_ref_3d.shape[2], ),
                                                   (0, ))
            self._zs = utils.make_storage_data(zs_3d[:, :, 0],
                                               zs_3d.shape[0:2], (0, 0))
            self.update_height_on_d_grid = updatedzd.UpdateHeightOnDGrid(
                stencil_factory,
                damping_coefficients,
                grid_data,
                grid_type,
                config.hord_tm,
                self._dp_ref,
                column_namelist,
                d_sw.k_bounds(),
            )
            self.riem_solver3 = RiemannSolver3(stencil_factory, config.riemann)
            self.riem_solver_c = RiemannSolverC(stencil_factory,
                                                p_fac=config.p_fac)
            origin, domain = grid_indexing.get_origin_domain(
                [X_DIM, Y_DIM, Z_INTERFACE_DIM], halos=(2, 2))
            self._compute_geopotential_stencil = stencil_factory.from_origin_domain(
                compute_geopotential,
                origin=origin,
                domain=domain,
            )
        self.dgrid_shallow_water_lagrangian_dynamics = (
            d_sw.DGridShallowWaterLagrangianDynamics(
                stencil_factory,
                grid_data,
                damping_coefficients,
                column_namelist,
                nested,
                stretched_grid,
                config.d_grid_shallow_water,
            ))
        self.cgrid_shallow_water_lagrangian_dynamics = CGridShallowWaterDynamics(
            stencil_factory,
            grid_data,
            nested,
            config.grid_type,
            config.nord,
        )

        self._set_gz = stencil_factory.from_origin_domain(
            set_gz,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(add=(0, 0, 1)),
        )
        self._set_pem = stencil_factory.from_origin_domain(
            set_pem,
            origin=grid_indexing.origin_compute(add=(-1, -1, 0)),
            domain=grid_indexing.domain_compute(add=(2, 2, 0)),
        )

        self._p_grad_c = stencil_factory.from_origin_domain(
            p_grad_c_stencil,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(add=(1, 1, 0)),
            externals={"hydrostatic": config.hydrostatic},
        )

        self.update_geopotential_height_on_c_grid = (
            updatedzc.UpdateGeopotentialHeightOnCGrid(stencil_factory,
                                                      grid_data.area))

        self._zero_data = stencil_factory.from_origin_domain(
            zero_data,
            origin=grid_indexing.origin_full(),
            domain=grid_indexing.domain_full(),
        )
        ax_offsets_pe = axis_offsets(
            grid_indexing,
            grid_indexing.origin_full(),
            grid_indexing.domain_full(add=(0, 0, 1)),
        )
        self._edge_pe_stencil = stencil_factory.from_origin_domain(
            pe_halo.edge_pe,
            origin=grid_indexing.origin_full(),
            domain=grid_indexing.domain_full(add=(0, 0, 1)),
            externals={**ax_offsets_pe},
        )
        """The stencil object responsible for updating the interface pressure"""

        self._do_del2cubed = self._nk_heat_dissipation != 0 and config.d_con > 1.0e-5

        if self._do_del2cubed:
            nf_ke = min(3, config.nord + 1)
            self._hyperdiffusion = HyperdiffusionDamping(stencil_factory,
                                                         damping_coefficients,
                                                         grid_data.rarea,
                                                         nmax=nf_ke)
        if config.rf_fast:
            self._rayleigh_damping = ray_fast.RayleighDamping(
                stencil_factory,
                rf_cutoff=config.rf_cutoff,
                tau=config.tau,
                hydrostatic=config.hydrostatic,
            )
        self._compute_pkz_tempadjust = stencil_factory.from_origin_domain(
            temperature_adjust.compute_pkz_tempadjust,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.restrict_vertical(
                nk=self._nk_heat_dissipation).domain_compute(),
        )
        self._pk3_halo = PK3Halo(stencil_factory)
        self._copy_stencil = stencil_factory.from_origin_domain(
            basic.copy_defn,
            origin=grid_indexing.origin_full(),
            domain=grid_indexing.domain_full(add=(0, 0, 1)),
        )

        # Halo updaters
        self._halo_updaters = AcousticDynamics._HaloUpdaters(
            self.comm, grid_indexing)
Esempio n. 23
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        config: RemappingConfig,
        area_64,
        nq,
        pfull,
    ):
        grid_indexing = stencil_factory.grid_indexing
        if config.kord_tm >= 0:
            raise NotImplementedError(
                "map ppm, untested mode where kord_tm >= 0")
        hydrostatic = config.hydrostatic
        if hydrostatic:
            raise NotImplementedError("Hydrostatic is not implemented")

        shape_kplus = grid_indexing.domain_full(add=(0, 0, 1))
        self._t_min = 184.0
        self._nq = nq
        # do_omega = hydrostatic and last_step # TODO pull into inputs
        self._domain_jextra = (
            grid_indexing.domain[0],
            grid_indexing.domain[1] + 1,
            grid_indexing.domain[2] + 1,
        )

        self._pe1 = utils.make_storage_from_shape(shape_kplus)
        self._pe2 = utils.make_storage_from_shape(shape_kplus)
        self._dp2 = utils.make_storage_from_shape(shape_kplus)
        self._pn2 = utils.make_storage_from_shape(shape_kplus)
        self._pe0 = utils.make_storage_from_shape(shape_kplus)
        self._pe3 = utils.make_storage_from_shape(shape_kplus)

        self._gz: FloatField = utils.make_storage_from_shape(
            shape_kplus, grid_indexing.origin_compute())
        self._cvm: FloatField = utils.make_storage_from_shape(
            shape_kplus, grid_indexing.origin_compute())

        self._init_pe = stencil_factory.from_origin_domain(
            init_pe,
            origin=grid_indexing.origin_compute(),
            domain=self._domain_jextra)

        self._moist_cv_pt_pressure = stencil_factory.from_origin_domain(
            moist_cv_pt_pressure,
            externals={
                "kord_tm": config.kord_tm,
                "hydrostatic": hydrostatic
            },
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(add=(0, 0, 1)),
        )
        self._moist_cv_pkz = stencil_factory.from_origin_domain(
            moist_cv.moist_pkz,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )

        self._pn2_pk_delp = stencil_factory.from_origin_domain(
            pn2_pk_delp,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )

        self._kord_tm = abs(config.kord_tm)
        self._map_single_pt = MapSingle(
            stencil_factory,
            self._kord_tm,
            1,
            grid_indexing.isc,
            grid_indexing.iec,
            grid_indexing.jsc,
            grid_indexing.jec,
        )

        self._mapn_tracer = MapNTracer(
            stencil_factory,
            abs(config.kord_tr),
            nq,
            grid_indexing.isc,
            grid_indexing.iec,
            grid_indexing.jsc,
            grid_indexing.jec,
            fill=config.fill,
        )

        self._kord_wz = config.kord_wz
        self._map_single_w = MapSingle(
            stencil_factory,
            self._kord_wz,
            -2,
            grid_indexing.isc,
            grid_indexing.iec,
            grid_indexing.jsc,
            grid_indexing.jec,
        )
        self._map_single_delz = MapSingle(
            stencil_factory,
            self._kord_wz,
            1,
            grid_indexing.isc,
            grid_indexing.iec,
            grid_indexing.jsc,
            grid_indexing.jec,
        )

        self._undo_delz_adjust_and_copy_peln = stencil_factory.from_origin_domain(
            undo_delz_adjust_and_copy_peln,
            origin=grid_indexing.origin_compute(),
            domain=(
                grid_indexing.domain[0],
                grid_indexing.domain[1],
                grid_indexing.domain[2] + 1,
            ),
        )

        self._pressures_mapu = stencil_factory.from_origin_domain(
            pressures_mapu,
            origin=grid_indexing.origin_compute(),
            domain=self._domain_jextra,
        )

        self._kord_mt = config.kord_mt
        self._map_single_u = MapSingle(
            stencil_factory,
            self._kord_mt,
            -1,
            grid_indexing.isc,
            grid_indexing.iec,
            grid_indexing.jsc,
            grid_indexing.jec + 1,
        )

        self._pressures_mapv = stencil_factory.from_origin_domain(
            pressures_mapv,
            origin=grid_indexing.origin_compute(),
            domain=(
                grid_indexing.domain[0] + 1,
                grid_indexing.domain[1],
                grid_indexing.domain[2] + 1,
            ),
        )

        self._map_single_v = MapSingle(
            stencil_factory,
            self._kord_mt,
            -1,
            grid_indexing.isc,
            grid_indexing.iec + 1,
            grid_indexing.jsc,
            grid_indexing.jec,
        )

        ax_offsets_jextra = axis_offsets(
            grid_indexing,
            grid_indexing.origin_compute(),
            grid_indexing.domain_compute(add=(0, 1, 0)),
        )
        self._update_ua = stencil_factory.from_origin_domain(
            update_ua,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(add=(0, 1, 0)),
            externals={**ax_offsets_jextra},
        )

        self._copy_from_below_stencil = stencil_factory.from_origin_domain(
            copy_from_below,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )

        self._moist_cv_last_step_stencil = stencil_factory.from_origin_domain(
            moist_pt_last_step,
            origin=(grid_indexing.isc, grid_indexing.jsc, 0),
            domain=(
                grid_indexing.domain[0],
                grid_indexing.domain[1],
                grid_indexing.domain[2] + 1,
            ),
        )

        self._basic_adjust_divide_stencil = stencil_factory.from_origin_domain(
            adjust_divide_stencil,
            origin=grid_indexing.origin_compute(),
            domain=grid_indexing.domain_compute(),
        )

        self._do_sat_adjust = config.do_sat_adj

        self.kmp = grid_indexing.domain[2] - 1
        for k in range(pfull.shape[0]):
            if pfull[k] > 10.0e2:
                self.kmp = k
                break

        self._saturation_adjustment = SatAdjust3d(stencil_factory,
                                                  config.sat_adjust, area_64,
                                                  self.kmp)

        self._sum_te_stencil = stencil_factory.from_origin_domain(
            sum_te,
            origin=(grid_indexing.isc, grid_indexing.jsc, self.kmp),
            domain=(
                grid_indexing.domain[0],
                grid_indexing.domain[1],
                grid_indexing.domain[2] - self.kmp,
            ),
        )
Esempio n. 24
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        damping_coefficients: DampingCoefficients,
        rarea,
        nord,
        nk: Optional[int] = None,
    ):
        """
        nord sets the order of damping to apply:
        nord = 0:   del-2
        nord = 1:   del-4
        nord = 2:   del-6
        """
        grid_indexing = stencil_factory.grid_indexing
        self._del6_u = damping_coefficients.del6_u
        self._del6_v = damping_coefficients.del6_v
        self._rarea = rarea
        if max(nord[:]) > 3:
            raise ValueError("nord must be less than 3")
        if not np.all(n in [0, 2, 3] for n in nord[:]):
            raise NotImplementedError("nord must have values 0, 2, or 3")
        self._nmax = int(max(nord[:]))
        i1 = grid_indexing.isc - 1 - self._nmax
        i2 = grid_indexing.iec + 1 + self._nmax
        j1 = grid_indexing.jsc - 1 - self._nmax
        j2 = grid_indexing.jec + 1 + self._nmax
        if nk is None:
            nk = grid_indexing.domain[2]
        nk = nk
        origin_d2 = (i1, j1, 0)
        domain_d2 = (i2 - i1 + 1, j2 - j1 + 1, nk)
        f1_ny = grid_indexing.jec - grid_indexing.jsc + 1 + 2 * self._nmax
        f1_nx = grid_indexing.iec - grid_indexing.isc + 2 + 2 * self._nmax
        fx_origin = (grid_indexing.isc - self._nmax, grid_indexing.jsc - self._nmax, 0)
        self._nord = nord

        if nk <= 3:
            raise NotImplementedError("nk must be more than 3 for DelnFluxNoSG")
        self._k_bounds = [1, 1, 1, nk - 3]

        preamble_ax_offsets = axis_offsets(grid_indexing, origin_d2, domain_d2)
        fx_ax_offsets = axis_offsets(grid_indexing, fx_origin, (f1_nx, f1_ny, nk))
        fy_ax_offsets = axis_offsets(
            grid_indexing, fx_origin, (f1_nx - 1, f1_ny + 1, nk)
        )

        origins_d2 = []
        domains_d2 = []
        origins_flux = []
        domains_fx = []
        domains_fy = []

        for n in range(self._nmax):
            nt = self._nmax - 1 - n
            nt_ny = grid_indexing.jec - grid_indexing.jsc + 3 + 2 * nt
            nt_nx = grid_indexing.iec - grid_indexing.isc + 3 + 2 * nt
            origins_d2.append(
                (grid_indexing.isc - nt - 1, grid_indexing.jsc - nt - 1, 0)
            )
            domains_d2.append((nt_nx, nt_ny, nk))
            origins_flux.append((grid_indexing.isc - nt, grid_indexing.jsc - nt, 0))
            domains_fx.append((nt_nx - 1, nt_ny - 2, nk))
            domains_fy.append((nt_nx - 2, nt_ny - 1, nk))

        nord_dictionary = {
            "nord0": nord[0],
            "nord1": nord[1],
            "nord2": nord[2],
            "nord3": nord[3],
        }

        self._d2_damp = stencil_factory.from_origin_domain(
            d2_damp_interval,
            externals={
                **nord_dictionary,
                **preamble_ax_offsets,
            },
            origin=origin_d2,
            domain=domain_d2,
        )

        self._copy_stencil_interval = stencil_factory.from_origin_domain(
            copy_stencil_interval,
            externals={
                **nord_dictionary,
                **preamble_ax_offsets,
            },
            origin=origin_d2,
            domain=domain_d2,
        )

        self._d2_stencil = get_stencils_with_varied_bounds(
            d2_highorder_stencil,
            origins_d2,
            domains_d2,
            stencil_factory=stencil_factory,
            externals={**nord_dictionary},
        )
        self._column_conditional_fx_calculation = get_stencils_with_varied_bounds(
            fx_calc_stencil_column,
            origins_flux,
            domains_fx,
            stencil_factory=stencil_factory,
            externals={**nord_dictionary},
        )
        self._column_conditional_fy_calculation = get_stencils_with_varied_bounds(
            fy_calc_stencil_column,
            origins_flux,
            domains_fy,
            stencil_factory=stencil_factory,
            externals={**nord_dictionary},
        )
        self._fx_calc_stencil = stencil_factory.from_origin_domain(
            fx_calc_stencil_nord,
            externals={**fx_ax_offsets, **nord_dictionary},
            origin=fx_origin,
            domain=(f1_nx, f1_ny, nk),
        )
        self._fy_calc_stencil = stencil_factory.from_origin_domain(
            fy_calc_stencil_nord,
            externals={**fy_ax_offsets, **nord_dictionary},
            origin=fx_origin,
            domain=(f1_nx - 1, f1_ny + 1, nk),
        )
        corner_origin, corner_domain = grid_indexing.get_origin_domain(
            dims=[X_DIM, Y_DIM, Z_DIM],
            halos=(grid_indexing.n_halo, grid_indexing.n_halo),
        )
        corner_domain = corner_domain[:2] + (nk,)
        corner_axis_offsets = axis_offsets(grid_indexing, corner_origin, corner_domain)

        self._corner_tmp = utils.make_storage_from_shape(
            corner_domain, origin=corner_origin
        )
        self._copy_corners_x_nord = stencil_factory.from_origin_domain(
            copy_corners_x_nord,
            externals={**corner_axis_offsets, **nord_dictionary},
            origin=corner_origin,
            domain=corner_domain,
        )
        self._copy_corners_y_nord = stencil_factory.from_origin_domain(
            copy_corners_y_nord,
            externals={**corner_axis_offsets, **nord_dictionary},
            origin=corner_origin,
            domain=corner_domain,
        )
Esempio n. 25
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        nwat: int,
        fv_sg_adj: float,
        n_sponge: int,
        hydrostatic: bool,
    ):
        assert not hydrostatic, "Hydrostatic not implemented for fv_subgridz"
        grid_indexing = stencil_factory.grid_indexing
        self._k_sponge = n_sponge
        if self._k_sponge is not None:
            if self._k_sponge < 3:
                return
        else:
            self._k_sponge = grid_indexing.domain[2]
        if self._k_sponge < min(grid_indexing.domain[2], 24):
            t_max = T2_MAX
        else:
            t_max = T3_MAX
        if nwat == 0:
            xvir = 0.0
        else:
            xvir = ZVIR
        self._m = 3
        self._fv_sg_adj = float(fv_sg_adj)
        self._is = grid_indexing.isc
        self._js = grid_indexing.jsc
        kbot_domain = (grid_indexing.domain[0], grid_indexing.domain[1], self._k_sponge)
        origin = grid_indexing.origin_compute()

        # TODO(eddied): Applying the `KCacheDetection` pass causes validation to fail
        self._init_stencil = stencil_factory.from_origin_domain(
            init,
            origin=origin,
            domain=(
                grid_indexing.domain[0],
                grid_indexing.domain[1],
                self._k_sponge + 1,
            ),
            skip_passes=("KCacheDetection",),
        )
        self._m_loop_stencil = stencil_factory.from_origin_domain(
            m_loop,
            externals={"t_max": t_max, "xvir": xvir},
            origin=origin,
            domain=kbot_domain,
        )
        self._finalize_stencil = stencil_factory.from_origin_domain(
            finalize,
            externals={
                "hydrostatic": hydrostatic,
                "fv_sg_adj": fv_sg_adj,
            },
            origin=origin,
            domain=kbot_domain,
        )
        shape = grid_indexing.domain_full(add=(1, 1, 0))
        self._q0 = {}
        for tracername in utils.tracer_variables:
            self._q0[tracername] = utils.make_storage_from_shape(shape)
        self._tmp_u0 = utils.make_storage_from_shape(shape)
        self._tmp_v0 = utils.make_storage_from_shape(shape)
        self._tmp_w0 = utils.make_storage_from_shape(shape)
        self._tmp_gz = utils.make_storage_from_shape(shape)
        self._tmp_t0 = utils.make_storage_from_shape(shape)
        self._tmp_static_energy = utils.make_storage_from_shape(shape)
        self._tmp_total_energy = utils.make_storage_from_shape(shape)
        self._tmp_cvm = utils.make_storage_from_shape(shape)
        self._tmp_cpm = utils.make_storage_from_shape(shape)
        self._ratios = {0: 0.25, 1: 0.5, 2: 0.999}
    def __init__(
        self,
        stencil_factory: StencilFactory,
        grid_data: GridData,
        damping_coefficients: DampingCoefficients,
        nested: bool,
        stretched_grid: bool,
        dddmp,
        d4_bg,
        nord,
        grid_type,
        nord_col: FloatFieldK,
        d2_bg: FloatFieldK,
    ):
        self.grid_indexing = stencil_factory.grid_indexing
        assert not nested, "nested not implemented"
        assert grid_type < 3, "Not implemented, grid_type>=3, specifically smag_corner"
        # TODO: make dddmp a compile-time external, instead of runtime scalar
        self._dddmp = dddmp
        # TODO: make da_min_c a compile-time external, instead of runtime scalar
        self._da_min_c = damping_coefficients.da_min_c
        self._grid_type = grid_type
        self._nord_column = nord_col
        self._d2_bg_column = d2_bg
        self._rarea_c = grid_data.rarea_c
        self._sin_sg1 = grid_data.sin_sg1
        self._sin_sg2 = grid_data.sin_sg2
        self._sin_sg3 = grid_data.sin_sg3
        self._sin_sg4 = grid_data.sin_sg4
        self._cosa_u = grid_data.cosa_u
        self._cosa_v = grid_data.cosa_v
        self._sina_u = grid_data.sina_u
        self._sina_v = grid_data.sina_v
        self._dxc = grid_data.dxc
        self._dyc = grid_data.dyc

        # TODO: calculate these locally based on grid_data
        self._divg_u = spec.grid.divg_u
        self._divg_v = spec.grid.divg_v

        nonzero_nord_k = 0
        self._nonzero_nord = int(nord)
        for k in range(len(self._nord_column)):
            if self._nord_column[k] > 0:
                nonzero_nord_k = k
                self._nonzero_nord = int(self._nord_column[k])
                break
        if stretched_grid:
            self._dd8 = damping_coefficients.da_min * d4_bg ** (self._nonzero_nord + 1)
        else:
            self._dd8 = (damping_coefficients.da_min_c * d4_bg) ** (
                self._nonzero_nord + 1
            )
        kstart = nonzero_nord_k
        nk = self.grid_indexing.domain[2] - kstart
        self._do_zero_order = nonzero_nord_k > 0
        low_k_stencil_factory = stencil_factory.restrict_vertical(
            k_start=0, nk=nonzero_nord_k
        )
        high_k_stencil_factory = stencil_factory.restrict_vertical(
            k_start=nonzero_nord_k
        )
        self.a2b_ord4 = AGrid2BGridFourthOrder(
            stencil_factory=high_k_stencil_factory,
            grid_data=grid_data,
            grid_type=self._grid_type,
            replace=False,
        )

        self._get_delpc = low_k_stencil_factory.from_dims_halo(
            func=get_delpc,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            compute_halos=(0, 0),
            skip_passes=("GreedyMerging",),
        )

        self._damping = low_k_stencil_factory.from_dims_halo(
            damping,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            compute_halos=(0, 0),
        )

        self._copy_computeplus = high_k_stencil_factory.from_dims_halo(
            func=basic.copy_defn,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            compute_halos=(0, 0),
        )

        origins = []
        origins_v = []
        origins_u = []
        domains = []
        domains_v = []
        domains_u = []
        for n in range(1, self._nonzero_nord + 1):
            nt = self._nonzero_nord - n
            nint = self.grid_indexing.domain[0] + 2 * nt + 1
            njnt = self.grid_indexing.domain[1] + 2 * nt + 1
            js = self.grid_indexing.jsc - nt
            is_ = self.grid_indexing.isc - nt
            origins_v.append((is_ - 1, js, kstart))
            domains_v.append((nint + 1, njnt, nk))
            origins_u.append((is_, js - 1, kstart))
            domains_u.append((nint, njnt + 1, nk))
            origins.append((is_, js, kstart))
            domains.append((nint, njnt, nk))
        self._vc_from_divg_stencils = get_stencils_with_varied_bounds(
            vc_from_divg,
            origins=origins_v,
            domains=domains_v,
            stencil_factory=stencil_factory,
        )

        self._uc_from_divg_stencils = get_stencils_with_varied_bounds(
            uc_from_divg,
            origins=origins_u,
            domains=domains_u,
            stencil_factory=stencil_factory,
        )

        self._redo_divg_d_stencils = get_stencils_with_varied_bounds(
            redo_divg_d,
            origins=origins,
            domains=domains,
            stencil_factory=stencil_factory,
            externals={"do_adjustment": not stretched_grid},
        )

        self._damping_nord_highorder_stencil = high_k_stencil_factory.from_dims_halo(
            func=damping_nord_highorder_stencil,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            compute_halos=(0, 0),
        )
        self._smagorinksy_diffusion_approx_stencil = (
            high_k_stencil_factory.from_dims_halo(
                func=smagorinksy_diffusion_approx,
                compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
                compute_halos=(0, 0),
            )
        )

        self._set_value = high_k_stencil_factory.from_dims_halo(
            func=basic.set_value_defn,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            compute_halos=(self.grid_indexing.n_halo, self.grid_indexing.n_halo),
        )

        self._corner_tmp = utils.make_storage_from_shape(self.grid_indexing.max_shape)

        self.fill_corners_bgrid_x = corners.FillCornersBGrid(
            direction="x",
            temporary_field=self._corner_tmp,
            stencil_factory=high_k_stencil_factory,
        )
        self.fill_corners_bgrid_y = corners.FillCornersBGrid(
            direction="y",
            temporary_field=self._corner_tmp,
            stencil_factory=high_k_stencil_factory,
        )
        self._fill_corners_dgrid_stencil = high_k_stencil_factory.from_dims_halo(
            func=corners.fill_corners_dgrid_defn,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            compute_halos=(self.grid_indexing.n_halo, self.grid_indexing.n_halo),
        )
Esempio n. 27
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        damping_coefficients: DampingCoefficients,
        rarea,
        nmax: int,
    ):
        """
        Args:
            grid: fv3core grid object
        """
        grid_indexing = stencil_factory.grid_indexing
        self._del6_u = damping_coefficients.del6_u
        self._del6_v = damping_coefficients.del6_v
        self._rarea = rarea
        self._fx = utils.make_storage_from_shape(grid_indexing.max_shape)
        self._fy = utils.make_storage_from_shape(grid_indexing.max_shape)
        self._q = utils.make_storage_from_shape(grid_indexing.max_shape)

        self._corner_fill = stencil_factory.from_dims_halo(
            func=corner_fill,
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
            compute_halos=(3, 3),
        )
        self._copy_stencil = stencil_factory.from_dims_halo(
            func=copy_defn,
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
            compute_halos=(3, 3),
        )

        self._ntimes = min(3, nmax)
        origins = []
        domains_x = []
        domains_y = []
        domains = []
        for n_halo in range(self._ntimes - 1, -1, -1):
            origin, domain = grid_indexing.get_origin_domain(
                [X_DIM, Y_DIM, Z_DIM], halos=(n_halo, n_halo))
            _, domain_x = grid_indexing.get_origin_domain(
                [X_INTERFACE_DIM, Y_DIM, Z_DIM], halos=(n_halo, n_halo))
            _, domain_y = grid_indexing.get_origin_domain(
                [X_DIM, Y_INTERFACE_DIM, Z_DIM], halos=(n_halo, n_halo))
            origins.append(cast_to_index3d(origin))
            domains.append(cast_to_index3d(domain))
            domains_x.append(cast_to_index3d(domain_x))
            domains_y.append(cast_to_index3d(domain_y))

        self._compute_zonal_flux = get_stencils_with_varied_bounds(
            compute_zonal_flux,
            origins,
            domains_x,
            stencil_factory=stencil_factory)
        self._compute_meridional_flux = get_stencils_with_varied_bounds(
            compute_meridional_flux,
            origins,
            domains_y,
            stencil_factory=stencil_factory)
        self._update_q = get_stencils_with_varied_bounds(
            update_q, origins, domains, stencil_factory=stencil_factory)

        self._copy_corners_x: corners.CopyCorners = corners.CopyCorners(
            direction="x", stencil_factory=stencil_factory)
        """Stencil responsible for doing corners updates in x-direction."""
        self._copy_corners_y: corners.CopyCorners = corners.CopyCorners(
            direction="y", stencil_factory=stencil_factory)
        """Stencil responsible for doing corners updates in y-direction."""
Esempio n. 28
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        grid_data: GridData,
        damping_coefficients: DampingCoefficients,
        column_namelist,
        nested: bool,
        stretched_grid: bool,
        config: DGridShallowWaterLagrangianDynamicsConfig,
    ):
        self._f0 = spec.grid.f0
        self.grid = grid_data
        self.grid_indexing = stencil_factory.grid_indexing
        assert config.grid_type < 3, "ubke and vbke only implemented for grid_type < 3"
        assert not config.inline_q, "inline_q not yet implemented"
        assert (
            config.d_ext <= 0
        ), "untested d_ext > 0. need to call a2b_ord2, not yet implemented"
        assert (column_namelist["damp_vt"] > dcon_threshold).all()
        # TODO: in theory, we should check if damp_vt > 1e-5 for each k-level and
        # only compute delnflux for k-levels where this is true
        assert (column_namelist["damp_w"] > dcon_threshold).all()
        # TODO: in theory, we should check if damp_w > 1e-5 for each k-level and
        # only compute delnflux for k-levels where this is true

        # only compute for k-levels where this is true
        self.hydrostatic = config.hydrostatic
        self._tmp_heat_s = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._vort_x_delta = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._vort_y_delta = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_ke = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_vort = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._uc_contra = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._vc_contra = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_ut = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_vt = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_fx = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_fy = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_gx = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_gy = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_dw = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_wk = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_fx2 = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_fy2 = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._tmp_damp_3d = utils.make_storage_from_shape(
            (1, 1, self.grid_indexing.domain[2])
        )
        self._advected_u = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._advected_v = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._ub_contra = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._vb_contra = utils.make_storage_from_shape(self.grid_indexing.max_shape)
        self._column_namelist = column_namelist

        self.delnflux_nosg_w = DelnFluxNoSG(
            stencil_factory,
            damping_coefficients,
            grid_data.rarea,
            self._column_namelist["nord_w"],
        )
        self.delnflux_nosg_v = DelnFluxNoSG(
            stencil_factory,
            damping_coefficients,
            grid_data.rarea,
            self._column_namelist["nord_v"],
        )
        self.fvtp2d_dp = FiniteVolumeTransport(
            stencil_factory=stencil_factory,
            grid_data=grid_data,
            damping_coefficients=damping_coefficients,
            grid_type=config.grid_type,
            hord=config.hord_dp,
            nord=self._column_namelist["nord_v"],
            damp_c=self._column_namelist["damp_vt"],
        )
        self.fvtp2d_dp_t = FiniteVolumeTransport(
            stencil_factory=stencil_factory,
            grid_data=grid_data,
            damping_coefficients=damping_coefficients,
            grid_type=config.grid_type,
            hord=config.hord_dp,
            nord=self._column_namelist["nord_t"],
            damp_c=self._column_namelist["damp_t"],
        )
        self.fvtp2d_tm = FiniteVolumeTransport(
            stencil_factory=stencil_factory,
            grid_data=grid_data,
            damping_coefficients=damping_coefficients,
            grid_type=config.grid_type,
            hord=config.hord_tm,
            nord=self._column_namelist["nord_v"],
            damp_c=self._column_namelist["damp_vt"],
        )
        self.fvtp2d_vt_nodelnflux = FiniteVolumeTransport(
            stencil_factory=stencil_factory,
            grid_data=grid_data,
            damping_coefficients=damping_coefficients,
            grid_type=config.grid_type,
            hord=config.hord_vt,
        )
        self.fv_prep = FiniteVolumeFluxPrep(
            stencil_factory=stencil_factory,
            grid_data=grid_data,
        )
        self.divergence_damping = DivergenceDamping(
            stencil_factory,
            grid_data,
            damping_coefficients,
            nested,
            stretched_grid,
            config.dddmp,
            config.d4_bg,
            config.nord,
            config.grid_type,
            column_namelist["nord"],
            column_namelist["d2_divg"],
        )

        self._apply_pt_delp_fluxes = stencil_factory.from_dims_halo(
            func=apply_pt_delp_fluxes_stencil_defn,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            externals={
                "inline_q": config.inline_q,
            },
        )
        self._kinetic_energy_update_part_1 = stencil_factory.from_dims_halo(
            func=kinetic_energy_update_part_1,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            externals={
                "iord": config.hord_mt,
                "jord": config.hord_mt,
                "mord": config.hord_mt,
                "xt_minmax": False,
                "yt_minmax": False,
            },
            skip_passes=("GreedyMerging",),
        )
        self._kinetic_energy_update_part_2 = stencil_factory.from_dims_halo(
            func=kinetic_energy_update_part_2,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
            externals={
                "iord": config.hord_mt,
                "jord": config.hord_mt,
                "mord": config.hord_mt,
                "xt_minmax": False,
                "yt_minmax": False,
            },
            skip_passes=("GreedyMerging",),
        )
        self._flux_adjust_stencil = stencil_factory.from_dims_halo(
            func=flux_adjust, compute_dims=[X_DIM, Y_DIM, Z_DIM]
        )
        self._flux_capacitor_stencil = stencil_factory.from_dims_halo(
            func=flux_capacitor,
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
            compute_halos=(3, 3),
        )
        self._vort_differencing_stencil = stencil_factory.from_dims_halo(
            func=vort_differencing,
            compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
        )
        self._u_and_v_from_ke_stencil = stencil_factory.from_dims_halo(
            func=u_and_v_from_ke, compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM]
        )
        self._compute_vort_stencil = stencil_factory.from_dims_halo(
            func=compute_vort,
            externals={
                "radius": constants.RADIUS,
                "do_f3d": config.do_f3d,
                "hydrostatic": self.hydrostatic,
            },
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
            compute_halos=(3, 3),
        )
        self._adjust_w_and_qcon_stencil = stencil_factory.from_dims_halo(
            func=adjust_w_and_qcon,
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
        )
        self._heat_diss_stencil = stencil_factory.from_dims_halo(
            func=heat_diss,
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
        )
        self._heat_source_from_vorticity_damping_stencil = (
            stencil_factory.from_dims_halo(
                func=heat_source_from_vorticity_damping,
                compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM],
                externals={
                    "do_skeb": config.do_skeb,
                    "d_con": config.d_con,
                },
            )
        )
        self._compute_vorticity_stencil = stencil_factory.from_dims_halo(
            compute_vorticity,
            compute_dims=[X_DIM, Y_DIM, Z_DIM],
            compute_halos=(3, 3),
        )
        self._update_u_and_v_stencil = stencil_factory.from_dims_halo(
            update_u_and_v, compute_dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM]
        )
        damping_factor_calculation_stencil = stencil_factory.from_origin_domain(
            delnflux.calc_damp,
            origin=(0, 0, 0),
            domain=(1, 1, stencil_factory.grid_indexing.domain[2]),
        )
        damping_factor_calculation_stencil(
            self._tmp_damp_3d,
            self._column_namelist["nord_v"],
            self._column_namelist["damp_vt"],
            damping_coefficients.da_min_c,
        )
        self._delnflux_damp_vt = utils.make_storage_data(
            self._tmp_damp_3d[0, 0, :], (self.grid_indexing.domain[2],), (0,)
        )

        damping_factor_calculation_stencil(
            self._tmp_damp_3d,
            self._column_namelist["nord_w"],
            self._column_namelist["damp_w"],
            damping_coefficients.da_min_c,
        )
        self._delnflux_damp_w = utils.make_storage_data(
            self._tmp_damp_3d[0, 0, :], (self.grid_indexing.domain[2],), (0,)
        )
        y_temporary = utils.make_storage_from_shape(
            shape=self.grid_indexing.max_shape, origin=self.grid_indexing.origin
        )
        self._copy_corners = PreAllocatedCopiedCornersFactory(
            stencil_factory,
            dims=[X_DIM, Y_DIM, Z_INTERFACE_DIM],
            y_temporary=y_temporary,
        )
Esempio n. 29
0
    def __init__(
        self,
        stencil_factory: StencilFactory,
        grid_data: GridData,
        damping_coefficients: DampingCoefficients,
        grid_type: int,
        hord,
        nord=None,
        damp_c=None,
    ):
        # use a shorter alias for grid_indexing here to avoid very verbose lines
        idx = stencil_factory.grid_indexing
        self._area = grid_data.area
        origin = idx.origin_compute()
        self._q_advected_y = utils.make_storage_from_shape(
            idx.max_shape, origin)
        self._q_advected_x = utils.make_storage_from_shape(
            idx.max_shape, origin)
        self._q_x_advected_mean = utils.make_storage_from_shape(
            idx.max_shape, origin)
        self._q_y_advected_mean = utils.make_storage_from_shape(
            idx.max_shape, origin)
        self._q_advected_x_y_advected_mean = utils.make_storage_from_shape(
            idx.max_shape, origin)
        self._q_advected_y_x_advected_mean = utils.make_storage_from_shape(
            idx.max_shape, origin)
        self._corner_tmp = utils.make_storage_from_shape(
            idx.max_shape, origin=idx.origin_full())
        """Temporary field to use for corner computation in both x and y direction"""
        self._nord = nord
        self._damp_c = damp_c
        ord_outer = hord
        ord_inner = 8 if hord == 10 else hord
        self.q_i_stencil = stencil_factory.from_origin_domain(
            q_i_stencil,
            origin=idx.origin_full(add=(0, 3, 0)),
            domain=idx.domain_full(add=(0, -3, 1)),
        )
        self.q_j_stencil = stencil_factory.from_origin_domain(
            q_j_stencil,
            origin=idx.origin_full(add=(3, 0, 0)),
            domain=idx.domain_full(add=(-3, 0, 1)),
        )
        self.stencil_transport_flux = stencil_factory.from_origin_domain(
            final_fluxes,
            origin=idx.origin_compute(),
            domain=idx.domain_compute(add=(1, 1, 1)),
        )
        if (self._nord is not None) and (self._damp_c is not None):
            self.delnflux: Optional[DelnFlux] = DelnFlux(
                stencil_factory=stencil_factory,
                damping_coefficients=damping_coefficients,
                rarea=grid_data.rarea,
                nord=self._nord,
                damp_c=self._damp_c,
            )
        else:
            self.delnflux = None

        self.x_piecewise_parabolic_inner = XPiecewiseParabolic(
            stencil_factory=stencil_factory,
            dxa=grid_data.dxa,
            grid_type=grid_type,
            iord=ord_inner,
            origin=idx.origin_compute(add=(0, -idx.n_halo, 0)),
            domain=idx.domain_compute(add=(1, 1 + 2 * idx.n_halo, 1)),
        )
        self.y_piecewise_parabolic_inner = YPiecewiseParabolic(
            stencil_factory=stencil_factory,
            dya=grid_data.dya,
            grid_type=grid_type,
            jord=ord_inner,
            origin=idx.origin_compute(add=(-idx.n_halo, 0, 0)),
            domain=idx.domain_compute(add=(1 + 2 * idx.n_halo, 1, 1)),
        )
        self.x_piecewise_parabolic_outer = XPiecewiseParabolic(
            stencil_factory=stencil_factory,
            dxa=grid_data.dxa,
            grid_type=grid_type,
            iord=ord_outer,
            origin=idx.origin_compute(),
            domain=idx.domain_compute(add=(1, 1, 1)),
        )
        self.y_piecewise_parabolic_outer = YPiecewiseParabolic(
            stencil_factory=stencil_factory,
            dya=grid_data.dya,
            grid_type=grid_type,
            jord=ord_outer,
            origin=idx.origin_compute(),
            domain=idx.domain_compute(add=(1, 1, 1)),
        )
    def __init__(
        self,
        stencil_factory: StencilFactory,
        kord: int,
        iv: int,
        i1: int,
        i2: int,
        j1: int,
        j2: int,
    ):
        """
        The constraints on the spline are set by kord and iv.
        Arguments:
            stencil_factory
            kord: ???
            iv: ???
            i1: The first i-element to compute on
            i2: The last i-element to compute on
            j1: The first j-element to compute on
            j2: The last j-element to compute on
        """
        assert kord <= 10, f"kord {kord} not implemented."
        grid_indexing = stencil_factory.grid_indexing
        full_orig: Tuple[int] = grid_indexing.origin_full()
        km: int = grid_indexing.domain[2]
        self._kord = kord

        self._gam: FloatField = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=full_orig
        )
        self._q: FloatField = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=full_orig
        )
        self._q_bot: FloatField = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=full_orig
        )
        self._extm: BoolField = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=full_orig, dtype=bool
        )
        self._ext5: BoolField = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=full_orig, dtype=bool
        )
        self._ext6: BoolField = utils.make_storage_from_shape(
            grid_indexing.domain_full(add=(0, 0, 1)), origin=full_orig, dtype=bool
        )

        i_extent: int = i2 - i1 + 1
        j_extent: int = j2 - j1 + 1
        origin: Tuple[int, int, int] = (i1, j1, 0)
        domain: Tuple[int, int, int] = (i_extent, j_extent, km)
        domain_extend: Tuple[int, int, int] = (i_extent, j_extent, km + 1)

        self._set_initial_values = stencil_factory.from_origin_domain(
            func=set_initial_vals,
            externals={"iv": iv, "kord": abs(kord)},
            origin=origin,
            domain=domain_extend,
        )

        self._apply_constraints = stencil_factory.from_origin_domain(
            func=apply_constraints,
            externals={"iv": iv, "kord": abs(kord)},
            origin=origin,
            domain=domain,
        )

        self._set_interpolation_coefficients = stencil_factory.from_origin_domain(
            func=set_interpolation_coefficients,
            externals={"iv": iv, "kord": abs(kord)},
            origin=origin,
            domain=domain,
        )