Matlab 在模拟反弹粒子时,稍有不同的最大时间会产生截然不同的中间结果。我做错了什么?

Matlab 在模拟反弹粒子时,稍有不同的最大时间会产生截然不同的中间结果。我做错了什么?,matlab,simulation,Matlab,Simulation,我试图模拟一个粒子在一个盒子里弹跳,盒子的壁以给定的速度定律移动(现在被认为是锯齿形的),并记录粒子的能量作为时间的函数。虽然我做了一些不完全准确的近似(我将在我的代码示例中对此进行扩展),但我遇到了一个问题,即稍微不同的最大时间会产生与我预期结果一致的最大时间相比大不相同的结果(参见图:在图中,最大时间为200,而在图中,最大时间为201。这些图来自二维版本的代码,尽管即使在一维中问题仍然存在) 在一维环境中,我的尝试如下: 首先,我设置了最小时间、最大时间和时间步长,然后以时间步长的间隔生成

我试图模拟一个粒子在一个盒子里弹跳,盒子的壁以给定的速度定律移动(现在被认为是锯齿形的),并记录粒子的能量作为时间的函数。虽然我做了一些不完全准确的近似(我将在我的代码示例中对此进行扩展),但我遇到了一个问题,即稍微不同的最大时间会产生与我预期结果一致的最大时间相比大不相同的结果(参见图:在图中,最大时间为200,而在图中,最大时间为201。这些图来自二维版本的代码,尽管即使在一维中问题仍然存在)

在一维环境中,我的尝试如下:

首先,我设置了最小时间、最大时间和时间步长,然后以时间步长的间隔生成从最小时间到最大时间的时间数组:

TMin = 0;
TMax = 200;
TimeStep = .0001;
times = linspace(TMin,TMax,(TMax-TMin)/TimeStep);
据我所知,这一步是为了正确生成我想要的时间数组

x = zeros(1,TNum(2));
vx = zeros(1,TNum(2));
在这一步中,我还设置了粒子的初始条件。接下来,我设置了壁振动的参数,包括振幅和频率,以定义速度定律,例如

VLeft = ALeft*FLeft*sawtooth(FLeft.*times+SLeft)
其中VLeft是左壁的速度,ALeft是位置振荡的振幅,FLeft是振荡的频率,SLeft是相对于另一面壁的相移。据我所知,这一步也在做我想做的。接下来,我设置了壁的初始条件,并生成了壁的位置使用黎曼和近似从速度定律导出l

Left(1)=-1; %For example...
for i=2:TNum(2)
    Left(i)=Left(i-1)+VLeft(i).*(TimeStep);
end
只要我使用一个足够小的TimeStep值(这是基于我的计算方式我所期望的),这似乎可以为墙的位置生成正确的形式,作为时间的函数。对正确的墙也会进行类似的时间演化

下一步是,我尝试生成粒子的位置和速度,作为时间的函数,我想这一定是出了问题的地方

for i=2:TNum(2)

    x(i)=x(i-1)+vx(i-1)*(TimeStep);%distance=velocity*time

    if x(i) < Right(i) && x(i) > Left(i) 
    vx(i)=vx(i-1); %If it doesn't hit a wall, velocity doesn't change
    end

    if x(i) < Left(i) || x(i) == Left(i) %If it hits the left wall, bounce off
    vx(i)=-vx(i-1)+VLeft(i);
    x(i) = Left(i)+abs(x(i)-Left(i));
    end

    if x(i) > Right(i) || x(i) == Right(i) %If it hits the right wall, bounce off
    vx(i)=-vx(i-1)+VRight(i);
    x(i) = Right(i)-abs(Right(i)-x(i));
    end
end
我真正无法理解的是,为什么同一时间步长的最大时间变化会产生如此不同的结果。减少时间步长会增加结果匹配的区域,但如果我正确理解代码的操作,那么最大时间的增加不应该改变低层发生的任何事情时间数组的值在该点之前是相同的

很抱歉,这个问题太冗长和笼统,但我真的不确定我在这里做错了什么,我想提供尽可能多的信息

编辑:我已经为下面的二维版本添加了完整的代码

%--------- THE TIME BLOCK ------------------------------------------------%

TMin = 0;
TMax = 201;
TimeStep = .001;
TDensity = (TMax-TMin)/TimeStep; %Declare instance variables that determine the time steps

times = linspace(TMin,TMax,TDensity); %Generate the array of time steps

 TNum = size(times); %For looping purposes and generating velocity, position arrays


%-------- THE OBJECT INITIAL CONDITIONS BLOCK-----------------------------%

Lx = 1; %Half the length of the box, which spans from -Lx to Lx
Ly = 1; %Half the width of the box, from -Ly to Ly

x0 = 0; %Initial x position
v0x = .1; %Initial x velocity
y0 = 0; %Initial y position
v0y = .1; %Initial y velocity

x = zeros(1,TNum(2));
vx = zeros(1,TNum(2)); %Initialize the arrays for position and velocity
y = zeros(1,TNum(2));
vy = zeros(1,TNum(2));

%------ WALL INITIAL CONDITIONS BLOCK ------------------------------------%

ALeft = 0.15; %Determines the size of the oscillations
ARight = 0.2;
ATop = 0.25;
ABottom = 0.12;

FLeft = 1; %Frequencies
FRight = 0.2;
FTop = 3;
FBottom = 0.2;


SLeft = pi/2; %Phase _S_hifts
SRight = 0;

STop = pi/2;
SBottom = 0;

Left = zeros(1,TNum(2));
Right = zeros(1,TNum(2));
Top = zeros(1,TNum(2));
Bottom = zeros(1,TNum(2));

VLeft = ALeft*FLeft*sawtooth(FLeft.*times+SLeft);
VRight = ARight*FRight*sawtooth(FRight.*times+SRight);
VTop = ATop*FTop*sawtooth(FTop.*times+STop);
VBottom = ABottom*FBottom*sawtooth(FBottom.*times+SBottom);

%---- TIME TO MOVE -------------------------------------------------------%

x(1)=x0; %Set the initial conditions for the variable arrays
y(1)=y0;
vx(1)=v0x;
vy(1)=v0y;
Left(1)=-Lx;
Right(1)=Lx;
Top(1)=Ly;
Bottom(1)=-Ly;

for i=2:TNum(2)
    Left(i)=Left(i-1)+(1/2)*TimeStep*(VLeft(i-1)+VLeft(i)); 
    Right(i)=Right(i-1)+(1/2)*TimeStep*(VRight(i-1)+VRight(i));
    Top(i)=Top(i-1)+(1/2)*TimeStep*(VTop(i-1)+VTop(i));
    Bottom(i)=Bottom(i-1)+(1/2)*TimeStep*(VBottom(i-1)+VBottom(i));
end

for i=2:TNum(2)

    x(i)=x(i-1)+vx(i-1)*(TimeStep);%distance=velocity*time
    y(i)=y(i-1)+vy(i-1)*(TimeStep);

    if x(i) < Right(i) && x(i) > Left(i) %If it doesn't hit a wall, velocity doesn't change
        vx(i)=vx(i-1);
    end

    if y(i) < Top(i) && y(i) > Bottom(i) %If it doesn't hit a wall, velocity doesn't change
        vy(i)=vy(i-1);
    end

    if x(i) < Left(i) %If it hits the left wall, bounce off
        vx(i)=-vx(i-1)+VLeft(i);
        x(i) = Left(i)+abs(x(i)-Left(i));
    end

    if x(i) > Right(i) %If it hits the right wall, bounce off
        vx(i)=-vx(i-1)+VRight(i);
        x(i) = Right(i)-abs(Right(i)-x(i));
    end

    if y(i) < Bottom(i) %If it hits the bottom wall, bounce off
        vy(i)=-vy(i-1)+VBottom(i);
        y(i) = Bottom(i)+abs(y(i)-Bottom(i));
    end

    if y(i) > Top(i) %If it hits the top wall, bounce off
        vy(i)=-vy(i-1)+VTop(i);
        y(i) = Top(i)-abs(Top(i)-y(i));
    end
end

Energy = zeros(1,TNum(2));

for i=1:TNum(2)
    Energy(i)=vx(i)^2+vy(i)^2;
end

% figure
% plot(x,y);
% title('Particle Trajectory')
% xlabel('X Position')
% ylabel('Y Position')

% figure
% subplot(2,1,1)
% plot(times,x);
% hold on
% plot(times,Right);
% plot(times,Left);
% ylabel('X Position')
% title('One-Dimensional Positions of Particle and Walls')
% subplot(2,1,2)
% plot(times, y);
% hold on
% plot(times,Top);
% plot(times,Bottom);
% xlabel('Time')
% ylabel('Y Position')



figure
plot(times,Energy);
axis([0 200 0 80])
title('Particle Energy (v^2)')
xlabel('Time')
ylabel('Energy')
%-----------时间段-----------------------------------------%
TMin=0;
TMax=201;
时间步长=.001;
TDensity=(TMax TMin)/TimeStep;%声明确定时间步长的实例变量
times=linspace(TMin,TMax,TDensity);%生成时间步长数组
TNum=大小(次);%用于循环和生成速度、位置阵列
%--------对象初始条件块-----------------------------------------%
Lx=1;%长方体长度的一半,从-Lx到Lx
Ly=1;%方框宽度的一半,从-Ly到Ly
x0=0;%初始x位置
v0x=.1;%初始x速度
y0=0;%初始y位置
v0y=.1;%初始y速度
x=零(1,TNum(2));
vx=零(1,TNum(2));%初始化阵列的位置和速度
y=零(1,TNum(2));
vy=零(1,TNum(2));
%------墙初始条件块---------------------------------------------------%
ALeft=0.15;%确定振荡的大小
A右=0.2;
顶部=0.25;
abotom=0.12;
FLeft=1;%频率
恐惧=0.2;
FTop=3;
FBottom=0.2;
SLeft=π/2;%相移
SRight=0;
停止=pi/2;
SBottom=0;
左=零(1,TNum(2));
右=零(1,TNum(2));
Top=零(1,TNum(2));
底部=零(1,TNum(2));
VLeft=ALeft*FLeft*锯齿(FLeft.*倍+SLeft);
V右=右*右*锯齿(右*倍+右);
VTop=顶部*FTop*锯齿(FTop.*次+停止);
VBottom=ABottom*FBottom*锯齿(FBottom.*倍+SBottom);
%----移动时间----------------------------------------------%
x(1)=x0;%设置变量数组的初始条件
y(1)=y0;
vx(1)=v0x;
vy(1)=v0y;
左(1)=-Lx;
右(1)=Lx;
Top(1)=Ly;
底部(1)=-Ly;
对于i=2:TNum(2)
左(i)=左(i-1)+(1/2)*时间步长*(VLeft(i-1)+VLeft(i));
右(i)=右(i-1)+(1/2)*时间步*(v右(i-1)+v右(i));
顶部(i)=顶部(i-1)+(1/2)*时间步长*(VTop(i-1)+VTop(i));
底部(i)=底部(i-1)+(1/2)*时间步长*(VBottom(i-1)+VBottom(i));
结束
对于i=2:TNum(2)
x(i)=x(i-1)+vx(i-1)*(时间步);%距离=速度*时间
y(i)=y(i-1)+vy(i-1)*(时间步);
如果x(i)<右(i)&&x(i)>左(i)%,如果它没有撞到墙,速度不会改变
vx(i)=vx(i-1);
结束
如果y(i)Bottom(i)%如果它没有撞到墙,速度不会改变
vy(i)=vy(i-1);
结束
如果x(i)<左(i)%如果击中左墙,则反弹
vx(i)=-vx(i-1)+VLeft(i);
x(i)=左(i)+abs(x(i)-左(i));
结束
如果x(i)>Right(i)%如果它撞到了右边的墙,就会反弹
vx(i)=-vx(i-1)+VRight(i);
x(i)=右(i)-abs(右(i)-x(i));
结束
如果y(i)顶部(i)%如果它撞到顶墙,则反弹
vy(i)=-vy(i-1)+VTop(i);
y(i)=顶部(i)-abs(顶部(i)-y(i));
结束
结束
能量=零(1,TNum(2));
对于i=1:TNum(2)
能量(i)=vx(i)^2+vy(i)^2;
结束
%身材
%图(x,y);
%标题(“粒子Traje”
%--------- THE TIME BLOCK ------------------------------------------------%

TMin = 0;
TMax = 201;
TimeStep = .001;
TDensity = (TMax-TMin)/TimeStep; %Declare instance variables that determine the time steps

times = linspace(TMin,TMax,TDensity); %Generate the array of time steps

 TNum = size(times); %For looping purposes and generating velocity, position arrays


%-------- THE OBJECT INITIAL CONDITIONS BLOCK-----------------------------%

Lx = 1; %Half the length of the box, which spans from -Lx to Lx
Ly = 1; %Half the width of the box, from -Ly to Ly

x0 = 0; %Initial x position
v0x = .1; %Initial x velocity
y0 = 0; %Initial y position
v0y = .1; %Initial y velocity

x = zeros(1,TNum(2));
vx = zeros(1,TNum(2)); %Initialize the arrays for position and velocity
y = zeros(1,TNum(2));
vy = zeros(1,TNum(2));

%------ WALL INITIAL CONDITIONS BLOCK ------------------------------------%

ALeft = 0.15; %Determines the size of the oscillations
ARight = 0.2;
ATop = 0.25;
ABottom = 0.12;

FLeft = 1; %Frequencies
FRight = 0.2;
FTop = 3;
FBottom = 0.2;


SLeft = pi/2; %Phase _S_hifts
SRight = 0;

STop = pi/2;
SBottom = 0;

Left = zeros(1,TNum(2));
Right = zeros(1,TNum(2));
Top = zeros(1,TNum(2));
Bottom = zeros(1,TNum(2));

VLeft = ALeft*FLeft*sawtooth(FLeft.*times+SLeft);
VRight = ARight*FRight*sawtooth(FRight.*times+SRight);
VTop = ATop*FTop*sawtooth(FTop.*times+STop);
VBottom = ABottom*FBottom*sawtooth(FBottom.*times+SBottom);

%---- TIME TO MOVE -------------------------------------------------------%

x(1)=x0; %Set the initial conditions for the variable arrays
y(1)=y0;
vx(1)=v0x;
vy(1)=v0y;
Left(1)=-Lx;
Right(1)=Lx;
Top(1)=Ly;
Bottom(1)=-Ly;

for i=2:TNum(2)
    Left(i)=Left(i-1)+(1/2)*TimeStep*(VLeft(i-1)+VLeft(i)); 
    Right(i)=Right(i-1)+(1/2)*TimeStep*(VRight(i-1)+VRight(i));
    Top(i)=Top(i-1)+(1/2)*TimeStep*(VTop(i-1)+VTop(i));
    Bottom(i)=Bottom(i-1)+(1/2)*TimeStep*(VBottom(i-1)+VBottom(i));
end

for i=2:TNum(2)

    x(i)=x(i-1)+vx(i-1)*(TimeStep);%distance=velocity*time
    y(i)=y(i-1)+vy(i-1)*(TimeStep);

    if x(i) < Right(i) && x(i) > Left(i) %If it doesn't hit a wall, velocity doesn't change
        vx(i)=vx(i-1);
    end

    if y(i) < Top(i) && y(i) > Bottom(i) %If it doesn't hit a wall, velocity doesn't change
        vy(i)=vy(i-1);
    end

    if x(i) < Left(i) %If it hits the left wall, bounce off
        vx(i)=-vx(i-1)+VLeft(i);
        x(i) = Left(i)+abs(x(i)-Left(i));
    end

    if x(i) > Right(i) %If it hits the right wall, bounce off
        vx(i)=-vx(i-1)+VRight(i);
        x(i) = Right(i)-abs(Right(i)-x(i));
    end

    if y(i) < Bottom(i) %If it hits the bottom wall, bounce off
        vy(i)=-vy(i-1)+VBottom(i);
        y(i) = Bottom(i)+abs(y(i)-Bottom(i));
    end

    if y(i) > Top(i) %If it hits the top wall, bounce off
        vy(i)=-vy(i-1)+VTop(i);
        y(i) = Top(i)-abs(Top(i)-y(i));
    end
end

Energy = zeros(1,TNum(2));

for i=1:TNum(2)
    Energy(i)=vx(i)^2+vy(i)^2;
end

% figure
% plot(x,y);
% title('Particle Trajectory')
% xlabel('X Position')
% ylabel('Y Position')

% figure
% subplot(2,1,1)
% plot(times,x);
% hold on
% plot(times,Right);
% plot(times,Left);
% ylabel('X Position')
% title('One-Dimensional Positions of Particle and Walls')
% subplot(2,1,2)
% plot(times, y);
% hold on
% plot(times,Top);
% plot(times,Bottom);
% xlabel('Time')
% ylabel('Y Position')



figure
plot(times,Energy);
axis([0 200 0 80])
title('Particle Energy (v^2)')
xlabel('Time')
ylabel('Energy')
TMin = 0;
TMax = 200;
TimeStep = .0001;
times = linspace(TMin,TMax,(TMax-TMin)/TimeStep);

TMin = 0;
TMax = 201;
TimeStep = .0001;
times_2 = linspace(TMin,TMax,(TMax-TMin)/TimeStep);

all(times(1:2000000) == times_2(1:2000000))
0