CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-seawater

Python implementation of the CSIRO seawater toolbox for calculating properties of sea water using EOS-80 equation of state

Pending
Overview
Eval results
Files

geostrophic.mddocs/

Geostrophic Functions

Ocean circulation and dynamic oceanography calculations for analyzing geostrophic currents, ocean stability, and potential vorticity. These functions are essential for understanding ocean dynamics and circulation patterns.

Capabilities

Brünt-Väisälä Frequency

Ocean stability analysis through buoyancy frequency calculations.

def bfrq(s, t, p, lat=None):
    """
    Brünt-Väisälä frequency squared and potential vorticity.
    
    Calculates the buoyancy frequency (also known as the Brünt-Väisälä frequency)
    which indicates ocean stability and stratification strength.
    
    Parameters:
    - s: array_like, salinity profile [psu (PSS-78)]
    - t: array_like, temperature profile [°C (ITS-90)]
    - p: array_like, pressure profile [db]
    - lat: array_like, latitude [decimal degrees], optional
    
    Returns:
    - tuple: (n2, q, p_ave)
        - n2: array_like, Brünt-Väisälä frequency squared [rad²/s²]
        - q: array_like, potential vorticity [(m·s)⁻¹]
        - p_ave: array_like, mid-point pressures [db]
    """

Specific Volume Anomaly

Specific volume calculations for geostrophic velocity analysis.

def svan(s, t, p=0):
    """
    Specific volume anomaly of seawater.
    
    Calculates the specific volume anomaly which is used in geostrophic
    velocity calculations and dynamic height computations.
    
    Parameters:
    - s: array_like, salinity [psu (PSS-78)]
    - t: array_like, temperature [°C (ITS-90)]
    - p: array_like, pressure [db], default 0
    
    Returns:
    - array_like: specific volume anomaly [m³/kg]
    """

Geopotential Anomaly

Geopotential calculations for dynamic oceanography.

def gpan(s, t, p):
    """
    Geopotential anomaly of seawater.
    
    Calculates geopotential anomaly which represents the work done against
    gravity in lifting a unit mass from a reference level.
    
    Parameters:
    - s: array_like, salinity [psu (PSS-78)]
    - t: array_like, temperature [°C (ITS-90)]
    - p: array_like, pressure [db]
    
    Returns:
    - array_like: geopotential anomaly [m²/s²]
    """

Geostrophic Velocity

Geostrophic current calculations from geopotential gradients.

def gvel(ga, lat, lon):
    """
    Geostrophic velocity from geopotential anomaly gradients.
    
    Calculates geostrophic velocities from horizontal gradients of
    geopotential anomaly, accounting for Earth's rotation (Coriolis effect).
    
    Parameters:
    - ga: array_like, geopotential anomaly [m²/s²]
    - lat: array_like, latitude [decimal degrees]
    - lon: array_like, longitude [decimal degrees]
    
    Returns:
    - array_like: geostrophic velocity [m/s]
    """

Usage Examples

Ocean Stability Analysis

import seawater as sw
import numpy as np
import matplotlib.pyplot as plt

# Create a stratified ocean profile
pressure = np.arange(0, 1000, 10)  # 0 to 1000 db
# Typical thermocline structure
temperature = 20 * np.exp(-pressure/200) + 2
salinity = 34.5 + 0.5 * (pressure/1000)
latitude = 30.0  # degrees N

# Calculate Brünt-Väisälä frequency
n2, q, p_mid = sw.bfrq(salinity, temperature, pressure, latitude)

# Convert to buoyancy frequency in cycles per hour
n_cph = np.sqrt(np.maximum(n2, 0)) * 3600 / (2 * np.pi)

# Plot stratification
plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
plt.plot(temperature, pressure, 'b-', label='Temperature')
plt.plot(salinity, pressure, 'r-', label='Salinity')
plt.gca().invert_yaxis()
plt.xlabel('Temperature (°C) / Salinity (psu)')
plt.ylabel('Pressure (db)')
plt.legend()
plt.title('Ocean Profile')

plt.subplot(1, 2, 2)
plt.plot(n_cph, p_mid, 'g-', linewidth=2)
plt.gca().invert_yaxis()
plt.xlabel('Buoyancy Frequency (cph)')
plt.ylabel('Pressure (db)')
plt.title('Ocean Stability')
plt.grid(True)

plt.tight_layout()
plt.show()

Geostrophic Current Calculation

import seawater as sw
import numpy as np

# Create two ocean stations for geostrophic calculation
pressure = np.arange(0, 500, 25)  # pressure levels

# Station 1 (warmer, less saline)
s1 = np.full_like(pressure, 34.8) - 0.001 * pressure
t1 = 15.0 * np.exp(-pressure/150) + 4

# Station 2 (cooler, more saline)  
s2 = np.full_like(pressure, 35.0) - 0.0005 * pressure
t2 = 12.0 * np.exp(-pressure/180) + 3

# Calculate geopotential anomaly at each station
gpa1 = sw.gpan(s1, t1, pressure)
gpa2 = sw.gpan(s2, t2, pressure)

# Calculate geopotential difference (proxy for geostrophic velocity)
dgpa = gpa2 - gpa1
print("Geopotential anomaly difference:")
for i in range(0, len(pressure), 4):
    print(f"P: {pressure[i]:3.0f} db, Δφ: {dgpa[i]:8.3f} m²/s²")

# Calculate specific volume anomaly
sva1 = sw.svan(s1, t1, pressure)
sva2 = sw.svan(s2, t2, pressure)

print(f"\\nSpecific volume anomaly range:")
print(f"Station 1: {sva1.min():.2e} to {sva1.max():.2e} m³/kg")
print(f"Station 2: {sva2.min():.2e} to {sva2.max():.2e} m³/kg")

Dynamic Height Analysis

import seawater as sw
import numpy as np

# Typical subtropical ocean profile
depth = np.arange(0, 2000, 50)
lat = 25.0  # degrees N

# Convert depth to pressure
pressure = sw.pres(depth, lat)

# Create realistic T-S profile
temperature = 22 * np.exp(-depth/300) + 2.5
salinity = 36.0 - 1.0 * np.exp(-depth/500)

# Calculate dynamic properties
n2, q, p_mid = sw.bfrq(salinity, temperature, pressure, lat)
sva = sw.svan(salinity, temperature, pressure)
gpa = sw.gpan(salinity, temperature, pressure)

# Calculate dynamic height (integrated specific volume anomaly)
# This is a simplified calculation - proper dynamic height requires
# integration between pressure levels
dyn_height = np.cumsum(sva * np.gradient(pressure)) / 10  # convert to dynamic meters

print("Dynamic oceanography summary:")
print(f"Maximum N²: {np.max(n2):.2e} rad²/s²")
print(f"Surface specific volume anomaly: {sva[0]:.2e} m³/kg")
print(f"Deep specific volume anomaly: {sva[-1]:.2e} m³/kg")
print(f"Total dynamic height: {dyn_height[-1]:.3f} dynamic meters")

# Find thermocline depth (maximum stratification)
max_strat_idx = np.argmax(n2)
thermocline_depth = depth[max_strat_idx//2]  # approximate due to mid-point pressures
print(f"Thermocline depth: {thermocline_depth:.0f} m")

Install with Tessl CLI

npx tessl i tessl/pypi-seawater

docs

auxiliary.md

core-eos80.md

geostrophic.md

index.md

support.md

tile.json