Example #1
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
Example #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
    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
Example #3
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
Example #4
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
Example #5
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
Example #6
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