Skip to content

Commit 5d8535f

Browse files
authored
Merge pull request #20 from ECCO-GROUP/vol_bud_comments
improved text of vol budget closure
2 parents 7746c36 + 74c8e10 commit 5d8535f

2 files changed

Lines changed: 35 additions & 23 deletions

File tree

Tutorials_as_Jupyter_Notebooks/ECCO_v4_Volume_budget_closure.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@
12781278
"cell_type": "markdown",
12791279
"metadata": {},
12801280
"source": [
1281-
"These values are all essentially zero (at the noise level). On average the only vertical flux divergence in the column is across the ocean surface, because the column integrated vertical flux divergences below the surface is in the noise. This may be related to the $z^*$ coordinate system. When water is added or removed from he column, $\\eta$ changes and the depth levels of top and bottom 'w' faces of the grid cells are scaled up or down via the $s*$ factor. Because grid cells change thickness via $s*$ no vertical flux divergence is required. Thus, the fact that the vertical flux divergences are zero may be an artifact of the $z*$ coordinate system. If you, dear reader, have a better explanation, please share."
1281+
"These values are everywhere essentially zero (numerical noise). On average, the only vertical flux divergence in the column is across the ocean surface. Below the surface, the sum of vertical flux divergence in all tracer cells in the column must be zero because any divergence in any one particular cell is exactly offset by convergence in another cell. Net convergence into the column manifests as a positive vertical velocity at the surface which is equal to oceFWflux in the time-mean. **Thanks to Hong Zhang for comments that improved this explanation**"
12821282
]
12831283
},
12841284
{
@@ -2001,7 +2001,7 @@
20012001
"name": "python",
20022002
"nbconvert_exporter": "python",
20032003
"pygments_lexer": "ipython3",
2004-
"version": "3.7.3"
2004+
"version": "3.7.8"
20052005
}
20062006
},
20072007
"nbformat": 4,

Tutorials_as_Python_Files/ECCO_v4_Volume_budget_closure.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#
1717
# ECCOv4 uses the $z^*$ coordinate system in which the depth of the vertical coordinate, $z^*$ varies with time as:
1818
#
19-
# $$ z^* = \frac{z - \eta(x,y,t)}{H(x,y) + \eta(x,y,t)} H(x,y)$$
19+
# \begin{equation}
20+
# z^* = \frac{z - \eta(x,y,t)}{H(x,y) + \eta(x,y,t)} H(x,y)
21+
# \end{equation}
2022
#
2123
# With $H$ being the model depth, $\eta$ being the model sea level anomaly, and $z$ being depth.
2224
#
@@ -45,15 +47,15 @@
4547
#
4648
# To make budget calculations easier we provide the scaled velocities quantities ``UVELMASS`` and ``VVELMASS``,
4749
#
48-
# \begin{equation}
50+
# \begin{align}
4951
# \mathit{UVELMASS}(x,y,k) = \mathit{UVEL}(x,y,k) \times \mathit{hFacW}(x,y,k) \times s^{*}(x,y,k,t)
50-
# \end{equation}
52+
# \end{align}
5153
# and
52-
# \begin{equation}
54+
# \begin{align}
5355
# \mathit{VVELMASS}(x,y,k) = \mathit{VVEL}(x,y,k) \times \mathit{hFacS}(x,y,k) \times s^{*}(x,y,k,t)
54-
# \end{equation}
56+
# \end{align}
5557
#
56-
# > **Note:** The word **mass** in ``UVELMASS`` and ``VVELMASS`` is confusing since there is no mass involved here. Think of these terms as simply being ``UVEL`` and ``VVEL`` multiplied by the scaled grid cell area fraction.
58+
# It is worth noting that the word **mass** in ``UVELMASS`` and ``VVELMASS`` is confusing since there is no mass involved here. Think of these terms as simply being ``UVEL`` and ``VVEL`` multiplied by the fraction of the grid cell height that is open grid cell face across which the volume transport occurs. Partial cell bathymetry can make this fraction (hFacW, hFacS) less than one, and the $s^*$ scaling factor further adjusts this fraction higher or lower through time.
5759
#
5860
# Fully closing the budget requires the vertical volume fluxes across the top and bottom 'w' faces of the grid cell and surface freshwater fluxes. Regarding vertical volume fluxes, there are no $s^*$ or ``hFac`` equivalent scaling factors that modify our top and bottom grid cell areas. Therefore, vertical volume fluxes through 'w' faces are simply:
5961
#
@@ -71,7 +73,7 @@
7173
#
7274
# Greatbatch, 1994. J. of Geophys. Res. Oceans, https://doi.org/10.1029/94JC00847
7375

74-
# # Evaluating the model sea level anomaly ``ETAN`` volume budget
76+
# ## Evaluating the model sea level anomaly ``ETAN`` volume budget
7577

7678
# We will evalute
7779
#
@@ -101,7 +103,7 @@
101103
#
102104
# The ``UVELMASS, VVELMASS, WVELMASS`` and ``oceFWflx`` terms must be time-average quantities between the monthly $\eta$ snapshots.
103105
#
104-
# ## Prepare environment and loading the relevant model variables
106+
# ### Prepare environment and loading the relevant model variables
105107

106108
# In[1]:
107109

@@ -117,15 +119,16 @@
117119
warnings.filterwarnings('ignore')
118120

119121

120-
# In[2]:
122+
# In[62]:
121123

122124

123125
# Density kg/m^3
124126
rhoconst = 1029
125127

126128
## needed to convert surface mass fluxes to volume fluxes
127129

128-
# lat/lon resolution in degrees to interpolate the model fields for the purposes of plotting
130+
# lat/lon resolution in degrees to interpolate the model
131+
# fields for the purposes of plotting
129132
map_dx = .2
130133
map_dy = .2
131134

@@ -180,7 +183,7 @@
180183

181184

182185
# load one extra year worth of snapshots
183-
ecco_monthly_snaps = ecco.recursive_load_ecco_var_from_years_nc(data_dir, vars_to_load=['ETAN'], years_to_load=range(year_start, year_end+1)).load()
186+
ecco_monthly_snaps = ecco.recursive_load_ecco_var_from_years_nc(data_dir, vars_to_load=['ETAN'], years_to_load=range(year_start, year_end+1)).load()
184187

185188
num_months = len(ecco_monthly_snaps.time.values)
186189
# drop the last 11 months so that we have one snapshot at the beginning and end of each month within the
@@ -200,7 +203,8 @@
200203

201204

202205
# find the record of the last ETAN snapshot
203-
last_record_date = ecco.extract_yyyy_mm_dd_hh_mm_ss_from_datetime64(ecco_monthly_snaps.time[-1].values)
206+
last_record_date =
207+
ecco.extract_yyyy_mm_dd_hh_mm_ss_from_datetime64(ecco_monthly_snaps.time[-1].values)
204208
print(last_record_date)
205209
last_record_year = last_record_date[0]
206210

@@ -236,7 +240,7 @@
236240
print('number of monthly snapshot records: ', len(ecco_monthly_snaps.time))
237241

238242

239-
# ## Create the xgcm 'grid' object
243+
# ### Create the xgcm 'grid' object
240244
#
241245
# the xgcm grid object makes it easy to make flux divergence calculations across different tiles of the lat-lon-cap grid.
242246

@@ -415,6 +419,7 @@
415419
cmin=-1, cmax=1, \
416420
cmap=cmocean.cm.balance, user_lon_0=-67,\
417421
dx=map_dx,dy=map_dy);
422+
418423
plt.title('Actual $\Delta \eta$ [m]', fontsize=20);
419424

420425

@@ -440,6 +445,7 @@
440445
tmp = ecco.extract_yyyy_mm_dd_hh_mm_ss_from_datetime64(G_total_tendency.time[100].values)
441446
print(tmp)
442447
ecco.plot_proj_to_latlon_grid(ecco_grid.XC, ecco_grid.YC, G_total_tendency.isel(time=100), show_colorbar=True, cmin=-1e-7, cmax=1e-7, cmap=cmocean.cm.balance, user_lon_0=-67, dx=map_dx,dy=map_dy);
448+
443449
plt.title('$\partial \eta / \partial t$ [m/s] during ' +
444450
str(tmp[0]) +'/' + str(tmp[1]), fontsize=20);
445451

@@ -621,7 +627,7 @@
621627
fontsize=20);
622628

623629

624-
# These values are all essentially zero (at the noise level). On average the only vertical flux divergence in the column is across the ocean surface, because the column integrated vertical flux divergences below the surface is in the noise. This may be related to the $z^*$ coordinate system. When water is added or removed from he column, $\eta$ changes and the depth levels of top and bottom 'w' faces of the grid cells are scaled up or down via the $s*$ factor. Because grid cells change thickness via $s*$ no vertical flux divergence is required. Thus, the fact that the vertical flux divergences are zero may be an artifact of the $z*$ coordinate system. If you, dear reader, have a better explanation, please share.
630+
# These values are everywhere essentially zero (numerical noise). On average, the only vertical flux divergence in the column is across the ocean surface. Below the surface, the sum of vertical flux divergence in all tracer cells in the column must be zero because any divergence in any one particular cell is exactly offset by convergence in another cell. Net convergence into the column manifests as a positive vertical velocity at the surface which is equal to oceFWflux in the time-mean. **Thanks to Hong Zhang for comments that improved this explanation**
625631

626632
# ### Horizontal Volume Flux Divergence
627633

@@ -858,7 +864,8 @@
858864
plt.grid()
859865

860866
plt.subplots_adjust(hspace = .5, wspace=.2)
861-
plt.suptitle('Volume Budget for one Arctic Ocean point',fontsize=20);
867+
plt.suptitle('Volume Budget for one Arctic Ocean point',
868+
fontsize=20);
862869

863870

864871
# Indeed, the volume divergence term does contribute to $\eta$ variations at this one point.
@@ -875,7 +882,7 @@
875882
plt.title('d(eta)/d(t) from surf. fluxes in 1995 [m/s]');
876883

877884

878-
# # Predicted vs. actual $\eta$
885+
# ## Predicted vs. actual $\eta$
879886
#
880887
# As we have shown, in our Boussinesq model the only term that can change global mean model sea level anomaly $\eta$ is net surface freshwater flux. Let us compare the time-evolution of $\eta$ implied by surface freshwater fluxes and the actual $\eta$ from the model output.
881888
#
@@ -887,11 +894,14 @@
887894

888895
area_masked = ecco_grid.rA.where(ecco_grid.maskC.isel(k=0) == 1)
889896

890-
dETA_per_month_predicted_from_surf_fluxes = ((G_surf_fluxes * area_masked).sum(dim=('i','j','tile'))/area_masked.sum())*secs_per_month
897+
dETA_per_month_predicted_from_surf_fluxes = ((G_surf_fluxes * area_masked).sum(dim=('i','j','tile')) /
898+
area_masked.sum())*secs_per_month
891899

892900
ETA_predicted_by_surf_fluxes = np.cumsum(dETA_per_month_predicted_from_surf_fluxes.values)
893901

894-
ETA_from_ETAN = (ecco_monthly_snaps.ETAN * area_masked).sum(dim=('i','j','tile'))/ area_masked.sum()
902+
ETA_from_ETAN =
903+
(ecco_monthly_snaps.ETAN * area_masked).sum(dim=('i','j','tile')) /
904+
area_masked.sum()
895905

896906
# plotting
897907
plt.figure(figsize=(14,5));
@@ -901,10 +911,11 @@
901911
plt.grid()
902912
plt.ylabel('global mean $\eta$');
903913
plt.legend(('predicted', 'actual'));
904-
plt.title('$\eta(t)$ as predicted from net surface fluxes and model ETAN [m]', fontsize=20);
914+
plt.title('$\eta(t)$ as predicted from net surface fluxes and model ETAN [m]',
915+
fontsize=20);
905916

906917

907-
# > **Note:** the first predicted $\eta$ occurs at the end of the first month (one month time integral of $\partial \eta / \partial t$. The first *actual* $\eta$ is set to be zero.
918+
# The first predicted $\eta$ occurs at the end of the first month (one month time integral of $\partial \eta / \partial t$. The first *actual* $\eta$ is set to be zero.
908919
#
909920
# The above plot is another way of confirming that in our Boussinesq model the only term that can change global mean model sea level anomaly $\eta$ is net surface freshwater flux. To account for changes in global mean density we must apply the Greatbatch correction, inverse-barometer correction, and a correction term to account for the fact that sea-ice does not 'float' on top of the ocean but in fact displaces seawater upwards. All of these corrections are made for the term ``SSH``, dynamic sea surface height anomaly (not shown here).
910921

@@ -933,7 +944,8 @@
933944
# the -0.13 is to make the starting value comparable with WCRP fig 16.
934945
plt.bar(annual_mean_GMSL_due_to_mass_fluxes.year.values[12:num_years], 1000*(annual_mean_GMSL_due_to_mass_fluxes.values[12:num_years]-.017), color='k')
935946
plt.grid()
936-
plt.xticks(np.arange(2005, annual_mean_GMSL_due_to_mass_fluxes.year.values[-1]+1,step=1));
947+
plt.xticks(np.arange(2005,
948+
annual_mean_GMSL_due_to_mass_fluxes.year.values[-1]+1,step=1));
937949
plt.title('Sea level (mm) caused by mass fluxes');
938950

939951

0 commit comments

Comments
 (0)