示例#1
0
    def build_cell_width_lat_lon(self):
        """
        Create cell width array for this mesh on a regular latitude-longitude
        grid

        Returns
        -------
        cellWidth : numpy.array
            m x n array of cell width in km

        lon : numpy.array
            longitude in degrees (length n and between -180 and 180)

        lat : numpy.array
            longitude in degrees (length m and between -90 and 90)
        """

        dlon = 10.
        dlat = 0.1
        nlon = int(360. / dlon) + 1
        nlat = int(180. / dlat) + 1
        lon = np.linspace(-180., 180., nlon)
        lat = np.linspace(-90., 90., nlat)

        cellWidthVsLat = mdt.EC_CellWidthVsLat(lat)
        cellWidth = np.outer(cellWidthVsLat, np.ones([1, lon.size]))

        return cellWidth, lon, lat
示例#2
0
def cellWidthVsLatLon():
    """
    Create cell width array for this mesh on a regular latitude-longitude grid.
    Returns
    -------
       cellWidth : ndarray
            m x n array, entries are desired cell width in km

       lat : ndarray
            latitude, vector of length m, with entries between -90 and 90,
            degrees

       lon : ndarray
            longitude, vector of length n, with entries between -180 and 180,
            degrees
    """

    dlon = 0.1
    dlat = dlon
    nlon = int(360./dlon) + 1
    nlat = int(180./dlat) + 1
    lon = np.linspace(-180., 180., nlon)
    lat = np.linspace(-90., 90., nlat)

    cellWidthVsLat = mdt.EC_CellWidthVsLat(lat)

    _, cellWidth = np.meshgrid(lon, cellWidthVsLat)

    fc = read_feature_collection('north_mid_res_region.geojson')

    earth_radius = constants['SHR_CONST_REARTH']

    mr_signed_distance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)

    fc = read_feature_collection('arctic_high_res_region.geojson')

    hr_signed_distance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)

    frac = (-mr_signed_distance / (-mr_signed_distance + hr_signed_distance))

    frac = np.maximum(0., np.minimum(1., frac))

    dx_min = 15.
    dx_max = 30.

    arctic_widths = dx_max + (dx_min - dx_max) * frac

    trans_width = 1000e3
    trans_start = 0.

    weights = 0.5 * (1 + np.tanh((mr_signed_distance - trans_start) /
                                 trans_width))

    cellWidth = arctic_widths * (1 - weights) + cellWidth * weights

    return cellWidth, lon, lat
示例#3
0
def setspac():

    spac = jigsawpy.jigsaw_msh_t()

    #------------------------------------ define spacing pattern

    spac.mshID = "ellipsoid-grid"
    spac.radii = np.full(3, FULL_SPHERE_RADIUS, dtype=spac.REALS_t)

    spac.xgrid = np.linspace(-1. * np.pi, +1. * np.pi, 360)

    spac.ygrid = np.linspace(-.5 * np.pi, +.5 * np.pi, 181)

    vals = \
        mdt.EC_CellWidthVsLat(spac.ygrid * 180. / np.pi)

    spac.value = np.array(np.tile(vals, (1, spac.xgrid.size)),
                          dtype=spac.REALS_t)

    return spac
示例#4
0
def cellWidthVsLatLon():
    """
    Create cell width array for this mesh on a regular latitude-longitude grid.
    Returns
    -------
       cellWidth : ndarray
            m x n array, entries are desired cell width in km

       lat : ndarray
            latitude, vector of length m, with entries between -90 and 90,
            degrees

       lon : ndarray
            longitude, vector of length n, with entries between -180 and 180,
            degrees
    """
    lat = np.arange(-90, 90.01, 0.1)
    lon = np.arange(-180, 180.01, 10.0)

    cellWidthVsLat = mdt.EC_CellWidthVsLat(lat)
    cellWidth = np.outer(cellWidthVsLat, np.ones([1, lon.size]))

    return cellWidth, lon, lat
示例#5
0
def create_background_mesh(
        grd_box,
        ddeg,
        mesh_type,
        dx_min,
        dx_max,  # {{{
        plot_option=False,
        plot_box=[],
        call=None):
    """
    Create a background field of cell widths

    Parameters
    ----------
    grd_box : list of float
        A list of 4 floats defining the bounds (min lon, max lon, min lat, max
        lat) of the grid

    ddeg : float
        The resolution of the mesh in degrees

    mesh_type : {'QU', 'EC', 'RRS'}
        The type of mesh: quasi-uniform (QU), Eddy-closure (EC) or Rossby-radius
        scaling (RRS)

    dx_min : float
        The resolution in meters of a QU mesh or the minimum resolution of of
        an RRS mesh. This parameter is ignored for EC meshes and the default
        function arguments to ``EC_CellWidthVsLat()`` are used instead.

    dx_max : float
        The maximum resolution in meters of of an RRS mesh. This parameter is
        ignored for QU meshes and EC meshes.  For EC meshes, the default
        function arguments are used instead.

    plot_option : bool, optional
        Whether to plot the resulting cell width and save it to files
        named ``bckgrnd_grid_cell_width_vs_lat###.png`` and
        ``bckgnd_grid_cell_width###.png``, where ``###`` is given by
        ``call`` and is meant to indicate how many times this function has been
        called during mesh creation.

    plot_box : list of float, optional
        The extent of the plot if ``plot_option=True``

    call : int, optional
        The number of times the function has been called, used to give the
        plot a unique name.


    Returns
    -------
    cell_width : ndarray
        A 2D array of cell widths in meters.

    lon_grd : ndarray
        A 1D array of longitudes in degrees in the range from -180 to 180

    lat_grd : ndarray
        A 1D array of latitudes in degrees in the range from -90 to 90
    """

    print("Create background mesh")
    print("------------------------")

    # Create cell width background grid
    ny_grd = int((grd_box[3] - grd_box[2]) / ddeg) + 1
    nx_grd = int((grd_box[1] - grd_box[0]) / ddeg) + 1
    lat_grd = grd_box[2] + ddeg * np.arange(ny_grd)
    lon_grd = grd_box[0] + ddeg * np.arange(nx_grd)
    print("   Background grid dimensions:", ny_grd, nx_grd)

    # Assign background grid cell width values
    if mesh_type == 'QU':
        cell_width_lat = dx_max / km * np.ones(lat_grd.size)
    elif mesh_type == 'EC':
        cell_width_lat = mdt.EC_CellWidthVsLat(lat_grd)
    elif mesh_type == 'RRS':
        cell_width_lat = mdt.RRS_CellWidthVsLat(lat_grd, dx_max / km,
                                                dx_min / km)
    else:
        raise ValueError('Unknown mesh_type {}'.format(mesh_type))
    cell_width = np.tile(cell_width_lat, (nx_grd, 1)).T * km

    # Plot background cell width
    if plot_option:
        print("   Plotting background cell width")

        plt.figure()
        plt.plot(lat_grd, cell_width_lat)
        plt.savefig('bckgrnd_grid_cell_width_vs_lat' + str(call) + '.png')

        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
        plt.contourf(lon_grd,
                     lat_grd,
                     cell_width,
                     transform=ccrs.PlateCarree())
        plot_coarse_coast(ax, plot_box)
        plt.colorbar()
        plt.savefig('bckgnd_grid_cell_width' + str(call) + '.png',
                    bbox_inches='tight')
        plt.close()
        print("   Done")

    return (lon_grd, lat_grd, cell_width)  # }}}
示例#6
0
def cellWidthVsLatLon():
    """
    Create cell width array for this mesh on a regular latitude-longitude grid.
    Returns
    -------
       cellWidth : ndarray
            m x n array, entries are desired cell width in km

       lat : ndarray
            latitude, vector of length m, with entries between -90 and 90,
            degrees

       lon : ndarray
            longitude, vector of length n, with entries between -180 and 180,
            degrees
    """
    dlon = 0.1
    dlat = dlon
    earth_radius = constants['SHR_CONST_REARTH']
    nlon = int(360./dlon) + 1
    nlat = int(180./dlat) + 1
    lon = np.linspace(-180., 180., nlon)
    lat = np.linspace(-90., 90., nlat)

    cellWidthSouth = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30.,
                                           cellWidthMidLat=45.,
                                           cellWidthPole=45.,
                                           latPosEq=7.5, latWidthEq=3.0)

    # Transition at Equator
    cellWidthNorth = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30.,
                                           cellWidthMidLat=60.,
                                           cellWidthPole=60.,
                                           latPosEq=7.5, latWidthEq=3.0)
    latTransition = 0.0
    latWidthTransition = 2.5
    cellWidthVsLat = mdt.mergeCellWidthVsLat(
        lat,
        cellWidthSouth,
        cellWidthNorth,
        latTransition,
        latWidthTransition)

    _, cellWidth = np.meshgrid(lon, cellWidthVsLat)

    # now, add the high-res region
    fc = read_feature_collection('high_res_region.geojson')

    so_signed_distance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)

    # Equivalent to 20 degrees latitude
    trans_width = 1600e3
    trans_start = -500e3
    dx_min = 12.

    weights = 0.5 * (1 + np.tanh((so_signed_distance - trans_start) /
                                 trans_width))

    cellWidth = dx_min * (1 - weights) + cellWidth * weights

    fc = read_feature_collection('north_mid_res_region.geojson')

    ar_signed_distance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)

    fc = read_feature_collection('greenland.geojson')

    gr_signed_distance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)

    frac = (-ar_signed_distance/(-ar_signed_distance + gr_signed_distance))

    frac = np.maximum(0., np.minimum(1., frac))

    dx_min = 15.
    dx_max = 35.

    arctic_widths = dx_max + (dx_min - dx_max)*frac

    trans_width = 1000e3
    trans_start = 0.

    weights = 0.5 * (1 + np.tanh((ar_signed_distance - trans_start) /
                                 trans_width))

    cellWidth = arctic_widths * (1 - weights) + cellWidth * weights

    return cellWidth, lon, lat
示例#7
0
def cellWidthVsLatLon():
    """
    Create cell width array for this mesh on a regular latitude-longitude grid.
    Returns
    -------
       cellWidth : ndarray
            m x n array, entries are desired cell width in km

       lat : ndarray
            latitude, vector of length m, with entries between -90 and 90,
            degrees

       lon : ndarray
            longitude, vector of length n, with entries between -180 and 180,
            degrees
    """
    # To speed up for testing, set following line to 1.0 degrees
    dlon = 0.1
    dlat = dlon
    earth_radius = constants['SHR_CONST_REARTH']
    print('\nCreating cellWidth on a lat-lon grid of: {0:.2f} x {0:.2f} '
          'degrees'.format(dlon,dlat))
    print('This can be set higher for faster test generation\n')
    nlon = int(360. / dlon) + 1
    nlat = int(180. / dlat) + 1
    lon = np.linspace(-180., 180., nlon)
    lat = np.linspace(-90., 90., nlat)
    km = 1.0e3

    print('plotting ...')
    fig = plt.figure()
    plt.clf()
    fig.set_size_inches(10.0, 14.0)
    register_sci_viz_colormaps()

    # Create cell width vs latitude for Atlantic and Pacific basins
    QU1 = np.ones(lat.size)
    EC60to30 = mdt.EC_CellWidthVsLat(lat)
    EC60to30Narrow = mdt.EC_CellWidthVsLat(lat, latPosEq = 8.0, latWidthEq = 3.0)

    # Expand from 1D to 2D
    _, cellWidth = np.meshgrid(lon, EC60to30Narrow)
    plot_cartopy(2, 'narrow EC60to30', cellWidth, '3Wbgy5')
    plotFrame = 3

    # global settings for regionally refines mesh
    highRes = 14.0 #[km]

    fileName = 'region_Central_America'
    transitionWidth = 800.0*km
    transitionOffset = 0.0
    fc = read_feature_collection('{}.geojson'.format(fileName))
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    mask = 0.5 * (1 + np.tanh((transitionOffset-signedDistance) /
                              (transitionWidth/2.)))
    cellWidth = 30.0 * mask + cellWidth * (1 - mask)

    fileName = 'coastline_CUSP'
    distanceToTransition = 600.0*km
    # transitionWidth is distance from 0.07 to 0.03 of transition within tanh
    transitionWidth = 600.0*km
    transitionOffset = distanceToTransition + transitionWidth/2.0
    fc = read_feature_collection('{}.geojson'.format(fileName))
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    mask = 0.5 * (1 + np.tanh((transitionOffset-signedDistance) /
                              (transitionWidth/2.)))
    cellWidth = highRes * mask + cellWidth * (1 - mask)
    plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
    plot_cartopy(plotFrame+1, 'cellWidth ', cellWidth, '3Wbgy5')
    plotFrame += 2

    fileName = 'region_Gulf_of_Mexico'
    transitionOffset = 600.0*km
    transitionWidth = 600.0*km
    fc = read_feature_collection('{}.geojson'.format(fileName))
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    maskSmooth = 0.5 * (1 + np.tanh((transitionOffset-signedDistance) /
                                    (transitionWidth/2.)))
    maskSharp = 0.5 * (1 + np.sign(-signedDistance))
    fc = read_feature_collection('land_mask_Mexico.geojson')
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    landMask = 0.5 * (1 + np.sign(-signedDistance))
    mask = maskSharp * landMask + maskSmooth * (1-landMask)
    cellWidth = highRes * mask + cellWidth * (1 - mask)
    plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
    plot_cartopy(plotFrame+1, 'cellWidth ', cellWidth, '3Wbgy5')
    plotFrame += 2

    fileName = 'region_Bering_Sea'
    transitionOffset = 0.0*km
    transitionWidth = 600.0*km
    fc = read_feature_collection('{}.geojson'.format(fileName))
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    maskSmooth = 0.5 * (1 + np.tanh((transitionOffset-signedDistance) /
                                    (transitionWidth/2.)))
    maskSharp = 0.5 * (1 + np.sign(-signedDistance))
    fc = read_feature_collection('land_mask_Kamchatka.geojson')
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    landMask = 0.5 * (1 + np.sign(-signedDistance))
    mask = maskSharp * landMask + maskSmooth * (1-landMask)
    cellWidth = highRes * mask + cellWidth * (1 - mask)
    plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
    plot_cartopy(plotFrame+1, 'cellWidth ', cellWidth, '3Wbgy5')
    plotFrame += 2

    fileName = 'region_Arctic_Ocean'
    transitionOffset = 0.0*km
    transitionWidth = 600.0*km
    fc = read_feature_collection('{}.geojson'.format(fileName))
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    mask = 0.5 * (1 + np.tanh((transitionOffset-signedDistance) /
                              (transitionWidth/2.)))
    cellWidth = highRes * mask + cellWidth * (1 - mask)
    plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
    plot_cartopy(plotFrame+1, 'cellWidth ', cellWidth, '3Wbgy5')
    plotFrame += 2

    fileName = 'region_Gulf_Stream_extension'
    transitionOffset = 0.0*km
    transitionWidth = 600.0*km
    fc = read_feature_collection('{}.geojson'.format(fileName))
    signedDistance = signed_distance_from_geojson(fc, lon, lat, earth_radius,
                                                  max_length=0.25)
    mask = 0.5 * (1 + np.tanh((transitionOffset-signedDistance) /
                              (transitionWidth/2.)))
    cellWidth = highRes * mask + cellWidth * (1 - mask)
    plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
    plot_cartopy(plotFrame+1, 'cellWidth ', cellWidth, '3Wbgy5')
    plotFrame += 2

    # save signed distance to a file
    # da = xarray.DataArray(signedDistance,
    #                      dims=['y', 'x'],
    #                      coords={'y': lat, 'x': lon},
    #                      name='signedDistance')
    #cw_filename = 'signedDistance.nc'
    # da.to_netcdf(cw_filename)

    ax = plt.subplot(6, 2, 1)
    ax.plot(lat, EC60to30, label='original EC60to30')
    ax.plot(lat, EC60to30Narrow, label='narrow EC60to30')
    ax.grid(True)
    plt.title('Grid cell size [km] versus latitude')
    plt.legend(loc="upper left")

    plt.savefig('mesh_construction.png')

    return cellWidth, lon, lat
示例#8
0
    def build_cell_width_lat_lon(self):
        """
        Create cell width array for this mesh on a regular latitude-longitude
        grid

        Returns
        -------
        cellWidth : numpy.array
            m x n array of cell width in km

        lon : numpy.array
            longitude in degrees (length n and between -180 and 180)

        lat : numpy.array
            longitude in degrees (length m and between -90 and 90)
        """

        dlon = 0.1
        dlat = dlon
        earth_radius = constants['SHR_CONST_REARTH']
        nlon = int(360./dlon) + 1
        nlat = int(180./dlat) + 1
        lon = np.linspace(-180., 180., nlon)
        lat = np.linspace(-90., 90., nlat)

        cellWidthSouth = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30.,
                                               cellWidthMidLat=45.,
                                               cellWidthPole=45.,
                                               latPosEq=7.5, latWidthEq=3.0)

        cellWidthNorth = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30.,
                                               cellWidthMidLat=60.,
                                               cellWidthPole=35.,
                                               latPosEq=7.5, latWidthEq=3.0)

        # Transition at Equator
        latTransition = 0.0
        latWidthTransition = 2.5
        cellWidthVsLat = mdt.mergeCellWidthVsLat(
            lat,
            cellWidthSouth,
            cellWidthNorth,
            latTransition,
            latWidthTransition)

        _, cellWidth = np.meshgrid(lon, cellWidthVsLat)

        cellWidthAtlantic = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30.,
                                                  cellWidthMidLat=30.,
                                                  cellWidthPole=35.,
                                                  latPosEq=7.5, latWidthEq=3.0)

        cellWidthAtlantic = mdt.mergeCellWidthVsLat(
            lat,
            cellWidthSouth,
            cellWidthAtlantic,
            latTransition,
            latWidthTransition)

        _, cellWidthAtlantic = np.meshgrid(lon, cellWidthAtlantic)

        fc = read_feature_collection('atlantic.geojson')

        atlantic_signed_distance = signed_distance_from_geojson(
            fc, lon, lat, earth_radius, max_length=0.25)

        trans_width = 400e3
        trans_start = 0.
        weights = 0.5 * (1 + np.tanh((atlantic_signed_distance - trans_start) /
                                     trans_width))

        cellWidth = cellWidthAtlantic * (1 - weights) + cellWidth * weights

        fc = read_feature_collection('high_res_region.geojson')

        so_signed_distance = signed_distance_from_geojson(fc, lon, lat,
                                                          earth_radius,
                                                          max_length=0.25)

        # Equivalent to 20 degrees latitude
        trans_width = 1600e3
        trans_start = 500e3
        dx_min = 12.

        weights = 0.5 * (1 + np.tanh((so_signed_distance - trans_start) /
                                     trans_width))

        cellWidth = dx_min * (1 - weights) + cellWidth * weights

        return cellWidth, lon, lat
示例#9
0
def cellWidthVsLatLon():
    """
    Create cell width array for this mesh on a regular latitude-longitude grid.
    Returns
    -------
       cellWidth : ndarray
            m x n array, entries are desired cell width in km

       lat : ndarray
            latitude, vector of length m, with entries between -90 and 90,
            degrees

       lon : ndarray
            longitude, vector of length n, with entries between -180 and 180,
            degrees
    """
    # To speed up for testing, set following line to 1.0 degrees
    dlon = 1.0
    dlat = dlon
    earth_radius = constants['SHR_CONST_REARTH']
    print('\nCreating cellWidth on a lat-lon grid of: {0:.2f} x {0:.2f} '
          'degrees'.format(dlon, dlat))
    print('This can be set higher for faster test generation\n')
    nlon = int(360. / dlon) + 1
    nlat = int(180. / dlat) + 1
    lon = np.linspace(-180., 180., nlon)
    lat = np.linspace(-90., 90., nlat)
    km = 1.0e3

    print('plotting ...')
    fig = plt.figure()
    plt.clf()
    fig.set_size_inches(10.0, 10.0)
    register_sci_viz_colormaps()

    # Create cell width vs latitude for Atlantic and Pacific basins
    QU1 = np.ones(lat.size)
    EC60to30 = mdt.EC_CellWidthVsLat(lat)
    RRS30to10 = mdt.RRS_CellWidthVsLat(lat, 30, 10)
    AtlNH = RRS30to10
    AtlVsLat = mdt.mergeCellWidthVsLat(lat, EC60to30, AtlNH, 0, 6)
    PacNH = mdt.mergeCellWidthVsLat(lat, 30 * QU1, RRS30to10, 50, 10)
    PacVsLat = mdt.mergeCellWidthVsLat(lat, EC60to30, PacNH, 0, 6)

    # Expand from 1D to 2D
    _, AtlGrid = np.meshgrid(lon, AtlVsLat)
    _, PacGrid = np.meshgrid(lon, PacVsLat)

    # Signed distance of Atlantic region
    fc = read_feature_collection('Atlantic_region.geojson')
    signedDistance = signed_distance_from_geojson(fc,
                                                  lon,
                                                  lat,
                                                  earth_radius,
                                                  max_length=0.25)

    # Merge Atlantic and Pacific distrubutions smoothly
    transitionWidth = 500.0 * km
    maskSmooth = 0.5 * (1 + np.tanh(signedDistance / transitionWidth))
    cellWidthSmooth = PacGrid * maskSmooth + AtlGrid * (1 - maskSmooth)

    # Merge Atlantic and Pacific distrubutions with step function
    maskSharp = 0.5 * (1 + np.sign(signedDistance))
    cellWidthSharp = PacGrid * maskSharp + AtlGrid * (1 - maskSharp)

    # Create a land mask that is 1 over land
    fc = read_feature_collection('Americas_land_mask.geojson')
    Americas_land_mask = mask_from_geojson(fc, lon, lat)
    fc = read_feature_collection('Europe_Africa_land_mask.geojson')
    Europe_Africa_land_mask = mask_from_geojson(fc, lon, lat)
    landMask = np.fmax(Americas_land_mask, Europe_Africa_land_mask)

    # Merge: step transition over land, smooth transition over water
    cellWidth = cellWidthSharp * landMask + cellWidthSmooth * (1 - landMask)

    ax = plt.subplot(4, 2, 1)
    ax.plot(lat, AtlVsLat, label='Atlantic')
    ax.plot(lat, PacVsLat, label='Pacific')
    ax.grid(True)
    plt.title('Grid cell size [km] versus latitude')
    plt.legend()

    varNames = [
        'signedDistance', 'maskSmooth', 'cellWidthSmooth', 'maskSharp',
        'cellWidthSharp', 'landMask', 'cellWidth'
    ]
    j = 2
    for varName in varNames:
        plot_cartopy(j, varName, vars()[varName], '3Wbgy5')
        j += 1
    fig.canvas.draw()
    plt.tight_layout()

    plt.savefig('mesh_construction.png')

    return cellWidth, lon, lat
示例#10
0
    def build_cell_width_lat_lon(self):
        """
        Create cell width array for this mesh on a regular latitude-longitude
        grid

        Returns
        -------
        cellWidth : numpy.array
            m x n array of cell width in km

        lon : numpy.array
            longitude in degrees (length n and between -180 and 180)

        lat : numpy.array
            longitude in degrees (length m and between -90 and 90)
        """

        dlon = 0.1
        dlat = dlon
        earth_radius = constants['SHR_CONST_REARTH']
        print('\nCreating cellWidth on a lat-lon grid of: {0:.2f} x {0:.2f} '
              'degrees'.format(dlon, dlat))
        print('This can be set higher for faster test generation\n')
        nlon = int(360. / dlon) + 1
        nlat = int(180. / dlat) + 1
        lon = np.linspace(-180., 180., nlon)
        lat = np.linspace(-90., 90., nlat)
        km = 1.0e3

        print('plotting ...')
        plt.switch_backend('Agg')
        fig = plt.figure()
        plt.clf()
        fig.set_size_inches(10.0, 14.0)
        register_sci_viz_colormaps()

        # Create cell width vs latitude for Atlantic and Pacific basins
        EC60to30 = mdt.EC_CellWidthVsLat(lat)
        EC60to30Narrow = mdt.EC_CellWidthVsLat(lat, latPosEq=8.0,
                                               latWidthEq=3.0)

        # Expand from 1D to 2D
        _, cellWidth = np.meshgrid(lon, EC60to30Narrow)
        _plot_cartopy(2, 'narrow EC60to30', cellWidth, '3Wbgy5')
        plotFrame = 3

        # global settings for regionally refines mesh
        highRes = 14.0  # [km]

        fileName = 'region_Central_America'
        transitionWidth = 800.0 * km
        transitionOffset = 0.0
        fc = read_feature_collection('{}.geojson'.format(fileName))
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        mask = 0.5 * (1 + np.tanh((transitionOffset - signedDistance) /
                                  (transitionWidth / 2.)))
        cellWidth = 30.0 * mask + cellWidth * (1 - mask)

        fileName = 'coastline_CUSP'
        distanceToTransition = 600.0 * km
        # transitionWidth is distance from 0.07 to 0.03 of transition within
        # tanh
        transitionWidth = 600.0 * km
        transitionOffset = distanceToTransition + transitionWidth / 2.0
        fc = read_feature_collection('{}.geojson'.format(fileName))
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        mask = 0.5 * (1 + np.tanh((transitionOffset - signedDistance) /
                                  (transitionWidth / 2.)))
        cellWidth = highRes * mask + cellWidth * (1 - mask)
        _plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
        _plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5')
        plotFrame += 2

        fileName = 'region_Gulf_of_Mexico'
        transitionOffset = 600.0 * km
        transitionWidth = 600.0 * km
        fc = read_feature_collection('{}.geojson'.format(fileName))
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        maskSmooth = 0.5 * (1 + np.tanh((transitionOffset - signedDistance) /
                                        (transitionWidth / 2.)))
        maskSharp = 0.5 * (1 + np.sign(-signedDistance))
        fc = read_feature_collection('land_mask_Mexico.geojson')
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        landMask = 0.5 * (1 + np.sign(-signedDistance))
        mask = maskSharp * landMask + maskSmooth * (1 - landMask)
        cellWidth = highRes * mask + cellWidth * (1 - mask)
        _plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
        _plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5')
        plotFrame += 2

        fileName = 'region_Bering_Sea'
        transitionOffset = 0.0 * km
        transitionWidth = 600.0 * km
        fc = read_feature_collection('{}.geojson'.format(fileName))
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        maskSmoothEast = 0.5 * (
                    1 + np.tanh((transitionOffset - signedDistance) /
                                (transitionWidth / 2.)))

        fc = read_feature_collection('region_Bering_Sea_reduced.geojson')
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        maskSmoothWest = 0.5 * (
                    1 + np.tanh((transitionOffset - signedDistance) /
                                (transitionWidth / 2.)))

        fc = read_feature_collection('land_mask_Kamchatka.geojson')
        maskWest = mask_from_geojson(fc, lon, lat)
        mask = maskSmoothWest * maskWest + maskSmoothEast * (1 - maskWest)
        cellWidth = highRes * mask + cellWidth * (1 - mask)
        _plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
        _plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5')
        plotFrame += 2

        fileName = 'region_Arctic_Ocean'
        transitionOffset = 0.0 * km
        transitionWidth = 600.0 * km
        fc = read_feature_collection('{}.geojson'.format(fileName))
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        mask = 0.5 * (1 + np.tanh((transitionOffset - signedDistance) /
                                  (transitionWidth / 2.)))
        cellWidth = highRes * mask + cellWidth * (1 - mask)
        _plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
        _plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5')
        plotFrame += 2

        fileName = 'region_Gulf_Stream_extension'
        transitionOffset = 0.0 * km
        transitionWidth = 600.0 * km
        fc = read_feature_collection('{}.geojson'.format(fileName))
        signedDistance = signed_distance_from_geojson(fc, lon, lat,
                                                      earth_radius,
                                                      max_length=0.25)
        mask = 0.5 * (1 + np.tanh((transitionOffset - signedDistance) /
                                  (transitionWidth / 2.)))
        cellWidth = highRes * mask + cellWidth * (1 - mask)
        _plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues')
        _plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5')
        plotFrame += 2

        ax = plt.subplot(6, 2, 1)
        ax.plot(lat, EC60to30, label='original EC60to30')
        ax.plot(lat, EC60to30Narrow, label='narrow EC60to30')
        ax.grid(True)
        plt.title('Grid cell size [km] versus latitude')
        plt.legend(loc="upper left")

        plt.savefig('mesh_construction.png', dpi=300)

        return cellWidth, lon, lat
示例#11
0
def setspac():

    spac_ocn = 30.  # regional ocn. km
    spac_1_m = 2.  # sqrt(H) ocn. km
    spac_lnd = 45.  # global land km
    spac_wbd = 5.  # watershed km
    spac_pfz = 2.  # PFZ km
    elev_pfz = 25.  # PFZ elev. thresh
    dhdx_lim = 0.0625  # |dH/dx| thresh

    fade_pos = [-75.2316, 39.1269]
    fade_len = 700.
    fade_gap = 350.

    spac = jigsawpy.jigsaw_msh_t()

    opts = jigsawpy.jigsaw_jig_t()
    poly = jigsawpy.jigsaw_msh_t()

    opts.jcfg_file = os.path.join(TDIR, "opts.jig")
    opts.hfun_file = os.path.join(TDIR, "spac.msh")

    #------------------------------------ define spacing pattern

    print("BUILDING MESH SPAC.")

    print("Loading elevation assets...")

    data = nc.Dataset(
        os.path.join("data", "etopo_gebco", "etopo_gebco_tiled.nc"), "r")

    zlev = np.array(data.variables["z"])

    spac.mshID = "ellipsoid-grid"  # use elev. grid
    spac.radii = np.full(+3, FULL_SPHERE_RADIUS, dtype=spac.REALS_t)

    spac.xgrid = np.array(data.variables["x"][:], dtype=spac.REALS_t)

    spac.ygrid = np.array(data.variables["y"][:], dtype=spac.REALS_t)

    spac.xgrid *= np.pi / +180.
    spac.ygrid *= np.pi / +180.

    xgrd, ygrd = np.meshgrid(spac.xgrid, spac.ygrid)

    grid = np.concatenate(
        (  # to [x, y] list
            xgrd.reshape((xgrd.size, +1)), ygrd.reshape((ygrd.size, +1))),
        axis=+1)

    #------------------------------------ global ocn ec-60-to-30

    print("Compute global ocean h(x)...")

    vals = \
        mdt.EC_CellWidthVsLat(spac.ygrid * 180. / np.pi)

    vals = np.reshape(vals, (spac.ygrid.size, 1))

    spac.value = np.array(np.tile(vals, (1, spac.xgrid.size)),
                          dtype=spac.REALS_t)

    #------------------------------------ region ocn "eddy" halo

    filename = os.path.join("data", "na_ocean_halo", "na_ocean_halo.geojson")

    loadgeo(filename, poly)

    poly.point["coord"] *= np.pi / +180.

    mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"])

    mask = np.reshape(mask, spac.value.shape)

    mask = np.logical_and(mask, zlev <= +0.0)

    spac.value[mask] = \
        np.minimum(spac_ocn, spac.value[mask])

    #------------------------------------ coastal ocn heuristics

    mask = zlev <= +0.0

    hval = np.sqrt(np.maximum(-zlev, +0.0))
    hval = np.maximum(spac_1_m, hval / np.sqrt(+1.0) / spac_1_m)

    dist = sphdist(FULL_SPHERE_RADIUS, grid[:, 0], grid[:, 1],
                   fade_pos[0] * np.pi / 180., fade_pos[1] * np.pi / 180.)
    dist = np.reshape(dist, spac.value.shape)

    hval = blender(hval, spac.value, dist, fade_len, fade_gap)

    spac.value[mask] = \
        np.minimum(hval[mask], spac.value[mask])

    #------------------------------------ global lnd const. = 45

    print("Compute global land h(x)...")

    halo = +9  # filter islands

    zmed = median_filter(zlev, size=halo, mode="wrap")

    spac.value[zmed >= 0.0] = spac_lnd

    #------------------------------------ push watershed(s) = 5.

    print("Compute watersheds h(x)...")

    shed = np.full((grid.shape[0]), False, dtype=bool)

    filename = os.path.join("data", "NHD_H_0204_HU4_Shape", "Shape",
                            "WBDHU4.shp")

    loadshp(filename, poly)

    poly.point["coord"] *= np.pi / +180.

    mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"])

    shed[mask] = True

    filename = os.path.join("data", "NHD_H_0205_HU4_Shape", "Shape",
                            "WBDHU4.shp")

    loadshp(filename, poly)

    poly.point["coord"] *= np.pi / +180.

    mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"])

    shed[mask] = True

    filename = os.path.join("data", "NHD_H_0206_HU4_Shape", "Shape",
                            "WBDHU4.shp")

    loadshp(filename, poly)

    poly.point["coord"] *= np.pi / +180.

    mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"])

    shed[mask] = True

    filename = os.path.join("data", "NHD_H_0207_HU4_Shape", "Shape",
                            "WBDHU4.shp")

    loadshp(filename, poly)

    poly.point["coord"] *= np.pi / +180.

    mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"])

    shed[mask] = True

    filename = os.path.join("data", "NHD_H_0208_HU4_Shape", "Shape",
                            "WBDHU4.shp")

    loadshp(filename, poly)

    poly.point["coord"] *= np.pi / +180.

    mask, _ = inpoly2(grid, poly.point["coord"], poly.edge2["index"])

    shed[mask] = True

    shed = np.reshape(shed, spac.value.shape)

    spac.value[shed] = \
        np.minimum(spac_wbd, spac.value[shed])

    #------------------------------------ partially flooded zone

    mask = np.logical_and(shed, zlev < elev_pfz)

    spac.value[mask] = \
        np.minimum(spac_pfz, spac.value[mask])

    #------------------------------------ push |DH/DX| threshold

    print("Impose |DH/DX| threshold...")

    spac.slope = np.full(spac.value.shape, dhdx_lim, dtype=spac.REALS_t)

    jigsawpy.savemsh(opts.hfun_file, spac, "precision = 9")

    jigsawpy.cmd.marche(opts, spac)

    spac.slope = \
        np.empty((+0), dtype=spac.REALS_t)

    return spac