当前位置: 首页 > news >正文

《潮汐调和分析原理和应用》之四S_Tide使用2

1、M2和N2分潮叠加

基于S_TIDEs_construct函数构造的M2N2分潮,可以把M2N2分潮叠加后的结果理解为M2振幅的27.55天(661.2小时)的调制,即如果不在调和分析模型里分辨N2分潮,M2振幅的时间变化会存在27.55天周期。

function [sumconsti,consti]=s_construct(tides,amp,pha,dt,length);
%Haidong Pan(Ocean University of China) 2020/12/24   
%email:1027128116@qq.com      panhaidong_phd@qq.com     
% S_TIDE users QQ group number 485997351
%the input:
%     tides:the names of input tidal constituents
%     amp: the amplitudes of input tidal constituents
%     pha: the phases of input tidal constituents
%     dt: the interval of constructed time series (unit:hour)
%     length: the total length of constructed tiem series
%
% the output:
%    consti: the water levels induced by individual tidal constituent
%    sumconsti: the sum of tidal water levels(分潮是为
%
%see s_demo.m for examples
nobsu=length-rem(length-1,2);% makes series odd to give a center point
t=dt*([1:length]')-ceil(nobsu/2);  % Time vector for entire time series,

load t_constituents
J=size(amp);JJ=J(find(J>1));
if isempty(JJ)==1
JJ=1;
end
if iscell(tides)==1
for i=1:JJ
ju(i)=strmatch(upper(tides(i)),const.name);
fu(i)=const.freq(ju(i));
end
end
consti=zeros(JJ,length,'double');
t=t';
for j=1:JJ
aa=amp(j)*cosd(pha(j));bb=amp(j)*sind(pha(j));
consti(j,:)=aa*cos((2*pi)*t*fu(j))+bb*sin((2*pi)*t*fu(j));
end
sumconsti=sum(consti);
if JJ==1
sumconsti=consti; 
end

%M2和N2分潮叠加

tides={'M2';'N2'};

amp=[1,0.5];pha=[180,90];dt=1;length=8760;

[sumconsti,consti]=s_construct(tides,amp,pha,dt,length);

subplot(3,1,1);plot(consti(1,:),'r-');xlim([0 1200])

title('(a) M2 tide');

subplot(3,1,2);plot(consti(2,:),'b-');xlim([0 1200])

title('(b) N2 tide');

subplot(3,1,3);plot(sumconsti,'k-');xlim([0 1200])

title('(cM2+N2 tides');xlabel('Time(hour)')

2、交点因子和交点订正角

月球升交点的黄经N存在的18.61年循环会调制太阴分潮的振幅和迟角,通过积化和差产生一些小分潮,而将主要分潮和这些小分潮分开需要最少18.61年的数据,显然,很多验潮站的水位观测无法满足这个条件,故引入交点因子f和交点订正角u来消除18.61年的影响。

%交点因子和交点订正角的计算

function [ff,uu,vv,N,s,h,p,pp]=s_nodal_cal(tides,stime,etime,dt,latitude)
% written by Haidong Pan, 2021/03/16
% calculate the nodal factor and angle for input constituents
%-----input-----
% tides    the name of input tidal constituents (in the form of cell)
% stime    start time
% etime    end   time
% dt       sampling interval (day)
% latitude latitude should not be zero)
%----output-----
% ff    nodal factor
% uu    nodal angle                         
% vv    astronomical phase
% N     mean longitude of the ascending node
% s     mean longitude of the moon
% h     mean longitude of the sun
% p     mean longitude of the lunar perigee 
% pp    mean longitude of the perihelion (solar perigee)   
% see s_demo.m for example or see the example below
%
%[ff,uu]=s_nodal_cal({'K1';'O1';'M2'},[1920,01,01],[2020,01,01],365,10);
% subplot(2,1,1);
% plot(ff(1,:),'k');hold on;plot(ff(2,:),'r');plot(ff(3,:),'b')
% legend('K1','O1','M2');
% set(gca,'XTick',0:25:2020)
% set(gca,'XTickLabel',{'1920','1945','1970','1995','2020'})
% title('(a) nodal factor')  
% subplot(2,1,2);
% plot(uu(1,:),'k');hold on;plot(uu(2,:),'r');plot(uu(3,:),'b')
% set(gca,'XTick',0:25:2020)
% set(gca,'XTickLabel',{'1920','1945','1970','1995','2020'})
% title('(b) nodal angle')
%
disp(['******calculating astronomical phase V, the nodal phase modulation U, and the nodal amplitude correction F*********'])
disp(['***********************accurate nodal/satellite corrections need lots of time!*************************************'])
disp(['***********written by Haidong Pan***********'])
load t_constituents
if iscell(tides)==1          
for i=1:length(tides)
ju(i)=strmatch(upper(tides(i)),const.name);
end
end
Lor=datenum(etime)-datenum(stime);
num=floor(Lor/dt);
%ff=zeros(length(ju),num,'double');uu=ff;vv=ff;N=ff;s=ff;h=ff;p=ff;pp=ff;
for i=1:num
days=datenum(stime)+(i-1)*dt;
[v,u,f,astro]=t_vuf('nodal',days,ju,latitude);
ff(:,i)=f(:);
uu(:,i)=360*u;
vv(:,i)=360*v;
N(i)=astro(5)*-360; 
s(i)=astro(2)*360;
h(i)=astro(3)*360;
p(i)=astro(4)*360;
pp(i)=astro(6)*360;
end
N(N<0)=N(N<0)+360;

%iscell的解释

m=5 %m为1×1的数值
m='5' %m为1×1的字符
m='h' %m为1×1的字符
m="h" %m为1×1字符串
m="hello" %m为1×1的字符串
m="hello world" %m为1×1的字符串
m='hello' %m为1×5的字符数组
m='hello world' %m为1×11的字符数组
m={'hello'} %m为1×1的元胞数组
m={'hello','world'} %m为1×2的元胞数组

%t_vuf函数

function [v,u,f,astro]=t_vuf(ltype,ctime,ju,lat);
% T_VUF Computes nodal modulation corrections.
% [V,U,F]=T_VUF(TYPE,DATE,JU,LAT) returns the astronomical phase V, the 
% nodal phase modulation U, and the nodal amplitude correction F at
% a decimal date DATE for the components specified by index JU 
% at a latitude LAT.
%
% TYPE is either 'full' for the 18.6 year set of constitunets, or 'nodal'
% for the 1-year set with satellite modulations.
%
% If LAT is not specified, then the Greenwich phase V is computed with
% U=0 and F=1. 
%
% Note that V and U are in 'cycles', not degrees or radians (i.e.,
% multiply by 360 to get degrees).
%
% If LAT is set to NaN, then the nodal corrections are computed for all
% satellites that do *not* have a "latitude-dependent" correction 
% factor. This is for compatibility with the ways things are done in
% the xtide package. (The latitude-dependent corrections were zeroed
% out there partly because it was convenient, but this was rationalized
% by saying that since the forcing of tides can occur at latitudes
% other than where they are observed, the idea that observations have 
% the equilibrium latitude-dependence is possibly bogus anyway).
% T_VUF 计算交点调制校正量
% [V,U,F] = T_VUF(类型,日期,JU,纬度) 返回在十进制日期DATE下,
% 针对JU索引指定分量在纬度LAT处的天文相位角V、交点相位调制U
% 及交点振幅校正因子F
%
% 类型参数可选:
% 'full' 采用18.6年周期分潮组
% 'nodal' 采用包含卫星调制的1年周期分潮组
%
% 若未指定LAT参数,则计算格林尼治相位V(此时U=0且F=1)
%
% 注意:V和U的单位为"周角"(非度或弧度,需乘以360转换为度)
%
% 若将LAT设为NaN,则仅计算不依赖纬度校正因子的卫星分量校正值。
% 此特性用于保持与xtide软件包的兼容性(该包中出于便利性考虑,
% 直接忽略了纬度依赖性校正;其理论依据是:由于潮汐驱动力可能源自
% 观测点以外的纬度区域,认为观测结果应遵循平衡潮纬度依赖性的
% 理论假设本身可能存在谬误)
% R. Pawlowicz 11/8/99
%               1/5/00 - Changed to allow for no LAT setting.
%              11/8/00 - Added the LAT=NaN option.
%              10/02/03 - Suuport for 18-year (full) constituent set.
% Version 1.2

% Get all the info about constituents.

% Calculate astronomical arguments at mid-point of data time series.
[astro,ader]=t_astron(ctime);

if strcmp(ltype,'full'),

  [const]=t_get18consts(ctime);

  % Phase relative to Greenwich (in units of cycles).
v=rem( const.doodson*astro+const.semi, 1);

  v=v(ju);
u=zeros(size(v));
f=ones(size(v));

else 

  [const,sat,shallow]=t_getconsts(ctime);

  % Phase relative to Greenwich (in units of cycles).
% (This only returns values when we have doodson#s, i.e., not for the 
% shallow water components, but these will be computed later.)
v=rem( const.doodson*astro+const.semi, 1);

  if nargin==4, % If we have a latitude, get nodal corrections.

    % Apparently the second-order terms in the tidal potential go to zero
% at the equator, but the third-order terms do not. Hence when trying
% to infer the third-order terms from the second-order terms, the 
% nodal correction factors blow up. In order to prevent this, it is 
% assumed that the equatorial forcing is due to second-order forcing 
% OFF the equator, from about the 5 degree location. Latitudes are 
% hence (somewhat arbitrarily) forced to be no closer than 5 deg to 
% the equator, as per note in Foreman.

    if isfinite(lat) & (abs(lat)<5); lat=sign(lat).*5; end

    slat=sin(pi.*lat./180);
% Satellite amplitude ratio adjustment for latitude. 

    rr=sat.amprat;           % no amplitude correction

    if isfinite(lat),
j=find(sat.ilatfac==1); % latitude correction for diurnal constituents
rr(j)=rr(j).*0.36309.*(1.0-5.0.*slat.*slat)./slat;

      j=find(sat.ilatfac==2); % latitude correction for semi-diurnal constituents
rr(j)=rr(j).*2.59808.*slat;
else 
rr(sat.ilatfac>0)=0;
end;

    % Calculate nodal amplitude and phase corrections.

    uu=rem( sat.deldood*astro(4:6)+sat.phcorr, 1);

    %%uu=uudbl-round(uudbl);  <_ I think this was wrong. The original
%                         FORTRAN code is:  IUU=UUDBL
%                                           UU=UUDBL-IUU
%                         which is truncation.        


% Sum up all of the satellite factors for all satellites.

    nsat=length(sat.iconst);
nfreq=length(const.isat);

    fsum=1+sum(sparse([1:nsat],sat.iconst,rr.*exp(i*2*pi*uu),nsat,nfreq)).';

    f=abs(fsum);
u=angle(fsum)./(2.*pi);

    % Compute amplitude and phase corrections for shallow water constituents. 

    for k=find(isfinite(const.ishallow))',
ik=const.ishallow(k)+[0:const.nshallow(k)-1];
f(k)=prod(f(shallow.iname(ik)).^abs(shallow.coef(ik)));
u(k)=sum( u(shallow.iname(ik)).*shallow.coef(ik) );
v(k)=sum( v(shallow.iname(ik)).*shallow.coef(ik) );
end;

    f=f(ju);
u=u(ju);
v=v(ju);

  else % Astronomical arguments only, so nodal corrections.

    % Compute phases for shallow water constituents.
for k=find(isfinite(const.ishallow))',
ik=const.ishallow(k)+[0:const.nshallow(k)-1];
v(k)=sum( v(shallow.iname(ik)).*shallow.coef(ik) );
end;
v=v(ju);
f=ones(size(v));
u=zeros(size(v));
end;
end;

%调用交点计算程序,获取交点因子、订正角、初相位,黄经

%绘制黄经N

[ff,uu,vv,N]=s_nodal_cal({'K1';'O1';'M2'},[1920,01,01],[2020,01,01],365,10);

subplot(2,1,1);plot(N,'k');hold on;

set(gca,'XTick',0:25:2020);title('(a) N (°)');

set(gca,'XTickLabel',{'1920','1945','1970','1995','2020'})

subplot(2,1,2);plot(cosd(N),'r');hold on;

set(gca,'XTick',0:25:2020);title('(b) cos(N)');

set(gca,'XTickLabel',{'1920','1945','1970','1995','2020'})

%计算交点因子、订正角、初相位和黄经
%绘制K1、M2分潮的交点因子、订正角

[ff,uu,vv,N]=s_nodal_cal({'K1';'M2'},[1920,01,01],[2020,01,01],365,10);

subplot(2,1,1);plot(ff(1,:),'k');hold on;plot(ff(2,:),'r');grid on;

legend('K1','M2');set(gca,'XTick',0:25:2020)

set(gca,'XTickLabel',{'1920','1945','1970','1995','2020'})

title('(a) f')

subplot(2,1,2);plot(uu(1,:),'k');hold on;plot(uu(2,:),'r');grid on;

set(gca,'XTick',0:25:2020)

set(gca,'XTickLabel',{'1920','1945','1970','1995','2020'})

title('(b) u (°)')

作为非专业人士,理解到t_vuf已经是博主的极限了。如果看t_vuf函数内部的内容,根本搞不懂。

t_vuf函数还用到2个函数t_getconsts和 t_astron,就粘贴函数代码了,只看看它们的描述。

% t_astron函数

计算儒略日JD时刻(世界协调时UTC,具体详见代码说明)的天文参数 A = [τ, s, h, p, np, pp](单位:周角)及其时间变化率

function [astro,ader] = t_astron(jd)
% T_ASTRON Computes astronomical Variables
% [A,ADER] = ASTRON(JD) computes the astronomical variables 
%            A=[tau,s,h,p,np,pp] (cycles) 
%  and their time derivatives 
%            ADER=[dtau,ds,dh,dp,dnp,dpp] (cycles/day) 
%  at the matlab time JD (UTC, but see code for details) where
%
%    tau = lunar time
%    s = mean longitude of the moon
%    h = mean longitude of the sun
%    p = mean longitude of the lunar perigee 
%    np = negative of the longitude of the mean ascending node
%    pp = mean longitude of the perihelion (solar perigee)   
%

%
%    The formulae for calculating these ephemerides (other than tau) 
%    were taken from pages 98 and 107 of the Explanatory Supplement to
%    the Astronomical Ephemeris and the American Ephemeris and Nautical 
%    Almanac (1961). They require EPHEMERIS TIME (ET), now TERRESTRIAL 
%    TIME (TT) and are based on observations made in the 1700/1800s.
%    In a bizarre twist, the current definition of time is derived
%    by reducing observations of planetary motions using these formulas.
%
%    The current world master clock is INTERNATIONAL ATOMIC TIME (TAI).
%    The length of the second is based on inverting the actual 
%    locations of the planets over the period 1956-65 into "time" 
%    using these formulas, and an offset added to keep the scale 
%    continuous with previous defns. Thus
%
%                     TT = TAI + 32.184 seconds.
%
%    Universal Time UT is a time scale that is 00:00 at midnight (i.e.,
%    based on the earth's rotation rather than on planetary motions).
%    Coordinated Universal Time (UTC) is kept by atomic clocks, the 
%    length of the second is the same as for TAI but leap seconds are
%    inserted at intervals so that it provides UT to within 1 second. 
%    This is necessary because the period of the earth's rotation is 
%    slowly increasing (the day was exactly 86400 seconds around 1820, 
%    it is now about 2 ms longer). 22 leap seconds have been added in 
%    the last 27 years.
%
%    As of 1/1/99,    TAI = UTC + 32 seconds.
%       
%    Thus,             TT = UTC + 62.184 seconds
%
%    GPS time was synchronized with UTC 6/1/1980 ( = TAI - 19 secs), 
%    but is NOT adjusted for leap seconds. Your receiver might do this
%    automatically...or it might not.
%
%    Does any of this matter? The moon longitude is the fastest changing
%    parameter at 13 deg/day. A time error of one minute implies a
%    position error of less than 0.01 deg. This would almost always be 
%    unimportant for tidal work.
%
%    The lunar time (tau) calculation requires UT as a base.  UTC is 
%    close enough - an error of 1 second, the biggest difference that
%    can occur between UT and UTC, implies a Greenwich phase error of 
%    0.01 deg.  In Doodson's definition (Proc R. Soc. A, vol 100, 
%    reprinted in International Hydrographic Review, Appendix to 
%    Circular Letter 4-H, 1954) mean lunar time is taken to begin at 
%    "lunar midnight". 
% T_ASTRON 计算天文参数
% [A, ADER] = ASTRON(JD) 计算儒略日JD时刻(世界协调时UTC,具体详见代码说明)的
% 天文参数 A = [τ, s, h, p, np, pp](单位:周角)
%及其时间变化率
% ADER = [dτ, ds, dh, dp, dnp, dpp](单位:周角/天)
% 其中:
% τ = 月球时角
% s = 月球平经度
% h = 太阳平经度
% p = 月球近地点平经度
% np = 月球升交点平经度的负值
% pp = 近日点平经度(太阳近地点)

%
% 这些星历参数(除τ外)的计算公式源自《天文星历解释性补充说明及
% 美国星历与航海年历》(1961年)第98和107页,需采用历书时(ET)
% ——现称为地球时(TT)——作为时间基准,其观测数据基于18-19世纪的记录。
% 耐人寻味的是,当前时间标准的定义正是通过使用这些公式
% 对行星运动观测数据进行归算而推导得出的。
%
% 当前世界主钟采用国际原子时(TAI),其秒长定义基于1956-65年间
% 通过上述公式对行星实际位置反算推导的"时间"尺度,
% 并通过添加偏移量保持与历史时间定义的连续性。因此:
%
% TT = TAI + 32.184 秒
%
% 世界时(UT)是以午夜零时为起点的时标(基于地球自转而非行星运动)。
% 协调世界时(UTC)由原子钟守时,其秒长与TAI相同,但通过间隔插入闰秒
% 使其与UT的偏差保持在1秒以内。此举的必要性在于地球自转周期
% 正逐渐变长(1820年时1日恰好为86400秒,现今已延长约2毫秒)。
% 过去27年间已添加22次闰秒。
%
% 截至1999年1月1日:TAI = UTC + 32 秒
%
% 因此: TT = UTC + 62.184 秒
%
% GPS时在1980年6月1日与UTC同步(= TAI - 19秒),但不进行闰秒调整。
% 用户接收设备可能自动实现闰秒补偿...亦可能未作处理。
%
% 这些时差影响几何?月球经度变化最快达13度/天。1分钟的时间误差
% 导致的定位偏差小于0.01度,对潮汐研究通常可忽略不计。
%
% 月球时角(τ)计算需以UT为基准。UTC已足够近似——UT与UTC之间
% 最大可能存在的1秒误差,对应的格林尼治相位误差仅为0.01度。
% 根据杜德森定义(《皇家学会会刊A辑》第100卷,1954年转载于
% 《国际水文评论》4-H号通函附录),平月球时以"月球午夜"为起始点。

% t_getconsts函数

主要读取t_constituents.mat文件

获取分潮数据结构,返回包含潮汐分析信息的数据结构

function [const,sat,shallow]=t_getconsts(ctime);
% T_GETCONSTS Gets constituent data structures
% [CONST,SAT,SHALLOW]=T_GETCONSTS returns data structures holding
% information for tidal analyses.
%
% Variables are loaded from 't_constituents.mat', otherwise the 
% ascii files 'tide3.dat' (provided with the IOS analysis package)
% and 't_equilib.dat' are read, and the results stored in 
% 't_constituents.mat' for future use.
%
% [...]=T_GETCONSTS(TIME) recomputes the frequencies from the 
% rates-of-change of astronomical parameters at the matlab TIME given.
% T_GETCONSTS 获取分潮数据结构
% [CONST,SAT,SHALLOW]=T_GETCONSTS 返回包含潮汐分析信息的数据结构
%
% 程序优先从't_constituents.mat'文件加载变量,若该文件不存在,
% 则读取IOS潮汐分析包提供的ASCII文件'tide3.dat'及't_equilib.dat',
% 并将处理结果保存至't_constituents.mat'供后续使用
%
% [...]=T_GETCONSTS(TIME) 根据给定的MATLAB时间TIME,
% 通过天文参数变化率重新计算频率

t_constituents.mat文件的结构体字段进行了翻译。

t_constituents.mat

 const=struct('name',setstr(zeros(nc,4)),... % constituent names
'freq',empvec,...              % and frequencies (cph)
'kmpr',setstr(zeros(nc,4)),... % names of comparisons
'ikmpr',empvec,'df',empvec,... % ..and their index (into .name)
'doodson',zeros(nc,6)+NaN,...  % doodson#s (when available)
'semi',empvec,...              % phase offsets
'isat',empvec,...              % index into "sat"
'nsat',empvec,...              % # of associated satellites in "sat"
'ishallow',empvec,...          % index in "shallow"
'nshallow',empvec,...          % # of generating freqs in "shallow"
'doodsonamp',empvec,...        % Equilibrium Amplitude (when available)
'doodsonspecies',empvec);      % Species
nsat=162;
sat=struct('deldood',zeros(nsat,3),...  % changes in last 3 doodson#s 
'phcorr',zeros(nsat,1),...   % phase corrections
'amprat',zeros(nsat,1),...   % amplitude corrections
'ilatfac',zeros(nsat,1),...  % latitude-dependent correction type
'iconst',zeros(nsat,1));     % index of major (in const.)

nshl=251;
shallow=struct('iconst',zeros(nshl,1),... % index of shallow constituent name
'coef',zeros(nshl,1),...   % corresponding combination number and
'iname',zeros(nshl,1));    % index of main constituent

const=struct('name',setstr(zeros(nc,4)),... % 分潮名称'freq',empvec,...              % 频率(单位:周/小时)'kmpr',setstr(zeros(nc,4)),... % 比较项名称'ikmpr',empvec,'df',empvec,... % 及其索引(指向.name字段)'doodson',zeros(nc,6)+NaN,...  % 杜德森数(若可用)'semi',empvec,...              % 相位偏移量'isat',empvec,...              % 指向"sat"结构的索引'nsat',empvec,...              % "sat"中关联卫星分潮的数量'ishallow',empvec,...          % 指向"shallow"结构的索引'nshallow',empvec,...          % "shallow"中生成频率的数量'doodsonamp',empvec,...        % 平衡潮振幅(若可用)'doodsonspecies',empvec);      % 种类nsat=162;sat=struct('deldood',zeros(nsat,3),...  % 最后3个杜德森数的变化量'phcorr',zeros(nsat,1),...   % 相位校正值'amprat',zeros(nsat,1),...   % 振幅校正系数'ilatfac',zeros(nsat,1),...  % 纬度相关校正类型'iconst',zeros(nsat,1));     % 主分潮索引(指向const结构)nshl=251;shallow=struct('iconst',zeros(nshl,1),... % 浅水分潮名称的索引'coef',zeros(nshl,1),...   % 相应的组合数和'iname',zeros(nshl,1));    % 主分潮的索引
http://www.xdnf.cn/news/1406323.html

相关文章:

  • Java中不太常见的语法-总结
  • 架构进阶——解读 69页 方法轮IT规划培训 架构-重点-细节【附全文阅读】
  • Shell编程核心入门:参数传递、运算符与流程控制全解析
  • 2025年9月计算机二级C++语言程序设计——选择题打卡Day11
  • 学习日志41 python
  • Linux/UNIX系统编程手册笔记:文件I/O、进程和内存分配
  • vue2下拉菜单
  • 【小宁学习日记5 PCB】电路定理
  • 9. 函数和匿名函数(一)
  • 快消品牌如何用 DAM 管理万张素材?
  • 【光照】[光照模型]是什么?以UnityURP为例
  • C++的反向迭代器
  • BEV-VAE
  • 二进制方式安装部署 Logstash
  • Java试题-选择题(23)
  • 【Linux基础】深入理解计算机启动原理:MBR主引导记录详解
  • 并发编程:Java中的多线程与线程池!
  • 魔方的使用
  • LangGraph 深度解析(二):掌握 LangGraph 函数式 API 的状态化 AI 工作流
  • 每日算法题【二叉树】:堆的实现、堆排序的实现、文件中找TopK
  • [光学原理与应用-338]:ZEMAX - Documents\Zemax\Samples
  • 吴恩达机器学习作业九:kmeans聚类
  • 2025最确定性的答案:AI+IP的结合
  • CNB远程部署和EdgeOne Pages
  • 恶补DSP:3.F28335的ePWM模块
  • Wheat Gene ID Convert Tool 小麦中国春不同参考基因组GeneID转换在线工具
  • TensorFlow 深度学习 | 使用底层 API 实现模型训练(附可视化与 MLP)
  • 「日拱一码」066 深度学习——Transformer
  • ADB常用命令大全
  • Linux中的Shell编程 第一章