In [1]:
%reload_ext autoreload
%autoreload 2
In [2]:
from PDESolver import *

1D Tests in periodic conditions¶

1D stationnary equation with psiOp()¶

In [3]:
# Define symbolic variables
x, xi = symbols('x xi')
u = Function('u')(x)

# Define the PDE: psiOp[xi^2 + 1, u](x) = 0
equation = Eq(psiOp(xi**2 + 1, u), sin(x))  # rhs will be overwritten

# Define exact solution

def u_exact(x):
    return np.sin(x)/2

# Create the solver
solver = PDESolver(equation)

# Setup parameters
Lx = 2 * np.pi
Nx = 256
solver.setup(Lx=Lx, Nx=Nx, initial_condition=None)

# Solve the stationary problem
u_num = solver.solve_stationary_psiOp(order=1)

# Exact solution on grid
u_ref = u_exact(solver.X)

# Compute relative L2 error
error = np.linalg.norm(np.real(u_num) - u_ref) / np.linalg.norm(u_ref)

solver.test(u_exact=u_exact, threshold=5e-3, component='abs')

solver.show_stationary_solution(u=u_num, component='real')
*********************************
* Partial differential equation *
*********************************

     ⎛ 2          ⎞         
psiOp⎝ξ  + 1, u(x)⎠ = sin(x)

********************
* Equation parsing *
********************


Equation rewritten in standard form: -sin(x) + psiOp(xi**2 + 1, u(x))
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: -sin(x) + psiOp(xi**2 + 1, u(x))
Analyzing term: -sin(x)
  --> Classified as source term
Analyzing term: psiOp(xi**2 + 1, u(x))
  --> Classified as pseudo linear term (psiOp)
Final linear terms: {}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(1, xi**2 + 1)]
Source terms: [-sin(x)]
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

symbol = 
 2    
ξ  + 1
⚠️ For psiOp, use interactive_symbol_analysis.

*******************************
* Solving the stationnary PDE *
*******************************

boundary condition:  periodic

symbol = 
 2    
ξ  + 1
✅ Elliptic pseudo-differential symbol: inversion allowed.
Right inverse asymptotic symbol:
  1   
──────
 2    
ξ  + 1
⚡ Optimization: symbol independent of x — direct product in Fourier.
Testing a stationary solution.
Test error : 2.151e-16
No description has been provided for this image
No description has been provided for this image

1D stationnary equation with psiOp() depending on $x$¶

In [4]:
# Define symbolic variables
x, xi = symbols('x xi', real=True)
u = Function('u')(x)

# Define the symbol
p_symbol = xi**2 + x**2 + 1

# Define the right-hand side f(x) = P[u_exact]
f_expr = 3 * (1 - x**2) * exp(-x**2)

# Define the full equation: P[u] = f
equation = Eq(psiOp(p_symbol, u), f_expr)

# Exact and initial
def u_exact(x): return np.exp(-x**2)


solver = PDESolver(equation)
solver.setup(Lx=30, Nx=1024, initial_condition=None)

u_num = solver.solve_stationary_psiOp(order=1)
solver.test(u_exact=u_exact, threshold=2, component='real')
*********************************
* Partial differential equation *
*********************************

                                         2
     ⎛ 2    2          ⎞   ⎛       2⎞  -x 
psiOp⎝x  + ξ  + 1, u(x)⎠ = ⎝3 - 3⋅x ⎠⋅ℯ   

********************
* Equation parsing *
********************


Equation rewritten in standard form: -(3 - 3*x**2)*exp(-x**2) + psiOp(x**2 + xi**2 + 1, u(x))
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: -(3 - 3*x**2)*exp(-x**2) + psiOp(x**2 + xi**2 + 1, u(x))
Analyzing term: -(3 - 3*x**2)*exp(-x**2)
  --> Classified as source term
Analyzing term: psiOp(x**2 + xi**2 + 1, u(x))
  --> Classified as pseudo linear term (psiOp)
Final linear terms: {}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(1, x**2 + xi**2 + 1)]
Source terms: [-(3 - 3*x**2)*exp(-x**2)]
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

symbol = 
 2    2    
x  + ξ  + 1
⚠️ For psiOp, use interactive_symbol_analysis.

*******************************
* Solving the stationnary PDE *
*******************************

boundary condition:  periodic

symbol = 
 2    2    
x  + ξ  + 1
✅ Elliptic pseudo-differential symbol: inversion allowed.
Right inverse asymptotic symbol:
    4.0⋅ⅈ⋅x⋅ξ           1     
- ────────────── + ───────────
               3    2    2    
  ⎛ 2    2    ⎞    x  + ξ  + 1
  ⎝x  + ξ  + 1⎠               
⚙️ 1D Kohn-Nirenberg Quantification
Testing a stationary solution.
Test error : 1.827e-01
No description has been provided for this image

1D integro-differential equation¶

In [5]:
# Define the symbols and the integro-differential equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u')
u = u_func(t, x)
eps = 0.001
# Define the equation with an integral term using Op
integral_term = Op(1 / (I * (kx + eps)), u)

eq = Eq(diff(u, t), diff(u, x) + integral_term - u)

# Create the solver
# solver = PDESolver(eq, time_scheme='ETD-RK4', dealiasing_ratio=2/3)
solver = PDESolver(eq, time_scheme='ETD-RK4')

# Simulation parameters
Lt = 2.0  # Total simulation time
Lx = 20   # Spatial domain size
Nx = 1024 # Number of grid points
Nt = 200  # Number of time steps

# Initial condition
initial_condition = lambda x: np.sin(x)

# Setup the solver
solver.setup(
    Lx=Lx, Nx=Nx, Lt=Lt, Nt=Nt,
    initial_condition=initial_condition
)

# Solve the equation
solver.solve()

# Exact solution at any time t
def u_exact(x, t):
    return np.exp(-t) * np.sin(x)

# Automatic testing at multiple times
n_test = 4
test_set = [
    solver.test(
        u_exact=u_exact,
        t_eval=i * Lt / n_test,
        threshold=0.5,  # Adjust threshold if necessary
        component='real'
    )
    for i in range(n_test + 1)
]
*********************************
* Partial differential equation *
*********************************

∂                          ⎛   -ⅈ              ⎞   ∂          
──(u(t, x)) = -u(t, x) + Op⎜──────────, u(t, x)⎟ + ──(u(t, x))
∂t                         ⎝kx + 0.001         ⎠   ∂x         

********************
* Equation parsing *
********************


Equation rewritten in standard form: u(t, x) - Op(-I/(kx + 0.001), u(t, x)) + Derivative(u(t, x), t) - Derivative(u(t, x), x)

Expanded equation: u(t, x) - Op(-I/(kx + 0.001), u(t, x)) + Derivative(u(t, x), t) - Derivative(u(t, x), x)
Analyzing term: u(t, x)
  --> Classified as linear
Analyzing term: -Op(-I/(kx + 0.001), u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), x)
  Derivative found: Derivative(u(t, x), x)
  --> Classified as linear
Final linear terms: {u(t, x): 1, Derivative(u(t, x), t): 1, Derivative(u(t, x), x): -1}
Final nonlinear terms: []
Symbol terms: [(-1, -I/(kx + 0.001))]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
-ⅈ⋅kx - ⅈ⋅ω + 1

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: I/(kx + 0.001)

Raw characteristic equation:
                      ⅈ     
-ⅈ⋅kx - ⅈ⋅ω + 1 + ──────────
                  kx + 0.001
Temporal order from dispersion relation: 1
self.pseudo_terms =  []
--- Solutions found ---
⎡           2                                ⎤
⎢- 1000.0⋅kx  - kx - 1000.0⋅ⅈ⋅kx + 1000.0 - ⅈ⎥
⎢────────────────────────────────────────────⎥
⎣              1000.0⋅kx + 1.0               ⎦

--- Final linear operator ---
   ⎛           2                                ⎞ 
-ⅈ⋅⎝- 1000.0⋅kx  - kx - 1000.0⋅ⅈ⋅kx + 1000.0 - ⅈ⎠ 
──────────────────────────────────────────────────
                 1000.0⋅kx + 1.0                  

*****************
* CFL condition *
*****************

CFL condition violated: dt = 0.01, max allowed dt = 9.765625e-06

********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.749e-02
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 2.484e-01
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 3.472e-01
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 4.210e-01
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 4.840e-01
No description has been provided for this image

1D convolution equation¶

In [6]:
# Define symbols
t, x, kx, xi, omega, lam = symbols('t x kx xi omega lambda')
u_func = Function('u')
u = u_func(t, x)
lam = 1.0
# Define the kernel f(x) = exp(-lambda * |x|)
f_kernel = exp(-lam * Abs(x))

# Convolution equation: ∂t u = - OpConv(f_kernel, u)
eq = Eq(diff(u, t), -Op(fourier_transform(f_kernel, x, kx/(2*pi)), u))

# Create solver with lambda=1
solver = PDESolver(eq.subs(lam, 1), time_scheme='ETD-RK4')

# Simulation parameters
Lt = 2.0
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=100,
    initial_condition=lambda x: np.cos(x)
)

# Solve
solver.solve()

# Exact solution: u(x, t) = cos(x) * exp(- (2*lambda / (lambda^2 + k^2)) * t )
def u_exact(x, t):
    lam_val = 1.0
    k_val = 1.0  # mode k=1 (cos(x))
    decay = 2 * lam_val / (lam_val**2 + k_val**2)
    return np.cos(x) * np.exp(-decay * t)

# Automatic testing at multiple times
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-3, component='abs')
            for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

∂                ⎛  2.0           ⎞
──(u(t, x)) = -Op⎜───────, u(t, x)⎟
∂t               ⎜  2             ⎟
                 ⎝kx  + 1         ⎠

********************
* Equation parsing *
********************


Equation rewritten in standard form: Op(2.0/(kx**2 + 1), u(t, x)) + Derivative(u(t, x), t)

Expanded equation: Op(2.0/(kx**2 + 1), u(t, x)) + Derivative(u(t, x), t)
Analyzing term: Op(2.0/(kx**2 + 1), u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1}
Final nonlinear terms: []
Symbol terms: [(1, 2.0/(kx**2 + 1))]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
-ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 2.0/(kx**2 + 1)

Raw characteristic equation:
         2.0  
-ⅈ⋅ω + ───────
         2    
       kx  + 1
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡ -2.0⋅ⅈ  ⎤
⎢─────────⎥
⎢  2      ⎥
⎣kx  + 1.0⎦

--- Final linear operator ---
  -2.0   
─────────
  2      
kx  + 1.0

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
⚠️ Insufficient high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 1.065e-04
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 1.055e-04
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.048e-04
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.042e-04
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.040e-04
No description has been provided for this image

1D transport equation¶

In [7]:
# Define the symbols and the 1D transport equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

eq = Eq(diff(u, t), -diff(u, x))  # Rightward transport at speed +1

# Create the solver
solver = PDESolver(eq, time_scheme='ETD-RK4')
Lt=5.0
# Domain setup and initial condition
solver.setup(
    Lx=10, Nx=256, Lt=Lt, Nt=2000,
    initial_condition=lambda x: np.exp(-x**2)
)

# Solving
solver.solve()

# Exact solution at t = 2.0 (with periodic wrapping)
def u_exact(x, t):
    L = 10  # Domain length
    return np.exp(-((x - t + L/2) % L - L/2)**2)

# Automatic testing
n_test = 5
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

∂              ∂          
──(u(t, x)) = -──(u(t, x))
∂t             ∂x         

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), t) + Derivative(u(t, x), x)

Expanded equation: Derivative(u(t, x), t) + Derivative(u(t, x), x)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: Derivative(u(t, x), x)
  Derivative found: Derivative(u(t, x), x)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), x): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
ⅈ⋅(kx - ω)

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
ⅈ⋅(kx - ω)
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
[kx]

--- Final linear operator ---
-ⅈ⋅kx

*****************
* CFL condition *
*****************

CFL condition violated: dt = 0.0025, max allowed dt = 0.00024285117048934224

********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
⚠️ Insufficient high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

/home/fifi/pdesolver_prod/PDESolver.py:4234: RuntimeWarning: invalid value encountered in divide
  return np.where(np.abs(z) > 1e-12, (np.exp(z) - 1) / z, 1.0)
/home/fifi/pdesolver_prod/PDESolver.py:4237: RuntimeWarning: invalid value encountered in divide
  return np.where(np.abs(z) > 1e-12, (np.exp(z) - 1 - z) / z**2, 0.5)
Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 2.871e-12
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 4.749e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 4.749e-02
No description has been provided for this image
Closest available time to t_eval=3.0: 3.0
Test error t = 3.0: 4.749e-02
No description has been provided for this image
Closest available time to t_eval=4.0: 4.0
Test error t = 4.0: 4.761e-02
No description has been provided for this image
Closest available time to t_eval=5.0: 5.0
Test error t = 5.0: 4.788e-02
No description has been provided for this image

1D Fractional diffusion equation¶

In [8]:
# Define the symbols and the equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

# Fractional diffusion equation with alpha = 1.5 and added dissipation
alpha = 1.5
nu = 0.01  # Diffusion coefficient
# eq = Eq(diff(u, t), Op(abs(kx)**alpha, u) + nu * diff(u, x, 2))
eq = Eq(diff(u, t), -Op(abs(kx)**alpha, u))

# Create the solver
solver = PDESolver(eq, dealiasing_ratio=0.5, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=2000,  # Reduced dt by increasing Nt
    initial_condition=lambda x: np.sin(x)
)

# Solve the equation
solver.solve()

# Exact solution function at t = 1
def u_exact(x, t):
    return np.sin(x) * np.exp(-t * abs(1)**alpha)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

∂                ⎛    1.5         ⎞
──(u(t, x)) = -Op⎝│kx│   , u(t, x)⎠
∂t                                 

********************
* Equation parsing *
********************


Equation rewritten in standard form: Op(Abs(kx)**1.5, u(t, x)) + Derivative(u(t, x), t)

Expanded equation: Op(Abs(kx)**1.5, u(t, x)) + Derivative(u(t, x), t)
Analyzing term: Op(Abs(kx)**1.5, u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1}
Final nonlinear terms: []
Symbol terms: [(1, Abs(kx)**1.5)]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
-ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: Abs(kx)**1.5

Raw characteristic equation:
           1.5
-ⅈ⋅ω + │kx│   
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡       3/2⎤
⎣-ⅈ⋅│kx│   ⎦

--- Final linear operator ---
     3/2
-│kx│   

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.134e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 1.888e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.771e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.651e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.530e-02
No description has been provided for this image

1D transport equation with Op¶

In [9]:
# Define symbols and equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u')
u = u_func(t, x)

# Parameters
c = 1.0
beta = 1.3

# Equation
eq = Eq(diff(u, t) + c * diff(u, x), -Op(abs(kx)**beta, u))

# Create the solver
solver = PDESolver(eq, dealiasing_ratio=0.5, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=2000,
    initial_condition=lambda x: np.cos(x)
)

# Solve the equation
solver.solve()

# Exact solution function at t = 1
def u_exact(x, t):
    return np.cos(x - c * t) * np.exp(-t * abs(1)**beta)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=7e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

∂                 ∂                ⎛    1.3         ⎞
──(u(t, x)) + 1.0⋅──(u(t, x)) = -Op⎝│kx│   , u(t, x)⎠
∂t                ∂x                                 

********************
* Equation parsing *
********************


Equation rewritten in standard form: Op(Abs(kx)**1.3, u(t, x)) + Derivative(u(t, x), t) + 1.0*Derivative(u(t, x), x)

Expanded equation: Op(Abs(kx)**1.3, u(t, x)) + Derivative(u(t, x), t) + 1.0*Derivative(u(t, x), x)
Analyzing term: Op(Abs(kx)**1.3, u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: 1.0*Derivative(u(t, x), x)
  Derivative found: Derivative(u(t, x), x)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), x): 1.00000000000000}
Final nonlinear terms: []
Symbol terms: [(1, Abs(kx)**1.3)]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
ⅈ⋅(1.0⋅kx - ω)

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: Abs(kx)**1.3

Raw characteristic equation:
                     1.3
ⅈ⋅(1.0⋅kx - ω) + │kx│   
Temporal order from dispersion relation: 1
self.pseudo_terms =  []
--- Solutions found ---
⎡           13⎤
⎢           ──⎥
⎢           10⎥
⎣kx - ⅈ⋅│kx│  ⎦

--- Final linear operator ---
   ⎛           13⎞
   ⎜           ──⎟
   ⎜           10⎟
-ⅈ⋅⎝kx - ⅈ⋅│kx│  ⎠

*****************
* CFL condition *
*****************

CFL condition violated: dt = 0.001, max allowed dt = 9.587379924285257e-05

********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 1.065e-04
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 2.474e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 2.282e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 3.492e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 6.492e-02
No description has been provided for this image

1D heat equation with periodic initial condition¶

In [10]:
# Define the symbols and the equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

# 1D heat equation
eq = Eq(diff(u, t), diff(u, x, x)) 

# Create the solver
solver = PDESolver(eq, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=100,
    initial_condition=lambda x: np.sin(x)
)

# Solve the equation
solver.solve()

# Exact solution function
def u_exact(x, t):
    return np.sin(x) * np.exp(-t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

               2          
∂             ∂           
──(u(t, x)) = ───(u(t, x))
∂t              2         
              ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), t) - Derivative(u(t, x), (x, 2))

Expanded equation: Derivative(u(t, x), t) - Derivative(u(t, x), (x, 2))
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2      
kx  - ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2      
kx  - ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡     2⎤
⎣-ⅈ⋅kx ⎦

--- Final linear operator ---
   2
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.134e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 6.131e-03
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 6.145e-03
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 6.167e-03
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 6.197e-03
No description has been provided for this image

1D heat equation with compact support initial condition¶

In [11]:
# Definition of symbols and equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u = Function('u')(t, x)

# 1D heat equation
eq = Eq(diff(u, t), diff(u, x, x))

# Creation of the solver with ETD-RK4 scheme
solver = PDESolver(eq, time_scheme='ETD-RK4')

# Simulation parameters
Lt = 2.0  # Total time
Lx = 5 * np.pi  # Spatial domain
Nx = 256  # Grid points
Nt = 100  # Time steps

# Solver setup with Gaussian initial condition
solver.setup(
    Lx=Lx,
    Nx=Nx,
    Lt=Lt,
    Nt=Nt,
    initial_condition=lambda x: np.exp(-2 * x**2)  # Gaussian σ=0.5
)

# Solving the equation
solver.solve()

# Exact solution for the Gaussian with diffusion
def u_exact(x, t):
    sigma = 0.5
    variance = sigma**2 + 2 * t  # Variance increases linearly
    return (np.exp(-x**2 / (2 * variance)) /
            np.sqrt(1 + 2 * t / sigma**2))

# Automated tests at different times
n_test = 4
test_set = [
    solver.test(
        u_exact=u_exact,
        t_eval=i * Lt / n_test,
        threshold=5e-3,  
        component='real'
    )
    for i in range(n_test + 1)
]

# Animate the solution
ani = solver.animate()
HTML(ani.to_jshtml())
*********************************
* Partial differential equation *
*********************************

               2          
∂             ∂           
──(u(t, x)) = ───(u(t, x))
∂t              2         
              ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), t) - Derivative(u(t, x), (x, 2))

Expanded equation: Derivative(u(t, x), t) - Derivative(u(t, x), (x, 2))
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2      
kx  - ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2      
kx  - ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡     2⎤
⎣-ⅈ⋅kx ⎦

--- Final linear operator ---
   2
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 3.111e-53
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 7.390e-12
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 4.035e-07
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 2.867e-05
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 2.799e-04
No description has been provided for this image
*********************
* Solution plotting *
*********************

No description has been provided for this image
Out[11]:
No description has been provided for this image

1D heat equation with Op¶

In [12]:
# Define the symbols and the equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

# 1D heat equation
#eq = Eq(diff(u, t),  diff(u, x, 2)) 
eq = Eq(diff(u, t), Op((I*kx)**2, u)/2 + diff(u, x, 2)/2)
#eq = Eq(Op(-(I*omega),u), Op(-(I*kx)**2, u)/2 + diff(u, x, 2)/2)
# Create the solver
solver = PDESolver(eq, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=2.0, Nt=100,
    initial_condition=lambda x: np.sin(x)
)

# Solve the equation
solver.solve()

# Exact solution function at t = 1
def u_exact(x, t):
    return np.sin(x) * np.exp(-t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

                                   2          
                                  ∂           
                                  ───(u(t, x))
                ⎛   2         ⎞     2         
∂             Op⎝-kx , u(t, x)⎠   ∂x          
──(u(t, x)) = ───────────────── + ────────────
∂t                    2                2      

********************
* Equation parsing *
********************


Equation rewritten in standard form: -Op(-kx**2, u(t, x))/2 + Derivative(u(t, x), t) - Derivative(u(t, x), (x, 2))/2

Expanded equation: -Op(-kx**2, u(t, x))/2 + Derivative(u(t, x), t) - Derivative(u(t, x), (x, 2))/2
Analyzing term: -Op(-kx**2, u(t, x))/2
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))/2
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 2)): -1/2}
Final nonlinear terms: []
Symbol terms: [(-1/2, -kx**2)]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2      
kx       
─── - ⅈ⋅ω
 2       

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: kx**2/2

Raw characteristic equation:
  2      
kx  - ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡     2⎤
⎣-ⅈ⋅kx ⎦

--- Final linear operator ---
   2
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.134e-03
/home/fifi/pdesolver_prod/PDESolver.py:4234: RuntimeWarning: invalid value encountered in divide
  return np.where(np.abs(z) > 1e-12, (np.exp(z) - 1) / z, 1.0)
/home/fifi/pdesolver_prod/PDESolver.py:4237: RuntimeWarning: invalid value encountered in divide
  return np.where(np.abs(z) > 1e-12, (np.exp(z) - 1 - z) / z**2, 0.5)
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 6.131e-03
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 6.145e-03
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 6.167e-03
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 6.197e-03
No description has been provided for this image

1D heat equation in Op formulation¶

In [13]:
# Define the symbols and the equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

# 1D heat equation in Op formulation
# eq = Eq(Op((-I*omega), u), diff(u, x, x))
eq = Eq(Op((-I*omega), u), Op((-I*kx)**2, u))

# Create the solver
solver = PDESolver(eq, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=512, Lt=Lt, Nt=400,
    initial_condition=lambda x: np.sin(x),
    initial_velocity=lambda x: np.zeros_like(x)  # ∂u/∂t(x,0) = 0
)

# Solve the equation
solver.solve()

# Exact solution function
def u_exact(x, t):
    return np.sin(x) * np.exp(-t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=2e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

                      ⎛   2         ⎞
Op(-ⅈ⋅ω, u(t, x)) = Op⎝-kx , u(t, x)⎠

********************
* Equation parsing *
********************


Equation rewritten in standard form: -Op(-kx**2, u(t, x)) + Op(-I*omega, u(t, x))

Expanded equation: -Op(-kx**2, u(t, x)) + Op(-I*omega, u(t, x))
Analyzing term: -Op(-kx**2, u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Op(-I*omega, u(t, x))
  --> Classified as symbolic linear term (Op)
Final linear terms: {}
Final nonlinear terms: []
Symbol terms: [(-1, -kx**2), (1, -I*omega)]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
0

--- Symbolic symbol analysis ---
symb_omega: -I*omega
symb_k: kx**2

Raw characteristic equation:
  2      
kx  - ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡     2⎤
⎣-ⅈ⋅kx ⎦

--- Final linear operator ---
   2
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 2.169e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 1.516e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.504e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.492e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.480e-02
No description has been provided for this image

1D diffusion equation with psiOp¶

In [14]:
# Definition of the PDE: ∂u/∂t = - ∂²u/∂x² (diffusion equation)
u = Function('u')
t, x, xi = symbols('t x xi')
eq = Eq(diff(u(t,x), t), psiOp(-xi**2, u(t,x)))

# Solver configuration
solver = PDESolver(eq)
Lt=2.0
solver.setup(Lx=2*np.pi, Nx=128, Lt=Lt, Nt=200,
             initial_condition=lambda x: np.sin(x))

# Solving and visualization
solver.solve()

# Exact solution function
def u_exact(x, t):
    return np.sin(x) * np.exp(-t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

∂                  ⎛  2         ⎞
──(u(t, x)) = psiOp⎝-ξ , u(t, x)⎠
∂t                               

********************
* Equation parsing *
********************


Equation rewritten in standard form: -psiOp(-xi**2, u(t, x)) + Derivative(u(t, x), t)
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: -psiOp(-xi**2, u(t, x)) + Derivative(u(t, x), t)
Analyzing term: -psiOp(-xi**2, u(t, x))
  --> Classified as pseudo linear term (psiOp)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(-1, -xi**2)]
Source terms: []
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
-ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
-ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  [(-1, -xi**2)]
✅ Time derivative coefficient detected: 1

symbol = 
  2
-ξ 
⚠️ For psiOp, use interactive_symbol_analysis.

*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 1.734e-02
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 1.852e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.771e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.745e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.786e-02
No description has been provided for this image

1D heat equation with Op¶

In [15]:
# Define symbols and equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u')
u = u_func(t, x)

# Parameters
alpha = 1.8
nu = 0.1

# Equation
eq = Eq(diff(u, t), -Op(abs(kx)**alpha, u) + nu * diff(u, x, 2))

# Create the solver
solver = PDESolver(eq, dealiasing_ratio=0.5, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=2000,
    initial_condition=lambda x: np.sin(x)
)

# Solve the equation
solver.solve()

# Exact solution function at t = 1
def u_exact(x, t):
    return np.sin(x) * np.exp(-t * (abs(1)**alpha + nu * 1**2))

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=2e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

                                            2          
∂                 ⎛    1.8         ⎞       ∂           
──(u(t, x)) = - Op⎝│kx│   , u(t, x)⎠ + 0.1⋅───(u(t, x))
∂t                                           2         
                                           ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Op(Abs(kx)**1.8, u(t, x)) + Derivative(u(t, x), t) - 0.1*Derivative(u(t, x), (x, 2))

Expanded equation: Op(Abs(kx)**1.8, u(t, x)) + Derivative(u(t, x), t) - 0.1*Derivative(u(t, x), (x, 2))
Analyzing term: Op(Abs(kx)**1.8, u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -0.1*Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 2)): -0.100000000000000}
Final nonlinear terms: []
Symbol terms: [(1, Abs(kx)**1.8)]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
      2      
0.1⋅kx  - ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: Abs(kx)**1.8

Raw characteristic equation:
      2             1.8
0.1⋅kx  - ⅈ⋅ω + │kx│   
Temporal order from dispersion relation: 1
self.pseudo_terms =  []
--- Solutions found ---
⎡  ⎛        2       9/5⎞⎤
⎣ⅈ⋅⎝- 0.1⋅kx  - │kx│   ⎠⎦

--- Final linear operator ---
        2       9/5
- 0.1⋅kx  - │kx│   

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.134e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 1.958e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.695e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.434e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.192e-02
No description has been provided for this image

1D Burgers equation¶

In [16]:
# Definition of symbols and equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u = Function('u')(t, x)

# 1D Burgers equation
nu = 0.1
eq = Eq(diff(u, t), -u * diff(u, x) + nu * diff(u, x, x))

# Corrected exact solution
def phi(x, t):
    return 2 + np.sin(x) * np.exp(-nu * t)


def dphi_dx(x, t):
    return np.cos(x) * np.exp(-nu * t)

def u_exact(x, t):
    return -2 * nu * dphi_dx(x, t) / phi(x, t)

# Creation of the solver
solver = PDESolver(eq, time_scheme='ETD-RK4')
Lt = 1.0

# Configuration with corrected initial condition
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=200,
    initial_condition=lambda x: u_exact(x, 0)
)

# Solving
solver.solve()

# Automated tests
n_test = 4
test_set = [
    solver.test(
        u_exact=u_exact,
        t_eval=i * Lt / n_test,
        threshold=5e-2,  # Adjusted threshold
        component='real'
    )
    for i in range(n_test + 1)
]
*********************************
* Partial differential equation *
*********************************

                                           2          
∂                       ∂                 ∂           
──(u(t, x)) = - u(t, x)⋅──(u(t, x)) + 0.1⋅───(u(t, x))
∂t                      ∂x                  2         
                                          ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: u(t, x)*Derivative(u(t, x), x) + Derivative(u(t, x), t) - 0.1*Derivative(u(t, x), (x, 2))

Expanded equation: u(t, x)*Derivative(u(t, x), x) + Derivative(u(t, x), t) - 0.1*Derivative(u(t, x), (x, 2))
Analyzing term: u(t, x)*Derivative(u(t, x), x)
  --> Classified as nonlinear
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -0.1*Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 2)): -0.100000000000000}
Final nonlinear terms: [u(t, x)*Derivative(u(t, x), x)]
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************

Characteristic equation before symbol treatment:
      2      
0.1⋅kx  - ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
      2      
0.1⋅kx  - ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡         2⎤
⎣-0.1⋅ⅈ⋅kx ⎦

--- Final linear operator ---
       2
-0.1⋅kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 2.790e-03
No description has been provided for this image
Closest available time to t_eval=0.25: 0.25
Test error t = 0.25: 1.455e-02
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 2.692e-02
No description has been provided for this image
Closest available time to t_eval=0.75: 0.75
Test error t = 0.75: 3.759e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 4.685e-02
No description has been provided for this image

1D equation with psiOp depending on spatial variable but not on $\xi$¶

In [17]:
# === Symbols ===
t, x, xi = symbols('t x xi', real=True)
u = Function('u')
# === Symbol dependent on x, periodic
symbol_expr = 1 + sin(x)
# === Equation ∂t u = -ψOp(symbol_expr, u) = - (1 + sin x) * u
eq = Eq(diff(u(t,x), t), -psiOp(symbol_expr, u(t,x)))
# === Solver creation
solver = PDESolver(eq)
# === Parameters
Lx = 2 * np.pi
Nx = 128
Lt = 2.0
Nt = 200
# === Initial condition
initial_condition = lambda x: np.cos(x)
# === Exact solution
def u_exact(x, t):
    return np.cos(x) * np.exp(-t * (1 + np.sin(x)))
# === Setup
solver.setup(
    Lx=Lx,
    Nx=Nx,
    Lt=Lt,
    Nt=Nt,
    boundary_condition='periodic',
    initial_condition=initial_condition
)
# === Solving
solver.solve()
# === Tests
n_test = 4
for i in range(n_test + 1):
    t_eval = i * Lt / n_test
    solver.test(
        u_exact=u_exact,
        t_eval=t_eval,
        threshold=5e-2,
        component='real'
    )
*********************************
* Partial differential equation *
*********************************

∂                                        
──(u(t, x)) = -psiOp(sin(x) + 1, u(t, x))
∂t                                       

********************
* Equation parsing *
********************


Equation rewritten in standard form: psiOp(sin(x) + 1, u(t, x)) + Derivative(u(t, x), t)
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: psiOp(sin(x) + 1, u(t, x)) + Derivative(u(t, x), t)
Analyzing term: psiOp(sin(x) + 1, u(t, x))
  --> Classified as pseudo linear term (psiOp)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(1, sin(x) + 1)]
Source terms: []
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
-ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
-ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  [(1, sin(x) + 1)]
✅ Time derivative coefficient detected: 1

symbol = 
sin(x) + 1
⚠️ For psiOp, use interactive_symbol_analysis.

*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.019e-04
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 9.440e-03
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.165e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.267e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.203e-02
No description has been provided for this image

1D wave equation with periodic initial condition¶

In [18]:
# Define the symbols and the equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

# Wave equation
eq = Eq(diff(u, t, t), diff(u, x, x))

# Create the solver
solver = PDESolver(eq, time_scheme="ETD-RK4")
Lt=2.0
# Domain and initial conditions setup
solver.setup(
    Lx=2 * np.pi, Nx=512, Lt=Lt, Nt=500,
    initial_condition=lambda x: np.sin(x),
    initial_velocity=lambda x: np.zeros_like(x)  # ∂u/∂t(x,0) = 0
)

# Solving
solver.solve()

solver.plot_energy()
solver.plot_energy(log=True) 

# Exact solution 
def u_exact(x, t):
    return np.sin(x) * np.cos(t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=2e-1, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

 2              2          
∂              ∂           
───(u(t, x)) = ───(u(t, x))
  2              2         
∂t             ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))

Expanded equation: Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), (t, 2)): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2    2
kx  - ω 

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2    2
kx  - ω 
Temporal order from dispersion relation: 2
self.pseudo_terms =  []

--- Solutions found ---
[-kx, kx]
--- Final linear operator ---
   2
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*****************************
* Wave propagation analysis *
*****************************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

No description has been provided for this image
No description has been provided for this image
Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 2.169e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 1.022e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 2.173e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 1.530e-01
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 2.070e-02
No description has been provided for this image

1D wave equation with compact support initial condition¶

In [19]:
# Define the symbols and the wave equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u = Function('u')(t, x)

# 1D wave equation: ∂²u/∂t² = ∂²u/∂x²
eq = Eq(diff(u, t, t), diff(u, x, x))

# Create the PDE solver with ETD-RK4 time integration
solver = PDESolver(eq, time_scheme="ETD-RK4")

# Simulation parameters
Lt = 10.0          # Total simulation time
Lx = 30.0          # Spatial domain size (increased for better Gaussian containment)
Nx = 1024          # Number of spatial grid points
Nt = 1000          # Number of time steps

# Gaussian initial condition parameters
sigma = 2.0        # Standard deviation of the Gaussian
x0 = 0.0           # Center position

# Initial condition: Gaussian pulse
initial_condition = lambda x: np.exp(-(x - x0)**2 / (2*sigma**2))

# Exact solution using d'Alembert's formula for wave equation
def u_exact(x, t):
    return 0.5 * (np.exp(-(x - t - x0)**2 / (2*sigma**2)) + 
                  np.exp(-(x + t - x0)**2 / (2*sigma**2)))

# Setup the solver with increased domain size
solver.setup(
    Lx=Lx, Nx=Nx, Lt=Lt, Nt=Nt,
    initial_condition=initial_condition,
    initial_velocity=lambda x: np.zeros_like(x)  # Zero initial velocity
)

# Solve the equation
solver.solve()

# Visualize energy conservation
solver.plot_energy()
solver.plot_energy(log=True)

# Perform automatic validation tests
n_test = 4
test_set = [
    solver.test(
        u_exact=u_exact,
        t_eval=i * Lt / n_test,
        threshold=1e-1,    # Adjusted threshold for Gaussian decay
        component='real'
    )
    for i in range(n_test + 1)
]
*********************************
* Partial differential equation *
*********************************

 2              2          
∂              ∂           
───(u(t, x)) = ───(u(t, x))
  2              2         
∂t             ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))

Expanded equation: Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), (t, 2)): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2    2
kx  - ω 

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2    2
kx  - ω 
Temporal order from dispersion relation: 2
self.pseudo_terms =  []

--- Solutions found ---
[-kx, kx]

--- Final linear operator ---
   2
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*****************************
* Wave propagation analysis *
*****************************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

No description has been provided for this image
No description has been provided for this image
Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 1.360e-14
No description has been provided for this image
Closest available time to t_eval=2.5: 2.5
Test error t = 2.5: 3.380e-02
No description has been provided for this image
Closest available time to t_eval=5.0: 5.0
Test error t = 5.0: 3.143e-02
No description has been provided for this image
Closest available time to t_eval=7.5: 7.5
Test error t = 7.5: 3.108e-02
No description has been provided for this image
Closest available time to t_eval=10.0: 10.0
Test error t = 10.0: 3.247e-02
No description has been provided for this image

1D wave equation with a source term¶

In [20]:
# Define the symbols and the wave equation with a source term
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u')
u = u_func(t, x)

# Source term
source_term = cos(x) * (3 * cos(sqrt(2) * t) - sqrt(2) * sin(sqrt(2) * t))

# Equation with source term
eq = Eq(diff(u, t, t), diff(u, x, x) - u + source_term)

# Create the solver with ETD-RK4 scheme
solver = PDESolver(eq, time_scheme='ETD-RK4', dealiasing_ratio=1)

# Simulation parameters
Lt = 2.0  # Total simulation time
solver.setup(
    Lx=20, Nx=1024, Lt=Lt, Nt=400,
    initial_condition=lambda x: np.cos(x),
    initial_velocity=lambda x: np.zeros_like(x)
)

# Solving
solver.solve()

# Plot energy evolution
solver.plot_energy()
solver.plot_energy(log=True)

# Exact solution at t = 2: harmonic oscillation with frequency sqrt(2)
def u_exact(x, t):
    return np.cos(x) * np.cos(np.sqrt(2) * t)

# Automatic testing
n_test = 4
test_set = [
    solver.test(
        u_exact=u_exact,
        t_eval=i * Lt / n_test,
        threshold=1,  # Adjust threshold if necessary
        component='real'
    )
    for i in range(n_test + 1)
]
*********************************
* Partial differential equation *
*********************************

 2                                                               2          
∂                                                               ∂           
───(u(t, x)) = (-√2⋅sin(√2⋅t) + 3⋅cos(√2⋅t))⋅cos(x) - u(t, x) + ───(u(t, x))
  2                                                               2         
∂t                                                              ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: -(-sqrt(2)*sin(sqrt(2)*t) + 3*cos(sqrt(2)*t))*cos(x) + u(t, x) + Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))

Expanded equation: u(t, x) + sqrt(2)*sin(sqrt(2)*t)*cos(x) - 3*cos(x)*cos(sqrt(2)*t) + Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))
Analyzing term: u(t, x)
  --> Classified as linear
Analyzing term: sqrt(2)*sin(sqrt(2)*t)*cos(x)
  --> Classified as source term
Analyzing term: -3*cos(x)*cos(sqrt(2)*t)
  --> Classified as source term
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {u(t, x): 1, Derivative(u(t, x), (t, 2)): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: [sqrt(2)*sin(sqrt(2)*t)*cos(x), -3*cos(x)*cos(sqrt(2)*t)]

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2    2    
kx  - ω  + 1

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2    2    
kx  - ω  + 1
Temporal order from dispersion relation: 2
self.pseudo_terms =  []

--- Solutions found ---
⎡    _________     _________⎤
⎢   ╱   2         ╱   2     ⎥
⎣-╲╱  kx  + 1 , ╲╱  kx  + 1 ⎦

--- Final linear operator ---
    2    
- kx  - 1
*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*****************************
* Wave propagation analysis *
*****************************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

No description has been provided for this image
No description has been provided for this image
Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 8.905e-04
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 6.417e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 6.890e-01
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 2.464e-01
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.127e-01
No description has been provided for this image

1D wave equation with Op¶

In [21]:
# Define symbols and equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u')
u = u_func(t, x)

# Parameters
gamma = 1.4

# Equation
eq = Eq(diff(u, t, 2) - diff(u, x, 2), -Op(abs(kx)**gamma, u))

# Create the solver
solver = PDESolver(eq, dealiasing_ratio=0.5, time_scheme='ETD-RK4')
Lt=2.0
# Domain and initial condition setup
solver.setup(
    Lx=2 * np.pi, Nx=256, Lt=Lt, Nt=2000,
    initial_condition=lambda x: np.sin(x),
    initial_velocity=lambda x: np.zeros_like(x)  # Correction ici
)

# Solve the equation
solver.solve()

# Exact solution function at t = 1
def u_exact(x, t):
    return np.sin(x) * np.cos(np.sqrt(1 + abs(1)**gamma) * t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=0.2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

 2              2                                  
∂              ∂                 ⎛    1.4         ⎞
───(u(t, x)) - ───(u(t, x)) = -Op⎝│kx│   , u(t, x)⎠
  2              2                                 
∂t             ∂x                                  

********************
* Equation parsing *
********************


Equation rewritten in standard form: Op(Abs(kx)**1.4, u(t, x)) + Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))

Expanded equation: Op(Abs(kx)**1.4, u(t, x)) + Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))
Analyzing term: Op(Abs(kx)**1.4, u(t, x))
  --> Classified as symbolic linear term (Op)
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), (t, 2)): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: [(1, Abs(kx)**1.4)]
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2    2
kx  - ω 

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: Abs(kx)**1.4

Raw characteristic equation:
  2    2       1.4
kx  - ω  + │kx│   
Temporal order from dispersion relation: 2
self.pseudo_terms =  []
--- Solutions found ---
⎡    _______________     _______________⎤
⎢   ╱   2       1.4     ╱   2       1.4 ⎥
⎣-╲╱  kx  + │kx│    , ╲╱  kx  + │kx│    ⎦

--- Final linear operator ---
    2       1.4
- kx  - │kx│   

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*****************************
* Wave propagation analysis *
*****************************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.134e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 2.523e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 1.416e-01
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 3.260e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.805e-02
No description has been provided for this image

1D wave equation with psiOp¶

In [22]:
# Define the symbols
t, x, xi = symbols('t x xi', real=True)
u_func = Function('u') 
u = u_func(t, x)

# Wave equation with psiOp
eq = Eq(diff(u, t, t), psiOp((-I*xi)**2, u))

# Create the solver
solver = PDESolver(eq)

Lt = 5.0

# Domain and initial conditions setup
solver.setup(
    Lx=2 * np.pi, Nx=512, Lt=Lt, Nt=1000,
    initial_condition=lambda x: np.sin(x),
    initial_velocity=lambda x: np.zeros_like(x)  # ∂u/∂t(x,0) = 0
)

# Solve
solver.solve()

# Plot energy
solver.plot_energy()
solver.plot_energy(log=True)

# Exact solution
def u_exact(x, t):
    return np.sin(x) * np.cos(t)

# Automatic testing
n_test = 10
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=1, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

 2                                
∂                   ⎛  2         ⎞
───(u(t, x)) = psiOp⎝-ξ , u(t, x)⎠
  2                               
∂t                                

********************
* Equation parsing *
********************


Equation rewritten in standard form: -psiOp(-xi**2, u(t, x)) + Derivative(u(t, x), (t, 2))
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: -psiOp(-xi**2, u(t, x)) + Derivative(u(t, x), (t, 2))
Analyzing term: -psiOp(-xi**2, u(t, x))
  --> Classified as pseudo linear term (psiOp)
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), (t, 2)): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(-1, -xi**2)]
Source terms: []
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2
-ω 

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2
-ω 
Temporal order from dispersion relation: 2
self.pseudo_terms =  [(-1, -xi**2)]
✅ Time derivative coefficient detected: 1

symbol = 
  2
-ξ 
⚠️ For psiOp, use interactive_symbol_analysis.

*******************
* Solving the PDE *
*******************

No energy data recorded. Call compute_energy() within solve().
No energy data recorded. Call compute_energy() within solve().
Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 2.169e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 2.526e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 6.972e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 6.340e-01
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 9.970e-02
No description has been provided for this image
Closest available time to t_eval=2.5: 2.5
Test error t = 2.5: 3.567e-02
No description has been provided for this image
Closest available time to t_eval=3.0: 3.0
Test error t = 3.0: 1.146e-02
No description has been provided for this image
Closest available time to t_eval=3.5: 3.5
Test error t = 3.5: 1.818e-02
No description has been provided for this image
Closest available time to t_eval=4.0: 4.0
Test error t = 4.0: 5.193e-02
No description has been provided for this image
Closest available time to t_eval=4.5: 4.5
Test error t = 4.5: 2.080e-01
No description has been provided for this image
Closest available time to t_eval=5.0: 5.0
Test error t = 5.0: 1.534e-01
No description has been provided for this image

1D equation with psiOp depending on spatial potential¶

In [23]:
# Symbols
t, x, xi = symbols('t x xi', real=True)
u = Function('u')

# Symbol for the pseudo-differential operator (regular, x-dependent)
p_expr = xi**2 + cos(x)

# Define the PDE
equation = Eq(diff(u(t,x), t, t), -psiOp(p_expr, u(t,x)))
solver = PDESolver(equation)

# Setup the solver
Lx = 2 * np.pi
Nx = 512
Lt = 2.0
Nt = 1000
k = 5
omega = np.sqrt(k**2 + 0)  # approximation si V(x) ≈ 0

initial_condition = lambda x: np.cos(k * x)
initial_velocity = lambda x: 0 * x
# Exact solution
u_exact = lambda x, t: np.cos(omega * t) * np.cos(k * x)

solver.setup(
    Lx=Lx,
    Nx=Nx,
    Lt=Lt,
    Nt=Nt,
    boundary_condition='periodic',
    initial_condition=initial_condition,
    initial_velocity=initial_velocity
)

# Solve the PDE
solver.solve()

# Perform tests
for i in range(5):
    solver.test(u_exact=u_exact, t_eval=i * Lt / 4, threshold=3e-1, component='real')
*********************************
* Partial differential equation *
*********************************

 2                                         
∂                    ⎛ 2                  ⎞
───(u(t, x)) = -psiOp⎝ξ  + cos(x), u(t, x)⎠
  2                                        
∂t                                         

********************
* Equation parsing *
********************


Equation rewritten in standard form: psiOp(xi**2 + cos(x), u(t, x)) + Derivative(u(t, x), (t, 2))
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: psiOp(xi**2 + cos(x), u(t, x)) + Derivative(u(t, x), (t, 2))
Analyzing term: psiOp(xi**2 + cos(x), u(t, x))
  --> Classified as pseudo linear term (psiOp)
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), (t, 2)): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(1, xi**2 + cos(x))]
Source terms: []
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2
-ω 

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2
-ω 
Temporal order from dispersion relation: 2
self.pseudo_terms =  [(1, xi**2 + cos(x))]
✅ Time derivative coefficient detected: 1

symbol = 
 2         
ξ  + cos(x)
⚠️ For psiOp, use interactive_symbol_analysis.

*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 4.700e-04
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 7.342e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 2.809e-01
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 2.035e-01
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 7.893e-02
No description has been provided for this image

1D KdV equation¶

In [24]:
# Define the symbols and the KdV equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)


eq = Eq(diff(u, t) + 6 * u * diff(u, x) - diff(u, x, x, x), 0)  # Standard KdV form

# Soliton parameters
c = 0.5   # Speed and amplitude of the soliton
x0 = 0.0  # Initial position

# Initial condition: centered soliton
initial_condition = lambda x: c / 2 * (1 / np.cosh(np.sqrt(c)/2 * (x - x0)))**2

# Create the solver with periodic boundary conditions and adapted dealiasing
solver = PDESolver(eq, time_scheme='ETD-RK4', dealiasing_ratio=2/3)

# Simulation parameters
Lx = 40
Nx = 2048
Lt = 5.0
Nt = 1000

# Setup
solver.setup(Lx=Lx, Nx=Nx, Lt=Lt, Nt=Nt, initial_condition=initial_condition)

# Solve
solver.solve()

# Exact solution at t = Lt
def u_exact(x, t):
    return c / 2 * (1 / np.cosh(np.sqrt(c)/2 * (x - c*t - x0)))**2

# Automatic testing
n_test = 6
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=0.5, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

                                       3              
          ∂             ∂             ∂               
6⋅u(t, x)⋅──(u(t, x)) + ──(u(t, x)) - ───(u(t, x)) = 0
          ∂x            ∂t              3             
                                      ∂x              

********************
* Equation parsing *
********************


Equation rewritten in standard form: 6*u(t, x)*Derivative(u(t, x), x) + Derivative(u(t, x), t) - Derivative(u(t, x), (x, 3))

Expanded equation: 6*u(t, x)*Derivative(u(t, x), x) + Derivative(u(t, x), t) - Derivative(u(t, x), (x, 3))
Analyzing term: 6*u(t, x)*Derivative(u(t, x), x)
  --> Classified as nonlinear
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 3))
  Derivative found: Derivative(u(t, x), (x, 3))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 3)): -1}
Final nonlinear terms: [6*u(t, x)*Derivative(u(t, x), x)]
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************

Characteristic equation before symbol treatment:
  ⎛  3    ⎞
ⅈ⋅⎝kx  - ω⎠

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  ⎛  3    ⎞
ⅈ⋅⎝kx  - ω⎠
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡  3⎤
⎣kx ⎦

--- Final linear operator ---
     3
-ⅈ⋅kx 

*****************
* CFL condition *
*****************

CFL condition violated: dt = 0.005, max allowed dt = 2.346607975283368e-09

********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
⚠️ Insufficient high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 5.816e-09
No description has been provided for this image
Closest available time to t_eval=0.8333333333333334: 0.8500000000000001
Test error t = 0.8500000000000001: 9.495e-02
No description has been provided for this image
Closest available time to t_eval=1.6666666666666667: 1.6500000000000001
Test error t = 1.6500000000000001: 1.760e-01
No description has been provided for this image
Closest available time to t_eval=2.5: 2.5
Test error t = 2.5: 2.556e-01
No description has been provided for this image
Closest available time to t_eval=3.3333333333333335: 3.35
Test error t = 3.35: 3.318e-01
No description has been provided for this image
Closest available time to t_eval=4.166666666666667: 4.15
Test error t = 4.15: 4.014e-01
No description has been provided for this image
Closest available time to t_eval=5.0: 5.0
Test error t = 5.0: 4.741e-01
No description has been provided for this image

1D Schrodinger equation¶

In [25]:
# Define the symbols and the 1D Schrödinger equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

eq = Eq(diff(u, t), -I * diff(u, x, x))

# Create the solver with ETD-RK4 time scheme
solver = PDESolver(eq, time_scheme='ETD-RK4', dealiasing_ratio=1/2)
Lt=2.0
# Configure the domain and initial condition: modulated Gaussian packet
solver.setup(
    Lx=20, Nx=1024, Lt=Lt, Nt=500,
    initial_condition=lambda x: np.exp(-x**2) * np.exp(1j * x)
)

# Solve
solver.solve()

# Exact solution (one of the two propagated packets, here moving to the left)
def u_exact(x, t):
    return 1 / np.sqrt(1 - 4j * t) * np.exp(1j * (x + t)) * np.exp(-((x + 2*t)**2) / (1 - 4j * t))

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=0.5, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

                  2          
∂                ∂           
──(u(t, x)) = -ⅈ⋅───(u(t, x))
∂t                 2         
                 ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), t) + I*Derivative(u(t, x), (x, 2))

Expanded equation: Derivative(u(t, x), t) + I*Derivative(u(t, x), (x, 2))
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: I*Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 2)): I}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  ⎛    2    ⎞
ⅈ⋅⎝- kx  - ω⎠

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  ⎛    2    ⎞
ⅈ⋅⎝- kx  - ω⎠
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡   2⎤
⎣-kx ⎦

--- Final linear operator ---
    2
ⅈ⋅kx 

*****************
* CFL condition *
*****************

CFL condition violated: dt = 0.004, max allowed dt = 3.7745082245147894e-07

********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
⚠️ Insufficient high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 5.367e-45
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 4.410e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 4.590e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 9.757e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 2.648e-01
No description has been provided for this image

1D Schrodinger equation with psiOp¶

In [26]:
# Define the symbols and the 1D Schrödinger equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

eq = Eq(diff(u, t), -I * psiOp(-xi**2, u))

# Create the solver with ETD-RK4 time scheme
solver = PDESolver(eq)
Lt=2.0
# Configure the domain and initial condition: modulated Gaussian packet
solver.setup(
    Lx=20, Nx=1024, Lt=Lt, Nt=500,
    initial_condition=lambda x: np.exp(-x**2) * np.exp(1j * x)
)

# Solve
solver.solve()

# Exact solution (one of the two propagated packets, here moving to the left)
def u_exact(x, t):
    return 1 / np.sqrt(1 - 4j * t) * np.exp(1j * (x + t)) * np.exp(-((x + 2*t)**2) / (1 - 4j * t))

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=0.5, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

∂                     ⎛  2         ⎞
──(u(t, x)) = -ⅈ⋅psiOp⎝-ξ , u(t, x)⎠
∂t                                  

********************
* Equation parsing *
********************


Equation rewritten in standard form: I*psiOp(-xi**2, u(t, x)) + Derivative(u(t, x), t)
⚠️ psiOp detected: skipping expansion for safety

Expanded equation: I*psiOp(-xi**2, u(t, x)) + Derivative(u(t, x), t)
Analyzing term: I*psiOp(-xi**2, u(t, x))
  --> Classified as pseudo linear term (psiOp)
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: [(I, -xi**2)]
Source terms: []
⚠️  Pseudo‑differential operator detected: all other linear terms have been rejected.

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
-ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
-ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  [(I, -xi**2)]
✅ Time derivative coefficient detected: 1

symbol = 
  2
-ξ 
⚠️ For psiOp, use interactive_symbol_analysis.

*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 5.367e-45
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 4.410e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 4.589e-02
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 9.680e-02
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 2.597e-01
No description has been provided for this image

1D Klein-Gordon equation¶

In [27]:
# Define the symbols and the Klein-Gordon equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

eq = Eq(diff(u, t, t), diff(u, x, x) - u)

# Create the solver with ETD-RK4 scheme
solver = PDESolver(eq, time_scheme='ETD-RK4', dealiasing_ratio=1/4)
Lt=2.0
# Simulation parameters
solver.setup(
    Lx=20, Nx=1024, Lt=Lt, Nt=200,
    initial_condition=lambda x: np.cos(x),
    initial_velocity=lambda x: np.zeros_like(x)
)

# Solving
solver.solve()

solver.plot_energy()
solver.plot_energy(log=True) 

# Exact solution at t = 2: harmonic oscillation with frequency sqrt(2)
def u_exact(x, t):
    return np.cos(np.sqrt(2) * t) * np.cos(x)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

 2                         2          
∂                         ∂           
───(u(t, x)) = -u(t, x) + ───(u(t, x))
  2                         2         
∂t                        ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: u(t, x) + Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))

Expanded equation: u(t, x) + Derivative(u(t, x), (t, 2)) - Derivative(u(t, x), (x, 2))
Analyzing term: u(t, x)
  --> Classified as linear
Analyzing term: Derivative(u(t, x), (t, 2))
  Derivative found: Derivative(u(t, x), (t, 2))
  --> Classified as linear
Analyzing term: -Derivative(u(t, x), (x, 2))
  Derivative found: Derivative(u(t, x), (x, 2))
  --> Classified as linear
Final linear terms: {u(t, x): 1, Derivative(u(t, x), (t, 2)): 1, Derivative(u(t, x), (x, 2)): -1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  2    2    
kx  - ω  + 1

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  2    2    
kx  - ω  + 1
Temporal order from dispersion relation: 2
self.pseudo_terms =  []

--- Solutions found ---
⎡    _________     _________⎤
⎢   ╱   2         ╱   2     ⎥
⎣-╲╱  kx  + 1 , ╲╱  kx  + 1 ⎦

--- Final linear operator ---
    2    
- kx  - 1

*****************
* CFL condition *
*****************

CFL condition violated: dt = 0.01, max allowed dt = 0.00975625926088619

********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*****************************
* Wave propagation analysis *
*****************************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

No description has been provided for this image
No description has been provided for this image
Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 8.905e-04
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 6.145e-02
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 6.619e-01
No description has been provided for this image
Closest available time to t_eval=1.5: 1.5
Test error t = 1.5: 2.391e-01
No description has been provided for this image
Closest available time to t_eval=2.0: 2.0
Test error t = 2.0: 1.125e-01
No description has been provided for this image

1D biharmonic equation¶

In [28]:
# Definition of the 1D biharmonic equation
t, x, kx, xi, omega = symbols('t x kx xi omega')
u_func = Function('u') 
u = u_func(t, x)

biharmonic_eq = Eq(diff(u, t), -diff(u, x, x, x, x))

# Creation of the solver with periodic boundary conditions
solver = PDESolver(biharmonic_eq)

# Configuration of the domain and initial condition
Lx = 2 * np.pi
Nx = 256
Lt = 1.0
Nt = 200

solver.setup(
    Lx=Lx, Nx=Nx,
    Lt=Lt, Nt=Nt,
    initial_condition=lambda x: np.sin(x)
)

# Solving
solver.solve()

# Exact solution
def u_exact(x, t):
    return np.sin(x) * np.exp(-t)

# Automatic testing
n_test = 4
test_set = [solver.test(u_exact=u_exact, t_eval=i * Lt / n_test, threshold=5e-2, component='real') for i in range(n_test + 1)]
*********************************
* Partial differential equation *
*********************************

                4          
∂              ∂           
──(u(t, x)) = -───(u(t, x))
∂t               4         
               ∂x          

********************
* Equation parsing *
********************


Equation rewritten in standard form: Derivative(u(t, x), t) + Derivative(u(t, x), (x, 4))

Expanded equation: Derivative(u(t, x), t) + Derivative(u(t, x), (x, 4))
Analyzing term: Derivative(u(t, x), t)
  Derivative found: Derivative(u(t, x), t)
  --> Classified as linear
Analyzing term: Derivative(u(t, x), (x, 4))
  Derivative found: Derivative(u(t, x), (x, 4))
  --> Classified as linear
Final linear terms: {Derivative(u(t, x), t): 1, Derivative(u(t, x), (x, 4)): 1}
Final nonlinear terms: []
Symbol terms: []
Pseudo terms: []
Source terms: []

*******************************
* Linear operator computation *
*******************************


Characteristic equation before symbol treatment:
  4      
kx  - ⅈ⋅ω

--- Symbolic symbol analysis ---
symb_omega: 0
symb_k: 0

Raw characteristic equation:
  4      
kx  - ⅈ⋅ω
Temporal order from dispersion relation: 1
self.pseudo_terms =  []

--- Solutions found ---
⎡     4⎤
⎣-ⅈ⋅kx ⎦

--- Final linear operator ---
   4
-kx 

*****************
* CFL condition *
*****************


********************
* Symbol condition *
********************

✅ Spectral stability satisfied: Re(a(k)) ≤ 0
✅ Proper high-frequency dissipation
✅ Reasonable spectral growth
✔ Symbol analysis completed.

*******************
* Symbol plotting *
*******************

No description has been provided for this image
*******************
* Solving the PDE *
*******************

Closest available time to t_eval=0.0: 0.0
Test error t = 0.0: 6.134e-03
No description has been provided for this image
Closest available time to t_eval=0.25: 0.25
Test error t = 0.25: 7.655e-03
No description has been provided for this image
Closest available time to t_eval=0.5: 0.5
Test error t = 0.5: 7.383e-03
No description has been provided for this image
Closest available time to t_eval=0.75: 0.75
Test error t = 0.75: 7.131e-03
No description has been provided for this image
Closest available time to t_eval=1.0: 1.0
Test error t = 1.0: 6.903e-03
No description has been provided for this image
In [ ]: