Пример #1
0
def test_make_ibound(all_layers):
    top = all_layers[0].copy()
    botm = all_layers[1:].copy()
    nodata = -9999
    botm[-1, 0, 0] = nodata
    botm[-2] = 2
    botm[-2, 2, 2] = np.nan
    botm[:, 3, 3] = np.arange(1, 10)[::-1] # column of cells all eq. to min thickness
    filled_top, filled_botm = fill_cells_vertically(top, botm)
    ibound = make_ibound(top, botm, nodata=nodata,
                           minimum_layer_thickness=1,
                           drop_thin_cells=True,
                           tol=1e-4)
    # test ibound based on nans
    assert np.array_equal(ibound[:, 2, 2].astype(bool), ~np.isnan(botm[:, 2, 2]))
    # test ibound based on nodata
    assert ibound[-1, 0, 0] == 0
    # test ibound based on layer thickness
    # unlike for idomain, individual cells < min thickness are not deactivated
    # (unless all cells at i, j location are < min thickness + tol)
    assert ibound[-1].sum() == 98
    assert ibound[-2].sum() == 98
    # test that nans in the model top result in the highest active botms being excluded
    # (these cells have valid botms, but no tops)
    assert ibound[:, 0, 0].sum() == 1
    # in all_layers, cells with valid tops are idomain=0
    # because all botms in layer 1 are nans
    assert ibound[0].sum() == 0

    # test edge case of values that match the layer thickness when tol=0
    ibound = make_ibound(top, botm, nodata=nodata,
                           minimum_layer_thickness=1,
                           drop_thin_cells=True,
                           tol=0)
    assert ibound[-1].sum() == 99
Пример #2
0
def rasters_to_grid(modelgrid, dem, rasters,
                    dem_elevation_units='meters', raster_elevation_units='meters',
                    dest_elevation_units='meters'):
    """Sample a sequence of rasters onto the i, j locations of a modelgrid,
    returning a 3D numpy array of the sampled elevations. Fill places with nodata
    using the next valid surface above.

    Parameters
    ----------
    modelgrid : Modflow-setup :class:`~mfsetup.grid.MFsetupGrid` instance
        Modflow-setup grid instance describing the model grid
    dem : str (filepath)
        Raster representing the land surface, at the highest resolution being contemplated for the model.
        Usually this is derived by sampling a higher resolution DEM using zonal statistics, taking
        the mean DEM value for each model cell.
    rasters : list of strings (filepaths)
        Raster surfaces describing hydrogelogic contacts surrounding the voxel data.
    dem_elevation_units : str, optional
        Elevation units of dem_means_raster, by default 'meters'
    framework_raster_elevation_units : str, optional
        Elevation units of the framework_rasters, by default 'meters'
    model_length_units : str, optional
        Length units used in the model, by default 'meters'

    References
    ----------
    See the documentation for the :func:`fill_cells_vertically <mfsetup.discretization.fill_cells_vertically>`
    function in Modflow-setup for an explanation of the filling process.

    """
    grid = modelgrid
    dem_elevations = get_values_at_points(dem, grid.xcellcenters, grid.ycellcenters,
                                          method='linear')
    # convert to model units
    dem_elevations *= convert_length_units(dem_elevation_units, dest_elevation_units)

    raster_elevations = []
    for raster in rasters:
        grid_cell_values = get_values_at_points(raster, grid.xcellcenters, grid.ycellcenters,
                                                method='linear')
        # convert to model units
        grid_cell_values *= convert_length_units(raster_elevation_units, dest_elevation_units)
        raster_elevations.append(grid_cell_values)
    raster_elevations = np.array(raster_elevations)
    
    # fill nans in the sampled original framework elevations
    # (nans are where a layer surface is absent)
    # fill the nans with the next surface above
    # see https://github.com/aleaf/modflow-setup/blob/develop/mfsetup/discretization.py
    model_top_filled, filled_raster_elevations = fill_cells_vertically(dem_elevations, raster_elevations)
    above_land_surface = filled_raster_elevations > dem_elevations
    # reset any values above land surface to land surface
    dem_means_3d = np.tile(dem_elevations, (filled_raster_elevations.shape[0], 1, 1))
    filled_raster_elevations[above_land_surface] = dem_means_3d[above_land_surface]
    del dem_means_3d
    filled_raster_elevations = np.vstack([np.reshape(dem_elevations, (1, *dem_elevations.shape)),
                                          filled_raster_elevations])
    return filled_raster_elevations
Пример #3
0
def test_fill_na(all_layers):
    top = all_layers[0].copy()
    botm = all_layers[1:].copy()
    botm[-2] = 2
    botm[-2, 2, 2] = np.nan

    top, botm = fill_cells_vertically(top, botm)
    filled = all_layers.copy()
    filled[0] = top
    filled[1:] = botm
    assert filled[:, 2, 2].tolist() == [10., 10.,  8.,  8.,  8.,  5.,  5.,  5.,  5, 1.]
    assert filled[:, 0, 0].tolist() == [8] * 8 + [2, 1]