\n",
"## Click here for a description of the plot

\n",
"Sea surface temperature on average decreases with increasing latitude, so the tropics show temperatures of about $30°\\text{C}$. Along western coastlines, it is additionally decreased due to the upwelling of low-temperature water masses caused by Ekman pumping (see also previous Tutorial 4). Water masses in polar regions are below $0°\\text{C}$ as the salinity decreases the freezing point.\n",
"\n",
"*** \n",
"\n",
"

"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"# plot Sea Surface Salinity\n",
"fig, ax = plt.subplots(\n",
" subplot_kw={\"projection\": ccrs.PlateCarree()}, dpi=100\n",
") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n",
"p = subset_salt.plot(\n",
" cmap=cmo.cm.haline,\n",
" robust=True,\n",
" #vmin=30,\n",
" cbar_kwargs={\n",
" \"shrink\": 0.75,\n",
" \"orientation\": \"horizontal\",\n",
" \"extend\": \"both\",\n",
" \"pad\": 0.175,\n",
" \"label\": \"psu\",\n",
" },\n",
" ax=ax,\n",
")\n",
"ax.coastlines(color=\"grey\", lw=0.5)\n",
"ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n",
"ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n",
"lon_formatter = LongitudeFormatter(zero_direction_label=True)\n",
"lat_formatter = LatitudeFormatter()\n",
"ax.add_feature(cfeature.LAND, zorder=100, edgecolor=\"k\")\n",
"ax.set_title(\"Sea Surface Salinity (2014 – 2016 mean)\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"\n",
"## Click here for a description of the plot

\n",
"The mean sea surface salinity varies around the average of $35\\perthousand$ with high salinities in the subtropics, the regions of strongest evaporation and minimal precipitation. In contrast, less saline water masses can be found in the polar regions where the precipitation (and sea ice melting) induce a freshwater influx.\n",
"\n",
"*** \n",
"\n",
"

"
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"# Section 2: Calculating Density from Salinity & Temperature\n",
"The equation relating ocean water density to other water properties is called the ***equation of state***. It is a non-linear function of temperature, salinity, and pressure. This can be expressed as $\\rho=\\rho(T,S,p)$. Here we will show two ways to calculate the density.\n",
"\n",
"The first is a *linear approximation* to the equation of state. We will then show how to calculate the full, non-linear equation of state using the `gsw` package.\n",
"\n",
"Note that the [potential temperature](https://glossary.ametsoc.org/wiki/Potential_temperature) $\\theta$ is commonly used in oceanographic calculations, which is why our temperature file is called `surface_theta.nc` and the corresponding variable `THETA`. For the following linearization, we follow the probably more familiar $T$ convention and neglect their difference."
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"## Section 2.1: Linearized Equation of State\n",
"Here we take the linearized equation of state from equation 1.57 in Vallis' textbook [\"*Atmospheric and Oceanic Fluid Dynamics*\"](https://www.cambridge.org/core/books/atmospheric-and-oceanic-fluid-dynamics/41379BDDC4257CBE11143C466F6428A4)\n",
"\n",
"$$ \\rho=\\rho_0[1-\\beta_T(T-T_0)+\\beta_S(S-S_0)+\\beta_p(p-p_0)] $$\n",
"\n",
"In this equation, $\\rho_0\\simeq 1027$ is a reference density, $\\beta_T \\simeq 2*10^{-4} /\\text{K} $ is the thermal expansion coefficient, $\\beta_S \\simeq 7.6*10^{-4}/\\text{ppt}$ is the haline contraction coefficient, and $\\beta_p \\simeq 4.4*10^{-10}/\\text{Pa}$ is the compressibility coefficient. The values with subscript $_0$ are reference values, and here we use $T_0 = 283 \\text{K}$ and $S_0=35$. Since surface pressure rarely changes by more than a few percent, let's assume that the pressure at the surface is equal to the reference pressure at every point ($\\beta_p(p-p_0)=0$). *The non-linearities in the full equation of state (which we will use later) arise because, in reality, the $\\beta$ terms themselves vary with pressure, salinity, and temperature.*\n",
"\n",
"Let's now calculate a global map of surface density using this linear equation of state. Note that since we are using temperature and salinity *datasets*, our result will also be a dataset."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"rho_linear = 1027 * (\n",
" 1 - 2e-4 * (subset_theta + 273.15 - 283) + 7.6e-4 * (subset_salt - 35)\n",
")\n",
"rho_linear"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"# plot linearized density\n",
"fig, ax = plt.subplots(\n",
" subplot_kw={\"projection\": ccrs.PlateCarree()}, dpi=100\n",
") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n",
"p = rho_linear.plot(\n",
" cmap=cmo.cm.dense,\n",
" vmin=1021,\n",
" vmax=1029,\n",
" cbar_kwargs={\n",
" \"shrink\": 0.75,\n",
" \"orientation\": \"horizontal\",\n",
" \"extend\": \"both\",\n",
" \"pad\": 0.15,\n",
" \"label\": \"Density (kg/m$^3$)\",\n",
" },\n",
" ax=ax,\n",
")\n",
"ax.coastlines(color=\"grey\", lw=0.5)\n",
"ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n",
"ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n",
"lon_formatter = LongitudeFormatter(zero_direction_label=True)\n",
"lat_formatter = LatitudeFormatter()\n",
"ax.add_feature(cfeature.LAND, zorder=100, edgecolor=\"k\")\n",
"ax.set_title(\"Surface density from linear equation (2014 – 2016 mean)\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"## Section 2.2: Full Nonlinear Equation of State\n",
"The full, non-linear equation of state is more complicated than the linear equation we just used. It contains dozens of equations which are impractical to code in this tutorial. Fortunately packages exist to do this calculation!\n",
"\n",
"Here we will compute surface density from the full nonlinear equation in `python` using the `gsw` package which is a Python implementation of the [Thermodynamic Equation of Seawater 2010 (TEOS-10)](https://teos-10.github.io/GSW-Python/)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"CT = gsw.CT_from_pt(\n",
" subset_salt, subset_theta\n",
") # get conservative temperature from potential temperature\n",
"rho_nonlinear = gsw.rho(subset_salt, CT, 0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"# plot density from full nonlinear equation\n",
"fig, ax = plt.subplots(\n",
" subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n",
") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n",
"p = rho_nonlinear.plot(\n",
" cmap=cmo.cm.dense,\n",
" vmin=1021,\n",
" vmax=1029,\n",
" cbar_kwargs={\n",
" \"shrink\": 0.75,\n",
" \"orientation\": \"horizontal\",\n",
" \"extend\": \"both\",\n",
" \"pad\": 0.05,\n",
" \"label\": \"Density (kg/m$^3$)\",\n",
" },\n",
" ax=ax,\n",
")\n",
"ax.coastlines(color=\"grey\", lw=0.5)\n",
"ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n",
"ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n",
"lon_formatter = LongitudeFormatter(zero_direction_label=True)\n",
"lat_formatter = LatitudeFormatter()\n",
"ax.add_feature(cfeature.LAND, zorder=100, edgecolor=\"k\")\n",
"ax.set_title(\"Surface density from nonlinear equation (2014-2016 mean)\")\n",
"fig.tight_layout()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"# plot difference between linear and non-linear equations of state\n",
"fig, ax = plt.subplots(\n",
" subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n",
") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n",
"p = (rho_linear - rho_nonlinear).plot(\n",
" cmap=\"coolwarm\",\n",
" vmin=-3,\n",
" vmax=3,\n",
" cbar_kwargs={\n",
" \"shrink\": 0.75,\n",
" \"orientation\": \"horizontal\",\n",
" \"extend\": \"both\",\n",
" \"pad\": 0.05,\n",
" \"label\": \"Density difference (kg/m$^3$)\",\n",
" },\n",
" ax=ax,\n",
")\n",
"ax.coastlines(color=\"grey\", lw=0.5)\n",
"ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n",
"ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n",
"lon_formatter = LongitudeFormatter(zero_direction_label=True)\n",
"lat_formatter = LatitudeFormatter()\n",
"ax.add_feature(cfeature.LAND, zorder=100, edgecolor=\"k\")\n",
"ax.set_title(\"Linear minus non-linear equation of state (2014-2016 mean)\")\n",
"fig.tight_layout()"
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"Upon comparing the two equations of state, we observe that they are generally similar, but certain differences arise. These differences stem from the nonlinearity of the equation of state, where the haline contraction coefficient and thermal expansion coefficient are not constant as assumed in our linear equation of state.\n",
"\n",
"Irrespective of the method used to calculate density, we notice the presence of horizontal density variations (gradients) at the ocean surface. For instance, seawater tends to be less dense in the subtropics and denser near the poles. These density differences play a crucial role in driving ocean currents, as we discussed in the slides.\n",
"\n",
"These findings emphasize the significant density gradients in the ocean, which shape oceanic circulation patterns. The nonlinearity in the equation of state contributes to these density variations, which in turn also influences the movement of water masses and the formation of currents."
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"### Questions 2.2\n",
"\n",
"1. Considering the nonlinear equation of state and TEOS-10, how do changes in ocean salinity and temperature uniquely impact the haline contraction and thermal expansion coefficients, thereby affecting density and ocean currents?\n",
"2. One place that deep convection, a critical component of thermohaline circulation occurs, is in the North Atlantic Ocean to the south of Greenland. Based on the density maps you made, does it make sense that this would be an ideal location for a deepwater mass to form?"
]
},
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"execution": {}
},
"source": [
"[*Click for solution*](https://github.com/neuromatch/climate-course-content/tree/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/solutions/W1D2_Tutorial5_Solution_0e98a4a4.py)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"# Summary\n",
"\n",
"In this tutorial, you explored sea surface salinity and temperature data from 2014 to 2016, and how those contribute to surface density patterns through the equation of state. You also compared the linear and non-linear equation of state and analyzed their differences."
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"# Resources\n",
"\n",
"Data for this tutorial can be accessed [here](https://www.ecco-group.org/)."
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"include_colab_link": true,
"name": "W1D2_Tutorial5",
"provenance": [],
"toc_visible": true
},
"kernel": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.19"
}
},
"nbformat": 4,
"nbformat_minor": 4
}