def _shared_steps(out_filename, vtk_dir, preserve_floodplain, floodplain_elevation, do_inject_bathymetry, logger, use_progress_bar): step = 5 if do_inject_bathymetry: logger.info('Step {}. Injecting bathymetry'.format(step)) inject_bathymetry(mesh_file=out_filename) step += 1 if preserve_floodplain: logger.info('Step {}. Injecting flag to preserve floodplain'.format( step)) inject_preserve_floodplain(mesh_file=out_filename, floodplain_elevation=floodplain_elevation) step += 1 logger.info('Step {}. Create vtk file for visualization'.format(step)) extract_vtk(ignore_time=True, lonlat=True, dimension_list=['maxEdges='], variable_list=['allOnCells'], filename_pattern=out_filename, out_dir=vtk_dir, use_progress_bar=use_progress_bar) logger.info("***********************************************") logger.info("** The global mesh file is {} **".format(out_filename)) logger.info("***********************************************")
if options.with_cavities: fcAntarcticIce = gf.read(componentName='bedmachine', objectType='region', featureNames=['AntarcticIceCoverage']) fcAntarcticIce.to_geojson('ice_coverage.geojson') dsMask = conversion.mask(dsCulledMesh, fcMask=fcAntarcticIce) landIceMask = dsMask.regionCellMasks.isel(nRegions=0) dsLandIceMask = xarray.Dataset() dsLandIceMask['landIceMask'] = landIceMask write_netcdf(dsLandIceMask, 'land_ice_mask.nc', format=netcdfFormat) dsLandIceCulledMesh = conversion.cull(dsCulledMesh, dsMask=dsMask) write_netcdf(dsLandIceCulledMesh, 'no_ISC_culled_mesh.nc', format=netcdfFormat) extract_vtk(ignore_time=True, dimension_list=['maxEdges='], variable_list=['allOnCells'], filename_pattern='culled_mesh.nc', out_dir='culled_mesh_vtk') if options.with_cavities: extract_vtk(ignore_time=True, dimension_list=['maxEdges='], variable_list=['allOnCells'], filename_pattern='no_ISC_culled_mesh.nc', out_dir='no_ISC_culled_mesh_vtk')
def build_mesh( preserve_floodplain=False, floodplain_elevation=20.0, do_inject_bathymetry=False, geometry='sphere', plot_cellWidth=True): if geometry == 'sphere': on_sphere = True else: on_sphere = False print('Step 1. Build cellWidth array as function of horizontal coordinates') if on_sphere: cellWidth, lon, lat = define_base_mesh.cellWidthVsLatLon() da = xarray.DataArray(cellWidth, dims=['lat', 'lon'], coords={'lat': lat, 'lon': lon}, name='cellWidth') cw_filename = 'cellWidthVsLatLon.nc' da.to_netcdf(cw_filename) plot_cellWidth = True if plot_cellWidth: register_sci_viz_colormaps() fig = plt.figure(figsize=[16.0, 8.0]) ax = plt.axes(projection=ccrs.PlateCarree()) ax.set_global() im = ax.imshow(cellWidth, origin='lower', transform=ccrs.PlateCarree(), extent=[-180, 180, -90, 90], cmap='3Wbgy5', zorder=0) ax.add_feature(cartopy.feature.LAND, edgecolor='black', zorder=1) gl = ax.gridlines( crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, color='gray', alpha=0.5, linestyle='-', zorder=2) gl.top_labels = False gl.right_labels = False plt.title( 'Grid cell size, km, min: {:.1f} max: {:.1f}'.format( cellWidth.min(),cellWidth.max())) plt.colorbar(im, shrink=.60) fig.canvas.draw() plt.tight_layout() plt.savefig('cellWidthGlobal.png', bbox_inches='tight', dpi=300) plt.close() else: cellWidth, x, y, geom_points, geom_edges = define_base_mesh.cellWidthVsXY() da = xarray.DataArray(cellWidth, dims=['y', 'x'], coords={'y': y, 'x': x}, name='cellWidth') cw_filename = 'cellWidthVsXY.nc' da.to_netcdf(cw_filename) print('Step 2. Generate mesh with JIGSAW') if on_sphere: jigsaw_driver(cellWidth, lon, lat) else: jigsaw_driver( cellWidth, x, y, on_sphere=False, geom_points=geom_points, geom_edges=geom_edges) print('Step 3. Convert triangles from jigsaw format to netcdf') jigsaw_to_netcdf(msh_filename='mesh-MESH.msh', output_name='mesh_triangles.nc', on_sphere=on_sphere) print('Step 4. Convert from triangles to MPAS mesh') write_netcdf(convert(xarray.open_dataset('mesh_triangles.nc')), 'base_mesh.nc') print('Step 5. Inject correct meshDensity variable into base mesh file') inject_meshDensity(cw_filename=cw_filename, mesh_filename='base_mesh.nc', on_sphere=on_sphere) if do_inject_bathymetry: print('Step 6. Injecting bathymetry') inject_bathymetry(mesh_file='base_mesh.nc') if preserve_floodplain: print('Step 7. Injecting flag to preserve floodplain') inject_preserve_floodplain(mesh_file='base_mesh.nc', floodplain_elevation=floodplain_elevation) print('Step 8. Create vtk file for visualization') extract_vtk(ignore_time=True, lonlat=True, dimension_list=['maxEdges='], variable_list=['allOnCells'], filename_pattern='base_mesh.nc', out_dir='base_mesh_vtk') print("***********************************************") print("** The global mesh file is base_mesh.nc **") print("***********************************************")
def _cull_mesh_with_logging(logger, with_cavities, with_critical_passages, custom_critical_passages, custom_land_blockages, preserve_floodplain, use_progress_bar, process_count): """ Cull the mesh once the logger is defined for sure """ critical_passages = with_critical_passages or \ (custom_critical_passages is not None) land_blockages = with_critical_passages or \ (custom_land_blockages is not None) gf = GeometricFeatures() # start with the land coverage from Natural Earth fcLandCoverage = gf.read(componentName='natural_earth', objectType='region', featureNames=['Land Coverage']) # remove the region south of 60S so we can replace it based on ice-sheet # topography fcSouthMask = gf.read(componentName='ocean', objectType='region', featureNames=['Global Ocean 90S to 60S']) fcLandCoverage = fcLandCoverage.difference(fcSouthMask) # Add "land" coverage from either the full ice sheet or just the grounded # part if with_cavities: fcAntarcticLand = gf.read( componentName='bedmachine', objectType='region', featureNames=['AntarcticGroundedIceCoverage']) else: fcAntarcticLand = gf.read( componentName='bedmachine', objectType='region', featureNames=['AntarcticIceCoverage']) fcLandCoverage.merge(fcAntarcticLand) # save the feature collection to a geojson file fcLandCoverage.to_geojson('land_coverage.geojson') # these defaults may have been updated from config options -- pass them # along to the subprocess netcdf_format = mpas_tools.io.default_format netcdf_engine = mpas_tools.io.default_engine # Create the land mask based on the land coverage, i.e. coastline data args = ['compute_mpas_region_masks', '-m', 'base_mesh.nc', '-g', 'land_coverage.geojson', '-o', 'land_mask.nc', '-t', 'cell', '--process_count', '{}'.format(process_count), '--format', netcdf_format, '--engine', netcdf_engine] check_call(args, logger=logger) dsBaseMesh = xarray.open_dataset('base_mesh.nc') dsLandMask = xarray.open_dataset('land_mask.nc') dsLandMask = add_land_locked_cells_to_mask(dsLandMask, dsBaseMesh, latitude_threshold=43.0, nSweeps=20) # create seed points for a flood fill of the ocean # use all points in the ocean directory, on the assumption that they are, # in fact, in the ocean fcSeed = gf.read(componentName='ocean', objectType='point', tags=['seed_point']) if land_blockages: if with_critical_passages: # merge transects for critical land blockages into # critical_land_blockages.geojson fcCritBlockages = gf.read( componentName='ocean', objectType='transect', tags=['Critical_Land_Blockage']) else: fcCritBlockages = FeatureCollection() if custom_land_blockages is not None: fcCritBlockages.merge(read_feature_collection( custom_land_blockages)) # create masks from the transects fcCritBlockages.to_geojson('critical_blockages.geojson') args = ['compute_mpas_transect_masks', '-m', 'base_mesh.nc', '-g', 'critical_blockages.geojson', '-o', 'critical_blockages.nc', '-t', 'cell', '-s', '10e3', '--process_count', '{}'.format(process_count), '--format', netcdf_format, '--engine', netcdf_engine] check_call(args, logger=logger) dsCritBlockMask = xarray.open_dataset('critical_blockages.nc') dsLandMask = add_critical_land_blockages(dsLandMask, dsCritBlockMask) fcCritPassages = FeatureCollection() dsPreserve = [] if critical_passages: if with_critical_passages: # merge transects for critical passages into fcCritPassages fcCritPassages.merge(gf.read(componentName='ocean', objectType='transect', tags=['Critical_Passage'])) if custom_critical_passages is not None: fcCritPassages.merge(read_feature_collection( custom_critical_passages)) # create masks from the transects fcCritPassages.to_geojson('critical_passages.geojson') args = ['compute_mpas_transect_masks', '-m', 'base_mesh.nc', '-g', 'critical_passages.geojson', '-o', 'critical_passages.nc', '-t', 'cell', 'edge', '-s', '10e3', '--process_count', '{}'.format(process_count), '--format', netcdf_format, '--engine', netcdf_engine] check_call(args, logger=logger) dsCritPassMask = xarray.open_dataset('critical_passages.nc') # Alter critical passages to be at least two cells wide, to avoid sea # ice blockage dsCritPassMask = widen_transect_edge_masks(dsCritPassMask, dsBaseMesh, latitude_threshold=43.0) dsPreserve.append(dsCritPassMask) if preserve_floodplain: dsPreserve.append(dsBaseMesh) # cull the mesh based on the land mask dsCulledMesh = cull(dsBaseMesh, dsMask=dsLandMask, dsPreserve=dsPreserve, logger=logger) # create a mask for the flood fill seed points dsSeedMask = compute_mpas_flood_fill_mask(dsMesh=dsCulledMesh, fcSeed=fcSeed, logger=logger) # cull the mesh a second time using a flood fill from the seed points dsCulledMesh = cull(dsCulledMesh, dsInverse=dsSeedMask, graphInfoFileName='culled_graph.info', logger=logger) write_netcdf(dsCulledMesh, 'culled_mesh.nc') if critical_passages: # make a new version of the critical passages mask on the culled mesh fcCritPassages.to_geojson('critical_passages.geojson') args = ['compute_mpas_transect_masks', '-m', 'culled_mesh.nc', '-g', 'critical_passages.geojson', '-o', 'critical_passages_mask_final.nc', '-t', 'cell', '-s', '10e3', '--process_count', '{}'.format(process_count), '--format', netcdf_format, '--engine', netcdf_engine] check_call(args, logger=logger) if with_cavities: fcAntarcticIce = gf.read( componentName='bedmachine', objectType='region', featureNames=['AntarcticIceCoverage']) fcAntarcticIce.to_geojson('ice_coverage.geojson') args = ['compute_mpas_region_masks', '-m', 'culled_mesh.nc', '-g', 'ice_coverage.geojson', '-o', 'ice_coverage.nc', '-t', 'cell', '--process_count', '{}'.format(process_count), '--format', netcdf_format, '--engine', netcdf_engine] check_call(args, logger=logger) dsMask = xarray.open_dataset('ice_coverage.nc') landIceMask = dsMask.regionCellMasks.isel(nRegions=0) dsLandIceMask = xarray.Dataset() dsLandIceMask['landIceMask'] = landIceMask write_netcdf(dsLandIceMask, 'land_ice_mask.nc') dsLandIceCulledMesh = cull(dsCulledMesh, dsMask=dsMask, logger=logger) write_netcdf(dsLandIceCulledMesh, 'no_ISC_culled_mesh.nc') extract_vtk(ignore_time=True, dimension_list=['maxEdges='], variable_list=['allOnCells'], filename_pattern='culled_mesh.nc', out_dir='culled_mesh_vtk', use_progress_bar=use_progress_bar) if with_cavities: extract_vtk(ignore_time=True, dimension_list=['maxEdges='], variable_list=['allOnCells'], filename_pattern='no_ISC_culled_mesh.nc', out_dir='no_ISC_culled_mesh_vtk', use_progress_bar=use_progress_bar)