diff --git a/docs/make.jl b/docs/make.jl index d287d1d..edc9fef 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,12 +1,13 @@ using GreenFunc using Documenter +using Documenter.Remotes: GitHub DocMeta.setdocmeta!(GreenFunc, :DocTestSetup, :(using GreenFunc); recursive=true) makedocs(; modules=[GreenFunc], authors="Kun Chen, Tao Wang, Xiansheng Cai, PengCheng Hou, and Zhiyi Li", - repo="https://github.com/numericaleft/GreenFunc.jl/blob/{commit}{path}#{line}", + repo=GitHub("numericaleft/GreenFunc.jl"), sitename="GreenFunc.jl", format=Documenter.HTML(; prettyurls=get(ENV, "CI", "false") == "true", diff --git a/docs/src/index.md b/docs/src/index.md index 1a38d65..876262b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -22,24 +22,31 @@ GreenFunc.jl is a differentiable numerical framework to manipulate multidimensio - Interface to the [`TRIQS`](https://triqs.github.io/) library. ## Installation -This package has been registered. So, simply type `import Pkg; Pkg.add("GreenFunc")` in the Julia REPL to install. +This package has been registered. So, simply type +```julia +import Pkg; Pkg.add("GreenFunc") +``` +in the Julia REPL to install. ## Basic Usage ### Example 1: Green's function of a single level We first show how to use `MeshArray` to present Green's function of a single-level quantum system filled with spinless fermionic particles. We assume that the system could exchange particles and energy with the environment so that it's equilibrium state is a grand canonical ensemble. The single-particle Green's function then has a simple form in Matsubara-frequency representation: $G(ωₙ) = \frac{1}{(iωₙ - E)}$ where $E$ is the level energy. We show how to generate and manipulate this Green's function. - -```julia - using GreenFunc - β = 100.0; E = 1.0 # inverse temperature and the level energy - ωₙ_mesh = MeshGrids.ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy - Gn = MeshArray(ωₙ_mesh; dtype=ComplexF64); # Green's function defined on the ωₙ_mesh - - for (n, ωₙ) in enumerate(Gn.mesh[1]) - Gn[n] = 1/(ωₙ*im - E) - end +```julia +using GreenFunc + +# inverse temperature and the level energy +β = 100.0; E = 1.0 +# UV energy cutoff is 100 times larger than the level energy +ωₙ_mesh = MeshGrids.ImFreq(100.0, FERMION; Euv = 100E) +# Green's function defined on the ωₙ_mesh +Gn = MeshArray(ωₙ_mesh; dtype=ComplexF64) + +for (n, ωₙ) in enumerate(Gn.mesh[1]) + Gn[n] = 1/(ωₙ*im - E) +end ``` - Green's function describes correlations between two or more spacetime events. The spacetime continuum needs to be discretized into spatial and temporal meshes. This example demonstrates how to define a one-body Green's function on a temporal mesh. The package provides three types of temporal meshes: imaginary-time grid, Matsubara-frequency grid, and DLR grid. The latter provides a generic compressed representation for Green's functions (We will show how to use DLR later). Correspondingly, They can be created with the `ImTime`, `ImFreq`, and `DLRFreq` methods. The user needs to specify the inverse temperature, whether the particle is fermion or boson (using the constant `FERMION` or `BOSON`). Internally, a set of non-uniform grid points optimized for the given inverse temperature and the cutoff energy will be created with the given parameters. @@ -50,19 +57,24 @@ We first show how to use `MeshArray` to present Green's function of a single-lev ### Example 2: Green's function of a free electron gas -Now let us show how to create a Green's function of a free electron gas. Unlike the spinless fermionic particle, the electron is a spin-1/2 particle so that it has two inner states. In free space, it has a kinetic energy $ϵ_q = q^2-E$ (we use the unit where $m_e = 1/2$). The Green's function in Matsubara-frequency space is then given by the following equation: $G_n = G_{\sigma_1, \sigma_2}(q,\omega_n) = \frac{1}{i \omega_n - \epsilon_q}$, where $\sigma_i$ denotes the spins of the incoming and the outgoing electron in the propagator. We inherit the Matsubara-frequency grid from the first example. We show how to use the `CompositeGrids` package to generate momentum grids and how to treat the multiple inner states and the meshes with `MeshArray`. +Now let us show how to create a Green's function of a free electron gas. Unlike the spinless fermionic particle, the electron is a spin-1/2 particle so that it has two inner states. In free space, it has a kinetic energy ``ϵ_q = q^2-E`` (we use the unit where ``m_e = 1/2``). The Green's function in Matsubara-frequency space is then given by the following equation: ``G_n = G_{\sigma_1, \sigma_2}(q,\omega_n) = \frac{1}{i \omega_n - \epsilon_q}``, where ``\sigma_i`` denotes the spins of the incoming and the outgoing electron in the propagator. We inherit the Matsubara-frequency grid from the first example. We show how to use the `CompositeGrids` package to generate momentum grids and how to treat the multiple inner states and the meshes with `MeshArray`. ```julia - using GreenFunc, CompositeGrids - β = 100.0; E = 1.0 # inverse temperature and the level energy - ωₙ_mesh = MeshGrids.ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy - kmesh = SimpleGrid.Uniform{Float64}([0.0, 10.0], 50); # initialze an uniform momentum grid - G_n = MeshArray(1:2, 1:2, kmesh, ωₙ_mesh; dtype=ComplexF64); # Green's function of free electron gas with 2x2 innerstates - - for ind in eachindex(G_n) - q = G_n.mesh[3][ind[3]] - ω_n = G_n.mesh[4][ind[4]] - G_n[ind] = 1/(ω_n*im - (q^2-E)) - end +using GreenFunc, CompositeGrids + +# inverse temperature and the level energy +β = 100.0; E = 1.0 +# UV energy cutoff is 100 times larger than the level energy +ωₙ_mesh = MeshGrids.ImFreq(100.0, FERMION; Euv = 100E) +# initialze an uniform momentum grid +kmesh = SimpleGrid.Uniform{Float64}([0.0, 10.0], 50) +# Green's function of free electron gas with 2x2 innerstates +G_n = MeshArray(1:2, 1:2, kmesh, ωₙ_mesh; dtype=ComplexF64) + +for ind in eachindex(G_n) + q = G_n.mesh[3][ind[3]] + ω_n = G_n.mesh[4][ind[4]] + G_n[ind] = 1/(ω_n*im - (q^2-E)) +end ``` - One can generate various types of grids with the `CompositeGrids` package. The `SimpleGrid` module here provides several basic grids, such as uniform grids and logarithmically dense grids. The` Uniform` method here generates a 1D linearly spaced grid. The user has to specify the number of grid points `N` and the boundary points `[min, max]`. One can also combine arbitrary numbers of `SimpleGrid` subgrids with a user-specified pattern defined by a `panel grid`. These more advanced grids optimized for different purposes can be found in this [link](https://github.com/numericalEFT/CompositeGrids.jl). @@ -70,26 +82,26 @@ Now let us show how to create a Green's function of a free electron gas. Unlike ### Example 3: Green's function of a Hubbard lattice -Now we show how to generate a multi-dimensional Green's function on a Brillouin Zone meshe. We calculate the Green's function of a free spinless Fermi gas on a square lattice. It has a tight-binding dispersion $\epsilon_q = -2t(\cos(q_x)+\cos(q_y))$, which gives -$G(q, \omega_n) = \frac{1}{i\omega_n - \epsilon_q}$. +Now we show how to generate a multi-dimensional Green's function on a Brillouin Zone meshe. We calculate the Green's function of a free spinless Fermi gas on a square lattice. It has a tight-binding dispersion ``\epsilon_q = -2t(\cos(q_x)+\cos(q_y))``, which gives +``G(q, \omega_n) = \frac{1}{i\omega_n - \epsilon_q}``. The momentum is defined on the first Brillouin zone captured by a 2D k-mesh. ```julia - using GreenFunc - using GreenFunc: BrillouinZoneMeshes - - DIM, nk = 2, 8 - latvec = [1.0 0.0; 0.0 1.0] .* 2π - bzmesh = BrillouinZoneMeshes.BaseMesh.UniformMesh{DIM, nk}([0.0, 0.0], latvec) - ωₙmesh = ImFreq(10.0, FERMION) - g_freq = MeshArray(bzmesh, ωₙmesh; dtype=ComplexF64) - - t = 1.0 - for ind in eachindex(g_freq) - q = g_freq.mesh[1][ind[1]] - ωₙ = g_freq.mesh[2][ind[2]] - g_freq[ind] = 1/(ωₙ*im - (-2*t*sum(cos.(q)))) - end +using GreenFunc +using GreenFunc: BrillouinZoneMeshes + +DIM, nk = 2, 8 +latvec = [1.0 0.0; 0.0 1.0] .* 2π +bzmesh = BrillouinZoneMeshes.BaseMesh.UniformMesh{DIM, nk}([0.0, 0.0], latvec) +ωₙmesh = ImFreq(10.0, FERMION) +g_freq = MeshArray(bzmesh, ωₙmesh; dtype=ComplexF64) + +t = 1.0 +for ind in eachindex(g_freq) + q = g_freq.mesh[1][ind[1]] + ωₙ = g_freq.mesh[2][ind[2]] + g_freq[ind] = 1/(ωₙ*im - (-2*t*sum(cos.(q)))) +end ``` - For lattice systems with multi-dimensional Brillouin zone, the momentum grids internally generated with the [`BrillouinZoneMeshes.jl`](https://github.com/numericalEFT/BrillouinZoneMeshes.jl) package. Here a `UniformMesh{DIM,N}(origin, latvec)` generates a linearly spaced momentum mesh on the first Brillouin zone defined by origin and lattice vectors given. For more detail, see the [link](https://github.com/numericalEFT/BrillouinZoneMeshes.jl). @@ -100,27 +112,27 @@ DLR provides a compact representation for one-body Green's functions. At a tempe In the following example, we demonstrate how to perform DLR-based Fourier transform in `GreenFunc.jl` between the imaginary-time and the Matsubara-frequency domains back and forth through the DLR representation. ```julia - using GreenFunc, CompositeGrids +using GreenFunc, CompositeGrids - β = 100.0; E = 1.0 # inverse temperature and the level energy - ωₙ_mesh = ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy - kmesh = SimpleGrid.Uniform{Float64}([0.0, 10.0], 50); # initialze an uniform momentum grid - G_n = MeshArray(1:2, 1:2, kmesh, ωₙ_mesh; dtype=ComplexF64); # Green's function of free electron gas with 2x2 innerstates +β = 100.0; E = 1.0 # inverse temperature and the level energy +ωₙ_mesh = ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy +kmesh = SimpleGrid.Uniform{Float64}([0.0, 10.0], 50); # initialze an uniform momentum grid +G_n = MeshArray(1:2, 1:2, kmesh, ωₙ_mesh; dtype=ComplexF64); # Green's function of free electron gas with 2x2 innerstates - for ind in eachindex(G_n) - q = G_n.mesh[3][ind[3]] - ω_n = G_n.mesh[4][ind[4]] - G_n[ind] = 1/(im*ω_n - (q^2-E)) - end +for ind in eachindex(G_n) + q = G_n.mesh[3][ind[3]] + ω_n = G_n.mesh[4][ind[4]] + G_n[ind] = 1/(im*ω_n - (q^2-E)) +end - G_dlr = to_dlr(G_n) # convert G_n to DLR space - G_tau = to_imtime(G_dlr) # convert G_dlr to the imaginary-time domain +G_dlr = to_dlr(G_n) # convert G_n to DLR space +G_tau = to_imtime(G_dlr) # convert G_dlr to the imaginary-time domain - #alternative, you can use the pipe operator - G_tau = G_n |> to_dlr |> to_imtime #Fourier transform to (k, tau) domain +#alternative, you can use the pipe operator +G_tau = G_n |> to_dlr |> to_imtime #Fourier transform to (k, tau) domain ``` -The imaginary-time Green's function after the Fourier transform shoud be consistent with the analytic solution $G_{\tau} = -e^{-\tau \epsilon_q}/(1+e^{-\beta \epsilon_q})$. +The imaginary-time Green's function after the Fourier transform shoud be consistent with the analytic solution ``G_{\tau} = -e^{-\tau \epsilon_q}/(1+e^{-\beta \epsilon_q})``. - For any Green's function that has at least one imaginary-temporal grid (`ImTime`, `ImFreq`, and `DLRFreq`) in meshes, we provide a set of operations (`to_dlr`, `to_imfreq` and `to_imtime`) to bridge the DLR space with imaginary-time and Matsubara-frequency space. By default, all these functions find the dimension of the imaginary-temporal mesh within Green's function meshes and perform the transformation with respect to it. Alternatively, one can specify the dimension with the optional keyword argument `dim`. Be careful that the original version of DLR is only guaranteed to work with one-body Green's function. diff --git a/example/SYK.jl b/example/SYK.jl index 4deed44..7877e42 100644 --- a/example/SYK.jl +++ b/example/SYK.jl @@ -1,23 +1,27 @@ """ A SYK model solver based on a forward fixed-point iteration method. - The self-energy of the SYK model is given by, +The self-energy of the SYK model is given by, - Σ(τ) = J² * G(τ) * G(τ) * G(β-τ), +```math +Σ(τ) = J² * G(τ) * G(τ) * G(β-τ), +``` - where Green's function of the SYK model is given by the Dyson equation, +where Green's function of the SYK model is given by the Dyson equation, - G(iωₙ) = -1/(iωₙ -μ + Σ(iωₙ)) +```math +G(iωₙ) = -1/(iωₙ -μ + Σ(iωₙ)) +``` - We solve the Dyson equation self-consistently by a weighted fixed point iteration, - with weight `mix` assigned to the new iterate and weight `1-mix` assigned to the previous iterate. +We solve the Dyson equation self-consistently by a weighted fixed point iteration, +with weight `mix` assigned to the new iterate and weight `1-mix` assigned to the previous iterate. - The self-energy is evaluated in the imaginary time domain, - and the Dyson equation is solved in the Matsubara frequency domain. +The self-energy is evaluated in the imaginary time domain, +and the Dyson equation is solved in the Matsubara frequency domain. - The SYK Green's function has particle-hole symmetry when μ=0. - You may enforce such symmetry by setting `symmetry = :ph` when initialize the DLR grids. - A symmetrized solver tends to be more robust than a unsymmetrized one. +The SYK Green's function has particle-hole symmetry when μ=0. +You may enforce such symmetry by setting `symmetry = :ph` when initialize the DLR grids. +A symmetrized solver tends to be more robust than a unsymmetrized one. """ using GreenFunc @@ -76,4 +80,3 @@ for (i, t) in enumerate(G.mesh[1]) @printf("%15.8f%40.15f%40.15f%40.15f\n", t, imag(G[i]), real(G[i]), conformal_tau(t, β)) end println() - diff --git a/src/green/DictParser.jl b/src/green/DictParser.jl index 4c1068d..6c64e2a 100644 --- a/src/green/DictParser.jl +++ b/src/green/DictParser.jl @@ -3,7 +3,7 @@ module DictParser export evalwithdict """ -evalwithdict(e::Union{Expr,Symbol,Number}, map::Dict{Symbol,Number}) + evalwithdict(e::Union{Expr,Symbol,Number}, map::Dict{Symbol,Number}) Evaluate the result produced by Meta.parse, looking up the values of user-defined variables in "map". Argument "e" is a Union, because @@ -79,4 +79,4 @@ end function f(::Val{:^}, args, map::Dict{Symbol,Number}) return f(args[1], map) ^ f(args[2], map) end -end # module MyEval \ No newline at end of file +end # module MyEval diff --git a/src/green/transform.jl b/src/green/transform.jl index f68fcb5..353de70 100644 --- a/src/green/transform.jl +++ b/src/green/transform.jl @@ -78,17 +78,19 @@ end """ Base.:<<(objL::MeshArray, objR::MeshArray) -DLR Fourier transform of functions on the first temporal grid (ImTime, ImFreq or DLRFreq). +DLR Fourier transform of functions on the first temporal grid (`ImTime`, `ImFreq`, or `DLRFreq`). -- If objL and objR have identical temporal grid, objL< 0 "No temporal can be transformed to dlr." @@ -243,11 +245,12 @@ end """ function to_dlr(mesharray[; dim]) -Calculate the DLR sepctral density of an imaginary-time or Matsubara-frequency Green's function. +Calculate the DLR spectral density of an imaginary-time or Matsubara-frequency Green's function. -#Arguements -- 'mesharray': MeshArray in the imaginary-time or the Matsubara-frequency domain. -- `dim`: The dimension of the mesh to be transformed. Default value is the first dimension with mesh type ImTime or ImFreq. +# Arguments +- `mesharray`: MeshArray in the imaginary-time or the Matsubara-frequency domain. +- `dim`: The dimension of the mesh to be transformed. + Default value is the first dimension with mesh type `ImTime` or `ImFreq`. """ function to_dlr(obj::MeshArray{T,N,MT}; dim::Int=_find_mesh(MT, ImTime, ImFreq) @@ -269,9 +272,10 @@ end Transform a Green's function to the imaginary-time domain. -#Arguements -- 'mesharray': MeshArray in the imaginary-time, the Matsubara-frequency or the DLR frequency domain. -- `dim`: The dimension of the mesh to be transformed. Default value is the first dimension with mesh type DLRFreq, ImTime or ImFreq. +# Arguments +- `mesharray`: MeshArray in the imaginary-time, the Matsubara-frequency or the DLR frequency domain. +- `dim`: The dimension of the mesh to be transformed. + Default value is the first dimension with mesh type `DLRFreq`, `ImTime` or `ImFreq`. """ function to_imtime(obj::MeshArray{T,N,MT}; dim::Int=_find_mesh(MT, ImTime, ImFreq, DLRFreq) @@ -291,9 +295,10 @@ end Transform a Green's function to the Matsubara-frequency domain. -#Arguements -- 'mesharray': MeshArray in the imaginary-time, the Matsubara-frequency or the DLR frequency domain. -- `dim`: The dimension of the mesh to be transformed. Default value is the first dimension with mesh type DLRFreq, ImTime or ImFreq. +# Arguments +- `mesharray`: MeshArray in the imaginary-time, the Matsubara-frequency or the DLR frequency domain. +- `dim`: The dimension of the mesh to be transformed. + Default value is the first dimension with mesh type `DLRFreq`, `ImTime` or `ImFreq`. """ function to_imfreq(obj::MeshArray{T,N,MT}; dim::Int=_find_mesh(MT, ImTime, ImFreq, DLRFreq) @@ -341,6 +346,7 @@ end # return nothing # end +# """ # Return the single-particle density matrix of the Green's function `obj`. # """ # function density(obj::MeshArray; kwargs...) @@ -349,12 +355,12 @@ end # end #rMatrix transform of the target space of a matrix valued Greens function. -#Sets the current Greens function :math:`g_{ab}` to the matrix transform of :math:`G_{cd}` -#using the left and right transform matrices :math:`L_{ac}` and :math:`R_{db}`. -#.. math:: +#Sets the current Greens function :math:`g_{ab}` to the matrix transform of ``G_{cd}`` +#using the left and right transform matrices ``L_{ac}`` and ``R_{db}``. +#```math #g_{ab} = \sum_{cd} L_{ac} G_{cd} R_{db} - - +#``` +# # """ # def from_L_G_R(self, L, G, R): # Parameters @@ -392,4 +398,4 @@ end # """ # function from_L_G_R(self,L,G::MeshArray,R) # return 1 -# end \ No newline at end of file +# end diff --git a/src/mesharrays/dense.jl b/src/mesharrays/dense.jl index 7fc8df5..84ec161 100644 --- a/src/mesharrays/dense.jl +++ b/src/mesharrays/dense.jl @@ -7,23 +7,23 @@ The mesh is stored in the field `mesh` and the data is stored in the field `data # Parameters: - `T`: type of data -- `MT`: type of mesh, e.g., Tuple{MeshType1, MeshType2, ...} +- `MT`: type of mesh, e.g., `Tuple{MeshType1, MeshType2, ...}` - `N`: number of dimensions # Members: -- `mesh` (MT): the mesh is a tuple of meshes. +- `mesh` (`MT`): the mesh is a tuple of meshes. The mesh should be an iterable object that contains an ordered list of grid points. Examples are the 1. Meshes defined in the `MeshGrids` module. 2. UnitRange such as `1:10`, etc. - 2. Product of meshes `MeshProduct` defined in the `MeshGrids` module. + 3. Product of meshes `MeshProduct` defined in the `MeshGrids` module. If a mesh is defined on a continuous manifold and supports the following methods, then one can perform interpolation, derivatives, etc. on the mesh: - `locate(mesh, value)`: find the index of the closest grid point for given value; - `volume(mesh, index)`: find the volume of grid space near the point at griven index. - `volume(mesh, gridpoint)`: locate the corresponding index of a given grid point and than find the volume spanned by the grid point. -- `data`: Array{T,N}: the data. +- `data` (`Array{T,N}`): the data. - `dims`: dimension of the data """ struct MeshArray{T,N,MT} <: AbstractMeshArray{T,N} @@ -154,7 +154,8 @@ function Base.similar(obj::MeshArray{T,N,MT}, ::Type{S}) where {T,MT,N,S} return MeshArray(mesh=obj.mesh, dtype=S, data=similar(obj.data, S)) end Base.similar(obj::MeshArray{T,N,MT}) where {T,MT,N} = Base.similar(obj, T) -#By default, the following functions will all call Base.similar(obj::MeshArray, ::Type{S}, inds) as explained in https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array +#By default, the following functions will all call Base.similar(obj::MeshArray, ::Type{S}, inds) +#as explained in https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array #`Base.similar(obj::MeshArray, ::Type{S}, inds)`: Return a slice of obj.data. #However, we don't want that since slice of GreeNew itself is not well defined with meshes. @@ -203,10 +204,8 @@ end # end function Base.show(io::IO, obj::MeshArray) - print(io, "Meshed array with dims = $(obj.dims) and total length = $(length(obj.data))\n" - * - "- Mesh: $(typeof(obj.mesh)) \n" - ) + print(io, "Meshed array with dims = $(obj.dims) and total length = $(length(obj.data))\n", + "- Mesh: $(typeof(obj.mesh)) \n") end Base.show(io::IO, ::MIME"text/plain", obj::MeshArray) = Base.show(io, obj) @@ -269,4 +268,3 @@ function _check(objL::MeshArray, objR::MeshArray) # @assert objL.tgrid == objR.tgrid "Green's function time grids are not compatible:\n $(objL.tgrid)\nand\n $(objR.tgrid)" # @assert objL.mesh == objR.mesh "Green's function meshes are not compatible:\n $(objL.mesh)\nand\n $(objR.mesh)" end - diff --git a/src/meshgrids/MeshProduct.jl b/src/meshgrids/MeshProduct.jl index 0968790..8df07be 100644 --- a/src/meshgrids/MeshProduct.jl +++ b/src/meshgrids/MeshProduct.jl @@ -1,17 +1,20 @@ """ -Cartisian product of 1 dimensional meshes +Cartesian product of 1 dimensional meshes """ """ -The cartesian Mesh product: + MeshProduct{MT,N} + MeshProduct(vargs...) -#Parameters: -- 'MT': Type of meshes -- 'N' : Number of meshes +The Cartesian Mesh product: -#Members: -- 'meshes' : The list of Meshes in the MeshProduct -- 'dims' : A tuple of the length of the mesh factors +# Parameters: +- `MT`: Type of meshes +- `N` : Number of meshes + +# Members: +- `meshes`: The list of Meshes in the MeshProduct +- `dims`: A tuple of the length of the mesh factors """ struct MeshProduct{MT,N} meshes::MT @@ -33,13 +36,13 @@ Base.length(obj::MeshProduct) = reduce(*, obj.dims) """ function Base.size(obj::MeshProduct, I::Int) -Return the length of the specifict Ith mesh factor of the MeshProduct. +Return the length of the specific `I`th mesh factor of the MeshProduct. """ Base.size(obj::MeshProduct, I::Int) = obj.dims[I] """ function Base.size(obj::MeshProduct, I::Int) -Return the length of the specifict Ith mesh factor of the MeshProduct. +Return the length of the specific `I`th mesh factor of the MeshProduct. """ Base.size(obj::MeshProduct) = obj.dims @@ -56,8 +59,8 @@ Base.eachindex(obj::MeshProduct) = Base.eachindex(obj.meshes) Convert a tuple of the indexes of each mesh to a single linear index of the MeshProduct. # Argument: -- 'obj': The MeshProduct object -- 'index...': N indexes of the mesh factor, where N is the number of mesh factor +- `obj`: The MeshProduct object +- `index...`: N indexes of the mesh factor, where N is the number of mesh factor """ @generated function index_to_linear(obj::MeshProduct{MT,N}, I...) where {MT,N} ex = :(I[$N] - 1) @@ -80,8 +83,8 @@ end Convert the single linear index of the MeshProduct to a tuple of indexes of each mesh. # Argument: -- 'obj': The MeshProduct object -- 'I': The linear index of the MeshProduct +- `obj`: The MeshProduct object +- `I`: The linear index of the MeshProduct """ @generated function linear_to_index(obj::MeshProduct{MT,N}, I::Int) where {MT,N} inds, quotient = :((I - 1) % obj.dims[1] + 1), :((I - 1) ÷ obj.dims[1]) @@ -151,7 +154,9 @@ Base.show(io::IO, obj::MeshProduct) = print(io, "MeshProduct of: $(obj.meshes)") """ - All meshes in meshes should have locate and volume functions. Here in meshproduct we just delegate these functions to the meshes, and return the proper array of returned values. +All meshes in meshes should have locate and volume functions. Here in +meshproduct we just delegate these functions to the meshes, and return the +proper array of returned values. """ # function locate(obj::MeshProduct, index...) # return Tuple(locate(obj, index[mi]) for (mi, m) in enumerate(obj)) diff --git a/src/meshgrids/common.jl b/src/meshgrids/common.jl index 477e9c8..fb4fdb2 100644 --- a/src/meshgrids/common.jl +++ b/src/meshgrids/common.jl @@ -37,7 +37,7 @@ locate(tg::TemporalGrid{T,true}, pos) where {T} = length(tg) - locate(tg.grid, p If the grid is in ascend order, then floor returns the largest index that the grid point is smaller than pos. If the grid is in descend order, then floor returns the largest index that the grid point is larger than pos. -In both cases, the returned index is in the range [1, length(tg)-1] +In both cases, the returned index is in the range `[1, length(tg)-1]` """ Base.floor(tg::TemporalGrid{T,false}, pos) where {T} = floor(tg.grid, pos) #TODO: how to implement? Base.floor(tg::TemporalGrid{T,true}, pos) where {T} = length(tg) - floor(tg.grid, pos) #TODO: how to implement? @@ -83,4 +83,4 @@ function _to_AbstractGrid(grid::AbstractVector, dtype) end grid = SimpleG.Arbitrary{dtype}(dtype.(grid)) return grid, rev -end \ No newline at end of file +end diff --git a/src/meshgrids/dlrfreq.jl b/src/meshgrids/dlrfreq.jl index 2252fc2..9c86078 100644 --- a/src/meshgrids/dlrfreq.jl +++ b/src/meshgrids/dlrfreq.jl @@ -78,4 +78,12 @@ end Write a text representation of the DLR grid `tg` to the output stream `io`. """ -Base.show(io::IO, tg::DLRFreq) = print(io, "DLR frequency grid with $(length(tg)) points, inverse temperature = $(tg.β), UV Energy scale = $(tg.Euv), rtol = $(tg.rtol), sym = $(tg.symmetry), fermionic = $(tg.isFermi): $(_grid(tg.grid))") +Base.show(io::IO, tg::DLRFreq) = print( + io, + "DLR frequency grid with ", + length(tg), " points, inverse temperature = ", tg.β, + ", UV Energy scale = ", tg.Euv, + ", rtol = ", tg.rtol, + ", sym = ", tg.symmetry, + ", fermionic = ", tg.isFermi, ": ", _grid(tg.grid) +) diff --git a/src/meshgrids/imfreq.jl b/src/meshgrids/imfreq.jl index ed43d2d..b2928b6 100644 --- a/src/meshgrids/imfreq.jl +++ b/src/meshgrids/imfreq.jl @@ -7,7 +7,7 @@ Imaginary-frequency grid for Green's functions. - `T<:Real`: type of the `grid` point, `β` and `Euv`. - `G<:AbstractGrid{T}`: type of 1D grid with `T` as the grid point type. - `R`: type of the representation. -- REV: access the grid in reverse order or not. +- `REV`: access the grid in reverse order or not. # Members - `grid`: 1D grid of time axis, with locate, volume, and AbstractArray interface implemented. Always in ascend order @@ -80,7 +80,10 @@ function ImFreq(β, isFermi::Bool=false; end """ - function ImFreq(dlr::DLRGrid; dtype=Float64, grid::Union{AbstractGrid,AbstractVector}=SimpleG.Arbitrary{Int}(dlr.n)) + function ImFreq(dlr::DLRGrid; + dtype=Float64, + grid::Union{AbstractGrid,AbstractVector}=SimpleG.Arbitrary{Int}(dlr.n) + ) Construct `ImFreq` from a `DLRGrid`, with a given `grid`. By default, `grid` is the Matsubara-frequency points from `DLRGrid`. """ @@ -92,7 +95,7 @@ function ImFreq(dlr::DLRGrid; if rev grid = reverse(grid) end - if (grid isa AbstractGrid) == false + if !(grid isa AbstractGrid) grid = SimpleG.Arbitrary{Int}(grid) end @assert eltype(grid) <: Int "Matsubara-frequency grid should be Int." @@ -111,10 +114,10 @@ matfreq(tg::ImFreq{T,G,R,true}) where {T,G,R} = [int_to_matfreq(tg, n) for n in """ getindex(g::ImFreq{T, G, R, REV}, I::Int) -Equivalent to `g[I]`, get the __real-valued__ Matsubara frequency of the Ith point in the grid. -For fermion, return (2g[I]+1)π/β, for boson, return 2g[I]*π/β. +Equivalent to `g[I]`, get the __real-valued__ Matsubara frequency of the `I`th point in the grid. +For fermion, return `(2g[I]+1)π/β`, for boson, return `2g[I]*π/β`. -If REV = true, then index in the reversed order, namely I will be replaced with `length(g) - I + 1`. +If `REV` = `true`, then index in the reversed order, namely I will be replaced with `length(g) - I + 1`. If you need the __integer-valued__ frequency, use `g.grid[I]` instead. """ diff --git a/src/meshgrids/imtime.jl b/src/meshgrids/imtime.jl index 1e17be1..964496c 100644 --- a/src/meshgrids/imtime.jl +++ b/src/meshgrids/imtime.jl @@ -81,7 +81,9 @@ function ImTime(β, isFermi::Bool=false; end """ - function ImTime(dlr::DLRGrid; dtype=Float64, grid::Union{AbstractGrid,AbstractVector}=SimpleG.Arbitrary{dtype}(dlr.τ)) + function ImTime(dlr::DLRGrid; + dtype=Float64, + grid::Union{AbstractGrid,AbstractVector}=SimpleG.Arbitrary{dtype}(dlr.τ)) Construct `ImTime` from a `DLRGrid`, with a given `grid`. By default, `grid` is the imaginary-time grid points from `DLRGrid`. """