Mesh

Spherical Meshes

Tasks that use global, spherical meshes can add either polaris.mesh.QuasiUniformSphericalMeshStep or polaris.mesh.IcosahedralMeshStep in order to creating a base mesh, using JIGSAW. Alternatively, they can use polaris.mesh.QuasiUniformSphericalMeshStep as the base class for creating a more complex mesh by overriding the polaris.mesh.QuasiUniformSphericalMeshStep.build_cell_width_lat_lon() method.

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 polaris.mesh.IcosahedralMeshStep.make_jigsaw_mesh() or polaris.mesh.QuasiUniformSphericalMeshStep.make_jigsaw_mesh() methods.

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

The following config options are associated with spherical meshes:

# 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 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 = True

# 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

Planar Meshes

So far, there is not support for creating planar meshes in the polaris framework. But there are helpful functions for creating both uniform hexagonal meshes and more general planar meshes using the mpas_tools package.

Uniform planar meshes

You can build a uniform planar mesh in a step by calling mpas_tools.planar_hex.make_planar_hex_mesh(). The mesh is defined by the number of cells in the x and y directions (nx and ny), the resolution dc in km (dc is the distance between adjacent cell centers), and some (admittedly oddly named) parameters for determining which directions (if any) are periodic, nonperiodic_x and nonperiodic_y.

There are a few considerations for determining nx and ny. There is a framework level function polaris.mesh.planar.compute_planar_hex_nx_ny() to take care of this for you:

from polaris.mesh.planar import compute_planar_hex_nx_ny


nx, ny = compute_planar_hex_nx_ny(lx, ly, resolution)

What follows is an explanation of the subtleties that are accounted for in that function. Typically, we need at least 4 grid cells in each direction for MPAS-Ocean to be well behaved, and similar restrictions may apply to other components. Second, ny needs to be an even number because of the staggering of the hexagons used to create the mesh. (We typically also use even numbers for nx but that is not strictly necessary.)

Another important consideration is that the physical size of the mesh in the x direction is lx = nx * dc. However, the physical extent in the y direction is ly = (np.sqrt(3) / 2) * ny * dc because of the staggering of the hexagons in that direction. As a result, if you know the desired domain size ly, you need to compute the number of cells in that direction including an extra factor of 2. / np.sqrt(3), as in this example:

import numpy as np
from mpas_tools.planar_hex import make_planar_hex_mesh

lx = 500e3
ly = 160e3
dc = 1e3

nx = max(2 * int(0.5 * lx / dc + 0.5), 4)
# factor of 2/sqrt(3) because of hexagonal mesh
ny = max(2 * int(0.5 * ly * (2. / np.sqrt(3)) / dc + 0.5), 4)

ds_mesh = make_planar_hex_mesh(nx=nx, ny=ny, dc=dc, nonperiodic_x=False,
                               nonperiodic_y=True)

General planar meshes

One way to create a more general planar mesh is by calling mpas_tools.mesh.creation.build_mesh.build_planar_mesh(), which uses JIGSAW to build a mesh with variable resolution. See Planar Meshes for more details. We plan to create framework-level steps for planar meshes similar to polaris.mesh.QuasiUniformSphericalMeshStep and polaris.mesh.IcosahedralMeshStep in the not too distant future.