Skip to content

Commit 369e655

Browse files
update the functions
1 parent 9a16b0f commit 369e655

File tree

2 files changed

+73
-106
lines changed

2 files changed

+73
-106
lines changed

benchmarks/NonStiffODE/NLS_wpd.jmd

Lines changed: 66 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ The system consists of two coupled (1+1)D nonlinear PDEs:
3333

3434
```julia
3535
using OrdinaryDiffEq, DiffEqDevTools, Plots, StaticArrays, FFTW, LinearAlgebra
36-
using SciMLBenchmarks
3736

3837
# Parameters
3938
const β₂F = -1.0
@@ -48,6 +47,7 @@ const s4 = β₂F / abs(β₂S)
4847
const s5 = γc / γs
4948
const s6 = γf / γs
5049
const q = 10.0
50+
const steps=2000.0
5151

5252
# Grid parameters
5353
const N = 2048
@@ -59,102 +59,97 @@ const T_max = N / 2
5959
const dT = 1.0
6060
const T = collect((-N/2):(N/2-1)) * dT
6161
const ω = 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))
6666
end
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))
7070
end
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
119109
end
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

132121
abstols = 1.0 ./ 10.0 .^ (5:8)
133122
reltols = 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)
143132
xlabel!(p1, "τ")
144133
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])
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)
153136
xlabel!(p2, "τ")
154137
ylabel!(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

191171
wp = 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;
211191
plot(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

236196
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:
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)

benchmarks/NonStiffODE/Project.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
[deps]
2+
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
23
DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d"
4+
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
35
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
46
LSODA = "7f56f5a3-f504-529b-bc02-0b1fe5e64312"
57
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
8+
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
69
ODEInterface = "54ca160b-1b9f-5127-a996-1867f4bc2a2c"
710
ODEInterfaceDiffEq = "09606e27-ecf5-54fc-bb29-004bd9f985bf"
811
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
@@ -12,9 +15,12 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1215
SciMLBenchmarks = "31c91b34-3c75-11e9-0341-95557aab0344"
1316
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1417
Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
18+
TerminalLoggers = "5d786b92-1e48-4d6f-9151-6b4477ca9bed"
1519

1620
[compat]
21+
BenchmarkTools = "1"
1722
DiffEqDevTools = "2.30"
23+
DifferentialEquations = "7"
1824
FFTW = "1"
1925
LSODA = "0.7"
2026
ODEInterface = "0.5"
@@ -25,3 +31,4 @@ Plots = "1.4"
2531
SciMLBenchmarks = "0.1"
2632
StaticArrays = "1"
2733
Sundials = "4.2"
34+
TerminalLoggers = "0.1"

0 commit comments

Comments
 (0)