From 449c93817a8bbf294d2280193d3c753ca9ba6583 Mon Sep 17 00:00:00 2001 From: Nuwan Yapa Date: Thu, 27 Jun 2024 18:04:56 -0400 Subject: [PATCH] Refactor 3-body V matrix --- 3body_resonance.jl | 19 ++++--------------- 3body_resonance_EC.jl | 1 - XZ_technique.jl | 2 +- berggren.jl | 4 ++-- berggren_3body.jl | 18 +++--------------- ho_basis.jl | 36 ++++++++++++++++++++++++++++++++++-- ho_basis_2body.jl | 4 ++-- ho_basis_3body.jl | 8 ++++---- ho_basis_benchmark.jl | 4 ++-- ho_basis_test.jl | 4 ++-- 10 files changed, 54 insertions(+), 46 deletions(-) diff --git a/3body_resonance.jl b/3body_resonance.jl index 97453ec..d7f73f1 100644 --- a/3body_resonance.jl +++ b/3body_resonance.jl @@ -28,26 +28,15 @@ println("Basis size = ", length(Es)) println("Constructing KE matrices") -@time "T1" T1 = sp_T_matrix(n1s, l1s; mask=mask1, μω_gen=μ1ω1, μ=μ1) -@time "T2" T2 = sp_T_matrix(n2s, l2s; mask=mask2, μω_gen=μ2ω2, μ=μ2) +@time "T1" T1 = get_sp_T_matrix(n1s, l1s; mask=mask1, μω_gen=μ1ω1, μ=μ1) +@time "T2" T2 = get_sp_T_matrix(n2s, l2s; mask=mask2, μω_gen=μ2ω2, μ=μ2) println("Constructing PE matrices") -atol = 10^-6 -maxevals = 10^5 -V1_elem(l, n1, n2) = V_numerical(V_of_r, l, n1, n2; μω_gen=μ1ω1, atol=atol, maxevals=maxevals) -V_relative_elem(l, n1, n2) = V_numerical(V_of_r, l, n1, n2; μω_gen=μω_global, atol=atol, maxevals=maxevals) -V1_cache = LRU{Tuple{UInt8, UInt8, UInt8}, ComplexF64}(maxsize=(1+l_max)*(1+n_max)^2) -V_relative_cache = LRU{Tuple{UInt8, UInt8, UInt8}, ComplexF64}(maxsize=(1+l_max)*(1+n_max)^2) - -@time "V1" V1 = sp_V_matrix(V1_elem, n1s, l1s; mask=mask1, dtype=ComplexF64, cache=V1_cache) -@time "V relative" V_relative = sp_V_matrix(V_relative_elem, n1s, l1s; mask=mask1, dtype=ComplexF64, cache=V_relative_cache) + sp_V_matrix(V_relative_elem, n2s, l2s; mask=mask2, dtype=ComplexF64, cache=V_relative_cache) -@time "Moshinsky brackets" U = Moshinsky_transform(Es, n1s, l1s, n2s, l2s, Λ) -@time "V2" V2 = U' * V_relative * U +@time "V" V = get_jacobi_V_matrix(V_of_r, E_max, Λ, μ1ω1, μω_global) println("Calculating spectrum") - -@time "H" H = T1 + T2 + V1 + V2 +@time "H" H = T1 + T2 + V @time "Eigenvalues" evals, _ = eigs(H, nev=5, ncv=50, which=:LI, maxiter=5000, tol=1e-5, ritzvec=false, check=1) display(evals) \ No newline at end of file diff --git a/3body_resonance_EC.jl b/3body_resonance_EC.jl index 2c9e9b2..1d7aa8e 100644 --- a/3body_resonance_EC.jl +++ b/3body_resonance_EC.jl @@ -7,7 +7,6 @@ training_c = 2.0 : -0.2 : 1.2 extrapolating_c = 1.05 .- [0.0 : 0.1 : 0.4; 0.45 : 0.05 : 0.60] @time "H0" H0 = T1 + T2 -@time "V" V = V1 + V2 # free memory Es = n1s = l1s = n2s = l2s = mask1 = mask2 = T1 = T2 = V1_cache = V_relative_cache = V1 = V_relative = U = V2 = nothing diff --git a/XZ_technique.jl b/XZ_technique.jl index f4a13f8..c739da6 100644 --- a/XZ_technique.jl +++ b/XZ_technique.jl @@ -14,7 +14,7 @@ n_max = 15 ns = collect(0:n_max) ls = fill(l, n_max + 1) -T = sp_T_matrix(ns, ls; μω_gen=μω_gen, μ=μ) +T = get_sp_T_matrix(ns, ls; μω_gen=μω_gen, μ=μ) V = V1 .* V_Gaussian.(R1, l, ns, transpose(ns); μω_gen=μω_gen) + V2 .* V_Gaussian.(R2, l, ns, transpose(ns); μω_gen=μω_gen) n_EC = 8 diff --git a/berggren.jl b/berggren.jl index d41ee58..136ed95 100644 --- a/berggren.jl +++ b/berggren.jl @@ -2,8 +2,8 @@ using SparseArrays include("ho_basis.jl") "Basis transformation from HO to momentum space" -function get_W_matrix(basis_p, basis_HO, μ1ω1, μ2ω2=μ1ω1; weights=true) - Es, n1s, l1s, n2s, l2s = basis_HO +function get_W_matrix(basis_p, E_max, Λ, μ1ω1, μ2ω2=μ1ω1; weights=true) + Es, n1s, l1s, n2s, l2s = get_2p_basis(E_max, Λ) W = zeros(ComplexF64, length(basis_p), length(Es)) Threads.@threads for idx in CartesianIndices(W) (i1, i2) = Tuple(idx) diff --git a/berggren_3body.jl b/berggren_3body.jl index 010c5a4..ec115e0 100644 --- a/berggren_3body.jl +++ b/berggren_3body.jl @@ -43,25 +43,13 @@ end E_max = 30 μω_global = 0.5 - μ1ω1 = μω_global * 1/2 μ2ω2 = μω_global * 2 -basis_HO = get_2p_basis(E_max, Λ) -Es, n1s, l1s, n2s, l2s = basis_HO -l_max = max(maximum(l1s), maximum(l2s)) -n_max = max(maximum(n1s), maximum(n2s)) -mask1 = (n2s .== n2s') .&& (l2s .== l2s') -mask2 = (n1s .== n1s') .&& (l1s .== l1s') +@time "V2_HO" V2_HO = get_jacobi_V2_matrix(V_of_r, E_max, Λ, μω_global) -V_relative_elem(l, n1, n2) = V_numerical(V_of_r, l, n1, n2; μω_gen=μω_global, atol=atol, maxevals=maxevals) -V_relative_cache = LRU{Tuple{UInt8, UInt8, UInt8}, Float64}(maxsize=(1+l_max)*(1+n_max)^2) -@time "V relative" V_relative = sp_V_matrix(V_relative_elem, n1s, l1s; mask=mask1, dtype=Float64, cache=V_relative_cache) + sp_V_matrix(V_relative_elem, n2s, l2s; mask=mask2, dtype=Float64, cache=V_relative_cache) -@time "Moshinsky brackets" U = Moshinsky_transform(Es, n1s, l1s, n2s, l2s, Λ) -@time "V2_HO" V2_HO = U' * V_relative * U - -@time "W_right" W_right = get_W_matrix(basis, basis_HO, μ1ω1, μ2ω2; weights=true) -@time "W_left" W_left = get_W_matrix(basis, basis_HO, μ1ω1, μ2ω2; weights=false) +@time "W_right" W_right = get_W_matrix(basis, E_max, Λ, μ1ω1, μ2ω2; weights=true) +@time "W_left" W_left = get_W_matrix(basis, E_max, Λ, μ1ω1, μ2ω2; weights=false) @time "V2" V2 = W_left * V2_HO * transpose(W_right) @time "H" H = T + V1 + V2 diff --git a/ho_basis.jl b/ho_basis.jl index 0ec0bb4..b7826b3 100644 --- a/ho_basis.jl +++ b/ho_basis.jl @@ -56,7 +56,7 @@ function get_2p_basis(E_max, Λ=-1) return (Es, n1s, l1s, n2s, l2s) end -function sp_T_matrix(ns, ls; mask=trues(length(ns),length(ns)), μω_gen=1.0, μ=1.0) +function get_sp_T_matrix(ns, ls; mask=trues(length(ns),length(ns)), μω_gen=1.0, μ=1.0) mat = spzeros(length(ns), length(ns)) for idx in CartesianIndices(mat) if !mask[idx]; continue; end @@ -73,7 +73,7 @@ function sp_T_matrix(ns, ls; mask=trues(length(ns),length(ns)), μω_gen=1.0, μ return (μω_gen / μ) .* mat end -function sp_V_matrix(V_l, ns, ls; mask=trues(length(ns),length(ns)), dtype=Float64, cache=LRU{Tuple{UInt8, UInt8, UInt8}, dtype}(maxsize=(1+maximum(ns))^2)) +function get_sp_V_matrix(V_l, ns, ls; mask=trues(length(ns),length(ns)), dtype=Float64, cache=LRU{Tuple{UInt8, UInt8, UInt8}, dtype}(maxsize=(1+maximum(ns))^2)) mat = zeros(dtype, length(ns), length(ns)) Threads.@threads for idx in CartesianIndices(mat) if !mask[idx]; continue; end @@ -137,3 +137,35 @@ function V_numerical(V_of_r, l, n1, n2; μω_gen=1.0, atol=0, maxevals=10^7) (integral, _) = quadgk(integrand, 0, Inf; atol=atol, maxevals=maxevals) return integral end + +function get_jacobi_V_matrix(V_of_r, E_max, Λ, μ1ω1, μω_global; atol=10^-6, maxevals=10^5) + _, n1s, l1s, n2s, l2s = get_2p_basis(E_max, Λ) + l_max = max(maximum(l1s), maximum(l2s)) + n_max = max(maximum(n1s), maximum(n2s)) + mask1 = (n2s .== n2s') .&& (l2s .== l2s') + + V1_elem(l, n1, n2) = V_numerical(V_of_r, l, n1, n2; μω_gen=μ1ω1, atol=atol, maxevals=maxevals) + V1_cache = LRU{Tuple{UInt8, UInt8, UInt8}, ComplexF64}(maxsize=(1+l_max)*(1+n_max)^2) + V1 = get_sp_V_matrix(V1_elem, n1s, l1s; mask=mask1, dtype=ComplexF64, cache=V1_cache) + + V2 = get_jacobi_V2_matrix(V_of_r, E_max, Λ, μω_global; atol=atol, maxevals=maxevals) + + return V1 + V2 +end + +function get_jacobi_V2_matrix(V_of_r, E_max, Λ, μω_global; atol=10^-6, maxevals=10^5) + Es, n1s, l1s, n2s, l2s = get_2p_basis(E_max, Λ) + l_max = max(maximum(l1s), maximum(l2s)) + n_max = max(maximum(n1s), maximum(n2s)) + mask1 = (n2s .== n2s') .&& (l2s .== l2s') + mask2 = (n1s .== n1s') .&& (l1s .== l1s') + + V_relative_elem(l, n1, n2) = V_numerical(V_of_r, l, n1, n2; μω_gen=μω_global, atol=atol, maxevals=maxevals) + V_relative_cache = LRU{Tuple{UInt8, UInt8, UInt8}, ComplexF64}(maxsize=(1+l_max)*(1+n_max)^2) + + V_relative = get_sp_V_matrix(V_relative_elem, n1s, l1s; mask=mask1, dtype=ComplexF64, cache=V_relative_cache) + get_sp_V_matrix(V_relative_elem, n2s, l2s; mask=mask2, dtype=ComplexF64, cache=V_relative_cache) + U = Moshinsky_transform(Es, n1s, l1s, n2s, l2s, Λ) + V2 = U' * V_relative * U + + return V2 +end \ No newline at end of file diff --git a/ho_basis_2body.jl b/ho_basis_2body.jl index 0fb8677..f8e704f 100644 --- a/ho_basis_2body.jl +++ b/ho_basis_2body.jl @@ -17,11 +17,11 @@ Es, n1s, l1s = get_sp_basis(E_max) println("Basis size = ", length(Es)) println("Constructing KE matrices") -@time "T1" T1 = sp_T_matrix(n1s, l1s; μω_gen=μω_gen, μ=μ1) +@time "T1" T1 = get_sp_T_matrix(n1s, l1s; μω_gen=μω_gen, μ=μ1) println("Constructing PE matrices") V1_elem(l, n1, n2) = Va * V_Gaussian(Ra, l, n1, n2; μω_gen=μω_gen) -@time "V1" V1 = sp_V_matrix(V1_elem, n1s, l1s) +@time "V1" V1 = get_sp_V_matrix(V1_elem, n1s, l1s) println("Calculating spectrum") @time "H" H = T1 + V1 diff --git a/ho_basis_3body.jl b/ho_basis_3body.jl index 427cdcd..a026342 100644 --- a/ho_basis_3body.jl +++ b/ho_basis_3body.jl @@ -26,14 +26,14 @@ end println("Basis size = ", length(Es)) println("Constructing KE matrices") -@time "T1" T1 = sp_T_matrix(n1s, l1s; mask=mask1, μω_gen=μ1ω1, μ=μ1) -@time "T2" T2 = sp_T_matrix(n2s, l2s; mask=mask2, μω_gen=μ2ω2, μ=μ2) +@time "T1" T1 = get_sp_T_matrix(n1s, l1s; mask=mask1, μω_gen=μ1ω1, μ=μ1) +@time "T2" T2 = get_sp_T_matrix(n2s, l2s; mask=mask2, μω_gen=μ2ω2, μ=μ2) println("Constructing PE matrices") V1_elem(l, n1, n2) = Va * V_Gaussian(Ra, l, n1, n2; μω_gen=μ1ω1) V_relative_elem(l, n1, n2) = Va * V_Gaussian(Ra, l, n1, n2; μω_gen=μω_global) -@time "V1" V1 = sp_V_matrix(V1_elem, n1s, l1s; mask=mask1) -@time "V relative" V_relative = sp_V_matrix(V_relative_elem, n1s, l1s; mask=mask1) + sp_V_matrix(V_relative_elem, n2s, l2s; mask=mask2) +@time "V1" V1 = get_sp_V_matrix(V1_elem, n1s, l1s; mask=mask1) +@time "V relative" V_relative = get_sp_V_matrix(V_relative_elem, n1s, l1s; mask=mask1) + get_sp_V_matrix(V_relative_elem, n2s, l2s; mask=mask2) @time "Moshinsky brackets" U = Moshinsky_transform(Es, n1s, l1s, n2s, l2s, Λ) @time "V2" V2 = U' * V_relative * U diff --git a/ho_basis_benchmark.jl b/ho_basis_benchmark.jl index 15fad92..0af39b7 100644 --- a/ho_basis_benchmark.jl +++ b/ho_basis_benchmark.jl @@ -14,10 +14,10 @@ n_max = 15 ns = collect(0:n_max) ls = fill(l, n_max + 1) -T = sp_T_matrix(ns, ls; μω_gen=μω_gen, μ=μ) +T = get_sp_T_matrix(ns, ls; μω_gen=μω_gen, μ=μ) V_l(l, n1, n2) = V1 * V_Gaussian(R1, l, n1, n2; μω_gen=μω_gen) + V2 * V_Gaussian(R2, l, n1, n2; μω_gen=μω_gen) -V = sp_V_matrix(V_l, ns, ls; dtype=ComplexF64) +V = get_sp_V_matrix(V_l, ns, ls; dtype=ComplexF64) cs = range(1.25, 0.25, 10) diff --git a/ho_basis_test.jl b/ho_basis_test.jl index 6d26fb0..5d9e436 100644 --- a/ho_basis_test.jl +++ b/ho_basis_test.jl @@ -9,10 +9,10 @@ n_max = 20 ns = collect(0:n_max) ls = fill(l, n_max + 1) -T = sp_T_matrix(ns, ls) +T = get_sp_T_matrix(ns, ls) V_l(l, n1, n2) = V0 * V_Gaussian(R, l, n1, n2) -V = sp_V_matrix(V_l, ns, ls) +V = get_sp_V_matrix(V_l, ns, ls) H = T + V