📄 upwindfirsteno3b.m
字号:
function [ derivL, derivR ] = upwindFirstENO3b(grid, data, dim, generateAll)
% upwindFirstENO3b: third order upwind approx of first deriv by direct calc.
%
% [ derivL, derivR ] = upwindFirstENO3b(grid, data, dim, generateAll)
%
% Computes a third order directional approximation to the first
% derivative, using an Essentially Non-Oscillatory (ENO) approximation.
%
% The approximation is constructed by the equations in O&F, section 3.4
% equations (3.25) - (3.27). This is an
% alternative to the more efficient divided difference
% table for computing the ENO approximations, which is used in
% upwindFirstENO3a. In particular, the left and right approximations
% are computed independently in this version.
%
% The generateAll option is used for debugging, and possibly by
% higher order weighting schemes. Under normal circumstances
% the default (generateAll = false) should be used.
%
% parameters:
% grid Grid structure (see processGrid.m for details).
% data Data array.
% dim Which dimension to compute derivative on.
% generateAll Return all possible third order upwind approximations.
% If this boolean is true, then derivL and derivR will
% be cell vectors containing all the approximations
% instead of just the ENO approximation. Note that
% the ordering of these approximations may not be
% consistent between upwindFirstENO1 and upwindFirstENO2.
% (optional, default = 0)
%
% derivL Left approximation of first derivative (same size as data).
% derivR Right approximation of first derivative (same size as data).
% Copyright 2004 Ian M. Mitchell (mitchell@cs.ubc.ca).
% This software is used, copied and distributed under the licensing
% agreement contained in the file LICENSE in the top directory of
% the distribution.
%
% Ian Mitchell, 1/26/04
%---------------------------------------------------------------------------
if((dim < 0) | (dim > grid.dim))
error('Illegal dim parameter');
end
if(nargin < 4)
generateAll = 0;
end
% How big is the stencil?
stencil = 3;
% Check that approximations that should be equivalent are equivalent
% (for debugging purposes, only used if generateAll == 1).
checkEquivalentApproximations = 1;
small = 100 * eps; % a small number for "equivalence"
% Add ghost cells.
gdata = feval(grid.bdry{dim}, data, dim, stencil, grid.bdryData{dim});
%---------------------------------------------------------------------------
if(generateAll)
% Compute the left and right approximations.
% No need to build WENO approximation, just return all the ENO approx.
derivL = upwindFirstENO3bHelper(grid, gdata, dim, -1);
derivR = upwindFirstENO3bHelper(grid, gdata, dim, +1);
%---------------------------------------------------------------------------
% If necessary, check equivalence of ENO terms.
% Using notation of (3.25) - (3.27) for phi^i and the Left/Right
% choices at the D^1, D^2 and D^3 levels in that order:
% For left approximation, phi^1 is LLL, phi^2 is LLR/LRL and phi^3 is LRR;
% For right approximation, phi^1 is RRR, phi^2 is RLR/RRL and phi^3 is RLL.
% Hence the equivalences listed below.
if(checkEquivalentApproximations)
checkEquivalentApprox(derivL{2}, derivR{3}, small);
checkEquivalentApprox(derivL{3}, derivR{2}, small);
end
%---------------------------------------------------------------------------
else
%---------------------------------------------------------------------------
% Compute the left and right ENO approximations.
[ dL, smoothL ] = upwindFirstENO3bHelper(grid, gdata, dim, -1);
[ dR, smoothR ] = upwindFirstENO3bHelper(grid, gdata, dim, +1);
%---------------------------------------------------------------------------
% The best ENO approximant has the smallest smoothness estimate
derivL = choose(dL, smoothL);
derivR = choose(dR, smoothR);
end
%---------------------------------------------------------------------------
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%---------------------------------------------------------------------------
function deriv = choose(d, s)
% deriv = choose(d, s);
%
% Helper function to choose least oscillatory ENO approximant.
choose1over2 = (s{1} < s{2});
choose1over3 = (s{1} < s{3});
choose2over3 = (s{2} < s{3});
deriv = ((choose1over2 & choose1over3) .* d{1} ...
+ (~choose1over2 & choose2over3) .* d{2} ...
+ (~choose1over3 & ~choose2over3) .* d{3});
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -