Compare commits

..

33 Commits
irrep ... main

Author SHA1 Message Date
Nuwan Yapa 7545ebf5b5 Update README.md 2026-02-18 01:09:14 +00:00
Nuwan Yapa 840efad148 First version of README.md 2026-02-14 01:02:21 +00:00
Nuwan Yapa cf9de201a9 Julia package dependencies 2026-02-13 23:53:42 +00:00
Nuwan Yapa 37acda8fac Ignore VS Code configuration files 2026-02-13 15:32:27 -05:00
Nuwan Yapa 45b43728fb R2R EC implemented 2024-07-12 18:09:36 -04:00
Nuwan Yapa 850447a507 Merge remote-tracking branch 'origin/calculations' 2024-07-12 14:52:13 -04:00
Nuwan Yapa df0b5820ea Move calculations into folder 2024-07-12 14:48:43 -04:00
Nuwan Yapa 1f4a648d52 Simple 3-body bound system 2024-04-09 18:07:17 -04:00
Nuwan Yapa 8ee4057f7e .gitignore HPC stuff 2024-02-26 10:26:48 -05:00
ysyapa d3a25b2ccf New ComplexScaling-FV calculation 2023-10-21 14:57:45 -04:00
ysyapa 922807eca1 n_imag=1 2023-09-05 16:18:19 +00:00
ysyapa 7cc20a9c27 Fixed GPU related bug 2023-08-27 23:02:51 -04:00
ysyapa 547be9fa98 Changed parameters 2023-08-25 22:09:41 +00:00
ysyapa 7a74745f7e Merge branch 'master' into calculations 2023-08-25 21:21:32 +00:00
ysyapa b21242ad49 Double krylovdim again 2023-08-25 21:20:14 +00:00
ysyapa 3d29c323d0 New calculation for paper 2023-08-25 21:03:25 +00:00
ysyapa 7fdb5947a1 Merge branch 'master' into calculations 2023-08-25 21:02:53 +00:00
Nuwan Yapa 0bcb7b3d16 Ignore calculation outputs 2023-08-14 10:46:22 -04:00
Nuwan Yapa 3f0d7566fa Merge branch 'master' into calculations 2023-08-10 05:45:10 -04:00
Nuwan Yapa 1195e63f51 Merge branch 'master' into calculations 2023-08-10 05:37:12 -04:00
ysyapa b05fb757b1 Merge branch 'master' into calculations 2023-08-10 09:11:19 +00:00
ysyapa 3b6a57c512 New parameters 2023-08-10 09:09:56 +00:00
ysyapa 490e94262b Increase N 2023-08-09 18:22:05 +00:00
ysyapa e6f32295f5 Export .dat file 2023-08-09 18:19:55 +00:00
ysyapa cbd0460600 Chose potential for new paper 2023-08-07 19:46:19 +00:00
ysyapa 911143a9ca Minor fix 2023-05-24 00:46:21 -04:00
ysyapa 8ce0f749b7 Use CPU 2023-05-23 19:13:58 +00:00
ysyapa 700d2b4308 Seperate .jl files instead of notebook 2023-05-23 19:11:36 +00:00
ysyapa d3726c725b Adopt to new interface 2023-05-23 19:08:09 +00:00
ysyapa c831c52f78 Merge branch 'master' into calculations 2023-05-23 18:43:54 +00:00
ysyapa 77eea9319c Not worrying about memory leak 2023-04-20 16:28:08 -04:00
ysyapa 7879f047f2 Merge branch 'master' into calculations 2023-04-20 16:27:33 -04:00
ysyapa 0c3fb156ae 3-body resonance calculation 2023-04-09 20:08:00 -04:00
16 changed files with 260 additions and 186 deletions

6
.gitignore vendored
View File

@ -1,3 +1,9 @@
# VSCode
.vscode/
# HPC scripts and logs
hpc/
# Calculation outputs # Calculation outputs
*.dat *.dat
*.csv *.csv

View File

@ -9,9 +9,6 @@ struct Hamiltonian{T}
K_partial::Matrix{Complex{T}} K_partial::Matrix{Complex{T}}
K_diag::Union{CuTensor{Complex{T}},Nothing} K_diag::Union{CuTensor{Complex{T}},Nothing}
K_mixed::Union{CuTensor{Complex{T}},Nothing} K_mixed::Union{CuTensor{Complex{T}},Nothing}
K_partial_1::Union{Tuple,Nothing}
K_partial_2::Union{Tuple,Nothing}
K_partial_c::Union{Tuple,Nothing}
Vs::Union{Array{Complex{T}},CuArray{Complex{T}}} Vs::Union{Array{Complex{T}},CuArray{Complex{T}}}
hermitian::Bool hermitian::Bool
mode::Hamiltonian_backend mode::Hamiltonian_backend
@ -19,27 +16,25 @@ struct Hamiltonian{T}
function Hamiltonian{T}(s::system{T}, V_twobody::Function, ϕ::Real, n_image::Int, mode::Hamiltonian_backend) where {T<:Float} function Hamiltonian{T}(s::system{T}, V_twobody::Function, ϕ::Real, n_image::Int, mode::Hamiltonian_backend) where {T<:Float}
@assert mode != gpu_cutensor || CUDA.functional() && CUDA.has_cuda() && CUDA.has_cuda_gpu() "CUDA not available" @assert mode != gpu_cutensor || CUDA.functional() && CUDA.has_cuda() && CUDA.has_cuda_gpu() "CUDA not available"
k = -s.N÷2:s.N÷2-1 k = -s.N÷2:s.N÷2-1
Vs = calculate_Vs(s, V_twobody, convert(T, ϕ), n_image)
hermitian = ϕ == 0.0 hermitian = ϕ == 0.0
K_partial = (exp(-im * convert(T, ϕ)) * im / sqrt(2 * s.μ)) .* ∂_1DOF.(Ref(s), k, k') K_partial = (exp(-im * convert(T, ϕ)) * im / sqrt(2 * s.μ)) .* ∂_1DOF.(Ref(s), k, k')
K_partial_1, K_partial_2, K_partial_c = sym_reduce(s, K_partial) K_diag = nothing
Vs = calculate_Vs(s, V_twobody, convert(T, ϕ), n_image) K_mixed = nothing
if mode == gpu_cutensor if mode == gpu_cutensor
K_diag = CuTensor(CuArray(K_partial * K_partial), ['a', 'A']) K_diag = CuTensor(CuArray(K_partial * K_partial), ['a', 'A'])
K_mixed = CuTensor(CuArray(K_partial), ['a', 'A']) * CuTensor(CuArray(K_partial), ['b', 'B']) K_mixed = CuTensor(CuArray(K_partial), ['a', 'A']) * CuTensor(CuArray(K_partial), ['b', 'B'])
Vs = CuArray(Vs) Vs = CuArray(Vs)
else
K_diag = nothing
K_mixed = nothing
end end
return new{T}(s, K_partial, K_diag, K_mixed, K_partial_1, K_partial_2, K_partial_c, Vs, hermitian, mode) return new{T}(s, K_partial, K_diag, K_mixed, Vs, hermitian, mode)
end end
end end
Base.size(H::Hamiltonian, i::Int)::Int = (i == 1 || i == 2) ? H.s.N^(H.s.d * (H.s.n - 2)) * length(H.s.unique_i) : throw(ArgumentError("Hamiltonian only has 2 dimesions")) Base.size(H::Hamiltonian, i::Int)::Int = (i == 1 || i == 2) ? H.s.N^(H.s.d * (H.s.n - 1)) : throw(ArgumentError("Hamiltonian only has 2 dimesions"))
Base.size(H::Hamiltonian)::Dims{2} = (size(H, 1), size(H, 2)) Base.size(H::Hamiltonian)::Dims{2} = (size(H, 1), size(H, 2))
"Dimensions of a vector to which 'H' can be applied" "Dimensions of a vector to which 'H' can be applied"
vectorDims(H::Hamiltonian)::Dims = tuple(length(H.s.unique_i), fill(H.s.N, H.s.d * (H.s.n - 2))...) vectorDims(H::Hamiltonian)::Dims = tuple(fill(H.s.N, H.s.d * (H.s.n - 1))...)
"Apply 'H' on 'v' and store the result in 'out' using the 'cpu_tensor' backend" "Apply 'H' on 'v' and store the result in 'out' using the 'cpu_tensor' backend"
function LinearAlgebra.mul!(out::Array{Complex{T}}, H::Hamiltonian{T}, v::Array{Complex{T}})::Array{Complex{T}} where {T<:Float} function LinearAlgebra.mul!(out::Array{Complex{T}}, H::Hamiltonian{T}, v::Array{Complex{T}})::Array{Complex{T}} where {T<:Float}
@ -47,9 +42,10 @@ function LinearAlgebra.mul!(out::Array{Complex{T}}, H::Hamiltonian{T}, v::Array{
# apply V operator # apply V operator
@. out = H.Vs * v @. out = H.Vs * v
# apply K opereator # apply K opereator
nconList_v_template = -collect(1:(H.s.d * (H.s.n - 2) + 1)) coords = H.s.n - 1
nconList_v_template = -collect(1:H.s.d*(coords))
for dim = 1:H.s.d for dim = 1:H.s.d
for coord1 = 1:(H.s.n - 1) for coord1 = 1:coords
for coord2 = 1:coord1 for coord2 = 1:coord1
i1 = which_index(H.s, dim, coord1) i1 = which_index(H.s, dim, coord1)
i2 = which_index(H.s, dim, coord2) i2 = which_index(H.s, dim, coord2)
@ -62,17 +58,7 @@ function LinearAlgebra.mul!(out::Array{Complex{T}}, H::Hamiltonian{T}, v::Array{
nconList_v[i1] = 1 nconList_v[i1] = 1
end end
nconList_v[i2] = 2 nconList_v[i2] = 2
v_new = @ncon((H.K_partial, H.K_partial, v), (nconList_1, nconList_2, nconList_v))
if coord1 == 1 && coord2 == 1
tensor1 = H.K_partial_1[dim]
tensor2 = H.K_partial_2[dim]
else
tensor1 = coord1 == 1 ? H.K_partial_c[dim] : H.K_partial
tensor2 = coord2 == 1 ? H.K_partial_c[dim] : H.K_partial
end
v_new = @ncon((tensor1, tensor2, v), (nconList_1, nconList_2, nconList_v))
out = axpy!(1, v_new, out) out = axpy!(1, v_new, out)
end end
end end
@ -82,8 +68,8 @@ end
"cuTENSOR contraction and accumulation (C = A * B + C)" "cuTENSOR contraction and accumulation (C = A * B + C)"
function contract_accumulate!(C::CuTensor, A::CuTensor, B::CuTensor)::CuTensor function contract_accumulate!(C::CuTensor, A::CuTensor, B::CuTensor)::CuTensor
CUTENSOR.contraction!(one(eltype(C)), A.data, A.inds, CUTENSOR.CUTENSOR_OP_IDENTITY, B.data, B.inds, CUTENSOR.CUTENSOR_OP_IDENTITY, cuTENSOR.contraction!(one(eltype(C)), A.data, A.inds, cuTENSOR.CUTENSOR_OP_IDENTITY, B.data, B.inds, cuTENSOR.CUTENSOR_OP_IDENTITY,
one(eltype(C)), C.data, C.inds, CUTENSOR.CUTENSOR_OP_IDENTITY, CUTENSOR.CUTENSOR_OP_IDENTITY) one(eltype(C)), C.data, C.inds, cuTENSOR.CUTENSOR_OP_IDENTITY, cuTENSOR.CUTENSOR_OP_IDENTITY)
return C return C
end end
@ -148,8 +134,7 @@ function eig(H::Hamiltonian{T}, levels::Int; resonances = !H.hermitian)::Tuple{V
x₀ = CUDA.rand(Complex{T}, vectorDims(H)...) x₀ = CUDA.rand(Complex{T}, vectorDims(H)...)
synchronize() synchronize()
end end
KrylovKit_hermitian = H.hermitian && H.s.sym == all evals, evecs, info = eigsolve(H, x₀, levels, resonances ? :LI : :SR; ishermitian = H.hermitian, tol = tolerance, krylovdim = levels * 8)
evals, evecs, info = eigsolve(H, x₀, levels, resonances ? :LI : :SR; ishermitian = KrylovKit_hermitian, tol = tolerance, krylovdim = levels * 4)
info.converged < levels && throw(error("Not enough convergence")) info.converged < levels && throw(error("Not enough convergence"))
if H.hermitian evals = real.(evals) end if H.hermitian evals = real.(evals) end
if H.mode == gpu_cutensor # to avoid possible GPU memory leak if H.mode == gpu_cutensor # to avoid possible GPU memory leak

2
LocalPreferences.toml Normal file
View File

@ -0,0 +1,2 @@
[TensorOperations]
precompile_workload = true

7
Project.toml Normal file
View File

@ -0,0 +1,7 @@
[deps]
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77"
NVTX = "5da4648a-3479-48b8-97b9-01cb529c0a1f"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
cuTENSOR = "011b41b2-24ef-40a8-b3eb-fa098493e9e1"

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# DVR-jl
Solves the quantum $n$-body problem in finite volume (lattice) with periodic boundary conditions. Uses discrete variable representation (DVR) with optional support for complex scaling to study resonances. All details can be found in [H. Yu, N. Yapa, and S. König, Complex scaling in finite volume, Phys. Rev. C 109, 014316 (2024)](https://doi.org/10.1103/PhysRevC.109.014316).
Written in Julia with optional CUDA GPU acceleration (experimental).
## Installation
Make sure you have Julia installed. Required packages can be installed with a single command:
```bash
julia --project=. -e 'import Pkg; Pkg.instantiate()'
```
## Usage
See `calculations/3b_bound.jl` for an example on a 3-body bound state.
See `calculations/3b_res_from_paper.jl` for an example of a 3-body resonance via complex scaling.
## Planned features
- [ ] Spin and isospin degrees of freedom for nuclear calculations
- [ ] Multi-node HPC support
- [ ] Parity and cubic symmetries ($S_4$)
## Acknowledgments
The author gratefully acknowledges the guidance from Sebastian König.

19
calculations/3b_bound.jl Normal file
View File

@ -0,0 +1,19 @@
include("../Hamiltonian.jl")
mode = cpu_tensor
T = Float32
V_gauss(r2) = -2 * exp(-r2 / 4)
d = 3
n = 3
N = 20
L = 15
n_imag = 1
ϕ = 0
s = system{T}(d, n, N, L)
H = Hamiltonian{T}(s, V_gauss, ϕ, n_imag, mode)
@time evals, _, info = eig(H, 5)
print(info.numops, " operations")
display(evals)

View File

@ -0,0 +1,36 @@
# 10.1007/s00601-020-01550-8
# Fig. 7
# E_R = 4.18(8)
#./En.run -d 3 -n 3 -N 16 -c pot=v_shifted_gauss,v0=2.0,r=1.5,a=3.0 -c n_eig=20 -c which=li -c tol=1e-6 -L 16 -c phi=0.3 -v
include("../Hamiltonian.jl")
mode = cpu_tensor
T = Float32 # single-precision mode
using Plots
V_gauss(r2) =
2 * exp(-((sqrt(r2) - 3) / 1.5) ^ 2)
d = 3
n = 3
N = 16
L = 16
n_imag = 0
for ϕ::T in 0.2:0.05:0.4
s = system{T}(d, n, N, L)
H = Hamiltonian{T}(s, V_gauss, ϕ, n_imag, mode)
@time evals, _, info = eig(H, 20)
print(info.numops, " operations")
display(evals)
scatter(real.(evals), imag.(evals); legend=false)
xlabel!("Re E")
ylabel!("Im E")
xlims!(0, 6)
ylims!(-0.6, 0)
savefig("temp/phi$(Int(round(ϕ * 100))).png")
end

View File

@ -0,0 +1,24 @@
include("../Hamiltonian.jl")
mode = cpu_tensor
T = Float32 # single-precision mode
V_gauss(r2) =
-10 * exp(-(sqrt(r2)) ^ 2)
d = 3
n = 2
N = 96
ϕ = pi/6
n_imag = 1
open("ComplexScaling-FV-P-res.dat", "w") do f
for L = range(20, 35, length=16)
println("Calculating L=", L)
s = system{T}(d, n, N, L)
H = Hamiltonian{T}(s, V_gauss, ϕ, n_imag, mode)
@time evals, _, info = eig(H, 40)
dataline = vcat([L], hcat(real.(evals), imag.(evals))'[:])
println(f, join(dataline, '\t'))
end
end

View File

@ -0,0 +1,24 @@
include("../Hamiltonian.jl")
mode = cpu_tensor
T = Float32 # single-precision mode
V_gauss(r2) =
-10 * exp(-(sqrt(r2)) ^ 2)
d = 3
n = 2
N = 30
L = 6
n_imag = 1
open("ComplexScaling-FV-S-bound-phi.dat", "w") do f
for ϕ = range(0.0, 0.5, length=11)
println("Calculating ϕ=", ϕ)
s = system{T}(d, n, N, L)
H = Hamiltonian{T}(s, V_gauss, ϕ, n_imag, mode)
@time evals, _, info = eig(H, 10, resonances = false)
dataline = vcat([ϕ], hcat(real.(evals), imag.(evals))'[:])
println(f, join(dataline, '\t'))
end
end

View File

@ -0,0 +1,24 @@
include("../Hamiltonian.jl")
mode = cpu_tensor
T = Float32 # single-precision mode
V_gauss(r2) =
2 * exp(- ((sqrt(r2)-3)/1.5) ^ 2)
d = 3
n = 2
N = 96
L = 30
n_imag = 1
open("ComplexScaling-FV-S-res-phi.dat", "w") do f
for ϕ = range(0.1, 0.6, length=26)
println("Calculating ϕ=", ϕ)
s = system{T}(d, n, N, L)
H = Hamiltonian{T}(s, V_gauss, ϕ, n_imag, mode)
@time evals, _, info = eig(H, 40, resonances = true)
dataline = vcat([ϕ], hcat(real.(evals), imag.(evals))'[:])
println(f, join(dataline, '\t'))
end
end

67
calculations/EC-R2R-S.jl Normal file
View File

@ -0,0 +1,67 @@
using Plots, Arpack
include("../helper.jl")
include("../Hamiltonian.jl")
mode = cpu_tensor
T = Float32 # single-precision mode
V_r2(c) = r2 -> c * (-5 * exp(-r2/3) + 2 * exp(-r2/10))
d = 3
n = 2
N = 48
L = 30
ϕ = pi/6
n_imag = 1
s = system{T}(d, n, N, L)
train_cs = range(0.78, 0.45, length=5)
train_ref = reverse([0.05387926313545913-0.008900278182520881im,
0.11254295298924327-0.020515067379548786im,
0.16060154707503538-0.03716539208626717im,
0.19741353362674618-0.05994519982799412im,
0.2219100763497223-0.08959449893439568im])
extrapolate_cs = range(0.38, 0.22, length=5)
extrapolate_ref = reverse([0.23165109150003316-0.12052751440975719im,
0.23190549514995962-0.1406687118589838im,
0.22763660218046278-0.1626190970863793im,
0.21807104244164865-0.18635600686249373im,
0.2020979906072586-0.21180157628258728im])
training_E = ComplexF64[]
training_vec = Array[]
exact_E = ComplexF64[]
extrapolated_E = ComplexF64[]
for c in train_cs
println("Training c=", c)
H = Hamiltonian{T}(s, V_r2(c), ϕ, n_imag, mode)
@time evals, evecs, info = eig(H, 20, resonances = true)
i = nearestIndex(evals, pop!(train_ref))
push!(training_E, evals[i])
push!(training_vec, evecs[i])
end
N_EC = [sum(x .* y) for (x, y) in Iterators.product(training_vec, training_vec)]
for c in extrapolate_cs
println("Extrapolating c=", c)
H = Hamiltonian{T}(s, V_r2(c), ϕ, n_imag, mode)
@time evals, _, info = eig(H, 40, resonances = true)
nearestE = nearest(evals, pop!(extrapolate_ref))
push!(exact_E, nearestE)
# EC extrapolation
H_training_vec = H.(training_vec)
H_EC = [sum(x .* y) for (x, y) in Iterators.product(training_vec, H_training_vec)]
evals = eigvals(H_EC, N_EC)
push!(extrapolated_E, nearestE)
end
scatter(real.(training_E), imag.(training_E), label="training")
scatter!(real.(exact_E), imag.(exact_E), label="exact")
scatter!(real.(extrapolated_E), imag.(extrapolated_E), label="extrapolated")
savefig("temp/EC-R2R-S.pdf")

View File

@ -1,7 +1,4 @@
include("irrep.jl")
Float = Union{Float32,Float64} Float = Union{Float32,Float64}
@enum rep all A1
"A few-body system defined by its physical parameters" "A few-body system defined by its physical parameters"
struct system{T} struct system{T}
@ -11,23 +8,7 @@ struct system{T}
L::T L::T
μ::T μ::T
sym::rep system{T}(d::Int, n::Int, N::Int, L::Real, μ::Real=0.5) where {T<:Float} = new{T}(d, n, N, convert(T, L), convert(T, μ))
unique_i::Array{Int}
unique_point::Array{Int}
multiplicity::Array{Int}
labels::Array{Int}
function system{T}(d::Int, n::Int, N::Int, L::Real, μ::Real=0.5, sym::rep=all) where {T<:Float}
@assert d == 3 "Only supports 3D"
if sym == all
unique_i, unique_point, multiplicity, labels = calculate_all_data(N)
elseif sym == A1
unique_i, unique_point, multiplicity, labels = calculate_A1_data(N)
else
throw(ArgumentError("Symmetry not yet implemented"))
end
return new{T}(d, n, N, convert(T, L), convert(T, μ), sym, unique_i, unique_point, multiplicity, labels)
end
end end
norm_square(x::Array{Int})::Int = sum(x .* x) norm_square(x::Array{Int})::Int = sum(x .* x)
@ -42,27 +23,18 @@ function ∂_1DOF(s::system{T}, k::Int, l::Int)::Complex{T} where {T<:Float}
end end
"Which index (dimension of the multidimensional array) corresponds to spatial dimension 'dim' and particle 'p'?" "Which index (dimension of the multidimensional array) corresponds to spatial dimension 'dim' and particle 'p'?"
which_index(s::system, dim::Int, p::Int)::Int = p == 1 ? 1 : (dim - 1) * (s.n - 2) + p which_index(s::system, dim::Int, p::Int)::Int = (dim - 1) * (s.n - 1) + p
"Δk (distance in terms of lattice paramter) between two particles along the given dimension"
function get_k(s::system, i::CartesianIndex, dim::Int, p::Int)::Int
if p == 1
s.unique_point[i[1], dim]
else
return i[which_index(s, dim, p)] - s.N ÷ 2 - 1
end
end
"Δk (distance in terms of lattice paramter) between two particles along the given dimension" "Δk (distance in terms of lattice paramter) between two particles along the given dimension"
function get_Δk(s::system, i::CartesianIndex, dim::Int, p1::Int, p2::Int)::Int function get_Δk(s::system, i::CartesianIndex, dim::Int, p1::Int, p2::Int)::Int
if p1 == p2 if p1 == p2
return 0 return 0
elseif p1 == s.n elseif p1 == s.n
return -get_k(s, i, dim, p2) return -(i[which_index(s, dim, p2)] - s.N ÷ 2 - 1)
elseif p2 == s.n elseif p2 == s.n
return get_k(s, i, dim, p1) return i[which_index(s, dim, p1)] - s.N ÷ 2 - 1
else else
return get_k(s, i, dim, p1) - get_k(s, i, dim, p2) return i[which_index(s, dim, p1)] - i[which_index(s, dim, p2)]
end end
end end
@ -70,7 +42,7 @@ end
function calculate_Vs(s::system{T}, V_twobody::Function, ϕ::T, n_image::Int)::Array{Complex{T}} where {T<:Float} function calculate_Vs(s::system{T}, V_twobody::Function, ϕ::T, n_image::Int)::Array{Complex{T}} where {T<:Float}
coeff² = (exp(im * ϕ) * s.L / s.N)^2 coeff² = (exp(im * ϕ) * s.L / s.N)^2
images = collect.(Iterators.product(fill(-n_image:n_image, s.d)...)) # TODO: Learn how to use tuples instead of vectors images = collect.(Iterators.product(fill(-n_image:n_image, s.d)...)) # TODO: Learn how to use tuples instead of vectors
Vs = zeros(Complex{T}, length(s.unique_i), fill(s.N, s.d * (s.n - 2))...) Vs = zeros(Complex{T}, fill(s.N, s.d * (s.n - 1))...)
Threads.@threads for i in CartesianIndices(Vs) Threads.@threads for i in CartesianIndices(Vs)
for p1 in 1:s.n for p1 in 1:s.n
for p2 in (p1 + 1):s.n for p2 in (p1 + 1):s.n

5
helper.jl Normal file
View File

@ -0,0 +1,5 @@
"Index of the nearest value in a list to a given reference point"
nearestIndex(list::Array, ref) = argmin(norm.(list .- ref))
"Nearest value in a list to a given reference point"
nearest(list::Array, ref) = list[nearestIndex(list, ref)]

View File

@ -1,77 +0,0 @@
using DelimitedFiles, LinearAlgebra
function calculate_all_data(N::Int)
ks = -N÷2:N÷2-1
lattice = hcat((collect.(Iterators.product(ks, ks, ks)))...)
labels = reshape(collect(1:N^3), (N, N, N))
unique_i = collect(1:N^3)
multiplicity = fill(1, length(unique_i))
unique_point = transpose(lattice)
return unique_i, unique_point, multiplicity, labels
end
function calculate_A1_data(N::Int)
rotations = readdlm("rotations.mat", ',', Int, '\n')
rotations = reshape(rotations, (24, 3, 3))
ks = -N÷2:N÷2-1
lattice = hcat((collect.(Iterators.product(ks, ks, ks)))...)
labels = reshape(collect(1:N^3), (N, N, N))
for r in 1:24
rotated_lattice = Matrix(rotations[r, :, :]) * lattice
for index in 1:N^3
rotated_lattice_point = rotated_lattice[:, index]
(i, j, k) = mod1.(rotated_lattice_point .+ (N÷2 + 1), N)
old_label = max(labels[index], labels[i, j, k])
new_label = min(labels[index], labels[i, j, k])
if old_label != new_label
for o in findall(isequal(old_label), labels)
labels[o] = new_label
end
end
end
end
unique_i = unique(labels)
multiplicity = [count(labels.==i) for i in unique_i]
unique_point = transpose(lattice[:, unique_i])
return unique_i, unique_point, multiplicity, labels
end
function sym_reduce(s, K_partial)
I = one(K_partial)
K_partial_x1 = kron(kron(K_partial, I), I)
K_partial_y1 = kron(kron(I, K_partial), I)
K_partial_z1 = kron(kron(I, I), K_partial)
K_partial_x1 = K_partial_x1[s.unique_i, :]
K_partial_y1 = K_partial_y1[s.unique_i, :]
K_partial_z1 = K_partial_z1[s.unique_i, :]
K_partial_x2 = kron(kron(K_partial, I), I)
K_partial_y2 = kron(kron(I, K_partial), I)
K_partial_z2 = kron(kron(I, I), K_partial)
for (i, label) in enumerate(s.labels)
if i != label
K_partial_x2[:, label] .+= K_partial_x2[:, i]
K_partial_y2[:, label] .+= K_partial_y2[:, i]
K_partial_z2[:, label] .+= K_partial_z2[:, i]
end
end
K_partial_x2 = K_partial_x2[:, s.unique_i]
K_partial_y2 = K_partial_y2[:, s.unique_i]
K_partial_z2 = K_partial_z2[:, s.unique_i]
K_partial_xc = K_partial_x2[s.unique_i, :]
K_partial_yc = K_partial_y2[s.unique_i, :]
K_partial_zc = K_partial_z2[s.unique_i, :]
return (K_partial_x1, K_partial_y1, K_partial_z1), (K_partial_x2, K_partial_y2, K_partial_z2), (K_partial_xc, K_partial_yc, K_partial_zc)
end

View File

@ -1,24 +0,0 @@
1,0,0,0,1,0,0,0,1
1,0,0,0,0,-1,0,1,0
0,0,1,0,1,0,-1,0,0
0,-1,0,1,0,0,0,0,1
1,0,0,0,-1,0,0,0,-1
-1,0,0,0,1,0,0,0,-1
-1,0,0,0,-1,0,0,0,1
1,0,0,0,0,1,0,-1,0
0,0,-1,0,1,0,1,0,0
0,1,0,-1,0,0,0,0,1
0,0,-1,1,0,0,0,-1,0
0,0,1,-1,0,0,0,-1,0
0,0,-1,-1,0,0,0,1,0
0,0,1,1,0,0,0,1,0
0,1,0,0,0,-1,-1,0,0
0,-1,0,0,0,-1,1,0,0
0,-1,0,0,0,1,-1,0,0
0,1,0,0,0,1,1,0,0
0,1,0,1,0,0,0,0,-1
0,-1,0,-1,0,0,0,0,-1
0,0,1,0,-1,0,1,0,0
0,0,-1,0,-1,0,-1,0,0
-1,0,0,0,0,1,0,1,0
-1,0,0,0,0,-1,0,-1,0

View File

@ -1,23 +0,0 @@
include("Hamiltonian.jl")
println("Running with ",Threads.nthreads()," thread(s)")
T=Float32
function V_test(r2)
return -4*exp(-r2/4)
end
n = 3
N = 8
println("\n$n-body system with N=$N")
for L::T in [16]
println("L=$L")
println("Constructing Hamiltonian")
s=system{T}(3,n,N,L,0.5,A1)
@time H=Hamiltonian{T}(s,V_test,0,0,cpu_tensor)
println("Solving eigenvalues")
@time evals,_,_ = eig(H,5)
println(evals)
end