Skip to content

Commit a3a34ee

Browse files
committed
Add omega support to barotropic gyre
1 parent 3e15afd commit a3a34ee

File tree

5 files changed

+115
-44
lines changed

5 files changed

+115
-44
lines changed

polaris/tasks/ocean/barotropic_gyre/analysis.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import matplotlib.pyplot as plt
55
import mosaic
66
import numpy as np
7-
import xarray as xr
87
from matplotlib import colors as mcolors
98
from mpas_tools.ocean import compute_barotropic_streamfunction
109

@@ -50,9 +49,9 @@ def __init__(
5049

5150
def run(self):
5251
logger = self.logger
53-
ds_mesh = xr.open_dataset('mesh.nc')
54-
ds_init = xr.open_dataset('init.nc')
55-
ds = xr.open_dataset('output.nc')
52+
ds_mesh = self.open_model_dataset('mesh.nc')
53+
ds_init = self.open_model_dataset('init.nc')
54+
ds = self.open_model_dataset('output.nc')
5655

5756
field_mpas = compute_barotropic_streamfunction(
5857
ds_init.isel(Time=0), ds, prefix='', time_index=-1
@@ -84,7 +83,6 @@ def run(self):
8483

8584
use_mplstyle()
8685
pad = 20
87-
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(12, 2))
8886
x0 = ds_mesh.xEdge.min().values
8987
y0 = ds_mesh.yEdge.min().values
9088

@@ -94,6 +92,8 @@ def run(self):
9492
# convert to km
9593
descriptor.vertex_patches *= 1.0e-3
9694

95+
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(12, 2))
96+
9797
eta0 = max(
9898
np.max(np.abs(field_exact.values)),
9999
np.max(np.abs(field_mpas.values)),

polaris/tasks/ocean/barotropic_gyre/barotropic_gyre.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
[barotropic_gyre]
22

3+
# time integrator
4+
time_integrator = RK4
5+
36
# distance in kilometers between cell centers
47
resolution = 10
58

polaris/tasks/ocean/barotropic_gyre/forward.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ def __init__(
9393
self.add_yaml_file('polaris.ocean.config', 'output.yaml')
9494

9595
self.add_input_file(filename='init.nc', target='../init/init.nc')
96-
self.add_input_file(filename='forcing.nc', target='../init/forcing.nc')
9796

9897
self.add_output_file(
9998
filename='output.nc',
@@ -195,32 +194,58 @@ def dynamic_model_config(self, at_setup):
195194
f'maximum value is {nu_max} or decrease the time step'
196195
)
197196

197+
model = config.get('ocean', 'model')
198198
options = {'config_dt': dt_str, 'config_density0': rho_0}
199199
self.add_model_config_options(
200200
options=options, config_model='mpas-ocean'
201201
)
202202

203203
if self.run_time_steps is not None:
204+
output_interval_units = 'Seconds'
204205
run_duration = ceil(self.run_time_steps * dt)
205206
stop_time_str = time.strftime(
206207
'0001-01-01_%H:%M:%S', time.gmtime(run_duration)
207208
)
208-
output_interval_str = time.strftime(
209-
'0000_%H:%M:%S', time.gmtime(run_duration)
210-
)
209+
if model == 'omega':
210+
output_interval_str = str(run_duration)
211+
else:
212+
output_interval_str = get_time_interval_string(
213+
seconds=run_duration
214+
)
211215
else:
216+
output_interval = 1
217+
output_interval_units = 'Months'
212218
run_duration = config.getfloat('barotropic_gyre', 'run_duration')
213219
stop_time_str = time.strftime(
214220
f'{run_duration + 1.0:04g}-01-01_00:00:00'
215221
)
216-
output_interval_str = time.strftime('0000-01-00_00:00:00')
222+
if model == 'omega':
223+
output_interval_str = str(output_interval)
224+
else:
225+
output_interval_str = get_time_interval_string(
226+
days=output_interval * 30.0
227+
)
217228

218229
slip_factor_dict = {'no-slip': 0.0, 'free-slip': 1.0}
230+
time_integrator = config.get('barotropic_gyre', 'time_integrator')
231+
time_integrator_map = dict([('RK4', 'RungeKutta4')])
232+
if model == 'omega':
233+
if time_integrator in time_integrator_map.keys():
234+
time_integrator = time_integrator_map[time_integrator]
235+
else:
236+
print(
237+
'Warning: mapping from time integrator '
238+
f'{time_integrator} to omega not found, '
239+
'retaining name given in config'
240+
)
241+
219242
replacements = dict(
220243
dt=dt_str,
221244
dt_btr=dt_btr_str,
222245
stop_time=stop_time_str,
223246
output_interval=output_interval_str,
247+
output_interval_units=output_interval_units,
248+
time_integrator=time_integrator,
224249
nu=f'{nu:02g}',
225250
slip_factor=f'{slip_factor_dict[self.boundary_condition]:02g}',
226251
)
@@ -232,6 +257,16 @@ def dynamic_model_config(self, at_setup):
232257
template_replacements=replacements,
233258
)
234259

260+
def setup(self):
261+
"""
262+
TEMP: symlink initial condition to name hard-coded in Omega
263+
"""
264+
super().setup()
265+
model = self.config.get('ocean', 'model')
266+
# TODO: remove as soon as Omega no longer hard-codes this file
267+
if model == 'omega':
268+
self.add_input_file(filename='OmegaMesh.nc', target='init.nc')
269+
235270
def compute_max_time_step(self, config):
236271
"""
237272
Compute the approximate maximum time step for stability

polaris/tasks/ocean/barotropic_gyre/forward.yaml

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,39 @@ ocean:
44
config_run_duration: none
55
time_integration:
66
config_dt: {{ dt }}
7-
config_time_integrator: split_explicit_ab2
7+
config_time_integrator: {{ time_integrator }}
88
hmix_del2:
99
config_use_mom_del2: true
1010
config_mom_del2: {{ nu }}
11+
hmix_del4:
12+
config_use_mom_del4: false
13+
forcing:
14+
config_use_bulk_wind_stress: true
15+
debug:
16+
config_disable_vel_explicit_bottom_drag: true
17+
18+
mpas-ocean:
19+
run_modes:
20+
config_ocean_run_mode: forward
21+
decomposition:
22+
config_block_decomp_file_prefix: graph.info.part.
23+
advection:
24+
config_thickness_flux_type: constant
25+
lateral_walls:
26+
config_wall_slip_factor: {{ slip_factor }}
27+
debug:
28+
config_disable_thick_vadv: true
29+
config_disable_vel_hadv: true
30+
config_disable_vel_hmix: false
31+
config_disable_tr_all_tend: true
32+
1133
streams:
1234
mesh:
1335
filename_template: init.nc
1436
input:
1537
filename_template: init.nc
1638
forcing:
17-
filename_template: forcing.nc
39+
filename_template: init.nc
1840
input_interval: initial_only
1941
type: input
2042
contents:
@@ -33,24 +55,39 @@ ocean:
3355
- ssh
3456
- relativeVorticity
3557

36-
mpas-ocean:
37-
advection:
38-
config_thickness_flux_type: constant
39-
bottom_drag:
40-
config_implicit_constant_bottom_drag_coeff: 0.
41-
forcing:
42-
config_use_bulk_wind_stress: true
43-
lateral_walls:
44-
config_wall_slip_factor: {{ slip_factor }}
45-
debug:
46-
config_disable_thick_vadv: true
47-
config_disable_vel_hadv: true
48-
config_disable_vel_hmix: false
49-
config_disable_tr_all_tend: true
50-
5158
Omega:
5259
Tendencies:
53-
VelDiffTendencyEnable: true
54-
VelHyperDiffTendencyEnable: false
60+
TracerHorzAdvTendencyEnable : false
61+
TracerDiffTendencyEnable : false
62+
TracerHyperDiffTendencyEnable : false
63+
Advection:
64+
FluxThicknessType: Center
5565
Dimension:
5666
NVertLevels: 1
67+
IOStreams:
68+
InitialState:
69+
UsePointerFile: false
70+
Filename: init.nc
71+
Mode: read
72+
Precision: double
73+
Freq: 1
74+
FreqUnits: OnStartup
75+
UseStartEnd: false
76+
Contents:
77+
- State
78+
- WindStressZonal
79+
- WindStressMeridional
80+
History:
81+
UsePointerFile: false
82+
Filename: output.nc
83+
Mode: write
84+
IfExists: append
85+
Precision: double
86+
Freq: {{ output_interval }}
87+
FreqUnits: {{ output_interval_units }}
88+
UseStartEnd: false
89+
Contents:
90+
- State
91+
- SshCell
92+
FileFreq: 9999
93+
FileFreqUnits: years

polaris/tasks/ocean/barotropic_gyre/init.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import numpy as np
22
import xarray as xr
3-
from mpas_tools.io import write_netcdf
43
from mpas_tools.mesh.conversion import convert, cull
54
from mpas_tools.planar_hex import make_planar_hex_mesh
65

7-
from polaris import Step
86
from polaris.mesh.planar import compute_planar_hex_nx_ny
7+
from polaris.ocean.model import OceanIOStep
98
from polaris.ocean.vertical import init_vertical_coord
109
from polaris.viz import plot_horiz_field
1110

1211

13-
class Init(Step):
12+
class Init(OceanIOStep):
1413
"""
1514
A step for creating a mesh and initial condition for baroclinic channel
1615
tasks
@@ -43,7 +42,6 @@ def __init__(
4342
'base_mesh.nc',
4443
'culled_mesh.nc',
4544
'culled_graph.info',
46-
'forcing.nc',
4745
]:
4846
self.add_output_file(file)
4947
self.name = name
@@ -72,13 +70,13 @@ def run(self):
7270
ds_mesh = make_planar_hex_mesh(
7371
nx=nx, ny=ny, dc=dc, nonperiodic_x=True, nonperiodic_y=True
7472
)
75-
write_netcdf(ds_mesh, 'base_mesh.nc')
73+
self.write_model_dataset(ds_mesh, 'base_mesh.nc')
7674

7775
ds_mesh = cull(ds_mesh, logger=logger)
7876
ds_mesh = convert(
7977
ds_mesh, graphInfoFileName='culled_graph.info', logger=logger
8078
)
81-
write_netcdf(ds_mesh, 'culled_mesh.nc')
79+
self.write_model_dataset(ds_mesh, 'culled_mesh.nc')
8280

8381
# vertical coordinate parameters
8482
bottom_depth = config.getfloat('vertical_grid', 'bottom_depth')
@@ -116,30 +114,28 @@ def run(self):
116114
normal_velocity = normal_velocity.expand_dims(dim='Time', axis=0)
117115
ds['normalVelocity'] = normal_velocity
118116

119-
# write the initial condition file
120-
write_netcdf(ds, 'init.nc')
121-
122117
# set the wind stress forcing
123-
ds_forcing = xr.Dataset()
124118
# Convert from km to m
125119
ly = ly * 1e3
126120
wind_stress_zonal = -tau_0 * np.cos(
127121
np.pi * (ds.yCell - ds.yCell.min()) / ly
128122
)
129123
wind_stress_meridional = xr.zeros_like(ds.xCell)
130-
ds_forcing['windStressZonal'] = wind_stress_zonal.expand_dims(
124+
ds['windStressZonal'] = wind_stress_zonal.expand_dims(
131125
dim='Time', axis=0
132126
)
133-
ds_forcing['windStressMeridional'] = (
134-
wind_stress_meridional.expand_dims(dim='Time', axis=0)
127+
ds['windStressMeridional'] = wind_stress_meridional.expand_dims(
128+
dim='Time', axis=0
135129
)
136-
write_netcdf(ds_forcing, 'forcing.nc')
130+
131+
# write the initial condition file
132+
self.write_model_dataset(ds, 'init.nc')
137133

138134
cell_mask = ds.maxLevelCell >= 1
139135

140136
plot_horiz_field(
141137
ds_mesh,
142-
ds_forcing['windStressZonal'],
138+
ds['windStressZonal'],
143139
'forcing_wind_stress_zonal.png',
144140
cmap='cmo.balance',
145141
show_patch_edges=True,

0 commit comments

Comments
 (0)