Skip to content

Commit

Permalink
add symmetrized NewDLR
Browse files Browse the repository at this point in the history
  • Loading branch information
fsxbhyy committed Aug 13, 2024
1 parent b686c51 commit e1ff333
Show file tree
Hide file tree
Showing 12 changed files with 2,131 additions and 43 deletions.
48 changes: 24 additions & 24 deletions src/vertex3/QR.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ function addBasisBlock!(basis::Basis, idx, verbose)
basis.mesh.residual[idx] = 0 # the selected mesh grid has zero residual
#print("$(mirror(basis.mesh, idx))\n")
gridmirror , idxmirror = mirror(basis.mesh, idx)
print(idxmirror)
#print("mirror $(idx) $(idxmirror)\n")
for (gi,grid) in enumerate(gridmirror)
addBasis!(basis, grid, verbose)
L2Res = L2Residual(basis.mesh)
#L2Res = L2Residual(basis.mesh)
# if typeof(basis.mesh)<:FreqFineMesh
# if output && num % 5 == 0 && typeof(basis.mesh)<: TauFineMesh#MatsuFineMesh
# pic = plot(ylabel = "residual")
Expand Down Expand Up @@ -168,24 +168,24 @@ function updateResidual!(basis::Basis{Grid, Mesh, F, D}) where {Grid,Mesh,F,D}
end
end
end
if basis.mesh.simplegrid
Threads.@threads for idx in 1:length(mesh.L2grids)
candidate = mesh.L2grids[idx]
pp = sum(q[j] * dot(mesh, candidate, basis.grid[j]) for j in 1:basis.N)
#pp = q[basis.N] * dot(mesh, candidate, basis.grid[basis.N])
_residual = mesh.residual_L2[idx] - abs(pp) * abs(pp)
# @assert isnan(_residual) == false "$pp and $([q[j] for j in 1:basis.N]) => $([dot(mesh, basis.grid[j], candidate) for j in 1:basis.N])"
# println("working on $candidate : $_residual")
if _residual < 0
if _residual < -basis.rtol
@warn("warning: residual smaller than 0 at $candidate got $(mesh.residual_L2[idx]) - $(abs(pp)^2) = $_residual")
end
mesh.residual_L2[idx] = 0
else
mesh.residual_L2[idx] = _residual
end
end
end
# if basis.mesh.simplegrid
# Threads.@threads for idx in 1:length(mesh.L2grids)
# candidate = mesh.L2grids[idx]
# pp = sum(q[j] * dot(mesh, candidate, basis.grid[j]) for j in 1:basis.N)
# #pp = q[basis.N] * dot(mesh, candidate, basis.grid[basis.N])
# _residual = mesh.residual_L2[idx] - abs(pp) * abs(pp)
# # @assert isnan(_residual) == false "$pp and $([q[j] for j in 1:basis.N]) => $([dot(mesh, basis.grid[j], candidate) for j in 1:basis.N])"
# # println("working on $candidate : $_residual")
# if _residual < 0
# if _residual < -basis.rtol
# @warn("warning: residual smaller than 0 at $candidate got $(mesh.residual_L2[idx]) - $(abs(pp)^2) = $_residual")
# end
# mesh.residual_L2[idx] = 0
# else
# mesh.residual_L2[idx] = _residual
# end
# end
# end
end

# function updateResidual!(basis::Basis{Grid, Mesh, F, D}, candidate) where {Grid,Mesh,F,D}
Expand Down Expand Up @@ -227,9 +227,9 @@ function GramSchmidt(basis::Basis{G,M,F,D}) where {G,M,F,D}
newgrid = basis.grid[end]

overlap = [dot(basis.mesh, basis.grid[j], newgrid) for j in 1:basis.N-1]
if !isempty(overlap)
println( "$(maximum(imag(overlap)))\n" )
end
# if !isempty(overlap)
# println( "$(maximum(imag(overlap)))\n" )
# end
for qi in 1:basis.N-1
_R[qi, end] = basis.Q[:, qi]' * overlap
_Q[:, end] -= _R[qi, end] * _Q[:, qi] # <q, qnew> q
Expand All @@ -238,7 +238,7 @@ function GramSchmidt(basis::Basis{G,M,F,D}) where {G,M,F,D}
_norm = dot(basis.mesh, newgrid, newgrid) - _R[:, end]' * _R[:, end]
_norm = sqrt(abs(_norm))

@assert _norm > eps(F(1)) * 100 "$_norm is too small as a denominator!\nnewgrid = $newgrid\nexisting grid = $(basis.grid)\noverlap=$overlap\nR=$_R\nQ=$_Q"
@assert _norm > eps(F(1)) * 100 "$_norm is too small as a denominator!"#\nnewgrid = $newgrid\nexisting grid = $(basis.grid)\noverlap=$overlap\nR=$_R\nQ=$_Q"

_R[end, end] = _norm
_Q[:, end] /= _norm
Expand Down
4 changes: 2 additions & 2 deletions src/vertex3/frequency.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ struct FreqFineMesh{D,Float,Double} <: FQR.FineMesh
# elseif D == 3
elseif D == 1
if simplegrid
candidate_grid = log_ωGrid(Float(init), Float(factor*Λ), Float(ratio))# Float(1.35^(log(1e-6) / log(rtol))))
#candidate_grid = matsu_ωGrid(50, Float(1.0))
#candidate_grid = log_ωGrid(Float(init), Float(factor*Λ), Float(ratio))# Float(1.35^(log(1e-6) / log(rtol))))
candidate_grid = matsu_ωGrid(80, Float(1.0))
#fine_ωGrid(Float(10Λ), 1, Float(1.3))
else
candidate_grid = _finegrid
Expand Down
8 changes: 4 additions & 4 deletions src/vertex3/generate_basis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,12 @@ end
if abspath(PROGRAM_FILE) == @__FILE__

D = 1
Err = [-6, ]
Err = [-10, ]
#Λ = [1e4, ]
#Err = [-6, -8, -10, -12, -14]
#Err = [-5, -7, -9, -11, -13]
Λ = [1e2] # [1e3, 1e4, 1e5, 1e6,1e7]
setprecision(128)
Λ = [1e4] # [1e3, 1e4, 1e5, 1e6,1e7]
setprecision(512)
Float = BigFloat
Double = BigFloat
#Float = Float64
Expand Down Expand Up @@ -299,7 +299,7 @@ if abspath(PROGRAM_FILE) == @__FILE__
# for rat in ratio_scan
# for init in init_scan
#mesh = FreqFineMesh{D,Float, Double}(lambda, rtol, sym=sym, degree = degree1, ratio = ratio1, simplegrid=true)
mesh = FreqFineMesh{D,Float, Double}(lambda, rtol, sym=sym, degree = degree1, ratio = ratio1, factor = 1000, init=init, simplegrid=false)
mesh = FreqFineMesh{D,Float, Double}(lambda, rtol, sym=sym, degree = degree1, ratio = ratio1, factor = 1000, init=init, simplegrid=true)
basis = FQR.Basis{FreqGrid, Float ,Double}(lambda, rtol, mesh)

L2Res = L2Residual(basis.mesh)
Expand Down
18 changes: 17 additions & 1 deletion src/vertex3/matsubara.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct MatsuFineMesh{Float} <: FQR.FineMesh
_finegrid = Int.(nGrid(isFermi, Float(Λ), degree, Float(ratio) ))
#print("ngrid $(_finegrid)\n")
# separationTest(_finegrid)
mesh = new(isFermi, sym, [], [], [], _finegrid)
mesh = new{Float}(isFermi, sym, [], [], [], _finegrid)

for (xi, x) in enumerate(_finegrid)
coord = xi
Expand All @@ -48,6 +48,22 @@ struct MatsuFineMesh{Float} <: FQR.FineMesh

return mesh
end

function MatsuFineMesh{Float}(U::AbstractMatrix, finegrid, isFermi; sym=1) where {Float}
mesh = new{Float}(isFermi, sym, [], [], [], finegrid)

for (xi, x) in enumerate(finegrid)
coord = xi
#if irreducible(coord, sym, Nfine) # if grid point is in the reducible zone, then skip residual initalization
vec = U[xi, :]
g = MatsuGrid(x, coord, vec)
push!(mesh.candidates, g)
push!(mesh.residual, real.(FQR.dot(mesh, g, g)) )
push!(mesh.selected, false)
#end
end
return mesh
end
end

function Freq2Index(isFermi, ωnList)
Expand Down
244 changes: 244 additions & 0 deletions src/vertex3/omega.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
using Lehmann
using StaticArrays, Printf
using CompositeGrids
using LinearAlgebra
using DelimitedFiles
#const Float = BigFloat #FQR.Float
#const Double =BigFloat #FQR.Double
#const DotF = BigFloat
#const Tiny = DotF(1e-5)

struct TauGrid{Float} <: FQR.Grid
tau::Float # actual location of the grid point
coord::Int # integer coordinate of the grid point on the fine meshes
vec::Vector{Float}
end

Base.show(io::IO, grid::TauGrid) = print(io, "τ = ($(@sprintf("%12.4f", grid.tau[1])))")

struct TauFineMesh{Float} <: FQR.FineMesh
symmetry::Int # symmetrize (omega1, omega2) <-> (omega2, omega1)
candidates::Vector{TauGrid{Float}} # vector of grid points
selected::Vector{Bool}
residual::Vector{Float}

## for frequency mesh only ###
fineGrid::Vector{Float} # fine grid for each dimension

function TauFineMesh(U::AbstractMatrix{Float}, finegrid; sym=1) where {Float}
# initialize the residual on fineGrid with <g, g>
#_finegrid = Float.(τChebyGrid(Λ))
# separationTest(_finegrid)
mesh = new{Float}(sym, [], [], [], finegrid)

for (xi, x) in enumerate(finegrid)
coord = xi
#if irreducible(coord, sym, Nfine) # if grid point is in the reducible zone, then skip residual initalization
vec = U[xi,:]
g = TauGrid(x, coord, vec)
push!(mesh.candidates, g)
push!(mesh.residual, FQR.dot(mesh, g, g))
push!(mesh.selected, false)
#end
end

println("fine mesh initialized.")
return mesh
end
end



# function τChebyGrid(Λ, degree=24, print = true)
# npt = Int(ceil(log(Λ) / log(2.0))) - 2 # subintervals on [0,1/2] in tau space (# subintervals on [0,1] is 2*npt)

# pbpt = zeros(Float, 2npt + 1)
# pbpt[1] = 0.0
# for i = 1:npt
# pbpt[i+1] = 1.0 / 2^(npt - i + 1)
# end
# pbpt[npt+2:2npt+1] = 1 .- pbpt[npt:-1:1]
# #println("fine grid size: $(length(grid)) within [$(grid[1]), $(grid[end])]")
# finegrid = Lehmann.Discrete.CompositeChebyshevGrid(degree, pbpt).grid
# #println("$(finegrid)\n")#[1:(length(finegrid)÷2+1)])
# #println("$(finegrid+reverse(finegrid))\n")
# return finegrid
# end

"""
composite expoential grid
"""
function fine_τGrid::Float,degree,ratio::Float) where {Float}
############## use composite grid #############################################
# Generating a log densed composite grid with LogDensedGrid()
npo = Int(ceil(log(Λ) / log(ratio))) - 2 # subintervals on [0,1/2] in tau space (# subintervals on [0,1] is 2*npt)
grid = CompositeGrid.LogDensedGrid(
:cheb,# The top layer grid is :gauss, optimized for integration. For interpolation use :cheb
[0.0, 1.0],# The grid is defined on [0.0, β]
[0.0, 1.0],# and is densed at 0.0 and β, as given by 2nd and 3rd parameter.
npo,# N of log grid
0.5 / ratio^(npo-1), # minimum interval length of log grid
degree, # N of bottom layer
Float
)
#print(grid[1:length(grid)÷2+1])
#print(grid+reverse(grid))
# println("Composite expoential grid size: $(length(grid))")
println("fine grid size: $(length(grid)) within [$(grid[1]), $(grid[end])]")
return grid

############# DLR based fine grid ##########################################
# dlr = DLRGrid(Euv=Float64(Λ), beta=1.0, rtol=Float64(rtol) / 100, isFermi=true, symmetry=:ph, rebuild=true)
# # println("fine basis number: $(dlr.size)\n", dlr.ω)
# degree = 4
# grid = Vector{Double}(undef, 0)
# panel = Double.(dlr.τ)
# for i in 1:length(panel)-1
# uniform = [panel[i] + (panel[i+1] - panel[i]) / degree * j for j in 0:degree-1]
# append!(grid, uniform)
# end

# println("fine grid size: $(length(grid)) within [$(grid[1]), $(grid[2])]")
# return grid
end

# """
# Test the finegrids do not overlap
# """
# function separationTest(finegrid)
# epsilon = eps(DotF(1)) * 10
# for (i, f) in enumerate(finegrid)
# # either zero, or sufficiently large
# @assert abs(f) < epsilon || abs(f) > Tiny "$i: $f should either smaller than $epsilon or larger than $Tiny"
# for (j, g) in enumerate(finegrid)
# # two frequencies are either the same, or well separated
# @assert abs(f - g) < epsilon || abs(f - g) > Tiny "$i: $f and $j: $g should either closer than $epsilon or further than $Tiny"
# fg = f + g
# for (k, l) in enumerate(finegrid)
# @assert abs(l - fg) < epsilon || abs(l - fg) > Tiny "$i: $f + $j: $g = $fg and $k: $l should either closer than $epsilon or further than $Tiny"
# end
# end
# end
# return
# end

# function irreducible(coord, symmetry,length)
# @assert iseven(length) "The fineGrid should have even number of points"
# if symmetry == 0
# return true
# else
# return coord<length÷2+1
# end
# end

# function FQR.irreducible(grid::TauGrid)
# return irreducible(grid.coord, mesh.symmetry, length(mesh.fineGrid))
# end

function FQR.mirror(mesh::TauFineMesh{Float}, idx) where {Float}
meshsize = length(mesh.candidates)
if mesh.symmetry == 0
return [],[-1]
else
newgrids = TauGrid{Float}[]
idxmirror = []
#coords = unique([(idx), (meshsize - idx)])
g = deepcopy(mesh.candidates[meshsize - idx+1])
#print("\n$(mesh.candidates[meshsize - idx+1].tau+mesh.candidates[idx].tau)\n")
push!(newgrids, g)
push!(idxmirror,meshsize - idx+1)
return newgrids,idxmirror
end
# end
end


"""
basis dot
"""
function FQR.dot(mesh, g1::TauGrid, g2::TauGrid)
# println("dot: ", g1, ", ", g2)
return dot(g1.vec, g2.vec)
end



if abspath(PROGRAM_FILE) == @__FILE__


lambda, β, rtol = 100000, 1.0,1e-8
dlr = DLRGrid(Euv=Float64(lambda), beta=β, rtol=Float64(rtol) / 100, isFermi=true, symmetry=:sym, rebuild=false)
dlrfile = "basis.dat"
data = readdlm(dlrfile,'\n')
FreqGrid = BigFloat.(data[:,1])
mesh = TauFineMesh{BigFloat}(lambda, FreqGrid, sym=1)

# KK = zeros(3, 3)
# n = (2, 2)
# o = (mesh.fineGrid[n[1]], mesh.fineGrid[n[2]])
# for i in 1:3
# g1 = FreqGrid{2}(i, o, n)
# for j in 1:3
# g2 = FreqGrid{2}(j, o, n)
# println(g1, ", ", g2)
# KK[i, j] = FQR.dot(mesh, g1, g2)
# end
# end
# display(KK)
# println()

basis = FQR.Basis{TauGrid, BigFloat, BigFloat}(lambda, rtol, mesh)
FQR.qr!(basis, verbose=1)

# lambda, rtol = 1000, 1e-8
# mesh = TauFineMesh{D}(lambda, rtol, sym=0)
# basis = FQR.Basis{D,TauGrid{D}}(lambda, rtol, mesh)
# @time FQR.qr!(basis, verbose=1)

FQR.test(basis)

mesh = basis.mesh
grids = basis.grid
tau_grid = []
for (i, grid) in enumerate(grids)
push!(tau_grid, grid.tau)
end
tau_grid = sort(BigFloat.(tau_grid))
#print(tau_grid)
open("basis_τ.dat", "w") do io
for i in 1:length(tau_grid)
println(io, tau_grid[i])
end
end
# Nfine = length(mesh.fineGrid)
# open("finegrid.dat", "w") do io
# for i in 1:Nfine
# println(io, basis.mesh.fineGrid[i])
# end
# end
# open("residual.dat", "w") do io
# # println(mesh.symmetry)
# residual = zeros(Double, Nfine, Nfine)
# for i in 1:length(mesh.candidates)
# if mesh.candidates[i].sector == 1
# x, y = mesh.candidates[i].coord
# residual[x, y] = mesh.residual[i]
# # println(x, ", ", y, " -> ", length(mirror(mesh, i)))

# for grid in FQR.mirror(mesh, i)
# if grid.sector == 1
# xp, yp = grid.coord
# residual[xp, yp] = residual[x, y]
# # println(xp, ", ", yp)
# end
# end
# end
# end

# for i in 1:Nfine
# for j in 1:Nfine
# println(io, residual[i, j])
# end
# end
# end
end
Loading

0 comments on commit e1ff333

Please sign in to comment.