Internal Modes Basics

Initialize InternalModesSpectral, compute hydrostatic and fixed-frequency modes, and repeat the workflow for a realistic LatMix profile.

Source: Examples/Tutorials/InternalModesBasics.m

Initialize InternalModesSpectral from an exponential profile

This tutorial shows the minimum workflow for computing and plotting vertical modes with InternalModesSpectral. The same overall pattern also appears in InternalModesWKBSpectral, InternalModesAdaptiveSpectral, InternalModesDensitySpectral, and InternalModesFiniteDifference.

We start from the standard exponential stratification

\[N^2(z) = N_0^2 e^{2 z / b},\]

sample the implied density profile on a depth grid, and initialize the spectral solver on a denser output grid for plotting.

g = 9.81;
N0 = 5.2e-3;
b = 1300;

zIn = linspace(-5000, 0, 500).';
zOut = linspace(zIn(1), zIn(end), 1024).';
rho = 1025 * (1 + (b * N0^2 / (2 * g)) * (1 - exp(2 * zIn / b)));

im = InternalModesSpectral(rho=rho, zIn=zIn, zOut=zOut, latitude=33, nEVP=257);

Compute the hydrostatic modes

The simplest first solve is the hydrostatic call modesAtFrequency, which uses omega = 0 as the starting point.

[F, G] = im.modesAtFrequency(0);

figure(Color="w", Position=[100 100 980 360])
tiledlayout(1, 3, TileSpacing="compact", Padding="compact")

nexttile
plot(sqrt(im.N2), im.z, LineWidth=2)
xlabel("N(z) (rad s^{-1})")
ylabel("z (m)")
title("Exponential profile")
grid on

nexttile
plot(F(:, 1:4), im.z, LineWidth=1.5)
xlabel("F_j(z)")
title("Hydrostatic F modes")
grid on

nexttile
plot(G(:, 1:4), im.z, LineWidth=1.5)
xlabel("G_j(z)")
title("Hydrostatic G modes")
grid on

The hydrostatic solve gives a clean first look at the leading vertical modes for the standard exponential stratification.

The hydrostatic solve gives a clean first look at the leading vertical modes for the standard exponential stratification.

Compute modes at a nonzero frequency

To move away from the hydrostatic limit, choose a representative frequency between f0 and the largest buoyancy frequency in the water column.

The companion fixed-wavenumber problem is also available through modesAtWavenumber, which returns [F, G, h, omega] for a chosen horizontal wavenumber k.

omega = im.f0 + 0.35 * (max(sqrt(im.N2)) - im.f0);
[F, G] = im.modesAtFrequency(omega);

figure(Color="w", Position=[100 100 980 360])
tiledlayout(1, 3, TileSpacing="compact", Padding="compact")

nexttile
plot(sqrt(im.N2), im.z, LineWidth=2)
xlabel("N(z) (rad s^{-1})")
ylabel("z (m)")
title("Exponential profile")
grid on

nexttile
plot(F(:, 1:4), im.z, LineWidth=1.5)
xlabel("F_j(z)")
title(sprintf("F modes at \\omega = %.2f f_0", omega / im.f0))
grid on

nexttile
plot(G(:, 1:4), im.z, LineWidth=1.5)
xlabel("G_j(z)")
title(sprintf("G modes at \\omega = %.2f f_0", omega / im.f0))
grid on

Choosing a nonzero frequency shifts the modal structure while keeping the same InternalModesSpectral workflow.

Choosing a nonzero frequency shifts the modal structure while keeping the same InternalModesSpectral workflow.

Compute modes for a realistic LatMix profile

The same solver can be initialized directly from a gridded observed profile. Here we load the first stored Site 1 LatMix profile that ships with the examples.

scriptDir = fileparts(mfilename("fullpath"));
latmixData = load(fullfile(scriptDir, "..", "SampleLatmixProfiles.mat"));

rhoLatMix = latmixData.rhoProfile{1};
zLatMix = latmixData.zProfile{1};
zOutLatMix = linspace(zLatMix(1), zLatMix(end), 1024).';

imLatMix = InternalModesSpectral(rho=rhoLatMix, zIn=zLatMix, zOut=zOutLatMix, latitude=latmixData.latitude, nEVP=257);
[F, G] = imLatMix.modesAtFrequency(0);

figure(Color="w", Position=[100 100 980 360])
tiledlayout(1, 3, TileSpacing="compact", Padding="compact")

nexttile
plot(imLatMix.rho, imLatMix.z, LineWidth=2)
xlabel("\rho(z) (kg m^{-3})")
ylabel("z (m)")
title("LatMix density profile")
grid on

nexttile
plot(F(:, 1:4), imLatMix.z, LineWidth=1.5)
xlabel("F_j(z)")
title("LatMix hydrostatic F modes")
grid on

nexttile
plot(G(:, 1:4), imLatMix.z, LineWidth=1.5)
xlabel("G_j(z)")
title("LatMix hydrostatic G modes")
grid on

InternalModesSpectral works directly on the realistic LatMix profile and returns the leading hydrostatic modes on the requested output grid.

InternalModesSpectral works directly on the realistic LatMix profile and returns the leading hydrostatic modes on the requested output grid.

Choose the solver to match the profile

This LatMix density profile is not monotonic, so InternalModesWKBSpectral is not a good choice for this case. The depth-coordinate InternalModesSpectral solver still works directly on the supplied profile, which makes it a convenient default for realistic profiles like this one.