%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% SUB-FUNCTIONS %% %% USED BY: VOLBET2ISO %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % USE DIRECTLY AT YOUR OWN RISK ! % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Master sub-function: function varargout = subfct_getvol(CHP,Z,Y,X,LIMITS) % Limits: %disp(strcat('Limits: ',num2str(LIMITS))); O = LIMITS(1); MZ = LIMITS(2); MY = sort( LIMITS(3:4) ); MX = sort( LIMITS(5:6) ); % Compute the volume: [V Vmat dV] = getvol(Z,Y,X,O,MZ,MY,MX,CHP); % Outputs: switch nargout case 1 varargout(1) = {V}; case 2 varargout(1) = {V}; varargout(2) = {Vmat}; case 3 varargout(1) = {V}; varargout(2) = {Vmat}; varargout(3) = {dV}; end %switch nargout %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This function computes the volume limited southward by % MY(1), northward by iso-O (or MY(2) if iso-O reaches it), % eastward by MX(1), westward by MX(2) and downward by iso-O % (or MZ if iso-O reaches it). % % Updates: % 20060615: add a default meridional gradient (negative) % test on x,y,z limits % function varargout = getvol(Z,Y,X,O,MZ,MY,MX,CHP) %% Dim: nz = length(Z); ny = length(Y); nx = length(X); %disp(num2str([nz ny nx])); %% Indices: izmax = min( find( Z>MZ ) ); if isempty(izmax),izmax=nz;end; iymin = max( find( YMY(2) ) ); if isempty(iymax),iymax=ny;end; ixmin = max( find( XMX(2) ) ); if isempty(ixmax),ixmax=nx;end; %disp(num2str([1 izmax iymin iymax ixmin ixmax])); %% 1- determine the 3D matrix of volume elements defined by % the grid: dV = getdV(Z,Y,X); %% 2- compute the 3D volume matrix where 1 means dV must be % counted and 0 must not: V = ones(nz,ny,nx); % initialy keep all points % Exclude northward iso-O limits: % NB: here the test depends on the meridional gradient of CHP % if CHP increase (resp. decreases) with LAT then we must % keep lower (resp. higher) values than O limit % a: determine test type: N = iymax - iymin + 1; % Number of Y points in the domain CHPsouth = nanmean(nanmean(squeeze(CHP(1,iymin:iymin+fix(N/2),ixmin:ixmax)))); CHPnorth = nanmean(nanmean(squeeze(CHP(1,iymin+fix(N/2):iymax,ixmin:ixmax)))); SNgrad = (CHPnorth - CHPsouth)./abs(CHPnorth - CHPsouth); if isnan(SNgrad), SNgrad=-1; end % Assume negative gradient by default %disp(strcat('Northward gradient sign is:',num2str(SNgrad))); switch SNgrad case 1, testype = 'le'; % Less than or equal case -1, testype = 'ge'; % Greater than or equal end %switch % b: exclude points for iz=1:izmax chpZ = squeeze(CHP(iz,:,:)); V(iz,:,:)=double(feval(testype,chpZ,O)); end %for iz % Exclude southward limit: V(:,1:iymin,:) = zeros(nz,iymin,nx); % Exclude northward limit: V(:,iymax:ny,:) = zeros(nz,(ny-iymax)+1,nx); % Exclude westward limit: V(:,:,1:ixmin) = zeros(nz,ny,ixmin); % Exclude eastward limit: V(:,:,ixmax:nx) = zeros(nz,ny,(nx-ixmax)+1); % Exclude downward limit: V(izmax:nz,:,:) = zeros((nz-izmax)+1,ny,nx); %% 3- Then compute the volume by summing dV elements % for non 0 V points Vkeep = V.*dV; Vkeep = sum(sum(sum(Vkeep))); %% 4- Outputs: switch nargout case 1 varargout(1) = {Vkeep}; % Volume single value case 2 varargout(1) = {Vkeep}; varargout(2) = {V}; % Logical V matrix with included/excluded points case 3 varargout(1) = {Vkeep}; varargout(2) = {V}; varargout(3) = {dV}; % Volume elements matrix end %switch nargout %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This function computes the 3D dV volume elements. function dv = getdV(Z,Y,X); nz = length(Z); ny = length(Y); nx = length(X); %%% Compute the DY: % Assuming Y is independant of ix: d = m_lldist([1 1]*X(1),Y); dy = [d(1)/2 (d(2:length(d))+d(1:length(d)-1))/2 d(length(d))/2]; dy = meshgrid(dy,X)'; %%% Compute the DX: clear d for iy = 1 : ny d(:,iy) = m_lldist(X,Y([iy iy])); end dx = [d(1,:)/2 ; ( d(2:size(d,1),:) + d(1:size(d,1)-1,:) )./2 ; d(size(d,1),:)/2]; dx = dx'; %% Compute the horizontal DS surface element: ds = dx.*dy; %% Compute the DZ: d = diff(Z); dz = [d(1)/2 ( d(2:length(d)) + d(1:length(d)-1) )./2 d(length(d))/2]; %% Then compute the DV volume elements: dv = ones(nz,ny,nx)*NaN; for iz=1:nz dv(iz,:,:) = dz(iz).*ds; end