logo

The Algae-Zooplankton Model as a Dynamical System 📂Dynamical Systems

The Algae-Zooplankton Model as a Dynamical System

Model 1

$$ \begin{align*} \dot{A} =& r A \left( 1 - \frac{A}{K} \right) - g Z \frac{A}{A + h_{A}} + i \left( K - A \right) \\ \dot{Z} =& e g Z \frac{A}{A + h_{A}} - m Z - F {\frac{ Z^{2} }{ Z + h_{Z} }} \end{align*} $$

Variables

  • $A$: density of algae
  • $Z$: density of zooplankton

Parameters

  • $r = 0.5$: growth rate of algae
  • $K = 6$: carrying capacity of algae
  • $g = 0.4$: grazing rate of zooplankton
  • $h_{A} = 0.6$: half-saturation constant of algae
  • $i = 0.1$: inflow rate of algae
  • $e = 0.6$: grazing efficiency of zooplankton
  • $m = 0.15$: natural mortality rate of zooplankton
  • $F$: loss due to the fish community
  • $h_{Z} = 0.5$: half-saturation constant of zooplankton

Explanation

The algae-zooplankton model is a variant of the typical Lotka-Volterra predator-prey model, a mathematical model that describes the interaction between algae and zooplankton in water.

In the model above, each term has the following meaning.

  • $\dot{A} = \cdots$
  • $\dot{Z} = \cdots$
    • $e g Z \frac{A}{A + h_{A}}$: growth of zooplankton by algae, which is affected by the grazing efficiency $e \le 1$.
    • $m Z$: natural death of zooplankton.
    • $F {\frac{ Z^{2} }{ Z + h_{Z} }}$: the zooplankton eaten by fish, which follows a Holling type II functional response.

B-tipping

alt text

The given equation exhibits a bifurcation diagram similar to the one above as $F$ varies. There are two kinds of saddle-node bifurcations, so it shows hysteresis, and B-tipping naturally occurs.

alt text

Such bifurcation diagrams appear differently in the figure above for (a) $K = 4, 6, 8, 10$, (b) $i = 0.025, 0.05, 0.075, 0.1$, (c) $g = 0.35, 0.40, 0.45, 0.50$, (d) $m = 0.10, 0.12, 0.14, 0.16$.

Code

The following is Julia code that can simulate the algae-zooplankton model.

using DataFrames, DifferentialEquations, OrdinaryDiffEqLowOrderRK

function factory_algaezooplankton(F::Number; ic = [5, 5], saveat = 0:1e-2:100)
      r, K,   g,  hA,   i,   e,    m,  hZ = (
    0.5, 6, 0.4, 0.6, 0.1, 0.6, 0.15, 0.5 )
    function sys(du, u, p, t)
        A,Z = u
        F = p[1]

        du[1] = r*A*(1 - frac(A,K)) - g*Z*frac(A, A + hA) + i*(K - A)
        du[2] = e*g*Z*frac(A, A + hA) - m*Z - F*frac(Z^2, Z^2 + hZ^2)
        return du
    end
    sol = solve(ODEProblem(sys, ic, (0, last(saveat)), [F]), RK4(), dt = saveat.step.hi, adaptive=false, maxiters = 1e+7)
    matrix = Matrix([sol.t'; sol[:, :]; stack([sys(zeros(2), u, [F], 0) for u in sol.u])]')
    return matrix[sol.t .≥ first(saveat), :][1:end-1, :]
end
factory_algaezooplankton(T::Type, args...; kargs...) =
DataFrame(factory_algaezooplankton(args...; kargs...), ["t", "A", "Z", "dA", "dZ"])

  1. Chattopadhyay, S. N., & Gupta, A. K. (2024). B-tipping points in plankton dynamics: Stochasticity and early warning signals. Physical Review E, 110(6), 064218. https://doi.org/10.1103/PhysRevE.110.064218 ↩︎