diff --git a/.vscode/settings.json b/.vscode/settings.json index 3ecb8fcd..351cd5d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "[python]": { "editor.defaultFormatter": "ms-python.autopep8" }, - "python.formatting.provider": "none" -} + "python.formatting.provider": "none", + "julia.environmentPath": "/home/pchou/Documents/DiagMC/Code/numericalEFT/FeynmanDiagram.jl" +} \ No newline at end of file diff --git a/archived/src/FeynmanDiagram.jl b/archived/src/FeynmanDiagram.jl new file mode 100644 index 00000000..3ebfa82b --- /dev/null +++ b/archived/src/FeynmanDiagram.jl @@ -0,0 +1,217 @@ +module FeynmanDiagram +using Random, LinearAlgebra, Parameters, AbstractTrees, RuntimeGeneratedFunctions + +macro todo() + return :(error("Not yet implemented!")) +end + +@enum DiagramType begin + VacuumDiag #vaccum diagram for the free energy + SigmaDiag #self-energy + GreenDiag #green's function + PolarDiag #polarization + Ver3Diag #3-point vertex function + Ver4Diag #4-point vertex function + GnDiag #n-point Green's function + GcDiag #n-point connected Green's function +end +Base.length(r::DiagramType) = 1 +Base.iterate(r::DiagramType) = (r, nothing) +function Base.iterate(r::DiagramType, ::Nothing) end + +abstract type DiagType end +abstract type Vacuum <: DiagType end +abstract type Tadpole <: DiagType end +abstract type FermiPropagator <: DiagType end +abstract type BosePropagator <: DiagType end +abstract type FermiSelfEnergy <: DiagType end +abstract type BoseSelfEnergy <: DiagType end +abstract type VertexDiag <: DiagType end +abstract type GncDiag <: DiagType end +abstract type GndDiag <: DiagType end + +@enum Filter begin + Wirreducible #remove all polarization subdiagrams + Girreducible #remove all self-energy inseration + NoHartree + NoFock + NoBubble # true to remove all bubble subdiagram + Proper #ver4, ver3, and polarization diagrams may require to be irreducible along the transfer momentum/frequency + DirectOnly # only direct interaction, this can be useful for debug purpose +end + +Base.length(r::Filter) = 1 +Base.iterate(r::Filter) = (r, nothing) +function Base.iterate(r::Filter, ::Nothing) end + +@enum Response begin + Composite + ChargeCharge + SpinSpin + ProperChargeCharge + ProperSpinSpin + UpUp + UpDown +end + +Base.length(r::Response) = 1 +Base.iterate(r::Response) = (r, nothing) +function Base.iterate(r::Response, ::Nothing) end + +@enum AnalyticProperty begin + Instant + Dynamic + D_Instant #derivative of instant interaction + D_Dynamic #derivative of the dynamic interaction +end + +Base.length(r::AnalyticProperty) = 1 +Base.iterate(r::AnalyticProperty) = (r, nothing) +function Base.iterate(r::AnalyticProperty, ::Nothing) end + +export SigmaDiag, PolarDiag, Ver3Diag, Ver4Diag, GreenDiag +export VacuumDiag, GnDiag, GcDiag +export Wirreducible, Girreducible, NoBubble, NoHartree, NoFock, Proper, DirectOnly +export Response, ChargeCharge, SpinSpin, UpUp, UpDown +export AnalyticProperty, Instant, Dynamic, D_Instant, D_Dynamic + +export DiagType +export FermiPropagator, BosePropagator, FermiSelfEnergy, BoseSelfEnergy, VertexDiag +export Vacuum, Tadpole, GncDiag, GndDiag + +include("common.jl") +export DiagPara, DiagParaF64 +export Interaction, interactionTauNum, innerTauNum + +include("common_new.jl") +export DiagramPara, DiagramParaF64 +# export Interaction, interactionTauNum, innerTauNum + +include("quantum_operator/QuantumOperators.jl") + +using .QuantumOperators +export QuantumOperators +export QuantumOperator, OperatorProduct, isfermionic +export 𝑓⁻, 𝑓⁺, 𝑓, 𝑏⁻, 𝑏⁺, 𝜙 +# export 𝑓⁻ₑ, 𝑓⁺ₑ, 𝑓ₑ, 𝑏⁻ₑ, 𝑏⁺ₑ, 𝜙ₑ +export fermionic_annihilation, fermionic_creation, majorana +export bosonic_annihilation, bosonic_creation, real_classic +export correlator_order, normal_order + + + + +include("computational_graph/ComputationalGraph.jl") +using .ComputationalGraphs +export ComputationalGraphs +export labelreset, parity +# export AbstractOperator, Prod, Sum + +export AbstractGraph, AbstractOperator +export Graph, FeynmanGraph, FeynmanProperties + +export isequiv, drop_topology, is_external, is_internal, diagram_type, orders, vertices, topology +export external_legs, external_indices, external_operators, external_labels +export multi_product, linear_combination, feynman_diagram, propagator, interaction, external_vertex +# export DiagramType, Interaction, ExternalVertex, Propagator, SelfEnergy, VertexDiag, GreenDiag, GenericDiag + +# export standardize_order! +# export reducibility, connectivity +# export 𝐺ᶠ, 𝐺ᵇ, 𝐺ᵠ, 𝑊, Green2, Interaction +# export Coupling_yukawa, Coupling_phi3, Coupling_phi4, Coupling_phi6 +export haschildren, onechild, isleaf, isbranch, ischain, isfactorless, has_zero_subfactors, eldest +export relabel!, standardize_labels!, replace_subgraph!, merge_linear_combination!, merge_multi_product!, merge_chains! +export relabel, standardize_labels, replace_subgraph, merge_linear_combination, merge_multi_product, merge_chains +export open_parenthesis, open_parenthesis!, flatten_prod!, flatten_prod, flatten_sum!, flatten_sum +export optimize!, optimize, merge_all_chains!, merge_all_linear_combinations!, remove_duplicated_leaves! + +include("TaylorSeries/TaylorSeries.jl") +using .Taylor +export Taylor + +include("diagram_tree/DiagTree.jl") +using .DiagTree +export DiagTree +export TwoBodyChannel, Alli, PHr, PHEr, PPr, AnyChan +export Permutation, Di, Ex, DiEx +export Diagram, addSubDiagram!, toDataFrame +export evalDiagNode!, evalDiagTree!, evalDiagTreeKT! +export Operator, Sum, Prod +export DiagramId, GenericId, Ver4Id, Ver3Id, GreenId, SigmaId, PolarId +export PropagatorId, BareGreenId, BareInteractionId +export BareGreenNId, BareHoppingId, GreenNId, ConnectedGreenNId +export uidreset, toDataFrame, mergeby, plot_tree + + +include("parquet_builder/parquet.jl") +using .Parquet +export Parquet +export ParquetBlocks + +include("strong_coupling_expansion_builder/strong_coupling_expansion") +using .SCE +export SCE +export Gn + +include("expression_tree/ExpressionTree.jl") +using .ExprTree +export ExprTree +export Component, ExpressionTree +# export Propagator +export addpropagator!, addnode! +export setroot!, addroot! +export evalNaive, showTree + +include("utility.jl") +using .Utility +export Utility +export taylorexpansion! + +include("frontend/frontends.jl") +using .FrontEnds +export FrontEnds +export LabelProduct + +include("frontend/GV.jl") +using .GV +export GV +export diagdictGV, diagdict_parquet, leafstates, leafstates_diagtree + +include("backend/compiler.jl") +using .Compilers +export Compilers + + +##################### precompile ####################### +# precompile as the final step of the module definition: +if ccall(:jl_generating_output, Cint, ()) == 1 # if we're precompiling the package + let + para = DiagParaF64(type=Ver4Diag, innerLoopNum=2, hasTau=true) + # ver4 = Parquet.vertex4(para) # this will force precompilation + ver4 = Parquet.build(para) # this will force precompilation + + mergeby(ver4, [:response]) + mergeby(ver4.diagram) + mergeby(ver4.diagram, [:response]; idkey=[:extT, :response]) + + para = DiagParaF64(type=SigmaDiag, innerLoopNum=2, hasTau=true) + Parquet.build(para) # this will force precompilation + para = DiagParaF64(type=GreenDiag, innerLoopNum=2, hasTau=true) + Parquet.green(para) # this will force precompilation + para = DiagParaF64(type=PolarDiag, innerLoopNum=2, hasTau=true) + # Parquet.polarization(para) # this will force precompilation + Parquet.build(para) # this will force precompilation + para = DiagParaF64(type=Ver3Diag, innerLoopNum=2, hasTau=true) + # Parquet.vertex3(para) # this will force precompilation + Parquet.build(para) # this will force precompilation + + DiagTree.removeHartreeFock!(ver4.diagram) + DiagTree.derivative(ver4.diagram, BareGreenId) + DiagTree.derivative(ver4.diagram, BareInteractionId) + # DiagTree.removeHartreeFock!(ver4.diagram) + ExprTree.build(ver4.diagram, 3) + end +end + + +end \ No newline at end of file diff --git a/src/common.jl b/archived/src/common.jl similarity index 100% rename from src/common.jl rename to archived/src/common.jl diff --git a/src/diagram_tree/DiagTree.jl b/archived/src/diagram_tree/DiagTree.jl similarity index 100% rename from src/diagram_tree/DiagTree.jl rename to archived/src/diagram_tree/DiagTree.jl diff --git a/src/diagram_tree/common.jl b/archived/src/diagram_tree/common.jl similarity index 100% rename from src/diagram_tree/common.jl rename to archived/src/diagram_tree/common.jl diff --git a/src/diagram_tree/eval.jl b/archived/src/diagram_tree/eval.jl similarity index 100% rename from src/diagram_tree/eval.jl rename to archived/src/diagram_tree/eval.jl diff --git a/src/diagram_tree/io.jl b/archived/src/diagram_tree/io.jl similarity index 100% rename from src/diagram_tree/io.jl rename to archived/src/diagram_tree/io.jl diff --git a/src/diagram_tree/operation.jl b/archived/src/diagram_tree/operation.jl similarity index 100% rename from src/diagram_tree/operation.jl rename to archived/src/diagram_tree/operation.jl diff --git a/src/diagram_tree/optimize.jl b/archived/src/diagram_tree/optimize.jl similarity index 100% rename from src/diagram_tree/optimize.jl rename to archived/src/diagram_tree/optimize.jl diff --git a/src/diagram_tree/traits.jl b/archived/src/diagram_tree/traits.jl similarity index 100% rename from src/diagram_tree/traits.jl rename to archived/src/diagram_tree/traits.jl diff --git a/src/diagram_tree/tree.jl b/archived/src/diagram_tree/tree.jl similarity index 100% rename from src/diagram_tree/tree.jl rename to archived/src/diagram_tree/tree.jl diff --git a/src/frontend/diagtree.jl b/archived/src/diagtree.jl similarity index 100% rename from src/frontend/diagtree.jl rename to archived/src/diagtree.jl diff --git a/src/expression_tree/ExpressionTree.jl b/archived/src/expression_tree/ExpressionTree.jl similarity index 100% rename from src/expression_tree/ExpressionTree.jl rename to archived/src/expression_tree/ExpressionTree.jl diff --git a/src/expression_tree/build.jl b/archived/src/expression_tree/build.jl similarity index 100% rename from src/expression_tree/build.jl rename to archived/src/expression_tree/build.jl diff --git a/src/expression_tree/common.jl b/archived/src/expression_tree/common.jl similarity index 100% rename from src/expression_tree/common.jl rename to archived/src/expression_tree/common.jl diff --git a/src/expression_tree/eval.jl b/archived/src/expression_tree/eval.jl similarity index 100% rename from src/expression_tree/eval.jl rename to archived/src/expression_tree/eval.jl diff --git a/src/expression_tree/io.jl b/archived/src/expression_tree/io.jl similarity index 100% rename from src/expression_tree/io.jl rename to archived/src/expression_tree/io.jl diff --git a/src/expression_tree/pool.jl b/archived/src/expression_tree/pool.jl similarity index 100% rename from src/expression_tree/pool.jl rename to archived/src/expression_tree/pool.jl diff --git a/src/expression_tree/tree.jl b/archived/src/expression_tree/tree.jl similarity index 100% rename from src/expression_tree/tree.jl rename to archived/src/expression_tree/tree.jl diff --git a/src/frontend/parquet.jl b/archived/src/parquet.jl similarity index 100% rename from src/frontend/parquet.jl rename to archived/src/parquet.jl diff --git a/src/parquet_builder/benchmark/benchmark.jl b/archived/src/parquet_builder/benchmark/benchmark.jl similarity index 100% rename from src/parquet_builder/benchmark/benchmark.jl rename to archived/src/parquet_builder/benchmark/benchmark.jl diff --git a/src/parquet_builder/benchmark/diagram_count.jl b/archived/src/parquet_builder/benchmark/diagram_count.jl similarity index 100% rename from src/parquet_builder/benchmark/diagram_count.jl rename to archived/src/parquet_builder/benchmark/diagram_count.jl diff --git a/src/parquet_builder/benchmark/vertex4.jl b/archived/src/parquet_builder/benchmark/vertex4.jl similarity index 100% rename from src/parquet_builder/benchmark/vertex4.jl rename to archived/src/parquet_builder/benchmark/vertex4.jl diff --git a/src/parquet_builder/benchmark/vertex4_eval.jl b/archived/src/parquet_builder/benchmark/vertex4_eval.jl similarity index 100% rename from src/parquet_builder/benchmark/vertex4_eval.jl rename to archived/src/parquet_builder/benchmark/vertex4_eval.jl diff --git a/src/parquet_builder/benchmark/vertex4_io.jl b/archived/src/parquet_builder/benchmark/vertex4_io.jl similarity index 100% rename from src/parquet_builder/benchmark/vertex4_io.jl rename to archived/src/parquet_builder/benchmark/vertex4_io.jl diff --git a/src/parquet_builder/common.jl b/archived/src/parquet_builder/common.jl similarity index 100% rename from src/parquet_builder/common.jl rename to archived/src/parquet_builder/common.jl diff --git a/src/parquet_builder/ep_coupling.jl b/archived/src/parquet_builder/ep_coupling.jl similarity index 100% rename from src/parquet_builder/ep_coupling.jl rename to archived/src/parquet_builder/ep_coupling.jl diff --git a/src/parquet_builder/filter.jl b/archived/src/parquet_builder/filter.jl similarity index 100% rename from src/parquet_builder/filter.jl rename to archived/src/parquet_builder/filter.jl diff --git a/src/parquet_builder/green.jl b/archived/src/parquet_builder/green.jl similarity index 100% rename from src/parquet_builder/green.jl rename to archived/src/parquet_builder/green.jl diff --git a/src/parquet_builder/parquet.jl b/archived/src/parquet_builder/parquet.jl similarity index 100% rename from src/parquet_builder/parquet.jl rename to archived/src/parquet_builder/parquet.jl diff --git a/src/parquet_builder/polarization.jl b/archived/src/parquet_builder/polarization.jl similarity index 100% rename from src/parquet_builder/polarization.jl rename to archived/src/parquet_builder/polarization.jl diff --git a/src/parquet_builder/sigma.jl b/archived/src/parquet_builder/sigma.jl similarity index 100% rename from src/parquet_builder/sigma.jl rename to archived/src/parquet_builder/sigma.jl diff --git a/src/parquet_builder/sigmaGV.jl b/archived/src/parquet_builder/sigmaGV.jl similarity index 100% rename from src/parquet_builder/sigmaGV.jl rename to archived/src/parquet_builder/sigmaGV.jl diff --git a/src/parquet_builder/vertex3.jl b/archived/src/parquet_builder/vertex3.jl similarity index 100% rename from src/parquet_builder/vertex3.jl rename to archived/src/parquet_builder/vertex3.jl diff --git a/src/parquet_builder/vertex4.jl b/archived/src/parquet_builder/vertex4.jl similarity index 100% rename from src/parquet_builder/vertex4.jl rename to archived/src/parquet_builder/vertex4.jl diff --git a/test/common.jl b/archived/test/common.jl similarity index 100% rename from test/common.jl rename to archived/test/common.jl diff --git a/test/diagram_tree.jl b/archived/test/diagram_tree.jl similarity index 100% rename from test/diagram_tree.jl rename to archived/test/diagram_tree.jl diff --git a/test/expression_tree.jl b/archived/test/expression_tree.jl similarity index 100% rename from test/expression_tree.jl rename to archived/test/expression_tree.jl diff --git a/test/parquet_builder.jl b/archived/test/parquet_builder.jl similarity index 100% rename from test/parquet_builder.jl rename to archived/test/parquet_builder.jl diff --git a/src/FeynmanDiagram.jl b/src/FeynmanDiagram.jl index 17d2bc6f..175b6877 100644 --- a/src/FeynmanDiagram.jl +++ b/src/FeynmanDiagram.jl @@ -5,88 +5,6 @@ macro todo() return :(error("Not yet implemented!")) end -@enum DiagramType begin - VacuumDiag #vaccum diagram for the free energy - SigmaDiag #self-energy - GreenDiag #green's function - PolarDiag #polarization - Ver3Diag #3-point vertex function - Ver4Diag #4-point vertex function - GnDiag #n-point Green's function - GcDiag #n-point connected Green's function -end -Base.length(r::DiagramType) = 1 -Base.iterate(r::DiagramType) = (r, nothing) -function Base.iterate(r::DiagramType, ::Nothing) end - -abstract type DiagType end -abstract type Vacuum <: DiagType end -abstract type Tadpole <: DiagType end -abstract type FermiPropagator <: DiagType end -abstract type BosePropagator <: DiagType end -abstract type FermiSelfEnergy <: DiagType end -abstract type BoseSelfEnergy <: DiagType end -abstract type VertexDiag <: DiagType end -abstract type GncDiag <: DiagType end -abstract type GndDiag <: DiagType end - -@enum Filter begin - Wirreducible #remove all polarization subdiagrams - Girreducible #remove all self-energy inseration - NoHartree - NoFock - NoBubble # true to remove all bubble subdiagram - Proper #ver4, ver3, and polarization diagrams may require to be irreducible along the transfer momentum/frequency - DirectOnly # only direct interaction, this can be useful for debug purpose -end - -Base.length(r::Filter) = 1 -Base.iterate(r::Filter) = (r, nothing) -function Base.iterate(r::Filter, ::Nothing) end - -@enum Response begin - Composite - ChargeCharge - SpinSpin - ProperChargeCharge - ProperSpinSpin - UpUp - UpDown -end - -Base.length(r::Response) = 1 -Base.iterate(r::Response) = (r, nothing) -function Base.iterate(r::Response, ::Nothing) end - -@enum AnalyticProperty begin - Instant - Dynamic - D_Instant #derivative of instant interaction - D_Dynamic #derivative of the dynamic interaction -end - -Base.length(r::AnalyticProperty) = 1 -Base.iterate(r::AnalyticProperty) = (r, nothing) -function Base.iterate(r::AnalyticProperty, ::Nothing) end - -export SigmaDiag, PolarDiag, Ver3Diag, Ver4Diag, GreenDiag -export VacuumDiag, GnDiag, GcDiag -export Wirreducible, Girreducible, NoBubble, NoHartree, NoFock, Proper, DirectOnly -export Response, ChargeCharge, SpinSpin, UpUp, UpDown -export AnalyticProperty, Instant, Dynamic, D_Instant, D_Dynamic - -export DiagType -export FermiPropagator, BosePropagator, FermiSelfEnergy, BoseSelfEnergy, VertexDiag -export Vacuum, Tadpole, GncDiag, GndDiag - -include("common.jl") -export DiagPara, DiagParaF64 -export Interaction, interactionTauNum, innerTauNum - -include("common_new.jl") -export DiagramPara, DiagramParaF64 -# export Interaction, interactionTauNum, innerTauNum - include("quantum_operator/QuantumOperators.jl") using .QuantumOperators @@ -98,9 +16,6 @@ export fermionic_annihilation, fermionic_creation, majorana export bosonic_annihilation, bosonic_creation, real_classic export correlator_order, normal_order - - - include("computational_graph/ComputationalGraph.jl") using .ComputationalGraphs export ComputationalGraphs @@ -129,38 +44,23 @@ include("TaylorSeries/TaylorSeries.jl") using .Taylor export Taylor -include("diagram_tree/DiagTree.jl") -using .DiagTree -export DiagTree -export TwoBodyChannel, Alli, PHr, PHEr, PPr, AnyChan -export Permutation, Di, Ex, DiEx -export Diagram, addSubDiagram!, toDataFrame -export evalDiagNode!, evalDiagTree!, evalDiagTreeKT! -export Operator, Sum, Prod -export DiagramId, GenericId, Ver4Id, Ver3Id, GreenId, SigmaId, PolarId -export PropagatorId, BareGreenId, BareInteractionId -export BareGreenNId, BareHoppingId, GreenNId, ConnectedGreenNId -export uidreset, toDataFrame, mergeby, plot_tree - - -include("parquet_builder/parquet.jl") -using .Parquet -export Parquet -export ParquetBlocks - -include("strong_coupling_expansion_builder/strong_coupling_expansion") -using .SCE -export SCE -export Gn - -include("expression_tree/ExpressionTree.jl") -using .ExprTree -export ExprTree -export Component, ExpressionTree -# export Propagator -export addpropagator!, addnode! -export setroot!, addroot! -export evalNaive, showTree +# include("diagram_tree/DiagTree.jl") +# using .DiagTree +# export DiagTree +# export TwoBodyChannel, Alli, PHr, PHEr, PPr, AnyChan +# export Permutation, Di, Ex, DiEx +# export Diagram, addSubDiagram!, toDataFrame +# export evalDiagNode!, evalDiagTree!, evalDiagTreeKT! +# export Operator, Sum, Prod +# export DiagramId, GenericId, Ver4Id, Ver3Id, GreenId, SigmaId, PolarId +# export PropagatorId, BareGreenId, BareInteractionId +# export BareGreenNId, BareHoppingId, GreenNId, ConnectedGreenNId +# export uidreset, toDataFrame, mergeby, plot_tree + +# include("strong_coupling_expansion_builder/strong_coupling_expansion") +# using .SCE +# export SCE +# export Gn include("utility.jl") using .Utility @@ -172,6 +72,23 @@ using .FrontEnds export FrontEnds export LabelProduct +include("frontend/parquet/parquet.jl") +using .Parquet +export Parquet +export ParquetBlocks +export DiagramType, VacuumDiag, SigmaDiag, GreenDiag, PolarDiag, Ver3Diag, Ver4Diag +export Filter, Wirreducible, Girreducible, NoBubble, NoHartree, NoFock, Proper, DirectOnly +export Response, Composite, ChargeCharge, SpinSpin, ProperChargeCharge, ProperSpinSpin, UpUp, UpDown +export AnalyticProperty, Instant, Dynamic, D_Instant, D_Dynamic + +export DiagPara +export Interaction, interactionTauNum, innerTauNum +export TwoBodyChannel, Alli, PHr, PHEr, PPr, AnyChan +export Permutation, Di, Ex, DiEx +export DiagramId, GenericId, Ver4Id, Ver3Id, GreenId, SigmaId, PolarId +export PropagatorId, BareGreenId, BareInteractionId +export mergeby + include("frontend/GV.jl") using .GV export GV diff --git a/src/backend/compiler.jl b/src/backend/compiler.jl index 64a3767a..95af7fb8 100644 --- a/src/backend/compiler.jl +++ b/src/backend/compiler.jl @@ -3,8 +3,8 @@ using PyCall using ..ComputationalGraphs import ..ComputationalGraphs: id, name, set_name!, operator, subgraphs, subgraph_factors, factor, FeynmanProperties -using ..DiagTree -using ..DiagTree: Diagram, PropagatorId, BareGreenId, BareInteractionId +using ..Parquet +using ..Parquet: PropagatorId, BareGreenId, BareInteractionId using ..QuantumOperators import ..QuantumOperators: isfermionic diff --git a/src/common_new.jl b/src/common_new.jl deleted file mode 100644 index a680bcd0..00000000 --- a/src/common_new.jl +++ /dev/null @@ -1,250 +0,0 @@ -# struct Interaction -# response::Response -# type::Set{AnalyticProperty} -# function Interaction(response, type) -# return new(response, Set(type)) -# end -# function Interaction(response, type::AnalyticProperty) -# return new(response, Set([type,])) -# end -# end - -# Base.isequal(a::Interaction, b::Interaction) = (a.response == b.response) && issetequal(a.type, b.type) -# Base.:(==)(a::Interaction, b::Interaction) = Base.isequal(a, b) - -# function short(inter::Interaction) -# return "$(short(inter.response))_$(reduce(*, [short(t) for t in inter.type]))" -# end - -# function short(name::Response) -# if name == ChargeCharge -# return "cc" -# elseif name == SpinSpin -# return "σσ" -# elseif name == UpUp -# return "↑↑" -# elseif name == UpDown -# return "↑↓" -# else -# @error("$name is not implemented!") -# end -# end - -# function short(type::AnalyticProperty) -# if type == Instant -# return "Ins" -# elseif type == Dynamic -# return "Dyn" -# elseif type == D_Instant -# return "dIns" -# elseif type == D_Dynamic -# return "dDyn" -# else -# @error("$type is not implemented!") -# end -# end - -# function symbol(name::Response, type::AnalyticProperty, addition=nothing) -# if isnothing(addition) -# return Symbol("$(short(name))$(short(type))") -# else -# return Symbol("$(short(name))$(short(type))$(addition)") -# end -# end - -@with_kw struct DiagramPara{W}#,T<:DiagType} - type::DataType - # type::T - innerLoopNum::Int - extNum::Int = 2 - - isFermi::Bool = true - spin::Int = 2 - # loopDim::Int = 3 - interaction::Vector{Interaction} = [Interaction(ChargeCharge, [Instant,]),] # :ChargeCharge, :SpinSpin, ... - - firstLoopIdx::Int = firstLoopIdx(type, extNum) - totalLoopNum::Int = firstLoopIdx + innerLoopNum - 1 - - #### turn the following parameters on if there is tau variables ######## - hasTau::Bool = false - firstTauIdx::Int = firstTauIdx(type, extNum) - totalTauNum::Int = firstTauIdx + innerTauNum(type, innerLoopNum, interactionTauNum(hasTau, interaction), extNum) - 1 - #if there is no imaginary-time at all, then set this number to zero! - ######################################################################## - filter::Vector{Filter} = [NoHartree,] #usually, the Hartree subdiagram should be removed - transferLoop::Vector{Float64} = [] #Set it to be the transfer momentum/frequency if you want to check the diagrams are proper or not - extra::Any = Nothing -end - -const DiagramParaF64 = DiagramPara{Float64} - -@inline interactionTauNum(para::DiagramPara) = interactionTauNum(para.hasTau, para.interaction) -@inline innerTauNum(para::DiagramPara) = innerTauNum(para.type, para.innerLoopNum, para.interactionTauNum) - -""" - Parameters.reconstruct(p::DiagramPara; kws...) - - Type-stable version of the Parameters.reconstruct -""" -function Parameters.reconstruct(::Type{DiagramPara{W}}, p::DiagramPara{W}, di) where {W} - di = !isa(di, AbstractDict) ? Dict(di) : copy(di) - get(p, di, key) = pop!(di, key, getproperty(p, key)) - return DiagramPara{W}( - # type = pop!(di, :type, p.type), - type=get(p, di, :type), - innerLoopNum=get(p, di, :innerLoopNum), - extNum=get(p, di, :extNum), - isFermi=get(p, di, :isFermi), - spin=get(p, di, :spin), - # loopDim=get(p, di, :loopDim), - interaction=get(p, di, :interaction), - firstLoopIdx=get(p, di, :firstLoopIdx), - totalLoopNum=get(p, di, :totalLoopNum), - hasTau=get(p, di, :hasTau), - firstTauIdx=get(p, di, :firstTauIdx), - totalTauNum=get(p, di, :totalTauNum), - filter=get(p, di, :filter), - transferLoop=get(p, di, :transferLoop), - extra=get(p, di, :extra) - ) - length(di) != 0 && error("Fields $(keys(di)) not in type $T") -end - -function derivepara(p::DiagramPara{W}; kwargs...) where {W} - di = !isa(kwargs, AbstractDict) ? Dict(kwargs) : copy(kwargs) - get(p, di, key) = pop!(di, key, getproperty(p, key)) - return DiagramPara{W}( - # type = pop!(di, :type, p.type), - type=get(p, di, :type), - innerLoopNum=get(p, di, :innerLoopNum), - extNum=get(p, di, :extNum), - isFermi=get(p, di, :isFermi), - spin=get(p, di, :spin), - # loopDim=get(p, di, :loopDim), - interaction=get(p, di, :interaction), - firstLoopIdx=get(p, di, :firstLoopIdx), - totalLoopNum=get(p, di, :totalLoopNum), - hasTau=get(p, di, :hasTau), - firstTauIdx=get(p, di, :firstTauIdx), - totalTauNum=get(p, di, :totalTauNum), - filter=get(p, di, :filter), - transferLoop=get(p, di, :transferLoop), - extra=get(p, di, :extra) - ) - length(di) != 0 && error("Fields $(keys(di)) not in type $T") -end - -function Base.isequal(p::DiagramPara{W}, q::DiagramPara{W}) where {W} - for field in fieldnames(typeof(p)) #fieldnames doesn't include user-defined entries in Base.getproperty - if field == :filter - if Set(p.filter) != Set(q.filter) - return false - end - elseif field == :transferLoop - if (isempty(p.transferLoop) && isempty(q.transferLoop) == false) || (isempty(p.transferLoop) == false && isempty(q.transferLoop)) - return false - elseif isempty(p.transferLoop) == false && isempty(q.transferLoop) == false - if (p.transferLoop ≈ q.transferLoop) == false - return false - end - end - elseif field == :interaction - if (p.interaction ⊆ q.interaction) == false || (q.interaction ⊆ p.interaction) == false - return false - end - else - if Base.getproperty(p, field) != Base.getproperty(q, field) - return false - end - end - end - return true -end - -Base.:(==)(a::DiagramPara{W}, b::DiagramPara{W}) where {W} = Base.isequal(a, b) - -""" - function innerTauNum(type, innerLoopNum, interactionTauNum) - - internal imaginary-time degrees of freedom for a given diagram type and internal loop number. - For the vertex functions (self-energy, polarization, vertex3, and vertex4), innerTauNum is equivalent to tauNum. - For the Green function, tauNum = innerTauNum + external tauNum -""" -function innerTauNum(type, innerLoopNum, interactionTauNum, extN) - if type == VertexDiag && extN == 4 - return (innerLoopNum + 1) * interactionTauNum - elseif type == FermiSelfEnergy - return innerLoopNum * interactionTauNum - elseif type == FermiPropagator - return innerLoopNum * interactionTauNum - elseif type == BoseSelfEnergy - return 1 + innerTauNum(VertexDiag, innerLoopNum - 1, interactionTauNum, extN) - elseif type == VertexDiag && extN == 3 - return 1 + innerTauNum(VertexDiag, innerLoopNum - 1, interactionTauNum, extN) - else - error("not implemented!") - end -end - -# function interactionTauNum(hasTau::Bool, interactionSet) -# if hasTau == false -# return 0 -# end -# for interaction in interactionSet -# if Dynamic in interaction.type || D_Dynamic in interaction.type -# return 2 -# end -# end -# return 1 -# end - -function firstTauIdx(type, extN::Int, offset::Int=0) - if type == FermiPropagator - return 3 + offset - elseif type == VertexDiag && extN == 3 - return 1 + offset - elseif type == BosePropagator - return 1 + offset - else - return 1 + offset - end -end - -function firstLoopIdx(type, extN::Int, offset::Int=0) - if type == VertexDiag && extN == 4 #three extK - return 4 + offset - elseif type == FermiSelfEnergy #one extK - return 2 + offset - elseif type == FermiPropagator #one extK - return 2 + offset - elseif type == BosePropagator #one extK - return 2 + offset - elseif type == VertexDiag && extN == 3 #two extK - return 3 + offset - else - error("not implemented!") - end -end - -function totalTauNum(type, innerLoopNum, interactionTauNum, extNum::Int, offset::Int=0) - return firstTauIdx(type, extNum, offset) + innerTauNum(type, innerLoopNum, interactionTauNum, extNum) - 1 -end - -function totalLoopNum(type, innerLoopNum, extNum::Int, offset::Int=0) - return firstLoopIdx(type, extNum, offset) + innerLoopNum - 1 -end - -# function totalTauNum(para, type::Symbol=:none) -# return para.totalTauNum -# # if type == :Ver4 -# # return (para.internalLoopNum + 1) * para.interactionTauNum -# # else -# # error("not implemented!") -# # end -# end - -# function totalLoopNum(para, type::Symbol=:none) -# return para.totalLoopNum -# end - diff --git a/src/computational_graph/feynmangraph.jl b/src/computational_graph/feynmangraph.jl index e47b544c..c33e848a 100644 --- a/src/computational_graph/feynmangraph.jl +++ b/src/computational_graph/feynmangraph.jl @@ -375,7 +375,8 @@ function linear_combination(g1::FeynmanGraph{F,W}, g2::FeynmanGraph{F,W}, c1=F(1 subgraphs[2] = g2.subgraphs[1] end - if subgraphs[1] == subgraphs[2] + if subgraphs[1].id == subgraphs[2].id + # if isequiv(subgraphs[1], subgraphs[2], :id) g = FeynmanGraph([subgraphs[1]], properties; subgraph_factors=[sum(subgraph_factors)], operator=Sum(), orders=orders(g1), ftype=F, wtype=W) else g = FeynmanGraph(subgraphs, properties; subgraph_factors=subgraph_factors, operator=Sum(), orders=orders(g1), ftype=F, wtype=W) diff --git a/src/frontend/GV.jl b/src/frontend/GV.jl index c03aaafa..9360b5b8 100644 --- a/src/frontend/GV.jl +++ b/src/frontend/GV.jl @@ -6,46 +6,23 @@ import ..ComputationalGraphs: FeynmanGraph import ..ComputationalGraphs: Graph import ..ComputationalGraphs: _dtype import ..Parquet +import ..Parquet: Filter, NoBubble, NoHartree, NoFock, DirectOnly +import ..Parquet: Wirreducible #remove all polarization subdiagrams +import ..Parquet: Girreducible #remove all self-energy inseration +import ..Parquet: NoBubble # true to remove all bubble subdiagram +import ..Parquet: Proper #ver4, ver3, and polarization diagrams may require to be irreducible along the transfer momentum/frequency +import ..Parquet: Response, Composite, ChargeCharge, SpinSpin, UpUp, UpDown +import ..Parquet: AnalyticProperty, Instant, Dynamic, D_Instant, D_Dynamic +import ..Parquet: DiagramType, VacuumDiag, SigmaDiag, GreenDiag, PolarDiag, Ver3Diag, Ver4Diag import ..Taylor -using ..DiagTree +# using ..DiagTree using ..FrontEnds using AbstractTrees import ..Utility: taylorexpansion! -import ..Filter -import ..Wirreducible #remove all polarization subdiagrams -import ..Girreducible #remove all self-energy inseration -import ..NoHartree -import ..NoFock -import ..NoBubble # true to remove all bubble subdiagram -import ..Proper #ver4, ver3, and polarization diagrams may require to be irreducible along the transfer momentum/frequency -import ..DirectOnly - -import ..DiagramType -import ..VacuumDiag -import ..GreenDiag -import ..SigmaDiag -import ..PolarDiag -import ..Ver3Diag -import ..Ver4Diag - -import ..Composite -import ..ChargeCharge -import ..SpinSpin -import ..UpUp -import ..UpDown -import ..Response - -import ..Instant -import ..Dynamic -import ..D_Instant -import ..D_Dynamic -import ..AnalyticProperty - import ..Interaction import ..DiagPara -import ..DiagParaF64 import ..DiagramId import ..Ver4Id @@ -274,7 +251,7 @@ function diagdict_parquet(type::Symbol, MaxOrder::Int, has_counterterm::Bool=tru for order in MinOrder:MaxOrder Taylor.set_variables("x y"; orders=[MaxOrder - order, MaxOrder - order]) para = diagPara(diagtype, isDynamic, spin, order, filter, transferLoop) - # legK = [DiagTree.getK(para.totalLoopNum + 3, 1), DiagTree.getK(para.totalLoopNum + 3, 2), DiagTree.getK(para.totalLoopNum + 3, 3)] + # legK = [Parquet.getK(para.totalLoopNum + 3, 1), Parquet.getK(para.totalLoopNum + 3, 2), Parquet.getK(para.totalLoopNum + 3, 3)] # d::Vector{Diagram{Float64}} = Parquet.vertex4(para, legK, channel).diagram # diags::Vector{Diagram{Float64}} = Parquet.build(para).diagram parquet_builder = Parquet.build(para) @@ -443,7 +420,7 @@ function diagPara(type, isDynamic::Bool, spin, order, filter, transferLoop=nothi end if isnothing(transferLoop) - return DiagParaF64( + return DiagPara( type=type, innerLoopNum=innerLoopNum, hasTau=true, @@ -452,7 +429,7 @@ function diagPara(type, isDynamic::Bool, spin, order, filter, transferLoop=nothi filter=filter, ) else - return DiagParaF64( + return DiagPara( type=type, innerLoopNum=innerLoopNum, hasTau=true, @@ -608,7 +585,7 @@ function leafstates_diagtree(leaf_maps::Vector{Dict{Int,Graph}}, maxloopNum::Int push!(leafOutTau[ikey], diagId.extT[2]) push!(leafOrders[ikey], leaf_orders) - push!(leafType[ikey], DiagTree.index(typeof(diagId))) + push!(leafType[ikey], Parquet.index(typeof(diagId))) end end diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_0.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_0.diag new file mode 100644 index 00000000..a6ef92f3 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_0.diag @@ -0,0 +1,32 @@ +#Type: SelfEnergy +#DiagNum: 1 +#Order: 2 +#GNum: 4 +#Ver4Num: 2 +#LoopNum: 3 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 2 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_1.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_1.diag new file mode 100644 index 00000000..f3877e19 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_1.diag @@ -0,0 +1,72 @@ +#Type: SelfEnergy +#DiagNum: 3 +#Order: 2 +#GNum: 4 +#Ver4Num: 2 +#LoopNum: 3 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 2 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 1 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_2.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_2.diag new file mode 100644 index 00000000..13a29262 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_0_2.diag @@ -0,0 +1,132 @@ +#Type: SelfEnergy +#DiagNum: 6 +#Order: 2 +#GNum: 4 +#Ver4Num: 2 +#LoopNum: 3 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 2 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 2 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 1 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 1 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 0 0 | +# SpinFactor +-2 1 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_1_0.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_1_0.diag new file mode 100644 index 00000000..8518b8e9 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_1_0.diag @@ -0,0 +1,52 @@ +#Type: SelfEnergy +#DiagNum: 2 +#Order: 2 +#GNum: 4 +#Ver4Num: 2 +#LoopNum: 3 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 2 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 1 1 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 1 1 | 0 0 | +# SpinFactor +-2 1 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_1_1.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_1_1.diag new file mode 100644 index 00000000..f4459f16 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_1_1.diag @@ -0,0 +1,132 @@ +#Type: SelfEnergy +#DiagNum: 6 +#Order: 2 +#GNum: 4 +#Ver4Num: 2 +#LoopNum: 3 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 2 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 1 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 1 1 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 1 1 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 1 1 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 1 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 1 1 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 1 1 | 0 0 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 1 1 | 0 0 | +# SpinFactor +-2 1 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_2_0.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_2_0.diag new file mode 100644 index 00000000..9c6dd4a3 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex2_2_0.diag @@ -0,0 +1,72 @@ +#Type: SelfEnergy +#DiagNum: 3 +#Order: 2 +#GNum: 4 +#Ver4Num: 2 +#LoopNum: 3 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 2 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 0 0 | 2 2 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 1 1 | 1 1 | +# SpinFactor +-2 1 + +# Permutation + 3 2 1 0 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 +# VertexBasis + 0 0 1 1 + 1 1 0 0 +# LoopBasis + 1 0 1 0 + 0 1 1 0 + 1 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 0 3 | +# WType(Direct,Exchange) + 2 2 | 0 0 | +# SpinFactor +-2 1 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_0_0.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_0_0.diag new file mode 100644 index 00000000..9dd8a407 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_0_0.diag @@ -0,0 +1,138 @@ +#Type: SelfEnergy +#DiagNum: 6 +#Order: 3 +#GNum: 6 +#Ver4Num: 3 +#LoopNum: 4 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 3 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_0_1.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_0_1.diag new file mode 100644 index 00000000..d1cf5a3f --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_0_1.diag @@ -0,0 +1,642 @@ +#Type: SelfEnergy +#DiagNum: 30 +#Order: 3 +#GNum: 6 +#Ver4Num: 3 +#LoopNum: 4 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 3 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 1 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 1 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 1 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 1 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 1 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 1 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 1 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 1 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 1 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 1 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 1 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 1 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 1 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 1 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 1 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_1_0.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_1_0.diag new file mode 100644 index 00000000..c517fdf3 --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex3_1_0.diag @@ -0,0 +1,390 @@ +#Type: SelfEnergy +#DiagNum: 18 +#Order: 3 +#GNum: 6 +#Ver4Num: 3 +#LoopNum: 4 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 3 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 1 1 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 1 1 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 1 1 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 1 1 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 1 1 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 1 1 | +# SpinFactor +-2 1 1 -2 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 1 1 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 0 0 | 1 1 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 0 0 | 1 1 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 1 1 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 0 0 | 1 1 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 0 0 | 1 1 | 0 0 | +# SpinFactor +-2 1 1 -2 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 1 0 + 0 0 1 0 0 0 + 0 1 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 1 1 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 3 5 4 0 2 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 2 0 1 0 +# LoopBasis + 1 0 1 0 1 0 + 0 1 1 0 0 0 + 0 0 0 1 1 0 + 1 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 0 3 | 2 4 1 5 | +# WType(Direct,Exchange) + 1 1 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 + +# Permutation + 2 4 0 1 3 5 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 2 0 0 1 2 +# LoopBasis + 1 0 0 1 0 0 + 1 0 1 0 0 0 + 0 1 0 1 1 0 + 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 5 5 | +# WType(Direct,Exchange) + 1 1 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 5 3 0 1 4 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 1 0 0 2 1 +# LoopBasis + 1 0 0 1 0 1 + 0 0 1 0 0 0 + 1 0 0 1 1 0 + 0 1 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 1 3 | 4 4 0 5 | +# WType(Direct,Exchange) + 1 1 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 + +# Permutation + 3 2 0 1 5 4 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 1 1 0 0 2 2 +# LoopBasis + 1 0 0 0 0 1 + 0 1 0 0 -1 1 + 0 0 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 4 5 | +# WType(Direct,Exchange) + 1 1 | 0 0 | 0 0 | +# SpinFactor +-2 0 4 0 + +# Permutation + 5 4 0 1 3 2 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 +# VertexBasis + 0 0 1 1 2 2 + 2 2 0 0 1 1 +# LoopBasis + 1 0 0 1 1 0 + 0 0 0 0 -1 1 + 0 1 0 1 1 0 + 1 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 0 5 | +# WType(Direct,Exchange) + 1 1 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 + diff --git a/src/frontend/GV_diagrams/groups_vertex4/4Vertex4_0_0.diag b/src/frontend/GV_diagrams/groups_vertex4/4Vertex4_0_0.diag new file mode 100644 index 00000000..ce9af15d --- /dev/null +++ b/src/frontend/GV_diagrams/groups_vertex4/4Vertex4_0_0.diag @@ -0,0 +1,870 @@ +#Type: SelfEnergy +#DiagNum: 39 +#Order: 4 +#GNum: 8 +#Ver4Num: 4 +#LoopNum: 5 +#ExtLoopIndex: 0 +#DummyLoopIndex: +#TauNum: 4 +#ExtTauIndex: 0 2 +#DummyTauIndex: + +# Permutation + 2 3 0 1 7 6 5 4 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 1 0 0 3 3 2 2 +# LoopBasis + 1 0 0 1 0 1 0 1 + 1 0 1 0 0 0 0 0 + 0 0 0 1 1 0 0 0 + 0 0 0 0 0 1 1 0 + 0 1 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 1 3 | 7 4 6 5 | 5 6 4 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-8 4 4 -8 4 -2 -2 4 + +# Permutation + 6 5 4 0 2 1 3 7 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 3 2 2 0 1 0 1 3 +# LoopBasis + 1 0 1 0 1 0 1 0 + 0 1 1 0 0 0 0 0 + 0 0 0 1 1 0 0 0 + 1 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 6 3 | 2 4 1 5 | 0 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 4 0 -2 0 -2 0 1 + +# Permutation + 2 4 0 1 3 6 5 7 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 1 3 2 3 +# LoopBasis + 1 0 0 1 1 0 0 0 + 1 0 1 0 0 0 0 0 + 0 1 0 1 1 0 0 0 + 0 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 6 5 | 5 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 4 0 -2 0 -2 0 1 + +# Permutation + 5 6 0 1 4 2 3 7 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 3 0 0 2 1 1 3 +# LoopBasis + 1 0 0 1 0 1 0 0 + 0 0 1 0 0 0 0 0 + 1 0 0 1 1 0 0 0 + 0 1 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 6 3 | 4 4 0 5 | 1 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 0 0 -2 0 0 0 1 + +# Permutation + 6 5 0 1 4 3 2 7 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 3 2 0 0 2 1 1 3 +# LoopBasis + 1 0 0 1 0 1 1 0 + 0 0 1 0 0 0 0 0 + 1 0 0 1 1 0 0 0 + 0 1 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 6 2 5 3 | 4 4 1 5 | 0 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 0 4 -2 0 0 -2 1 + +# Permutation + 4 2 1 0 3 6 5 7 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 1 3 2 3 +# LoopBasis + 1 0 1 0 1 0 0 0 + 0 1 1 0 0 0 0 0 + 1 0 0 1 1 0 0 0 + 0 0 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 1 2 4 3 | 0 4 6 5 | 5 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 0 0 -2 0 0 0 1 + +# Permutation + 2 4 0 1 3 6 5 7 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 1 3 2 3 +# LoopBasis + 1 0 0 1 1 0 1 0 + 0 0 1 0 0 0 0 0 + 0 1 0 1 1 0 0 0 + 0 0 0 0 0 1 1 0 + 1 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 6 5 | 5 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-8 4 4 -2 4 -2 -2 1 + +# Permutation + 2 6 0 1 5 4 3 7 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 3 0 0 2 2 1 3 +# LoopBasis + 1 0 0 1 0 1 0 0 + 1 0 1 0 0 0 0 0 + 0 0 0 1 1 0 0 0 + 0 1 0 0 0 1 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 6 3 | 5 4 4 5 | 1 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 4 0 0 0 -2 0 0 + +# Permutation + 2 5 0 1 6 3 4 7 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 3 1 2 3 +# LoopBasis + 1 0 0 0 0 0 1 0 + 0 0 1 0 0 0 0 0 + 0 0 0 1 1 0 0 0 + 0 1 0 0 0 1 1 0 + 1 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 5 3 | 6 4 1 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-8 4 4 -2 4 -2 -2 1 + +# Permutation + 3 2 0 1 6 4 5 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 1 0 0 3 2 2 3 +# LoopBasis + 1 0 0 0 1 0 0 0 + 0 -1 0 0 -1 1 0 0 + 1 1 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 6 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 8 -4 8 -4 -16 8 + +# Permutation + 4 6 1 0 3 2 5 7 +# SymFactor +0.5 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 3 0 0 1 1 2 3 +# LoopBasis + 1 0 1 0 0 1 0 0 + 0 0 0 0 -1 1 0 0 + 1 0 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 2 1 | 5 2 4 3 | 0 4 6 5 | 1 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 0 -1 0 2 + +# Permutation + 4 3 0 1 2 7 5 6 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 1 3 2 3 +# LoopBasis + 1 0 1 0 0 1 0 1 + 0 0 0 0 -1 1 0 0 + 1 0 0 1 1 0 0 0 + 0 0 1 0 1 0 1 0 + 0 1 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 4 2 1 3 | 0 4 6 5 | 7 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 8 2 -4 2 -4 -1 2 + +# Permutation + 5 6 4 0 2 1 3 7 +# SymFactor +1.0 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 3 2 0 1 0 1 3 +# LoopBasis + 1 0 1 0 0 0 0 0 + 1 0 0 0 -1 1 0 0 + 0 0 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 6 3 | 2 4 0 5 | 1 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 0 -1 0 2 + +# Permutation + 3 2 0 1 6 4 5 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 1 0 0 3 2 2 3 +# LoopBasis + 1 0 0 1 0 0 0 0 +-1 0 0 0 -1 1 0 0 + 1 1 0 1 1 0 0 0 + 1 0 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 0 3 | 5 4 6 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 8 -4 8 -4 -16 8 + +# Permutation + 2 7 0 1 5 4 3 6 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 3 0 0 2 2 1 3 +# LoopBasis + 1 0 0 0 0 1 1 0 + 0 1 0 0 -1 1 0 0 + 0 0 0 1 1 0 0 0 + 0 0 1 0 1 0 1 0 + 1 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 6 3 | 5 4 4 5 | 7 6 1 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 8 0 0 2 -4 0 0 + +# Permutation + 2 5 0 1 6 7 4 3 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 3 3 2 1 +# LoopBasis + 1 0 0 0 0 0 1 0 + 0 0 0 0 -1 1 0 0 + 0 0 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 1 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 7 3 | 6 4 1 5 | 4 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -4 2 -1 -1 2 + +# Permutation + 5 4 0 1 6 2 3 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 2 0 0 3 1 1 3 +# LoopBasis + 1 0 1 0 0 1 1 0 +-1 1 0 0 -1 1 0 0 + 1 0 0 1 1 0 0 0 + 1 0 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 6 3 | 1 4 0 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 0 0 0 0 + +# Permutation + 2 4 0 1 3 7 5 6 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 1 3 2 3 +# LoopBasis + 1 0 0 1 1 0 1 0 + 0 0 0 0 -1 1 0 0 + 0 1 0 1 1 0 0 0 + 0 0 1 0 1 0 1 0 + 1 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 4 3 | 1 4 6 5 | 7 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 8 2 -4 2 -4 -1 2 + +# Permutation + 4 5 0 1 2 6 3 7 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 2 0 0 1 3 1 3 +# LoopBasis + 1 0 1 0 0 1 1 0 + 0 0 0 0 -1 1 0 0 + 1 0 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 4 2 6 3 | 0 4 1 5 | 5 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 0 0 0 0 + +# Permutation + 5 2 0 1 6 3 4 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 3 1 2 3 +# LoopBasis + 1 0 1 0 0 0 1 0 + 1 0 0 0 -1 1 0 0 + 0 0 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 5 3 | 6 4 0 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 8 -4 -4 2 + +# Permutation + 7 3 0 1 6 4 5 2 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 3 1 0 0 3 2 2 1 +# LoopBasis + 1 0 1 0 0 0 0 1 +-1 0 0 0 -1 1 0 0 + 1 0 0 1 1 0 0 0 + 1 0 1 0 1 0 1 0 + 0 1 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 7 2 1 3 | 5 4 6 5 | 4 6 0 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 8 -4 2 -1 -4 2 + +# Permutation + 5 3 0 1 7 6 2 4 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 3 3 1 2 +# LoopBasis + 1 0 1 0 1 0 0 1 + 0 0 0 0 -1 1 0 0 + 0 0 0 1 1 0 0 0 + 1 0 1 0 1 0 1 0 + 0 1 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 6 2 1 3 | 7 4 0 5 | 5 6 4 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 0 0 0 0 0 0 0 + +# Permutation + 6 4 0 1 3 2 5 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 3 2 0 0 1 1 2 3 +# LoopBasis + 1 0 0 0 1 0 1 0 + 0 -1 0 0 -1 1 0 0 + 0 1 0 1 1 0 0 0 + 1 1 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 6 5 | 0 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 0 -1 0 2 + +# Permutation + 3 6 4 0 2 7 5 1 +# SymFactor +0.5 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 3 2 0 1 3 2 0 +# LoopBasis + 1 0 1 0 1 0 1 0 + 0 0 0 0 -1 1 0 0 + 0 0 0 1 1 0 0 0 + 0 1 1 0 1 0 1 0 + 1 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 7 1 | 4 2 0 3 | 2 4 6 5 | 1 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 8 2 -4 2 -4 -1 2 + +# Permutation + 6 4 0 1 3 2 5 7 +# SymFactor +0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 3 2 0 0 1 1 2 3 +# LoopBasis + 1 0 0 1 1 0 1 0 + 0 0 0 0 -1 1 0 0 + 0 1 0 1 1 0 0 0 + 1 0 1 0 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 5 2 4 3 | 1 4 6 5 | 0 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 -1 0 -1 0 2 + +# Permutation + 4 3 0 1 7 5 2 6 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 3 2 1 3 +# LoopBasis + 1 0 0 1 1 0 0 1 + 0 0 1 0 0 0 0 0 + 1 0 0 0 0 1 0 0 + 0 0 0 1 1 0 1 0 + 0 1 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 6 2 1 3 | 0 4 5 5 | 7 6 4 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 8 2 -4 2 -4 -1 2 + +# Permutation + 2 4 0 1 6 3 5 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 3 1 2 3 +# LoopBasis + 1 0 0 1 1 0 1 0 + 1 0 1 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 1 0 1 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 5 3 | 1 4 6 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 2 0 0 0 -1 0 0 + +# Permutation + 4 5 6 0 2 1 3 7 +# SymFactor +1.0 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 2 3 0 1 0 1 3 +# LoopBasis + 1 0 1 0 1 0 0 0 + 0 1 1 0 0 0 0 0 + 1 0 0 0 0 1 0 0 + 0 0 0 1 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 5 1 | 4 2 6 3 | 0 4 1 5 | 2 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 8 -4 -4 2 + +# Permutation + 3 4 0 1 6 5 2 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 3 2 1 3 +# LoopBasis + 1 0 0 0 1 0 0 0 + 0 0 1 0 0 0 0 0 + 1 0 0 0 0 1 0 0 + 0 1 0 1 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 6 2 0 3 | 1 4 5 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 2 -1 8 -4 -4 2 + +# Permutation + 5 2 0 1 4 6 3 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 2 3 1 3 +# LoopBasis + 1 0 0 1 0 1 1 0 + 0 0 1 0 0 0 0 0 + 0 1 0 0 0 1 0 0 + 1 0 0 1 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 6 3 | 4 4 0 5 | 5 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor + 0 0 2 -1 0 0 -4 2 + +# Permutation + 2 5 0 1 6 4 3 7 +# SymFactor +1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 3 2 1 3 +# LoopBasis + 1 0 0 1 0 0 1 0 + 1 0 1 0 0 0 0 0 + 0 0 0 0 0 1 0 0 + 0 1 0 1 1 0 1 0 + 0 0 0 0 0 0 0 1 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 0 2 6 3 | 5 4 1 5 | 4 6 7 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-4 2 0 0 2 -1 0 0 + +# Permutation + 7 2 0 1 6 4 5 3 +# SymFactor +-0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 3 1 0 0 3 2 2 1 +# LoopBasis + 1 0 1 0 0 0 0 1 +-1 0 0 0 -1 1 0 0 + 1 1 1 0 1 0 0 1 + 1 0 1 0 1 0 1 0 + 0 0 -1 1 0 0 0 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 7 3 | 5 4 6 5 | 4 6 0 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 4 -2 4 -2 -8 4 + +# Permutation + 5 4 0 1 7 6 2 3 +# SymFactor +-0.25 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 2 0 0 3 3 1 1 +# LoopBasis + 1 0 1 0 1 0 0 1 + 0 0 0 0 -1 1 0 0 + 0 1 1 0 1 0 0 1 + 1 0 1 0 1 0 1 0 + 0 0 -1 1 0 0 0 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 6 2 7 3 | 1 4 0 5 | 5 6 4 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 1 -2 -2 1 + +# Permutation + 3 4 0 1 2 7 5 6 +# SymFactor +-0.5 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 2 0 0 1 3 2 3 +# LoopBasis + 1 0 0 0 1 0 0 0 + 0 -1 0 0 -1 1 0 0 + 1 1 1 0 1 0 0 1 + 0 1 1 0 1 0 1 0 + 0 0 -1 1 0 0 0 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 4 2 0 3 | 1 4 6 5 | 7 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 4 1 -2 4 -8 -2 4 + +# Permutation + 3 7 0 1 6 4 5 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 3 0 0 3 2 2 1 +# LoopBasis + 1 0 0 0 1 0 0 0 + 0 0 0 0 0 1 1 -1 + 1 0 0 1 0 0 -1 1 + 0 0 1 0 0 0 0 1 + 0 1 0 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 7 2 0 3 | 5 4 6 5 | 4 6 1 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 4 -2 4 -2 -8 4 + +# Permutation + 5 7 0 1 3 6 2 4 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 3 0 0 1 3 1 2 +# LoopBasis + 1 0 0 0 1 0 0 1 + 1 -1 0 0 0 1 1 -1 +-1 1 0 1 0 0 -1 1 + 0 1 1 0 0 0 0 1 + 1 0 0 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 6 2 4 3 | 7 4 0 5 | 5 6 1 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 1 -2 -2 4 + +# Permutation + 4 5 0 1 7 6 3 2 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 2 0 0 3 3 1 1 +# LoopBasis + 1 0 1 0 0 1 1 0 + 0 1 0 0 0 1 1 -1 + 1 -1 0 1 0 0 -1 1 + 0 0 1 0 0 0 0 1 + 0 1 0 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 7 2 6 3 | 0 4 1 5 | 5 6 4 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 1 1 -2 1 -2 -2 1 + +# Permutation + 2 6 4 0 3 7 5 1 +# SymFactor +-1.0 +# GType +-2 -2 0 -2 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 1 3 2 0 1 3 2 0 +# LoopBasis + 1 0 1 0 0 0 0 0 +-1 0 0 0 0 1 1 -1 + 1 0 0 1 0 0 -1 1 + 1 1 1 0 0 0 0 1 + 0 0 0 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 3 0 7 1 | 0 2 4 3 | 2 4 6 5 | 1 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 4 1 -2 4 -8 -2 4 + +# Permutation + 4 2 0 1 3 7 5 6 +# SymFactor +-1.0 +# GType +-2 -2 -2 0 0 0 0 0 +# VertexBasis + 0 0 1 1 2 2 3 3 + 2 1 0 0 1 3 2 3 +# LoopBasis + 1 0 1 0 0 1 0 1 + 0 -1 0 0 0 1 1 -1 + 1 1 0 1 0 0 -1 1 + 0 1 1 0 0 0 0 1 + 0 0 0 0 1 0 1 0 +# Ver4Legs(InL,OutL,InR,OutR) + 2 0 3 1 | 1 2 4 3 | 0 4 6 5 | 7 6 5 7 | +# WType(Direct,Exchange) + 0 0 | 0 0 | 0 0 | 0 0 | +# SpinFactor +-2 4 1 -2 4 -8 -2 4 + diff --git a/src/frontend/GV_diagrams/main_vertex4.py b/src/frontend/GV_diagrams/main_vertex4.py index 2f88bc30..cf91542a 100644 --- a/src/frontend/GV_diagrams/main_vertex4.py +++ b/src/frontend/GV_diagrams/main_vertex4.py @@ -76,7 +76,7 @@ def Generate(Order, VerOrder, SigmaOrder, SPIN): if __name__ == "__main__": # print "Input Diagram Order: " # Order = int(sys.argv[1]) - Order = 6 + Order = 4 SPIN = 2 for o in range(2, Order+1): for v in range(0, Order): diff --git a/src/frontend/GV_diagrams/vertex4.py b/src/frontend/GV_diagrams/vertex4.py index 95b1bb72..87c89641 100644 --- a/src/frontend/GV_diagrams/vertex4.py +++ b/src/frontend/GV_diagrams/vertex4.py @@ -60,7 +60,7 @@ def ToString(self, PolarHugenList, VerOrder, SigmaOrder, SPIN): for FeynPermu in FeynList: if (FeynPermu[0] == 1 or FeynPermu[1] == 0 or self.__IsHartree(FeynPermu, Diag.LoopBasis, vertype, gtype) or - self.__IsTwoParticleReducible(FeynPermu, Diag.LoopBasis)): + self.__IsReducible(FeynPermu, Diag.LoopBasis, vertype, gtype) or self.__IsTwoParticleReducible(FeynPermu, Diag.LoopBasis)): FactorList.append(0) else: FactorList.append(1) @@ -98,30 +98,30 @@ def ToString(self, PolarHugenList, VerOrder, SigmaOrder, SPIN): # print "newPermu: {0}".format(Permutation) # print Diag.LoopBasis - loopBasis = np.copy(Diag.LoopBasis) - gtype_temp = np.copy(GType) - if len(swap_ver) > 0: - loopBasis[:, swap_ver[0]], loopBasis[:, 2] = Diag.LoopBasis[:,2], Diag.LoopBasis[:, swap_ver[0]] - GType[swap_ver[0]], GType[2] = gtype_temp[2], gtype_temp[swap_ver[0]] - if swap_ver[1] != 2: - loopBasis[:, swap_ver[1]], loopBasis[:, 3] = Diag.LoopBasis[:,3], Diag.LoopBasis[:, swap_ver[1]] - GType[swap_ver[1]], GType[3] = gtype_temp[3], gtype_temp[swap_ver[1]] - if jp_0 >= 2: - locs_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,2]))[0] - loc_extloop=locs_extloop[0] - # loc_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,2]))[0][0] - else: - # loc_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,1]))[0][0] - locs_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,1]))[0] - loc_extloop=locs_extloop[0] - if len(locs_extloop)>1: - print yellow("{0}".format(loopBasis)) - for loc in locs_extloop[1:]: - if loopBasis[loc, 0] == loopBasis[loc_extloop, 0]: - loopBasis[loc, :] = loopBasis[loc, :] - loopBasis[loc_extloop, :] - else: - loopBasis[loc, :] = loopBasis[loc, :] + loopBasis[loc_extloop, :] - print blue("{0}".format(loopBasis)) + # loopBasis = np.copy(Diag.LoopBasis) + # gtype_temp = np.copy(GType) + # if len(swap_ver) > 0: + # loopBasis[:, swap_ver[0]], loopBasis[:, 2] = Diag.LoopBasis[:,2], Diag.LoopBasis[:, swap_ver[0]] + # GType[swap_ver[0]], GType[2] = gtype_temp[2], gtype_temp[swap_ver[0]] + # if swap_ver[1] != 2: + # loopBasis[:, swap_ver[1]], loopBasis[:, 3] = Diag.LoopBasis[:,3], Diag.LoopBasis[:, swap_ver[1]] + # GType[swap_ver[1]], GType[3] = gtype_temp[3], gtype_temp[swap_ver[1]] + # if jp_0 >= 2: + # locs_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,2]))[0] + # loc_extloop=locs_extloop[0] + # # loc_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,2]))[0][0] + # else: + # # loc_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,1]))[0][0] + # locs_extloop = np.where(abs(loopBasis[:, 0]) == 1 & (loopBasis[:, 0] == loopBasis[:,1]))[0] + # loc_extloop=locs_extloop[0] + # if len(locs_extloop)>1: + # print yellow("{0}".format(loopBasis)) + # for loc in locs_extloop[1:]: + # if loopBasis[loc, 0] == loopBasis[loc_extloop, 0]: + # loopBasis[loc, :] = loopBasis[loc, :] - loopBasis[loc_extloop, :] + # else: + # loopBasis[loc, :] = loopBasis[loc, :] + loopBasis[loc_extloop, :] + # print blue("{0}".format(loopBasis)) print "Save {0}".format(Permutation) @@ -134,7 +134,7 @@ def ToString(self, PolarHugenList, VerOrder, SigmaOrder, SPIN): Body += "# GType\n" for i in range(self.GNum): - if Permutation[i] == 0: + if Permutation[i] == 0 or i == 0 or i == 1: Body += "{0:2d} ".format(-2) else: Body += "{0:2d} ".format(GType[i]) @@ -151,18 +151,19 @@ def ToString(self, PolarHugenList, VerOrder, SigmaOrder, SPIN): Body += "# LoopBasis\n" - basis_temp = np.copy(loopBasis) - if loc_extloop > 0: - if loopBasis[loc_extloop, 0] == 1: - basis_temp[0, :] = loopBasis[loc_extloop, :] - else: - basis_temp[0, :] = -loopBasis[loc_extloop, :] - basis_temp[loc_extloop:-1, :] = loopBasis[loc_extloop+1:, :] - basis_temp[-1, :] = loopBasis[0, :] + # basis_temp = np.copy(loopBasis) + # if loc_extloop > 0: + # if loopBasis[loc_extloop, 0] == 1: + # basis_temp[0, :] = loopBasis[loc_extloop, :] + # else: + # basis_temp[0, :] = -loopBasis[loc_extloop, :] + # basis_temp[loc_extloop:-1, :] = loopBasis[loc_extloop+1:, :] + # basis_temp[-1, :] = loopBasis[0, :] # print yellow("{0}".format(loc_extloop)) for i in range(self.LoopNum): for j in range(self.GNum): - Body += "{0:2d} ".format(basis_temp[i, j]) + # Body += "{0:2d} ".format(basis_temp[i, j]) + Body += "{0:2d} ".format(Mom[i, j]) Body += "\n" # print basis_temp @@ -190,7 +191,8 @@ def ToString(self, PolarHugenList, VerOrder, SigmaOrder, SPIN): FactorList = [] for idx, FeynPermu in enumerate(FeynList): - if self.__IsHartree(FeynPermu, basis_temp, vertype, gtype): + # if self.__IsHartree(FeynPermu, basis_temp, vertype, gtype): + if self.__IsHartree(FeynPermu, Mom, vertype, gtype): prefactor = 0 else: prefactor = 1 diff --git a/src/frontend/frontends.jl b/src/frontend/frontends.jl index a80e258b..96cb22e3 100644 --- a/src/frontend/frontends.jl +++ b/src/frontend/frontends.jl @@ -8,21 +8,14 @@ import ..ComputationalGraphs: FeynmanGraph import ..ComputationalGraphs: Graph import ..ComputationalGraphs: _dtype -using ..DiagTree - include("pool.jl") export LoopPool include("LabelProduct.jl") export LabelProduct -# include("parquet.jl") +# include("parquet/parquet.jl") # using .Parquet # export Parquet -include("diagtree.jl") - -include("parquet/parquet.jl") -using .Parquet - end \ No newline at end of file diff --git a/src/frontend/parquet/benchmark/benchmark.jl b/src/frontend/parquet/benchmark/benchmark.jl new file mode 100644 index 00000000..5aa5cdbc --- /dev/null +++ b/src/frontend/parquet/benchmark/benchmark.jl @@ -0,0 +1,24 @@ +module Benchmark +using StaticArrays, PyCall +using AbstractTrees +using Parameters, Combinatorics + +import ..DiagPara +import ..interactionTauNum + +const DI, EX = 1, 2 +const INL, OUTL, INR, OUTR = 1, 2, 3, 4 +# orginal diagrams T, U, S; particle-hole counterterm Ts, Us; and their counterterm Tc, Uc, Sc, Tsc, Usc +const I, T, U, S, Ts, Us, Ic, Tc, Uc, Sc, Tsc, Usc = 1:12 +# const ChanName = ["I", "T", "U", "S", "Ts", "Us", "Ic", "Tc", "Uc", "Sc", "Tsc", "Usc"] +const SymFactor = [1.0, -1.0, 1.0, -0.5, +1.0, -1.0] + +# const Fchan = [I, U, S, Ts, Us, Ic, Uc, Sc, Tsc, Usc] +# const Vchan = [I, T, U, Ts, Us, Ic, Tc, Uc, Sc, Tsc, Usc] +# const Allchan = [I, T, U, S, Ts, Us, Ic, Tc, Uc, Sc, Tsc, Usc] + +include("vertex4.jl") +include("vertex4_eval.jl") +include("vertex4_io.jl") +include("diagram_count.jl") +end \ No newline at end of file diff --git a/src/frontend/parquet/benchmark/diagram_count.jl b/src/frontend/parquet/benchmark/diagram_count.jl new file mode 100644 index 00000000..2153c054 --- /dev/null +++ b/src/frontend/parquet/benchmark/diagram_count.jl @@ -0,0 +1,124 @@ +""" Count diagram numbers +see Ref. https://arxiv.org/pdf/cond-mat/0512342.pdf for details +We assume: +1. interaction is spin-symmetric. +2. the propagator conserves the spin. +""" + +function count_ver3_g2v(innerLoopNum, spin) + @assert innerLoopNum >= 0 + if innerLoopNum == 0 + return 1 + elseif innerLoopNum == 1 + return 1 + elseif innerLoopNum == 2 + return 3 * (2 + spin) + elseif innerLoopNum == 3 + return 5 * (10 + 9 * spin + spin^2) + else + error("not implemented!") + end +end + +function count_ver3_G2v(innerLoopNum, spin) + @assert innerLoopNum >= 0 + if innerLoopNum == 0 + return 1 + elseif innerLoopNum == 1 + return 1 + elseif innerLoopNum == 2 + return 4 + 3 * spin + elseif innerLoopNum == 3 + return 27 + 31 * spin + 5 * spin^2 + else + error("not implemented!") + end +end + +function count_ver3_G2W(innerLoopNum, spin) + @assert innerLoopNum >= 0 + if innerLoopNum == 0 + return 1 + elseif innerLoopNum == 1 + return 1 + elseif innerLoopNum == 2 + return 4 + 2 * spin + elseif innerLoopNum == 3 + return 27 + 22 * spin + else + error("not implemented!") + end +end + +function count_sigma_G2v(innerLoopNum, spin) + @assert innerLoopNum >= 1 + if innerLoopNum == 1 + return 1 + elseif innerLoopNum == 2 + return 1 + spin + elseif innerLoopNum == 3 + return 4 + 5 * spin + spin^2 + elseif innerLoopNum == 4 + return 27 + 40 * spin + 14 * spin^2 + spin^3 + else + error("not implemented!") + end +end + +function count_sigma_G2W(innerLoopNum, spin) + @assert innerLoopNum >= 1 + return count_ver3_G2W(innerLoopNum, spin) +end + +function count_polar_G2v(innerLoopNum, spin) + @assert innerLoopNum >= 1 + return spin * count_ver3_G2v(innerLoopNum - 1, spin) +end + +function count_polar_G2W(innerLoopNum, spin) + return spin * count_ver3_G2W(innerLoopNum - 1, spin) +end + +function count_polar_g2v_noFock_upup(innerLoopNum, spin) + #polarization for + @assert innerLoopNum >= 1 + @assert spin == 2 "only spin=2 has been implemented!" + if innerLoopNum == 1 + return 2 + elseif innerLoopNum == 2 + return 2 + elseif innerLoopNum == 3 + return 28 + elseif innerLoopNum == 4 + return 274 + elseif innerLoopNum == 5 + return 3586 + else + error("not implemented!") + end +end + +function count_polar_g2v_noFock_updown(innerLoopNum, spin) + #polarization for + @assert innerLoopNum >= 1 + @assert spin == 2 "only spin=2 has been implemented!" + if innerLoopNum == 1 + return 0 + elseif innerLoopNum == 2 + return 0 + elseif innerLoopNum == 3 + return 4 + elseif innerLoopNum == 4 + return 52 + elseif innerLoopNum == 5 + return 844 + else + error("not implemented!") + end +end + +function count_polar_g2v_noFock(innerLoopNum, spin) + return count_polar_g2v_noFock_upup(innerLoopNum, spin) + + count_polar_g2v_noFock_updown(innerLoopNum, spin) +end + diff --git a/src/frontend/parquet/benchmark/vertex4.jl b/src/frontend/parquet/benchmark/vertex4.jl new file mode 100644 index 00000000..516c81ed --- /dev/null +++ b/src/frontend/parquet/benchmark/vertex4.jl @@ -0,0 +1,288 @@ +mutable struct Green + Tpair::Tuple{Int,Int} + weight::Float64 + function Green(inT, outT) + return new((inT, outT), 0.0) + end + function Green(tpair::Tuple{Int,Int}) + return new(tpair, 0.0) + end +end + +# add Tpairs to Green's function (in, out) or vertex4 (inL, outL, inR, outR) +function addTidx(obj, _Tidx) + for (i, Tidx) in enumerate(obj.Tpair) + if Tidx == _Tidx + return i + end + end + push!(obj.Tpair, _Tidx) + push!(obj.weight, zero(eltype(obj.weight))) # add zero to the weight table of the object + push!(obj.child, []) + return length(obj.Tpair) +end + +""" + struct IdxMap{_Ver4} + + Map left vertex Tpair[lidx], right vertex Tpair[ridx], the shared Green's function G0 and the channel specific Green's function Gx to the top level 4-vertex Tpair[vidx] + +# Arguments +- l::_Ver4 : left vertex +- r::_Ver4 : right vertex +- v::_Ver4 : composte vertex +- lidx::Int : left sub-vertex index +- ridx::Int : right sub-vertex index +- vidx::Int : composite vertex index +- G0::Green : shared Green's function index +- Gx::Green : channel specific Green's function index +""" +mutable struct IdxMap{_Ver4} + l::_Ver4 #left vertex + r::_Ver4 #right vertex + v::_Ver4 #composte vertex + lidx::Int # left sub-vertex index + ridx::Int # right sub-vertex index + vidx::Int # composite vertex index + G0::Green # shared Green's function index + Gx::Green # channel specific Green's function index + node::Any # useful for constructing DiagTree + function IdxMap(l::V, r::V, v::V, lidx, ridx, vidx, G0::Green, Gx::Green) where {V} + return new{V}(l, r, v, lidx, ridx, vidx, G0, Gx, nothing) + end +end + +struct Bubble{_Ver4} # template Bubble to avoid mutually recursive struct + id::Int + chan::Int + Lver::_Ver4 + Rver::_Ver4 + map::Vector{IdxMap{_Ver4}} + + function Bubble(ver4::_Ver4, chan::Int, oL::Int, level::Int, _id::Vector{Int}) where {_Ver4} + # @assert chan in para.chan "$chan isn't a bubble channels!" + @assert oL < ver4.loopNum "LVer loopNum must be smaller than the ver4 loopNum" + + idbub = _id[1] # id vector will be updated later, so store the current id as the bubble id + _id[1] += 1 + + oR = ver4.loopNum - 1 - oL # loopNum of the right vertex + lLpidxOffset = ver4.loopidxOffset + 1 + rLpidxOffset = lLpidxOffset + oL + LTidx = ver4.TidxOffset # the first τ index of the left vertex + TauNum = interactionTauNum(ver4.para) # maximum tau number for each bare interaction + RTidx = LTidx + (oL + 1) * TauNum # the first τ index of the right sub-vertex + + if chan == T || chan == U + LverChan = (level == 1) ? ver4.Fouter : ver4.F + RverChan = (level == 1) ? ver4.Allouter : ver4.All + elseif chan == S + LverChan = (level == 1) ? ver4.Vouter : ver4.V + RverChan = (level == 1) ? ver4.Allouter : ver4.All + else + error("chan $chan isn't implemented!") + end + + # println("left ver chan: ", LsubVer, ", loop=", oL) + # W = eltype(ver4.weight) + Lver = _Ver4(ver4.para, LverChan, ver4.F, ver4.V, ver4.All; + loopNum=oL, loopidxOffset=lLpidxOffset, tidxOffset=LTidx, + level=level + 1, id=_id) + + Rver = _Ver4(ver4.para, RverChan, ver4.F, ver4.V, ver4.All; + loopNum=oR, loopidxOffset=rLpidxOffset, tidxOffset=RTidx, + level=level + 1, id=_id) + + @assert Lver.TidxOffset == ver4.TidxOffset "Lver Tidx must be equal to vertex4 Tidx! LoopNum: $(ver4.loopNum), LverLoopNum: $(Lver.loopNum), chan: $chan" + + ############## construct IdxMap ######################################## + map = [] + for (lt, LvT) in enumerate(Lver.Tpair) + for (rt, RvT) in enumerate(Rver.Tpair) + VerTidx = 0 + + if chan == T + VerT = (LvT[INL], LvT[OUTL], RvT[INR], RvT[OUTR]) + GTx = (RvT[OUTL], LvT[INR]) + elseif chan == U + VerT = (LvT[INL], RvT[OUTR], RvT[INR], LvT[OUTL]) + GTx = (RvT[OUTL], LvT[INR]) + elseif chan == S + VerT = (LvT[INL], RvT[OUTL], LvT[INR], RvT[OUTR]) + GTx = (LvT[OUTL], RvT[INR]) + else + throw("This channel is invalid!") + end + + Gx = Green(GTx) + push!(ver4.G[Int(chan)], Gx) + + GT0 = (LvT[OUTR], RvT[INL]) + G0 = Green(GT0) + push!(ver4.G[1], G0) + + VerTidx = addTidx(ver4, VerT) + for tpair in ver4.Tpair + @assert tpair[1] == ver4.TidxOffset "InL Tidx must be the same for all Tpairs in the vertex4" + end + + ###### test if the internal + exteranl variables is equal to the total 8 variables of the left and right sub-vertices ############ + Total1 = vcat(collect(LvT), collect(RvT)) + Total2 = vcat(collect(GT0), collect(GTx), collect(VerT)) + # println(Total1) + # println(Total2) + @assert compare(Total1, Total2) "chan $(chan): G0=$GT0, Gx=$GTx, external=$VerT don't match with Lver4 $LvT and Rver4 $RvT" + + idxmap = IdxMap(Lver, Rver, ver4, lt, rt, VerTidx, G0, Gx) + push!(map, idxmap) + push!(ver4.child[VerTidx], idxmap) + end + end + return new{_Ver4}(idbub, chan, Lver, Rver, map) + end +end + +""" + function Ver4{W}(para::Para, loopNum = para.internalLoopNum, tidx = 1; chan = para.chan, F = para.F, V = para.V, level = 1, id = [1,]) where {W} + + Generate 4-vertex diagrams using Parquet Algorithm + +#Arguments +- `para`: parameters. It should provide internalLoopNum, interactionTauNum, firstTauIdx +- `chan`: list of channels of the current 4-vertex. +- `F` : channels of left sub-vertex for the particle-hole and particle-hole-exchange bubbles +- `V` : channels of left sub-vertex for the particle-particle bubble +- `All` : channels of right sub-vertex of all channels +- `Fouter` : channels of left sub-vertex for the particle-hole and particle-hole-exchange bubbles, only take effect for the outermost bubble +- `Vouter` : channels of left sub-vertex for the particle-particle bubble, only take effect for the outermost bubble +- `Allouter` : channels of right sub-vertex of all channels +- `loopNum`: momentum loop degrees of freedom of the 4-vertex diagrams +- `tidx`: the first τ variable index. It will be the τ variable of the left incoming electron for all 4-vertex diagrams +- `level`: level in the diagram tree +- `id`: the first element will be used as the id of the Ver4. All nodes in the tree will be labeled in preorder depth-first search + +#Remark: +- AbstractTrees interface is implemented for Ver4. So one can use the API in https://juliacollections.github.io/AbstractTrees.jl/stable/ to manipulate/print the tree structre of Ver4. +- There are three different methods to print/visualize the tree structre: +1) `print_tree(ver4::Ver4)` or `print_tree(bub::Bubble)` to print the tree to terminal. This function is provided by AbstractTrees API. +2) `newick(ver4::Ver4)` or `newick(bub::Bubble)` to serilize the tree to a newick format string. You may save the string to a text file, then visualize it with a newick format visualizer application. +3) `showTree(ver4::Ver4)` to visualize the tree using the python package ete3. You have to install ete3 properly to use this function. +""" +struct Ver4{W} + para::Any + chan::Vector{Int} # list of channels + F::Vector{Int} + V::Vector{Int} + All::Vector{Int} + Fouter::Vector{Int} + Vouter::Vector{Int} + Allouter::Vector{Int} + + ###### vertex topology information ##################### + id::Int + level::Int + + ####### vertex properties ########################### + loopNum::Int + loopidxOffset::Int # offset of the loop index from the first internal loop + TidxOffset::Int # offset of the Tidx from the tau index of the left most incoming leg + + ###### components of vertex ########################## + G::SVector{16,Vector{Green}} # large enough to host all Green's function + bubble::Vector{Bubble{Ver4{W}}} + + ####### weight and tau table of the vertex ############### + Tpair::Vector{Tuple{Int,Int,Int,Int}} + child::Vector{Vector{IdxMap{Ver4{W}}}} + weight::Vector{W} + + function Ver4{W}(para, chan, F=[I, U, S], V=[I, T, U], All=union(F, V); + loopNum=para.innerLoopNum, loopidxOffset=0, tidxOffset=0, + Fouter=F, Vouter=V, Allouter=All, + level=1, id=[1,] + ) where {W} + + @assert para.totalTauNum >= (loopNum + 1) * interactionTauNum(para) "$para" + + if level > 1 + @assert Set(F) == Set(Fouter) + @assert Set(V) == Set(Vouter) + @assert Set(All) == Set(Allouter) + end + + @assert (T in F) == false "F vertex is particle-hole irreducible, so that T channel is not allowed in F" + @assert (S in V) == false "V vertex is particle-particle irreducible, so that S channel is not allowed in V" + @assert (T in Fouter) == false "F vertex is particle-hole irreducible, so that T channel is not allowed in F" + @assert (S in Vouter) == false "V vertex is particle-particle irreducible, so that S channel is not allowed in V" + + g = @SVector [Vector{Green}([]) for i = 1:16] + ver4 = new{W}(para, chan, F, V, All, Fouter, Vouter, Allouter, id[1], level, loopNum, loopidxOffset, tidxOffset, g, [], [], [[],], []) + id[1] += 1 + @assert loopNum >= 0 + + + if loopNum == 0 + tidx = tidxOffset + # bare interaction may have one, two or four independent tau variables + if interactionTauNum(para) == 1 # instantaneous interaction + addTidx(ver4, (tidx, tidx, tidx, tidx)) #direct instant intearction + addTidx(ver4, (tidx, tidx, tidx, tidx)) #exchange instant interaction + end + if interactionTauNum(para) == 2 # interaction with incoming and outing τ varibales + addTidx(ver4, (tidx, tidx, tidx, tidx)) # direct and exchange instant interaction + addTidx(ver4, (tidx, tidx, tidx + 1, tidx + 1)) # direct dynamic interaction + addTidx(ver4, (tidx, tidx + 1, tidx + 1, tidx)) # exchange dynamic interaction + end + if interactionTauNum(para) == 4 # interaction with incoming and outing τ varibales + error("Not implemented!") + # addTidx(ver4, (tidx, tidx + 1, tidx + 2, tidx + 3)) # direct dynamic interaction + # addTidx(ver4, (tidx, tidx + 3, tidx + 2, tidx + 1)) # exchange dynamic interaction + end + else # loopNum>0 + for c in chan + for ol = 0:loopNum-1 + bubble = Bubble(ver4, c, ol, level, id) + if length(bubble.map) > 0 # if zero, bubble diagram doesn't exist + push!(ver4.bubble, bubble) + end + end + end + # TODO: add envolpe diagrams + # for c in II + # end + test(ver4) # more test + end + return ver4 + end +end + +function compare(A, B) + # check if the elements of XY are the same as Z + XY, Z = copy(A), copy(B) + for e in XY + if (e in Z) == false + return false + end + Z = (idx = findfirst(x -> x == e, Z)) > 0 ? deleteat!(Z, idx) : Z + end + return length(Z) == 0 +end + +function test(ver4) + if length(ver4.bubble) == 0 + return + end + + G = ver4.G + for bub in ver4.bubble + Lver, Rver = bub.Lver, bub.Rver + @assert Rver.loopidxOffset + Rver.loopNum == ver4.loopidxOffset + ver4.loopNum "Rver loopidx offset = $(Rver.loopidxOffset) + loopNum = $(Rver.loopNum) is not equal to ver4 loopidx offset = $(ver4.loopidxOffset) + loopNum = $(ver4.loopNum)" + @assert Lver.loopNum + Rver.loopNum + 1 == ver4.loopNum + for map in bub.map + LverT, RverT = collect(Lver.Tpair[map.lidx]), collect(Rver.Tpair[map.ridx]) # 8 τ variables relevant for this bubble + G1T, GxT = collect(map.G0.Tpair), collect(map.Gx.Tpair) # 4 internal variables + ExtT = collect(ver4.Tpair[map.vidx]) # 4 external variables + @assert compare(vcat(G1T, GxT, ExtT), vcat(LverT, RverT)) "chan $(bub.chan): G1=$G1T, Gx=$GxT, external=$ExtT don't match with Lver4 $LverT and Rver4 $RverT" + end + end +end \ No newline at end of file diff --git a/src/frontend/parquet/benchmark/vertex4_eval.jl b/src/frontend/parquet/benchmark/vertex4_eval.jl new file mode 100644 index 00000000..c0171f80 --- /dev/null +++ b/src/frontend/parquet/benchmark/vertex4_eval.jl @@ -0,0 +1,142 @@ +mutable struct Weight <: FieldVector{2,Float64} + d::Float64 + e::Float64 + Weight() = new(0.0, 0.0) + Weight(d, e) = new(d, e) +end + +const Base.zero(::Type{Weight}) = Weight(0.0, 0.0) +const Base.abs(w::Weight) = abs(w.d) + abs(w.e) # define abs(Weight) + +function evalAllG!(G, K, T0idx, varT, evalG; kwargs...) + for g in G + tin, tout = g.Tpair + g.weight = evalG(K, varT[T0idx+tin], varT[T0idx+tout], kwargs...) + end +end + +# function phase(varT, Tpair, isF) +# tInL, tOutL, tInR, tOutR = varT[Tpair[INL]], varT[Tpair[OUTL]], varT[Tpair[INR]], +# varT[Tpair[OUTR]] +# if (isF) +# return cos(π / β * ((tInL + tOutL) - (tInR + tOutR))) +# else +# return cos(π / β * ((tInL - tOutL) + (tInR - tOutR))) +# end +# end + +function eval(para, ver4::Ver4, varK, varT, legK, evalG::Function, evalV::Function, fast=false; kwargs...) + KinL, KoutL, KinR, KoutR = legK + spin = para.spin + T0idx = para.firstTauIdx + Kidx = para.firstLoopIdx + ver4.loopidxOffset + + if ver4.loopNum == 0 + qd = KinL - KoutL + qe = KinL - KoutR + if interactionTauNum(para) == 1 + sign = para.isFermi ? -1 : 1 + ver4.weight[1].d = -evalV(qd) + ver4.weight[1].e = (-evalV(qe)) * sign + else + Tidx = para.firstTauIdx + ver4.TidxOffset + τIn, τOut = varT[Tidx], varT[Tidx+1] + error("not implemented!") + # elseif ver4.interactionTauNum == 2 + # vd, wd, ve, we = vertexDynamic(para, qd, qe, τIn, τOut) + + # ver4.weight[1].d = vd + # ver4.weight[1].e = ve + # ver4.weight[2].d = wd + # ver4.weight[2].e = 0.0 + # ver4.weight[3].d = 0.0 + # ver4.weight[3].e = we + end + return + end + + # LoopNum>=1 + for w in ver4.weight + w.d, w.e = 0.0, 0.0 # initialize all weights + end + G = ver4.G + K = varK[:, Kidx] + + evalAllG!(G[1], K, T0idx, varT, evalG, kwargs...) + + # PhaseFactor = 1.0 / (2π)^para.loopDim + PhaseFactor = 1.0 + Kt, Ku, Ks = similar(K), similar(K), similar(K) #Kt, Ku and Ks will be re-created later, slow in performance + + for c in ver4.chan + if c == T + @. Kt = KoutL + K - KinL + evalAllG!(G[Int(c)], Kt, T0idx, varT, evalG, kwargs...) + # println("initializating", G[Int(c)]) + elseif c == U + # can not be in box! + @. Ku = KoutR + K - KinL + evalAllG!(G[Int(c)], Ku, T0idx, varT, evalG, kwargs...) + elseif c == S + # S channel, and cann't be in box! + @. Ks = KinL + KinR - K + evalAllG!(G[Int(c)], Ks, T0idx, varT, evalG, kwargs...) + else + error("not impossible!") + end + end + for b in ver4.bubble + c = b.chan + Factor = SymFactor[Int(c)] * PhaseFactor + if para.isFermi == false + Factor = abs(Factor) + end + + if c == T + eval(para, b.Lver, varK, varT, [KinL, KoutL, Kt, K], evalG, evalV; kwargs...) + eval(para, b.Rver, varK, varT, [K, Kt, KinR, KoutR], evalG, evalV; kwargs...) + elseif c == U + eval(para, b.Lver, varK, varT, [KinL, KoutR, Ku, K], evalG, evalV; kwargs...) + eval(para, b.Rver, varK, varT, [K, Ku, KinR, KoutL], evalG, evalV; kwargs...) + elseif c == S + # S channel + eval(para, b.Lver, varK, varT, [KinL, Ks, KinR, K], evalG, evalV; kwargs...) + eval(para, b.Rver, varK, varT, [K, KoutL, Ks, KoutR], evalG, evalV; kwargs...) + else + error("not implemented") + end + + rN = length(b.Rver.weight) + gWeight = 0.0 + for (l, Lw) in enumerate(b.Lver.weight) + for (r, Rw) in enumerate(b.Rver.weight) + map = b.map[(l-1)*rN+r] + + gWeight = map.G0.weight * map.Gx.weight * Factor + + if fast && ver4.level == 1 + # gWeight *= phase(varT, ver4.Tpair[map.ver]) + w = ver4.weight[1] + else + w = ver4.weight[map.vidx] + end + + if c == T + w.d += gWeight * (Lw.d * Rw.d * spin + Lw.d * Rw.e + Lw.e * Rw.d) + w.e += gWeight * Lw.e * Rw.e + elseif c == U + w.d += gWeight * Lw.e * Rw.e + w.e += gWeight * (Lw.d * Rw.d * spin + Lw.d * Rw.e + Lw.e * Rw.d) + elseif c == S + # S channel, see the note "code convention" + w.d += gWeight * (Lw.d * Rw.e + Lw.e * Rw.d) + w.e += gWeight * (Lw.d * Rw.d + Lw.e * Rw.e) + else + error("not implemented") + end + + end + end + + end +end \ No newline at end of file diff --git a/src/frontend/parquet/benchmark/vertex4_io.jl b/src/frontend/parquet/benchmark/vertex4_io.jl new file mode 100644 index 00000000..c09d2d24 --- /dev/null +++ b/src/frontend/parquet/benchmark/vertex4_io.jl @@ -0,0 +1,224 @@ +################## implement AbstractTrees interface ####################### +# refer to https://github.com/JuliaCollections/AbstractTrees.jl for more details +function AbstractTrees.children(ver4::Ver4) + return ver4.bubble +end + +function AbstractTrees.children(bubble::Bubble) + return (bubble.Lver, bubble.Rver) +end + +function iterate(ver4::Ver4{W}) where {W} + if length(ver4.bubble) == 0 + return nothing + else + return (ver4.bubble[1], 1) + end +end + +function iterate(bub::Bubble) + return (bub.Lver, false) +end + +function iterate(ver4::Ver4{W}, state) where {W} + if state >= length(ver4.bubble) || length(ver4.bubble) == 0 + return nothing + else + return (ver4.bubble[state+1], state + 1) + end +end + +function iterate(bub::Bubble, state::Bool) + state && return nothing + return (bub.Rver, true) +end + +Base.IteratorSize(::Type{Ver4{W}}) where {W} = Base.SizeUnknown() +Base.eltype(::Type{Ver4{W}}) where {W} = Ver4{W} + +Base.IteratorSize(::Type{Bubble{Ver4{W}}}) where {W} = Base.SizeUnknown() +Base.eltype(::Type{Bubble{Ver4{W}}}) where {W} = Bubble{Ver4{W}} + +AbstractTrees.printnode(io::IO, ver4::Ver4) = print(io, tpair(ver4)) +AbstractTrees.printnode(io::IO, bub::Bubble) = print(io, + "\u001b[32m$(bub.id): $(bub.chan) $(bub.Lver.para.innerLoopNum)Ⓧ $(bub.Rver.para.innerLoopNum)\u001b[0m") + +function tpair(ver4, MaxT = 18) + s = "\u001b[31m$(ver4.id):\u001b[0m" + if ver4.para.innerLoopNum > 0 + s *= "$(ver4.para.innerLoopNum)lp, T$(length(ver4.Tpair))⨁ " + else + s *= "⨁ " + end + # if ver4.loopNum <= 1 + for (ti, T) in enumerate(ver4.Tpair) + if ti <= MaxT + s *= "($(T[1]),$(T[2]),$(T[3]),$(T[4]))" + else + s *= "..." + break + end + end + # end + return s +end + +##### pretty print of Bubble and Ver4 ########################## +Base.show(io::IO, bub::Bubble) = AbstractTrees.printnode(io::IO, bub) +Base.show(io::IO, ver4::Ver4) = AbstractTrees.printnode(io::IO, ver4) + + +""" +convert Ver4 tree struct to a string in the newick format +""" +function newick(ver4::Ver4) + return "$(newickVer4(ver4));" +end + +""" +convert Bubble tree struct to a string in the newick format +""" +function newick(bub::Bubble) + return "$(newickBuble(bub));" +end + +function newickBubble(bub::Bubble) + # Recursive version + # Practically a postorder tree traversal + left = newickVer4(bub.Lver) + right = newickVer4(bub.Rver) + return "($left,$right)$(bub.id)_$(ChanName[bub.chan])_$(bub.Lver.para.innerLoopNum)Ⓧ$(bub.Rver.para.innerLoopNum)" +end + + +function newickVer4(ver4::Ver4) + # Recursive version + # Practically a postorder tree traversal + + function tpairNewick(ver4) + if ver4.para.innerLoopNum > 0 + s = "$(ver4.id):lp$(ver4.para.innerLoopNum)_T$(length(ver4.Tpair))⨁" + else + s = "$(Ver4.id):⨁" + end + # if ver4.loopNum <= 1 + for (ti, T) in enumerate(ver4.Tpair) + if ti <= 5 + s *= "⟨$(T[1])-$(T[2])-$(T[3])-$(T[4])⟩" + else + s *= "…" + break + end + end + # end + return s + end + + if ver4.para.innerLoopNum == 0 + return tpairNewick(ver4) + else + s = "(" + for (bi, bub) in enumerate(ver4.bubble) + s *= newickBubble(bub) + if bi != length(ver4.bubble) + s *= "," + else + s *= ")" + end + end + return s * tpairNewick(ver4) + end +end + +""" + showTree(ver4, para::Para; verbose=0, depth=999) + + Visualize the diagram tree using ete3 python package + +#Arguments +- `ver4`: the 4-vertex diagram tree to visualize +- `para`: parameters +- `verbose=0`: the amount of information to show +- `depth=999`: deepest level of the diagram tree to show +""" +function showTree(ver4; verbose = 0, depth = 999) + + # pushfirst!(PyVector(pyimport("sys")."path"), @__DIR__) #comment this line if no need to load local python module + ete = pyimport("ete3") + + function tpairETE(ver4, depth) + s = "$(ver4.id):" + if ver4.para.innerLoopNum > 0 + s *= "$(ver4.para.innerLoopNum)lp, T$(length(ver4.Tpair))⨁ " + else + s *= "⨁ " + end + if ver4.para.innerLoopNum == 0 || ver4.level > depth + MaxT = Inf + else + MaxT = 1 + end + + # if ver4.loopNum <= 1 + for (ti, T) in enumerate(ver4.Tpair) + if ti <= MaxT + s *= "($(T[1]),$(T[2]),$(T[3]),$(T[4]))" + else + s *= "..." + break + end + end + # end + return s + end + + + function treeview(ver4, t = nothing) + if isnothing(t) + t = ete.Tree(name = " ") + end + + if ver4.para.innerLoopNum == 0 || ver4.level > depth + nt = t.add_child(name = tpairETE(ver4, depth)) + return t + else + # prefix = "$(ver4.id): $(ver4.loopNum) lp, $(length(ver4.Tpair)) elem" + # nt = t.add_child(name=prefix * ", ⨁") + nt = t.add_child(name = tpairETE(ver4, depth)) + name_face = ete.TextFace(nt.name, fgcolor = "black", fsize = 10) + nt.add_face(name_face, column = 0, position = "branch-top") + end + + for bub in ver4.bubble + nnt = nt.add_child(name = "$(bub.id): $(bub.chan) $(bub.Lver.para.innerLoopNum)Ⓧ$(bub.Rver.para.innerLoopNum)") + + name_face = ete.TextFace(nnt.name, fgcolor = "black", fsize = 10) + nnt.add_face(name_face, column = 0, position = "branch-top") + + treeview(bub.Lver, nnt) + treeview(bub.Rver, nnt) + end + + return t + end + + t = treeview(ver4) + # style = ete.NodeStyle() + # style["bgcolor"] = "Khaki" + # t.set_style(style) + + + ts = ete.TreeStyle() + ts.show_leaf_name = true + # ts.show_leaf_name = True + # ts.layout_fn = my_layout + ####### show tree vertically ############ + # ts.rotation = 90 #show tree vertically + + ####### show tree in an arc ############# + # ts.mode = "c" + # ts.arc_start = -180 + # ts.arc_span = 180 + # t.write(outfile="/home/kun/test.txt", format=8) + t.show(tree_style = ts) +end \ No newline at end of file diff --git a/src/frontend/parquet/ep_coupling.jl b/src/frontend/parquet/ep_coupling.jl new file mode 100644 index 00000000..3221e7a1 --- /dev/null +++ b/src/frontend/parquet/ep_coupling.jl @@ -0,0 +1,144 @@ +""" + function ep_coupling(para::DiagPara; + extK=[getK(para.totalLoopNum, 1), getK(para.totalLoopNum, 2), getK(para.totalLoopNum, 3)], + channels::AbstractVector=[PHr, PHEr, PPr, Alli], + subdiagram=false, + name=:none, resetuid=false, + blocks::ParquetBlocks=ParquetBlocks() + ) + +Generate electron-phonon 4-vertex diagrams using Parquet Algorithm. The right incoming Tau will be set to the last Tau for all diagrams +| | +Γ3 -------| +| | + +# Arguments +- `para` : parameters. It should provide internalLoopNum, interactionTauNum, firstTauIdx +- `extK` : basis of external loops as a vector [left in, left out, right in, right out]. +- `channels` : vector of channels in the left Γ3 diagrams. +- `subdiagram` : a sub-vertex or not +- `name` : name of the vertex +- `resetuid` : restart uid count from 1 +- `blocks` : building blocks of the Parquet equation. See the struct ParquetBlocks for more details. + +# Output +- A DataFrame with fields :response, :extT, :diagram, :hash. + +# Output +- A DataFrame with fields :response, :type, :extT, :diagram, :hash +""" +function ep_coupling(para::DiagPara; + extK=[getK(para.totalLoopNum, 1), getK(para.totalLoopNum, 2), getK(para.totalLoopNum, 3)], + channels::AbstractVector=[PHr, PHEr, PPr, Alli], + subdiagram=false, + name=:none, resetuid=false, + blocks::ParquetBlocks=ParquetBlocks() +) + + @warn("ep vertex4 breaks SU(2) spin symmetry!") + if NoBubble in para.filter + @warn("the RPA chain counterterms from the renormalization of the outgoing interaction leg in the ep vertex4 have not yet been implemented!") + end + + for k in extK + @assert length(k) >= para.totalLoopNum "expect dim of extK>=$(para.totalLoopNum), got $(length(k))" + end + + legK = [k[1:para.totalLoopNum] for k in extK[1:3]] + push!(legK, legK[1] + legK[3] - legK[2]) + + resetuid && ComputationalGraphs.uidreset() + + @assert para.totalTauNum >= maxVer4TauIdx(para) "Increase totalTauNum!\n$para" + @assert para.totalLoopNum >= maxVer4LoopIdx(para) "Increase totalLoopNum\n$para" + + loopNum = para.innerLoopNum + # @assert loopNum >= 0 + + ver4df = DataFrame(response=Response[], type=AnalyticProperty[], extT=Tuple{Int,Int,Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + + partition = orderedPartition(loopNum - 1, 4, 0) + + for p in partition + if p[3] == 0 #oL, oG0, oR, oGx + ep_bubble!(ver4df, para, legK, channels, p, name, blocks, 1.0) + end + end + + if NoBubble in para.filter + # add RPA bubble counter-diagram to remove the bubble + ep_RPA_chain!(ver4df, para, legK, name, -1.0) + end + # println(bub) + + diags = ver4df.diagram + @assert all(x -> x.properties isa Ver4Id, diags) "not all id are Ver4Id! $diags" + @assert all(x -> x.properties.extK ≈ legK, diags) "not all extK are the same! $diags" + + ver4df = merge_vertex4(para, ver4df, name, legK) + @assert all(x -> x[1] == para.firstTauIdx, ver4df.extT) "not all extT[1] are equal to the first Tau index $(para.firstTauIdx)! $ver4df" + # @assert all(x -> x[3] == para.totalTauNum, ver4df.extT) "not all extT[3] are equal to the first Tau index $(para.totalTauNum)! $ver4df" + # @assert all(x -> x[4] == para.totalTauNum, ver4df.extT) "not all extT[4] are equal to the first Tau index $(para.totalTauNum)! $ver4df" + # println(typeof(groups)) + return ver4df +end + +function ep_bubble!(ver4df::DataFrame, para::DiagPara, legK, chans::Vector{TwoBodyChannel}, partition::Vector{Int}, name::Symbol, blocks::ParquetBlocks, + extrafactor=1.0) + + @assert partition[3] == 0 + + TauNum = interactionTauNum(para) # maximum tau number for each bare interaction + oL, oG0, oR, oGx = partition[1], partition[2], partition[3], partition[4] + if isValidG(para.filter, oG0) == false || isValidG(para.filter, oGx) == false + return + end + + #the first loop idx is the inner loop of the bubble! + LoopIdx = para.firstLoopIdx + idx, maxLoop = findFirstLoopIdx(partition, LoopIdx + 1) + LfirstLoopIdx, G0firstLoopIdx, RfirstLoopIdx, GxfirstLoopIdx = idx + @assert maxLoop == maxVer4LoopIdx(para) + + type = [Ver4Diag, GreenDiag, Ver4Diag, GreenDiag] + idx, maxTau = findFirstTauIdx(partition, type, para.firstTauIdx, TauNum) + LfirstTauIdx, G0firstTauIdx, RfirstTauIdx, GxfirstTauIdx = idx + @assert maxTau == maxVer4TauIdx(para) "Partition $partition with tauNum configuration $idx. maxTau = $maxTau, yet $(maxTauIdx(para)) is expected!" + + lPara = reconstruct(para, type=Ver4Diag, innerLoopNum=oL, firstLoopIdx=LfirstLoopIdx, firstTauIdx=LfirstTauIdx) + rPara = reconstruct(para, type=Ver4Diag, innerLoopNum=oR, firstLoopIdx=RfirstLoopIdx, firstTauIdx=RfirstTauIdx) + gxPara = reconstruct(para, type=GreenDiag, innerLoopNum=oGx, firstLoopIdx=GxfirstLoopIdx, firstTauIdx=GxfirstTauIdx) + g0Para = reconstruct(para, type=GreenDiag, innerLoopNum=oG0, firstLoopIdx=G0firstLoopIdx, firstTauIdx=G0firstTauIdx) + + LLegK, K, RLegK, Kx = legBasis(PHr, legK, LoopIdx) + + Lver = vertex4(lPara, LLegK, chans, true; name=:Γf, blocks=blocks) + isempty(Lver) && return + + Rver = DataFrame(response=Response[], type=AnalyticProperty[], extT=Tuple{Int,Int,Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + bareVer4(Rver, rPara, RLegK, [Di,], false) # the external tau is right aligned + Rver = merge_vertex4(rPara, Rver, :bare, RLegK) + + @assert isempty(Rver) == false + + for ldiag in Lver.diagram + for rdiag in Rver.diagram + LvT, RvT = ldiag.properties.extT, rdiag.properties.extT + extT, G0T, GxT = tauBasis(PHr, ldiag.properties.extT, rdiag.properties.extT) + g0 = green(g0Para, K, G0T, true, name=:G0, blocks=blocks) + gx = green(gxPara, Kx, GxT, true, name=:Gx, blocks=blocks) + @assert g0 isa Graph && gx isa Graph + # append!(diag, bubble2diag(para, chan, ldiag, rdiag, legK, g0, gx, extrafactor)) + bubble2diag!(ver4df, para, PHr, ldiag, rdiag, legK, g0, gx, extrafactor) + end + end + return +end + +function ep_RPA_chain!(ver4df::DataFrame, para::DiagPara, legK, name::Symbol, extrafactor) + new_filter = union(union(para.filter, Girreducible), DirectOnly) + para_rpa = reconstruct(para, filter=new_filter) + blocks = ParquetBlocks(; phi=[], ppi=[], Γ4=[PHr,]) + ep_bubble!(ver4df, para_rpa, legK, [PHr,], [0, 0, para.innerLoopNum - 1, 0], Symbol("$(name)_ep_RPA_CT"), blocks, extrafactor) + return +end \ No newline at end of file diff --git a/src/frontend/parquet/green.jl b/src/frontend/parquet/green.jl index a16cf098..b4c274bf 100644 --- a/src/frontend/parquet/green.jl +++ b/src/frontend/parquet/green.jl @@ -1,5 +1,5 @@ """ - green(para::DiagPara, extK = DiagTree.getK(para.totalLoopNum, 1), extT = para.hasTau ? (1, 2) : (0, 0), subdiagram = false; + green(para::DiagPara, extK = getK(para.totalLoopNum, 1), extT = para.hasTau ? (1, 2) : (0, 0), subdiagram = false; name = :G, resetuid = false, blocks::ParquetBlocks=ParquetBlocks()) Build composite Green's function. @@ -18,7 +18,7 @@ By definition, para.firstTauIdx is the first Tau index of the left most self-ene # Output - A Diagram object or nothing if the Green's function is illegal. """ -function green(para::DiagPara, extK=DiagTree.getK(para.totalLoopNum, 1), extT=para.hasTau ? (1, 2) : (0, 0), subdiagram=false; +function green(para::DiagPara, extK=getK(para.totalLoopNum, 1), extT=para.hasTau ? (1, 2) : (0, 0), subdiagram=false; name=:G, resetuid=false, blocks::ParquetBlocks=ParquetBlocks()) @assert isValidG(para) "$para doesn't gives a valid Green's function" diff --git a/src/frontend/parquet/parquet.jl b/src/frontend/parquet/parquet.jl index ec3dac74..88e06060 100644 --- a/src/frontend/parquet/parquet.jl +++ b/src/frontend/parquet/parquet.jl @@ -27,9 +27,6 @@ const SymFactor = [1.0, -1.0, 1.0, -0.5, +1.0, -1.0] @enum TwoBodyChannel Alli = 1 PHr PHEr PPr AnyChan @enum Permutation Di = 1 Ex DiEx -export TwoBodyChannel, Alli, PHr, PHEr, PPr, AnyChan -export Permutation, Di, Ex, DiEx - Base.length(r::TwoBodyChannel) = 1 Base.iterate(r::TwoBodyChannel) = (r, nothing) function Base.iterate(r::TwoBodyChannel, ::Nothing) end @@ -288,9 +285,24 @@ include("vertex4.jl") include("sigma.jl") include("green.jl") -# include("vertex3.jl") -# include("polarization.jl") +include("vertex3.jl") +include("polarization.jl") + +include("ep_coupling.jl") +include("benchmark/benchmark.jl") + +export DiagPara, ParquetBlocks +export Interaction, interactionTauNum, innerTauNum +export DiagramType, VacuumDiag, SigmaDiag, GreenDiag, PolarDiag, Ver3Diag, Ver4Diag +export Filter, Wirreducible, Girreducible, NoBubble, NoHartree, NoFock, Proper, DirectOnly +export Response, Composite, ChargeCharge, SpinSpin, ProperChargeCharge, ProperSpinSpin, UpUp, UpDown +export AnalyticProperty, Instant, Dynamic, D_Instant, D_Dynamic +export TwoBodyChannel, Alli, PHr, PHEr, PPr, AnyChan +export Permutation, Di, Ex, DiEx +export DiagramId, GenericId, Ver4Id, Ver3Id, GreenId, SigmaId, PolarId +export PropagatorId, BareGreenId, BareInteractionId +# export BareGreenNId, BareHoppingId, GreenNId, ConnectedGreenNId +export mergeby -# include("benchmark/benchmark.jl") end \ No newline at end of file diff --git a/src/frontend/parquet/polarization.jl b/src/frontend/parquet/polarization.jl new file mode 100644 index 00000000..6308cec7 --- /dev/null +++ b/src/frontend/parquet/polarization.jl @@ -0,0 +1,138 @@ + +""" + function polarization(para::DiagPara, extK=getK(para.totalLoopNum, 1), subdiagram=false; name=:Π, resetuid=false, blocks::ParquetBlocks=ParquetBlocks()) +Generate polarization diagrams using Parquet Algorithm. + +# Arguments +- `para` : parameters. It should provide internalLoopNum, interactionTauNum, firstTauIdx +- `extK` : basis of external loop. +- `subdiagram` : a sub-vertex or not +- `name` : name of the vertex +- `resetuid` : restart uid count from 1 +- `blocks` : building blocks of the Parquet equation. See the struct ParquetBlocks for more details. + +# Output +- A DataFrame with fields `:response`, `:diagram`, `:hash`. +- All polarization share the same external Tau index. With imaginary-time variables, they are extT = (para.firstTauIdx, para.firstTauIdx+1) +""" +function polarization(para::DiagPara, extK=getK(para.totalLoopNum, 1), subdiagram=false; name=:Π, resetuid=false, + blocks::ParquetBlocks=ParquetBlocks() +) + resetuid && uidreset() + @assert para.type == PolarDiag + @assert para.innerLoopNum >= 1 + # @assert length(extK) == para.totalLoopNum + @assert length(extK) >= para.totalLoopNum "expect dim of extK>=$(para.totalLoopNum), got $(length(extK))" + + #polarization diagram should always proper + # if !(Proper in _para.filter) || (length(_para.transferLoop) != length(extK)) || (_para.transferLoop ≈ extK) + # # @warn "Polarization diagram parameter is not proper. It will be reconstructed with proper transfer loops." + # para = derivepara(_para, filter=union(Proper, _para.filter), transferLoop=extK) + # end + para = _properPolarPara(para, extK) + + extK = extK[1:para.totalLoopNum] + + # if (para.extra isa ParquetBlocks) == false + # para::DiagPara = reconstruct(para, extra=ParquetBlocks()) + # end + + K = zero(extK) + LoopIdx = para.firstLoopIdx + K[LoopIdx] = 1.0 + @assert (K ≈ extK) == false + t0 = para.firstTauIdx + extT = para.hasTau ? (t0, t0 + 1) : (t0, t0) + legK = [extK, K, K .- extK] + + polar = DataFrame(response=Response[], extT=Tuple{Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + + for (oVer3, oGin, oGout) in orderedPartition(para.innerLoopNum - 1, 3, 0) + # ! Vertex3 must be in the first place, because we want to make sure that the bosonic extT of the vertex3 start with t0+1 + + idx, maxLoop = findFirstLoopIdx([oVer3, oGin, oGout], LoopIdx + 1) # GGΓ3 consumes one internal loop + @assert maxLoop <= para.totalLoopNum "maxLoop = $maxLoop > $(para.totalLoopNum)" + Ver3Kidx, GinKidx, GoutKidx = idx + + if isValidG(para.filter, oGin) && isValidG(para.filter, oGout) + if oVer3 == 0 + ######################## Π0 = GG ######################################### + gt0 = para.hasTau ? extT[2] + 1 : extT[1] + idx, maxTau = findFirstTauIdx([oGin, oGout], [GreenDiag, GreenDiag], gt0, interactionTauNum(para)) + @assert maxTau <= para.totalTauNum "maxTau = $maxTau > $(para.totalTauNum)" + GinTidx, GoutTidx = idx + + paraGin = reconstruct(para, type=GreenDiag, innerLoopNum=oGin, + firstLoopIdx=GinKidx, firstTauIdx=GinTidx) + paraGout = reconstruct(para, type=GreenDiag, innerLoopNum=oGout, + firstLoopIdx=GoutKidx, firstTauIdx=GoutTidx) + + response = UpUp + polarid = PolarId(para, response, k=extK, t=extT) + gin = green(paraGin, K, (extT[1], extT[2]), true, name=:Gin) + gout = green(paraGout, K .- extK, (extT[2], extT[1]), true, name=:Gout) + @assert gin isa Graph && gout isa Graph "$gin or $gout is not a single graph" + + sign = para.isFermi ? -1.0 : 1.0 + # polardiag = Diagram{W}(polarid, Prod(), [gin, gout], name=name, factor=sign) + polardiag = Graph([gin, gout], properties=polarid, operator=Prod(), name=name, factor=sign) + push!(polar, (response=response, extT=extT, diagram=polardiag)) + else + ##################### composite polarization ##################################### + idx, maxTau = findFirstTauIdx([oVer3, oGin, oGout], [Ver3Diag, GreenDiag, GreenDiag], extT[2], interactionTauNum(para)) + @assert maxTau <= para.totalTauNum "maxTau = $maxTau > $(para.totalTauNum)" + Ver3Tidx, GinTidx, GoutTidx = idx + + paraGin = reconstruct(para, type=GreenDiag, innerLoopNum=oGin, + firstLoopIdx=GinKidx, firstTauIdx=GinTidx) + paraGout = reconstruct(para, type=GreenDiag, innerLoopNum=oGout, + firstLoopIdx=GoutKidx, firstTauIdx=GoutTidx) + + paraVer3 = reconstruct(para, type=Ver3Diag, innerLoopNum=oVer3, + firstLoopIdx=Ver3Kidx, firstTauIdx=Ver3Tidx) + ver3 = vertex3(paraVer3, legK, true; blocks=blocks) + if isnothing(ver3) || isempty(ver3) + continue + end + if para.hasTau + @assert all(x -> x[1] == extT[2], ver3.extT) "The bosonic T must be firstTauIdx+1 if hasTau\n$ver3" + @assert all(x -> x[2] == ver3[1, :extT][2], ver3.extT) "The TinL must be firstTauIdx+2 if hasTau\n$ver3" + end + + #transform extT coloum into extT for Vertex4 and the extT for Gin and Gout + df = transform(ver3, :extT => ByRow(x -> [extT, (extT[1], x[2]), (x[3], extT[1])]) => [:extT, :GinT, :GoutT]) + + groups = mergeby(df, [:response, :GinT, :GoutT, :extT], operator=Sum()) + + for v3 in eachrow(groups) + response = v3.response + @assert response == UpUp || response == UpDown + #type: Instant or Dynamic + polarid = PolarId(para, response, k=extK, t=v3.extT) + gin = green(paraGin, K, v3.GinT, true, name=:Gin, blocks=blocks) + gout = green(paraGout, K .- extK, v3.GoutT, true, name=:Gout, blocks=blocks) + @assert gin isa Graph && gout isa Graph + + # polardiag = Diagram{W}(polarid, Prod(), [gin, gout, v3.diagram], name=name) + polardiag = Graph([gin, gout, v3.diagram], properties=polarid, operator=Prod(), name=name) + push!(polar, (response=response, extT=v3.extT, diagram=polardiag)) + end + end + end + end + + if isempty(polar) == false + polar = mergeby(polar, [:response, :extT]; name=name, + getid=g -> PolarId(para, g[1, :response], k=extK, t=extT) + ) + end + return polar +end + +function _properPolarPara(p::DiagPara, q) + # ############ reset transferLoop to be q ################ + if !(Proper in p.filter) || (length(p.transferLoop) != length(q)) || (p.transferLoop ≈ q) + return derivepara(p, transferLoop=q, filter=union(Proper, p.filter)) + end + return p +end \ No newline at end of file diff --git a/src/frontend/parquet/sigma.jl b/src/frontend/parquet/sigma.jl index 07b5daaf..36310a5c 100644 --- a/src/frontend/parquet/sigma.jl +++ b/src/frontend/parquet/sigma.jl @@ -1,6 +1,7 @@ """ - function sigma(para, extK = DiagTree.getK(para.totalLoopNum, 1), subdiagram = false; name = :Σ, resetuid = false, blocks::ParquetBlocks=ParquetBlocks()) - + function sigma(para::DiagPara, extK=getK(para.totalLoopNum, 1), subdiagram=false; + name=:Σ, resetuid=false, blocks::ParquetBlocks=ParquetBlocks()) + Build sigma diagram. When sigma is created as a subdiagram, then no Fock diagram is generated if para.filter contains NoFock, and no sigma diagram is generated if para.filter contains Girreducible @@ -16,7 +17,7 @@ When sigma is created as a subdiagram, then no Fock diagram is generated if para - A DataFrame with fields `:type`, `:extT`, `:diagram`, `:hash` - All sigma share the same incoming Tau index, but not the outgoing one """ -function sigma(para::DiagPara, extK=DiagTree.getK(para.totalLoopNum, 1), subdiagram=false; +function sigma(para::DiagPara, extK=getK(para.totalLoopNum, 1), subdiagram=false; name=:Σ, resetuid=false, blocks::ParquetBlocks=ParquetBlocks() ) resetuid && ComputationalGraphs.uidreset() diff --git a/src/frontend/parquet/sigmaGV.jl b/src/frontend/parquet/sigmaGV.jl new file mode 100644 index 00000000..976d09f9 --- /dev/null +++ b/src/frontend/parquet/sigmaGV.jl @@ -0,0 +1,130 @@ + +""" + function sigmaGV(para, extK = DiagTree.getK(para.totalLoopNum, 1), subdiagram = false; name = :Σ, resetuid = false, blocks::ParquetBlocks=ParquetBlocks()) + +Build sigma diagram. +When sigma is created as a subdiagram, then no Fock diagram is generated if para.filter contains NoFock, and no sigma diagram is generated if para.filter contains Girreducible + +# Arguments +- `para` : parameters. It should provide internalLoopNum, interactionTauNum, firstTauIdx +- `extK` : basis of external loop. +- `subdiagram` : a sub-vertex or not +- `name` : name of the diagram +- `resetuid` : restart uid count from 1 +- `blocks` : building blocks of the Parquet equation. See the struct ParquetBlocks for more details. + +# Output +- A DataFrame with fields `:type`, `:extT`, `:diagram`, `:hash` +- All sigma share the same incoming Tau index, but not the outgoing one +""" +function sigmaGV(para::DiagPara, extK=DiagTree.getK(para.totalLoopNum, 1), subdiagram=false; + name=:Σ, resetuid=false, blocks::ParquetBlocks=ParquetBlocks() +) + resetuid && uidreset() + for i in para.interaction + @assert (Dynamic in i.type) == false "Dynamic interaction is not supported for sigmaGV diagrams." + end + @assert NoHartree in para.filter "sigmaGV diagrams must have NoHartree in para.filter." + + (para.type == SigmaDiag) || error("$para is not for a sigma diagram") + (para.innerLoopNum >= 1) || error("sigma must has more than one inner loop") + # @assert length(extK) == para.totalLoopNum + # @assert (para.innerLoopNum <= 1) || ((NoBubble in para.filter) == false) "The many-body correction sigma only accounts for half of the bubble counterterm right now." + if (para.innerLoopNum > 1) && (NoBubble in para.filter) + @warn "Sigma with two or more loop orders still contain bubble subdiagram even if NoBubble is turned on in para.filter!" + end + + (length(extK) >= para.totalLoopNum) || error("expect dim of extK>=$(para.totalLoopNum), got $(length(extK))") + extK = extK[1:para.totalLoopNum] + + compositeSigma = DataFrame(type=AnalyticProperty[], extT=Tuple{Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + + if isValidSigma(para.filter, para.innerLoopNum, subdiagram) == false + # return DataFrame(type=[], extT=[], diagram=[]) + return compositeSigma + end + + # if (para.extra isa ParquetBlocks) == false + # parquetblocks = ParquetBlocks(phi=[PPr, PHEr], ppi=[PHr, PHEr], Γ4=[PPr, PHr, PHEr]) + # para::DiagPara = reconstruct(para, extra=parquetblocks) + # end + + K = zero(extK) + LoopIdx = para.firstLoopIdx + K[LoopIdx] = 1.0 + (isapprox(K, extK) == false) || error("K and extK can not be the same") + legK = [extK, K, K, extK] + + function GWwithGivenExTtoΣ(group, oW, paraG) + # println(group) + # @assert length(group[:, :diagram]) == 1 + # allsame(group, [:response, :type, :GT]) + (group[:response] == UpUp || group[:response] == UpDown) || error("GW with given ExT to Σ only works for UpUp or UpDown") + #type: Instant or Dynamic + response, type = group[:response], group[:type] + sid = SigmaId(para, type, k=extK, t=group[:extT]) + g = green(paraG, K, group[:GT], true; name=(oW == 0 ? :Gfock : :G_Σ), blocks=blocks) #there is only one G diagram for a extT + (g isa Graph) || error("green function must return a Graph") + # Sigma = G*(2 W↑↑ - W↑↓) + # ! The sign of ↑↓ is from the spin symmetry, not from the fermionic statistics! + spinfactor = (response == UpUp) ? 2 : -1 + if (oW > 0) # oW are composte Sigma, there is a symmetry factor 1/2 + spinfactor *= 0.5 + end + # plot_tree(mergeby(DataFrame(group)), maxdepth = 7) + sigmadiag = Graph([g, group[:diagram]], properties=sid, operator=Prod(), factor=spinfactor, name=name) + # plot_tree(sigmadiag, maxdepth = 7) + return (type=type, extT=group[:extT], diagram=sigmadiag) + end + + for (oG, oW) in orderedPartition(para.innerLoopNum - 1, 2, 0) + + idx, maxLoop = findFirstLoopIdx([oW, oG], LoopIdx + 1) + (maxLoop <= para.totalLoopNum) || error("maxLoop = $maxLoop > $(para.totalLoopNum)") + WfirstLoopIdx, GfirstLoopIdx = idx + + # it is important to do W first, because the left in of W is also the incoming leg of sigma, they have the same Tidx + idx, maxTau = findFirstTauIdx([oW, oG], [Ver3Diag, GreenDiag], para.firstTauIdx, interactionTauNum(para)) + (maxTau <= para.totalTauNum) || error("maxTau = $maxTau > $(para.totalTauNum)") + WfirstTauIdx, GfirstTauIdx = idx + + paraG = reconstruct(para, type=GreenDiag, innerLoopNum=oG, + firstLoopIdx=GfirstLoopIdx, firstTauIdx=GfirstTauIdx) + paraW = reconstruct(para, type=Ver3Diag, innerLoopNum=oW, + firstLoopIdx=WfirstLoopIdx, firstTauIdx=WfirstTauIdx) + + #TODO: add validation for paraW + # println("oG: $oG, oW: $oW -> ", isValidG(paraG)) + if isValidG(paraG) + # println(paraW) + paraW0 = reconstruct(paraW, filter=union(paraW.filter, Proper), transferLoop=zero(K)) + bareV = vertex4(paraW0, legK, [], true) + if oW == 0 # Fock-type Σ + ver4 = bareV + df = transform(ver4, :extT => ByRow(x -> [(x[INL], x[OUTR]), (x[OUTL], x[INR])]) => [:extT, :GT]) + + groups = mergeby(df, [:response, :type, :GT, :extT], operator=Sum()) + for mergedVer4 in eachrow(groups) + push!(compositeSigma, GWwithGivenExTtoΣ(mergedVer4, oW, paraG)) + end + else # composite Σ + ver3 = vertex3(paraW, [extK - K, extK, K]) + end + #transform extT coloum intwo extT for Σ and extT for G + # plot_tree(ver4) + end + end + + + if isempty(compositeSigma) + return compositeSigma + else + sigmadf = mergeby(compositeSigma, [:type, :extT], name=name, + getid=g -> SigmaId(para, g[1, :type], k=extK, t=g[1, :extT])) + + all(x -> x[1] == para.firstTauIdx, sigmadf.extT) || error("all sigma should share the same in Tidx\n$sigmadf") + # println(sigmadf) + # plot_tree(sigmadf) + return sigmadf + end +end \ No newline at end of file diff --git a/src/frontend/parquet/vertex3.jl b/src/frontend/parquet/vertex3.jl new file mode 100644 index 00000000..036a92c4 --- /dev/null +++ b/src/frontend/parquet/vertex3.jl @@ -0,0 +1,124 @@ +""" + function vertex3(para::DiagPara, _extK=[getK(para.totalLoopNum, 1), getK(para.totalLoopNum, 2)], subdiagram=false; + name=:Γ3, chan=[PHr, PHEr, PPr, Alli], resetuid=false, blocks::ParquetBlocks=ParquetBlocks()) + +Generate 3-vertex diagrams using Parquet Algorithm. +With imaginary-time variables, all vertex3 generated has the same bosonic Tidx ``extT[1]=para.firstTauIdx`` and the incoming fermionic Tidx ``extT[2]=para.firstTauIdx+1``. + +#Arguments +- `para` : parameters. It should provide internalLoopNum, interactionTauNum, firstTauIdx +- `extK` : basis of external loops as a vector [bosonic leg (out), fermionic in, fermionic out], extK[1] = extK[2] - extK[3]. +- `subdiagram` : a sub-vertex or not +- `name` : name of the vertex +- `chan` : vector of channels of the current 4-vertex. +- `resetuid` : restart uid count from 1 +- `blocks` : building blocks of the Parquet equation. See the struct ParquetBlocks for more details. + +# Output +- A DataFrame with fields :response, :extT, :diagram, :hash. +""" +function vertex3(para::DiagPara, + _extK=[getK(para.totalLoopNum, 1), getK(para.totalLoopNum, 2)], + subdiagram=false; + name=:Γ3, + chan=[PHr, PHEr, PPr, Alli], + resetuid=false, + blocks::ParquetBlocks=ParquetBlocks() +) + + resetuid && ComputationalGraphs.uidreset() + @assert para.type == Ver3Diag + @assert para.innerLoopNum >= 1 "Only generates vertex corrections with more than one internal loops." + for k in _extK + @assert length(k) >= para.totalLoopNum "expect dim of extK>=$(para.totalLoopNum), got $(length(k))" + end + + q, Kin = _extK[1][1:para.totalLoopNum], _extK[2][1:para.totalLoopNum] + # Kout = length(extK) == 3 ? extK[3] : Kin .- q + Kout = Kin - q + @assert ((q ≈ Kin) == false) && ((q ≈ Kout) == false) "The bosonic q cann't be same as the fermionic k. Ohterwise the proper diagram check will fail!" + extK = [q, Kin, Kout] + + para = _properVer3Para(para, q) + + t0 = para.firstTauIdx + vertex3 = DataFrame(response=Response[], extT=Tuple{Int,Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + + # if para.innerLoopNum == 0 + # push!(vertex3, (response = UpUp, extT = (t0, t0, t0), diagram = ver3diag)) + # end + + K = zero(q) + LoopIdx = para.firstLoopIdx + K[LoopIdx] = 1.0 + # extT = (t0, t0 + 1) + legK = [Kin, Kout, K, K .+ q] + + ######################## Π0 = GG ######################################### + for (oVer4, oGin, oGout) in orderedPartition(para.innerLoopNum - 1, 3, 0) + # ! Vertex4 must be in the first place, because we want to make sure that the TinL of the vertex4 start with t0+1 + + idx, maxLoop = findFirstLoopIdx([oVer4, oGin, oGout], LoopIdx + 1) + @assert maxLoop <= para.totalLoopNum "maxLoop = $maxLoop > $(para.totalLoopNum)" + Ver4Kidx, GinKidx, GoutKidx = idx + + ver4t0 = para.hasTau ? para.firstTauIdx + 1 : para.firstTauIdx + idx, maxTau = findFirstTauIdx([oVer4, oGin, oGout], [Ver4Diag, GreenDiag, GreenDiag], ver4t0, interactionTauNum(para)) + @assert maxTau <= para.totalTauNum "maxTau = $maxTau > $(para.totalTauNum)" + Ver4Tidx, GinTidx, GoutTidx = idx + + if isValidG(para.filter, oGin) && isValidG(para.filter, oGout) + paraGin = reconstruct(para, type=GreenDiag, innerLoopNum=oGin, + firstLoopIdx=GinKidx, firstTauIdx=GinTidx) + paraGout = reconstruct(para, type=GreenDiag, innerLoopNum=oGout, + firstLoopIdx=GoutKidx, firstTauIdx=GoutTidx) + paraVer4 = reconstruct(para, type=Ver4Diag, innerLoopNum=oVer4, + firstLoopIdx=Ver4Kidx, firstTauIdx=Ver4Tidx) + ver4 = vertex4(paraVer4, legK, chan, true; blocks=blocks) + if isnothing(ver4) || isempty(ver4) + continue + end + + if para.hasTau + @assert all(x -> x[INL] == ver4t0, ver4.extT) "The TinL of the inner Γ4 must be firstTauIdx+1" + end + + #transform extT coloum into extT for Vertex4 and the extT for Gin and Gout + df = transform(ver4, :extT => ByRow(x -> [(t0, x[INL], x[OUTL]), (t0, x[INR]), (x[OUTR], t0)]) => [:extT, :GinT, :GoutT]) + + groups = mergeby(df, [:response, :GinT, :GoutT, :extT], operator=Sum()) + + for v4 in eachrow(groups) + response = v4.response + @assert response == UpUp || response == UpDown + #type: Instant or Dynamic + ver3id = Ver3Id(para, response, k=extK, t=v4.extT) + gin = green(paraGin, K, v4.GinT, true, name=:Gin, blocks=blocks) + gout = green(paraGout, K .+ q, v4.GoutT, true, name=:Gout, blocks=blocks) + @assert gin isa Graph && gout isa Graph + + # ver3diag = Diagram{WW}(ver3id, Prod(), [gin, gout, v4.diagram], name=name) + ver3diag = Graph([gin, gout, v4.diagram], properties=ver3id, operator=Prod(), name=name) + push!(vertex3, (response=response, extT=v4.extT, diagram=ver3diag)) + end + end + end + # println(vertex3) + + if isempty(vertex3) == false + vertex3 = mergeby(vertex3, [:response, :extT]; name=name, + getid=g -> Ver3Id(para, g[1, :response], k=extK, t=g[1, :extT]) + ) + end + return vertex3 +end + +function _properVer3Para(p::DiagPara, q) + # ############ reset transferLoop to be q ################ + if Proper in p.filter + if (length(p.transferLoop) != length(q)) || (!(p.transferLoop ≈ q)) #first check if the dimension is wrong + return derivepara(p, transferLoop=q) + end + end + return p +end diff --git a/src/frontend/parquet/vertex4.jl b/src/frontend/parquet/vertex4.jl index 4f7b2adc..2a686ac8 100644 --- a/src/frontend/parquet/vertex4.jl +++ b/src/frontend/parquet/vertex4.jl @@ -1,6 +1,6 @@ """ vertex4(para::DiagPara, - extK = [DiagTree.getK(para.totalLoopNum, 1), DiagTree.getK(para.totalLoopNum, 2), DiagTree.getK(para.totalLoopNum, 3)], + extK = [getK(para.totalLoopNum, 1), getK(para.totalLoopNum, 2), getK(para.totalLoopNum, 3)], chan::AbstractVector = [PHr, PHEr, PPr, Alli], subdiagram = false; level = 1, name = :none, resetuid = false, @@ -25,7 +25,7 @@ Generate 4-vertex diagrams using Parquet Algorithm - A DataFrame with fields :response, :type, :extT, :diagram, :hash """ function vertex4(para::DiagPara, - extK=[DiagTree.getK(para.totalLoopNum, 1), DiagTree.getK(para.totalLoopNum, 2), DiagTree.getK(para.totalLoopNum, 3)], + extK=[getK(para.totalLoopNum, 1), getK(para.totalLoopNum, 2), getK(para.totalLoopNum, 3)], chan::AbstractVector=[PHr, PHEr, PPr, Alli], subdiagram=false; level=1, name=:none, resetuid=false, # phi_toplevel=ParquetBlocks().phi, ppi_toplevel=ParquetBlocks().ppi, Γ4_toplevel=ParquetBlocks().Γ4, diff --git a/src/strong_coupling_expansion_builder/Gc.jl b/src/frontend/strong_coupling_expansion_builder/Gc.jl similarity index 100% rename from src/strong_coupling_expansion_builder/Gc.jl rename to src/frontend/strong_coupling_expansion_builder/Gc.jl diff --git a/src/strong_coupling_expansion_builder/Gn.jl b/src/frontend/strong_coupling_expansion_builder/Gn.jl similarity index 100% rename from src/strong_coupling_expansion_builder/Gn.jl rename to src/frontend/strong_coupling_expansion_builder/Gn.jl diff --git a/src/strong_coupling_expansion_builder/common.jl b/src/frontend/strong_coupling_expansion_builder/common.jl similarity index 100% rename from src/strong_coupling_expansion_builder/common.jl rename to src/frontend/strong_coupling_expansion_builder/common.jl diff --git a/src/strong_coupling_expansion_builder/strong_coupling_expansion b/src/frontend/strong_coupling_expansion_builder/strong_coupling_expansion similarity index 100% rename from src/strong_coupling_expansion_builder/strong_coupling_expansion rename to src/frontend/strong_coupling_expansion_builder/strong_coupling_expansion diff --git a/src/strong_coupling_expansion_builder/vacuum.jl b/src/frontend/strong_coupling_expansion_builder/vacuum.jl similarity index 100% rename from src/strong_coupling_expansion_builder/vacuum.jl rename to src/frontend/strong_coupling_expansion_builder/vacuum.jl diff --git a/src/utility.jl b/src/utility.jl index fcda7a98..12b2b296 100644 --- a/src/utility.jl +++ b/src/utility.jl @@ -5,16 +5,16 @@ using ..ComputationalGraphs: decrement_power using ..ComputationalGraphs: build_all_leaf_derivative, eval!, isfermionic import ..ComputationalGraphs: count_operation, count_expanded_operation using ..ComputationalGraphs.AbstractTrees -using ..DiagTree -using ..DiagTree: Diagram, PropagatorId, BareGreenId, BareInteractionId +# using ..DiagTree +# using ..DiagTree: Diagram, PropagatorId, BareGreenId, BareInteractionId using ..Taylor @inline apply(::Type{ComputationalGraphs.Sum}, diags::Vector{T}, factors::Vector{F}) where {T<:TaylorSeries,F<:Number} = sum(d * f for (d, f) in zip(diags, factors)) @inline apply(::Type{ComputationalGraphs.Prod}, diags::Vector{T}, factors::Vector{F}) where {T<:TaylorSeries,F<:Number} = prod(d * f for (d, f) in zip(diags, factors)) @inline apply(::Type{ComputationalGraphs.Power{N}}, diags::Vector{T}, factors::Vector{F}) where {N,T<:TaylorSeries,F<:Number} = (diags[1])^N * factors[1] -@inline apply(::Type{DiagTree.Sum}, diags::Vector{T}, factors::Vector{F}) where {T<:TaylorSeries,F<:Number} = sum(d * f for (d, f) in zip(diags, factors)) -@inline apply(::Type{DiagTree.Prod}, diags::Vector{T}, factors::Vector{F}) where {T<:TaylorSeries,F<:Number} = prod(d * f for (d, f) in zip(diags, factors)) +# @inline apply(::Type{DiagTree.Sum}, diags::Vector{T}, factors::Vector{F}) where {T<:TaylorSeries,F<:Number} = sum(d * f for (d, f) in zip(diags, factors)) +# @inline apply(::Type{DiagTree.Prod}, diags::Vector{T}, factors::Vector{F}) where {T<:TaylorSeries,F<:Number} = prod(d * f for (d, f) in zip(diags, factors)) """ @@ -95,41 +95,6 @@ function taylorexpansion!(graph::FeynmanGraph{F,W}, var_dependence::Dict{Int,Vec end end -""" - function taylorexpansion!(graph::Diagram{W}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{G}}=Dict{Int,TaylorSeries{G}}()) where {W} - - Return a taylor series of Diagram g, together with a map of between nodes of g and correponding taylor series. -# Arguments: -- `graph` Target diagram -- `var_dependence::Dict{Int,Vector{Bool}}` A dictionary that specifies the variable dependence of target diagram leaves. Should map the id of each leaf to a Bool vector. - The length of the vector should be the same as number of variables. -- `to_coeff_map::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target diagram to its correponding taylor series. -""" -function taylorexpansion!(graph::Diagram{W}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W} - if haskey(to_coeff_map, graph.hash) #If already exist, use taylor series in to_coeff_map. - return to_coeff_map[graph.hash], to_coeff_map - - elseif isempty(graph.subdiagram) - if haskey(var_dependence, graph.hash) - var = var_dependence[graph.hash] - else - var = fill(false, get_numvars()) #if dependence not provhashed, assume the graph depends on no variables - end - ordtuple = ((var[idx]) ? (0:get_orders(idx)) : (0:0) for idx in 1:get_numvars()) - result = TaylorSeries{Graph{W,W}}() - for order in collect(Iterators.product(ordtuple...)) #varidx specifies the variables graph depends on. Iterate over all taylor coefficients of those variables. - o = collect(order) - coeff = Graph([]; operator=ComputationalGraphs.Sum(), factor=graph.factor, properties=graph.id, orders=o) - result.coeffs[o] = coeff - end - to_coeff_map[graph.hash] = result - return result, to_coeff_map - else - to_coeff_map[graph.hash] = graph.factor * apply(typeof(graph.operator), [taylorexpansion!(sub, var_dependence; to_coeff_map=to_coeff_map)[1] for sub in graph.subdiagram], ones(W, length(graph.subdiagram))) - return to_coeff_map[graph.hash], to_coeff_map - end -end - """ function taylorexpansion!(graph::FeynmanGraph{F,W}, propagator_var::Tuple{Vector{Bool},Vector{Bool}}, label::Tuple{LabelProduct,LabelProduct}; to_coeff_map::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}()) where {F,W} @@ -162,21 +127,21 @@ end """ function taylorexpansion!(graph::Diagram{W}, propagator_var::Dict{DataType,Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W} - + Return a taylor series of Diagram g, together with a map of between nodes of g and correponding taylor series. In this set up, the leaves that are the same type of diagrams (such as Green functions) depend on the same set of variables. - + # Arguments: - `graph` Target Diagram - `propagator_var::Dict{DataType,Vector{Bool}}` A dictionary that specifies the variable dependence of different types of diagrams. Should be a map between DataTypes in DiagramID and Bool vectors. The dependence is given by a vector of the length same as the number of variables. - `to_coeff_map::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target diagram to its correponding taylor series. """ -function taylorexpansion!(graph::Diagram{W}, propagator_var::Dict{DataType,Vector{Bool}}; - to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W} +function taylorexpansion!(graph::Graph{F,W}, propagator_var::Dict{DataType,Vector{Bool}}; + to_coeff_map::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 haskey(propagator_var, typeof(leaf.id)) - var_dependence[leaf.hash] = [propagator_var[typeof(leaf.id)][idx] ? true : false for idx in 1:get_numvars()] + if haskey(propagator_var, typeof(leaf.properties)) + var_dependence[leaf.id] = [propagator_var[typeof(leaf.properties)][idx] ? true : false for idx in 1:get_numvars()] end end return taylorexpansion!(graph, var_dependence; to_coeff_map=to_coeff_map) @@ -192,17 +157,8 @@ function taylorexpansion!(graphs::Vector{G}, var_dependence::Dict{Int,Vector{Boo return result, to_coeff_map end -function taylorexpansion!(graphs::Vector{Diagram{W}}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); - to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W} - result = Vector{TaylorSeries{Graph{W,W}}}() - for graph in graphs - taylor, _ = taylorexpansion!(graph, var_dependence; to_coeff_map=to_coeff_map) - push!(result, taylor) - end - return result, to_coeff_map -end - -function taylorexpansion!(graphs::Vector{FeynmanGraph{F,W}}, propagator_var::Tuple{Vector{Bool},Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}()) where {F,W} +function taylorexpansion!(graphs::Vector{FeynmanGraph{F,W}}, propagator_var::Tuple{Vector{Bool},Vector{Bool}}; + to_coeff_map::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}()) where {F,W} result = Vector{TaylorSeries{Graph{F,W}}}() for graph in graphs taylor, _ = taylorexpansion!(graph, propagator_var; to_coeff_map=to_coeff_map) @@ -211,9 +167,9 @@ function taylorexpansion!(graphs::Vector{FeynmanGraph{F,W}}, propagator_var::Tup return result, to_coeff_map end -function taylorexpansion!(graphs::Vector{Diagram{W}}, propagator_var::Dict{DataType,Vector{Bool}}; - to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W} - result = Vector{TaylorSeries{Graph{W,W}}}() +function taylorexpansion!(graphs::Vector{Graph{F,W}}, propagator_var::Dict{DataType,Vector{Bool}}; + to_coeff_map::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}()) where {F,W} + result = Vector{TaylorSeries{Graph{F,W}}}() for graph in graphs taylor, _ = taylorexpansion!(graph, propagator_var; to_coeff_map=to_coeff_map) push!(result, taylor) diff --git a/test/front_end.jl b/test/front_end.jl index f05a585c..c5dad0d3 100644 --- a/test/front_end.jl +++ b/test/front_end.jl @@ -59,4 +59,710 @@ end @test eltype(typeof(labelProd)) == (eltype(typeof(flavors)), eltype(typeof(tau_labels)), eltype(typeof(loopbasis))) @test FrontEnds._find_label(typeof(labelProd.labels), typeof(loopbasis)) == 3 +end + +@testset "Parquet" begin + using FeynmanDiagram: ComputationalGraphs as Graphs + Ftype, Wtype = Graphs._dtype.factor, Graphs._dtype.weight + + @testset "Parameter" begin + p = DiagPara(type=Ver4Diag, innerLoopNum=1) + q = DiagPara(type=Ver4Diag, innerLoopNum=2) + a = DiagPara(type=Ver4Diag, innerLoopNum=2) + + @test p != q + @test q == a + + aa = reconstruct(a, transferLoop=[0.0, 0.0, 0.0]) + @test a != aa + + # reconstruct with the same type but different interaction + aaa = reconstruct(a, interaction=[]) + @test a != aaa + + # reconstruct with different diagram type leads to different parameter + #reconstructed DiagPara uses the old parameters such as firstLoopIdx, totalLoopNum etc., which are different between types + s = reconstruct(a, type=SigmaDiag) + ss = DiagPara(type=SigmaDiag, innerLoopNum=2) + @test s != ss + + end + + @testset "Partition" begin + p = Parquet.orderedPartition(5, 2) + expect = [[4, 1], [1, 4], [2, 3], [3, 2]] + @test Set(p) == Set(expect) + + p = Parquet.orderedPartition(3, 2, 0) + expect = [[3, 0], [0, 3], [1, 2], [2, 1]] + @test Set(p) == Set(expect) + end + + @testset "FindFirstIdx" begin + function testLoopIdx(partition, firstidx, expected) + firstLoopIdx, total = Parquet.findFirstLoopIdx(partition, firstidx) + @test firstLoopIdx == expected + totalExp = sum(partition) + firstidx - 1 + @test total == totalExp + end + + testLoopIdx([1, 1, 2, 1], 1, [1, 2, 3, 5]) + testLoopIdx([1, 1, 2, 1], 0, [0, 1, 2, 4]) + testLoopIdx([1, 0, 2, 0], 1, [1, 2, 2, 4]) + testLoopIdx([1,], 1, [1,]) + + function testTauIdx(partition, isG, firstidx, tauNum, expected) + firstIdx, total = Parquet.findFirstTauIdx(partition, isG, firstidx, tauNum) + @test firstIdx == expected + end + tauNum = 1 + # isG = [false, true, false, true] + isG = [Ver4Diag, GreenDiag, Ver4Diag, GreenDiag] + testTauIdx([1, 1, 2, 1], isG, 1, tauNum, [1, 3, 4, 7]) + testTauIdx([1, 1, 2, 1], isG, 0, tauNum, [0, 2, 3, 6]) + testTauIdx([1, 0, 2, 0], isG, 1, tauNum, [1, 3, 3, 6]) + + end + + @testset "Filter" begin + # for G irreducible diagrams, only 0-loop G is allowed + @test Parquet.isValidG([Girreducible,], 0) == true + @test Parquet.isValidG([Girreducible,], 1) == false + @test Parquet.isValidG([Girreducible,], 2) == false + + # for Fock irreducible diagrams, only 0-loop or 2, 3, 4...-loop G is allowed + @test Parquet.isValidG([NoFock,], 0) == true + @test Parquet.isValidG([NoFock,], 1) == true + #one-loop G diagram becomes invalid only if both Hartree and Fock are filtered + @test Parquet.isValidG([NoFock, NoHartree], 1) == false + @test Parquet.isValidG([NoFock, NoHartree], 2) == true + + # for G irreducible diagrams, no sigma subdiagram is allowed + @test Parquet.isValidSigma([Girreducible,], 0, true) == false + @test Parquet.isValidSigma([Girreducible,], 1, true) == false + @test Parquet.isValidSigma([Girreducible,], 2, true) == false + + @test Parquet.isValidSigma([Girreducible,], 0, false) == false + @test Parquet.isValidSigma([Girreducible,], 1, false) == true + @test Parquet.isValidSigma([Girreducible,], 2, false) == true + + # for Fock irreducible diagrams, no Fock sigma subdiagram is allowed + @test Parquet.isValidSigma([NoFock,], 0, true) == false + #one-loop sigma diagram can be either Hartree or Fock diagram + #one-loop sigma sub-diagram becomes invalid only if both Hartree and Fock are filtered + @test Parquet.isValidSigma([NoFock,], 1, true) == true + @test Parquet.isValidSigma([NoFock, NoHartree], 1, true) == false + @test Parquet.isValidSigma([NoFock, NoHartree], 2, true) == true + + @test Parquet.isValidSigma([NoFock,], 0, false) == false + @test Parquet.isValidSigma([NoFock,], 1, false) == true + @test Parquet.isValidSigma([NoFock, NoHartree], 1, false) == true + @test Parquet.isValidSigma([NoFock,], 2, false) == true + end + + function getdiagram(spin=2.0, D=3, Nk=4, Nt=2) + """ + k1-k3 k2+k3 + | | + t1.L ↑ t1.L t2.L ↑ t2.L + |-------------->----------| + | | k3+k4 | | + | v | | v | + | | k4 | | + |--------------<----------| + t1.L ↑ t1.L t2.L ↑ t2.L + | | + k1 k2 + """ + + Graphs.uidreset() + # We only consider the direct part of the above diagram + + paraG = DiagPara(type=GreenDiag, + innerLoopNum=0, totalLoopNum=Nk, + hasTau=true, totalTauNum=Nt) + paraV = paraG + + # #construct the propagator table + gK = [[0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 0.0, 1.0]] + gT = [(1, 2), (2, 1)] + g = [Graph([], properties=BareGreenId(paraG, k=gK[i], t=gT[i]), name=:G) for i in 1:2] + + vdK = [[0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 1.0, 0.0]] + # vdT = [[1, 1], [2, 2]] + vd = [Graph([], properties=BareInteractionId(paraV, ChargeCharge, k=vdK[i]), name=:Vd) for i in 1:2] + + veK = [[1, 0, -1, -1], [0, 1, 0, -1]] + # veT = [[1, 1], [2, 2]] + ve = [Graph([], properties=BareInteractionId(paraV, ChargeCharge, k=veK[i]), name=:Ve) for i in 1:2] + + Id = GenericId(paraV) + # contruct the tree + ggn = Graph([g[1], g[2]], properties=Id, operator=Graphs.Prod()) + vdd = Graph([vd[1], vd[2]], properties=Id, operator=Graphs.Prod(), factor=spin) + vde = Graph([vd[1], ve[2]], properties=Id, operator=Graphs.Prod(), factor=-1.0) + ved = Graph([ve[1], vd[2]], properties=Id, operator=Graphs.Prod(), factor=-1.0) + vsum = Graph([vdd, vde, ved], properties=Id, operator=Graphs.Sum()) + root = Graph([vsum, ggn], properties=Id, operator=Graphs.Prod(), factor=1 / (2π)^D, name=:root) + + return root, gK, gT, vdK, veK + end + + function assign_leaves(g::Graph, taylormap) #This should be written more generic later. + #For bench mark purpose, currently it assigns taylor coefficients of leaves with 1.0 / taylor_factorial(order)) so that it corresponds to assign all derivatives with 1. + leafmap = Dict{Int,Int}() + leafvec = Vector{Float64}() + idx = 0 + for leaf in Leaves(g) + taylor = taylormap[leaf.id] + for (order, coeff) in taylor.coeffs + idx += 1 + push!(leafvec, 1.0 / Taylor.taylor_factorial(order)) + leafmap[coeff.id] = idx + #print("assign $(order) $(coeff.id) $(taylor_factorial(order)) $(leafvec[idx])\n") + end + end + return leafmap, leafvec + end + + + @testset "Generic Parquet-generated graphs" begin + Graphs.uidreset() + # We only consider the direct part of the above diagram + spin = 1.0 + D = 3 + kF, β, mass2 = 1.919, 0.5, 1.0 + Nk, Nt = 4, 2 + + root, gK, gT, vdK, veK = getdiagram(spin, D, Nk, Nt) + rootval = Graphs.eval!(root) + Graphs.optimize!([root]) + @test Graphs.eval!(root) == rootval + + # autodiff + factor = 1 / (2π)^D + Taylor.set_variables("x y"; orders=[1, 1]) + propagator_var = Dict(BareGreenId => [true, false], BareInteractionId => [false, true]) # Specify variable dependence of fermi (first element) and bose (second element) particles. + t, taylormap = Utility.taylorexpansion!(root, propagator_var) + + taylorleafmap, taylorleafvec = assign_leaves(root, taylormap) + @test eval!(t.coeffs[[0, 0]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * factor + @test eval!(t.coeffs[[0, 1]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 2 * factor / Taylor.taylor_factorial([0, 1]) + @test eval!(t.coeffs[[1, 0]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 2 * factor / Taylor.taylor_factorial([1, 0]) + + # #more sophisticated test of the weight evaluation + varK = rand(D, Nk) + varT = [rand() * β for t in 1:Nt] + + function evalG(K, τBasis, varT, order=0) + ϵ = dot(K, K) / 2 - kF^2 + τ = varT[τBasis[2]] - varT[τBasis[1]] + if order == 0 + return Spectral.kernelFermiT(τ, ϵ, β) + elseif order == 1 + return Spectral.kernelFermiT(τ, ϵ, β) * 3.1415 + else + error("not implemented!") + end + end + + function evalV(K, order=0) + if order == 0 + return 8π / (dot(K, K) + mass2) + elseif order == 1 + return 8π / (dot(K, K) + mass2) * 3.1415 + else + error("not implemented!") + end + end + + # # getK(basis, varK) = sum([basis[i] * K for (i, K) in enumerate(varK)]) + getK(basis, varK) = varK * basis + + # eval(id::BareGreenId, varK, varT) = evalG(getK(id.extK, varK), id.extT, varT, id.order[1]) + # eval(id::BareInteractionId, varK, varT) = evalV(getK(id.extK, varK), id.order[2]) + + # gw = [evalG(getK(gK[i], varK), gT[i], varT) for i = 1:2] + # vdw = [evalV(getK(vdK[i], varK)) for i = 1:2] + # vew = [evalV(getK(veK[i], varK)) for i = 1:2] + + # dgw = [evalG(getK(gK[i], varK), gT[i], varT, 1) for i = 1:2] + # dvdw = [evalV(getK(vdK[i], varK), 1) for i = 1:2] + # dvew = [evalV(getK(veK[i], varK), 1) for i = 1:2] + + # Vweight = spin * vdw[1] * vdw[2] - vdw[1] * vew[2] - vew[1] * vdw[2] + # Gweight = gw[1] * gw[2] + # Weight = Gweight * Vweight / (2π)^D + + # dVweight = spin * (dvdw[1] * vdw[2] + vdw[1] * dvdw[2]) - + # (dvdw[1] * vew[2] + vdw[1] * dvew[2]) - + # (dvew[1] * vdw[2] + vew[1] * dvdw[2]) + + # dGweight = dgw[1] * gw[2] + gw[1] * dgw[2] + # dWeight_dg = dGweight * Vweight / (2π)^D + # dWeight_dv = Gweight * dVweight / (2π)^D + + + end + + function evalG(K, τin, τout) + # println(τBasis, ", ", varT) + kF, β = 1.0, 1.0 + ϵ = dot(K, K) / 2 - kF^2 + τ = τout - τin + if τ ≈ 0.0 + return Spectral.kernelFermiT(-1e-8, ϵ, β) + else + return Spectral.kernelFermiT(τ, ϵ, β) + end + end + evalV(K) = 8π / (dot(K, K) + 1) + + evalGfixK(K, τin, τout) = evalG(zero(K), τin, τout) + evalVfixK(K) = 1.0 + + evalFakeG(K, τin, τout) = 1.0 + evalFakeV(K) = 1.0 + + ################## api for expression tree ############################## + evalPropagator(id::BareGreenId, K, extT, varT) = evalG(K, varT[extT[1]], varT[extT[2]]) + evalPropagator(id::BareInteractionId, K, extT, varT) = evalV(K) + evalPropagatorfixK(id::BareGreenId, K, extT, varT) = evalGfixK(K, varT[extT[1]], varT[extT[2]]) + evalPropagatorfixK(id::BareInteractionId, K, extT, varT) = evalVfixK(K) + evalFakePropagator(id::PropagatorId, K, extT, varT) = 1.0 + + # @testset "ep Ver4" begin + # loopnum = 2 + # para = DiagPara(type=Ver4Diag, hasTau=true, innerLoopNum=loopnum, interaction=[Interaction(ChargeCharge, [Instant, Dynamic])]) + # Parquet.ep_coupling(para) # make sure ep_coupling runs + # end + + @testset "Ver4 RPA chain" begin + + loopnum = 3 + + para = DiagPara(type=Ver4Diag, hasTau=true, innerLoopNum=loopnum, interaction=[Interaction(ChargeCharge, [Instant, Dynamic])]) + + + legK1, legK2, legK3 = Parquet.getK(para.totalLoopNum, 1), Parquet.getK(para.totalLoopNum, 2), Parquet.getK(para.totalLoopNum, 3) + extK = [legK1, legK2, legK3, legK1 + legK3 - legK2] + level = 0 + + varK = rand(3, para.totalLoopNum) + varT = [rand() for i in 1:para.totalTauNum] + + weight = (2^loopnum) * (2^(loopnum + 1)) + + ############ PHEr ############ + c = PHEr + ver4df = DataFrame(response=Response[], type=AnalyticProperty[], extT=Tuple{Int,Int,Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + Parquet.RPA_chain!(ver4df, para, extK, c, level, :RPA, -1.0) + diags = mergeby(ver4df, :response) + # DiagTree.evalKT!(diags, varK, varT; eval=evalFakePropagator) + Graphs.eval!.(diags.diagram) + w = [diags.diagram[1].weight, diags.diagram[2].weight] + # plot_tree(diags, maxdepth=15) + # println(w1) + #each bubble contribute 2, each dynamic interaction contribute 2, and there is two spin configuration upup, updown + @test w[1] ≈ -weight #additional minus sign from the exchange diagram + @test w[2] ≈ 0.0 # updown is not allowed in exchange diagram + + + ############ PHr ############ + c = PHr + ver4df = DataFrame(response=Response[], type=AnalyticProperty[], extT=Tuple{Int,Int,Int,Int}[], diagram=Graph{Ftype,Wtype}[]) + Parquet.RPA_chain!(ver4df, para, extK, c, level, :RPA, -1.0) + diags = mergeby(ver4df, :response) + # DiagTree.evalKT!(diags, varK, varT; eval=evalFakePropagator) + Graphs.eval!.(diags.diagram) + w = [diags.diagram[1].weight, diags.diagram[2].weight] + # plot_tree(diags, maxdepth=15) + # println(w1) + weight = (2^loopnum) * (2^(loopnum + 1)) + #each bubble contribute 2, each dynamic interaction contribute 2, and there is two spin configuration upup, updown + @test w[1] ≈ weight + @test w[2] ≈ weight + end + + + @testset "ParquetNew Ver4" begin + Benchmark = Parquet.Benchmark + + function getfunction(type) + if type == :physical + return evalG, evalV, evalPropagator + elseif type == :fixK + return evalGfixK, evalVfixK, evalPropagatorfixK + elseif type == :fake + return evalFakeG, evalFakeV, evalFakePropagator + else + error("not implemented") + end + end + + function testVertex4(loopNum, chan, type::Symbol; filter=[NoHartree,], timing=false, toeval=true) + println("$(Int.(chan)) Channel Test") + Kdim, spin = 3, 2 + interactionTauNum = 1 + isFermi = true + + K0 = zeros(loopNum + 2) + KinL, KoutL, KinR, KoutR = deepcopy(K0), deepcopy(K0), deepcopy(K0), deepcopy(K0) + KinL[1] = KoutL[1] = 1 + KinR[2] = KoutR[2] = 1 + legK = [KinL, KoutL, KinR, KoutR] + + blocks = ParquetBlocks(phi=[PHEr, PPr], ppi=[PHr, PHEr]) + + para = DiagPara( + type=Ver4Diag, + # loopDim=Kdim, + isFermi=isFermi, + hasTau=true, + innerLoopNum=loopNum, + totalLoopNum=length(KinL), + totalTauNum=(loopNum + 1) * interactionTauNum, + spin=spin, + firstLoopIdx=3, + firstTauIdx=1, + filter=union(filter, [Girreducible,]), #ver4 evaluation only support one-particle-irreducible diagram + transferLoop=KinL - KoutL, + interaction=[Interaction(ChargeCharge, Instant),], + extra=blocks + ) + + varK = rand(Kdim, para.totalLoopNum) + varT = [rand() for i in 1:para.totalTauNum] + + #################### DiagTree #################################### + diags = Parquet.vertex4(para, legK, chan) + diags = mergeby(diags, :response) + # DiagTreeNew.plot_tree(diags[1]) + # DiagTreeNew.plot_tree(diags[2]) + + ################### ExprTree ################################### + # tree = ExprTree.build(diags.diagram, Kdim) + # println("root", root) + + ################### original Parquet builder ################################### + ver4 = Benchmark.Ver4{Benchmark.Weight}(para, Int.(chan), Int.(blocks.phi), Int.(blocks.ppi)) + + + if toeval + + evalG, evalV, evalPropagator = getfunction(type) + + # DiagTree.evalKT!(diags, varK, varT; eval=evalPropagator) + Graphs.eval!.(diags.diagram) + w1 = [diags.diagram[1].weight, diags.diagram[2].weight] + if timing + printstyled("naive Graph evaluator cost:", color=:green) + # @time DiagTree.evalKT!(diags, varK, varT; eval=evalPropagator) + @time Graphs.eval!.(diags.diagram) + end + + Graphs.optimize!(diags.diagram) + Graphs.eval!.(diags.diagram) + w1opt = [diags.diagram[1].weight, diags.diagram[2].weight] + if timing + printstyled("naive optimized Graph evaluator cost:", color=:green) + @time Graphs.eval!.(diags.diagram) + end + + # ExprTree.evalNaive!(tree, varK, varT; eval=evalPropagator) + # w1e = [tree[1], tree[2]] + # if timing + # printstyled("naive ExprTree cost:", color=:green) + # @time ExprTree.evalKT!(tree, varK, varT; eval=evalPropagator) + # end + + + # optdiags = DiagTree.optimize!(diags.diagram) + # opttree = ExprTree.build(diags.diagram, Kdim) + # ExprTree.evalKT!(opttree, varK, varT; eval=evalPropagator) + # w1eopt = [opttree[1], opttree[2]] + + # if timing + # printstyled("naive optimized ExprTree cost:", color=:green) + # @time ExprTree.evalKT!(opttree, varK, varT; eval=evalPropagator) + # end + + ##################### lower level subroutines ####################################### + + KinL, KoutL, KinR, KoutR = varK[:, 1], varK[:, 1], varK[:, 2], varK[:, 2] + legK = [KinL, KoutL, KinR, KoutR] + # Benchmark.eval(para, ver4, varK, varT, [KinL, KoutL, KinR, KoutR], evalG, evalV, true) + Benchmark.eval(para, ver4, varK, varT, legK, evalG, evalV, true) + + if timing + printstyled("parquet evaluator cost:", color=:green) + # @btime sin(p, ver4, var) setup = (x = rand()) + # @time Benchmark.eval(para, ver4, varK, varT, [KinL, KoutL, KinR, KoutR], evalG, evalV, true) + @time Benchmark.eval(para, ver4, varK, varT, legK, evalG, evalV, true) + # @btime Benchmark.eval(p, v4, vK, vT, lK, eG, eV, flag) setup = (p = para, v4 = ver4, vK = varK, vT = varT, l = legK, eG = evalG, eV = evalV, flag = true) + end + + w2 = ver4.weight[1] + + # println(w1, " vs ", w1e, " vs ", w2) + + # @assert w1 ≈ w1e + @assert w1 ≈ w1opt + + # The upup channel of charge-charge vertex4 == Direct + exchange + # @test w1[1] ≈ w2[1] + w2[2] + # # The updown channel of charge-charge vertex4 == Direct + # @test w1[2] ≈ w2[1] + + end + + return para, diags, ver4 + end + + function testEval(type) + for l = 1:3 + testVertex4(l, [PHr,], type) + testVertex4(l, [PHEr,], type) + testVertex4(l, [PPr,], type) + testVertex4(l, [PHr, PHEr, PPr], type; timing=true) + end + end + + # testEval(:fake) + # testEval(:fixK) + testEval(:physical) + + #test only proper diagrams are generated if the switch is turned on + # para, diag, ver4 = testVertex4(3, [Parquet.T, Parquet.U, Parquet.S], :physical; filter = [Builder.Proper], eval = false) + # for i in 1:length(diag.basisPool) + # @test (diag.basisPool.basis[:, i] ≈ para.transferLoop) == false + # end + end + + @testset "Parquet Sigma" begin + function getSigma(loopNum; Kdim=3, spin=2, interactionTauNum=1, filter=[NoHartree,], isFermi=true, subdiagram=false) + println("LoopNum =$loopNum Sigma Test") + + para = DiagPara( + type=SigmaDiag, + # loopDim=Kdim, + hasTau=true, + innerLoopNum=loopNum, + totalLoopNum=loopNum + 1, + totalTauNum=loopNum * interactionTauNum, + isFermi=isFermi, + spin=spin, + firstLoopIdx=2, + firstTauIdx=1, + filter=filter, + interaction=[Interaction(ChargeCharge, Instant),], + extra=ParquetBlocks(phi=[PHEr, PPr], ppi=[PHr, PHEr]) + ) + + extK = zeros(para.totalLoopNum) + extK[1] = 1.0 + + varK = rand(Kdim, para.totalLoopNum) + varT = [rand() for i in 1:para.totalTauNum] + + #################### DiagTree #################################### + diag = Parquet.sigma(para, extK, subdiagram) + diag = mergeby(diag) + # print_tree(diag.diagram[1]) + + return para, diag.diagram[1], varK, varT + end + + + function testDiagramNumber(para, diag, varK, varT) + w = Graphs.eval!(diag) + # plot_tree(diag, maxdepth = 7) + # factor = (1 / (2π)^para.loopDim)^para.innerLoopNum + factor = 1.0 + num = w / factor + @test num * (-1)^(para.innerLoopNum) ≈ Parquet.Benchmark.count_sigma_G2v(para.innerLoopNum, para.spin) + end + + + ################## G^2*v expansion ######################################### + for l = 1:4 + # ret = getSigma(l, spin = 1, isFermi = false, filter = [Builder.Girreducible,]) + # testDiagramNumber(ret...) + ret = getSigma(l, spin=2, isFermi=false, filter=[NoHartree, Girreducible,]) + testDiagramNumber(ret...) + end + + # para, diag, varK, varT = getSigma(1, spin = 2, isFermi = false, filter = [Builder.NoFock,], subdiagram = true) + # @test isempty(diag.root) + + end + + @testset "Green" begin + function buildG(loopNum, extT; Kdim=3, spin=2, interactionTauNum=1, filter=[NoHartree,], isFermi=true) + para = DiagPara( + type=GreenDiag, + # loopDim=Kdim, + hasTau=true, + innerLoopNum=loopNum, + isFermi=isFermi, + spin=spin, + filter=filter, + interaction=[Interaction(ChargeCharge, Instant),] + ) + extK = zeros(para.totalLoopNum) + extK[1] = 1.0 + if Parquet.isValidG(para) + G = Parquet.green(para, extK, extT) + return G + else + return nothing + end + end + # diag, Gidx = buildG(2, [1, 2], 3; filter = []) + # DiagTree.showTree(diag, Gidx) + + # If G is irreducible, then only loop-0 G exist for main diagram, and no G exist for subdiagram + G = buildG(0, [1, 2]; filter=[NoHartree, Girreducible,]) + @test G isa Graph + G = buildG(1, [1, 2]; filter=[NoHartree, Girreducible,]) + @test isnothing(G) + G = buildG(2, [1, 2]; filter=[NoHartree, Girreducible,]) + @test isnothing(G) + + # If Fock diagram is not allowed, then one-loop G diagram should not be exist for subdiagram + G = buildG(0, [1, 2]; filter=[NoHartree, NoFock,]) + @test G isa Graph + G = buildG(1, [1, 2]; filter=[NoHartree, NoFock,]) + @test isnothing(G) + G = buildG(2, [1, 2]; filter=[NoHartree, NoFock,]) #high order subdiagram is allowed + @test G isa Graph + + end + + + @testset "Parquet Vertex3" begin + function getGamma3(loopNum; Kdim=3, spin=2, interactionTauNum=1, filter=[NoHartree, Girreducible, Proper,], isFermi=true, subdiagram=false) + println("LoopNum =$loopNum Vertex3 Test") + + para = DiagPara( + type=Ver3Diag, + # loopDim=Kdim, + innerLoopNum=loopNum, + isFermi=isFermi, + hasTau=true, + filter=filter, + interaction=[Interaction(ChargeCharge, Instant),] + ) + + K0 = zeros(para.totalLoopNum) + KinL, Q = deepcopy(K0), deepcopy(K0) + Q[1] = 1 + KinL[2] = 1 + legK = [Q, KinL] + + varK = rand(Kdim, para.totalLoopNum) + varT = [rand() for i in 1:para.totalTauNum] + + #################### DiagTree #################################### + vertex3 = Parquet.vertex3(para, legK) + diag = mergeby(vertex3) + # print_tree(diag.diagram[1]) + + return para, diag.diagram[1], varK, varT + end + + + function testDiagramNumber(para, diag, varK, varT) + # w = DiagTree.evalKT!(diag, varK, varT; eval=evalFakePropagator) + w = Graphs.eval!(diag) + # plot_tree(diag, maxdepth = 9) + # factor = (1 / (2π)^para.loopDim)^para.innerLoopNum + factor = 1.0 + num = w / factor + @test num * (-1)^(para.innerLoopNum) ≈ Parquet.Benchmark.count_ver3_G2v(para.innerLoopNum, para.spin) + end + + + ################## G^2*v expansion ######################################### + for l = 1:3 + # ret = getSigma(l, spin = 1, isFermi = false, filter = [Builder.Girreducible,]) + # testDiagramNumber(ret...) + ret = getGamma3(l, isFermi=false, filter=[NoHartree, Girreducible, Proper]) + testDiagramNumber(ret...) + end + + # para, diag, varK, varT = getSigma(1, spin = 2, isFermi = false, filter = [Builder.NoFock,], subdiagram = true) + # @test isempty(diag.root) + + end + + + @testset "Parquet Polarization" begin + function getPolar(loopNum; Kdim=3, spin=2, interactionTauNum=1, filter=[NoHartree, Girreducible,], isFermi=true, subdiagram=false) + println("LoopNum =$loopNum Polarization Test") + + para = DiagPara( + type=PolarDiag, + # loopDim=Kdim, + innerLoopNum=loopNum, + isFermi=isFermi, + hasTau=true, + filter=filter, + interaction=[Interaction(ChargeCharge, Instant),] + ) + + Q = zeros(para.totalLoopNum) + Q[1] = 1 + + varK = rand(Kdim, para.totalLoopNum) + varT = [rand() for i in 1:para.totalTauNum] + + #################### DiagTree #################################### + diag = Parquet.polarization(para, Q) + # print_tree(diag.diagram[1]) + return para, diag, varK, varT + end + + # Test polarization Parquet builder when filter 'Proper' is specified explicitly + getPolar(1, filter=[Proper, NoHartree, NoFock,]) + + ################## G^2*v expansion ######################################### + for l = 1:4 + para, diag, varK, varT = getPolar(l, isFermi=false, filter=[NoHartree, Girreducible,]) + diag = mergeby(diag).diagram[1] + # w = DiagTree.evalKT!(diag, varK, varT; eval=evalFakePropagator) + w = Graphs.eval!(diag) + # factor = (1 / (2π)^para.loopDim)^para.innerLoopNum + factor = 1.0 + num = w / factor + # println(num * para.spin) + @test num * para.spin * (-1)^(para.innerLoopNum - 1) ≈ Parquet.Benchmark.count_polar_G2v(para.innerLoopNum, para.spin) + end + + ################## g^2*v expansion ######################################### + for l = 1:4 + para, diag, varK, varT = getPolar(l, isFermi=false, filter=[NoHartree, NoFock,]) + diag = mergeby(diag).diagram[1] + # w = DiagTree.evalKT!(diag, varK, varT, eval=evalFakePropagator) + w = Graphs.eval!(diag) + # factor = (1 / (2π)^para.loopDim)^para.innerLoopNum + factor = 1.0 + num = w / factor + # println(num * para.spin) + @test num * para.spin * (-1)^(para.innerLoopNum - 1) ≈ Parquet.Benchmark.count_polar_g2v_noFock(para.innerLoopNum, para.spin) + end + + ################## g^2*v expansion for the upup polarization ######################################### + for l = 1:4 + para, diag, varK, varT = getPolar(l, isFermi=false, filter=[NoHartree, NoFock,]) + # w = DiagTree.evalKT!(diag.diagram[1], varK, varT, eval=evalFakePropagator) + w = Graphs.eval!(diag.diagram[1]) + # factor = (1 / (2π)^para.loopDim)^para.innerLoopNum + factor = 1.0 + num = w / factor + # println(num * para.spin) + # println("$diag") + @test num * para.spin * (-1)^(para.innerLoopNum - 1) ≈ Parquet.Benchmark.count_polar_g2v_noFock_upup(para.innerLoopNum, para.spin) + end + end end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 635665b0..22914595 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -38,12 +38,10 @@ end # doctest(FeynmanDiagram) # end if isempty(ARGS) - include("common.jl") include("quantum_operator.jl") include("computational_graph.jl") - include("diagram_tree.jl") - include("expression_tree.jl") - include("parquet_builder.jl") + # include("diagram_tree.jl") + # include("graph_deriv.jl") include("compiler.jl") include("front_end.jl") include("taylor.jl") diff --git a/test/taylor.jl b/test/taylor.jl index 83934d53..d3fc6f13 100644 --- a/test/taylor.jl +++ b/test/taylor.jl @@ -1,6 +1,7 @@ using FeynmanDiagram using FeynmanDiagram: Taylor as Taylor -using ..DiagTree +using FeynmanDiagram: ComputationalGraphs as Graphs + function assign_random_numbers(g, taylormap1, taylormap2) #Benchmark taylor expansion generated by two different methods leafmap1 = Dict{Int,Int}() leafvec1 = Vector{Float64}() @@ -61,29 +62,31 @@ end eval!, forwardAD, node_derivative, backAD, build_all_leaf_derivative, count_operation using FeynmanDiagram.Utility: taylorexpansion!, build_derivative_backAD! - g1 = Graph([]) - g2 = Graph([]) - g3 = Graph([], factor=2.0) - G3 = g1 - G4 = 1.0 * g1 * g1 - G5 = 1.0 * (3.0 * G3 + 0.5 * G4) - G6 = (1.0 * g1 + 2.0 * g2) * (g1 + g3) - - set_variables("x y z", orders=[2, 3, 2]) - var_dependence = Dict{Int,Vector{Bool}}() - for G in [G3, G4, G5, G6] - for leaf in Leaves(G) - if !haskey(var_dependence, leaf.id) - var_dependence[leaf.id] = [true for _ in 1:get_numvars()] - end - end - T, taylormap = taylorexpansion!(G, var_dependence) - T_compare, taylormap_compare = build_derivative_backAD!(G) - leafmap1, leafvec1, leafmap2, leafvec2 = assign_random_numbers(G, taylormap, taylormap_compare) - for (order, coeff) in T_compare.coeffs - @test eval!(coeff, leafmap2, leafvec2) ≈ taylor_factorial(order) * eval!(T.coeffs[order], leafmap1, leafvec1) - end - end + + ### backAD has bugs! + # g1 = Graph([]) + # g2 = Graph([]) + # g3 = Graph([], factor=2.0) + # G3 = g1 + # G4 = 1.0 * g1 * g1 + # G5 = 1.0 * (3.0 * G3 + 0.5 * G4) + # G6 = (1.0 * g1 + 2.0 * g2) * (g1 + g3) + + # set_variables("x y z", orders=[2, 3, 2]) + # var_dependence = Dict{Int,Vector{Bool}}() + # for G in [G3, G4, G5, G6] + # for leaf in Leaves(G) + # if !haskey(var_dependence, leaf.id) + # var_dependence[leaf.id] = [true for _ in 1:get_numvars()] + # end + # end + # T, taylormap = taylorexpansion!(G, var_dependence) + # T_compare, taylormap_compare = build_derivative_backAD!(G) + # leafmap1, leafvec1, leafmap2, leafvec2 = assign_random_numbers(G, taylormap, taylormap_compare) + # for (order, coeff) in T_compare.coeffs + # @test eval!(coeff, leafmap2, leafvec2) ≈ taylor_factorial(order) * eval!(T.coeffs[order], leafmap1, leafvec1) + # end + # end end @@ -110,7 +113,6 @@ end end end - function getdiagram(spin=2.0, D=3, Nk=4, Nt=2) """ k1-k3 k2+k3 @@ -126,10 +128,10 @@ function getdiagram(spin=2.0, D=3, Nk=4, Nt=2) k1 k2 """ - DiagTree.uidreset() + Graphs.uidreset() # We only consider the direct part of the above diagram - paraG = DiagParaF64(type=GreenDiag, + paraG = DiagPara(type=GreenDiag, innerLoopNum=0, totalLoopNum=Nk, hasTau=true, totalTauNum=Nt) paraV = paraG @@ -137,35 +139,35 @@ function getdiagram(spin=2.0, D=3, Nk=4, Nt=2) # #construct the propagator table gK = [[0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 0.0, 1.0]] gT = [(1, 2), (2, 1)] - g = [Diagram{Float64}(BareGreenId(paraG, k=gK[i], t=gT[i]), name=:G) for i in 1:2] + g = [Graph([], properties=BareGreenId(paraG, k=gK[i], t=gT[i]), name=:G) for i in 1:2] vdK = [[0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 1.0, 0.0]] # vdT = [[1, 1], [2, 2]] - vd = [Diagram{Float64}(BareInteractionId(paraV, ChargeCharge, k=vdK[i], permu=Di), name=:Vd) for i in 1:2] + vd = [Graph([], properties=BareInteractionId(paraV, ChargeCharge, k=vdK[i]), name=:Vd) for i in 1:2] veK = [[1, 0, -1, -1], [0, 1, 0, -1]] # veT = [[1, 1], [2, 2]] - ve = [Diagram{Float64}(BareInteractionId(paraV, ChargeCharge, k=veK[i], permu=Ex), name=:Ve) for i in 1:2] + ve = [Graph([], properties=BareInteractionId(paraV, ChargeCharge, k=veK[i]), name=:Ve) for i in 1:2] Id = GenericId(paraV) # contruct the tree - ggn = Diagram{Float64}(Id, Prod(), [g[1], g[2]]) - vdd = Diagram{Float64}(Id, Prod(), [vd[1], vd[2]], factor=spin) - vde = Diagram{Float64}(Id, Prod(), [vd[1], ve[2]], factor=-1.0) - ved = Diagram{Float64}(Id, Prod(), [ve[1], vd[2]], factor=-1.0) - vsum = Diagram{Float64}(Id, Sum(), [vdd, vde, ved]) - root = Diagram{Float64}(Id, Prod(), [vsum, ggn], factor=1 / (2π)^D, name=:root) + ggn = Graph([g[1], g[2]], properties=Id, operator=Graphs.Prod()) + vdd = Graph([vd[1], vd[2]], properties=Id, operator=Graphs.Prod(), factor=spin) + vde = Graph([vd[1], ve[2]], properties=Id, operator=Graphs.Prod(), factor=-1.0) + ved = Graph([ve[1], vd[2]], properties=Id, operator=Graphs.Prod(), factor=-1.0) + vsum = Graph([vdd, vde, ved], properties=Id, operator=Graphs.Sum()) + root = Graph([vsum, ggn], properties=Id, operator=Graphs.Prod(), factor=1 / (2π)^D, name=:root) return root, gK, gT, vdK, veK end -function assign_leaves(g::Diagram, taylormap) #This should be written more generic later. +function assign_leaves(g::Graph, taylormap) #This should be written more generic later. #For bench mark purpose, currently it assigns taylor coefficients of leaves with 1.0 / taylor_factorial(order)) so that it corresponds to assign all derivatives with 1. leafmap = Dict{Int,Int}() leafvec = Vector{Float64}() idx = 0 for leaf in Leaves(g) - taylor = taylormap[leaf.hash] + taylor = taylormap[leaf.id] for (order, coeff) in taylor.coeffs idx += 1 push!(leafvec, 1.0 / taylor_factorial(order)) @@ -177,10 +179,9 @@ function assign_leaves(g::Diagram, taylormap) #This should be written more gener end -@testset "Taylor AD of DiagTree" begin - +@testset "Taylor AD of Parquet-generated Graph" begin - DiagTree.uidreset() + Graphs.uidreset() # We only consider the direct part of the above diagram spin = 0.5 D = 3 @@ -190,45 +191,20 @@ end root, gK, gT, vdK, veK = getdiagram(spin, D, Nk, Nt) #optimize the diagram - DiagTree.optimize!([root,]) + Graphs.optimize!([root,]) # autodiff - droot_dg = DiagTree.derivative([root,], BareGreenId)[1] - droot_dv = DiagTree.derivative([root,], BareInteractionId)[1] - droot_dvdg = DiagTree.derivative([droot_dg,], BareInteractionId)[1] - droot_dvdv = DiagTree.derivative([droot_dv,], BareInteractionId)[1] - droot_dgdg = DiagTree.derivative([droot_dg,], BareGreenId)[1] - # plot_tree(droot_dg) factor = 1 / (2π)^D - DiagTree.eval!(root; eval=(x -> 1.0)) - @test root.weight ≈ (-2 + spin) * factor - - DiagTree.eval!(droot_dg; eval=(x -> 1.0)) - @test droot_dg.weight ≈ (-2 + spin) * 2 * factor - - DiagTree.eval!(droot_dv; eval=(x -> 1.0)) - @test droot_dv.weight ≈ (-2 + spin) * 2 * factor - - DiagTree.eval!(droot_dvdv; eval=(x -> 1.0)) - @test droot_dv.weight ≈ (-2 + spin) * 2 * factor - - DiagTree.eval!(droot_dvdg; eval=(x -> 1.0)) - @test droot_dv.weight ≈ (-2 + spin) * 2 * factor - - DiagTree.eval!(droot_dgdg; eval=(x -> 1.0)) - @test droot_dv.weight ≈ (-2 + spin) * 2 * factor - set_variables("x y"; orders=[2, 2]) - - propagator_var = Dict(DiagTree.BareGreenId => [true, false], DiagTree.BareInteractionId => [false, true]) # Specify variable dependence of fermi (first element) and bose (second element) particles. + propagator_var = Dict(BareGreenId => [true, false], BareInteractionId => [false, true]) # Specify variable dependence of fermi (first element) and bose (second element) particles. t, taylormap = taylorexpansion!(root, propagator_var) taylorleafmap, taylorleafvec = assign_leaves(root, taylormap) - @test eval!(t.coeffs[[0, 0]], taylorleafmap, taylorleafvec) ≈ root.weight - @test eval!(t.coeffs[[0, 1]], taylorleafmap, taylorleafvec) ≈ droot_dv.weight / taylor_factorial([0, 1]) - @test eval!(t.coeffs[[1, 0]], taylorleafmap, taylorleafvec) ≈ droot_dg.weight / taylor_factorial([1, 0]) - @test eval!(t.coeffs[[1, 1]], taylorleafmap, taylorleafvec) ≈ droot_dvdg.weight / taylor_factorial([1, 1]) - @test eval!(t.coeffs[[2, 0]], taylorleafmap, taylorleafvec) ≈ droot_dgdg.weight / taylor_factorial([2, 0]) - @test eval!(t.coeffs[[0, 2]], taylorleafmap, taylorleafvec) ≈ droot_dvdv.weight / taylor_factorial([0, 2]) + @test eval!(t.coeffs[[0, 0]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * factor + @test eval!(t.coeffs[[0, 1]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 2 * factor / taylor_factorial([0, 1]) + @test eval!(t.coeffs[[1, 0]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 2 * factor / taylor_factorial([1, 0]) + @test eval!(t.coeffs[[1, 1]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 4 * factor / taylor_factorial([1, 1]) + @test eval!(t.coeffs[[2, 0]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 4 * factor / taylor_factorial([2, 0]) + @test eval!(t.coeffs[[0, 2]], taylorleafmap, taylorleafvec) ≈ (-2 + spin) * 4 * factor / taylor_factorial([0, 2]) end