clc; clear; close all;
% --- Paramètres physiques ---
g = 9.81; % Accélération gravitationnelle (m/s²)
L = 1000; % Longueur du canal (m)
B = 10; % Largeur du canal (m)
h0 = 10; % Hauteur initiale d'eau (m)
Qo = 10; % Débit initial (m³/s)
Qmax = 30; % Débit maximal (m³/s)
n_manning = 0.025; % Coefficient de Manning
% --- Paramètres numériques ---
Nx = 100; % Nombre de nœuds
dx = L / (Nx - 1); % Pas spatial
dt = 0.5; % Pas de temps (s)
Tmax = 120; % Temps total de simulation (s)
Nt = round(Tmax / dt); % Nombre d’itérations temporelles
% --- Grille spatiale ---
x = linspace(0, L, Nx)';
% --- Initialisation des variables ---
h = ones(Nx, 1) * h0; % Hauteur initiale d’eau
Q = ones(Nx, 1) * Qo; % Débit volumique initial
u = Q ./ (B * h); % Vitesse initiale
Z = zeros(Nx, 1); % Fond plat
% --- Matrices élémentaires EF ---
M = sparse(Nx, Nx);
C = sparse(Nx, Nx);
for i = 1:Nx-1
Me = (dx/6) * [2 1; 1 2];
Ce = (1/dx) * [-1 1; -1 1];
M(i:i+1, i:i+1) = M(i:i+1, i:i+1) + Me;
C(i:i+1, i:i+1) = C(i:i+1, i:i+1) + Ce;
end
% --- Fonction onde de crue à l'entrée ---
onde_crue = @(t) (t < 30) * (Qo + (Qmax - Qo) * (t / 30)) + (t >= 30) * Qmax;
% --- Boucle temporelle principale ---
for t = 1:Nt
time = t * dt;
% Mise à jour du débit à l’entrée (onde de crue)
Q(1) = onde_crue(time);
u(1) = Q(1) / (B * h(1));
% Calcul des flux
HU = h .* u;
Fh = -C * HU;
Friction = g * n_manning^2 * u .* abs(u) ./ (h.^(4/3));
FHU = -C * (h .* u.^2) - (g/2) * C * (h.^2) - g * h .* gradient(Z, dx) - Friction;
% Mise à jour (Euler explicite)
h = h + dt * (M \ Fh);
HU = h .* u + dt * (M \ FHU);
u = HU ./ h;
% Conditions aux limites (simple reflet)
h([1 end]) = h([2 end-1]);
u([1 end]) = u([2 end-1]);
% --- Affichage toutes les 5 secondes ---
if mod(t, 10) == 0
plot(x, h, 'b', 'LineWidth', 2); hold on;
plot(x, Z, 'k--', 'LineWidth', 1); hold off;
xlabel('Position (m)'); ylabel('Hauteur d''eau (m)');
title(['Propagation de l''onde de crue - t = ', num2str(time), ' s']);
grid on; ylim([9 13]);
drawnow;
end
end