前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线性一维平流方程解决以下PDE的程序。

线性一维平流方程解决以下PDE的程序。

作者头像
裴来凡
发布2022-05-28 15:25:40
4220
发布2022-05-28 15:25:40
举报
文章被收录于专栏:图像处理与模式识别研究所

burgers_exact.m

代码语言:javascript
复制
function burgers_exact
% Plot the exact solution of Burgers' equation
% u_t + u*u_x = 0, u(x,0)=f(x)

u = 0.01:0.01:0.999;

xp = @(u,t) u.*t + sqrt((1 - u)./u) ;
xm = @(u,t) u.*t - sqrt((1 - u)./u) ;

plot(xp(u,0),u,'-b',xm(u,0),u,'-b','LineWidth',2), grid on
xlabel 'x', ylabel 'u'
title ' Solution of u_{t} + uu_{x} = 0'

for t = 0:1:10
plot(xp(u,t),u,'-k',xm(u,t),u,'-k','LineWidth',2), grid on
pause(0.2);
end

burgers_exact2.m

代码语言:javascript
复制
function burgers_exact2

%SIDENOTE
%If the characteristics of the exact solution do not intersect, then the
%classical solution of burgers equation is given by:

% Domain
x = 0:0.02:1;
% IC (at t=0)
u0 = 0.2 + sin(2*pi*x);
% u function
u = @(x,t) 0.2 + sin(2*pi*x);

for t = 0:0.01:0.1
    u_next = u(x - t*u(x,t),t);
    plot(x,u_next,'o');
    pause(0.1)
    drawnow
end

% This solution is valid for any u(x,t) function.
% However if the characteristics colide, then the classical solution is not
% valid anymore. It can only be solved computationally.

LinearAdvection_1D.m

代码语言:javascript
复制
%% Linear 1D Advection equation
% Routine for solving the following PDE
%
%    du/dt + a du/dx = 0
%
% Using the following scheemes:
%
% 1. One-sided Upwind
% 2. Lax-Friedrichs
% 3. Lax-Wendroff
% 4. Beam-Warming
%
clc; clear; close all; 
%% Parameters
cfl   = 0.8; % CFL = a*dt/dx
tend  = 0.2; % End time
a     = 0.5; % Scalar wave speed 

%% Domain Discretization
dx = 0.01; 
dt = cfl/abs(a)*dx;
x  = 0:dx:1;
t  = 0:dt:tend;

%% Initial Condition
n   = length(x);
u_0 = zeros(1,n);
u_0(1:floor(n/2)) = 1; u_0(floor(n/2)+1:n) = 0;
u_next = zeros(1,n);

%% 1. One-Sided Upwind
u_upwind = u_0;
for k = t
    for j = 2:n-1
    u_next(j) = u_upwind(j) - cfl*(u_upwind(j)-u_upwind(j-1));
    end
    u_upwind = u_next;
    % BC
    u_upwind(1) = u_next(2);
    u_upwind(n) = u_next(n-1);
end
u_next = zeros(1,n);

%% 2. Lax-Friedrichs
u_LF = u_0;
for k = t
    for j = 2:n-1
    u_next(j) = 1/2*(u_LF(j-1)+u_LF(j+1)) - 1/2*cfl*(u_LF(j+1)-u_LF(j-1));
    end
    u_LF = u_next;
    % BC
    u_LF(1) = u_next(2);
    u_LF(n) = u_next(n-1);
end 
u_next = zeros(1,n);

%% 3. Lax-Wendroff
u_LW = u_0;
for k = t
    for j = 2:n-1
    u_next(j) = u_LW(j) - 1/2*cfl*(u_LW(j+1)-u_LW(j-1)) + ...
        1/2*(cfl^2)*(u_LW(j+1)-2*u_LW(j)+u_LW(j-1));
    end
    u_LW = u_next;
    % BC
    u_LW(1) = u_next(2);
    u_LW(n) = u_next(n-1);
end
u_next = zeros(1,n);

%% 4. Beam-Warming
u_BW = u_0;
for k = t
    for j = 3:n
    u_next(j) = u_BW(j) - 1/2*cfl*(3*u_BW(j)-4*u_BW(j-1)+u_BW(j-2)) + ...
        1/2*(cfl^2)*(u_BW(j)-2*u_BW(j-1)+u_BW(j-2));
    end
    u_BW = u_next;
    % BC
    u_BW(1) = u_next(3);
    u_BW(2) = u_next(3);
end

%% Exact Solution
x_exact = 0.5 + a*tend;
u_exact = zeros(1,n);
for j = 1:n
    if x(j) <= x_exact
    u_exact(j) = 1;
    else
    u_exact(j) = 0;
    end
end

%% Make a comparative Plot
offset = 0.05;
subplot(221); 
hold on
plot(x,u_upwind,'.'); plot(x,u_exact,'k'); xlabel('X-Coordinate [-]'); ylabel('U-state [-]'); ylim([-0.5,1.5]); title 'One-Sided Upwind'; 
hold off
subplot(222); 
hold on
plot(x,u_LF,'.'); plot(x,u_exact,'k'); xlabel('X-Coordinate [-]'); ylabel('U-state [-]'); ylim([-0.5,1.5]); title 'Lax-Friedrichs';
hold off
subplot(223);
hold on
plot(x,u_LW,'.'); plot(x,u_exact,'k'); xlabel('X-Coordinate [-]'); ylabel('U-state [-]'); ylim([-0.5,1.5]); title 'Lax-wendroff';
hold off
subplot(224); 
hold on
plot(x,u_BW,'.'); plot(x,u_exact,'k'); xlabel('X-Coordinate [-]'); ylabel('U-state [-]'); ylim([-0.5,1.5]); title 'Beam-Warming';
hold off

sweby.m

代码语言:javascript
复制
%% Plot sweby diagrams

% number of points
N = 1000;
% compute flux limiting functions for a range of methods
theta = linspace(-1, 5, N);

upwind      = zeros(N,1);
laxwendroff = ones(N,1);
beamwarming = theta;
fromm       = 0.5*(1+theta);

minmo    = minmod(1, theta);
superbee = max(0, max(min(1,2*theta), min(2,theta)));
MC       = max(0, min(min( (1+theta)/2, 2), 2*theta));
vanleer  = (theta+abs(theta))./(1+abs(theta));

% plot TVD stability region 
% vertices of polygonal bounding region (truncated at x=10) 
figure(1)
x = [0 10 10 1];
y = [0  0  2 2];
fill(x,y,[.9 .9 .9]); % fill region with grey

hold on;
plot(theta, upwind,         'r-', 'LineWidth', 1.5)
plot(theta, laxwendroff,  'b-', 'LineWidth', 1.5)
plot(theta, beamwarming,    'g-', 'LineWidth', 1.5)
plot(theta, fromm,          'm', 'LineWidth', 1.5)
hold off;

axis equal
axis([-1 4 -.5 2.5])
legend('TVD region', 'Upwind', 'Lax-Wendroff', 'Beam-Warming', 'Fromm');
xlabel('\theta', 'FontSize', 18);
ylabel('\phi', 'FontSize', 18);

% plot Sweby modified TVD stability region 
% vertices of polygonal bounding region (truncated at x=10) 
figure(2)
x = [0 1 10 10 2  1 0.5 0];
y = [0 1  1  2 2  1   1 0];
fill(x,y,[.9 .9 .9]); % fill Sweby TVD region with grey

hold on;
plot(theta, minmo,      'r-', 'LineWidth', 1.5);
plot(theta, superbee,  'g-', 'LineWidth', 1.5);
plot(theta, MC,         'b-', 'LineWidth', 1.5);
plot(theta, vanleer,  'm-', 'LineWidth', 1.5);
hold off;

axis equal
axis([-1 4 -.5 2.5])
legend('Sweby TVD region', 'minmod', 'superbee', 'MC', 'van Leer');
xlabel('\theta', 'FontSize', 18);
ylabel('\phi', 'FontSize', 18);

TVD_scheme.m

代码语言:javascript
复制
%% 1D Linear Advection Equation
%
% du/dt + a du/dx = 0
%
% Subroutine for solving using TVD Method.
% by Manuel Diaz, manuel.ade'at'gmail.com 
% Institute of Applied Mechanics, 2012.08.12

clear all; close all; clc;

%% Parameters
a = -0.5;
a_m = min(0,a);
a_p = max(0,a);
dx = 0.01;
cfl = 0.9;
dt = cfl*dx/abs(a);
t_end = 0.4;

%% Discretization of Domain
x = 1:dx:2;
t = 0:dt:t_end;

%% Initial Condition
n = length(x);
%u_0 = zeros(1,n);
u_0(1:ceil(n/2)) = 1;
u_0((ceil(n/2)+1):n) = 2;

%% Main Loop

% Initilize vector variables
r = zeros(1,n);
F_rl = zeros(1,n);
F_rh = zeros(1,n);
F_ll = zeros(1,n);
F_lh = zeros(1,n);
F_right = zeros(1,n);
F_left  = zeros(1,n);
u_next = zeros(1,n);

% Load Initial condition
u = u_0;

% Start TVD Loop
for k = t
    for j = 2:n-1
        % smooth measurement factor 'r'
        if u(j) == u(j+1)
            r(j) = 1;
        elseif a > 0
            r(j) = (u(j) - u(j-1)) / (u(j+1) - u(j));
        elseif a < 0
            r(j) = (u(j+2) - u(j+1)) / (u(j+1) - u(j));
        end
        r(1) = 1; r(n) = 1;
    end
        
        % Define Flux Limiter function
        phi = (r + abs(r))./(1 + abs(r));
        
    for j = 2:n-1    
        % Compute fluxes for TVD
        F_rl(j) = a_p*u(j) + a_m*u(j+1);
        F_rh(j) = (1/2)*a*(u(j)+u(j+1)) - (1/2)*(a^2)*(dt/dx)*(u(j+1)-u(j));
        
        F_ll(j) = a_p*u(j-1) + a_m*u(j);
        F_lh(j) = (1/2)*a*(u(j-1)+u(j)) - (1/2)*(a^2)*(dt/dx)*(u(j)-u(j-1));
        
        % Compute next time step
        F_right(j) = F_rl(j) + phi(j)*( F_rh(j) - F_rl(j) );
        F_left(j)  = F_ll(j) + phi(j-1)*( F_lh(j) - F_ll(j) );
        
        u_next(j) = u(j) - dt/dx*(F_right(j) - F_left(j));
    end
    
        % right sided Upwind
        %u_next(j) = u(j) - a*dt/dx*(u(j)-u(j-1)); 
        
        % letf sided Upwind
        %u_next(j) = u(j) - a*dt/dx*(u(j+1)-u(j)); 
        
        % Lax-Wendroff 
        %u_next(j) = u(j) - dt/(2*dx)*a*(u(j+1)-u(j-1)) ...
        %   +(dt^2/2)/(dx^2)*(a^2)*(u(j+1)-2*u(j)+u(j-1)); % LW
        
        % Double sided Upwind
        %u_next(j) = u(j)-a_p*dt/dx*(u(j)-u(j-1))-a_m*dt/dx*(u(j+1)-u(j));
    
        % BC
        u_next(1) = u_next(2);
        u_next(n) = u_next(n-1);
    
        % UPDATE info
        u = u_next(1:n);
end
    
%% Plot Results
plot(x,u,'.'); Ylim([0.5,2.5]); Title('TVD'); 
xlabel('X-Coordinate [-]'); ylabel('U-state [-]');

Upwind.m

代码语言:javascript
复制
%% 1D Linear Advection Equation
%
% du/dt + a du/dx = 0
%
% Ref's: 
%   Randall J. Leveque;
%   Finite Volume Methods for Hyperbolic Problems
%   Cambridge Press, 2002.
%
% Subroutine for solving using Upwind Method.
% by Manuel Diaz, manuel.ade'at'gmail.com 
% Institute of Applied Mechanics, 2012.08.12

clear all; close all; clc;

%% Parameters
a = 0.5;
a_m = min(0,a);
a_p = max(0,a);
dx = 0.01;
cfl = 0.9;
dt = cfl*dx/abs(a);
t_end = 0.6;

%% Discretization of Domain
x = 1:dx:2;
t = 0:dt:t_end;

%% Initial Condition
n = length(x);
%u_0 = zeros(1,n);
u0(1:ceil(n/2)) = 1;
u0((ceil(n/2)+1):n) = 2;

%% Main Loop
% Initilize vector variables
u_next = zeros(size(u0)); % u^{n+1}
u_bar1 = zeros(size(u0)); % preallocate for MacCormack
u_bar2 = zeros(size(u0)); % preallocate for MacCormack

% Load Initial condition
u = u0;

% Main Loop
for k = t
    % plot every time step
    plot(x,u,'.')
    
    for j = 2:n-1    
        % Single Sided Upwind
        %u_next(j) = u(j) - a*dt/dx*(u(j)-u(j-1)); % Upwind
        %u_next(j) = u(j) - a*dt/dx*(u(j+1)-u(j)); % Downwind
        
        % Double Sided Upwind
        u_next(j) = u(j) - a_p*dt/dx*(u(j)-u(j-1)) - a_m*dt/dx*(u(j+1)-u(j));
        
        % Comparing to Lax-Wendroff:
        %u_next(j) = u(j) - a*dt/(2*dx)*(u(j+1)-u(j-1)) ...
        %   +(dt^2/2)/(dx^2)*(a^2)*(u(j+1)-2*u(j)+u(j-1)); % LW
        
        % Comparing to MacCormack Method:
        % Predictor steps
        %u_bar1(j) = u(j) - a*dt/dx*(u(j+1)-u(j)); 
        %    u_bar1(1) = u_bar1(2); % Neumann BC in predictor step
        %u_bar2(j) = u_bar1(j) - a*dt/dx*(u_bar1(j)-u_bar1(j-1)); 
        % Corrector step
        %u_next(j) = 1/2*(u(j)+u_bar2(j));
    end
    % BC
    u_next(1) = u_next(2);      % Neumann BC
    u_next(n) = u_next(n-1);    % Neumann BC
    
    % UPDATE info
    u = u_next(1:n);
    
    % update figure
    pause(0.05); drawnow
end
    
%% Plot final Result
plot(x,u,'.')

Upwind_for_Nazanin.m

代码语言:javascript
复制
%% 1D Linear Advection Equation
% for Nazanin
%
% du/dt + a du/dx = 0
%
% Subroutine for solving using Upwind Method.
% by Manuel Diaz, manuel.ade'at'gmail.com 
% Institute of Applied Mechanics, 2013.03.08

clear all; close all; clc;

%% Parameters
dx  = 1/200; % using 200 points
cfl  = 0.9;
t_end = 0.5;

%% Discretization of Domain
x = 0:dx:1;
n = length(x);

%% Initial Condition
u0 = zeros(1,n);
idx = find( x>=0.2 & x<=0.4);
u0(idx) = 1;

%% Main Loop
% Initilize vector variables
u_next = zeros(size(u0)); % u^{n+1}

% Load Initial condition
u = u0;

% Main Loop
t = 0;
while t < t_end
    % plot every time step
    plot(x,u,'.')
    
    % Compute advection speed
    a = (1+x.^2)./(1+2*x*t+2*x.^2+x.^4);
    a_m = min(0,a);
    a_p = max(0,a);
    
    % compute time step
    dt = cfl*dx/abs(max(a));
    t = t + dt;
    
    for j = 2:n-1    
        % Using double Sided Upwind
        u_next(j) = u(j) - a_p(j)*dt/dx*(u(j)-u(j-1)) - a_m(j)*dt/dx*(u(j+1)-u(j));
    end
    % BC
    u_next(1) = 0;              % Dirichlet BC
    %u_next(n) = u_next(n-1);    % Neumann BC
    
    % UPDATE info
    u = u_next;
    
    % update figure
    pause(0.01); drawnow
end

%% Compute exact solution at t = t_end
u_exact = zeros(1,n);
idx = find( x>=(0.2 - t_end/(1+0.2^2) ) & x<=(0.4 - t_end/(1+0.2^2)));
u_exact(idx) = 1;

%% Plot final Result
hold on
plot(x,u,'.')
%plot(x,u_exact,'-k')
hold off

http://mpvideo.qpic.cn/0b78leaacaaaymac5mocazpfawodafmqaaia.f10002.mp4?dis_k=1828ad8a9e8303d0d69ab2c8ca6bfd22&dis_t=1653729006&vid=wxv_1345401917991862273&format_id=10002&support_redirect=0&mmversion=false

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 图像处理与模式识别研究所 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档