采用 MRT-LBM 模拟旋转圆柱绕流---MATLAB代码--王富海2017--基于 MRT-LBM 的流场与声场仿真计算

走远了吗. 提交于 2019-12-02 15:17:13

%这个例子采用 MRT-LBM 模拟旋转圆柱绕流
%基于 MRT-LBM 的流场与声场仿真计算 --王富海2017
%左边速度边界-泊肃叶流,右边压力边界,上下无滑移壁面(全部用非平衡外推格式)
%还是老规矩先宣传一下QQ群: 格子玻尔兹曼救星:293267908。不收费的哦,就是为了早点毕业建的群。
clc
clear
close all
 
%%  设置仿真参数
 
uMax=0.05; %中间最大速度
Re=40;%雷诺数
yLen=81;%垂直方向格子数
xLen=161;%水平方向格子数
cylinderD=(yLen-1)/5;%圆的半径
nu=uMax*cylinderD/Re;%运动粘性
Cs=sqrt(1/3);%格子声速
tau=1/2+3*nu;%松弛时间
omega=1/tau;%松弛频率
step=120000;%最大迭代次数
rho_out=1;%出口密度
uo2=0.1;%圆柱的旋转速度
rhoo=1;%初始化密度
checkStep=100;%收敛计算间隔
saveStep=20;%保存结果间隔
% file Path=uigetdir(cd)%仿真中间过程图片的保存路径
VSSum=[];%所有节点格子速度总和-每 saveStep 步记录一次
VSSum2=[];%所有节点格子速度总和-每 checkStep 步记录一次,监视收敛曲线
dx=1;%相邻格子节点水平间隔
dy=1;%相邻格子节点垂直间隔
dt=1;
y1=1;%下边界垂直坐标
y2=yLen;%上边界垂直坐标
GG=uMax/((y1-y2)^2/4);
for j=1:yLen
  U_in(1,j)=uMax;%左边的速度剖面入口
  V_in(1,j)=0;
end
 
%为上下壁面边界点速度赋值
ub(1:xLen,1)=0;
vb(1:xLen,1)=0;
ub(1:xLen,yLen)=0;
vb(1:xLen,yLen)=0;
f_u(1,1)=0;
f_u(xLen,yLen)=0;
f_v(1,1)=0;
f_v(xLen,yLen)=0;
 
%导入拉格朗日点坐标--圆的方程式(x-xPos)^2+(y-yPos)^2=r^2;
xPos=2*cylinderD+cylinderD/2;%圆心坐标 x
r=cylinderD/2;
yPos=(yLen+1)/2;%圆心坐标 y
 
%%  计算与垂直网格的交点
lagPosChuiZhi=[];%存储拉格朗日点-位置索引
x_Start=1
x_Stop=xLen
y_Start=1
y_Stop=yLen
dx=1
dy=1
for i=x_Start:dx:x_Stop
     delta=r^2-(i-xPos)^2;
     if delta>0
         y1=yPos+sqrt(delta);%垂直交点的真正 y1 坐标
         y2=yPos-sqrt(delta);%垂直交点的真正 y2 坐标
         y1_index=(y1-y_Start)/dy+1;%垂直交点的 y 网格索引
         y2_index=(y2-y_Start)/dy+1;%垂直交点的 y 网格索引
         x_index=(i-x_Start)/dx+1;%x 的网格索引
         lagPosChuiZhi=[lagPosChuiZhi;x_index y1_index;x_index y2_index];
     elseif delta==0
   y1=yPos+sqrt(delta);%垂直交点的真正 y 坐标
         y1_index=(y1-y_Start)/dy+1;
         x_index=(i-x_Start)/dx+1;
         lagPosChuiZhi=[lagPosChuiZhi;x_index y1_index];
     end
end
 
%计算与水平网格的交点
 
lagPosShuiPing=[];%存储拉格朗日点-位置索引
for i2=y_Start:dy:y_Stop
     delta=r^2-(i2-yPos)^2;
     if delta>0
         x1=xPos+sqrt(delta);%水平交点的真正 x1 坐标
         x2=xPos-sqrt(delta);%水平交点的真正 x2 坐标
         x1_index=(x1-x_Start)/dx+1;%水平交点的 x 网格索引
         x2_index=(x2-x_Start)/dx+1;%水平交点的 x 网格索引
         y_index=(i2-y_Start)/dy+1;%y 的网格索引
         lagPosShuiPing=[lagPosShuiPing;x1_index y_index;x2_index y_index];
     elseif delta==0
         x1=xPos+sqrt(delta);%水平交点的真正 x 坐标
         x1_index=(x1-x_Start)/dx+1;
         y_index=(i2-y_Start)/dy+1;
         lagPosShuiPing=[lagPosShuiPing;x1_index y_index];
     end
end
 
%%  为拉格朗日点附上速度
 
lenLagShuiPing=length(lagPosShuiPing);
for i=1:lenLagShuiPing
     xTemp=lagPosShuiPing(i,1);
     yTemp=lagPosShuiPing(i,2);
     if yTemp-yPos>=0 && xTemp-xPos>=0
         thetaTemp=asin((yTemp-yPos)/r);
     end
     if yTemp-yPos>=0 && xTemp-xPos<0
         thetaTemp=pi-asin((yTemp-yPos)/r);
     end  
     if yTemp-yPos<0 && xTemp-xPos>=0
         thetaTemp=2*pi+asin((yTemp-yPos)/r);
     end
     if yTemp-yPos<0 && xTemp-xPos<0
         thetaTemp=pi-asin((yTemp-yPos)/r);
     end      
     %为拉格朗日点速度赋值,uo2 >0  顺时针。    
     lagPosShuiPing(i,3)=uo2*sin(thetaTemp);%u
     lagPosShuiPing(i,4)=-uo2*cos(thetaTemp);%v
end
lenLagChuiZhi=length(lagPosChuiZhi);
for i=1:lenLagChuiZhi
     xTemp=lagPosChuiZhi(i,1);
     yTemp=lagPosChuiZhi(i,2);
     if yTemp-yPos>=0 && xTemp-xPos>=0
         thetaTemp=asin((yTemp-yPos)/r);
     end
     if yTemp-yPos>=0 && xTemp-xPos<0
         thetaTemp=pi-asin((yTemp-yPos)/r);
     end  
     if yTemp-yPos<0 && xTemp-xPos>=0
         thetaTemp=2*pi+asin((yTemp-yPos)/r);
     end
     if yTemp-yPos<0 && xTemp-xPos<0
         thetaTemp=pi-asin((yTemp-yPos)/r);
     end         
     %为拉格朗日点速度赋值,uo2 >0  顺时针。    
     lagPosChuiZhi(i,3)=uo2*sin(thetaTemp);%u
     lagPosChuiZhi(i,4)=-uo2*cos(thetaTemp);%v
end
 
%%
%将索引位置转化为实际坐标
real_lagPosShuiPing=[(lagPosShuiPing(:,1)-1)*dx+x_Start,(lagPosShuiPing(:,2)-1)*dy+y_Start];
% plot(real_lagPosShuiPing(:,1),real_lagPosShuiPing(:,2),'r*')%绘制水平交点-拉格朗日点
 
%将索引位置转化为实际坐标
real_lagPosChuiZhi=[(lagPosChuiZhi(:,1)-1)*dx+x_Start,(lagPosChuiZhi(:,2)-1)*dy+y_Start];
% plot(real_lagPosChuiZhi(:,1),real_lagPosChuiZhi(:,2),'bo')%绘制垂直交点-拉格朗日点
% axis equal
% hold off
%%  计算朗格朗日附近格点-索引
lenShuiPing=length(lagPosShuiPing);
XY_left_index=[];
XY_right_index=[];
for i=1:lenShuiPing
     w1=floor(lagPosShuiPing(i,1));
     w2=ceil(lagPosShuiPing(i,1));
     if w1== w2
         XY_left_index=[XY_left_index;w1-1   lagPosShuiPing(i,2)];
         XY_right_index=[XY_right_index; w1+1   lagPosShuiPing(i,2)];
     else
         XY_left_index=[XY_left_index;w1   lagPosShuiPing(i,2)];
         XY_right_index=[XY_right_index; w2 lagPosShuiPing(i,2)];
     end
end
lenChuiZhi=length(lagPosChuiZhi);
XY_up_index=[];
XY_down_index=[];
for i=1:lenChuiZhi
     w1=floor(lagPosChuiZhi(i,2));
     w2=ceil(lagPosChuiZhi(i,2));
     if w1== w2
         XY_up_index=[XY_up_index; lagPosChuiZhi(i,1)   w1+1];
         XY_down_index=[XY_down_index; lagPosChuiZhi(i,1)   w1-1];
     else
         XY_up_index=[XY_up_index;lagPosChuiZhi(i,1)   w2];
         XY_down_index=[XY_down_index;lagPosChuiZhi(i,1) w1];
     end
end
XY_left_index=round(XY_left_index);
XY_right_index=round(XY_right_index);
XY_up_index=round(XY_up_index);
XY_down_index=round(XY_down_index);
%%
[~,~,c1]=intersect(XY_left_index,XY_up_index,'rows');
[~,~,c2]=intersect(XY_right_index,XY_up_index,'rows');
same_Up_LR=[c1;c2];%重复索引的行索引
[~,~,c3]=intersect(XY_left_index,XY_down_index,'rows');
[~,~,c4]=intersect(XY_right_index,XY_down_index,'rows');
same_Down_LR=[c3;c4];%重复索引的行索引
 
%%
%D2Q9 模型参数
w=[1/9 1/9 1/9 1/9 1/36 1/36 1/36 1/36 4/9 ]%各个方向的权重
cx=[ 1 0 -1 0 1 -1 -1 1 0];%各方向 x 速度分量
cy=[ 0 1 0 -1 1 1 -1 -1 0];%各方向 y 速度分量
M=[1 1 1 1 1 1 1 1 1;-4 -1 -1 -1 -1 2 2 2 2;4 -2 -2 -2 -2 1 1 1 1; ...
       0 1 0 -1 0 1 -1 -1 1;0 -2 0 2 0 1 -1 -1 1;0 0 1 0 -1 1 1 -1 -1; ...
       0 0 -2 0 2 1 1 -1 -1;0 1 -1 1 -1 0 0 0 0;0 0 0 0 0 1 -1 1 -1;]
%  由于分布函数 0 索引被放置在 matlab  索引 9 的位置,所以将 M 第一列放到最后。
M=circshift(M,[-1 -1]);                                                                  
         s1(9)=0;
         s1(3)=s1(9);
         s1(5)=s1(9);
         s1(7)=omega;
         s1(8)=s1(7);
         s1(4)=1.2;
         s1(6)=s1(4);
         s1(1)=omega;
         s1(2)=s1(1)-0.1;
s=diag(s1);%对角矩阵-松弛因子
Minv=inv(M);
Minv_s=Minv*s;
 
%%  网格节点初始化,初始化各节点密度=1,初始化各节点速度为0,初始化各节点分布函数=平衡分布函数
for i=1:xLen
     for j=1:yLen
         rho(i,j)=rhoo;
         u(i,j)=uMax;
         v(i,j)=0;
         t1=u(i,j)^2+v(i,j)^2;%速度 U*V 内积,t1 写到外面,节省计算量
         for k=1:9
             t2=u(i,j)*cx(k)+v(i,j)*cy(k);%U*C 内积             
             f(k,i,j)=rho(i,j)*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);%  计算初始态下的  分布函数=平衡分布函数                         
             Fi(k,i,j)=0;%初始化离散的边界作用力分布函数,初始值赋为 0
         end
     end
end
 
%%
%主循环
tstart = tic;%计算时钟
[meshX,meshY]=meshgrid(1:xLen,yLen:-1:1);%产生网格数据。
C_zhuli=[0];
C_shengli=[0];
figure
fplot=plot(C_zhuli)
hold on
fplot2=plot(C_shengli,'r')
% ylim([-3 3])
figure
pc=pcolor(meshX,meshY,ones(yLen,xLen));%绘制伪彩图
shading interp%伪彩色图---shading interp 会区分每个线形区域的颜色,并且插入与其相近的颜色
axis equal
 
ylim([1 yLen])
 
for kk=1:step
 
     step2=kk%显示程序的步进
     mm=max(max(rho))%观察最大密度    
     if mm>100%判断仿真是否发散
 break;
 
     end

     %1 碰撞过程
 
     for i=1:xLen
 
         for j=1:yLen %  
             %速度空间到动量空间
             m=M*f(1:9,i,j);
 
             %计算平衡动量
             m_eq(9,1)=rho(i,j);
             m_eq(1,1)=rho(i,j)*(-2+3*(u(i,j)^2+v(i,j)^2));
             m_eq(2,1)=rho(i,j)*(1-3*(u(i,j)^2+v(i,j)^2));
             m_eq(3,1)=rho(i,j)*u(i,j);
             m_eq(4,1)=-rho(i,j)*u(i,j);
             m_eq(5,1)=rho(i,j)*v(i,j);
             m_eq(6,1)=-rho(i,j)*v(i,j);
             m_eq(7,1)=rho(i,j)*(u(i,j)^2-v(i,j)^2);
             m_eq(8,1)=rho(i,j)*u(i,j)*v(i,j);
             %在动量空间松弛
             m_temp=Minv_s*(m-m_eq)-Minv*Fi(:,i,j);
 
             for k=1:9
                 f(k,i,j)=f(k,i,j)-m_temp(k);
             end
         end
     end
 
     % 2 迁移过程
     f2=f;%将碰撞后分布函数保存给变量 f2
     for i=1:9
         f(i,:,: ) = circshift(f2(i,:,: ), [0,cx(i),cy(i)]);
     end
 
     %非平衡外推格式-上下无滑移壁面
 
     for i=2:xLen-1%下边界
 
         %计算相邻点的速度
         j=2;
         rho(i,j)=sum(f(:,i,j));%计算密度
        uSum=0;
         vSum=0;
 
         for k=1:9
             uSum=uSum+f(k,i,j)*cx(k);
             vSum=vSum+f(k,i,j)*cy(k);
         end
 
         u(i,j)=uSum/rho(i,j);
         v(i,j)=vSum/rho(i,j);
 
         %计算边界上的平衡分布函数(用相邻点密度的代替边界密度)
         t1=u(i,j)^2+v(i,j)^2;%速度 U*V 内积
         t1b=ub(i,1)^2+vb(i,1)^2;
 
         for k=1:9%[2 5 6]%每个节点 9 个分量
 
             t2=u(i,j)*cx(k)+v(i,j)*cy(k);%U*C 内积
             t2b=ub(i,1)*cx(k)+vb(i,1)*cy(k);%U*C 内积
             %  计算边界平衡分布函数-用相邻点的密度代替边界密度
             feq(k,i,1)=rho(i,j)*w(k)*(1+3*t2b+4.5*t2b^2-1.5*t1b);
             %  计算相邻点非平衡分布函数
             fneq(k,i,j)=f(k,i,j)-rho(i,j)*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);
             %计算边界分布函数
             f(k,i,1)=feq(k,i,1)+fneq(k,i,j);
         end
     end
 
     for i=2:xLen-1%上边界
 
         %计算相邻点的速度
         j=yLen-1;
         rho(i,j)=sum(f(:,i,j));%计算密度
         uSum=0;
         vSum=0;
 
         for k=1:9
             uSum=uSum+f(k,i,j)*cx(k);
             vSum=vSum+f(k,i,j)*cy(k);
         end
 
         u(i,j)=uSum/rho(i,j);
         v(i,j)=vSum/rho(i,j);
 
         %计算边界上的平衡分布函数(用相邻点的密度代替边界密度)
   t1=u(i,j)^2+v(i,j)^2;%速度 U*V 内积
         t1b=ub(i,yLen)^2+vb(i,yLen)^2;
         for k=1:9%[4 7 8]%每个节点 9 个分量
             t2=u(i,j)*cx(k)+v(i,j)*cy(k);%U*C 内积
             t2b=ub(i,yLen)*cx(k)+vb(i,yLen)*cy(k);%U*C 内积
             %  计算边界平衡分布函数-用相邻点的密度代替边界密度
             feq(k,i,yLen)=rho(i,j)*w(k)*(1+3*t2b+4.5*t2b^2-1.5*t1b);
             %  计算相邻点非平衡分布函数
             fneq(k,i,j)=f(k,i,j)-rho(i,j)*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);
             %计算边界分布函
             f(k,i,yLen)=feq(k,i,yLen)+fneq(k,i,j);
         end
     end
 
        %非平衡外推模式-施加左右边界条件,修正所有分布函数变量  
         %左速度边界-非平衡外推格式
         u(1,:)=U_in;
         v(1,:)=V_in;         
     for j=1:yLen
         %计算相邻点的速度
         i=2;
         rho(i,j)=sum(f(:,i,j));%计算密度
         uSum=0;
         vSum=0;
         for k=1:9
             uSum=uSum+f(k,i,j)*cx(k);
             vSum=vSum+f(k,i,j)*cy(k);
         end
 
         u(i,j)=uSum/rho(i,j);
         v(i,j)=vSum/rho(i,j);
         for k=1:9%[1 5 8]%每个节点 9 个分量             
             %  计算边界平衡分布函数-用相邻点的密度代替边界密度
             i=1;             
             t1=u(i,j)^2+v(i,j)^2;%速度 U*V 内积
             t2=u(i,j)*cx(k)+v(i,j)*cy(k);%U*C 内积
             feq(k,1,j)=rho(2,j)*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);
    %  计算相邻点非平衡分布函数
             i=2;             
             t1=u(i,j)^2+v(i,j)^2;%速度 U*V 内积
             t2=u(i,j)*cx(k)+v(i,j)*cy(k);%U*C 内积             
             fneq(k,i,j)=f(k,i,j)-rho(i,j)*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);
             %计算边界分布函数
             f(k,1,j)=feq(k,1,j)+fneq(k,i,j);
         end         
     end
 
     %   右边界-压力出口-
     for j=1:yLen
         %计算相邻点的速度
         i=xLen-1;
         rho(i,j)=sum(f(:,i,j));%计算密度
         uSum=0;
         vSum=0;
         for k=1:9
             uSum=uSum+f(k,i,j)*cx(k);
             vSum=vSum+f(k,i,j)*cy(k);
         end
 
         u(i,j)=uSum/rho(i,j);
 
         v(i,j)=vSum/rho(i,j);
 
         %计算边界上的平衡分布函数(边界上的密度,用相邻点的速度代替边界速度)
 
         t1=u(i,j)^2+v(i,j)^2;%速度 U*V 内积
         for k=1:9%[3 6 7]%每个节点 9 个分量
             t2=u(i,j)*cx(k)+v(i,j)*cy(k);%U*C 内积
             %  计算边界平衡分布函数-用相邻点的速度代替边界速度
             feq(k,xLen,j)=rho_out*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);
             %  计算相邻点非平衡分布函数
             fneq(k,i,j)=f(k,i,j)-rho(i,j)*w(k)*(1+3*t2+4.5*t2^2-1.5*t1);
             %计算边界分布函数
            f(k,xLen,j)=feq(k,xLen,j)+fneq(k,i,j);
         end          
     end
 
     %计算宏观量
      for i=1:xLen
         for j=1:yLen
             rho(i,j)=sum(f(:,i,j));%计算每一点的密度
         end
     end
 
     for i=1:xLen
 
         for j=1:yLen
             uSum=0;
             vSum=0;
             for k=1:9
                 uSum=uSum+f(k,i,j)*cx(k);
                 vSum=vSum+f(k,i,j)*cy(k);
             end
             u(i,j)=uSum/rho(i,j);%计算速度场
             v(i,j)=vSum/rho(i,j);
         end
     end
 
     u_Before=u;
     v_Before=v;
 
     %%
 
         %3.5  圆柱边界
 
     %已经得到了拉格朗日点的坐标点位置,分别为 lagPosChuiZhi 和 lagPosShuiPing
     %3.5.1 进行水平拉格朗日交点的左右点速度修正
     u_Before=u;
     v_Before=v;
     len_ShuiPing=length(lagPosShuiPing);
 
     for i=1:len_ShuiPing
 
         %对左边的点修正采用二阶拉格朗日插值修正
         xb=lagPosShuiPing(i,1);
         x1=XY_left_index(i,1);
         x2=XY_left_index(i,1)-1;
         x3=XY_right_index(i,1)+1;
         y=XY_left_index(i,2);
 
         %用 xb,x2,x3 修正 x1
 
         %从左到右依次是 x3 x2 x1? xb
        u_xb=lagPosShuiPing(i,3);%固定边界
         u_x1=u_Before(x1,y);
         u_x2=u_Before(x2,y);
         u_x3=u_Before(x3,y);
 
         %二阶拉格朗日插值

u_x1_new=u_xb*(x1-x2)*(x1-x3)/((xb-x2)*(xb-x3))+u_x2*(x1-xb)*(x1-x3)/((x2-xb)*(x2-x3))+u_x3*(...
x1-xb)*(x1-x2)/((x3-xb)*(x3-x2));         
         v_xb=lagPosShuiPing(i,4);%固定边界
         v_x1=v_Before(x1,y);
         v_x2=v_Before(x2,y);
         v_x3=v_Before(x3,y);
v_x1_new=v_xb*(x1-x2)*(x1-x3)/((xb-x2)*(xb-x3))+v_x2*(x1-xb)*(x1-x3)/((x2-xb)*(x2-x3))+v_x3*(...
x1-xb)*(x1-x2)/((x3-xb)*(x3-x2));  
         %更新速度值
         u(x1,y)=u_x1_new;
         v(x1,y)=v_x1_new;
 
         %计算反馈力
 
         rho_temp=sum(f(:,x1,y));
         f_u(x1,y)=2*rho_temp*(u_x1_new-u_x1)/dt;
         f_v(x1,y)=2*rho_temp*(v_x1_new-v_x1)/dt;
 
         %计算离散的边界作用力分布函数
 
         Fi(1:9,x1,y)=getFi(u(x1,y),v(x1,y),f_u(x1,y),f_v(x1,y),s1);

         %对右边的点修正
         xb=lagPosShuiPing(i,1);
         x1=XY_right_index(i,1);
         x2=XY_left_index(i,1)-1;
         x3=XY_right_index(i,1)+1;
         y=XY_right_index(i,2);
 
         %用 xb,x2,x3 修正 x1
         %从左到右依次是  xb x1-?   x2 x3
 
         u_xb=lagPosShuiPing(i,3);%固定边界
          u_x1=u_Before(x1,y);
          u_x2=u_Before(x2,y);
          u_x3=u_Before(x3,y);
          %二阶拉格朗日插值

u_x1_new=u_xb*(x1-x2)*(x1-x3)/((xb-x2)*(xb-x3))+u_x2*(x1-xb)*(x1-x3)/((x2-xb)*(x2-x3))+u_x3*(...
x1-xb)*(x1-x2)/((x3-xb)*(x3-x2));
         v_xb=lagPosShuiPing(i,4);%固定边界
         v_x1=v_Before(x1,y);
         v_x2=v_Before(x2,y);
         v_x3=v_Before(x3,y);
 
        
v_x1_new=v_xb*(x1-x2)*(x1-x3)/((xb-x2)*(xb-x3))+v_x2*(x1-xb)*(x1-x3)/((x2-xb)*(x2-x3))+v_x3*(...
x1-xb)*(x1-x2)/((x3-xb)*(x3-x2));
 
         %更新速度值
 
         u(x1,y)=u_x1_new;
         v(x1,y)=v_x1_new;
 
         %计算反馈力
         rho_temp=sum(f(:,x1,y));
         f_u(x1,y)=2*rho_temp*(u_x1_new-u_x1)/dt;
         f_v(x1,y)=2*rho_temp*(v_x1_new-v_x1)/dt;
         %计算离散的边界作用力分布函数
         Fi(1:9,x1,y)=getFi(u(x1,y),v(x1,y),f_u(x1,y),f_v(x1,y),s1);
 
     end

     len_ChuiZhi=length(lagPosChuiZhi);
     for i=1:len_ChuiZhi
         %%  对上边的点修正
         yb=lagPosChuiZhi(i,2);
         y1=XY_up_index(i,2);
         y2=XY_up_index(i,2)+1;
         y3=XY_down_index(i,2)-1;
         x=XY_up_index(i,1);
 
         %用 yb,y2,y3 修正 y1
         %从上到下依次是 y3   y2 y1-? yb     
         u_yb=lagPosChuiZhi(i,3);%固定边界
         u_y1=u_Before(x,y1);
         u_y2=u_Before(x,y2);
         u_y3=u_Before(x,y3);
         %二阶拉格朗日插值
u_y1_new=u_yb*(y1-y2)*(y1-y3)/((yb-y2)*(yb-y3))+u_y2*(y1-yb)*(y1-y3)/((y2-yb)*(y2-y3))+u_y3*(...
y1-yb)*(y1-y2)/((y3-yb)*(y3-y2));
         v_yb=lagPosChuiZhi(i,4);%固定边界
         v_y1=v_Before(x,y1);
         v_y2=v_Before(x,y2);
         v_y3=v_Before(x,y3);

v_y1_new=v_yb*(y1-y2)*(y1-y3)/((yb-y2)*(yb-y3))+v_y2*(y1-yb)*(y1-y3)/((y2-yb)*(y2-y3))+v_y3*(...
y1-yb)*(y1-y2)/((y3-yb)*(y3-y2));
 
 
         %更新新的节点速度值
         %判断是不是需要 2 次修正      
         if ismember(i,same_Up_LR)
             u(x,y1)=0.5*(u(x,y1)+u_y1_new);
             v(x,y1)=0.5*(v(x,y1)+v_y1_new);             
         else
             u(x,y1)=u_y1_new;
             v(x,y1)=v_y1_new;
         end
 
         %计算 f 反馈力
         rho_temp=sum(f(:,x,y1));            
         f_u(x,y1)=2*rho_temp*(u(x,y1)-u_y1)/dt;
         f_v(x,y1)=2*rho_temp*(v(x,y1)-v_y1)/dt;
 
         %计算离散的边界作用力分布函数         
         Fi(1:9,x,y1)=getFi(u(x,y1),v(x,y1),f_u(x,y1),f_v(x,y1),s1);
         %  对下边的点修正,取欲修正点的下边两个点和边界点,采用二阶拉格朗日插值修正
         yb=lagPosChuiZhi(i,2);
         y1=XY_down_index(i,2);
         y2=XY_up_index(i,2)+1;
         y3=XY_down_index(i,2)-1;
         x=XY_down_index(i,1);
 
         %用 yb,y2,y3 修正 y1
         %从上到下依次是  yb y1? y3 y2  
         u_yb=lagPosChuiZhi(i,3);%固定边界
         u_y1=u_Before(x,y1);
         u_y2=u_Before(x,y2);
         u_y3=u_Before(x,y3);
         %二阶拉格朗日插值
u_y1_new=u_yb*(y1-y2)*(y1-y3)/((yb-y2)*(yb-y3))+u_y2*(y1-yb)*(y1-y3)/((y2-yb)*(y2-y3))+u_y3*(...
y1-yb)*(y1-y2)/((y3-yb)*(y3-y2));         
 
         v_yb=lagPosChuiZhi(i,4);%固定边界
         v_y1=v_Before(x,y1);
         v_y2=v_Before(x,y2);
         v_y3=v_Before(x,y3);

v_y1_new=v_yb*(y1-y2)*(y1-y3)/((yb-y2)*(yb-y3))+v_y2*(y1-yb)*(y1-y3)/((y2-yb)*(y2-y3))+v_y3*(...
y1-yb)*(y1-y2)/((y3-yb)*(y3-y2));  
 
         %判断是不是需要 2 次修正
         if ismember(i,same_Down_LR)
             u(x,y1)=0.5*(u(x,y1)+u_y1_new);
             v(x,y1)=0.5*(v(x,y1)+v_y1_new);
         else
             u(x,y1)=u_y1_new;
             v(x,y1)=v_y1_new;
         end
 
         %计算 f 反馈力
         rho_temp=sum(f(:,x,y1));            
         f_u(x,y1)=2*rho_temp*(u(x,y1)-u_y1)/dt;
         f_v(x,y1)=2*rho_temp*(v(x,y1)-v_y1)/dt;         
         %计算离散的边界作用力分布函数         
         Fi(1:9,x,y1)=getFi(u(x,y1),v(x,y1),f_u(x,y1),f_v(x,y1),s1);
     end   
  %每 saveStep 步保存下误差,检查收敛性     
 
     if mod(kk,saveStep)==0
         temp=0;
         for i=1:xLen
             for j=1:yLen
                 temp=temp+sqrt(u(i,j)^2+v(i,j)^2);%节点的速度和
             end
         end
         VSSum2=[VSSum2;temp];
         u2=rot90(u);
         v2=rot90(v);
 
         for i=1:xLen
             for j=1:yLen
                 speed(j,i)=sqrt(u2(j,i)^2+v2(j,i)^2);%节点的速度
             end
         end
         set(pc,'cdata',speed);
         drawnow
 
%          saveas(gcf,[file Path,'\',num2str(kk/saveStep),'.tif'])
%          pic Length=kk/saveStep;%保存的图片数量
         %
         ff=0;
         ff2=0;
         for i=1:xLen
             for j=1:yLen
                 %if (i-xPos)^2+(j-yPos)^2-r^2>0
                     ff=ff+f_u(i,j);
                     ff2=ff2+f_v(i,j);
                 %end
             end
 
         end
 
         %阻力系数与升力系数
         C_zhuli(kk/saveStep)=-2*ff/(rhoo*uMax^2*cylinderD);
         C_shengli(kk/saveStep)=-2*ff2/(rhoo*uMax^2*cylinderD);   
         set(fplot,'ydata',C_zhuli);
         set(fplot2,'ydata',C_shengli);         
         drawnow      
 
   %每 checkStep 次保存下误差
         if mod(kk,checkStep)==0
             VSSum=[VSSum;temp];
             save;
             %计算节点速度和变化(网格点总数*误差),判断是否跳出循环
             if length(VSSum)>=2 && abs(VSSum(end)-VSSum(end-1))/VSSum(end-1)<=(1e-6)
                 fprintf('迭代步数:%d \n',kk);
                 fprintf('迭代误差:%d\n',abs(VSSum(end)-VSSum(end-1))/(xLen*yLen));
                  break;
             end
         end
     end
end
 
runtime = toc(tstart);%仿真用的时间
 
%结果后处理
 
u2=rot90(u);
v2=rot90(v);
 
for i=1:xLen
     for j=1:yLen
         speed(j,i)=sqrt(u2(j,i)^2+v2(j,i)^2);
     end
end
save( ['re' num2str(Re) '-' num2str(uMax) '-' num2str(uo2) '.mat'])
 
%速度场彩图
figure
pcolor(meshX,meshY,speed);
shading interp
axis equal tight
ylim([1 yLen])
%绘制流线图 1
figure
startY=linspace(1,xLen,100);
startX=zeros(size(startY))+1;
streamline(meshX,meshY,u2,v2,startX,startY,2)  
axis equal tight
 
%绘制流线图 2
figure
streamslice(meshX,meshY,u2,v2,8,'nearest ' )
ylim([1 yLen])
axis equal tight
hold off
 
%  动态观看保存的计算图片
% figure
 
% for i=1:pic Length
 
%      i
 
%      picdata=imread([file Path,'\',num2str(i),'.tif']);
 
%      pause(0.05)
 
%      imshow(picdata);
 
% end

注意!以下是子函数!

注意!以下是子函数!

注意!以下是子函数!

function result=getFi(uu,vv,f_uTemp,f_vTemp,s1)   
 
         result(9)=0;
         result(1)=6*(1-0.5*s1(1))*(uu*f_uTemp+vv*f_vTemp);
         result(2)=-6*(1-0.5*s1(2))*(uu*f_uTemp+vv*f_vTemp);
         result(3)=f_uTemp;
         result(4)=-(1-0.5*s1(4))*f_uTemp;
         result(5)=f_vTemp;
         result(6)=-(1-0.5*s1(6))*f_vTemp;
         result(7)=2*(1-0.5*s1(7))*(uu*f_uTemp-vv*f_vTemp);
         result(8)=(1-0.5*s1(8))*(uu*f_vTemp+vv*f_uTemp);

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!