Home > fvcom_prepro > get_NAE2_forcing.m

get_NAE2_forcing

PURPOSE ^

Get the required parameters from NAE2 data to force FVCOM (through

SYNOPSIS ^

function Mobj = get_NAE2_forcing(Mobj, inputConf)

DESCRIPTION ^

 Get the required parameters from NAE2 data to force FVCOM (through
 Casename_wnd.nc).
 
 Mobj = get_NAE2_forcing(Mobj, inputConf)
 
 DESCRIPTION:
   Extract meteorological forcing data from Met Office NAE2 data to create
   an FVCOM forcing file.
 
 INPUT: 
   Mobj - MATLAB mesh object
 
 OUTPUT:
   Mobj - MATLAB mesh object containing meteorological forcing data for
   FVCOM, interpolated onto an unstructured grid.
 
 The parameters which can be obtained from the AMM/S12 model output are:
     - u wind component (uwnd)
     - v wind component (vwnd)
     - Sea level pressure (slp)
 
 In addition to these, the momentum flux is calculated from wind data.
 KJT note: took this out from Pierre's version. Implement this?

 Algorithm is based on Phil Hall's 'produce_netcdf_input_data.py' script,
 adapted to handle NAE2 data by Karen Thurston
 ('produce_netcdf_input_dataR.py'. This Python script is, in turn, based
 on Jenny Brown's 'MET_INT.f' Fortran script.
 
 Author(s)
   Karen Thurston (National Oceanography Centre Liverpool)
 
 Revision history:
   2012-12-05 First version
 
==========================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function Mobj = get_NAE2_forcing(Mobj, inputConf)
0002 % Get the required parameters from NAE2 data to force FVCOM (through
0003 % Casename_wnd.nc).
0004 %
0005 % Mobj = get_NAE2_forcing(Mobj, inputConf)
0006 %
0007 % DESCRIPTION:
0008 %   Extract meteorological forcing data from Met Office NAE2 data to create
0009 %   an FVCOM forcing file.
0010 %
0011 % INPUT:
0012 %   Mobj - MATLAB mesh object
0013 %
0014 % OUTPUT:
0015 %   Mobj - MATLAB mesh object containing meteorological forcing data for
0016 %   FVCOM, interpolated onto an unstructured grid.
0017 %
0018 % The parameters which can be obtained from the AMM/S12 model output are:
0019 %     - u wind component (uwnd)
0020 %     - v wind component (vwnd)
0021 %     - Sea level pressure (slp)
0022 %
0023 % In addition to these, the momentum flux is calculated from wind data.
0024 % KJT note: took this out from Pierre's version. Implement this?
0025 %
0026 % Algorithm is based on Phil Hall's 'produce_netcdf_input_data.py' script,
0027 % adapted to handle NAE2 data by Karen Thurston
0028 % ('produce_netcdf_input_dataR.py'. This Python script is, in turn, based
0029 % on Jenny Brown's 'MET_INT.f' Fortran script.
0030 %
0031 % Author(s)
0032 %   Karen Thurston (National Oceanography Centre Liverpool)
0033 %
0034 % Revision history:
0035 %   2012-12-05 First version
0036 %
0037 %==========================================================================
0038 
0039 subname = 'get_NAE2_forcing';
0040 
0041 global ftbverbose;
0042 if(ftbverbose);
0043   fprintf('\n')
0044   fprintf(['begin : ' subname '\n'])
0045 end
0046 
0047 %% Where are the files we'll need?
0048 if isunix       % Unix?
0049     metfname = ['/bank/jane/met/',datestr(inputConf.startDate,'YYYY'),...
0050         '/',lower(datestr(inputConf.startDate,'mmmYY')),'nae10R.dat'];
0051     comprfname = '/login/jane/NAE2/metintco.cs3x.nae2.compress.2';
0052     setupfname = '/work/jane/cs3x/prep/setupcs3xSGIl.uda';
0053 %     elevfname = ['/bank/jane/cs3x/sarray.uda.',...
0054 %         datestr(inputConf.startDate,'YYYY')];
0055 elseif ispc     % Or Windows?
0056     metfname = ['\\store\bank\jane\met\',datestr(inputConf.startDate,'YYYY'),...
0057         '\',lower(datestr(inputConf.startDate,'mmmYY')),'nae10R.dat'];
0058     comprfname = '\\store\kthurs\from_Jane\metintco.cs3x.nae2.compress.2';
0059     setupfname = '\\store\work\jane\cs3x\prep\setupcs3xSGIl.uda';
0060 %     elevfname = ['\\store\bank\jane\cs3x\sarray.uda.',...
0061 %         datestr(inputConf.startDate,'YYYY')];
0062 end
0063 
0064 % Define the parameters of the cs3x grid
0065 cs3x_nx = 198;   % number of grid cells in the x direction
0066 cs3x_ny = 207;   % number of grid cells in the y direction
0067 cs3x_lonstart = -19-(5/6); % longitude of the bottom left corner
0068 cs3x_latstart = 40+(1/9);   % latitude of the bottom left corner
0069 cs3x_loninc = 1/6;   % grid resolution in the x direction (degrees)
0070 cs3x_latinc = 1/9;   % grid resolution in the y direction (degrees)
0071 cs3x_lonfin = cs3x_lonstart+(cs3x_loninc*(cs3x_nx-1));  % longitude of the top right corner
0072 cs3x_latfin = cs3x_latstart+(cs3x_latinc*(cs3x_ny-1));  % latitude of the top right corner
0073 cs3x_lon = cs3x_lonstart:cs3x_loninc:cs3x_lonfin;   % array of grid lon points
0074 cs3x_lat = cs3x_latstart:cs3x_latinc:cs3x_latfin;   % array of grid lat points
0075 % cs3x_area = cs3x_loninc*cs3x_latinc;
0076 
0077 % Sanity check. Does our FVCOM grid fit within the cs3x domain?
0078 if min(Mobj.lon) < cs3x_lonstart || max(Mobj.lon) > cs3x_lonfin || ...
0079         min(Mobj.lat) < cs3x_latstart || max(Mobj.lat) > cs3x_latfin
0080     error('Your FVCOM grid is bigger than the available cs3x grid. Choose another met forcing option or crop your FVCOM grid.')
0081 end
0082 
0083 % Open the met compression info file
0084 fid = fopen(comprfname);
0085 tline = fgets(fid);
0086 count=0;
0087 while ischar(tline)
0088     count=count+1;
0089     compr_info{count}=tline;
0090     tline = fgets(fid);
0091 end
0092 fclose(fid);
0093 
0094 % This section reads info from the met data compression file. The first
0095 % line is a set of constants (NCCP, NRRP, NCCW, NRRW, NMOD/NTOTI).
0096 
0097 % Read the first line of the compression info file
0098 temp = sscanf(char(compr_info{1}),'%u');
0099 NCCP = temp(1);     % Number of columns in the pressure data
0100 NRRP = temp(2);     % Number of rows in the pressure data
0101 NCCW = temp(3);     % Number of columns in the wind data
0102 NRRW = temp(4);     % Number of rows in the wind data
0103 NTOTI = temp(5);    % Also referred to as 'NMOD'
0104 
0105 % Initialise compr_array
0106 compr_array = nan(10,length(compr_info)-1);
0107 
0108 for i=2:length(compr_info)
0109     temp = sscanf(char(compr_info{i}),'%8f');
0110     compr_array(:,i-1) = temp;
0111 end
0112 
0113 nelf = max(compr_array(1:4*NTOTI))+1;   % No idea what this is for
0114 
0115 % Index of specified corner of source gridbox (pressure)
0116 IBLP = compr_array(1:NTOTI)-1;    % Bottom left point
0117 IBRP = compr_array(NTOTI+1:2*NTOTI)-1;  % Bottom right point
0118 
0119 % Index of specified corner of source gridbox (wind)
0120 IBLW = compr_array(2*NTOTI+1:3*NTOTI)-1;    % Bottom left point
0121 IBRW = compr_array(3*NTOTI+1:4*NTOTI)-1;    % Bottom right point
0122 
0123 % Weight applied to value at specified corner of source gridbox (pressure)
0124 WTRP = compr_array(4*NTOTI+1:5*NTOTI);  % Top right point
0125 WBRP = compr_array(5*NTOTI+1:6*NTOTI);  % Bottom right point
0126 WTLP = compr_array(6*NTOTI+1:7*NTOTI);  % Top left point
0127 WBLP = compr_array(7*NTOTI+1:8*NTOTI);  % Bottom left point
0128 
0129 % Weight applied to value at specified corner of source gridbox (wind)
0130 WTRW = compr_array(8*NTOTI+1:9*NTOTI);  % Top right point
0131 WBRW = compr_array(9*NTOTI+1:10*NTOTI);  % Bottom right point
0132 WTLW = compr_array(10*NTOTI+1:11*NTOTI);  % Top left point
0133 WBLW = compr_array(11*NTOTI+1:12*NTOTI);  % Bottom left point
0134 
0135 % Coefficients to rotate winds onto equatorial lat/lon grid from ELF model
0136 COEFF1 = compr_array(12*NTOTI+1:13*NTOTI);
0137 COEFF2 = compr_array(13*NTOTI+1:14*NTOTI); 
0138 
0139 clear compr_info compr_array
0140 
0141 % This section reads cs3x model control data from the setup file.
0142 fid=fopen(setupfname,'r','b');
0143 temp=fread(fid,inf,'*int32','b');
0144 fclose(fid);
0145 
0146 NRR = temp(2);  % Number of rows in full rectangle
0147 NCC = temp(3);  % Number of columns in full rectangle
0148 ITOT = temp(4); % Total number of points in compact arrays
0149 IINZ = temp(5); % Number of internal Z-points
0150 
0151 NTRNS = temp(8:NRR+7);  % Transformation matrix for compact addressing
0152 NTRNT = temp(NRR+10:2*NRR+9);   % Transformation matrix for compact addressing
0153 NSUM = temp(2*NRR+12:3*NRR+11); % Transformation matrix for compact addressing
0154 
0155 clear temp
0156 
0157 % The array section numbers (as in MET_INT.F).
0158 hw0 = 1;
0159 hw1 = 326;
0160 hw2 = 100;
0161 hw3 = 521;
0162 hw4 = 600;
0163 hw5 = (hw1-hw0)*(hw3-hw2);
0164 
0165 % As far as I can tell, this section generates the cross-indexing between
0166 % the met data and the cs3x grid.
0167 ELFI = zeros(hw5,1);
0168 FIEJ = zeros(hw5,1);
0169 
0170 count = 1;
0171 j = 1;
0172 
0173 for iy = hw0:(hw1-1)
0174     for ix = hw2:(hw3-1)
0175         i = ix+iy*hw4;
0176         j = j+1;
0177         ELFI(count) = i-1;
0178         FIEJ(count) = j-1;
0179         count = count+1;
0180     end
0181 end
0182 
0183 if max(ELFI)+1 > nelf
0184     nelf = max(ELFI)+1;
0185 end
0186 
0187 if max(FIEJ)+1 > nelf
0188     nelf = max(FIEJ)+1;
0189 end
0190 
0191 %%
0192 % Create an array of daily timesteps, ensuring the output time series is
0193 % at least as long as the FVCOM model run time.
0194 timesteps = datevec(datenum(inputConf.startDate):datenum(inputConf.endDate)+1);
0195 
0196 % Find the number of months in the timeseries
0197 [months,ia]=unique(timesteps(:,1:2),'rows');
0198 
0199 for i=1:size(months,1)
0200     % Where are the met data files?
0201     if isunix       % Unix?
0202         metfname = ['/bank/jane/met/',num2str(timesteps(ia(i),1)),...
0203             '/',lower(datestr(timesteps(ia(i),:),'mmmYY')),'nae10R.dat'];
0204     elseif ispc     % Or Windows?
0205         metfname = ['\\store\bank\jane\met\',num2str(timesteps(ia(i),1)),...
0206             '\',lower(datestr(timesteps(ia(i),:),'mmmYY')),'nae10R.dat'];
0207     end
0208     
0209     PASTIT = false;
0210     kline = 0;
0211     
0212     % Open the met file
0213     fid = fopen(metfname);
0214     
0215     % calculate the number of lines per data segment
0216     I = fgets(fid);
0217     m1 = sscanf(I,'%u');
0218     data_seg = ceil(m1(1)/m1(2));
0219     
0220     frewind(fid);
0221     
0222     if i==1
0223         % Initialise the met data array
0224         met_temp = cell(1);
0225     end
0226     
0227     % Get met data from the met file and write to temporary cell array
0228     while PASTIT == false
0229         kline = kline + 2;
0230         I = fgets(fid);
0231         if I==-1
0232             % break the loop, it's the EOF
0233             break
0234         end
0235         J = fgets(fid);
0236         if J==-1
0237             % break the loop, it's the EOF
0238             break
0239         end
0240         
0241         % find the date in the met file
0242         datem = sscanf(J,'%u');
0243         datem = datenum(datem(4),datem(3),datem(2),datem(1),0,0);
0244         
0245         % Compare met file date with inputConf.startDate (is it bigger?) and
0246         % with inputConf.endDate (is it smaller?) If yes and yes, then we want
0247         % this. Write data to a temporary array.
0248         if (datem >= datenum(inputConf.startDate)) && ...
0249                 (datem <= datenum(inputConf.endDate))
0250             % Initialise temp cell array
0251             temp = cell(data_seg+2,1);
0252             % write I and J
0253             temp{1} = sscanf(I,'%u');
0254             temp{2} = sscanf(J,'%u');
0255             % Get the actual data
0256             for m = 1:data_seg
0257                 I = fgetl(fid);
0258                 temp{m+2} = sscanf(I,'%10f');
0259             end
0260             met_temp{end+1}=temp;
0261             clear temp;
0262         else
0263             PASTIT = true;
0264         end
0265     end
0266     
0267     fclose(fid);
0268 end
0269 
0270 met_temp = met_temp(2:end);
0271     
0272 % Not sure what these numbers are for.
0273 JBLP = IBLP-NCCP;
0274 JBRP = IBRP-NCCP;
0275 JBLW = IBLW-NCCW;
0276 JBRW = IBRW-NCCW;
0277 
0278 elf = zeros(nelf,1);
0279 
0280 % Temporary arrays to hold pressure/u-wind/v-wind from extracted met data
0281 P2 = zeros(NTOTI,1);
0282 tmpa = zeros(NTOTI,1);
0283 tmpb = zeros(NTOTI,1);
0284 
0285 % FirstInt = true;
0286 kline = 1;
0287 
0288 % Arrays to hold the pressure/u-wind/v-wind data when interpolated to the
0289 % FVCOM grid
0290 slp = zeros(Mobj.nVerts,size(met_temp,2)/3);
0291 uwnd = zeros(Mobj.nElems,size(met_temp,2)/3);
0292 vwnd = zeros(Mobj.nElems,size(met_temp,2)/3);
0293 time = zeros(size(met_temp,2)/3,1);
0294 
0295 % Take our forcing data, translate it to the cs3x grid, then interpolate
0296 % onto the FVCOM grid.
0297 for m=0:3:size(met_temp,2)-1
0298     for ISW = 1:3
0299         kline = kline+2;
0300         ipts =  met_temp{m+ISW}{1}(1);
0301         kpts =  met_temp{m+ISW}{1}(2);
0302         
0303         % Store the date
0304         if ISW == 1
0305             time((m/3)+1) = datenum(met_temp{m+ISW}{2}(4),...
0306                 met_temp{m+ISW}{2}(3),met_temp{m+ISW}{2}(2),...
0307                 met_temp{m+ISW}{2}(1),0,0);
0308         end
0309         
0310         % Preallocate 'field' for speed
0311         field = NaN(8,data_seg);
0312         
0313         % Get the met data we're interested in
0314         for n=1:data_seg
0315             field(:,n)=met_temp{m+ISW}{n+2};
0316         end
0317         field = reshape(field,data_seg*8,1);
0318         
0319         % if the last column of data is not full, adjust for that
0320         if size(met_temp{m+ISW}{end},1)<8
0321             too_many = 8-size(met_temp{m+ISW}{end},1);
0322             field = field(1:end-too_many);
0323         end
0324         
0325         elf(ELFI)=field(FIEJ);
0326         
0327         % Interpolate the data to the sea model grid
0328         if ISW == 1
0329             P2 = (WBLP.*elf(IBLP)')+(WBRP.*elf(IBRP)')+(WTLP.*elf(JBLP)')+...
0330                 (WTRP.*elf(JBRP)');
0331         elseif ISW == 2
0332             tmpa = (WBLW.*elf(IBLW)')+(WBRW.*elf(IBRW)')+(WTLW.*elf(JBLW)')+...
0333                 (WTRW.*elf(JBRW)');
0334         elseif ISW == 3
0335             tmpb = (WBLW.*elf(IBLW)')+(WBRW.*elf(IBRW)')+(WTLW.*elf(JBLW)')+...
0336                 (WTRW.*elf(JBRW)');
0337         end
0338         
0339         kline = kline+data_seg;
0340     end
0341     
0342     % Rotate the winds to equatorial lat/lon
0343     tmpc = (COEFF1.*tmpa)+(COEFF2.*tmpb);
0344     tmpd = (COEFF1.*tmpb)-(COEFF2.*tmpa);
0345     
0346     k = 0;
0347     
0348     % Convert the data to a gridded array instead of a vector
0349     for j = 0:NRR-1
0350         I1 = NTRNT(j+1);
0351         I2 = NTRNS(j+1);
0352         for i = I1+1:I2
0353             k = k+1;
0354             PRESS(i,NRR-j) = P2(k);
0355             U10E(i,NRR-j) = tmpc(k);
0356             U10N(i,NRR-j) = tmpd(k);
0357         end
0358     end
0359     
0360     % Interpolate the pressure data onto the FVCOM grid
0361     slp(:,(m/3)+1) = interp2(cs3x_lon,cs3x_lat,PRESS',Mobj.lon,Mobj.lat);
0362     
0363     % Calculate the coordinates of the centre of each FVCOM grid element
0364     xelement = mean(Mobj.lon(Mobj.tri(:,:)),2);
0365     yelement = mean(Mobj.lat(Mobj.tri(:,:)),2);
0366     
0367     % Interpolate the wind data onto the FVCOM grid
0368     uwnd(:,(m/3)+1) = interp2(cs3x_lon,cs3x_lat,U10E',xelement,yelement);
0369     vwnd(:,(m/3)+1) = interp2(cs3x_lon,cs3x_lat,U10N',xelement,yelement);
0370 end
0371 
0372 % Convert data time to Modified Julian Day time for FVCOM
0373 time = datevec(time);
0374 MJD_time = greg2mjulian(time(:,1),time(:,2),time(:,3),time(:,4),time(:,5),...
0375     time(:,6));
0376 
0377 % Add slp, uwnd, vwnd and time to Mobj
0378 Mobj.Met.slp.node = slp;
0379 Mobj.Met.uwnd.data = uwnd;
0380 Mobj.Met.vwnd.data = vwnd;
0381 Mobj.Met.time = MJD_time;
0382 
0383 if(ftbverbose);
0384     fprintf(['end   : ' subname '\n']);
0385 end

Generated on Wed 20-Feb-2019 16:06:01 by m2html © 2005