Skip to content

Commit

Permalink
Attempting correct non-hydrostatic flux
Browse files Browse the repository at this point in the history
Something is failing
  • Loading branch information
JeffreyEarly committed Nov 6, 2024
1 parent 219591b commit c7e199d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
3 changes: 3 additions & 0 deletions Matlab/WaveVortexModel/@WVTransform/summarizeModeEnergy.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
function summarizeModeEnergy(self,options)
% List the most energetic modes
%
% At the moment the +/- waves are simply added together for each mode.
% It would be better if they were separate.
%
% - Topic: Energetics
% - Declaration: summarizeModeEnergy(options)
% - Parameter n: (optional) number of modes to list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
% - Declaration: WVNonlinearFluxSpatial < [WVNonlinearFluxOperation](/classes/wvnonlinearfluxoperation/)
properties
dLnN2 = 0
cos_alpha
sin_alpha
ApmD
ApmW
end
methods
function self = WVNonlinearFluxNonhydrostatic(wvt)
Expand All @@ -35,13 +39,32 @@
self.dLnN2 = shiftdim(wvt.dLnN2,-2);
warning('WVTransform not recognized.')
end

k = shiftdim(wvt.k,-1);
l = shiftdim(wvt.l,-1);
kappa = sqrt(k.^2 + l.^2);
self.cos_alpha = k./kappa;
self.sin_alpha = l./kappa;
self.cos_alpha(1) = 0;
self.sin_alpha(1) = 0;

signNorm = -2*(mod(wvt.j,2) == 1)+1; % equivalent to (-1)^j
prefactor = -signNorm * sqrt((wvt.g*wvt.Lz)/(2*(wvt.N0*wvt.N0 - wvt.f*wvt.f)));
mj = (wvt.j*pi/wvt.Lz);
self.ApmD = (mj/2) .* prefactor;
self.ApmW = sqrt(-1) * (kappa/2) .* prefactor;
end

function varargout = compute(self,wvt,varargin)
function [uNL,vNL,wNL,nNL] = spatialFlux(self,wvt)
uNL = wvt.u .* wvt.diffX(wvt.u) + wvt.v .* wvt.diffY(wvt.u) + wvt.w .* wvt.diffZF(wvt.u);
vNL = wvt.u .* wvt.diffX(wvt.v) + wvt.v .* wvt.diffY(wvt.v) + wvt.w .* wvt.diffZF(wvt.v);
wNL = wvt.u .* wvt.diffX(wvt.w) + wvt.v .* wvt.diffY(wvt.w) + wvt.w .* wvt.diffZG(wvt.w);
nNL = wvt.u .* wvt.diffX(wvt.eta) + wvt.v .* wvt.diffY(wvt.eta) + wvt.w .* (wvt.diffZG(wvt.eta) + wvt.eta .* self.dLnN2);
end

function varargout = compute(self,wvt,varargin)

[uNL,vNL,wNL,nNL] = self.spatialFlux(wvt);

u_hat = wvt.transformFromSpatialDomainWithFourier(-uNL);
v_hat = wvt.transformFromSpatialDomainWithFourier(-vNL);
Expand All @@ -55,15 +78,16 @@
zeta_bar = wvt.transformFromSpatialDomainWithFg(iK .* v_hat - iL .* u_hat);
A0 = wvt.A0Z.*zeta_bar + wvt.A0N.*n_bar;

delta_bar = wvt.transformWithG_wg(wvt.h_0.*wvt.transformFromSpatialDomainWithFg(iK .* u_hat + iL .* v_hat));
delta_bar = self.ApmD .* (wvt.DCT * (self.cos_alpha .* u_hat + self.sin_alpha .* v_hat));
w_bar = self.ApmW .* (wvt.DST * w_hat);
nw_bar = wvt.transformWithG_wg(n_bar - A0);
Ap = wvt.ApmD .* delta_bar + wvt.ApmN .* nw_bar;
Am = wvt.ApmD .* delta_bar - wvt.ApmN .* nw_bar;
Ap = delta_bar + w_bar + wvt.ApmN .* nw_bar;
Am = delta_bar + w_bar - wvt.ApmN .* nw_bar;

Ap(:,1) = wvt.transformFromSpatialDomainWithFio(u_hat(:,1) - sqrt(-1)*v_hat(:,1))/2;
Am(:,1) = conj(Ap(:,1));

phase = exp(-wvt.iOmega*(t-wvt.t0));
phase = exp(-wvt.iOmega*(wvt.t-wvt.t0));
Ap = Ap .* phase;
Am = Am .* conj(phase);

Expand Down
29 changes: 21 additions & 8 deletions Matlab/WaveVortexModel/UnitTests/MiscTests/NonlinearFluxScratch.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
% removed the aliased wavenumbers. This means that all modes should be
% resolved in the nonlinear flux.

Lxyz = [500, 500, 500];
Lxyz = [500, 500, 250];
Nxyz = [8 8 9];
latitude = 33;

Expand All @@ -20,6 +20,7 @@
% wvt.initWithRandomFlow('geostrophic','mda','inertial',uvMax=0.1);
% wvt.initWithRandomFlow('mda',uvMax=0.1);
wvt.initWithRandomFlow('wave',uvMax=0.1);
% wvt.initWithRandomFlow('wave',uvMax=0.00001);
% wvt.initWithRandomFlow(uvMax=0.1);
% wvt.initWithWaveModes(kMode=1,lMode=1,j=2,phi=0,u=0.05,sign=1);
% wvt.addWaveModes(kMode=1,lMode=1,j=1,phi=0,u=0.05,sign=-1);
Expand All @@ -33,6 +34,13 @@
wvt.addWaveModes(kMode=1,lMode=1,j=1,phi=0,u=0.05,sign=1);
wvt.addWaveModes(kMode=1,lMode=0,j=1,phi=0,u=0.05,sign=1);

% Renormalize so that each wave-mode has the same total energy
renorm = 1./sqrt(wvt.Apm_TE_factor.*abs(wvt.Ap).^2);
renorm(isinf(renorm))=0;
wvt.Ap = wvt.Ap .* renorm;

% For this test, the vertical momentum contributions sum to zero

antialiasMask = zeros(wvt.spectralMatrixSize);
antialiasMask(wvt.Kh > 2*max(abs(wvt.k))/3) = 1;
antialiasMask(wvt.J > 2*max(abs(wvt.j))/3) = 1;
Expand All @@ -51,19 +59,24 @@

fprintf('\nNon-hydrostatic:\n')
% wvt.initWithUVEta(wvt.u,wvt.v,wvt.eta);
wvt.nonlinearFluxOperation = WVNonlinearFluxNonhydrostatic(wvt);
[Fp,Fm,F0] = wvt.nonlinearFlux();
[Ep,Em,E0] = wvt.energyFluxFromNonlinearFlux(Fp,Fm,F0,deltaT=0);
fprintf('(Ep,Em,E0) = (%g, %g, %g), total %g\n', sum(Ep(:)), sum(Em(:)), sum(E0(:)), sum(Ep(:))+sum(Em(:))+sum(E0(:)));

fprintf('Ep:\n')
displayFluxEnergy(wvt_hs,Ep)
% fprintf('Em:\n')
% displayFluxEnergy(wvt_hs,Em)
displayFluxEnergy(wvt,Ep)
fprintf('Em:\n')
displayFluxEnergy(wvt,Em)
% fprintf('E0:\n')
% displayFluxEnergy(wvt_hs,E0)
% displayFluxEnergy(wvt,E0)

% (wvt.totalEnergy-wvt.totalEnergySpatiallyIntegrated)/wvt.totalEnergy

% Not sure if this is helpful or meaningful.
% [uNL,vNL,wNL,nNL] = wvt.nonlinearFluxOperation.spatialFlux(wvt);
% energy = sum(shiftdim(wvt.z_int,-2).*mean(mean( wvt.u.*uNL + wvt.v.*vNL + wvt.w.*wNL + shiftdim(wvt.N2,-2).*wvt.eta.*nNL, 1 ),2 ) )/2

%%
fprintf('\nHydrostatic:\n')
wvt_hs.initWithUVEta(wvt.u,wvt.v,wvt.eta);
Expand All @@ -74,8 +87,8 @@

fprintf('Ep:\n')
displayFluxEnergy(wvt_hs,Ep)
% fprintf('Em:\n')
% displayFluxEnergy(wvt_hs,Em)
fprintf('Em:\n')
displayFluxEnergy(wvt_hs,Em)
% fprintf('E0:\n')
% displayFluxEnergy(wvt_hs,E0)

Expand All @@ -99,7 +112,7 @@
%%
function displayFluxEnergy(wvt,E)
[~,indices] = sort(abs(E(:)),'descend');
for iMode=1:10
for iMode=1:5
[kMode,lMode,jMode] = wvt.modeNumberFromIndex(indices(iMode));
fprintf('(%d,%d,%d) with energy %g\n',kMode,lMode,jMode,E(indices(iMode)));
end
Expand Down

0 comments on commit c7e199d

Please sign in to comment.