diff --git a/calculations/3body_Berggren_B2R_EC.jl b/calculations/3body_Berggren_B2R_EC.jl index 5efc161..263130d 100644 --- a/calculations/3body_Berggren_B2R_EC.jl +++ b/calculations/3body_Berggren_B2R_EC.jl @@ -1,5 +1,23 @@ +include("../p_space.jl") include("../EC.jl") +Λ = 0 +m = 1.0 +V_of_r(r) = 2 * exp(-(r-3)^2 / (1.5)^2) + +vertices = [0, 2 - 0.2im, 3, 4] +subdivisions = [15, 10, 10] +jmax = 4 + +E_max = 40 +μω_global = 0.5 + +H0, weights = get_3b_H_matrix(jacobi, V_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m) + +# Vp = perturbation to make the state artificially bound +Vp_of_r(r) = -exp(-(r/3)^2) +Vp, _ = get_3b_H_matrix(jacobi, Vp_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m, false, true) + training_c = [2.6, 2.4, 2.2, 2.0, 1.8] extrapolating_c = 0.0 : 0.2 : 1.2 @@ -13,24 +31,6 @@ extrapolating_ref = [4.076662025307587-0.012709842443350328im, 1.7164583929199813-0.0005455212208182736im, 1.233088227541505-0.0003070320106485624im] -include("../p_space_3body_resonance.jl") -H0 = H - -# Vp = perturbation to make the state artificially bound -Vp_of_r(r) = -exp(-(r/3)^2) -Vp_l(j, k, kp) = Vl_mat_elem(Vp_of_r, j, k, kp; atol=atol, maxevals=maxevals, R_cutoff=R_cutoff) - -@time "Vp block diagonal part" begin - Vpb_blocks = [kron_sum(get_V_matrix((k, kp) -> Vp_l(j1, k, kp), ks, ws), spzeros(length(ks), length(ks))) for (j1, _) in js] - Vpb = blockdiag(sparse.(Vpb_blocks)...) -end - -@time "Vp2_HO" Vp2_HO = get_jacobi_V2_matrix(Vp_of_r, basis_ho, μω_global; atol=atol, maxevals=maxevals) -@time "Vp2" Vp2 = W_left * Vp2_HO * transpose(W_right) -@time "Vp" Vp = Vpb + Vp2 - -weights = repeat(kron(ws, ws), jmax + 1) - EC = affine_EC(H0, Vp, weights) train!(EC, training_c; ref_eval=training_ref, CAEC=true) extrapolate!(EC, extrapolating_c; ref_eval=extrapolating_ref) diff --git a/calculations/3body_Berggren_R2R_EC.jl b/calculations/3body_Berggren_R2R_EC.jl index 4c59beb..8ca45d3 100644 --- a/calculations/3body_Berggren_R2R_EC.jl +++ b/calculations/3body_Berggren_R2R_EC.jl @@ -1,5 +1,23 @@ +include("../p_space.jl") include("../EC.jl") +Λ = 0 +m = 1.0 +V_of_r(r) = 2 * exp(-(r-3)^2 / (1.5)^2) + +vertices = [0, 2 - 0.2im, 3, 4] +subdivisions = [15, 10, 10] +jmax = 4 + +E_max = 40 +μω_global = 0.5 + +H0, weights = get_3b_H_matrix(jacobi, V_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m) + +# Vp = perturbation to make the state artificially bound +Vp_of_r(r) = -exp(-(r/3)^2) +Vp, _ = get_3b_H_matrix(jacobi, Vp_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m, false, true) + training_c = [1.1, 0.9, 0.7, 0.5] extrapolating_c = 0.0 : 0.2 : 1.2 @@ -16,24 +34,6 @@ extrapolating_ref = [4.076662025307587-0.012709842443350328im, 1.7164583929199813-0.0005455212208182736im, 1.233088227541505-0.0003070320106485624im] -include("../p_space_3body_resonance.jl") -H0 = H - -# Vp = perturbation to make the state artificially bound -Vp_of_r(r) = -exp(-(r/3)^2) -Vp_l(j, k, kp) = Vl_mat_elem(Vp_of_r, j, k, kp; atol=atol, maxevals=maxevals, R_cutoff=R_cutoff) - -@time "Vp block diagonal part" begin - Vpb_blocks = [kron_sum(get_V_matrix((k, kp) -> Vp_l(j1, k, kp), ks, ws), spzeros(length(ks), length(ks))) for (j1, _) in js] - Vpb = blockdiag(sparse.(Vpb_blocks)...) -end - -@time "Vp2_HO" Vp2_HO = get_jacobi_V2_matrix(Vp_of_r, basis_ho, μω_global; atol=atol, maxevals=maxevals) -@time "Vp2" Vp2 = W_left * Vp2_HO * transpose(W_right) -@time "Vp" Vp = Vpb + Vp2 - -weights = repeat(kron(ws, ws), jmax + 1) - EC = affine_EC(H0, Vp, weights) train!(EC, training_c; ref_eval=training_ref, CAEC=false) extrapolate!(EC, extrapolating_c; ref_eval=extrapolating_ref) diff --git a/p_space.jl b/p_space.jl index 7671c43..0746f78 100644 --- a/p_space.jl +++ b/p_space.jl @@ -1,5 +1,6 @@ using LinearAlgebra using SpecialFunctions, FastGaussQuadrature, QuadGK +include("ho_basis.jl") function gausslegendre_shifted(a, b, n) scale = (b - a) / 2 @@ -59,3 +60,56 @@ function Vl_mat_elem(V_of_r, l, p, q; atol=0, maxevals=10^7, R_cutoff=Inf) (integral, _) = quadgk(integrand, 0, R_cutoff; atol=atol, maxevals=maxevals) return (2 / pi) * integral end + +"Return the Hamiltonian matrix (and the array of weights) for the given system." +function get_3b_H_matrix(coord_system::coordinate_system, V_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m=1.0, kinetic_part=true, potential_part=true; atol=10^-5, maxevals=10^5, R_cutoff=16, verbose=true) + if coord_system == jacobi + μ1ω1 = μω_global * 1/2 + μ2ω2 = μω_global * 2 + μ1 = m * 1/2 + μ2 = m * 2/3 + else + error("Only Jacobi coordinates are implemented") + end + + verbose && println("No of threads = ", Threads.nthreads()) + + V_l(j, k, kp) = Vl_mat_elem(V_of_r, j, k, kp; atol=atol, maxevals=maxevals, R_cutoff=R_cutoff) + + ks, ws = get_mesh(vertices, subdivisions) + weights = repeat(kron(ws, ws), jmax + 1) + block_size = length(ks) + tri((j1, j2)) = triangle_ineq(j1, j2, Λ) + js = collect(Iterators.filter(tri, iter_prod(0:jmax, 0:jmax))) + basis = iter_prod(js, zip(ks, ws), zip(ks, ws)) # basis = ((j1, j2), (k1, w1), (k2, w2)) + basis_size = length(js) * length(ks)^2 + @assert length(basis) == basis_size "Something wrong with the basis" + verbose && println("Basis size = $basis_size") + + out = spzeros(basis_size, basis_size) + + @time "Block diagonal part" begin + if kinetic_part & potential_part + Hb_blocks = [kron_sum(get_H_matrix((k, kp) -> V_l(j1, k, kp), ks, ws, μ1), get_T_matrix(ks, μ2)) for (j1, _) in js] + elseif kinetic_part + Hb_blocks = [kron_sum(get_T_matrix(ks, μ1), get_T_matrix(ks, μ2)) for _ in js] + elseif potential_part + Hb_blocks = [kron_sum(get_V_matrix((k, kp) -> V_l(j1, k, kp), ks, ws), spzeros(block_size, block_size)) for (j1, _) in js] + end + out += blockdiag(sparse.(Hb_blocks)...) + end + + if potential_part + basis_ho = ho_basis_2B(E_max, Λ) + verbose && println("HO basis size = ", basis_ho.dim) + + @time "V2_HO" V2_HO = get_jacobi_V2_matrix(V_of_r, basis_ho, μω_global) + + @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 "V2" out += W_left * V2_HO * transpose(W_right) + end + + return (out, weights) +end \ No newline at end of file diff --git a/p_space_3body.jl b/p_space_3body.jl index 760fcdc..0476e53 100644 --- a/p_space_3body.jl +++ b/p_space_3body.jl @@ -1,56 +1,18 @@ -using LinearAlgebra, SparseArrays, Arpack -include("common.jl") +using Arpack include("p_space.jl") -include("ho_basis.jl") - -println("No of threads = ", Threads.nthreads()) - -atol = 10^-5 -maxevals = 10^5 -R_cutoff = 16 Λ = 0 m = 1.0 -μ1 = m * 1/2 -μ2 = m * 2/3 - -Va = -2 -Ra = 2 -V_of_r(r) = Va * exp(-r^2 / Ra^2) -V_l(j, k, kp) = Vl_mat_elem(V_of_r, j, k, kp; atol=atol, maxevals=maxevals, R_cutoff=R_cutoff) +V_of_r(r) = -2 * exp(-r^2 / 4) vertices = [0, 0.5 - 0.3im, 1, 4] subdivisions = [10, 10, 10] -ks, ws = get_mesh(vertices, subdivisions) - jmax = 4 -tri((j1, j2)) = triangle_ineq(j1, j2, Λ) -js = collect(Iterators.filter(tri, iter_prod(0:jmax, 0:jmax))) - -basis = iter_prod(js, zip(ks, ws), zip(ks, ws)) # basis = ((j1, j2), (k1, w1), (k2, w2)) -basis_size = length(js) * length(ks)^2 -@assert length(basis) == basis_size "Something wrong with the basis" -println("Basis size = $basis_size") - -@time "Block diagonal part" begin - Hb_blocks = [kron_sum(get_H_matrix((k, kp) -> V_l(j1, k, kp), ks, ws, μ1), get_T_matrix(ks, μ2)) for (j1,_ ) in js] - Hb = blockdiag(sparse.(Hb_blocks)...) -end E_max = 30 μω_global = 0.5 -μ1ω1 = μω_global * 1/2 -μ2ω2 = μω_global * 2 -basis_ho = ho_basis_2B(E_max, Λ) - -@time "V2_HO" V2_HO = get_jacobi_V2_matrix(V_of_r, basis_ho, μω_global) - -@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 "V2" V2 = W_left * V2_HO * transpose(W_right) -@time "H" H = Hb + V2 +H, _ = get_3b_H_matrix(jacobi, V_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m) @time "Eigenvalues" evals, _ = eigs(H, nev=3, ncv=24, which=:SR, maxiter=5000, tol=1e-5, ritzvec=false, check=1) display(evals) diff --git a/p_space_3body_resonance.jl b/p_space_3body_resonance.jl index 1a34b92..c3f9ec7 100644 --- a/p_space_3body_resonance.jl +++ b/p_space_3body_resonance.jl @@ -1,55 +1,20 @@ -using LinearAlgebra, SparseArrays, Arpack -include("common.jl") +using Arpack include("p_space.jl") -include("ho_basis.jl") - -println("No of threads = ", Threads.nthreads()) -atol = 10^-5 -maxevals = 10^5 -R_cutoff = 16 - -Λ = 0 -m = 1.0 -μ1 = m * 1/2 -μ2 = m * 2/3 target = 4.0766890719636875 - 0.012758927741074495im +Λ = 0 +m = 1.0 V_of_r(r) = 2 * exp(-(r-3)^2 / (1.5)^2) -V_l(j, k, kp) = Vl_mat_elem(V_of_r, j, k, kp; atol=atol, maxevals=maxevals, R_cutoff=R_cutoff) vertices = [0, 2 - 0.2im, 3, 4] subdivisions = [15, 10, 10] -ks, ws = get_mesh(vertices, subdivisions) - jmax = 4 -tri((j1, j2)) = triangle_ineq(j1, j2, Λ) -js = collect(Iterators.filter(tri, iter_prod(0:jmax, 0:jmax))) - -basis = iter_prod(js, zip(ks, ws), zip(ks, ws)) # basis = ((j1, j2), (k1, w1), (k2, w2)) -basis_size = length(js) * length(ks)^2 -@assert length(basis) == basis_size "Something wrong with the basis" -println("Basis size = $basis_size") - -@time "Block diagonal part" begin - Hb_blocks = [kron_sum(get_H_matrix((k, kp) -> V_l(j1, k, kp), ks, ws, μ1), get_T_matrix(ks, μ2)) for (j1,_ ) in js] - Hb = blockdiag(sparse.(Hb_blocks)...) -end E_max = 40 μω_global = 0.5 -μ1ω1 = μω_global * 1/2 -μ2ω2 = μω_global * 2 -basis_ho = ho_basis_2B(E_max, Λ) - -@time "V2_HO" V2_HO = get_jacobi_V2_matrix(V_of_r, basis_ho, μω_global; atol=atol, maxevals=maxevals) - -@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 "V2" V2 = W_left * V2_HO * transpose(W_right) -@time "H" H = Hb + V2 +H, _ = get_3b_H_matrix(jacobi, V_of_r, vertices, subdivisions, jmax, μω_global, E_max, Λ, m) @time "Eigenvalues" evals, _ = eigs(H, sigma=target, maxiter=5000, tol=1e-5, ritzvec=false, check=1) display(evals)