2017-07-24 1 views
0

Je voudrais utiliser Matlab pour calculer deux boucles de différences finies de telle sorte que si nous avons deux équations, disons (1) et (2), il termine une étape de (1) puis résout (2) pour une étape puis (1) pour l'étape suivante, puis (2) et ainsi de suite et ainsi de suite.Comment exécuter deux boucles en alternance sur Matlab?

À cette fin, je fournir les paramètres de mon code ci-dessous:

%% Parameters 

L = 5; % size of domain 
T = 5; % measurement time 
dx = 1e-2; % spatial step 
dt = 1e-3; % time step 
x0 = 0; 
c = 1; 

%% 

t = 0:dt:T; % time vector 
x = (0:dx:L)'; % spatial vector 
nt = length(t); 
nx = length(x); 
Lx = (1/dx^2)*spdiags(ones(nx,1)*[1 -2 1],-1:1,nx,nx); % discrete Laplace operator 
mu = dt/dx; 
I = eye(nx,nx); % identity matrix 
A = spdiags(ones(nx,1)*[-1 1 0],-1:1,nx,nx); % finite difference matrix 

Ensuite, la première boucle est donnée par

%% Finite Difference Equation (1) 

% preallocate memory 
u = zeros(nx,nt); 
v = zeros(nx,nt); 
% initial condition in time 
u(:,1) = sinc((x-x0)/dx); 
v(:,1) = sinc((x-x0)/dx); 
for i = 1:nx-1 
    u(:,i+1) = ((1/(c*dt))*I+(1/dx)*A)\((1/(c*dt))*u(:,i)+v(:,i)); 
end 

et la seconde équation (2) est donnée par

Dans le format actuel, Matlab exécute la première boucle i = 1:nx-1, puis la seconde.
%% Finite Difference Equation (2) 

% preallocate memory 
u = zeros(nx,nt); 
v = zeros(nx,nt); 
% final condition in time 
u(:,nt) = sinc((x-x0)/dt); 
% initial condition in space 
for j = nt:-1:2 
    v(:,j-1) = ((1/dx)*A+(1/(c*dt))*I)\((1/(c*dt))*v(:,j) 
end 

deuxième boucle j = nt:-1:2.

Mais je veux courir les deux boucles comme suit: i = 1, puis j = nt, puis i = 2, puis j = nt-1 et ainsi de suite et ainsi de suite. Comment dois-je coder ceci?

+0

sont nt et nx les mêmes? Je ne pense pas, alors comment pouvez-vous itérer dans la même boucle sur deux vecteurs de taille différente? – Ivan

+0

@Ivan N ° 'nt = 5001' et' nx = 501'. Oui, c'est un point. Peut-être est-ce possible si j'interpole 't' sur' x'? –

+0

Comment allez-vous faire ces itérations avec une seule boucle comme vous voulez? – Ivan

Répondre

1

Vous pouvez deux boucles composites comme les suivantes:

% define other variables and preallocations 
j = nt; 
for i = 1:nx-1 
    u(:,i+1) = ((1/(c*dt))*I+(1/dx)*A)\((1/(c*dt))*u(:,i)+v(:,i)); 
    v(:,j-1) = ((1/dx)*A+(1/(c*dt))*I)\((1/(c*dt))*v(:,j) 
    j = j - 1; 
end 
+0

Merci pour la réponse, mais de façon intéressante, la formulation de cette façon produit un 'v 'indésirable qui a des zéros partout (c'est-à-dire que la méthode devient instable). Peut-être ai-je besoin d'arranger mes conditions initiales et différemment car il peut y avoir un chevauchement –

1
for i = 1:nx-1 
    u(:,i+1) = ((1/(c*dt))*I+(1/dx)*A)\((1/(c*dt))*u(:,i)+v(:,i)); 
    %This if will be true once each 10 iterations 
    if(mod((nt-i),10)==0) 
     j=((nt-i)/10)+1; 
     v(:,j-1) = ((1/dx)*A+(1/(c*dt))*I)\((1/(c*dt))*v(:,j); 
    end 
end 

Ne sait pas vraiment si cela va fonctionner, mais en le rendant plus facile à utiliser que vous essayez mon idée.

+0

BTW êtes-vous sûr de l'index à 'u' et' v' ?, dans les deux vous les attribuez dans toutes les lignes de la colonne , et tous les deux ont des colonnes "nt" – Ivan