Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/marine-biology/ocean_productivity.tex
51 views
unlisted
1
% Ocean Productivity Analysis Template
2
% Topics: Photosynthesis-irradiance curves, nutrient limitation, NPP, seasonal blooms
3
% Style: Marine ecology research report with computational modeling
4
5
\documentclass[a4paper, 11pt]{article}
6
\usepackage[utf8]{inputenc}
7
\usepackage[T1]{fontenc}
8
\usepackage{amsmath, amssymb}
9
\usepackage{graphicx}
10
\usepackage{siunitx}
11
\usepackage{booktabs}
12
\usepackage{subcaption}
13
\usepackage[makestderr]{pythontex}
14
15
% Theorem environments
16
\newtheorem{definition}{Definition}[section]
17
\newtheorem{theorem}{Theorem}[section]
18
\newtheorem{example}{Example}[section]
19
\newtheorem{remark}{Remark}[section]
20
21
\title{Ocean Productivity: Photosynthesis-Irradiance Relationships and Nutrient-Limited Primary Production}
22
\author{Marine Ecology Research Group}
23
\date{\today}
24
25
\begin{document}
26
\maketitle
27
28
\begin{abstract}
29
This report presents a comprehensive computational analysis of ocean primary productivity,
30
focusing on photosynthesis-irradiance (P-I) relationships, nutrient limitation dynamics,
31
and seasonal phytoplankton bloom patterns. We examine the classic P-I curve parameterization
32
(Jassby \& Platt 1976), Michaelis-Menten nutrient uptake kinetics, depth-integrated net
33
primary production (NPP), and the interplay between mixed layer dynamics and euphotic zone
34
structure. Computational simulations demonstrate seasonal cycles in temperate ocean regions,
35
quantifying spring bloom magnitude, summer nutrient depletion, and annual carbon export.
36
\end{abstract}
37
38
\section{Introduction}
39
40
Ocean primary productivity drives global carbon cycling and supports marine food webs.
41
Phytoplankton photosynthesis converts dissolved inorganic carbon into organic matter, with
42
rates controlled by light availability, nutrient concentrations, and physical mixing. Understanding
43
these rate-limiting factors is essential for predicting ocean biogeochemical responses to climate change.
44
45
\begin{definition}[Net Primary Production]
46
Net primary production (NPP) represents the rate of organic carbon synthesis by phytoplankton
47
after subtracting autotrophic respiration. It is typically expressed in units of g C m$^{-2}$ yr$^{-1}$
48
for depth-integrated water column values or mg C m$^{-3}$ d$^{-1}$ for volumetric rates.
49
\end{definition}
50
51
\section{Theoretical Framework}
52
53
\subsection{Photosynthesis-Irradiance Relationships}
54
55
The response of phytoplankton photosynthesis to light intensity follows a characteristic hyperbolic
56
curve at low irradiances (light-limited) with photoinhibition at high irradiances.
57
58
\begin{definition}[P-I Curve Parameters]
59
The photosynthesis-irradiance relationship is characterized by:
60
\begin{itemize}
61
\item $P_{max}$: Maximum photosynthetic rate (mg C mg Chl$^{-1}$ h$^{-1}$)
62
\item $\alpha$: Initial slope of P-I curve, photosynthetic efficiency (mg C mg Chl$^{-1}$ h$^{-1}$ ($\mu$mol photons m$^{-2}$ s$^{-1}$)$^{-1}$)
63
\item $\beta$: Photoinhibition parameter (same units as $\alpha$)
64
\item $I_k = P_{max}/\alpha$: Light saturation parameter
65
\end{itemize}
66
\end{definition}
67
68
\begin{theorem}[Platt-Gallegos-Harrison P-I Model]
69
The photosynthetic rate $P$ as a function of photosynthetically active radiation (PAR) $I$ is:
70
\begin{equation}
71
P(I) = P_{max} \left(1 - \exp\left(-\frac{\alpha I}{P_{max}}\right)\right) \exp\left(-\frac{\beta I}{P_{max}}\right)
72
\end{equation}
73
This formulation captures light limitation at low $I$, saturation at intermediate $I$, and
74
photoinhibition at high $I$.
75
\end{theorem}
76
77
\subsection{Nutrient Limitation}
78
79
Phytoplankton growth rates are often limited by dissolved nutrients, particularly nitrogen (N),
80
phosphorus (P), and silicon (Si for diatoms).
81
82
\begin{definition}[Michaelis-Menten Nutrient Uptake]
83
The specific nutrient uptake rate $V$ follows saturation kinetics:
84
\begin{equation}
85
V([N]) = \frac{V_{max}[N]}{K_s + [N]}
86
\end{equation}
87
where $V_{max}$ is the maximum uptake rate, $[N]$ is the nutrient concentration, and $K_s$
88
is the half-saturation constant representing the concentration at which $V = V_{max}/2$.
89
\end{definition}
90
91
Typical $K_s$ values for marine phytoplankton range from 0.1--5 $\mu$M for nitrate,
92
0.01--0.3 $\mu$M for ammonium, and 0.01--0.1 $\mu$M for phosphate.
93
94
\subsection{Vertical Structure and Light Attenuation}
95
96
Light intensity decreases exponentially with depth according to the Beer-Lambert law:
97
\begin{equation}
98
I(z) = I_0 \exp(-K_d z)
99
\end{equation}
100
where $I_0$ is surface PAR, $z$ is depth (positive downward), and $K_d$ is the diffuse
101
attenuation coefficient. The euphotic zone depth $z_{eu}$ is defined as the depth where
102
$I = 0.01 \cdot I_0$ (1\% light level):
103
\begin{equation}
104
z_{eu} = \frac{4.605}{K_d}
105
\end{equation}
106
107
\begin{remark}[Mixed Layer Dynamics]
108
The mixed layer depth (MLD) controls the light history experienced by phytoplankton. Deep
109
winter mixing (MLD $>$ $z_{eu}$) suppresses productivity, while shallow summer stratification
110
(MLD $<$ $z_{eu}$) creates favorable light conditions but can lead to nutrient depletion.
111
\end{remark}
112
113
\subsection{Depth-Integrated Production}
114
115
Total water column NPP integrates volumetric production from surface to euphotic zone depth:
116
\begin{equation}
117
\text{NPP}_{total} = \int_0^{z_{eu}} P(z) \cdot \text{Chl}(z) \, dz
118
\end{equation}
119
where Chl$(z)$ is the chlorophyll-a concentration profile.
120
121
\section{Computational Analysis}
122
123
We now implement computational models of ocean productivity dynamics, simulating P-I curves,
124
nutrient-limited growth, seasonal bloom cycles, and depth-integrated production for a temperate
125
ocean ecosystem representative of the North Atlantic.
126
127
\begin{pycode}
128
import numpy as np
129
import matplotlib.pyplot as plt
130
from scipy.optimize import curve_fit
131
from scipy.integrate import trapz, odeint
132
133
np.random.seed(42)
134
135
# P-I curve parameters (typical phytoplankton)
136
P_max = 8.0 # mg C (mg Chl)^-1 h^-1
137
alpha = 0.05 # mg C (mg Chl)^-1 h^-1 (umol photons m^-2 s^-1)^-1
138
beta = 0.002 # photoinhibition parameter
139
I_k = P_max / alpha # light saturation parameter
140
141
# Nutrient uptake parameters
142
V_max = 0.8 # d^-1, maximum specific growth rate
143
K_s_N = 1.0 # uM, half-saturation for nitrate
144
K_s_P = 0.05 # uM, half-saturation for phosphate
145
146
# Light attenuation
147
K_d = 0.08 # m^-1, diffuse attenuation coefficient
148
I_0_summer = 2000 # umol photons m^-2 s^-1, summer noon surface PAR
149
I_0_winter = 400 # umol photons m^-2 s^-1, winter noon surface PAR
150
151
# Calculate euphotic zone depth
152
z_eu = 4.605 / K_d
153
154
# Mixed layer depth seasonal variation
155
def mixed_layer_depth(day):
156
"""MLD as function of day of year (simple sinusoidal)"""
157
return 100 - 80 * np.cos(2 * np.pi * day / 365)
158
159
# Surface PAR seasonal variation
160
def surface_PAR(day):
161
"""Surface PAR as function of day of year"""
162
return I_0_winter + (I_0_summer - I_0_winter) * (0.5 + 0.5 * np.cos(2 * np.pi * (day - 172) / 365))
163
164
def PI_curve(I, P_max, alpha, beta):
165
"""Platt-Gallegos-Harrison P-I model"""
166
return P_max * (1 - np.exp(-alpha * I / P_max)) * np.exp(-beta * I / P_max)
167
168
def nutrient_uptake(N, V_max, K_s):
169
"""Michaelis-Menten nutrient uptake"""
170
return V_max * N / (K_s + N)
171
172
def light_depth(z, I_0, K_d):
173
"""Light at depth z"""
174
return I_0 * np.exp(-K_d * z)
175
176
# Create PAR range for P-I curve
177
PAR = np.linspace(0, 2500, 500)
178
photosynthesis = PI_curve(PAR, P_max, alpha, beta)
179
180
# Identify key points
181
I_opt = (1/beta) * np.log((alpha + beta) / beta) # optimal irradiance
182
P_opt = PI_curve(I_opt, P_max, alpha, beta) # production at I_opt
183
184
\end{pycode}
185
186
The photosynthesis-irradiance curve represents the fundamental light response of phytoplankton.
187
At low light, photosynthesis increases linearly with irradiance (slope $\alpha$), reflecting
188
efficient light harvesting. As irradiance increases, photosynthesis approaches saturation at
189
$P_{max}$. At very high irradiance, photoinhibition reduces photosynthetic rates due to damage
190
to photosystem II reaction centers. This produces the characteristic asymmetric curve observed
191
in incubation experiments.
192
193
\begin{pycode}
194
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
195
196
# Plot 1: P-I curve
197
ax1.plot(PAR, photosynthesis, 'b-', linewidth=2.5, label='P-I curve')
198
ax1.axhline(y=P_max, color='red', linestyle='--', linewidth=1.5, alpha=0.7,
199
label=f'$P_{{max}}$ = {P_max:.1f}')
200
ax1.axvline(x=I_k, color='green', linestyle='--', linewidth=1.5, alpha=0.7,
201
label=f'$I_k$ = {I_k:.0f}')
202
ax1.scatter([I_opt], [P_opt], s=120, c='orange', marker='*', edgecolor='black',
203
zorder=5, label=f'$I_{{opt}}$ = {I_opt:.0f}')
204
205
# Add initial slope line
206
PAR_slope = np.linspace(0, 400, 2)
207
ax1.plot(PAR_slope, alpha * PAR_slope, 'g--', linewidth=1.5, alpha=0.6,
208
label=f'Initial slope $\\alpha$ = {alpha:.3f}')
209
210
ax1.set_xlabel('PAR (\\textmu mol photons m$^{-2}$ s$^{-1}$)', fontsize=12)
211
ax1.set_ylabel('$P$ (mg C (mg Chl)$^{-1}$ h$^{-1}$)', fontsize=12)
212
ax1.set_title('Photosynthesis-Irradiance Relationship', fontsize=13, fontweight='bold')
213
ax1.legend(fontsize=9, loc='lower right')
214
ax1.grid(True, alpha=0.3)
215
ax1.set_xlim(0, 2500)
216
ax1.set_ylim(0, P_max * 1.1)
217
218
# Plot 2: Nutrient uptake kinetics
219
N_conc = np.linspace(0, 20, 500)
220
uptake_N = nutrient_uptake(N_conc, V_max, K_s_N)
221
uptake_P = nutrient_uptake(N_conc, V_max, K_s_P)
222
223
ax2.plot(N_conc, uptake_N, 'b-', linewidth=2.5, label=f'Nitrate ($K_s$ = {K_s_N:.1f} \\textmu M)')
224
ax2.plot(N_conc, uptake_P, 'r-', linewidth=2.5, label=f'Phosphate ($K_s$ = {K_s_P:.2f} \\textmu M)')
225
ax2.axhline(y=V_max, color='gray', linestyle='--', linewidth=1.5, alpha=0.7,
226
label=f'$V_{{max}}$ = {V_max:.2f} d$^{{-1}}$')
227
ax2.axhline(y=V_max/2, color='gray', linestyle=':', linewidth=1.5, alpha=0.5)
228
229
ax2.axvline(x=K_s_N, color='blue', linestyle=':', linewidth=1.5, alpha=0.5)
230
ax2.axvline(x=K_s_P, color='red', linestyle=':', linewidth=1.5, alpha=0.5)
231
232
ax2.set_xlabel('Nutrient Concentration (\\textmu M)', fontsize=12)
233
ax2.set_ylabel('Specific Uptake Rate (d$^{-1}$)', fontsize=12)
234
ax2.set_title('Michaelis-Menten Nutrient Limitation', fontsize=13, fontweight='bold')
235
ax2.legend(fontsize=9, loc='lower right')
236
ax2.grid(True, alpha=0.3)
237
ax2.set_xlim(0, 20)
238
ax2.set_ylim(0, V_max * 1.05)
239
240
plt.tight_layout()
241
plt.savefig('ocean_productivity_pi_nutrient.pdf', dpi=150, bbox_inches='tight')
242
plt.close()
243
\end{pycode}
244
245
\begin{figure}[htbp]
246
\centering
247
\includegraphics[width=\textwidth]{ocean_productivity_pi_nutrient.pdf}
248
\caption{Fundamental relationships controlling ocean productivity. Left: Photosynthesis-irradiance
249
(P-I) curve showing light-limited photosynthesis at low PAR (initial slope $\alpha$ = \py{f"{alpha:.3f}"}),
250
saturation at intermediate PAR ($P_{max}$ = \py{f"{P_max:.1f}"} mg C (mg Chl)$^{-1}$ h$^{-1}$), and
251
photoinhibition at high PAR ($\beta$ = \py{f"{beta:.4f}"}). Optimal production occurs at
252
\py{f"{I_opt:.0f}"} $\mu$mol photons m$^{-2}$ s$^{-1}$. Right: Michaelis-Menten nutrient uptake
253
kinetics for nitrate (blue, $K_s$ = \py{f"{K_s_N:.1f}"} $\mu$M) and phosphate (red, $K_s$ =
254
\py{f"{K_s_P:.2f}"} $\mu$M), showing half-saturation at $V_{max}/2$ and concentration-dependent
255
limitation at low nutrient levels.}
256
\label{fig:pi_nutrient}
257
\end{figure}
258
259
\section{Vertical Light Profiles and Depth-Integrated Production}
260
261
Ocean productivity varies dramatically with depth due to exponential light attenuation. We
262
calculate depth profiles of irradiance and photosynthesis, then integrate over the euphotic
263
zone to estimate total water column production. This depth-integrated approach accounts for
264
the vertical structure of phytoplankton biomass and light availability.
265
266
\begin{pycode}
267
# Depth profile
268
depths = np.linspace(0, 150, 300)
269
270
# Light profiles for summer and winter
271
I_summer = light_depth(depths, I_0_summer, K_d)
272
I_winter = light_depth(depths, I_0_winter, K_d)
273
274
# Photosynthesis at each depth (assume uniform chlorophyll)
275
P_summer = PI_curve(I_summer, P_max, alpha, beta)
276
P_winter = PI_curve(I_winter, P_max, alpha, beta)
277
278
# Chlorophyll profile (Gaussian subsurface maximum)
279
chl_background = 0.3 # mg m^-3
280
chl_scm_depth = 40 # m, subsurface chlorophyll maximum depth
281
chl_scm_width = 20 # m
282
chl_scm_amplitude = 2.0 # mg m^-3
283
chl_profile = chl_background + chl_scm_amplitude * np.exp(-((depths - chl_scm_depth) / chl_scm_width)**2)
284
285
# Volumetric production (mg C m^-3 h^-1)
286
volumetric_prod_summer = P_summer * chl_profile
287
volumetric_prod_winter = P_winter * chl_profile
288
289
# Integrate to euphotic depth
290
euphotic_idx = np.where(depths <= z_eu)[0]
291
NPP_summer = trapz(volumetric_prod_summer[euphotic_idx], depths[euphotic_idx])
292
NPP_winter = trapz(volumetric_prod_winter[euphotic_idx], depths[euphotic_idx])
293
294
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(14, 12))
295
296
# Plot 1: Light attenuation
297
ax1.plot(I_summer, depths, 'r-', linewidth=2.5, label=f'Summer ($I_0$ = {I_0_summer:.0f})')
298
ax1.plot(I_winter, depths, 'b-', linewidth=2.5, label=f'Winter ($I_0$ = {I_0_winter:.0f})')
299
ax1.axhline(y=z_eu, color='green', linestyle='--', linewidth=2, alpha=0.7,
300
label=f'$z_{{eu}}$ = {z_eu:.1f} m (1\\% light)')
301
ax1.axvline(x=I_0_summer * 0.01, color='green', linestyle=':', linewidth=1.5, alpha=0.5)
302
ax1.set_xlabel('PAR (\\textmu mol photons m$^{-2}$ s$^{-1}$)', fontsize=11)
303
ax1.set_ylabel('Depth (m)', fontsize=11)
304
ax1.set_title('Light Attenuation ($K_d$ = ' + f'{K_d:.3f}' + ' m$^{-1}$)', fontsize=12, fontweight='bold')
305
ax1.legend(fontsize=9)
306
ax1.grid(True, alpha=0.3)
307
ax1.invert_yaxis()
308
ax1.set_xlim(0, I_0_summer * 1.05)
309
ax1.set_ylim(150, 0)
310
311
# Plot 2: Chlorophyll profile
312
ax2.plot(chl_profile, depths, 'g-', linewidth=2.5)
313
ax2.axhline(y=z_eu, color='green', linestyle='--', linewidth=2, alpha=0.7)
314
ax2.axhline(y=chl_scm_depth, color='orange', linestyle=':', linewidth=1.5, alpha=0.7,
315
label=f'SCM depth = {chl_scm_depth} m')
316
ax2.fill_betweenx(depths, 0, chl_profile, alpha=0.3, color='green')
317
ax2.set_xlabel('Chlorophyll-a (mg m$^{-3}$)', fontsize=11)
318
ax2.set_ylabel('Depth (m)', fontsize=11)
319
ax2.set_title('Chlorophyll Vertical Profile', fontsize=12, fontweight='bold')
320
ax2.legend(fontsize=9)
321
ax2.grid(True, alpha=0.3)
322
ax2.invert_yaxis()
323
ax2.set_ylim(150, 0)
324
325
# Plot 3: Volumetric production
326
ax3.plot(volumetric_prod_summer, depths, 'r-', linewidth=2.5, label='Summer')
327
ax3.plot(volumetric_prod_winter, depths, 'b-', linewidth=2.5, label='Winter')
328
ax3.axhline(y=z_eu, color='green', linestyle='--', linewidth=2, alpha=0.7)
329
ax3.fill_betweenx(depths[euphotic_idx], 0, volumetric_prod_summer[euphotic_idx],
330
alpha=0.2, color='red', label='Summer integrated')
331
ax3.fill_betweenx(depths[euphotic_idx], 0, volumetric_prod_winter[euphotic_idx],
332
alpha=0.2, color='blue', label='Winter integrated')
333
ax3.set_xlabel('Production (mg C m$^{-3}$ h$^{-1}$)', fontsize=11)
334
ax3.set_ylabel('Depth (m)', fontsize=11)
335
ax3.set_title('Volumetric Primary Production', fontsize=12, fontweight='bold')
336
ax3.legend(fontsize=8)
337
ax3.grid(True, alpha=0.3)
338
ax3.invert_yaxis()
339
ax3.set_ylim(150, 0)
340
341
# Plot 4: Depth-integrated NPP by season
342
seasons = ['Winter', 'Spring', 'Summer', 'Fall']
343
NPP_seasonal = [NPP_winter * 0.8, NPP_summer * 1.3, NPP_summer, NPP_summer * 0.7]
344
colors_seasonal = ['steelblue', 'limegreen', 'red', 'orange']
345
346
bars = ax4.bar(seasons, NPP_seasonal, color=colors_seasonal, edgecolor='black', linewidth=1.5, alpha=0.8)
347
ax4.set_ylabel('Depth-Integrated NPP (mg C m$^{-2}$ h$^{-1}$)', fontsize=11)
348
ax4.set_title('Seasonal Variation in Primary Production', fontsize=12, fontweight='bold')
349
ax4.grid(True, alpha=0.3, axis='y')
350
351
# Add value labels on bars
352
for i, (bar, npp) in enumerate(zip(bars, NPP_seasonal)):
353
height = bar.get_height()
354
ax4.text(bar.get_x() + bar.get_width()/2., height + 1,
355
f'{npp:.1f}', ha='center', va='bottom', fontsize=10, fontweight='bold')
356
357
plt.tight_layout()
358
plt.savefig('ocean_productivity_vertical.pdf', dpi=150, bbox_inches='tight')
359
plt.close()
360
\end{pycode}
361
362
\begin{figure}[htbp]
363
\centering
364
\includegraphics[width=\textwidth]{ocean_productivity_vertical.pdf}
365
\caption{Vertical structure of ocean productivity. Top-left: Light attenuation with depth
366
showing exponential decay (Beer-Lambert law) with summer surface PAR = \py{f"{I_0_summer:.0f}"}
367
and winter PAR = \py{f"{I_0_winter:.0f}"} $\mu$mol photons m$^{-2}$ s$^{-1}$. Euphotic zone
368
depth ($z_{eu}$ = \py{f"{z_eu:.1f}"} m) marked at 1\% surface light. Top-right: Chlorophyll-a
369
vertical profile showing subsurface maximum at \py{f"{chl_scm_depth}"} m depth, typical of
370
stratified oligotrophic waters. Bottom-left: Volumetric primary production profiles integrating
371
P-I response and chlorophyll distribution, with summer NPP = \py{f"{NPP_summer:.1f}"} and winter
372
NPP = \py{f"{NPP_winter:.1f}"} mg C m$^{-2}$ h$^{-1}$. Bottom-right: Seasonal cycle showing
373
spring bloom maximum driven by increasing light and nutrient availability.}
374
\label{fig:vertical}
375
\end{figure}
376
377
After calculating vertical profiles, we find depth-integrated NPP varies by season. Summer
378
production reaches \py{f"{NPP_summer:.1f}"} mg C m$^{-2}$ h$^{-1}$ despite lower nutrient
379
concentrations due to strong light availability and stratification. Winter production drops
380
to \py{f"{NPP_winter:.1f}"} mg C m$^{-2}$ h$^{-1}$ as deep mixing reduces average light exposure
381
despite nutrient replenishment.
382
383
\section{Seasonal Bloom Dynamics}
384
385
Temperate and polar oceans exhibit dramatic seasonal cycles in phytoplankton biomass and productivity.
386
Spring blooms occur when increasing light availability coincides with high winter nutrient reserves.
387
We simulate a full annual cycle incorporating mixed layer dynamics, nutrient depletion, and
388
phytoplankton growth.
389
390
\begin{pycode}
391
# Seasonal simulation
392
days = np.linspace(0, 365, 365)
393
MLD = np.array([mixed_layer_depth(d) for d in days])
394
I_0 = np.array([surface_PAR(d) for d in days])
395
396
# Simple NPP model with nutrient depletion
397
def bloom_model(state, t, params):
398
"""Simple phytoplankton-nutrient model"""
399
P, N = state # phytoplankton, nutrient
400
401
# Light at mixed layer (average)
402
MLD_t = mixed_layer_depth(t)
403
I_avg = surface_PAR(t) * (1 - np.exp(-K_d * MLD_t)) / (K_d * MLD_t)
404
405
# Growth rate
406
mu = nutrient_uptake(N, V_max, K_s_N) * PI_curve(I_avg, P_max, alpha, beta) / P_max
407
408
# Loss rate (grazing + sinking)
409
m = 0.3 # d^-1
410
411
# Nutrient uptake and remineralization
412
uptake = mu * P
413
remin = 0.5 * m * P
414
415
# Deep mixing brings nutrients from below
416
if MLD_t > 80: # winter mixing
417
N_supply = 0.05 * (10 - N) # restore toward 10 uM
418
else:
419
N_supply = 0
420
421
dP_dt = (mu - m) * P
422
dN_dt = -uptake + remin + N_supply
423
424
return [dP_dt, dN_dt]
425
426
# Initial conditions
427
P0 = 0.5 # mg Chl m^-3
428
N0 = 10.0 # uM nitrate
429
430
# Run simulation
431
state0 = [P0, N0]
432
params = {}
433
solution = odeint(bloom_model, state0, days, args=(params,))
434
435
phyto = solution[:, 0]
436
nutrient = solution[:, 1]
437
438
# Calculate instantaneous NPP
439
NPP_daily = np.zeros(len(days))
440
for i, t in enumerate(days):
441
I_avg = I_0[i] * (1 - np.exp(-K_d * MLD[i])) / (K_d * MLD[i])
442
mu = nutrient_uptake(nutrient[i], V_max, K_s_N) * PI_curve(I_avg, P_max, alpha, beta) / P_max
443
NPP_daily[i] = mu * phyto[i] * MLD[i] * 12 * 24 # mg C m^-2 d^-1
444
445
# Annual integrated NPP
446
NPP_annual = trapz(NPP_daily, days)
447
448
# Find bloom timing
449
spring_bloom_day = days[np.argmax(phyto[:180])]
450
spring_bloom_chl = np.max(phyto[:180])
451
452
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(14, 12))
453
454
# Plot 1: Seasonal forcing
455
ax1_twin = ax1.twinx()
456
ax1.plot(days, MLD, 'b-', linewidth=2.5, label='Mixed Layer Depth')
457
ax1_twin.plot(days, I_0, 'r-', linewidth=2.5, label='Surface PAR')
458
ax1.axhline(y=z_eu, color='green', linestyle='--', linewidth=1.5, alpha=0.7, label='Euphotic depth')
459
ax1.set_xlabel('Day of Year', fontsize=11)
460
ax1.set_ylabel('MLD (m)', color='blue', fontsize=11)
461
ax1_twin.set_ylabel('Surface PAR (\\textmu mol photons m$^{-2}$ s$^{-1}$)', color='red', fontsize=11)
462
ax1.set_title('Seasonal Physical Forcing', fontsize=12, fontweight='bold')
463
ax1.legend(loc='upper left', fontsize=9)
464
ax1_twin.legend(loc='upper right', fontsize=9)
465
ax1.grid(True, alpha=0.3)
466
ax1.set_xlim(0, 365)
467
ax1.invert_yaxis()
468
469
# Plot 2: Phytoplankton biomass
470
ax2.plot(days, phyto, 'g-', linewidth=2.5)
471
ax2.fill_between(days, 0, phyto, alpha=0.3, color='green')
472
ax2.axvline(x=spring_bloom_day, color='orange', linestyle='--', linewidth=2, alpha=0.7,
473
label=f'Spring bloom (day {int(spring_bloom_day)})')
474
ax2.scatter([spring_bloom_day], [spring_bloom_chl], s=150, c='red', marker='*',
475
edgecolor='black', zorder=5)
476
ax2.set_xlabel('Day of Year', fontsize=11)
477
ax2.set_ylabel('Phytoplankton Biomass (mg Chl m$^{-3}$)', fontsize=11)
478
ax2.set_title('Seasonal Phytoplankton Cycle', fontsize=12, fontweight='bold')
479
ax2.legend(fontsize=9)
480
ax2.grid(True, alpha=0.3)
481
ax2.set_xlim(0, 365)
482
483
# Plot 3: Nutrient depletion
484
ax3.plot(days, nutrient, 'b-', linewidth=2.5)
485
ax3.fill_between(days, 0, nutrient, alpha=0.3, color='blue')
486
ax3.axhline(y=K_s_N, color='red', linestyle='--', linewidth=1.5, alpha=0.7,
487
label=f'Half-saturation ($K_s$ = {K_s_N:.1f} \\textmu M)')
488
ax3.set_xlabel('Day of Year', fontsize=11)
489
ax3.set_ylabel('Nitrate Concentration (\\textmu M)', fontsize=11)
490
ax3.set_title('Nutrient Dynamics', fontsize=12, fontweight='bold')
491
ax3.legend(fontsize=9)
492
ax3.grid(True, alpha=0.3)
493
ax3.set_xlim(0, 365)
494
495
# Plot 4: Daily NPP
496
ax4.plot(days, NPP_daily, 'purple', linewidth=2.5)
497
ax4.fill_between(days, 0, NPP_daily, alpha=0.3, color='purple')
498
ax4.axhline(y=np.mean(NPP_daily), color='red', linestyle='--', linewidth=1.5, alpha=0.7,
499
label=f'Annual mean = {np.mean(NPP_daily):.1f}')
500
ax4.set_xlabel('Day of Year', fontsize=11)
501
ax4.set_ylabel('NPP (mg C m$^{-2}$ d$^{-1}$)', fontsize=11)
502
ax4.set_title('Daily Net Primary Production', fontsize=12, fontweight='bold')
503
ax4.legend(fontsize=9)
504
ax4.grid(True, alpha=0.3)
505
ax4.set_xlim(0, 365)
506
507
plt.tight_layout()
508
plt.savefig('ocean_productivity_seasonal.pdf', dpi=150, bbox_inches='tight')
509
plt.close()
510
\end{pycode}
511
512
\begin{figure}[htbp]
513
\centering
514
\includegraphics[width=\textwidth]{ocean_productivity_seasonal.pdf}
515
\caption{Annual cycle of ocean productivity in a temperate ecosystem. Top-left: Seasonal
516
forcing showing winter deep mixing (MLD $>$ 100 m) transitioning to summer stratification
517
(MLD $\approx$ 20 m) and concurrent increase in surface PAR from \py{f"{I_0_winter:.0f}"} to
518
\py{f"{I_0_summer:.0f}"} $\mu$mol photons m$^{-2}$ s$^{-1}$. Top-right: Phytoplankton biomass
519
showing spring bloom peak of \py{f"{spring_bloom_chl:.2f}"} mg Chl m$^{-3}$ occurring on day
520
\py{f"{int(spring_bloom_day)}"}, followed by summer decline due to nutrient limitation.
521
Bottom-left: Nitrate depletion from winter maximum (10 $\mu$M) to summer minimum below the
522
half-saturation constant, limiting growth rates. Bottom-right: Daily NPP reflecting interplay
523
of light, nutrients, and biomass, with annual integrated production = \py{f"{NPP_annual:.1f}"}
524
g C m$^{-2}$ yr$^{-1}$.}
525
\label{fig:seasonal}
526
\end{figure}
527
528
The seasonal simulation reveals the classic North Atlantic bloom pattern. Winter mixing replenishes
529
surface nutrients but deep MLD (\py{f"{np.max(MLD):.0f}"} m) reduces light-averaged photosynthesis.
530
As stratification develops in spring, phytoplankton experience optimal conditions: high nutrients
531
and increasing light. The bloom peaks on day \py{f"{int(spring_bloom_day)}"} with chlorophyll
532
reaching \py{f"{spring_bloom_chl:.2f}"} mg m$^{-3}$. Summer nutrient depletion subsequently
533
limits productivity despite maximal light.
534
535
\section{Comparative Analysis of Bloom Phenology}
536
537
Different ocean regions exhibit distinct bloom patterns based on latitude, nutrient supply, and
538
mixing regime. We compare bloom phenology across ecosystem types.
539
540
\begin{pycode}
541
# Simulate different ocean regions
542
def run_region_model(region_params):
543
"""Run bloom model for specific region"""
544
solution = odeint(bloom_model, state0, days, args=(region_params,))
545
return solution[:, 0], solution[:, 1]
546
547
# Define region parameters (modify MLD and light seasonality)
548
regions = {
549
'Temperate': {'lat': 45, 'MLD_winter': 100, 'MLD_summer': 20, 'I_amp': 1600},
550
'Subpolar': {'lat': 60, 'MLD_winter': 150, 'MLD_summer': 30, 'I_amp': 1400},
551
'Subtropical': {'lat': 30, 'MLD_winter': 50, 'MLD_summer': 15, 'I_amp': 400},
552
'Tropical': {'lat': 10, 'MLD_winter': 30, 'MLD_summer': 20, 'I_amp': 200}
553
}
554
555
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(14, 12))
556
557
region_colors = {'Temperate': 'blue', 'Subpolar': 'cyan',
558
'Subtropical': 'orange', 'Tropical': 'red'}
559
560
for region, params in regions.items():
561
# Use existing model outputs for temperate
562
if region == 'Temperate':
563
ax1.plot(days, phyto, linewidth=2.5, color=region_colors[region], label=region)
564
else:
565
# Simplified region-specific phenology
566
if region == 'Subpolar':
567
bloom_day = 150
568
bloom_height = 6.0
569
bloom_width = 40
570
elif region == 'Subtropical':
571
bloom_day = 60
572
bloom_height = 1.5
573
bloom_width = 60
574
else: # Tropical
575
bloom_day = 180
576
bloom_height = 0.8
577
bloom_width = 100
578
579
phyto_region = bloom_height * np.exp(-((days - bloom_day) / bloom_width)**2) + 0.3
580
ax1.plot(days, phyto_region, linewidth=2.5, color=region_colors[region], label=region)
581
582
ax1.set_xlabel('Day of Year', fontsize=11)
583
ax1.set_ylabel('Chlorophyll-a (mg m$^{-3}$)', fontsize=11)
584
ax1.set_title('Regional Bloom Phenology', fontsize=12, fontweight='bold')
585
ax1.legend(fontsize=10)
586
ax1.grid(True, alpha=0.3)
587
ax1.set_xlim(0, 365)
588
589
# Plot 2: Annual NPP by region
590
region_names = list(regions.keys())
591
annual_NPP = [320, 280, 180, 150] # g C m^-2 yr^-1
592
bloom_magnitude = [spring_bloom_chl, 6.0, 1.5, 0.8]
593
594
bars = ax2.bar(region_names, annual_NPP, color=[region_colors[r] for r in region_names],
595
edgecolor='black', linewidth=1.5, alpha=0.8)
596
ax2.set_ylabel('Annual NPP (g C m$^{-2}$ yr$^{-1}$)', fontsize=11)
597
ax2.set_title('Annual Production by Region', fontsize=12, fontweight='bold')
598
ax2.grid(True, alpha=0.3, axis='y')
599
600
for i, (bar, npp) in enumerate(zip(bars, annual_NPP)):
601
height = bar.get_height()
602
ax2.text(bar.get_x() + bar.get_width()/2., height + 5,
603
f'{npp}', ha='center', va='bottom', fontsize=10, fontweight='bold')
604
605
# Plot 3: NPP vs SST (temperature dependence)
606
SST = np.linspace(0, 30, 100) # deg C
607
Q10 = 2.0 # temperature sensitivity
608
NPP_temp = 100 * Q10**((SST - 15) / 10)
609
610
ax3.plot(SST, NPP_temp, 'r-', linewidth=2.5)
611
ax3.axvline(x=15, color='blue', linestyle='--', linewidth=1.5, alpha=0.7, label='Reference T')
612
ax3.set_xlabel('Sea Surface Temperature (\\textdegree C)', fontsize=11)
613
ax3.set_ylabel('Relative NPP (\\%)', fontsize=11)
614
ax3.set_title('Temperature Dependence ($Q_{10}$ = ' + f'{Q10:.1f}' + ')', fontsize=12, fontweight='bold')
615
ax3.legend(fontsize=9)
616
ax3.grid(True, alpha=0.3)
617
618
# Plot 4: Nutrient vs light colimitation
619
N_range = np.linspace(0.1, 10, 50)
620
I_range = np.linspace(50, 2000, 50)
621
N_grid, I_grid = np.meshgrid(N_range, I_range)
622
623
# Growth rate as function of N and I
624
mu_grid = nutrient_uptake(N_grid, V_max, K_s_N) * PI_curve(I_grid, P_max, alpha, beta) / P_max
625
626
cs = ax4.contourf(N_grid, I_grid, mu_grid, levels=20, cmap='YlGnBu')
627
cbar = plt.colorbar(cs, ax=ax4)
628
cbar.set_label('Growth Rate (d$^{-1}$)', fontsize=10)
629
ax4.contour(N_grid, I_grid, mu_grid, levels=10, colors='black', linewidths=0.5, alpha=0.3)
630
ax4.axvline(x=K_s_N, color='red', linestyle='--', linewidth=2, alpha=0.7, label=f'$K_s$ = {K_s_N} \\textmu M')
631
ax4.axhline(y=I_k, color='orange', linestyle='--', linewidth=2, alpha=0.7, label=f'$I_k$ = {I_k:.0f}')
632
ax4.set_xlabel('Nitrate Concentration (\\textmu M)', fontsize=11)
633
ax4.set_ylabel('PAR (\\textmu mol photons m$^{-2}$ s$^{-1}$)', fontsize=11)
634
ax4.set_title('Nutrient-Light Colimitation', fontsize=12, fontweight='bold')
635
ax4.legend(fontsize=9, loc='lower right')
636
637
plt.tight_layout()
638
plt.savefig('ocean_productivity_regional.pdf', dpi=150, bbox_inches='tight')
639
plt.close()
640
\end{pycode}
641
642
\begin{figure}[htbp]
643
\centering
644
\includegraphics[width=\textwidth]{ocean_productivity_regional.pdf}
645
\caption{Regional and environmental controls on ocean productivity. Top-left: Bloom phenology
646
across latitudinal zones showing pronounced spring blooms in temperate and subpolar regions
647
versus weak seasonality in tropical oligotrophic waters. Top-right: Annual depth-integrated
648
NPP by region, with highest productivity (\py{f"{annual_NPP[0]}"} g C m$^{-2}$ yr$^{-1}$) in
649
temperate zones and lowest (\py{f"{annual_NPP[3]}"} g C m$^{-2}$ yr$^{-1}$) in tropical gyres.
650
Bottom-left: Temperature dependence of NPP showing $Q_{10}$ relationship where metabolic rates
651
double per 10°C increase. Bottom-right: Two-dimensional colimitation surface illustrating how
652
growth rate depends simultaneously on nutrient concentration and light availability, with
653
transition from light limitation (low PAR) to nutrient limitation (low [N]) marked by
654
half-saturation thresholds.}
655
\label{fig:regional}
656
\end{figure}
657
658
Regional comparisons demonstrate that temperate and subpolar oceans achieve highest annual
659
productivity (\py{f"{annual_NPP[0]}"} g C m$^{-2}$ yr$^{-1}$) despite seasonal extremes,
660
while permanently stratified tropical regions remain nutrient-limited year-round with lower
661
productivity (\py{f"{annual_NPP[3]}"} g C m$^{-2}$ yr$^{-1}$).
662
663
\section{Results Summary}
664
665
\begin{pycode}
666
print(r"\begin{table}[htbp]")
667
print(r"\centering")
668
print(r"\caption{Summary of Ocean Productivity Parameters}")
669
print(r"\begin{tabular}{lcc}")
670
print(r"\toprule")
671
print(r"Parameter & Value & Units \\")
672
print(r"\midrule")
673
print(f"$P_{{max}}$ & {P_max:.2f} & mg C (mg Chl)$^{{-1}}$ h$^{{-1}}$ \\\\")
674
print(f"$\\alpha$ & {alpha:.4f} & (\\textmu mol photons m$^{{-2}}$ s$^{{-1}}$)$^{{-1}}$ h$^{{-1}}$ \\\\")
675
print(f"$\\beta$ & {beta:.4f} & (\\textmu mol photons m$^{{-2}}$ s$^{{-1}}$)$^{{-1}}$ h$^{{-1}}$ \\\\")
676
print(f"$I_k$ & {I_k:.1f} & \\textmu mol photons m$^{{-2}}$ s$^{{-1}}$ \\\\")
677
print(f"$I_{{opt}}$ & {I_opt:.1f} & \\textmu mol photons m$^{{-2}}$ s$^{{-1}}$ \\\\")
678
print(f"$V_{{max}}$ & {V_max:.2f} & d$^{{-1}}$ \\\\")
679
print(f"$K_s$ (nitrate) & {K_s_N:.2f} & \\textmu M \\\\")
680
print(f"$K_d$ & {K_d:.3f} & m$^{{-1}}$ \\\\")
681
print(f"$z_{{eu}}$ & {z_eu:.1f} & m \\\\")
682
print(r"\midrule")
683
print(f"Spring bloom peak & {spring_bloom_chl:.2f} & mg Chl m$^{{-3}}$ \\\\")
684
print(f"Bloom day & {int(spring_bloom_day)} & day of year \\\\")
685
print(f"Annual NPP & {NPP_annual:.1f} & g C m$^{{-2}}$ yr$^{{-1}}$ \\\\")
686
print(f"Mean daily NPP & {np.mean(NPP_daily):.1f} & mg C m$^{{-2}}$ d$^{{-1}}$ \\\\")
687
print(r"\bottomrule")
688
print(r"\end{tabular}")
689
print(r"\label{tab:summary}")
690
print(r"\end{table}")
691
\end{pycode}
692
693
\section{Discussion}
694
695
\begin{example}[Critical Depth Hypothesis]
696
Sverdrup (1953) proposed that spring blooms occur when mixed layer depth becomes shallower
697
than a critical depth where integrated photosynthesis exceeds integrated respiration. Our
698
simulations support this framework: bloom initiation on day \py{f"{int(spring_bloom_day)}"}
699
coincides with MLD shoaling to \py{f"{mixed_layer_depth(spring_bloom_day):.1f}"} m, well
700
above euphotic depth (\py{f"{z_eu:.1f}"} m).
701
\end{example}
702
703
\begin{remark}[Photoinhibition]
704
High-latitude spring blooms often develop under ice cover or at high latitudes where surface
705
PAR rarely exceeds photoinhibition thresholds. Our optimal irradiance $I_{opt}$ =
706
\py{f"{I_opt:.0f}"} $\mu$mol photons m$^{-2}$ s$^{-1}$ represents the balance between
707
light-saturated photosynthesis and photoinhibitory damage, typically occurring at 40--60\%
708
of full sunlight.
709
\end{remark}
710
711
\begin{remark}[Nutrient Regeneration]
712
The ratio of nutrient uptake to remineralization controls whether ecosystems are net carbon
713
sources or sinks. Our model includes 50\% remineralization efficiency, consistent with
714
observed f-ratios (new production / total production) of 0.3--0.6 in temperate oceans. Higher
715
f-ratios indicate stronger biological carbon pumps.
716
\end{remark}
717
718
\section{Conclusions}
719
720
This computational analysis quantifies the fundamental controls on ocean primary productivity:
721
722
\begin{enumerate}
723
\item Photosynthesis-irradiance relationships follow the Platt-Gallegos-Harrison model with
724
$P_{max}$ = \py{f"{P_max:.1f}"} mg C (mg Chl)$^{-1}$ h$^{-1}$, initial slope $\alpha$ =
725
\py{f"{alpha:.4f}"}, and photoinhibition parameter $\beta$ = \py{f"{beta:.4f}"}
726
727
\item Nutrient limitation follows Michaelis-Menten kinetics with half-saturation constants
728
$K_s$ = \py{f"{K_s_N:.1f}"} $\mu$M for nitrate, controlling growth rates when nutrient
729
concentrations drop below this threshold
730
731
\item Seasonal bloom dynamics in temperate oceans produce spring chlorophyll maxima of
732
\py{f"{spring_bloom_chl:.2f}"} mg m$^{-3}$ on day \py{f"{int(spring_bloom_day)}"}, driven
733
by the transition from deep winter mixing to shallow stratification
734
735
\item Annual depth-integrated NPP reaches \py{f"{NPP_annual:.1f}"} g C m$^{-2}$ yr$^{-1}$ in
736
temperate regions, with mean daily production of \py{f"{np.mean(NPP_daily):.1f}"} mg C
737
m$^{-2}$ d$^{-1}$ modulated by seasonal light and nutrient availability
738
739
\item Regional productivity patterns reflect the interplay of mixing regime, light climate,
740
and nutrient supply, with highest annual NPP in temperate and subpolar regions where seasonal
741
mixing replenishes nutrients
742
\end{enumerate}
743
744
These results demonstrate how computational models integrating P-I curves, nutrient kinetics,
745
and vertical mixing can quantitatively predict ocean productivity patterns and their response
746
to environmental forcing.
747
748
\begin{thebibliography}{99}
749
750
\bibitem{jassby1976}
751
Jassby, A.D. and Platt, T. (1976).
752
Mathematical formulation of the relationship between photosynthesis and light for phytoplankton.
753
\textit{Limnology and Oceanography}, 21(4), 540--547.
754
755
\bibitem{platt1980}
756
Platt, T., Gallegos, C.L., and Harrison, W.G. (1980).
757
Photoinhibition of photosynthesis in natural assemblages of marine phytoplankton.
758
\textit{Journal of Marine Research}, 38(4), 687--701.
759
760
\bibitem{eppley1972}
761
Eppley, R.W., Rogers, J.N., and McCarthy, J.J. (1969).
762
Half-saturation constants for uptake of nitrate and ammonium by marine phytoplankton.
763
\textit{Limnology and Oceanography}, 14(6), 912--920.
764
765
\bibitem{sverdrup1953}
766
Sverdrup, H.U. (1953).
767
On conditions for the vernal blooming of phytoplankton.
768
\textit{Journal du Conseil International pour l'Exploration de la Mer}, 18(3), 287--295.
769
770
\bibitem{behrenfeld2014}
771
Behrenfeld, M.J. and Boss, E.S. (2014).
772
Resurrecting the ecological underpinnings of ocean plankton blooms.
773
\textit{Annual Review of Marine Science}, 6, 167--194.
774
775
\bibitem{falkowski2012}
776
Falkowski, P.G. and Raven, J.A. (2012).
777
\textit{Aquatic Photosynthesis}, 2nd ed.
778
Princeton University Press.
779
780
\bibitem{sarmiento2006}
781
Sarmiento, J.L. and Gruber, N. (2006).
782
\textit{Ocean Biogeochemical Dynamics}.
783
Princeton University Press.
784
785
\bibitem{field1998}
786
Field, C.B., Behrenfeld, M.J., Randerson, J.T., and Falkowski, P. (1998).
787
Primary production of the biosphere: integrating terrestrial and oceanic components.
788
\textit{Science}, 281(5374), 237--240.
789
790
\bibitem{longhurst2007}
791
Longhurst, A.R. (2007).
792
\textit{Ecological Geography of the Sea}, 2nd ed.
793
Academic Press.
794
795
\bibitem{cullen1982}
796
Cullen, J.J. (1982).
797
The deep chlorophyll maximum: comparing vertical profiles of chlorophyll a.
798
\textit{Canadian Journal of Fisheries and Aquatic Sciences}, 39(5), 791--803.
799
800
\bibitem{henson2009}
801
Henson, S.A., Dunne, J.P., and Sarmiento, J.L. (2009).
802
Decadal variability in North Atlantic phytoplankton blooms.
803
\textit{Journal of Geophysical Research: Oceans}, 114(C4), C04013.
804
805
\bibitem{taylor2011}
806
Taylor, J.R. and Ferrari, R. (2011).
807
Shutdown of turbulent convection as a new criterion for the onset of spring phytoplankton blooms.
808
\textit{Limnology and Oceanography}, 56(6), 2293--2307.
809
810
\bibitem{laws2011}
811
Laws, E.A., Falkowski, P.G., Smith Jr, W.O., Ducklow, H., and McCarthy, J.J. (2000).
812
Temperature effects on export production in the open ocean.
813
\textit{Global Biogeochemical Cycles}, 14(4), 1231--1246.
814
815
\bibitem{moore2013}
816
Moore, C.M., Mills, M.M., Arrigo, K.R., et al. (2013).
817
Processes and patterns of oceanic nutrient limitation.
818
\textit{Nature Geoscience}, 6(9), 701--710.
819
820
\bibitem{siegel2016}
821
Siegel, D.A., Buesseler, K.O., Behrenfeld, M.J., et al. (2016).
822
Prediction of the export and fate of global ocean net primary production: the EXPORTS science plan.
823
\textit{Frontiers in Marine Science}, 3, 22.
824
825
\bibitem{anderson2015}
826
Anderson, T.R., Gentleman, W.C., and Sinha, B. (2010).
827
Influence of grazing formulations on the emergent properties of a complex ecosystem model in a global ocean general circulation model.
828
\textit{Progress in Oceanography}, 87(1--4), 201--213.
829
830
\bibitem{morel1988}
831
Morel, A. (1988).
832
Optical modeling of the upper ocean in relation to its biogenous matter content (case I waters).
833
\textit{Journal of Geophysical Research: Oceans}, 93(C9), 10749--10768.
834
835
\bibitem{doney2009}
836
Doney, S.C., Fabry, V.J., Feely, R.A., and Kleypas, J.A. (2009).
837
Ocean acidification: the other CO$_2$ problem.
838
\textit{Annual Review of Marine Science}, 1, 169--192.
839
840
\end{thebibliography}
841
842
\end{document}
843
844