(dev-spherical-meshes)= # Spherical Meshes The spherical meshes that have broad support accross tasks can be created with the shared helper function {py:func}`polaris.mesh.base.add_spherical_base_mesh_step()`. Each mesh is defined by a prefix (see the table below) and a `min_res` as well as an optional `max_res` (both in km). These meshes are all created with the [JIGSAW](https://github.com/dengwirda/jigsaw) and [JIGSAW-Python](https://github.com/dengwirda/jigsaw-python) tools. ```python from polaris.mesh.base import add_spherical_base_mesh_step mesh_step = add_spherical_base_mesh_step( prefix='qu', min_res=120.0, ) ``` ```python from polaris.mesh.base import add_spherical_base_mesh_step mesh_step = add_spherical_base_mesh_step( prefix='so', min_res=12.0, max_res=30.0, ) ``` | prefix | mesh description | |--------|------------------------------------------------------| | qu | quasi-uniform resolution | | icos | dual mesh of a subdivided icosahedron | | rrs | resolution approximately scaled by the Rossby radius | | so | resoluiton enhanced in the Southern Ocean | To define a new shared mesh or for more specialized meshes, can instantiate {py:class}`polaris.mesh.QuasiUniformSphericalMeshStep` or {py:class}`polaris.mesh.IcosahedralMeshStep` directly when you need more control. For more complex meshes, use {py:class}`polaris.mesh.QuasiUniformSphericalMeshStep` as a base class and override {py:meth}`polaris.mesh.QuasiUniformSphericalMeshStep.build_cell_width_lat_lon()`. A developer can also customize the options data structure passed on to JIGSAW either by modifying the `opts` attribute of either of these classes or by overriding the {py:meth}`polaris.mesh.IcosahedralMeshStep.make_jigsaw_mesh()` or {py:meth}`polaris.mesh.QuasiUniformSphericalMeshStep.make_jigsaw_mesh()` methods. The following config options are associated with spherical meshes: ```cfg # config options related to spherical meshes [spherical_mesh] # for icosahedral meshes, whether to use cell_width to determine the number of # subdivisions or to use subdivisions directly icosahedral_method = cell_width # output file names jigsaw_mesh_filename = mesh.msh jigsaw_geom_filename = geom.msh jigsaw_jcfg_filename = opts.jig jigsaw_hfun_filename = spac.msh triangles_filename = mesh_triangles.nc mpas_mesh_filename = base_mesh.nc # options related to mesh name and resolution # the prefix (e.g. Icos, QU, SO, RRS) prefix = PREFIX # the minimum (finest) resolution in the mesh min_cell_width = <<>> # the maximum (coarsest) resolution in the mesh, can be the same as # min_cell_width max_cell_width = <<>> # options related to writing out and plotting cell widths plot_cell_width = True cell_width_filename = cellWidthVsLatLon.nc cell_width_image_filename = cellWidthGlobal.png cell_width_colormap = 3Wbgy5 # whether to add the mesh density to the file add_mesh_density = False # convert the mesh to vtk format for visualization convert_to_vtk = False # the subdirectory for the vtk output vtk_dir = base_mesh_vtk # whether to extract the vtk output in lat/lon space, rather than on the sphere vtk_lat_lon = False ``` ## Supported Base Mesh Steps May Polaris tasks and steps are generated only for a set of predetermined, supported base meshes and resolutions. The list of base mesh steps is generated by {py:func}`polaris.mesh.base.get_base_mesh_steps()`. Currently, the following meshes and resolutions are include in the list returned by `get_base_mesh_steps()`: Uniform: * Icos480km * Icos240km * Icos120km * Icos60km * Icos30km * QU480km * QU240km * QU210km * QU180km * QU150km * QU120km * QU90km * QU60km * QU30km Variable: * SO12to30km * RRS6to18km If you wish to add a new resolution (in km), simply edit the list of either uniform or variable resolutions to add the new value(s): ```python uniform_res: Dict[str, List[float]] = { 'icos': [480.0, 240.0, 120.0, 60.0, 30.0], 'qu': [480.0, 240.0, 210.0, 180.0, 150.0, 120.0, 90.0, 60.0, 30.0], } # Add more variable resolution base meshes here variable_res: Dict[str, List[Tuple[float, float]]] = { 'so': [(12.0, 30.0)], 'rrs': [(6.0, 18.0)], } ``` Each variable resolution mesh has a tuple of the finest and coarsest resolution. To add a new type of base mesh, you first need to add its base class to `MESH_CLASSES` and `MESH_NAME_PREFIXES` in `polaris/mesh/base/add.py`: ```python MESH_CLASSES = { 'icos': IcosahedralMeshStep, 'qu': QuasiUniformSphericalMeshStep, 'rrs': RRSBaseMesh, 'so': SOBaseMesh, } MESH_NAME_PREFIXES = { 'icos': 'Icos', 'qu': 'QU', 'rrs': 'RRS', 'so': 'SO', } ``` Then, you can add prefix and its associated resolutions to `get_base_mesh_steps()` as above. By adding new mesh prefixes and/or resolutions to `get_base_mesh_steps()`, a version of each task that builds on base meshes (such as those for remapping topography and culling out land or ocean) will be added to the list of tasks when you run `polaris list`. ## Approximately Uniform Spherical Meshes Icosahedral meshes will be significantly more uniform and smooth in cell size than quasi-uniform spherical meshes. On the other hand, icosahedral meshes are restricted to resolutions that are an integer number of subdivisions of an icosahedron. The following table shows the approximate resolution of a mesh with a given number of subdivisions: | subdivisions | cell width (km) | |--------------|-----------------| | 5 | 240 | | 6 | 120 | | 7 | 60 | | 8 | 30 | | 9 | 15 | | 10 | 7.5 | | 11 | 3.8 | | 12 | 1.9 | | 13 | 0.94 | ## Rossby-radius Scaled (RRS) Meshes The RRS meshes are defined by {py:class}`polaris.mesh.base.rrs.RRSBaseMesh` and have a resolution that ranges from finest at the poles to coarsests at the equator, scaling approximately with the Rossby radius. The scaling is: ```{math} w(\phi) = \frac{r_{\min}}{\Big[\,\gamma + (1-\gamma)\,\sin^{4}(|\phi|)\,\Big]^{1/4}},\quad \gamma = \left(\frac{r_{\min}}{r_{\max}}\right)^{4}. ``` Where $\phi$ is the latitude in radians and $r_{\min}$ and $r_{\max}$ are the finest and coarsest resolutions, respectively. ```{image} images/rrs.png :align: center :width: 500 px ``` ## Southern Ocean (SO) Meshes The SO meshes are defined by {py:class}`polaris.mesh.base.so.SOBaseMesh` and have a quasi-uniform, coarse background resolution that transitions to a higher resolution region surrounding the Southern Ocean. The high resolution region is defined by a geojson shape that attempts to approximatly follow dynamical ocean contours since rapid changes in resolution have been shown to steer ocean currents along isocontours of resolution. ```{image} images/so.png :align: center :width: 500 px ```