@@ -33,7 +33,6 @@ The system consists of two coupled (1+1)D nonlinear PDEs:
3333
3434```julia
3535using OrdinaryDiffEq, DiffEqDevTools, Plots, StaticArrays, FFTW, LinearAlgebra
36- using SciMLBenchmarks
3736
3837# Parameters
3938const β₂F = -1.0
@@ -48,6 +47,7 @@ const s4 = β₂F / abs(β₂S)
4847const s5 = γc / γs
4948const s6 = γf / γs
5049const q = 10.0
50+ const steps=2000.0
5151
5252# Grid parameters
5353const N = 2048
@@ -59,102 +59,97 @@ const T_max = N / 2
5959const dT = 1.0
6060const T = collect((-N/2):(N/2-1)) * dT
6161const ω = 2π * fftfreq(N, 1/dT)
62+ const α = 0.5*sign(β₂S).*ω.^2.0
6263
63- # Initial condition functions
64- function soliton(q, t; shift=0.0)
65- return sqrt(2*q) * sech.(sqrt(q) * (t .- shift)) * exp.(1im * (t .- shift))
64+ function f(x,y,z,a)
65+ return a.*exp.(-((x.-y).^2.0)./(2*z^2.0))
6666end
6767
68- function f_pulse(t, t0, A, σ² )
69- return A * exp.(-0.5 * (t .- t0).^2 / σ² )
68+ function soliton(q,t,shift )
69+ sqrt(2.0*q)*sech.(sqrt(2.0*q).*(t.-shift) )
7070end
7171
72- # Initial conditions
73- ψ₀ = soliton(q, T, shift=20.0)
74- F₀ = f_pulse(T, -20.0, 10, 1e-18) .* exp.(1.12157im * T)
72+ t=(-N/2.0:N/2.0-1.0)*dt
73+ shift = 20.0
7574
76- # Combine into state vector: [Re(ψ), Im(ψ), Re(φ), Im(φ)]
77- u₀ = vcat(real(ψ₀), imag(ψ₀), real(F₀), imag(F₀) )
75+ psi_0 = soliton(q,t,shift)
76+ F_0 = f.(t,-20.0,1e-1,10^-2).*cis.(1.12157 * t )
7877
79- function nls_rhs!(du, u, p, X)
80- # Extract real and imaginary parts
81- ψ_re = @view u[1:N]
82- ψ_im = @view u[N+1:2N]
83- φ_re = @view u[2N+1:3N]
84- φ_im = @view u[3N+1:4N]
85-
86- # Reconstruct complex arrays
87- ψ = complex.(ψ_re, ψ_im)
88- φ = complex.(φ_re, φ_im)
89-
90- # FFT to frequency domain
91- ψ_hat = fft(ψ)
92- φ_hat = fft(φ)
93-
94- # Apply dispersion terms in frequency domain
95- # First equation: -i∂ψ/∂X = -(sgn(β₂S)/2)(∂²ψ/∂τ²) + nonlinear terms
96- disp_ψ = -1im * (sign(β₂S)/2) * (1im * ω).^2 .* ψ_hat
97- ψ_disp = ifft(disp_ψ)
98-
99- # Second equation dispersion: -(s₄/2)(∂²φ/∂τ²) + is₁(∂φ/∂τ)
100- disp_φ = -1im * ((s4/2) * (1im * ω).^2 .* φ_hat + s1 * (1im * ω) .* φ_hat)
101- φ_disp = ifft(disp_φ)
102-
103- # Nonlinear terms
104- ψ_mod² = abs2.(ψ)
105- nonlin_ψ = -1im * ψ_mod² .* ψ
106- nonlin_φ = -1im * (s2 * ψ .* conj.(φ) * exp(1im * (s3 + q) * X) + s5 * ψ_mod² .* φ)
78+ # Split complex initial conditions into real and imaginary parts
79+ psi_0_fft = fft(psi_0)
80+ F_0_fft = fft(F_0)
81+ ini = [real(psi_0_fft); imag(psi_0_fft); real(F_0_fft); imag(F_0_fft)]
82+
83+ ## Solution
84+
85+ function ODE!(dX,X,p,t)
86+ s2, s3, s5, s6, alpha, Omega, N = p
87+ exp_term_psi = cis.(alpha .* t)
88+ exp_term_phi = cis.(Omega .* t)
89+
90+ # Reconstruct complex arrays from real and imaginary parts
91+ A = complex.(X[1:N], X[N+1:2*N]) .* exp_term_psi
92+ B = complex.(X[2*N+1:3*N], X[3*N+1:4*N]) .* exp_term_phi
93+ psi = ifft(A)
94+ phi = ifft(B)
10795
108- # Total RHS for each equation
109- dψ_dt = ψ_disp + nonlin_ψ
110- dφ_dt = φ_disp + nonlin_φ
96+ rhs1 = 0.5 * cis.(-s3 * t) * s2 .* (phi.^2.0) .+ psi .* abs2.(psi) .+ psi .* s5 .* abs2.(phi)
97+ rhs2 = cis.(s3 * t) * s2 .* psi .* conj(phi) .+ phi * s5 .* abs2.(psi) .+ phi .* s6 .* abs2.(phi)
98+ rhs1_fft = fft(rhs1)
99+ rhs2_fft = fft(rhs2)
111100
112- # Store results in du
113- du[1:N] .= real.(dψ_dt)
114- du[N+1:2N] .= imag.(dψ_dt)
115- du[2N+1:3N] .= real.(dφ_dt)
116- du[3N+1:4N] .= imag.(dφ_dt)
101+ # Compute complex derivatives and split back into real/imaginary parts
102+ dpsi_dt = 1im .* rhs1_fft ./ exp_term_psi
103+ dphi_dt = 1im .* rhs2_fft ./ exp_term_phi
117104
118- return nothing
105+ dX[1:N] = real.(dpsi_dt) # Real part of psi derivative
106+ dX[N+1:2*N] = imag.(dpsi_dt) # Imaginary part of psi derivative
107+ dX[2*N+1:3*N] = real.(dphi_dt) # Real part of phi derivative
108+ dX[3*N+1:4*N] = imag.(dphi_dt) # Imaginary part of phi derivative
119109end
120110
121- # Create the ODE problem
122- prob = ODEProblem(nls_rhs!, u₀, (0.0, L))
123- probstatic = ODEProblem{false}(nls_rhs!, u₀, (0.0, L))
111+ p = (s2, s3, s5, s6, α, ω, N)
112+ prob = ODEProblem(ODE!,ini,(0.0,L),p)
124113
125114# Generate reference solution
126- ref_sol = solve(prob, Vern7(), abstol=1e-12, reltol=1e-12, saveat=0.1 )
115+ ref_sol = solve(prob, Vern7(), abstol=1e-12, reltol=1e-12)
127116
128117# Store solutions for work-precision testing
129- probs = [prob, probstatic ]
130- test_sol = [ref_sol, ref_sol ]
118+ probs = [prob]
119+ test_sol = [ref_sol]
131120
132121abstols = 1.0 ./ 10.0 .^ (5:8)
133122reltols = 1.0 ./ 10.0 .^ (2:5)
134123```
135124
136125```julia
137126# Plot initial conditions
138- ψ_init = complex.(u₀[1:N], u₀[N+1:2N])
139- φ_init = complex.(u₀[2N+1:3N], u₀[3N+1:4N])
127+ u₀ = prob.u0
128+ ψ_init = complex.(u₀[1:N], u₀[N+1:2*N]) # Reconstruct from real/imaginary parts
129+ φ_init = complex.(u₀[2*N+1:3*N], u₀[3*N+1:4*N])
140130
141- p1 = plot(T, abs.(ψ_init), label="|ψ₀|", title="Initial Conditions", lw=2)
142- plot!(p1, T, abs.(φ_init), label="|φ₀|", lw=2)
131+ p1 = plot(t, abs.(ifft(ψ_init)), label="|ψ₀|", title="Initial Conditions", lw=2)
143132xlabel!(p1, "τ")
144133ylabel!(p1, "Amplitude")
145- xlim!(p1, (-50, 50))
146-
147- # Plot final solution
148- ψ_final = complex.(ref_sol.u[end][1:N], ref_sol.u[end][N+1:2N])
149- φ_final = complex.(ref_sol.u[end][2N+1:3N], ref_sol.u[end][3N+1:4N])
150134
151- p2 = plot(T, abs.(ψ_final), label="|ψ(L)|", title="Final Solutions", lw=2)
152- plot!(p2, T, abs.(φ_final), label="|φ(L)|", lw=2)
135+ p2 = plot(t, abs.(ifft(φ_init)), label="|φ₀|", lw=2)
153136xlabel!(p2, "τ")
154137ylabel!(p2, "Amplitude")
155- xlim!(p2, (-50, 50))
156138
157- plot(p1, p2, layout=(1,2), size=(800, 400))
139+ # Plot final solution
140+ u_final = ref_sol.u[end]
141+ ψ_final = complex.(u_final[1:N], u_final[N+1:2*N])
142+ φ_final = complex.(u_final[2*N+1:3*N], u_final[3*N+1:4*N])
143+
144+ p3 = plot(t, abs.(ifft(ψ_final)), label="|ψ(L)|", title="Final Solutions", lw=2)
145+ xlabel!(p3, "τ")
146+ ylabel!(p3, "Amplitude")
147+
148+ p4 = plot(t, abs.(ifft(φ_final)), label="|φ(L)|", lw=2)
149+ xlabel!(p4, "τ")
150+ ylabel!(p4, "Amplitude")
151+
152+ plot(p1, p2, p3, p4, layout=(2,2), size=(800, 400))
158153```
159154
160155## Low Order Methods
@@ -165,33 +160,18 @@ setups = [
165160 Dict(:alg=>BS5()),
166161 Dict(:alg=>Tsit5()),
167162 Dict(:alg=>Vern6()),
168- Dict(:alg=>Tsit5(), :prob_choice => 2),
169- Dict(:alg=>Vern6(), :prob_choice => 2)
170- ]
171-
172- wp = WorkPrecisionSet(probs, abstols, reltols, setups;
173- save_everystep=false, appxsol=test_sol, maxiters=Int(1e5),
174- numruns=10)
175- plot(wp, title="NLS System - Low Order Methods")
176- ```
177-
178- ## Higher Order Methods
179-
180- ```julia
181- setups = [
182163 Dict(:alg=>DP8()),
183164 Dict(:alg=>Vern7()),
184165 Dict(:alg=>Vern8()),
185166 Dict(:alg=>Vern9()),
186- Dict(:alg=>Vern7(), :prob_choice => 2),
187- Dict(:alg=>Vern8(), :prob_choice => 2),
188- Dict(:alg=>Vern9(), :prob_choice => 2)
167+ Dict(:alg=>ROCK2()),
168+ Dict(:alg=>ROCK4()),
189169]
190170
191171wp = WorkPrecisionSet(probs, abstols, reltols, setups;
192172 save_everystep=false, appxsol=test_sol, maxiters=Int(1e5),
193173 numruns=10)
194- plot(wp, title="NLS System - Higher Order Methods" )
174+ plot(wp)
195175```
196176
197177## Adaptive vs Fixed Step Methods
@@ -211,31 +191,11 @@ wp = WorkPrecisionSet(probs, abstols, reltols, setups;
211191plot(wp, title="NLS System - Adaptive vs Fixed Step")
212192```
213193
214- ## Special Methods for Oscillatory Problems
215-
216- ```julia
217- abstols = 1.0 ./ 10.0 .^ (6:9)
218- reltols = 1.0 ./ 10.0 .^ (3:6)
219-
220- setups = [
221- Dict(:alg=>Vern7()),
222- Dict(:alg=>Vern8()),
223- Dict(:alg=>Vern9()),
224- Dict(:alg=>DP8()),
225- Dict(:alg=>TsitPap8())
226- ]
227-
228- wp = WorkPrecisionSet(probs, abstols, reltols, setups;
229- save_everystep=false, appxsol=test_sol, maxiters=Int(1e5),
230- numruns=10)
231- plot(wp, title="NLS System - Oscillatory Methods")
232- ```
233-
234194### Conclusion
235195
236196This benchmark demonstrates the performance of various ODE solvers on a large (8192-dimensional) system derived from a coupled nonlinear Schrödinger equation via spectral discretization. The system exhibits:
237197
238- - High dimensionality (N=2048 complex variables → 4096 real variables)
198+ - High dimensionality (N=2048 complex variables → 8192 real variables after real/imaginary splitting )
239199- Nonlinear dynamics with quadratic and cubic nonlinearities
240200- Oscillatory behavior due to dispersion and phase terms
241201- Conservation properties (energy, momentum)
0 commit comments