@@ -33,7 +33,6 @@ The system consists of two coupled (1+1)D nonlinear PDEs:
33
33
34
34
```julia
35
35
using OrdinaryDiffEq, DiffEqDevTools, Plots, StaticArrays, FFTW, LinearAlgebra
36
- using SciMLBenchmarks
37
36
38
37
# Parameters
39
38
const β₂F = -1.0
@@ -48,6 +47,7 @@ const s4 = β₂F / abs(β₂S)
48
47
const s5 = γc / γs
49
48
const s6 = γf / γs
50
49
const q = 10.0
50
+ const steps=2000.0
51
51
52
52
# Grid parameters
53
53
const N = 2048
@@ -59,102 +59,97 @@ const T_max = N / 2
59
59
const dT = 1.0
60
60
const T = collect((-N/2):(N/2-1)) * dT
61
61
const ω = 2π * fftfreq(N, 1/dT)
62
+ const α = 0.5*sign(β₂S).*ω.^2.0
62
63
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))
66
66
end
67
67
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) )
70
70
end
71
71
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
75
74
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 )
78
77
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)
107
95
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)
111
100
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
117
104
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
119
109
end
120
110
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)
124
113
125
114
# 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)
127
116
128
117
# 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]
131
120
132
121
abstols = 1.0 ./ 10.0 .^ (5:8)
133
122
reltols = 1.0 ./ 10.0 .^ (2:5)
134
123
```
135
124
136
125
```julia
137
126
# 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])
140
130
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)
143
132
xlabel!(p1, "τ")
144
133
ylabel!(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])
150
134
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)
153
136
xlabel!(p2, "τ")
154
137
ylabel!(p2, "Amplitude")
155
- xlim!(p2, (-50, 50))
156
138
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))
158
153
```
159
154
160
155
## Low Order Methods
@@ -165,33 +160,18 @@ setups = [
165
160
Dict(:alg=>BS5()),
166
161
Dict(:alg=>Tsit5()),
167
162
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 = [
182
163
Dict(:alg=>DP8()),
183
164
Dict(:alg=>Vern7()),
184
165
Dict(:alg=>Vern8()),
185
166
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()),
189
169
]
190
170
191
171
wp = WorkPrecisionSet(probs, abstols, reltols, setups;
192
172
save_everystep=false, appxsol=test_sol, maxiters=Int(1e5),
193
173
numruns=10)
194
- plot(wp, title="NLS System - Higher Order Methods" )
174
+ plot(wp)
195
175
```
196
176
197
177
## Adaptive vs Fixed Step Methods
@@ -211,31 +191,11 @@ wp = WorkPrecisionSet(probs, abstols, reltols, setups;
211
191
plot(wp, title="NLS System - Adaptive vs Fixed Step")
212
192
```
213
193
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
-
234
194
### Conclusion
235
195
236
196
This 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:
237
197
238
- - High dimensionality (N=2048 complex variables → 4096 real variables)
198
+ - High dimensionality (N=2048 complex variables → 8192 real variables after real/imaginary splitting )
239
199
- Nonlinear dynamics with quadratic and cubic nonlinearities
240
200
- Oscillatory behavior due to dispersion and phase terms
241
201
- Conservation properties (energy, momentum)
0 commit comments