0
# Auxiliary Functions
1
2
Additional oceanographic calculations including geographic distance computations, gas solubilities, Coriolis effects, and wave velocities. These functions complement the core EOS-80 calculations for comprehensive marine environment analysis.
3
4
## Capabilities
5
6
### Geographic Distance and Navigation
7
8
Distance and bearing calculations on Earth's surface using great circle methods.
9
10
```python { .api }
11
def dist(lat, lon, units="km"):
12
"""
13
Distance between geographic positions and phase angle.
14
15
Calculates great circle distance and initial bearing between
16
geographic coordinates using spherical Earth approximation.
17
18
Parameters:
19
- lat: array_like, latitude coordinates [decimal degrees]
20
- lon: array_like, longitude coordinates [decimal degrees]
21
- units: str, distance units ("km" or "nm"), default "km"
22
23
Returns:
24
- tuple: (distance, phase_angle)
25
- distance: array_like, great circle distance [km or nm]
26
- phase_angle: array_like, initial bearing [degrees]
27
"""
28
```
29
30
### Coriolis Effect
31
32
Earth rotation effects on ocean and atmospheric motion.
33
34
```python { .api }
35
def f(lat):
36
"""
37
Coriolis parameter (Coriolis frequency).
38
39
Calculates the Coriolis parameter which represents the component
40
of Earth's rotation affecting horizontal motion at given latitude.
41
42
Parameters:
43
- lat: array_like, latitude [decimal degrees]
44
45
Returns:
46
- array_like: Coriolis parameter [s⁻¹]
47
"""
48
```
49
50
### Gas Solubilities
51
52
Solubility of atmospheric gases in seawater.
53
54
```python { .api }
55
def satO2(s, t):
56
"""
57
Oxygen solubility in seawater.
58
59
Calculates equilibrium dissolved oxygen concentration in seawater
60
at atmospheric pressure using Weiss (1970) equations.
61
62
Parameters:
63
- s: array_like, salinity [psu (PSS-78)]
64
- t: array_like, temperature [°C (ITS-90)]
65
66
Returns:
67
- array_like: oxygen solubility [ml/l]
68
"""
69
70
def satN2(s, t):
71
"""
72
Nitrogen solubility in seawater.
73
74
Calculates equilibrium dissolved nitrogen concentration in seawater
75
at atmospheric pressure.
76
77
Parameters:
78
- s: array_like, salinity [psu (PSS-78)]
79
- t: array_like, temperature [°C (ITS-90)]
80
81
Returns:
82
- array_like: nitrogen solubility [ml/l]
83
"""
84
85
def satAr(s, t):
86
"""
87
Argon solubility in seawater.
88
89
Calculates equilibrium dissolved argon concentration in seawater
90
at atmospheric pressure.
91
92
Parameters:
93
- s: array_like, salinity [psu (PSS-78)]
94
- t: array_like, temperature [°C (ITS-90)]
95
96
Returns:
97
- array_like: argon solubility [ml/l]
98
"""
99
```
100
101
### Surface Wave Velocity
102
103
Surface wave propagation calculations.
104
105
```python { .api }
106
def swvel(length, depth):
107
"""
108
Surface wave velocity using shallow/deep water approximations.
109
110
Calculates phase velocity of surface gravity waves based on
111
wavelength and water depth using linear wave theory.
112
113
Parameters:
114
- length: array_like, wavelength [m]
115
- depth: array_like, water depth [m]
116
117
Returns:
118
- array_like: wave phase velocity [m/s]
119
"""
120
```
121
122
## Usage Examples
123
124
### Geographic Distance Calculations
125
126
```python
127
import seawater as sw
128
import numpy as np
129
130
# Define oceanographic station positions
131
# Station coordinates (lat, lon in decimal degrees)
132
stations = {
133
'A': (35.0, -75.0), # Off Cape Hatteras
134
'B': (40.0, -70.0), # Georges Bank
135
'C': (45.0, -65.0), # Nova Scotia shelf
136
}
137
138
# Calculate distances between all station pairs
139
station_names = list(stations.keys())
140
coords = list(stations.values())
141
142
print("Distance matrix between stations:")
143
print(" ", end="")
144
for name in station_names:
145
print(f"{name:>8}", end="")
146
print()
147
148
for i, (name1, (lat1, lon1)) in enumerate(stations.items()):
149
print(f"{name1:>4} ", end="")
150
for j, (name2, (lat2, lon2)) in enumerate(stations.items()):
151
if i <= j:
152
# Calculate distance
153
lats = np.array([lat1, lat2])
154
lons = np.array([lon1, lon2])
155
distance, bearing = sw.dist(lats, lons, units="km")
156
157
if i == j:
158
print(f"{'0':>8}", end="")
159
else:
160
print(f"{distance[1]:.0f}km", end="")
161
else:
162
print(f"{'':>8}", end="")
163
print()
164
165
# Calculate bearing from Station A to Station B
166
lat_ab = np.array([35.0, 40.0])
167
lon_ab = np.array([-75.0, -70.0])
168
dist_ab, bearing_ab = sw.dist(lat_ab, lon_ab)
169
print(f"\\nA→B: {dist_ab[1]:.1f} km at bearing {bearing_ab[1]:.1f}°")
170
```
171
172
### Coriolis Parameter Analysis
173
174
```python
175
import seawater as sw
176
import numpy as np
177
import matplotlib.pyplot as plt
178
179
# Calculate Coriolis parameter across latitudes
180
latitudes = np.linspace(-90, 90, 181)
181
coriolis = sw.f(latitudes)
182
183
# Key oceanographic latitudes
184
key_lats = [-60, -30, 0, 30, 60] # Southern Ocean, Subtropics, Equator, etc.
185
key_f = sw.f(key_lats)
186
187
print("Coriolis parameter at key latitudes:")
188
lat_names = ["60°S", "30°S", "Equator", "30°N", "60°N"]
189
for name, lat, f_val in zip(lat_names, key_lats, key_f):
190
print(f"{name:>8}: f = {f_val:.2e} s⁻¹")
191
192
# Rossby radius calculation example (first baroclinic mode)
193
# Typical values for mid-latitude ocean
194
N = 5e-3 # Brünt-Väisälä frequency [rad/s]
195
H = 1000 # depth scale [m]
196
f_30N = sw.f(30) # Coriolis at 30°N
197
198
rossby_radius = N * H / abs(f_30N) / 1000 # convert to km
199
print(f"\\nTypical Rossby radius at 30°N: {rossby_radius:.0f} km")
200
201
# Plot Coriolis parameter
202
plt.figure(figsize=(10, 6))
203
plt.plot(latitudes, coriolis * 1e4, 'b-', linewidth=2)
204
plt.axhline(0, color='k', linestyle='--', alpha=0.5)
205
plt.xlabel('Latitude (°)')
206
plt.ylabel('Coriolis Parameter (×10⁻⁴ s⁻¹)')
207
plt.title('Coriolis Parameter vs Latitude')
208
plt.grid(True, alpha=0.3)
209
plt.xlim(-90, 90)
210
211
# Mark key latitudes
212
for lat, f_val, name in zip(key_lats, key_f, lat_names):
213
plt.plot(lat, f_val * 1e4, 'ro', markersize=8)
214
plt.annotate(name, (lat, f_val * 1e4), xytext=(5, 5),
215
textcoords='offset points', fontsize=9)
216
217
plt.tight_layout()
218
plt.show()
219
```
220
221
### Gas Solubility Analysis
222
223
```python
224
import seawater as sw
225
import numpy as np
226
import matplotlib.pyplot as plt
227
228
# Temperature and salinity ranges for gas solubility analysis
229
temperatures = np.linspace(0, 30, 31) # 0-30°C
230
salinities = [0, 20, 35] # Fresh, brackish, seawater
231
232
plt.figure(figsize=(15, 5))
233
234
# Plot oxygen solubility
235
plt.subplot(1, 3, 1)
236
for s in salinities:
237
o2_sol = sw.satO2(s, temperatures)
238
plt.plot(temperatures, o2_sol, label=f'S = {s} psu', linewidth=2)
239
plt.xlabel('Temperature (°C)')
240
plt.ylabel('O₂ Solubility (ml/l)')
241
plt.title('Oxygen Solubility')
242
plt.legend()
243
plt.grid(True, alpha=0.3)
244
245
# Plot nitrogen solubility
246
plt.subplot(1, 3, 2)
247
for s in salinities:
248
n2_sol = sw.satN2(s, temperatures)
249
plt.plot(temperatures, n2_sol, label=f'S = {s} psu', linewidth=2)
250
plt.xlabel('Temperature (°C)')
251
plt.ylabel('N₂ Solubility (ml/l)')
252
plt.title('Nitrogen Solubility')
253
plt.legend()
254
plt.grid(True, alpha=0.3)
255
256
# Plot argon solubility
257
plt.subplot(1, 3, 3)
258
for s in salinities:
259
ar_sol = sw.satAr(s, temperatures)
260
plt.plot(temperatures, ar_sol, label=f'S = {s} psu', linewidth=2)
261
plt.xlabel('Temperature (°C)')
262
plt.ylabel('Ar Solubility (ml/l)')
263
plt.title('Argon Solubility')
264
plt.legend()
265
plt.grid(True, alpha=0.3)
266
267
plt.tight_layout()
268
plt.show()
269
270
# Calculate gas ratios at standard conditions
271
std_temp, std_sal = 20.0, 35.0 # Standard seawater conditions
272
o2_std = sw.satO2(std_sal, std_temp)
273
n2_std = sw.satN2(std_sal, std_temp)
274
ar_std = sw.satAr(std_sal, std_temp)
275
276
print(f"Gas solubilities at {std_temp}°C, {std_sal} psu:")
277
print(f"O₂: {o2_std:.2f} ml/l")
278
print(f"N₂: {n2_std:.2f} ml/l")
279
print(f"Ar: {ar_std:.3f} ml/l")
280
print(f"N₂/Ar ratio: {n2_std/ar_std:.1f}")
281
```
282
283
### Surface Wave Analysis
284
285
```python
286
import seawater as sw
287
import numpy as np
288
import matplotlib.pyplot as plt
289
290
# Wave analysis for different water depths and wavelengths
291
wavelengths = np.logspace(0, 3, 100) # 1 m to 1000 m
292
depths = [5, 20, 100, 1000] # Shallow to deep water
293
294
plt.figure(figsize=(12, 8))
295
296
# Plot wave velocity vs wavelength for different depths
297
plt.subplot(2, 2, 1)
298
for depth in depths:
299
velocities = sw.swvel(wavelengths, depth)
300
plt.loglog(wavelengths, velocities, label=f'h = {depth} m', linewidth=2)
301
302
# Add deep water limit (c = sqrt(g*L/(2*pi)))
303
g = 9.81
304
c_deep = np.sqrt(g * wavelengths / (2 * np.pi))
305
plt.loglog(wavelengths, c_deep, 'k--', label='Deep water limit', alpha=0.7)
306
307
plt.xlabel('Wavelength (m)')
308
plt.ylabel('Phase Velocity (m/s)')
309
plt.title('Wave Velocity vs Wavelength')
310
plt.legend()
311
plt.grid(True, alpha=0.3)
312
313
# Plot wave velocity vs depth for fixed wavelengths
314
plt.subplot(2, 2, 2)
315
depths_fine = np.logspace(0, 3, 100) # 1 m to 1000 m depth
316
wave_lengths = [10, 50, 200] # Different wavelengths
317
318
for wl in wave_lengths:
319
velocities = sw.swvel(wl, depths_fine)
320
plt.semilogx(depths_fine, velocities, label=f'λ = {wl} m', linewidth=2)
321
322
plt.xlabel('Water Depth (m)')
323
plt.ylabel('Phase Velocity (m/s)')
324
plt.title('Wave Velocity vs Water Depth')
325
plt.legend()
326
plt.grid(True, alpha=0.3)
327
328
# Calculate wave parameters for typical wind waves
329
plt.subplot(2, 2, 3)
330
periods = np.linspace(5, 20, 16) # Wave periods 5-20 seconds
331
g = 9.81
332
333
# Deep water wavelength: L = g*T²/(2π)
334
deep_wavelengths = g * periods**2 / (2 * np.pi)
335
deep_velocities = g * periods / (2 * np.pi)
336
337
plt.plot(periods, deep_wavelengths, 'b-', linewidth=2, label='Wavelength')
338
plt.plot(periods, deep_velocities, 'r-', linewidth=2, label='Phase velocity')
339
plt.xlabel('Wave Period (s)')
340
plt.ylabel('Wavelength (m) / Velocity (m/s)')
341
plt.title('Deep Water Wave Characteristics')
342
plt.legend()
343
plt.grid(True, alpha=0.3)
344
345
# Calculate relative depth parameter (kh = 2πh/L)
346
plt.subplot(2, 2, 4)
347
h_values = [10, 50, 200] # Water depths
348
for h in h_values:
349
kh = 2 * np.pi * h / deep_wavelengths
350
plt.plot(periods, kh, label=f'h = {h} m', linewidth=2)
351
352
plt.axhline(np.pi, color='k', linestyle='--', alpha=0.7, label='Deep water (kh > π)')
353
plt.axhline(np.pi/10, color='k', linestyle=':', alpha=0.7, label='Shallow water (kh < π/10)')
354
plt.xlabel('Wave Period (s)')
355
plt.ylabel('Relative Depth (kh)')
356
plt.title('Wave Dispersion Parameter')
357
plt.legend()
358
plt.grid(True, alpha=0.3)
359
360
plt.tight_layout()
361
plt.show()
362
363
# Example: Tsunami wave speed calculation
364
print("\\nTsunami wave analysis:")
365
tsunami_wavelength = 200000 # 200 km typical tsunami wavelength
366
ocean_depths = [1000, 3000, 5000] # Typical ocean depths
367
368
for depth in ocean_depths:
369
tsunami_speed = sw.swvel(tsunami_wavelength, depth)
370
print(f"Depth {depth:4d} m: Tsunami speed = {tsunami_speed:.0f} m/s ({tsunami_speed*3.6:.0f} km/h)")
371
```