Skip to content

Commit

Permalink
Merge pull request #774 from irenavankova/add-FRIS-meshes
Browse files Browse the repository at this point in the history
Add FRIS meshes
  • Loading branch information
xylar authored Feb 14, 2024
2 parents 4130abc + ca1bb44 commit 1e1ac50
Show file tree
Hide file tree
Showing 68 changed files with 4,738 additions and 9 deletions.
5 changes: 5 additions & 0 deletions compass/ocean/tests/global_ocean/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ def __init__(self, mpas_core):
# Kuroshio meshes without ice-shelf cavities
self._add_tests(mesh_names=['Kuroshio12to60', 'Kuroshio8to60'])

self._add_tests(mesh_names=['FRISwISC01to60'])
self._add_tests(mesh_names=['FRISwISC02to60'])
self._add_tests(mesh_names=['FRISwISC04to60'])
self._add_tests(mesh_names=['FRISwISC08to60'])

# A test case for making E3SM support files from an existing mesh
self.add_test_case(FilesForE3SM(test_group=self))

Expand Down
12 changes: 12 additions & 0 deletions compass/ocean/tests/global_ocean/mesh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
from compass.ocean.mesh.remap_topography import RemapTopography
from compass.ocean.tests.global_ocean.mesh.arrm10to60 import ARRM10to60BaseMesh
from compass.ocean.tests.global_ocean.mesh.ec30to60 import EC30to60BaseMesh
from compass.ocean.tests.global_ocean.mesh.fris01to60 import FRIS01to60BaseMesh
from compass.ocean.tests.global_ocean.mesh.fris02to60 import FRIS02to60BaseMesh
from compass.ocean.tests.global_ocean.mesh.fris04to60 import FRIS04to60BaseMesh
from compass.ocean.tests.global_ocean.mesh.fris08to60 import FRIS08to60BaseMesh
from compass.ocean.tests.global_ocean.mesh.kuroshio import KuroshioBaseMesh
from compass.ocean.tests.global_ocean.mesh.qu import (
IcosMeshFromConfigStep,
Expand Down Expand Up @@ -96,6 +100,14 @@ def __init__(self, test_group, mesh_name, high_res_topography):
base_mesh_step = RRS6to18BaseMesh(self, name=name, subdir=subdir)
elif mesh_name in ['SO12to60', 'SOwISC12to60']:
base_mesh_step = SO12to60BaseMesh(self, name=name, subdir=subdir)
elif mesh_name in ['FRIS01to60', 'FRISwISC01to60']:
base_mesh_step = FRIS01to60BaseMesh(self, name=name, subdir=subdir)
elif mesh_name in ['FRIS02to60', 'FRISwISC02to60']:
base_mesh_step = FRIS02to60BaseMesh(self, name=name, subdir=subdir)
elif mesh_name in ['FRIS04to60', 'FRISwISC04to60']:
base_mesh_step = FRIS04to60BaseMesh(self, name=name, subdir=subdir)
elif mesh_name in ['FRIS08to60', 'FRISwISC08to60']:
base_mesh_step = FRIS08to60BaseMesh(self, name=name, subdir=subdir)
elif mesh_name.startswith('Kuroshio'):
base_mesh_step = KuroshioBaseMesh(self, name=name, subdir=subdir)
elif mesh_name in ['WC14', 'WCwISC14']:
Expand Down
6 changes: 3 additions & 3 deletions compass/ocean/tests/global_ocean/mesh/ec30to60/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import numpy as np
import mpas_tools.mesh.creation.mesh_definition_tools as mdt
import numpy as np

from compass.mesh import QuasiUniformSphericalMeshStep

Expand Down Expand Up @@ -28,8 +28,8 @@ def build_cell_width_lat_lon(self):

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

Expand Down
203 changes: 203 additions & 0 deletions compass/ocean/tests/global_ocean/mesh/fris01to60/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import mpas_tools.mesh.creation.mesh_definition_tools as mdt
import numpy as np
from geometric_features import read_feature_collection
from mpas_tools.cime.constants import constants
from mpas_tools.mesh.creation.signed_distance import (
signed_distance_from_geojson,
)

from compass.mesh import QuasiUniformSphericalMeshStep


class FRIS01to60BaseMesh(QuasiUniformSphericalMeshStep):
"""
A step for creating SO12to60 meshes
"""
def setup(self):
"""
Add some input files
"""

self.add_input_file(filename='atlantic.geojson',
package=self.__module__)

self.add_input_file(filename='high_res_region.geojson',
package=self.__module__)

self.add_input_file(filename='fris_v1_transition.geojson',
package=self.__module__)

self.add_input_file(filename='fris_v1_peninsula_12km_v2.geojson',
package=self.__module__)

self.add_input_file(
filename='fris_v1_peninsula_12km_transition.geojson',
package=self.__module__)

self.add_input_file(filename='fris_v1.geojson',
package=self.__module__)

super().setup()

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

# Add high res FRIS region transition
dx_min_fris = 1. # minimum resolution within the FRIS cavity

fc = read_feature_collection('fris_v1_transition.geojson')

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

# Equivalent to 600 km
trans_width = 600e3
trans_start = 0
dx_min = dx_min_fris

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

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

# Add 12 km sharp correction west of the peninsula
fc = read_feature_collection('fris_v1_peninsula_12km_v2.geojson')

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

# Equivalent to 10 km
trans_width = 10e3
trans_start = 0
dx_min = 12.

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

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

# Add 12 km transition correction west of the peninsula
fc = read_feature_collection(
'fris_v1_peninsula_12km_transition.geojson')

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

# Equivalent to 150 km
trans_width = 150e3
trans_start = 0
dx_min = 12.

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

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

# Add high res FRIS region inner
fc = read_feature_collection('fris_v1.geojson')

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

# Equivalent to 100 km (0 should be enough given the setup but to be
# safe)
trans_width = 100e3
trans_start = 0
dx_min = dx_min_fris

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

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

return cellWidth, lon, lat
97 changes: 97 additions & 0 deletions compass/ocean/tests/global_ocean/mesh/fris01to60/atlantic.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "Atlantic region",
"component": "ocean",
"object": "region",
"author": "Xylar Asay-Davis"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-97.3828125,
85.05112877979998
],
[
-102.3046875,
40.17887331434696
],
[
-102.3046875,
23.241346102386135
],
[
-93.1640625,
15.623036831528264
],
[
-85.78125,
13.581920900545844
],
[
-83.583984375,
9.535748998133627
],
[
-81.2109375,
8.059229627200192
],
[
-79.013671875,
9.795677582829743
],
[
-75.9375,
5.61598581915534
],
[
-77.6953125,
0
],
[
16.171875,
0
],
[
27.773437499999996,
26.745610382199022
],
[
37.96875,
32.24997445586331
],
[
39.7265625,
39.36827914916014
],
[
32.6953125,
53.9560855309879
],
[
37.6171875,
61.438767493682825
],
[
25.664062500000004,
68.26938680456564
],
[
24.609375,
85.05112877979998
],
[
-97.3828125,
85.05112877979998
]
]
]
}
}
]
}
Loading

0 comments on commit 1e1ac50

Please sign in to comment.