Skip to content

Commit ae42772

Browse files
committed
Add polynomial functions for Arctic ICs
1 parent df641fe commit ae42772

File tree

2 files changed

+140
-45
lines changed

2 files changed

+140
-45
lines changed

compass/ocean/tests/turbulence_closure/initial_state.py

Lines changed: 118 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import xarray
2-
import numpy
1+
import xarray as xr
2+
import numpy as np
3+
import matplotlib.pyplot as plt
34

45
from compass.ocean.tests.turbulence_closure.boundary_values import add_boundary_arrays
56
from random import random, seed
@@ -57,13 +58,27 @@ def run(self):
5758
y_nonperiodic = section.getboolean('y_nonperiodic')
5859
disturbance_amplitude = section.getfloat('disturbance_amplitude')
5960
surface_temperature = section.getfloat('surface_temperature')
61+
interior_temperature_shape = section.get('interior_temperature_shape')
62+
interior_salinity_shape = section.get('interior_salinity_shape')
6063
surface_salinity = section.getfloat('surface_salinity')
6164
mixed_layer_salinity_gradient = section.getfloat('mixed_layer_salinity_gradient')
6265
mixed_layer_temperature_gradient = section.getfloat('mixed_layer_temperature_gradient')
6366
mixed_layer_depth_salinity = section.getfloat('mixed_layer_depth_salinity')
6467
mixed_layer_depth_temperature = section.getfloat('mixed_layer_depth_temperature')
6568
interior_salinity_gradient = section.getfloat('interior_salinity_gradient')
6669
interior_temperature_gradient = section.getfloat('interior_temperature_gradient')
70+
interior_temperature_c0 = section.getfloat('interior_temperature_c0')
71+
interior_temperature_c1 = section.getfloat('interior_temperature_c1')
72+
interior_temperature_c2 = section.getfloat('interior_temperature_c2')
73+
interior_temperature_c3 = section.getfloat('interior_temperature_c3')
74+
interior_temperature_c4 = section.getfloat('interior_temperature_c4')
75+
interior_temperature_c5 = section.getfloat('interior_temperature_c4')
76+
interior_salinity_c0 = section.getfloat('interior_salinity_c0')
77+
interior_salinity_c1 = section.getfloat('interior_salinity_c1')
78+
interior_salinity_c2 = section.getfloat('interior_salinity_c2')
79+
interior_salinity_c3 = section.getfloat('interior_salinity_c3')
80+
interior_salinity_c4 = section.getfloat('interior_salinity_c4')
81+
interior_salinity_c5 = section.getfloat('interior_salinity_c4')
6782
surface_heat_flux = section.getfloat('surface_heat_flux')
6883
surface_freshwater_flux = section.getfloat('surface_freshwater_flux')
6984
wind_stress_zonal = section.getfloat('wind_stress_zonal')
@@ -86,64 +101,122 @@ def run(self):
86101
xCell = ds.xCell
87102
yCell = ds.yCell
88103

89-
ds['bottomDepth'] = bottom_depth * xarray.ones_like(xCell)
90-
ds['ssh'] = xarray.zeros_like(xCell)
104+
ds['bottomDepth'] = bottom_depth * xr.ones_like(xCell)
105+
ds['ssh'] = xr.zeros_like(xCell)
91106

92107
init_vertical_coord(config, ds)
93108

94-
dsForcing['windStressZonal'] = wind_stress_zonal * xarray.ones_like(xCell)
95-
dsForcing['windStressMeridional'] = wind_stress_meridional * xarray.ones_like(xCell)
96-
dsForcing['sensibleHeatFlux'] = surface_heat_flux * xarray.ones_like(xCell)
97-
dsForcing['rainFlux'] = surface_freshwater_flux * xarray.ones_like(xCell)
109+
dsForcing['windStressZonal'] = wind_stress_zonal * xr.ones_like(xCell)
110+
dsForcing['windStressMeridional'] = wind_stress_meridional * xr.ones_like(xCell)
111+
dsForcing['sensibleHeatFlux'] = surface_heat_flux * xr.ones_like(xCell)
112+
dsForcing['rainFlux'] = surface_freshwater_flux * xr.ones_like(xCell)
98113

99114
write_netcdf(dsForcing, 'init_mode_forcing_data.nc')
100115

101-
normalVelocity = xarray.zeros_like(ds.xEdge)
102-
normalVelocity, _ = xarray.broadcast(normalVelocity, ds.refBottomDepth)
116+
normalVelocity = xr.zeros_like(ds.xEdge)
117+
normalVelocity, _ = xr.broadcast(normalVelocity, ds.refBottomDepth)
103118
normalVelocity = normalVelocity.transpose('nEdges', 'nVertLevels')
104119

105-
temperature = xarray.zeros_like(ds.layerThickness)
106-
107-
salinity = xarray.zeros_like(ds.layerThickness)
108-
109-
surf_indices = numpy.where(ds.refZMid.values >= -mixed_layer_depth_temperature)[0]
110-
111-
if len(surf_indices) > 0:
112-
temperature[0,:,surf_indices] = surface_temperature + mixed_layer_temperature_gradient* \
113-
ds.zMid[0,:,surf_indices].values
114-
115-
int_indices = numpy.where(ds.refZMid.values < -mixed_layer_depth_temperature)[0]
116-
117-
if len(int_indices) > 0:
118-
temperature[0,:,int_indices] = surface_temperature - mixed_layer_temperature_gradient* \
119-
mixed_layer_depth_temperature + interior_temperature_gradient* \
120-
(ds.zMid[0,:,int_indices] + \
121-
mixed_layer_depth_temperature)
122-
123-
temperature[0,:,0] += disturbance_amplitude*2*(numpy.random.rand(len(ds.xCell.values)) - 0.5)
124-
125-
surf_indices = numpy.where(ds.refZMid.values >= -mixed_layer_depth_salinity)[0]
126-
if len(surf_indices) > 0:
127-
salinity[0,:,surf_indices] = surface_salinity - mixed_layer_salinity_gradient * \
128-
ds.zMid[0,:,surf_indices]
129-
130-
int_indices = numpy.where(ds.refZMid.values < -mixed_layer_depth_salinity)[0]
131-
if len(int_indices) > 0:
132-
salinity[0,:,int_indices] = surface_salinity - mixed_layer_salinity_gradient* \
133-
mixed_layer_depth_salinity + interior_salinity_gradient* \
134-
(ds.zMid[0,:,int_indices] + \
135-
mixed_layer_depth_salinity)
120+
temperature = xr.zeros_like(ds.layerThickness)
121+
122+
salinity = xr.zeros_like(ds.layerThickness)
123+
124+
zMid = ds.refZMid.values
125+
126+
temperature_at_mld = (surface_temperature -
127+
mixed_layer_temperature_gradient * mixed_layer_depth_temperature)
128+
if interior_temperature_shape == 'linear':
129+
initial_temperature = np.where(
130+
zMid >= -mixed_layer_depth_temperature,
131+
surface_temperature + mixed_layer_temperature_gradient * zMid,
132+
temperature_at_mld + interior_temperature_gradient * zMid)
133+
elif interior_temperature_shape == 'polynomial':
134+
initial_temperature = np.where(
135+
zMid >= -mixed_layer_depth_temperature,
136+
surface_temperature + mixed_layer_temperature_gradient * zMid,
137+
interior_temperature_c0 +
138+
interior_temperature_c1 * zMid +
139+
interior_temperature_c2 * zMid**2. +
140+
interior_temperature_c3 * zMid**3. +
141+
interior_temperature_c4 * zMid**4. +
142+
interior_temperature_c5 * zMid**5.)
143+
else:
144+
print('interior_temperature_shape is not supported')
145+
146+
salinity_at_mld = (surface_salinity -
147+
mixed_layer_salinity_gradient * mixed_layer_depth_salinity)
148+
if interior_salinity_shape == 'linear':
149+
initial_salinity = np.where(
150+
zMid >= -mixed_layer_depth_salinity,
151+
surface_salinity + mixed_layer_salinity_gradient * zMid,
152+
salinity_at_mld + interior_salinity_gradient * zMid)
153+
elif interior_salinity_shape == 'polynomial':
154+
initial_salinity = np.where(
155+
zMid >= -mixed_layer_depth_salinity,
156+
surface_salinity + mixed_layer_salinity_gradient * zMid,
157+
interior_salinity_c0 +
158+
interior_salinity_c1 * zMid +
159+
interior_salinity_c2 * zMid**2. +
160+
interior_salinity_c3 * zMid**3. +
161+
interior_salinity_c4 * zMid**4. +
162+
interior_salinity_c5 * zMid**5.)
163+
else:
164+
print('interior_salinity_shape is not supported')
165+
# surf_indices = np.where(ds.refZMid.values >= -mixed_layer_depth_temperature)[0]
166+
#
167+
# if len(surf_indices) > 0:
168+
# temperature[0,:,surf_indices] = surface_temperature + mixed_layer_temperature_gradient* \
169+
# ds.zMid[0,:,surf_indices].values
170+
#
171+
# int_indices = np.where(ds.refZMid.values < -mixed_layer_depth_temperature)[0]
172+
#
173+
# if len(int_indices) > 0:
174+
# temperature[0,:,int_indices] = surface_temperature - mixed_layer_temperature_gradient* \
175+
# mixed_layer_depth_temperature + interior_temperature_gradient* \
176+
# (ds.zMid[0,:,int_indices] + \
177+
# mixed_layer_depth_temperature)
178+
#
179+
# temperature[0,:,0] += disturbance_amplitude*2*(np.random.rand(len(ds.xCell.values)) - 0.5)
180+
#
181+
# surf_indices = np.where(ds.refZMid.values >= -mixed_layer_depth_salinity)[0]
182+
# if len(surf_indices) > 0:
183+
# salinity[0,:,surf_indices] = surface_salinity - mixed_layer_salinity_gradient * \
184+
# ds.zMid[0,:,surf_indices]
185+
#
186+
# int_indices = np.where(ds.refZMid.values < -mixed_layer_depth_salinity)[0]
187+
# if len(int_indices) > 0:
188+
# salinity[0,:,int_indices] = surface_salinity - mixed_layer_salinity_gradient* \
189+
# mixed_layer_depth_salinity + interior_salinity_gradient* \
190+
# (ds.zMid[0,:,int_indices] + \
191+
# mixed_layer_depth_salinity)
136192

137193
normalVelocity = normalVelocity.expand_dims(dim='Time', axis=0)
138-
139194
ds['normalVelocity'] = normalVelocity
195+
196+
temperature[0, :, :] = initial_temperature
197+
salinity[0, :, :] = initial_salinity
140198
ds['temperature'] = temperature
141199
ds['salinity'] = salinity
142-
ds['fCell'] = coriolis_parameter * xarray.ones_like(xCell)
143-
ds['fEdge'] = coriolis_parameter * xarray.ones_like(ds.xEdge)
144-
ds['fVertex'] = coriolis_parameter * xarray.ones_like(ds.xVertex)
200+
ds['fCell'] = coriolis_parameter * xr.ones_like(xCell)
201+
ds['fEdge'] = coriolis_parameter * xr.ones_like(ds.xEdge)
202+
ds['fVertex'] = coriolis_parameter * xr.ones_like(ds.xVertex)
145203

146204
ds = add_boundary_arrays(ds, x_nonperiodic, y_nonperiodic)
147205

148206
write_netcdf(ds, 'ocean.nc')
149207

208+
plt.figure(dpi=100)
209+
plt.plot(initial_temperature, zMid, 'k-')
210+
plt.xlabel('PT (C)')
211+
plt.ylabel('z (m)')
212+
plt.savefig(f'pt_depth_t0h.png',
213+
bbox_inches='tight', dpi=200)
214+
plt.close()
215+
216+
plt.figure(dpi=100)
217+
plt.plot(initial_salinity, zMid, 'k-')
218+
plt.xlabel('SA (g/kg)')
219+
plt.ylabel('z (m)')
220+
plt.savefig(f'sa_depth_t0h.png',
221+
bbox_inches='tight', dpi=200)
222+
plt.close()

compass/ocean/tests/turbulence_closure/turbulence_closure.cfg

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,34 @@ mixed_layer_temperature_gradient = 0
4040
# Salinity gradient in the mixed layer (PSU/m)
4141
mixed_layer_salinity_gradient = 0
4242

43+
# Interior temperature shape, linear or polynomial
44+
interior_temperature_shape = linear
45+
4346
# Temperature gradient in the interior (^oC/m)
4447
interior_temperature_gradient = 0.1
4548

49+
# Temperature polynomial coefficients
50+
interior_temperature_c0 = 271.65
51+
interior_temperature_c1 = -0.42
52+
interior_temperature_c2 = -8.0e-3
53+
interior_temperature_c3 = -6.75e-5
54+
interior_temperature_c4 = -2.66e-7
55+
interior_temperature_c5 = -4.02e-10
56+
57+
# Interior salinity shape, linear or polynomial
58+
interior_salinity_shape = linear
59+
4660
# Salinity gradient in the interior (PSU/m)
4761
interior_salinity_gradient = 0
4862

63+
# Salinity polynomial coefficients
64+
interior_salinity_c0 = 22.36
65+
interior_salinity_c1 = -0.3
66+
interior_salinity_c2 = -3.83e-3
67+
interior_salinity_c3 = -2.54e-5
68+
interior_salinity_c4 = -8.53e-8
69+
interior_salinity_c5 = -1.18e-10
70+
4971
# Disturbance amplitude (added to initiate convection faster; ^oC)
5072
disturbance_amplitude = 0.005
5173

0 commit comments

Comments
 (0)