Back to home page

MITgcm

 
 

    


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

view on githubraw file Latest commit 4cf7d6e4 on 2006-06-29 18:52:07 UTC
d43e8328b9 Dani*0001 function HT = calcHeatTransFluxes(varargin);
32ec7e18d0 Dani*0002 
d43e8328b9 Dani*0003 % HT = calcHeatTransFluxes(od,ad,sd,og,ag,time,blkFile,[optional]);
                0004 % HT = calcHeatTransFluxes(od,ad,sd,og,ag,time,blkFile,'grav',9.81);
32ec7e18d0 Dani*0005 %
                0006 % Input:
                0007 %   The incoming data must be in a structured array format (which is the
d43e8328b9 Dani*0008 %   format that comes from rdmnc) having the following fields:
32ec7e18d0 Dani*0009 %       od  [Ocean tave data]  T,Ttave
                0010 %       ad  [Atmos tave data]  T,Ttave
                0011 %       sd  [Aim tave data  ]  T,TSRtave,OLRtave,SSRtave,SLRtave,
d43e8328b9 Dani*0012 %                              EVAPtave,SHFtave,EnFxPrtave
32ec7e18d0 Dani*0013 %       og  [Ocean grid data]  drF,HFacC,rA
                0014 %       ag  [Atmos grid data]  drF,HFacC
d43e8328b9 Dani*0015 %   Other input parameters:
                0016 %       time     (vec)  Time levels to analyze ([] for all, miminum 3)
                0017 %       blkFile  (str)  Broken line file (eg 'isoLat_cs32_59.mat')
                0018 %   Optional parameters:
                0019 %       'grav'   (num, default 9.81)  Acceleration due to gravity
                0020 %       'LhVap'  (num, default 2501)  Latent heat of vaporization
                0021 %       'CpO'    (num, default 3994)  Specific heat capacity of water
                0022 %       'RhoO'   (num, default 1035)  Density of sea water
                0023 %       'CpA'    (num, default 1004)  Specific heat capacity of water
32ec7e18d0 Dani*0024 %
                0025 % Output:
                0026 %   HT is a structured array with the oceanic, atmpspheric, and total heat
                0027 %   transport at time(2:end-1) in PW, the calculated adjustments, heat
                0028 %   content (and its change) in the bands, and appropriate axis
                0029 %   information.
                0030 %
d43e8328b9 Dani*0031 % Description:
                0032 %   Calculate heat transport from fluxes. Using a heat content budget
                0033 %   equation that equates the change in heat content of a zonal band with
                0034 %   the fluxes in and out of the top and bottom, find the poleward heat
                0035 %   transport by integrating from the north pole (HT = 0) southward.  The
                0036 %   adjustment to the flux fields required for the heat transport at the
                0037 %   south pole to be 0 is also tabulated.  In the atmosphere this
                0038 %   adjustment is associated with the frictional damping not coded to
                0039 %   increase the temperature.
                0040 % 
                0041 %   This function is built to be used with cubed-sphere output from the
                0042 %   Aim-ocean coupled model of the MITgcm.  The zonal bands are defined by
                0043 %   a set of broken lines, the information for which is contain in the
                0044 %   broken line file "blkFile".
                0045 %
                0046 % Original Author:  Daniel Enderton
                0047 %
32ec7e18d0 Dani*0048 % Usage:
                0049 % 
                0050 %   >> og = rdmnc('/GridOcn/grid.*');
                0051 %   >> ag = rdmnc('/GridAtm/grid.*');
                0052 %   >> od = rdmnc('/DataOcn/tave.*');
                0053 %   >> ad = rdmnc('/DataAtm/tave.*');
                0054 %   >> sd = rdmnc('/DataAtm/aim_tave.*');
                0055 %   
                0056 %   >> LhVap = 2500;
                0057 %   >> aHeat = 1004./9.81;  % aCp/g
                0058 %   >> oHeat = 3994.*1035;  % oCp*oRho
                0059 %   
                0060 %   >> HT = CalcHT_Fluxes(od,ad,sd,og,ag,[],LhVap,aHeat,oHeat,blkFile)
                0061 %
                0062 %   >> plot(HT.ylatHT,HT.HTocn(:,1),'g',...
                0063 %           HT.ylatHT,HT.HTatm(:,1),'b',...
                0064 %           HT.ylatHT,HT.HTtot(:,1),'r'); grid on;
                0065 
4cf7d6e47a Dani*0066 StorageAtm = 1;
                0067 StorageOcn = 1;
                0068 
d43e8328b9 Dani*0069 % Default constants (can be overriden).
                0070 LhVap = 2501;
                0071 grav = 9.81;
                0072 CpO = 3994;
                0073 RhoO = 1035;
                0074 CpA = 1004;
                0075 
                0076 % Read input parameters.
                0077 od = varargin{1};
                0078 ad = varargin{2};
                0079 sd = varargin{3};
                0080 og = varargin{4};
                0081 ag = varargin{5};
                0082 time = varargin{6};
                0083 blkFile = varargin{7};
                0084 for ii = 8:2:length(varargin)
                0085     temp = varargin{ii+1}; eval([varargin{ii},' = temp;']);
                0086 end
                0087 
                0088 aHeat = CpA./grav;
                0089 oHeat = RhoO.*CpO;
                0090 
32ec7e18d0 Dani*0091 
                0092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                0093 %                     Prepare / reform  incoming data                     %
                0094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                0095 
                0096 % Determine time indecies.
                0097 if isequal(od.T,ad.T) & isequal(od.T,sd.T)
                0098     if isempty(time), time = od.T; i_time = 1:length(time);  
                0099     else [dump,i_time] = ismember(time,od.T); end
                0100 else
                0101     error('Time axes must match for ocean, atmospheric, and aim data!');
                0102 end
                0103 
                0104 % Grid information.
                0105 nt = length(time);
                0106 nc = size(og.HFacC,2);
                0107 onr = size(og.HFacC,3);
                0108 anr = size(ag.HFacC,3);
                0109 
                0110 odrf = og.drF;
                0111 adrf = ag.drF;
                0112 ac  = reshape(og.rA ,[6*nc*nc,1]);
                0113 ohc = reshape(og.HFacC(1:6*nc,1:nc,1:onr),[6*nc*nc,onr]);
                0114 ahc = reshape(ag.HFacC(1:6*nc,1:nc,1:anr),[6*nc*nc,anr]);
                0115 
                0116 % Temperature fields.
4cf7d6e47a Dani*0117 if StorageOcn
                0118     ot = reshape(od.Ttave(1:6*nc,1:nc,1:onr,i_time),[6*nc*nc,onr,nt]);
                0119 end
                0120 if StorageAtm
                0121     at = reshape(ad.Ttave(1:6*nc,1:nc,1:anr,i_time),[6*nc*nc,anr,nt]);
                0122 end
32ec7e18d0 Dani*0123 
                0124 % Aim fields.
                0125 toaSW  = reshape(   sd.TSRtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0126 toaLW  = reshape(   sd.OLRtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0127 srfSW  = reshape(   sd.SSRtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0128 srfLW  = reshape(   sd.SLRtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0129 srfEvp = reshape(  sd.EVAPtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0130 srfSH  = reshape(   sd.SHFtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0131 srfEFP = reshape(sd.EnFxPrtave(1:6*nc,1:nc,i_time),[6*nc*nc,nt]);
                0132 
                0133 % Load broken line information.  Determine latitude axis of a broken line
                0134 % by the mean of the latitude of the edges along the broken line.  These
                0135 % are the latitude coordinates for the poleward heat transport calculations
                0136 % and the surface flux / heat contents values are the mean between two
                0137 % broken lines.
                0138 load(blkFile);
                0139 ydim=length(bkl_Ylat);
                0140 YlatAv=sum(bkl_Ysg,1)./(1+bkl_Npts');
                0141 ylatHT = [-90,YlatAv,90];
                0142 ylatSF = ( ylatHT(2:ydim+2) + ylatHT(1:ydim+1) )./2;
                0143 
                0144 
                0145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                0146 %                     Make heat transport calculations                    %
                0147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                0148 
                0149 % Top of atmosphere and surface fluxes.
                0150 Ft = toaSW-toaLW;
fbb955f500 Dani*0151 Fs = srfSW-srfLW-LhVap.*srfEvp-srfSH+srfEFP;
32ec7e18d0 Dani*0152 
                0153 % Loop over bands and calculate (per band) (1) surface area, (2) top of
                0154 % atmpsphere and surface fluxes, and (3) oceanic and atmospheric heat
                0155 % content.  There are nbkl broken lines and nbkl+1 bands between broken
                0156 % lines.  The variable "bkl_Zon" gives the band number (nbkl+1 total) for a
                0157 % given index between 0 and nbkl, that is, nbkl+1 total zones.
                0158 AreaZon = NaN.*zeros([ydim+1,1]);
                0159 Ft_Zon = NaN.*zeros([ydim+1,nt]);
                0160 Fs_Zon = NaN.*zeros([ydim+1,nt]);
                0161 HA = NaN.*zeros([ydim+1,nt]);
                0162 HO = NaN.*zeros([ydim+1,nt]);
                0163 dHAdt = NaN.*zeros([ydim+1,nt-2]);
                0164 dHOdt = NaN.*zeros([ydim+1,nt-2]);
                0165 for izon = 1:ydim+1
                0166     ii = find(bkl_Zon == izon-1);
                0167     AreaZon(izon,1) = sum(ac(ii));
                0168     for it = 1:length(time)
                0169         % ??? HFacC for surface fluxes? How to deal with runoff / land?
                0170         Ft_Zon(izon,it) = sum(Ft(ii,it).*ac(ii));
                0171         Fs_Zon(izon,it) = sum(Fs(ii,it).*ac(ii));
4cf7d6e47a Dani*0172         if StorageAtm
                0173             HA(izon,it) = sum(aHeat.*((at(ii,:,it).*ahc(ii,:))*adrf).*ac(ii));
                0174         end
32ec7e18d0 Dani*0175         HO(izon,it) = sum(oHeat.*((ot(ii,:,it).*ohc(ii,:))*odrf).*ac(ii));
                0176     end
                0177 end
                0178 
                0179 % Calculate change in heat content (this means that the heat transport is
                0180 % calculated for time(2:end-1) only, hence subsetting fluxes as well).
                0181 for it = 2:length(time)-1
4cf7d6e47a Dani*0182     if StorageAtm
                0183         dHAdt(:,it-1) = (HA(:,it+1)-HA(:,it-1))./(time(it+1)-time(it-1));
                0184     end
32ec7e18d0 Dani*0185     dHOdt(:,it-1) = (HO(:,it+1)-HO(:,it-1))./(time(it+1)-time(it-1));
                0186 end
                0187 Ft_Zon = Ft_Zon(:,2:end-1);
                0188 Fs_Zon = Fs_Zon(:,2:end-1);
                0189 
                0190 % Compute offsets.
                0191 % ??? However small, why is there an oceanic offset?
                0192 ocnadj_Zon = Fs_Zon - dHOdt;
                0193 atmadj_Zon = Ft_Zon - Fs_Zon - dHAdt;
                0194 for it = 1:size(ocnadj_Zon,2)
                0195     ocnadj(it) = sum(ocnadj_Zon(:,it))./sum(AreaZon);
                0196     atmadj(it) = sum(atmadj_Zon(:,it))./sum(AreaZon);
                0197 end
                0198 
                0199 % Using a heat content budget equation that equates the change in heat
                0200 % content of a band with the fluxes in and out of the top and bottom, find
                0201 % the poleward heat transport by integrating from the north pole (HT = 0)
                0202 % southward.  The above computed adjustment is required for the heat
                0203 % transport at the south pole to be 0.
                0204 HTocn = zeros(size(Ft_Zon)+[1,0]);
                0205 HTatm = zeros(size(Ft_Zon)+[1,0]);
                0206 for ilat = ydim+2:-1:2
                0207     HTocn(ilat-1,:) =   HTocn(ilat,:)    ...
                0208                       - Fs_Zon(ilat-1,:) ...
                0209                       + dHOdt(ilat-1,:)  ...
                0210                       + ocnadj.*AreaZon(ilat-1);
                0211     HTatm(ilat-1,:) =   HTatm(ilat,:)    ...
                0212                       - Ft_Zon(ilat-1,:) ...
                0213                       + Fs_Zon(ilat-1,:) ...
                0214                       + dHAdt(ilat-1,:)  ...
                0215                       + atmadj.*AreaZon(ilat-1);
                0216 end
                0217 HTtot = HTocn + HTatm;
                0218 
                0219 
                0220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                0221 %                             Assign outputs                              %
                0222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
                0223 
                0224 HT.time = time(2:end-1);
                0225 HT.ylatSF = ylatSF;
                0226 HT.ylatHT = ylatHT;
                0227 HT.AreaZon = AreaZon;
                0228 HT.Fs = Fs_Zon;
                0229 HT.Ft = Ft_Zon;
                0230 HT.HTtot = HTtot*1e-15;
                0231 HT.HTocn = HTocn*1e-15;
                0232 HT.HTatm = HTatm*1e-15;
                0233 HT.HO = HO(:,2:end-1);
                0234 HT.HA = HA(:,2:end-1);
                0235 HT.dHOdt = dHOdt;
                0236 HT.dHAdt = dHAdt;
                0237 HT.ocnadj = ocnadj;
                0238 HT.atmadj = atmadj;