CPU implemention (not converging)

This commit is contained in:
ysyapa 2023-08-18 17:28:44 +00:00
parent c5d43af5b0
commit f74f206d8b
3 changed files with 28 additions and 30 deletions

View File

@ -9,9 +9,7 @@ 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_1x::Union{Matrix{Complex{T}},Nothing} K_partial_1::Union{Tuple,Nothing}
K_partial_1y::Union{Matrix{Complex{T}},Nothing}
K_partial_1z::Union{Matrix{Complex{T}},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
@ -21,7 +19,7 @@ struct Hamiltonian{T}
k = -s.N÷2:s.N÷2-1 k = -s.N÷2:s.N÷2-1
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_1x, K_partial_1y, K_partial_1z = sym_reduce(s, K_partial) K_partial_1 = sym_reduce(s, K_partial)
Vs = calculate_Vs(s, V_twobody, convert(T, ϕ), n_image) Vs = calculate_Vs(s, V_twobody, convert(T, ϕ), n_image)
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'])
@ -31,7 +29,7 @@ struct Hamiltonian{T}
K_diag = nothing K_diag = nothing
K_mixed = nothing K_mixed = nothing
end end
return new{T}(s, K_partial, K_diag, K_mixed, K_partial_1x, K_partial_1y, K_partial_1z, Vs, hermitian, mode) return new{T}(s, K_partial, K_diag, K_mixed, K_partial_1, Vs, hermitian, mode)
end end
end end
@ -39,7 +37,7 @@ Base.size(H::Hamiltonian, i::Int)::Int = (i == 1 || i == 2) ? H.s.N^(H.s.d * (H.
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(H.dim1, fill(H.s.N, H.s.d * (H.s.n - 2))...) vectorDims(H::Hamiltonian)::Dims = tuple(length(H.s.unique_i), fill(H.s.N, H.s.d * (H.s.n - 2))...)
"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,28 +45,26 @@ 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
coords = H.s.n - 1 nconList_v_template = -collect(1:(H.s.d * (H.s.n - 2) + 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:coords for coord1 = 1:(H.s.n - 1)
for coord2 = 1:coord1 for coord2 = 1:coord1
i1 = which_index(H.s, dim, coord1)
if coord1 == 1 && coord2 == 1 i2 = which_index(H.s, dim, coord2)
nconList_1 = [-i1, 1]
nconList_2 = [-i2, 2]
nconList_v = copy(nconList_v_template)
if i1 == i2
nconList_2[1] = 1
else else
i1 = which_index(H.s, dim, coord1) nconList_v[i1] = 1
i2 = which_index(H.s, dim, coord2)
nconList_1 = [-i1, 1]
nconList_2 = [-i2, 2]
nconList_v = copy(nconList_v_template)
if i1 == i2
nconList_2[1] = 1
else
nconList_v[i1] = 1
end
nconList_v[i2] = 2
v_new = @ncon((H.K_partial, H.K_partial, v), (nconList_1, nconList_2, nconList_v))
end end
nconList_v[i2] = 2
tensor1 = coord1 == 1 ? H.K_partial_1[dim] : H.K_partial
tensor2 = coord2 == 1 ? H.K_partial_1[dim] : H.K_partial
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

View File

@ -41,7 +41,7 @@ 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 = (dim - 1) * (s.n - 2) + p + 1 which_index(s::system, dim::Int, p::Int)::Int = p == 1 ? 1 : (dim - 1) * (s.n - 2) + p + 1
"Δ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, p::Int)::Int function get_k(s::system, i::CartesianIndex, dim::Int, p::Int)::Int
@ -90,7 +90,7 @@ function calculate_Vs(s::system{T}, V_twobody::Function, ϕ::T, n_image::Int)::A
end end
end end
end end
Vs[i] *= s.multiplicity[i[1]]^2 Vs[i] *= s.multiplicity[i[1]]
end end
return Vs return Vs
end end

View File

@ -2,7 +2,7 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 1,
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
@ -21,11 +21,13 @@
"println(\"\\n$n-body system with N=$N\")\n", "println(\"\\n$n-body system with N=$N\")\n",
"\n", "\n",
"for L::T in 5.0:9.0\n", "for L::T in 5.0:9.0\n",
" print(\"L=$L\")\n", " println(\"L=$L\")\n",
" println(\"Constructing Hamiltonian\")\n",
" s=system{T}(3,n,N,L,0.5,all)\n", " s=system{T}(3,n,N,L,0.5,all)\n",
" @time H=Hamiltonian{T}(s,V_test,0,0,cpu_tensor)\n", " @time H=Hamiltonian{T}(s,V_test,0,0,cpu_tensor)\n",
" #evals,_,_ = eig(H,5)\n", " println(\"Solving eigenvalues\")\n",
" #println(real.(evals))\n", " @time evals,_,_ = eig(H,5)\n",
" println(real.(evals))\n",
"end" "end"
] ]
} }