diff --git a/src/frontend/GV.jl b/src/frontend/GV.jl index 7ca47ed7..fbfc3e1b 100644 --- a/src/frontend/GV.jl +++ b/src/frontend/GV.jl @@ -15,27 +15,23 @@ include("GV_diagrams/readfile.jl") function eachorder_diag(type::Symbol, order::Int, VerOrder::Int=0, GOrder::Int=0; loopPool::Union{LoopPool,Nothing}=nothing, tau_labels::Union{Nothing,Vector{Int}}=nothing, GTypes::Union{Nothing,Vector{Int}}=nothing, VTypes::Union{Nothing,Vector{Int}}=nothing) - Generates a `Vector{FeynmanGraph}`: the polarization diagrams with static interactions of a given order, where the actual order of diagrams equals to `order + VerOrder + 2 * GOrder`. - Generates fermionic/bosonic `LabelProduct`: `fermi_labelProd`/`bose_labelProd` with inputs `tau_labels`, `GTypes`/`VTypes`, and updated `loopPool`. + Generates a `Vector{FeynmanGraph}`: the given-`type` diagrams with static interactions of a given order, where the actual order of diagrams equals to `order + VerOrder + 2 * GOrder`. + Generates a `LabelProduct`: `labelProd` with inputs `tau_labels` and all the possible momenta-loop basis. Generates external tau labels Vector{Vector{Int}}. The i-th labels (Vector{Int}) corresponds to the i-th `FeynmanGraph` in `Vector{FeynmanGraph}`. # Arguments: - `type` (Symbol): The type of the diagrams, including `:spinPolar`, `:chargePolar`, `:sigma`, `:green`, or `:freeEnergy`. - `order` (Int): The order of the diagrams without counterterms. -- `VerOrder` (Int, optional): The order of interaction counterterms (defaults to 0). - `GOrder` (Int, optional): The order of self-energy counterterms (defaults to 0). -- `dim` (Int, optional): The dimension of the system (defaults to 3). +- `VerOrder` (Int, optional): The order of interaction counterterms (defaults to 0). +- `labelProd` (Union{Nothing,LabelProduct}=nothing, optional): The initial cartesian QuantumOperator.label product (defaults to `nothing`). - `spinPolarPara` (Float64, optional): The spin-polarization parameter (n_up - n_down) / (n_up + n_down) (defaults to `0.0`). -- `loopPool` (Union{LoopPool,Nothing}=nothing, optional): The initial pool of loop momenta (defaults to `nothing`). - `tau_labels`(Union{Nothing, Vector{Int}}, optional): The labels for the discrete time of each vertex. (defaults to `nothing`). -- `GTypes`: The types of fermion propagators `G` in the diagrams (defaults to `collect(0:GOrder)`). -- `VTypes`: The types of boson static interaction `V` in the diagrams (defaults to `collect(0:VerOrder)`). # Returns A tuple `(diagrams, fermi_labelProd, bose_labelProd, extT_labels)` where - `diagrams` is a `Vector{FeynmanGraph}` object representing the diagrams, -- `fermi_labelProd` is a `LabelProduct` object containing the labels for the fermionic `G` objects in the diagrams, -- `bose_labelProd` is a `LabelProduct` object containing the labels for the bosonic `W` objects in the diagrams. +- `labelProd` is a `LabelProduct` object containing the labels for the leaves of graphs, - `extT_labels` is a `Vector{Vector{Int}}` object containing the external tau labels for each `FeynmanGraph` in `diagrams`. """ function eachorder_diag(type::Symbol, order::Int, GOrder::Int=0, VerOrder::Int=0; @@ -60,12 +56,6 @@ function eachorder_diag(type::Symbol, order::Int, GOrder::Int=0, VerOrder::Int=0 end # println("Reading ", filename) - # Gorders = collect(0:GOrder) - # # type == :sigma_old && append!(Gorders, [-2, -3]) - # type in [:green, :sigma] && pushfirst!(Gorders, -2) - # Vorders = collect(0:VerOrder) - # # isnothing(VTypes) && (VTypes = collect(0:VerOrder)) - # GVorders = [Gorders, Vorders] if isnothing(labelProd) return read_diagrams(filename; tau_labels=tau_labels, diagType=diagtype, spinPolarPara=spinPolarPara) else @@ -74,25 +64,26 @@ function eachorder_diag(type::Symbol, order::Int, GOrder::Int=0, VerOrder::Int=0 end """ - function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false, dim::Int=3) + function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false; + MinOrder::Int=1, spinPolarPara::Float64=0.0) - Generates a FeynmanGraph Dict: the `dim`-dimensional spin/charge polarization or self-energy diagrams with static interactions in a given `type`, to a given maximum order `MaxOrder`, with switchable couterterms. - Generates fermionic/bosonic `LabelProduct`: `fermi_labelProd`/`bose_labelProd` for these FeynmanGraphs. + Generates a FeynmanGraph Dict: the Feynman diagrams with static interactions in a given `type`, and + spin-polarizaition parameter `spinPolarPara`, to given minmimum/maximum orders `MinOrder/MaxOrder`, with switchable couterterms. + Generates a `LabelProduct`: `labelProd` for these FeynmanGraphs. Generates a leafMap for mapping `g.id` to the index of unique leaf. # Arguments: - `type` (Symbol): The type of the Feynman diagrams, including `:spinPolar`, `:chargePolar`, `:sigma_old`, `:green`, or `:freeEnergy`. - `Maxorder` (Int): The maximum actual order of the diagrams. - `has_counterterm` (Bool): `false` for G0W0, `true` for GW with self-energy and interaction counterterms (defaults to `false`). -- `dim` (Int): The dimension of the system (defaults to 3). +- `MinOrder` (Int, optional): The minmimum actual order of the diagrams (defaults to `1`). - `spinPolarPara` (Float64, optional): The spin-polarization parameter (n_up - n_down) / (n_up + n_down) (defaults to `0.0`). # Returns A tuple `(dict_graphs, fermi_labelProd, bose_labelProd, leafMap)` where - `dict_graphs` is a `Dict{Tuple{Int,Int,Int},Tuple{Vector{FeynmanGraph},Vector{Vector{Int}}}}` object representing the diagrams. The key is (order, Gorder, Vorder). The element is a Tuple (graphVector, extT_labels). -- `fermi_labelProd` is a `LabelProduct` object containing the labels for the fermionic `G` objects in the diagrams, -- `bose_labelProd` is a `LabelProduct` object containing the labels for the bosonic `W` objects in the diagrams. +- `labelProd` is a `LabelProduct` object containing the labels for the leaves of graphs, - `leafMap` maps `g.id` to the index of unique leaf. """ function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false; @@ -117,7 +108,6 @@ function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false; else error("no support for $type diagram") end - # loopPool = LoopPool(:K, dim, MaxLoopNum, Float64) loopbasis = [vcat([1.0], [0.0 for _ in 2:MaxLoopNum])] # Create label product labelProd = LabelProduct(tau_labels, loopbasis) @@ -136,7 +126,6 @@ function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false; labelProd=labelProd, spinPolarPara=spinPolarPara) key = (order, GOrder, VerOrder) dict_graphs[key] = (gvec, extT_labels) - # loopPool = fermi_labelProd.labels[3] leafMap[key] = IR.optimize!(gvec) end end @@ -147,7 +136,6 @@ function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false; labelProd=labelProd, spinPolarPara=spinPolarPara) key = (order, 0, 0) dict_graphs[key] = (gvec, extT_labels) - # loopPool = fermi_labelProd.labels[3] leafMap[key] = IR.optimize!(gvec) end end @@ -156,24 +144,23 @@ function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false; end """ - function diagdictGV(type::Symbol, MaxOrder::Int, has_counterterm::Bool=false, dim::Int=3) + function diagdictGV(type::Symbol, gkeys::Vector{Tuple{Int,Int,Int}}; spinPolarPara::Float64=0.0) - Generates a FeynmanGraph Dict: the `dim`-dimensional spin/charge polarization or self-energy diagrams with static interactions in a given `type`, to a given maximum order `MaxOrder`, with switchable couterterms. - Generates fermionic/bosonic `LabelProduct`: `fermi_labelProd`/`bose_labelProd` for these FeynmanGraphs. + Generates a FeynmanGraph Dict: the Feynman diagrams with static interactions in the given `type` and + spin-polarizaition parameter `spinPolarPara`, with given couterterm-orders (from `gkeys`). + Generates a `LabelProduct`: `labelProd` for these FeynmanGraphs. Generates a leafMap for mapping `g.id` to the index of unique leaf. # Arguments: - `type` (Symbol): The type of the Feynman diagrams, including `:spinPolar`, `:chargePolar`, `:sigma_old`, `:green`, or `:freeEnergy`. - `gkeys` (Vector{Tuple{Int,Int,Int}}): The (order, Gorder, Vorder) of the diagrams. Gorder is the order of self-energy counterterms, and Vorder is the order of interaction counterterms. -- `dim` (Int): The dimension of the system (defaults to 3). - `spinPolarPara` (Float64, optional): The spin-polarization parameter (n_up - n_down) / (n_up + n_down) (defaults to `0.0`). # Returns A tuple `(dict_graphs, fermi_labelProd, bose_labelProd, leafMap)` where - `dict_graphs` is a `Dict{Tuple{Int,Int,Int},Tuple{Vector{FeynmanGraph},Vector{Vector{Int}}}}` object representing the diagrams. The key is (order, Gorder, Vorder). The element is a Tuple (graphVector, extT_labels). -- `fermi_labelProd` is a `LabelProduct` object containing the labels for the fermionic `G` objects in the diagrams, -- `bose_labelProd` is a `LabelProduct` object containing the labels for the bosonic `W` objects in the diagrams. +- `labelProd` is a `LabelProduct` object containing the labels for the leaves of graphs, - `leafMap` maps `g.id` to the index of unique leaf. """ function diagdictGV(type::Symbol, gkeys::Vector{Tuple{Int,Int,Int}}; spinPolarPara::Float64=0.0) @@ -197,7 +184,6 @@ function diagdictGV(type::Symbol, gkeys::Vector{Tuple{Int,Int,Int}}; spinPolarPa else error("no support for $type diagram") end - # loopPool = LoopPool(:K, dim, MaxLoopNum, Float64) loopbasis = [vcat([1.0], [0.0 for _ in 2:MaxLoopNum])] # Create label product @@ -219,24 +205,20 @@ function diagdictGV(type::Symbol, gkeys::Vector{Tuple{Int,Int,Int}}; spinPolarPa end """ - function leafstates( - FeynGraphs::Dict{T, Tuple{Vector{G}, Vector{Vector{Int}}}}, - labelProd::LabelProduct, labelProd::LabelProduct, - graph_keys::Vector{T} - ) where {T, G<:FeynmanGraph} + function leafstates(FeynGraphs::Dict{T,Tuple{Vector{G},Vector{Vector{Int}}}}, + labelProd::LabelProduct, graph_keys::Vector{T}) where {T,G<:FeynmanGraph} Extracts leaf information from a Dict collection of Feynman graphs (`FeynGraphs` with its keys `graph_keys`) - and their associated LabelProduct data (`labelProd` and `labelProd`). + and their associated LabelProduct data (`labelProd`). The information includes their initial value, type, in/out time, and loop momenta. # Arguments: - `FeynGraphs`: A dictionary mapping keys of type T to tuples containing a vector of `FeynmanGraph` objects and a vector of external time labels. -- `labelProd`: A LabelProduct used to label the fermionic `G` objects in the graphs. -- `labelProd`: A LabelProduct used to label bosonic `W` objects in the graphs. +- `labelProd`: A LabelProduct used to label the leaves of graphs. - `graph_keys`: A vector containing keys of type `T`, specifying which graphs to analyze. # Returns -- A tuple of vectors containing information about the leaves in the graphs, including their initial values, types, input and output time indexes, and loop-momenta indexes. +- A tuple of vectors containing information about the leaves of graphs, including their initial values, types, input and output time indexes, and loop-momenta indexes. - A Vector{Vector{Int}} representing the external tau variables of each vector of graph corresponding to each key of type `T`. """ function leafstates(FeynGraphs::Dict{T,Tuple{Vector{G},Vector{Vector{Int}}}}, @@ -274,14 +256,8 @@ function leafstates(FeynGraphs::Dict{T,Tuple{Vector{G},Vector{Vector{Int}}}}, elseif IR.diagram_type(g) == IR.Propagator if (Op.isfermionic(vertices[1])) In, Out = vertices[2][1].label, vertices[1][1].label - # if labelProd[In][2] in [-2, -3] - # push!(leafType[ikey], 0) - # push!(leafLoopIndex[ikey], 1) - # else - # push!(leafType[ikey], labelProd[In][2] * 2 + 1) push!(leafType[ikey], g.orders[1] * 2 + 1) push!(leafLoopIndex[ikey], FrontEnds.linear_to_index(labelProd, In)[end]) #the label of LoopPool for each fermionic leaf - # end push!(leafInTau[ikey], labelProd[In][1]) push!(leafOutTau[ikey], labelProd[Out][1]) else diff --git a/src/frontend/GV_diagrams/readfile.jl b/src/frontend/GV_diagrams/readfile.jl index 2db15201..333dc164 100644 --- a/src/frontend/GV_diagrams/readfile.jl +++ b/src/frontend/GV_diagrams/readfile.jl @@ -84,7 +84,6 @@ function read_diagrams(filename::AbstractString; labelProd::Union{Nothing,LabelP extIndex = Int[] GNum = 2 lineNum = 1 - # filename[1:5] == "Sigma" && keywords[1] = "SelfEnergy" while true line = readline(io) length(line) == 0 && break @@ -109,12 +108,6 @@ function read_diagrams(filename::AbstractString; labelProd::Union{Nothing,LabelP if isnothing(tau_labels) tau_labels = collect(1:tauNum) end - # current_labels = CurrentLabels(loopNum) - # innerlabels = [] - # GTypeNum >1 && push!(innerlabels, collect(1:GTypeNum)) - # WTypeNum >1 && push!(innerlabels, collect(1:WTypeNum)) - # labelProd = LabelProduct(tau_labels, current_labels, innerlabels...) - if isnothing(labelProd) loopbasis = [vcat([1.0], [0.0 for _ in 2:loopNum])] # Create label product @@ -124,11 +117,6 @@ function read_diagrams(filename::AbstractString; labelProd::Union{Nothing,LabelP maxloopNum = length(labelProd[1][end]) end - # Create loop pool if not provided - # if isnothing(loopPool) - # loopPool = LoopPool(:K, dim, loopNum, Float64) - # end - # Read one diagram at a time diagrams = FeynmanGraph{_dtype.factor,_dtype.weight}[] extT_labels = Vector{Int}[] @@ -139,11 +127,7 @@ function read_diagrams(filename::AbstractString; labelProd::Union{Nothing,LabelP push!(diagrams, diag) push!(extT_labels, extTlabel) end - - # Create new label products with loop pool close(io) - # fermi_labelProd = LabelProduct(tau_labels, GTypes, loopPool) - # bose_labelProd = LabelProduct(tau_labels, VTypes, loopPool) if diagType in [:sigma, :sigma_old] @assert length(extIndex) == 2 @@ -182,13 +166,9 @@ function read_onediagram!(io::IO, GNum::Int, verNum::Int, loopNum::Int, extIndex @assert occursin("VertexBasis", readline(io)) tau_labels = _StringtoIntVector(readline(io)) .- offset - # tau_labels = _StringtoIntVector(readline(io)) - # unique_values = sort(unique(tau_labels)) - # tau_labels = [findfirst(x -> x == tau, unique_values) for tau in tau_labels] .- (1 + offset) readline(io) @assert occursin("LoopBasis", readline(io)) - # currentBasis = zeros(Int, (GNum, loopNum)) currentBasis = zeros(Int, (GNum, maxLoopNum)) for i in 1:loopNum x = parse.(Int, split(readline(io))) @@ -230,31 +210,14 @@ function read_onediagram!(io::IO, GNum::Int, verNum::Int, loopNum::Int, extIndex permu, ver4Legs_ex = _exchange(permutation, ver4Legs, iex, extNum, offset_ver4=offset_ver4) ######################## Create Feynman diagram ######################### - # current_labels = labelProd.labels[dim] vertices = [𝜙(0) for i in 1:GNum] connected_operators = Op.OperatorProduct[] connected_operators_orders = Vector{Vector{Int}}() - # GTypes = fermi_labelProd.labels[2] - # VTypes = bose_labelProd.labels[2] - # fermi_dims = fermi_labelProd.dims - # bose_dims = bose_labelProd.dims - # if staticBose - # tau_labels = [collect(eachindex(extIndex)); repeat(extIndex+1:tauNum, inner=2)] - # else - # @assert tauNum == GNum - # tau_labels = collect(1:GNum) - # end - # create all fermionic operators for (ind1, ind2) in enumerate(permu) - # current_index = _current_to_index(currentBasis[ind1, :]) - # current_index = FrontEnds.append(loopPool, currentBasis[ind1, :]) current_index = FrontEnds.push_labelat!(labelProd, currentBasis[ind1, :], 2) - # ind_GType = findfirst(p -> p == opGType[ind1], GTypes) - # label1 = index_to_linear(fermi_labelProd, tau_labels[ind1], ind_GType, current_index) - # label2 = index_to_linear(fermi_labelProd, tau_labels[ind2], ind_GType, current_index) label1 = FrontEnds.index_to_linear(labelProd, tau_labels[ind1], current_index) label2 = FrontEnds.index_to_linear(labelProd, tau_labels[ind2], current_index) @@ -276,19 +239,9 @@ function read_onediagram!(io::IO, GNum::Int, verNum::Int, loopNum::Int, extIndex for (iVer, verLeg) in enumerate(ver4Legs_ex) current = currentBasis[verLeg[1]-offset, :] - currentBasis[verLeg[2]-offset, :] @assert current == currentBasis[verLeg[4]-offset, :] - currentBasis[verLeg[3]-offset, :] # momentum conservation - # current_index = _current_to_index(current) - # current_index = FrontEnds.append(loopPool, current) current_index = FrontEnds.push_labelat!(labelProd, current, 2) ind1, ind2 = 2 * (iVer - offset_ver4) - 1 + extNum, 2 * (iVer - offset_ver4) + extNum - # ind1_WType = findfirst(p -> p == opWType[2iVer-1], VTypes) - # ind2_WType = findfirst(p -> p == opWType[2iVer], VTypes) - - # label1 = index_to_linear(bose_labelProd, tau_labels[ind1], ind1_WType, current_index) - # label2 = index_to_linear(bose_labelProd, tau_labels[ind2], ind2_WType, current_index) - # labelProd_size = (bose_dims..., length(loopPool)) - # label1 = LinearIndices(labelProd_size)[tau_labels[ind1], ind1_WType, current_index] - # label2 = LinearIndices(labelProd_size)[tau_labels[ind2], ind2_WType, current_index] label1 = FrontEnds.index_to_linear(labelProd, tau_labels[ind1], current_index) label2 = FrontEnds.index_to_linear(labelProd, tau_labels[ind2], current_index) @@ -300,23 +253,9 @@ function read_onediagram!(io::IO, GNum::Int, verNum::Int, loopNum::Int, extIndex # add external operators in each external vertices if extNum > 0 && diagType != :sigma - # external_current = append!([1], zeros(Int, loopNum - 1)) external_current = append!([1], zeros(Int, maxLoopNum - 1)) - # extcurrent_index = FrontEnds.append(loopPool, external_current) extcurrent_index = FrontEnds.push_labelat!(labelProd, external_current, 2) - # if diagType == :sigma - # for (i, ind) in enumerate(extIndex) - # labelProd_size = (fermi_dims..., length(loopPool)) - # label = LinearIndices(labelProd_size)[tau_labels[ind], 1, extcurrent_index] - # if i == 1 - # vertices[ind] *= 𝑎⁻(label) - # else - # vertices[ind] *= 𝑎⁺(label) - # end - # end for ind in extIndex - # labelProd_size = (bose_dims..., length(loopPool)) - # label = LinearIndices(labelProd_size)[tau_labels[ind], 1, extcurrent_index] label = FrontEnds.index_to_linear(labelProd, tau_labels[ind], 1, extcurrent_index) vertices[ind] *= 𝜙(label) end @@ -330,7 +269,6 @@ function read_onediagram!(io::IO, GNum::Int, verNum::Int, loopNum::Int, extIndex end push!(graphs, IR.feynman_diagram(IR.interaction.(vertices), contraction, contraction_orders=connected_operators_orders, factor=symfactor, is_signed=true)) - # return IR.feynman_diagram(IR.interaction.(vertices), contraction, factor=symfactor * spinFactor), loopPool end # create a graph as a linear combination from all subgraphs and subgraph_factors (spinFactors), loopPool, and external-tau variables @@ -344,6 +282,5 @@ function read_onediagram!(io::IO, GNum::Int, verNum::Int, loopNum::Int, extIndex else extT = tau_labels[extIndex] end - # return IR.linear_combination(graphs, spinfactors_existed), loopPool, extT return IR.linear_combination(graphs, spinfactors_existed), labelProd, extT end \ No newline at end of file diff --git a/src/utility.jl b/src/utility.jl index 26bcf668..aa8241d9 100644 --- a/src/utility.jl +++ b/src/utility.jl @@ -139,15 +139,15 @@ end - `label::Tuple{LabelProduct,LabelProduct}` A Tuple fermi (first element) and bose LabelProduct (second element). - `taylormap::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target diagram to its correponding taylor series. """ -function taylorexpansion!(graph::FeynmanGraph{F,W}, propagator_var::Tuple{Vector{Bool},Vector{Bool}}, label::Tuple{LabelProduct,LabelProduct}; taylormap::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}()) where {F,W} +function taylorexpansion!(graph::FeynmanGraph{F,W}, propagator_var::Tuple{Vector{Bool},Vector{Bool}}; taylormap::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}()) where {F,W} var_dependence = Dict{Int,Vector{Bool}}() for leaf in Leaves(graph) if ComputationalGraphs.diagram_type(leaf) == ComputationalGraphs.Propagator - In = leaf.properties.vertices[2][1].label + # In = leaf.properties.vertices[2][1].label if isfermionic(leaf.properties.vertices[1]) - if label[1][In][2] >= 0 #For fake propagator, this label is smaller than zero, and those propagators should not be differentiated. - var_dependence[leaf.id] = [propagator_var[1][idx] ? true : false for idx in 1:get_numvars()] - end + # if label[1][In][2] >= 0 #For fake propagator, this label is smaller than zero, and those propagators should not be differentiated. + var_dependence[leaf.id] = [propagator_var[1][idx] ? true : false for idx in 1:get_numvars()] + # end else var_dependence[leaf.id] = [propagator_var[2][idx] ? true : false for idx in 1:get_numvars()] end diff --git a/test/taylor.jl b/test/taylor.jl index 812daf03..6320e62b 100644 --- a/test/taylor.jl +++ b/test/taylor.jl @@ -76,13 +76,13 @@ end @testset "Taylor AD of Sigma FeynmanGraph" begin - dict_g, fl, bl, leafmap = diagdictGV(:sigma, [(2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 2, 0), (2, 1, 2), (2, 2, 2)], 3) + dict_g, lp, leafmap = diagdictGV(:sigma, [(2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 2, 0), (2, 1, 2), (2, 2, 2)]) g = dict_g[(2, 0, 0)] set_variables("x y", orders=[2, 2]) propagator_var = ([true, false], [false, true]) # Specify variable dependence of fermi (first element) and bose (second element) particles. - t, taylormap = taylorexpansion!(g[1][1], propagator_var, (fl, bl)) + t, taylormap = taylorexpansion!(g[1][1], propagator_var) for (order, graph) in dict_g if graph[2][1] == g[2][1]