Back to home page

MITgcm

 
 

    


Warning, /utils/matlab/cs_grid/calcZonalAvgCube.m is written in an unsupported language. File is not indexed.

view on githubraw file Latest commit 6b4f212f on 2024-06-05 16:55:17 UTC
b3d495b63f Dani*0001 function [fldzon,mskzon,ylat,areazon] = calcZonalAvgCube(fld,ny,yc,ar,hc);
                0002 
                0003 % [fldzon,mskzon,ylat,areazon] = calcZonalAvgCube(fld,ny,yc,ar,hc);
                0004 %
6b4f212f67 Jean*0005 % Input arguments:
b3d495b63f Dani*0006 %   fld     Data to zonally average ([6*n,n,nr,nt], [6*n,n,nr], [6*n,n])
                0007 %   ny      Number of evenly spaces latitude lines to zonally average onto
                0008 %   yc      Cell centered latitude
                0009 %   ar      Cell area
                0010 %   hc      HFacC
                0011 %
6b4f212f67 Jean*0012 % Output arguments:
b3d495b63f Dani*0013 %   fldzon  Zonally averaged field ([ny,nr,nt], [ny,nr], [ny])
                0014 %   mskzon  Mask for zonal slice
                0015 %   ylat    Latitude coordinates for zonal average data
                0016 %   areazon Area associated with zonal band
                0017 %
                0018 % Description:
                0019 %   Calculates zonal average of "fld".
                0020 %
                0021 % Original author:  JMC
                0022 % Modifications: Daniel Enderton
                0023 
                0024 % Dimension information.
                0025 nBas = 0;
                0026 dims = size(fld);
f7a0cd83c0 Jean*0027 %if length(dims) > 4,
                0028 %    error(['To many dimensions (Max 4):  ',mat2str(dims)]);
                0029 %end
6b4f212f67 Jean*0030 n1h=dims(1); n2h=dims(2);
                0031 if n1h == n2h*6, nc=n2h; elseif n1h*6 == n2h, nc=n1h;
                0032 else
                0033    error(['Error in CS-dimensions: ',...
                0034            'n1h,n2h = ',int2str(n1h),', ',int2str(n2h)])
                0035 end
                0036 nr=1; nt=1; nDim=4;
f7a0cd83c0 Jean*0037 if length(dims) > 2,
                0038   if length(size(hc)) == 3, nr=size(hc,3); end
                0039   if dims(3) ~= nr, nr=1; nDim=3; end
                0040   nt=prod(dims(3:end))/nr;
b3d495b63f Dani*0041 end
                0042 
                0043 % Reshape data.
                0044 if nr == 1, hc = hc(:,:,1); end % Account for nr = 1
f7a0cd83c0 Jean*0045 hc = reshape(hc, [6*nc*nc,nr]);
                0046 yc = reshape(yc, [6*nc*nc,1] );
                0047 ar = reshape(ar, [6*nc*nc,1] );
                0048 fld= reshape(fld,[6*nc*nc,nr,nt]);
b3d495b63f Dani*0049 
                0050 % Define latitude axis (with regular spacing) to average to.
                0051 dy=180/ny; ylat=-90+([1:ny]-0.5)*dy;
                0052 
                0053 % Define minimum area fraction (relative to full latitude band):
                0054 frcZmn=0.05;                   % ??? Why
                0055 
                0056 % Compute zonal line weights.
                0057 nMax = 6*nc*3;           % Max number of cells near zonal line
                0058 ijzav = zeros(ny,nMax);  % Index of cells near band line (within dy)
                0059 alzav = zeros(ny,nMax);  % Area weights for cells near band line
                0060 npzav = zeros(ny,1);     % Number of cells close to band line
                0061 for ij = 1:6*nc*nc                % Loop over all cells
                0062     del=(yc(ij)-ylat(1))/dy;  % Latitude difference from bottom
                0063     jz=1+floor(del);              % Number of zonal lines away (round up)
                0064     del=rem(del,1);               % Fracional distance from upper line
                0065     if jz < 1
                0066         n = npzav(jz+1) + 1;   % Contribution from cell NORTH of line
                0067         ijzav(jz+1,n) = ij;
                0068         alzav(jz+1,n) = 1;     % Weight = 1 because all area accounted for
6b4f212f67 Jean*0069         npzav(jz+1) = n;
b3d495b63f Dani*0070     elseif jz >= ny
                0071         n = npzav(jz) + 1;     % Contribution from cell NORTH of line
                0072         ijzav(jz,n) = ij;
                0073         alzav(jz,n) = 1;       % Weight = 1 because all area accounted for
                0074         npzav(jz) = n;
                0075     else
                0076         n = npzav(jz) + 1;     % Contribution from cell SOUTH of line
                0077         ijzav(jz,n) = ij;
                0078         alzav(jz,n) = 1 - del;
                0079         npzav(jz) = n;
                0080         n = npzav(jz+1) + 1;   % Contribution from cell NORTH of line
                0081         ijzav(jz+1,n) = ij;
                0082         alzav(jz+1,n) = del;
                0083         npzav(jz+1) = n;
                0084     end
                0085 end
                0086 [NbMx,jM] = max(npzav);  % Reduce size
                0087 ijzav = ijzav(:,1:NbMx);
                0088 alzav = alzav(:,1:NbMx);
                0089 
                0090 mskC = ceil(hc); % Cell centered mask:  1 = any land, 0 = no land
                0091 
                0092 % Basin stuff:
                0093 % if nBas > 0
                0094 %     % standard 3. Sector definition:
                0095 %     % mskB=rdda([rac,'maskC_bas.bin'],[6*nc*nc nBas],1,'real*4','b');
                0096 %     % with Mediter in Indian Ocean Sector :
                0097 %     mskB = rdda([rac,'maskC_MdI.bin'],[6*nc*nc nBas],1,'real*4','b');
                0098 % elseif nBas < 0
                0099 %     landFrc = rdda([rac,'landFrc_cs32.zero.bin'],[6*nc*nc 1],1,'real*8','b');
                0100 %     mskB = zeros(6*nc*nc,abs(nBas));
                0101 %     mskB(:,1) = landFrc;
                0102 %     if nBas == -2, mskB(:,2) = 1 - landFrc; end
                0103 % end
                0104 
                0105 % Basin stuff:
                0106 if nBas < 0, mskzon = zeros(ny,1+abs(nBas));
                0107 else,        mskzon = zeros(ny,nr,1+abs(nBas)); end
                0108 for nb = 1:1+abs(nBas)
                0109     if nb == 1, vv1=ar; else vv1=ar.*mskB(:,nb-1); end
                0110     if nBas < 0,
                0111         var=vv1;
                0112         for j=1:ny,
                0113             ijLoc=ijzav(j,1:npzav(j));
                0114             vvLoc=alzav(j,1:npzav(j))';
                0115             mskzon(j,nb)=sum(vvLoc.*var(ijLoc));
                0116         end
                0117     else
                0118         for k=1:nr,
6b4f212f67 Jean*0119             var=vv1.*hc(:,k);
b3d495b63f Dani*0120             for j=1:ny,
                0121                 ijLoc=ijzav(j,1:npzav(j));
                0122                 vvLoc=alzav(j,1:npzav(j))';
                0123                 mskzon(j,k,nb)=sum(vvLoc.*var(ijLoc));
                0124             end
                0125         end
                0126     end
                0127 end
                0128 
                0129 % Area associated with zonal lines:
                0130 areazon=zeros(ny,1);
                0131 for j=1:ny,
                0132     ijLoc = ijzav(j,1:npzav(j));
                0133     vvLoc = alzav(j,1:npzav(j))';
                0134     areazon(j) = sum(vvLoc.*ar(ijLoc));
                0135 end
                0136 
                0137 % Compute zonal average:
                0138 fldzon = zeros(ny,nr,1+abs(nBas),nt);
                0139 for it = 1:nt,
f7a0cd83c0 Jean*0140     fld1t = fld(:,:,it);
b3d495b63f Dani*0141     for nb = 1:1+abs(nBas),
                0142         if nb == 1, vv1 = ar;
                0143         else        vv1 = ar.*mskB(:,nb-1); end
                0144         for k = 1:nr,
                0145             if nBas < 0, mskLoc=mskzon(:,nb);
                0146             else         mskLoc=mskzon(:,k,nb); end
                0147             var = vv1.*hc(:,k);
                0148             var = var.*fld1t(:,k);
                0149             for j = 1:ny
                0150                 if mskLoc(j) > frcZmn*areazon(j),
                0151                     ijLoc=ijzav(j,1:npzav(j));
                0152                     vvLoc=alzav(j,1:npzav(j))';
                0153                     fldzon(j,k,nb,it)=sum(vvLoc.*var(ijLoc))/mskLoc(j);
                0154                 else
                0155                     fldzon(j,k,nb,it)=NaN;
                0156                 end
                0157             end
                0158         end
                0159     end
                0160 end
f7a0cd83c0 Jean*0161 if length(dims) > nDim,
                0162   fldzon=reshape(fldzon,[ny nr 1+abs(nBas) dims(nDim:end)]);
                0163 end
                0164 fldzon = squeeze(fldzon);