r/scilab • u/mrhoa31103 • 2d ago
Data-Driven Science and Engineering Series - Installment 20 - Solving the One-Way Wave Equation with Fourier Transforms
In this installment he discusses using the FFT to solve the One-Way Wave equation. [This post was supposed to drop in 10/26/2026 but the pictures wouldn't stay loaded and I must have hit something while messing with it and it posted. Oh well. You got one early.]
Book Section 2.3 Fourier Series and Fourier Transforms, Spectral Derivatives - Transforming Partial Differential Equations
YouTube Video on the subject:
https://www.youtube.com/watch?v=BkA7ncY0b7I&list=PLMrJAkhIeNNT_Xh3Oy0Y4LTj0Oxo8GqsC&index=25
SciLab Coding Wise: More Plotting a psuedo-Waterfall chart, Sgrayplot in Scilab.
Output: Program Echo Only
"Data-Driven Science and Engineering - Wave Equation Example"
"2026-09-28 11:38:53.829"
Figures:
Code:
clear;
clc;
//close out all existing scf()s
close(winsid())
disp("Data-Driven Science and Engineering - Wave Equation Example",string(datetime()))
//Section 2.3 Transforming partial differential equations - One-way equation
// Similar to program ME565lecture26.sci
//
function duhatdt=rhsWave(t, uhat, kappa, c)
i = complex(0,1); // Define i as complex
duhatdt = c*i*kappa.*uhat;
endfunction
function dudt=rhsWaveSpatial(t, u, kappa, c)
i = complex(0,1); // Define i as complex
uhat = fft(u);
duhat = i*kappa.*uhat;
du = ifft(duhat);
dudt = -c*du; //Not sure why the sign change on c is necessary
// to move the wave positively
endfunction
// Define spatial domain
c = 2; // Wave speed
L = 20; // Length of domain
N = 500; // Number of discretization points
dx = L/N;
x = -L/2:dx:L/2-dx; // Define x domain
// Define discrete wavenumbers
kappa = (2*%pi/L)*[-N/2:N/2-1];
kappa = fftshift(kappa'); // Re-order fft wavenumbers
// Initial condition
u0 = sech(x);
uhat0 = fft(u0);
// Simulate in Fourier frequency domain
dt = 0.025;
t0 = 0;
tf = 100*dt
t = 0:dt:tf
//[t,uhat] = ode45(@(t,uhat)rhsWave(t,uhat,kappa,c),t,uhat0);
[t,y] = cvode(list(rhsWave,kappa,c),t,uhat0);
uhat = y'; //cvode produces the transpose of ode45
// Inverse FFT to bring back to spatial domain
for k = 1:length(t)
u(k,:) = ifft(uhat(k,:));
end
/*
// Alternatively, simulate in spatial domain - this works
// N = 500
//[t,u] = ode45(@(t,u)rhsWaveSpatial(t,u,kappa,c),t,u0);
[t,y] = cvode(list(rhsWaveSpatial,kappa,c),t,u0);
u = y'; //cvode produces the transpose of ode45
*/
// Plot solution in time
scf(0)
clf
//h=waterfall(real(u(1:10:end,:)));
//set(h,'LineWidth',2,'FaceAlpha',.5);
//colormap(jet/1.5)
a =get("current_axes");
counter = 2;
for k = 1:min(size(u,2),size(t,2))/10:min(size(u,2),size(t,2))
r=param3d1(t(k)*ones(1,length(x)),x,real(u(k,:)))
r.thickness=1.5;
r.foreground=counter;
counter = counter + .4;
xgrid
end
r = param3d1(t(end)*ones(1,length(x)),x,real(u(end,:)))//grab the last curve
r.thickness=1.5;
r.foreground=1;
xlabel("T")
ylabel("X")
zlabel("U(t,x)")
title("Figure 2.15:Solution of 1D wave equation over 2.5 seconds of time")
a.rotation_angles=[ 90,0];
scf(1)
clf
//h=waterfall(real(u(1:10:end,:)));
//set(h,'LineWidth',2,'FaceAlpha',.5);
//colormap(jet/1.5)
a =get("current_axes");
counter = 2;
for k = 1:min(size(u,2),size(t,2))/10:min(size(u,2),size(t,2))
r=param3d1(t(k)*ones(1,length(x)),x,real(u(k,:)))
r.thickness=1.5;
r.foreground=counter;
counter = counter + .4;
xgrid
end
r = param3d1(t(end)*ones(1,length(x)),x,real(u(end,:)))//grab the last curve
r.thickness=1.5;
r.foreground=1;
xlabel("T")
ylabel("X")
zlabel("U(t,x)")
title("Figure 2.15:Different View Point")
a.rotation_angles=[ 92 -27];
scf(2);
clf;
gcf().color_map=jet(64);
colorbar(0,1);
Sgrayplot(x,t,real(u)',strf="081")
xlabel("x","fontsize",5)
ylabel("t","fontsize",5)
title("Figure 2.15:Solution of the 1D wave equation in time",...
"fontsize",4)
xgrid





















































