clear
clc
close all hidden
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fni=input('生成人工地震波-输入数据文件名(20041012):','s');
fid=fopen(fni,'r');
fs=fscanf(fid,'%f',1);%采样频率
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tu=fscanf(fid,'%f',1);%上升时间长度
%上升时间包络线线形(1-直线、2-抛物线、3-指数曲线)
iu=fscanf(fid,'%f',1);
%上升时间包络线线形参数(只有指数曲线需要具体参数,其均为1)
cu=fscanf(fid,'%f',1);
ta=fscanf(fid,'%f',1);%持时时间长度
td=fscanf(fid,'%f',1);%下降时间长度
%下降时间包络线线形(1-直线、2-抛物线、3-指数曲线)
id= fscanf(fid,'%f',1);
%下降时间包络线线形(只有抛物线,指数曲线需要具体参数,其余为1)
cd=fscanf(fid,'%f',1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dp=fscanf(fid,'%f',1);%阴尼比值
p=fscanf(fid,'%f',1);%概率系数(一般可取P=0.85)
nn=fscanf(fid,'%f',1);%迭代次数
fno=fscanf(fid,'%f',1);%输出数据文件名
批注 [MS1]: 定义强度包络
线
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%对目标反应谱取值
x=fscanf(fid,'%f',[2,inf]);%反应谱频率和幅值数据
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tatus=fclose(fid);
%计算生成地震波的数据长度
tl=tu+ta+td;
%计算生成地震波的数据长度
nt=round(fs*tl+1);
%大于并最接近nt的2的幂次方为FFT长度
nfft=2^nestpow2(nt)
%计算频率间隔(Hz)
df=fs/nfft
%定义反应谱的离散频率向量
f=0:df:(nfft/2-1)*df
%计算时间间隔(s)
dt=1/fs;
%定义的离散时间向量
t=0:dt:(nt-1)*dt
%生成0到2PI的随机数为随机相位
g=rand(1,nfft/s)*2*pi;
%建立时间包络线
%建立与地震波长度相同元素为1的向量
en=ones(1,nt);
%上升时间阶段
%确定上升时间段的长度
l=round(tu*fs)+1
%产生上升时间段的包络线数组元素
switch iu
case 1 %直线
en(1:l)=linspace(0,1,1);% y = linspace(a,b,n) generates a row vector y of n points linearly
spaced between and including a and b.
case 2 %抛物线
a=0:l-1;
en(1:l)=(a/(l-1)).^2;
case 3 %指数曲线
a=0:l-1;
en(1:l)=1-exp(-cu*a/(l-1));
end
%持续时间阶段
%确定0时刻到持续时间结束时刻时间段的长度
m=round((tu+ta)*fs)+1;
%下降时间阶段
%产生下降时间段的包络线数组元素
switch id
case 1 %直线
en(m:nt)=linspace(1,0,nt-m+1);
case 2 %抛物线
a=0:nt-m;
en(m:nt)=1-cd*(a/(nt-m)).^2;
case 3 %指数曲线
a=0:nt-m;
en(m:nt)=exp(-cd*a/(nt-m));
end
%按线性插值建立目标反应谱离散数据
%按目标反应谱的长度生成元素为0的向量
a0=zeros(x(1,:));
%取目标反应谱数据的长度
n=length(x(1,:));
%四舍五入取整求反应谱最大频率对应数组元素的下标
nb=round(x(1,n)/df)+1;
for k=1:n-1
% 四舍五入取整求反应谱前一个频率数据对应数组元素的下标
l=round(x(1,K)/df)+1;
% 四舍五入取整求反应谱后一个频率数据对应数组元素的下标
m=round(x(1,K+1)/df)+1;
% 线性插值产生前后两个频率数据间的反应谱数组元素
a0(1:m)=linspace(x(2,k),x(2,k+1),m-l+1)
end
%根据目标反应谱计算对应的近似功率谱
a1=a0;
s=zeros(1,nfft/2);
k=nb:ne;
s(k)=2*dp/(pi.*(a1(k).^2)./f(k)./(-2*log(-log(p)*pi/tl)./f(k)));
%将功率谱转换成傅里叶幅值谱
b1=sqrt(4*df*s)*nfft/2;
%定义元素为0的反谱传递函数矩阵
hf=zeros(ne,nfft);
%计算加速度反应谱传递函数矩阵
for j-0:ne-1
w=2*pi*df*j
wd=w*sqrt(1-dp*dp);
e=exp(-t.*W*dp);
a=t.*wd;
s=sin(a)>*((1-2*dp*dp)/(1-dp*dp));
c=cos(a).*(2*dp/sqrt(1-dp*dp));
% 计算加速度反应谱的脉冲响应函数向量
h=wd*e.*(s+c)/fs;
%通过FFT变换求加速度反应谱传递函数向量
hf(j+1,:)=fft(h,nfft);
end
mm=nn
%进行生成人工地震波迭代计算
%100为最大迭代次数
for k=1:100
% 将幅值谱和相位谱转化为实部和虚部
c=b1.*exp(i*g);
% 将正负圆频率傅里叶谱向量组合成一仙向量
d=[c,c(nfft/2:-1:1)];
%IFFT 变换,并取变换结果实部为生成的地震波
e=ifft(d,nfft);
% 给生成的地震波加上强度包络线
y=en.*real(e(1:nt));
% 计算反应谱
% 对生成的地震波进行FFT变换
yf=fft(y,nfft);
for j=1:ne
% 用地震波FFT变换结果和反应谱传递函数的乘积的逆变换做卷积运算
d=ifft(yf.*hf(j,:),nfft);
% 求各频率对应地震的最大响应
al(j)=max(real(d(1:nt)));
end
% 如果达到指定的迭代次数显于图形
if k==mm
subplot(2,1,1);
%m 同时显示生成的地震波的强度包络线
plot(t,y,t,en,t,-en);
xlabel('时间 (s)');
ylabel('加速度 (g)');
grid on
sublpot(2,1,2);
% 同时显示期望反应谱与反应谱计算谱、
l=1:ne
plot(f(l),a0(l),':'f(l),a1(l));
xlabel('频率 (Hz)');
ylabel('加速度 (g)');
legend('目标谱','计算谱');
grid on;
ig=input('继续迭代次数[取值1-9,否则退出]:');
if ig>0&ig<10 %如果输入数字是1-9
mm=mm+ig
else
break ;
end
end
c=bl
% 期望谱与计算谱的比值来修改傅里叶值谱
j=nb:ne;
bl(j)=c(j).*a0(j)./a1(j);
end
%打开文件输入人工地震动数据
fid=fopen(fno,'W');
for K=1:nt
% 每一行输出两个实型数据,t为时间,y为人工地震动信号值
fprintf(fid,'%f%f\n',t(k),y(k));
end
status=fclose(fid);