Home > swan_scripts > ww3_to_swan_bndry.m

ww3_to_swan_bndry

PURPOSE ^

Generate SWAN boundary forcing by interpolating from WW3 output

SYNOPSIS ^

function ww3_to_swan_bndry();

DESCRIPTION ^

 Generate SWAN boundary forcing by interpolating from WW3 output

 function swan2netcdf(matfile,ncfile,basename,first_time,last_time,increment);

 DESCRIPTION:
    interpolate Hs,Tp,Dir from WW3 to a boundary forcing file for 
    unstructured swan
    this is an example file and will need to be modified for specific cases
    Note that for the unstructured SWAN you can specify separate TPAR files
    containing time series of hs,tp,dir for each node.  Also note that the nodes
    are not necessarily nodes of the SWAN mesh.  They are specified in arclength
    of the grid units from the first open boundary node (arclength 0).  SWAN
    assembles a boundary segment by piecing together the nodes marked as boundary 
    nodes in the node file (mark = 2).  This assumes somehow that the nodes are ordered
    sequentially along the boundary arc which is in fact a major assumption.

    Sample OBC section of a swan input file for the GoM domain is as follows where
    15 points are used to specify the boundary forcing while the domain in fact has 
    60 boundary points.  SWAN interpolates as necessary to force all the boundary nodes.
    The large numbers are the arclengths in meters

 BOUNDSPEC SIDE 2 CLOCKWISE VARIABLE FILE &
         0.00 'obc1.bnd' 1 &
     52704.26 'obc2.bnd' 1 &
    131926.06 'obc3.bnd' 1 &
    255117.10 'obc4.bnd' 1 &
    390381.71 'obc5.bnd' 1 &
    559989.50 'obc6.bnd' 1 &
    740759.98 'obc7.bnd' 1 &
    924330.66 'obc8.bnd' 1 &
   1104489.93 'obc9.bnd' 1 &
   1295381.43 'obc10.bnd' 1 &
   1480466.74 'obc11.bnd' 1 &
   1641071.70 'obc12.bnd' 1 &
   1750424.20 'obc13.bnd' 1 &
   1828825.67 'obc14.bnd' 1 &
   1951072.38 'obc15.bnd' 1

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function ww3_to_swan_bndry();
0002     
0003 % Generate SWAN boundary forcing by interpolating from WW3 output
0004 %
0005 % function swan2netcdf(matfile,ncfile,basename,first_time,last_time,increment);
0006 %
0007 % DESCRIPTION:
0008 %    interpolate Hs,Tp,Dir from WW3 to a boundary forcing file for
0009 %    unstructured swan
0010 %    this is an example file and will need to be modified for specific cases
0011 %    Note that for the unstructured SWAN you can specify separate TPAR files
0012 %    containing time series of hs,tp,dir for each node.  Also note that the nodes
0013 %    are not necessarily nodes of the SWAN mesh.  They are specified in arclength
0014 %    of the grid units from the first open boundary node (arclength 0).  SWAN
0015 %    assembles a boundary segment by piecing together the nodes marked as boundary
0016 %    nodes in the node file (mark = 2).  This assumes somehow that the nodes are ordered
0017 %    sequentially along the boundary arc which is in fact a major assumption.
0018 %
0019 %    Sample OBC section of a swan input file for the GoM domain is as follows where
0020 %    15 points are used to specify the boundary forcing while the domain in fact has
0021 %    60 boundary points.  SWAN interpolates as necessary to force all the boundary nodes.
0022 %    The large numbers are the arclengths in meters
0023 %
0024 % BOUNDSPEC SIDE 2 CLOCKWISE VARIABLE FILE &
0025 %         0.00 'obc1.bnd' 1 &
0026 %     52704.26 'obc2.bnd' 1 &
0027 %    131926.06 'obc3.bnd' 1 &
0028 %    255117.10 'obc4.bnd' 1 &
0029 %    390381.71 'obc5.bnd' 1 &
0030 %    559989.50 'obc6.bnd' 1 &
0031 %    740759.98 'obc7.bnd' 1 &
0032 %    924330.66 'obc8.bnd' 1 &
0033 %   1104489.93 'obc9.bnd' 1 &
0034 %   1295381.43 'obc10.bnd' 1 &
0035 %   1480466.74 'obc11.bnd' 1 &
0036 %   1641071.70 'obc12.bnd' 1 &
0037 %   1750424.20 'obc13.bnd' 1 &
0038 %   1828825.67 'obc14.bnd' 1 &
0039 %   1951072.38 'obc15.bnd' 1
0040 
0041 % INPUT
0042 %
0043 % OUTPUT:
0044 %   SWAN open boundary TPAR files obcXX.bnd
0045 %
0046 % Author(s):
0047 %    Geoff Cowles (University of Massachusetts Dartmouth)
0048 %
0049 % Revision history
0050 %
0051 %==============================================================================
0052 
0053 
0054 swan_node_file = '../gom1/gom1.node';
0055 
0056 % set year range
0057 ybeg = 2007;
0058 yend = 2007;
0059 
0060 % increment for dumping forcing:
0061 % swan does not force at nodes, just at locations along the arclength
0062 % of the boundary segment.
0063 inc = 4;
0064 
0065 % matlab output file
0066 outfile = ['swan_gom0_obc_2007' num2str(ybeg)];
0067 
0068 % datadir - location of all ww3 grib files
0069 ddir = '/Volumes/Data/Users/gcowles/Data/SCALLOP_RSA_2009/wavewatch_wna_grib/'; 
0070 
0071 % read the swan node file and grab boundary nodes
0072 [num,x,y,mark] = textread(swan_node_file,'%d %f %f %d\n','headerlines',1);
0073 obc_nodes = find(mark==2);
0074 nobc = prod(size(obc_nodes));
0075 xtmp = x(obc_nodes);
0076 ytmp = y(obc_nodes);
0077 arc = zeros(nobc,1); 
0078 for i=2:nobc
0079   arc(i) = arc(i-1) + sqrt( (xtmp(i)-xtmp(i-1))^2 + (ytmp(i)-ytmp(i-1))^2); 
0080 end;  
0081 
0082 % shift to discrete locations
0083 pts = 1:inc:nobc;
0084 pts(end) = nobc;
0085 xobc = xtmp(pts); 
0086 yobc = ytmp(pts); 
0087 aobc = arc(pts); 
0088 ndisc = prod(size(xobc));
0089 
0090 
0091 % inverse project discrete locations to lon/lat
0092 %junk = 0;
0093 fid = fopen('in.dat','w');
0094 for i=1:ndisc  
0095   fprintf(fid,'%f %f\n',xobc(i),yobc(i));
0096 end;
0097 fclose(fid);
0098 system('./project_cmd');
0099 fid = fopen('out.dat','r');
0100 for i=1:ndisc  
0101   C = textscan(fid, '%f %f', 1);
0102   lon_obc(i) = C{1};
0103   lat_obc(i) = C{2};
0104 end;
0105 fclose(fid);
0106 fprintf('finished: projecting to lon/lat\n')
0107 
0108 
0109 %---------------------------------------------------------
0110 % read a sample grib file and reconstruct WW3 grid => xg,yg
0111 %---------------------------------------------------------
0112 fname = [ddir 'wna.hs.200711.grb'];
0113 grib_struct=read_grib(fname,[1],'ScreenDiag',0);
0114 xmin = grib_struct.gds.Lo1;
0115 xmax = grib_struct.gds.Lo2;
0116 ymin = grib_struct.gds.La1;
0117 ymax = grib_struct.gds.La2;
0118 il = grib_struct.gds.Ni;
0119 jl = grib_struct.gds.Nj;
0120 dlon = (xmax-xmin)/(il-1);
0121 dlat = (ymax-ymin)/(jl-1);
0122 lon = xmin:dlon:xmax;
0123 lon = lon-360;
0124 lat = ymin:dlat:ymax;  
0125 [xg,yg] = meshgrid(lon,lat);
0126 
0127 
0128 %---------------------------------------------------------
0129 % extract Hs,Tp,Dir from each WWIII file
0130 %---------------------------------------------------------
0131 ndays      = [31,28,31,30,31,30,31,31,30,31,30,31];
0132 ndays_leap = [31,29,31,30,31,30,31,31,30,31,30,31];
0133 
0134 % loop over data and count number of days of data to preallocate
0135 icnt = 0;
0136 for y=ybeg:yend  
0137 for m=1:1 %debug 12;
0138   year = int2str(y);
0139   mnth = int2str(m);
0140   if(m>9)
0141     fname = [ddir 'wna.hs.' year mnth '.grb'];  
0142   else
0143     fname = [ddir 'wna.hs.' year '0' mnth '.grb'];  
0144   end;
0145   if(exist(fname)) 
0146     fprintf('file %s exists\n',fname)
0147     if(mod(y,4)==0) %leap year (note 2OOO was a leap year, 1900, 2100 are not)
0148       icnt = icnt + 8*ndays_leap(m);
0149     else
0150       icnt = icnt + 8*ndays(m);
0151     end; 
0152   else 
0153     fprintf('file %s does not exist\n',fname)
0154   end;
0155 end;
0156 end;
0157 fprintf('number of frames in year %d\n',icnt);
0158 
0159 % preallocate arrays
0160 hs = zeros(ndisc,icnt);
0161 tp = zeros(ndisc,icnt);
0162 dir = zeros(ndisc,icnt);
0163 time = zeros(icnt,1);
0164 
0165 %
0166 hour = [0,3,6,9,12,15,18,21];
0167 
0168 % read data into the arrays
0169 icnt = 0;
0170 for y=ybeg:yend;
0171 for m=1:1 %debug 12;
0172   year = int2str(y);
0173   mnth = int2str(m);
0174   if(m>9)
0175     hsname = [ddir 'wna.hs.' year mnth '.grb'];
0176     tpname = [ddir 'wna.tp.' year mnth '.grb'];
0177     drname = [ddir 'wna.dp.' year mnth '.grb'];
0178   else
0179     hsname = [ddir 'wna.hs.' year '0' mnth '.grb'];
0180     tpname = [ddir 'wna.tp.' year '0' mnth '.grb'];
0181     drname = [ddir 'wna.dp.' year '0' mnth '.grb'];
0182   end;
0183   if(exist(hsname)) 
0184     fprintf('processing year %d month %d\n',y,m);
0185     if(mod(y,4)==0) %leap year
0186        
0187        nd = ndays_leap(m);
0188     else
0189        nd = ndays(m);
0190     end;
0191   
0192     n = 0;
0193     for d=1:nd  %day loop
0194     for l=1:8   %hour loop
0195 
0196       n = n + 1;
0197       icnt = icnt + 1;
0198   
0199       % read hs and interpolate onto boundary points
0200       grib_struct=read_grib(hsname,[n],'ScreenDiag',0);
0201       var = reshape(grib_struct.fltarray,il,jl);
0202       hs(:,icnt) = interp2(xg,yg,var',lon_obc,lat_obc,'linear');
0203   
0204       %read tp from grib and interpolate onto boundary points
0205       grib_struct=read_grib(tpname,[n],'ScreenDiag',0);
0206       var = reshape(grib_struct.fltarray,il,jl);
0207       tp(:,icnt) = interp2(xg,yg,var',lon_obc,lat_obc,'linear');
0208 
0209       %read dir from grib and interpolate onto boundary points
0210       grib_struct=read_grib(drname,[n],'ScreenDiag',0);
0211       var = reshape(grib_struct.fltarray,il,jl);
0212       dir(:,icnt) = interp2(xg,yg,var',lon_obc,lat_obc,'linear');
0213 
0214       fprintf('processing time %s\n',grib_struct.stime);
0215   
0216       time(icnt) = greg2julian(y,m,d,hour(l),0,0);
0217       if(icnt>1);
0218       fprintf('processing frame %d %d %d %d %d %f\n',n,y,m,d,hour(l),time(icnt)-time(icnt-1));
0219        end;
0220     end;
0221     end;
0222   end; %file exists
0223   
0224 end;
0225 end;
0226 
0227 % process data to fix boundaries where GOM open boundary is considered land in WaveWatch
0228 for i=1:icnt
0229   hs(1:2,i) = hs(3,i);
0230   hs(end-1:end,i) = hs(end-2,i);
0231   tp(1:2,i) = tp(3,i);
0232   tp(end-1:end,i) = tp(end-2,i);
0233   dir(1:2,i) = dir(3,i);
0234   dir(end-1:end,i) = dir(end-2,i);
0235 end;
0236 
0237 % find points with NaN type data and use data from nearest neighbor
0238 pts = 1:ndisc;
0239 ney = pts + 1;
0240 ney2 = pts - 1;
0241 ney(end) = pts(end)-1;
0242 ney2(1)   = pts(1)+1;
0243 obcs = pts;
0244 
0245 for j=1:15
0246 for i=1:icnt
0247   pts = find(hs(:,i)>99); hs(pts,i) = hs(ney(pts),i);
0248   pts = find(hs(:,i)>99); hs(pts,i) = hs(ney2(pts),i);
0249   pts = find(tp(:,i)>99); tp(pts,i) = tp(ney(pts),i);
0250   pts = find(tp(:,i)>99); tp(pts,i) = tp(ney2(pts),i);
0251   pts = find(dir(:,i)>1000); dir(pts,i) = dir(ney(pts),i);
0252   pts = find(dir(:,i)>1000); dir(pts,i) = dir(ney2(pts),i);
0253 end;  
0254 end;  
0255 
0256 % dump data to a matlab object and save
0257 info = 'ww3 data interpolated onto gom0 open boundary';
0258 info2 = 'time in julian day';
0259 save(outfile,'info','info2','time','hs','tp','dir','lon_obc','lat_obc');  
0260 
0261 figure
0262 subplot(3,1,1)
0263 for i=1:ndisc 
0264 plot(hs(i,:)); hold on;
0265 end;
0266 subplot(3,1,2)
0267 for i=1:ndisc
0268 plot(tp(i,:)); hold on;
0269 end;
0270 subplot(3,1,3)
0271 for i=1:ndisc
0272 plot(dir(i,:)); hold on;
0273 end;
0274 
0275 %dump to separate swan forcing files
0276 for i=1:ndisc
0277   fname = ['obc' num2str(i) '.bnd'];
0278   fid = fopen(fname,'w');
0279   fid = fprintf(fid,'TPAR\n');
0280   for j=1:icnt
0281     [year,month,day,hour,mint,sec] = julian2greg(time(j));
0282     if(day < 10)
0283       daystr = ['0' int2str(day)];
0284     else
0285       daystr = int2str(day);
0286     end;
0287     if(month < 10)
0288       monthstr = ['0' int2str(month)];
0289     else
0290       monthstr = int2str(month);
0291     end;
0292     if(hour < 10)
0293       hourstr = ['0' int2str(hour)];
0294     else
0295       hourstr = int2str(hour);
0296     end;
0297     date = [' ' int2str(year) monthstr daystr '.' hourstr '00'];
0298     fprintf(fid,'%s %f %f %f %f\n',date,hs(i,j),tp(i,j),dir(i,j),10.);
0299   end;
0300   fclose(fid);
0301 end;
0302 
0303 % dump the main swan control file list
0304 fname = 'cntrllist.txt';
0305 fid = fopen(fname,'w');
0306 for i=1:ndisc
0307   fname = ['"' 'obc' num2str(i) '.bnd' '"'];
0308   fprintf(fid,'%12.2f %s %d %s\n',aobc(i),fname,1,'&');
0309 end;
0310

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