Commit 922c3a10 by Pierre Cazenave

### Add the TMD v2.04 code.

parent 496d3f4d
 % Bilinear interpolation (neigbouring NaNs avoided) % in point xt,yt % x(n),y(m) - coordinates for h(n,m) % xt(N),yt(N) - coordinates for interpolated values % Global case is considered ONLY for EXACTLY global solutions, % i.e. given in lon limits, satisfying: % ph_lim(2)-ph_lim(1)==360 % (thus for C-grid: x(end)-x(1)==360-dx ) % % usage: % [hi]=BLinterp(x,y,h,xt,yt,km); % km=1 if model is on Cartesian grid (km) otherwise 0 % function [hi]=BLinterp(x,y,h,xt,yt,km); % if nargin<5,km=0;end % dx=x(2)-x(1);dy=y(2)-y(1); glob=0; if km==0 & x(end)-x(1)==360-dx,glob=1;end inan=find(isnan(h)>0); h(inan)=0; mz=(h~=0); n=length(x);m=length(y); [n1,m1]=size(h); if n~=n1 | m~=m1, fprintf('Check dimensions\n'); hi=NaN; return end % extend solution both sides for global if glob==1, h0=h;mz0=mz; [k1,k2]=size(x);if k1==1,x=x';end [k1,k2]=size(y);if k1==1,y=y';end % just for consistency x=[x(1)-2*dx;x(1)-dx;x;x(end)+dx;x(end)+2*dx]; h=[h(end-1,:);h(end,:);h;h(1,:);h(2,:)]; mz=[mz(end-1,:);mz(end,:);mz;mz(1,:);mz(2,:)]; end % Adjust lon convention % THIS should be done only if km==0 !!!!!!! xti=xt; if km==0, ik=find(xtix(end)); if x(end)>180,xti(ik)=xti(ik)+360;end if x(end)<0, xti(ik)=xti(ik)-360;end ik=find(xti>360); xti(ik)=xti(ik)-360; ik=find(xti<-180); xti(ik)=xti(ik)+360; end % [X,Y]=meshgrid(x,y); q=1/(4+2*sqrt(2));q1=q/sqrt(2); h1=q1*h(1:end-2,1:end-2)+q*h(1:end-2,2:end-1)+q1*h(1:end-2,3:end)+... q1*h(3:end,1:end-2)+q*h(3:end,2:end-1)+q1*h(3:end,3:end)+... q*h(2:end-1,1:end-2)+q*h(2:end-1,3:end); mz1=q1*mz(1:end-2,1:end-2)+q*mz(1:end-2,2:end-1)+q1*mz(1:end-2,3:end)+... q1*mz(3:end,1:end-2)+q*mz(3:end,2:end-1)+q1*mz(3:end,3:end)+... q*mz(2:end-1,1:end-2)+q*mz(2:end-1,3:end); mz1(find(mz1==0))=1; h2=h; h2(2:end-1,2:end-1)=h1./mz1; ik=find(mz==1); h2(ik)=h(ik); h2(find(h2==0))=NaN; hi=interp2(X,Y,h2',xti,yt);hi=conj(hi); if glob==1, h=h0;mz=mz0;end return
 % Bilinear interpolation (neigbouring NaNs avoided) % in point xt,yt % x(n),y(m) - coordinates for h(n,m) % xt(N),yt(N) - coordinates for interpolated values % Global case is considered ONLY for EXACTLY global solutions, % i.e. given in lon limits, satisfying: % ph_lim(2)-ph_lim(1)==360 % (thus for C-grid: x(end)-x(1)==360-dx ) % function [hi]=BLinterp(x,y,h,xt,yt); % dx=x(2)-x(1);dy=y(2)-y(1); glob=0; if x(end)-x(1)==360-dx,glob=1;end inan=find(isnan(h)>0); h(inan)=0; mz=(h~=0); n=length(x);m=length(y); [n1,m1]=size(h); if n~=n1 | m~=m1, fprintf('Check dimensions\n'); hi=NaN; return end % extend solution both sides for global if glob==1, h0=h;mz0=mz; [k1,k2]=size(x);if k1==1,x=x';end [k1,k2]=size(y);if k1==1,y=y';end % just for consistency x=[x(1)-2*dx;x(1)-dx;x;x(end)+dx;x(end)+2*dx]; h=[h(end-1,:);h(end,:);h;h(1,:);h(2,:)]; mz=[mz(end-1,:);mz(end,:);mz;mz(1,:);mz(2,:)]; end % Adjust lon convention xti=xt; ik=find(xtix(end)); if x(end)>180,xti(ik)=xti(ik)+360;end if x(end)<0, xti(ik)=xti(ik)-360;end ik=find(xti>360); xti(ik)=xti(ik)-360; ik=find(xti<-180); xti(ik)=xti(ik)+360; % [X,Y]=meshgrid(x,y); q=1/(4+2*sqrt(2));q1=q/sqrt(2); h1=q1*h(1:end-2,1:end-2)+q*h(1:end-2,2:end-1)+q1*h(1:end-2,3:end)+... q1*h(3:end,1:end-2)+q*h(3:end,2:end-1)+q1*h(3:end,3:end)+... q*h(2:end-1,1:end-2)+q*h(2:end-1,3:end); mz1=q1*mz(1:end-2,1:end-2)+q*mz(1:end-2,2:end-1)+q1*mz(1:end-2,3:end)+... q1*mz(3:end,1:end-2)+q*mz(3:end,2:end-1)+q1*mz(3:end,3:end)+... q*mz(2:end-1,1:end-2)+q*mz(2:end-1,3:end); mz1(find(mz1==0))=1; h2=h; h2(2:end-1,2:end-1)=h1./mz1; ik=find(mz==1); h2(ik)=h(ik); h2(find(h2==0))=NaN; hi=interp2(X,Y,h2',xti,yt);hi=conj(hi); if glob==1, h=h0;mz=mz0;end return
FUNCTIONS/Huv.m 0 → 100644
 function [hu,hv] = Huv(hz); % Usage [hu,hv] = Huv(hz); [n,m] = size(hz); [mu,mv,mz] = Muv(hz); indxm = [n,1:n-1]; indym = [m,1:m-1]; hu = mu.*(hz + hz(indxm,:))/2; hv = mv.*(hz + hz(:,indym))/2;
FUNCTIONS/Muv.m 0 → 100644
 function [mz,mu,mv] = Muv(hz) % Given a rectangular bathymetry grid, construct masks for zeta, % u and v nodes on a C-grid % USAGE: [mz,mu,mv] = Muv(hz); [n,m] = size(hz); mz = hz > 0; indx = [2:n 1]; indy = [2:m 1]; mu(indx,:) = mz.*mz(indx,:); mv(:,indy) = mz.*mz(:,indy);
 % calculates tidal ellipse parameters for the arrays of % u and v - COMPLEX amplitudes of EW and NS currents of % a given tidal constituent % land should be set to 0 or NaN in u,v prior to calling tideEl % usage: [umajor,uminor,uincl,uphase]=tideEl(u,v); function [umajor,uminor,uincl,uphase]=tideEl(u,v); % change to polar coordinates % in Robin's was - + + -, this is as in Foreman's t1p = (real (u) - imag(v)); t2p = (real (v) + imag(u)); t1m = (real (u) + imag(v)); t2m = (real (v) - imag(u)); % ap, am - amplitudes of positevely and negatively % rotated vectors ap = sqrt( (t1p.^2 + t2p.^2)) / 2.; am = sqrt( (t1m.^2 + t2m.^2)) / 2.; % ep, em - phases of positively and negatively rotating vectors ep = atan2( t2p, t1p); ep = ep + 2 * pi * (ep < 0.0); ep = 180. * ep / pi; em = atan2( t2m, t1m); em = em + 2 * pi * (em < 0.0); em = 180. * em / pi; % determine the major and minor axes, phase and inclination using Foreman's formula umajor = (ap + am); uminor = (ap - am); uincl = 0.5 * (em + ep); uincl = uincl - 180. * (uincl > 180); uphase = - 0.5*(ep-em) ; uphase = uphase + 360. * (uphase < 0); uphase = uphase - 360. * (uphase >= 360); return
FUNCTIONS/XY.m 0 → 100644
 function [x,y] = XY(ll_lims,n,m); % Usage: [x,y] = XY(ll_lims,n,m); dx = (ll_lims(2)-ll_lims(1))/n; dy = (ll_lims(4)-ll_lims(3))/m; x = ll_lims(1)+dx/2:dx:ll_lims(2)-dx/2; y = ll_lims(3)+dy/2:dy:ll_lims(4)-dy/2;
 % Computes the basic astronomical mean longitudes s, h, p, N. % Note N is not N', i.e. N is decreasing with time. % These formulae are for the period 1990 - 2010, and were derived % by David Cartwright (personal comm., Nov. 1990). % time is UTC in decimal MJD. % All longitudes returned in degrees. % R. D. Ray Dec. 1990 % Non-vectorized version. Re-make for matlab by Lana Erofeeva, 2003 % usage: [s,h,p,N]=astrol(time) % time, MJD function [s,h,p,N]=astrol(time); circle=360; T = time - 51544.4993; % mean longitude of moon % ---------------------- s = 218.3164 + 13.17639648 * T; % mean longitude of sun % --------------------- h = 280.4661 + 0.98564736 * T; % mean longitude of lunar perigee % ------------------------------- p = 83.3535 + 0.11140353 * T; % mean longitude of ascending lunar node % -------------------------------------- N = 125.0445D0 - 0.05295377D0 * T; % s = mod(s,circle); h = mod(h,circle); p = mod(p,circle); N = mod(N,circle); % if s<0, s = s + circle; end if h<0, h = h + circle; end if p<0, p = p + circle; end if N<0, N = N + circle; end return
 % returns Flag=0, if ModName, GridName & type OK % Flag>0, if they are not or files do not exist % Flag<0, if not possible to define % usage: [Flag]=checkTypeName(ModName,GridName,type); function [Flag]=checkTypeName(ModName,GridName,type); Flag=0; % check if files exist if exist(ModName,'file')==0, fprintf('File %s NOT found\n',ModName); Flag=1; return end if exist(GridName,'file')==0, fprintf('File %s NOT found\n',GridName); Flag=1; return end type=deblank(type);btype=deblank(type(end:-1:1)); type=btype(end:-1:1);type=type(1:1); % Check type if type~='z' & type~='U'& type~='u'& type~='V' & type~='v', fprintf('WRONG TYPE %s: should be one of: ''z'',''U'',''u'',''V'',''v''\n',type); Flag=2; return end % Check type/name correspondence i1=findstr(ModName,'/'); if isempty(i1)>0,i1=1;else i1=i1(end)+1;end if ModName(i1:i1)=='h', if type=='U'| type=='u'|type=='V'| type=='v', fprintf('For file %s only legal type is ''z'' (%s given)\n',... ModName(i1:end),type); Flag=3; return end elseif ModName(i1:i1)=='u' | ModName(i1:i1)=='U', if type=='z', fprintf('For file %s legal types are: ''U'',''u'',''V'',''v'' (%s given)\n',... ModName(i1:end),type); Flag=4; return end else fprintf('WARNING: Model name %s does not correspond TMD convention:\n',ModName(i1:end)); fprintf('Can not check type %s:...\n',type); Flag=-1; end return
 function [l]=check_dim(ModName,n,m,n1,m1); l=1; if n~=n1 | m~=m1, fprintf('ERROR:\n'); fprintf('Control file %s contains inconsistent files:\n',ModName); fprintf('Grid size: %d x %d \n',n,m); fprintf('Elevation/transport size: %d x %d \n',n1,m1); l=0; end return;
 % constit returns amplitude, phase, frequency,alpha, species for % a tidal constituent identified by a 4 character string % This version returns zeros for all phases % Usage: [ispec,amp,ph,omega,alpha,constitNum] = constit(c); function [ispec,amp,ph,omega,alpha,constitNum] = constit(c); ispec=-1; amp=0;ph=0;omega=0;alpha=0;constitNum=0; if( nargout < 6) fprintf('Number of output arguments to constit.m does not agree with current usage\n'); end % c : character string ID of constituents that the program knows about % all other variables are in the same order c_data = ['m2 ';'s2 ';'k1 ';'o1 '; ... 'n2 ';'p1 ';'k2 ';'q1 '; ... '2n2 ';'mu2 ';'nu2 ';'l2 '; ... 't2 ';'j1 ';'no1 ';'oo1 '; ... 'rho1';'mf ';'mm ';'ssa ';'m4 ';'ms4 ';'mn4 ' ]; constitNum_data = [1,2,5,6,... 3,7,4,8,... 0,0,0,0,... 0,0,0,0,... 0,0,0,0,0,0,0]; % ispec : species type (spherical harmonic dependence of quadropole potential) ispec_data = [2;2;1;1; ... 2;1;2;1; ... 2;2;2;2; ... 2;1;1;1; ... 1;0;0;0;0;0;0]; % alpha : loading love number ... frequncy dependance here is suspect alpha_data = [ 0.693;0.693;0.736;0.695; ... 0.693;0.706;0.693;0.695; ... 0.693;0.693;0.693;0.693; ... 0.693;0.693;0.693;0.693; ... 0.693;0.693;0.693;0.693;0.693;0.693;0.693]; % omega : frequencies omega_data = [1.405189e-04;1.454441e-04;7.292117e-05;6.759774e-05; ... 1.378797e-04;7.252295e-05;1.458423e-04;6.495854e-05; ... 1.352405e-04;1.355937e-04;1.382329e-04;1.431581e-04; ... 1.452450e-04;7.556036e-05;7.028195e-05;7.824458e-05; ... 6.531174e-05;0.053234e-04;0.026392e-04;0.003982e-04; ... 2.810377e-04;2.859630e-04;2.783984e-04]; % phase : Astronomical arguments (relative to t0 = 1 Jan 0:00 1992] % Richrad Ray subs: "arguments" and "astrol" phase_data = [ 1.731557546;0.000000000;0.173003674;1.558553872;... 6.050721243;6.110181633;3.487600001;5.877717569; 4.086699633;3.463115091;5.427136701;0.553986502; 0.052841931;2.137025284;2.436575100;1.929046130; 5.254133027;1.756042456;1.964021610;3.487600001; 3.463115091;1.731557546;1.499093481]; % amp : amplitudes %amp_data = [0.242334;0.112743;0.141565;0.100661; ... amp_data = [0.2441 ;0.112743;0.141565;0.100661; ... 0.046397;0.046848;0.030684;0.019273; ... 0.006141;0.007408;0.008811;0.006931; ... 0.006608;0.007915;0.007915;0.004338; ... 0.003661;0.042041;0.022191;0.019567;0;0;0]; nspecies = length(ispec_data); nl = length(c); kk = 0; for k = 1:nspecies if(lower(c) == c_data(k,1:nl)) , kk = k; break end end if(kk == 0 ), ispec = -1; return else constitNum = constitNum_data(kk); ispec = ispec_data(kk); amp = amp_data(kk); alpha = alpha_data(kk); omega = omega_data(kk); % ph = 0; ph = phase_data(kk); end return
 % reads a grid file in matlab % USAGE: [ll_lims,hz,mz,iob,dt] = grd_in(cfile); % Location: C:\Toolboxes\TMD\FUNCTIONS function [ll_lims,hz,mz,iob,dt] = grd_in(cfile); fid = fopen(cfile,'r','b'); fseek(fid,4,'bof'); n = fread(fid,1,'long'); m = fread(fid,1,'long'); lats = fread(fid,2,'float'); lons = fread(fid,2,'float'); dt = fread(fid,1,'float'); if(lons(1) < 0) & (lons(2) < 0 ) & dt>0, lons = lons + 360; end ll_lims = [lons ; lats ]; %fprintf('Time step (sec): %10.1f\n',dt); nob = fread(fid,1,'long'); if nob == 0, fseek(fid,20,'cof'); iob = []; else fseek(fid,8,'cof'); iob = fread(fid,[2,nob],'long'); fseek(fid,8,'cof'); end hz = fread(fid,[n,m],'float'); fseek(fid,8,'cof'); mz = fread(fid,[n,m],'long'); fclose(fid);
 % outputs a grid file in matlab % USAGE: grd_out(cfile,ll_lims,hz,mz,iob,dt); function grd_out(cfile,ll_lims,hz,mz,iob,dt); % open this way for files to be read on Unix machine fid = fopen(cfile,'w','b'); [dum,nob] = size(iob); [n,m] = size(hz); reclen = 32; fwrite(fid,reclen,'long'); fwrite(fid,n,'long'); fwrite(fid,m,'long'); fwrite(fid,ll_lims(3:4),'float'); fwrite(fid,ll_lims(1:2),'float'); fwrite(fid,dt,'float'); fwrite(fid,nob,'long'); fwrite(fid,reclen,'long'); % if nob == 0, fwrite(fid,4,'long'); fwrite(fid,0,'long'); fwrite(fid,4,'long'); else reclen=8*nob; fwrite(fid,reclen,'long'); fwrite(fid,iob,'long'); fwrite(fid,reclen,'long'); end % reclen = 4*n*m; fwrite(fid,reclen,'long'); fwrite(fid,hz,'float'); fwrite(fid,reclen,'long'); fwrite(fid,reclen,'long'); fwrite(fid,mz,'long'); fwrite(fid,reclen,'long'); fclose(fid); return
FUNCTIONS/h_in.m 0 → 100644
 function [h,th_lim,ph_lim] = h_in(cfile,ic) %USAGE: [h,th_lim,ph_lim] = h_in(cfile,ic); % reads in elevation for constituent # ic in file cfile fid = fopen(cfile,'r','b'); ll = fread(fid,1,'long'); nm = fread(fid,3,'long'); n=nm(1); m = nm(2); nc = nm(3); th_lim = fread(fid,2,'float'); ph_lim = fread(fid,2,'float'); %nskip = (ic-1)*(nm(1)*nm(2)*8+8) + 8 + 4*nc; nskip = (ic-1)*(nm(1)*nm(2)*8+8) + 8 + ll - 28; fseek(fid,nskip,'cof'); htemp = fread(fid,[2*n,m],'float'); h = htemp(1:2:2*n-1,:)+i*htemp(2:2:2*n,:); fclose(fid);
FUNCTIONS/h_out.m 0 → 100644
 function [] = h_out(cfile,h,th_lim,ph_lim,c_ids) % Usage: [] = h_out(cfile,h,th_lim,ph_lim,c_ids) %WARNING!!!! C_IDS HAVE TO BE 4 CHARACTER STRINGS !!!!!!!!! % writes elevation file in standard format fid = fopen(cfile,'w','b'); [n,m,nc] = size(h); % length of header: allow for 4 character long c_id strings llHead = 4*(7+nc); fwrite(fid,llHead,'long'); fwrite(fid,n,'long'); fwrite(fid,m,'long'); fwrite(fid,nc,'long'); fwrite(fid,th_lim,'float'); fwrite(fid,ph_lim,'float'); fwrite(fid,c_ids,'char'); fwrite(fid,llHead,'long'); htemp = zeros(2*n,m); llConstit = 8*n*m; for ic = 1:nc fwrite(fid,llConstit,'long'); htemp(1:2:2*n-1,:) = real(h(:,:,ic)); htemp(2:2:2*n,:) = imag(h(:,:,ic)); fwrite(fid,htemp,'float'); fwrite(fid,llConstit,'long'); end fclose(fid);
FUNCTIONS/harp.m 0 → 100644
 % function to predict tidal elevation fields at "time" % using harmonic constants % INPUT: time (days) relatively Jan 1, 1992 (48622mjd) % con(nc,4) - char*4 tidal constituent IDs % hc(n,m,nc) - harmonic constant vector (complex) % OUTPUT:hhat - tidal field at time % % Nodal corrections included % % usage: [hhat]=harp(time,hc,con); % % see harp1 for making time series at ONE location