diff --git a/doc/reference/c++/gf/contents.rst b/doc/reference/c++/gf/contents.rst index 1ac2ccab..3b4d9aae 100644 --- a/doc/reference/c++/gf/contents.rst +++ b/doc/reference/c++/gf/contents.rst @@ -3,7 +3,7 @@ The Green function class ======================== -The TRIQS library has a class called ``gf`` which allows you to manipulate easily a whole set of Green functions. +The TRIQS library has a class called ``gf`` which allows you to use easily a whole set of Green functions. You can use as variable(s) @@ -19,7 +19,7 @@ You can use as variable(s) More generally, the variable is a point of a ``domain`` -The value of the Green function can be a scalar, a matrix or whatever you want (this type is called type ``target_t``). +The value of the Green function on a point of the domain can be a scalar, a matrix or whatever you want (this type is called type ``target_t``). You can group several green functions into *blocks* (for example, one block per orbital, or per wave vector...). @@ -34,5 +34,7 @@ Fourier transforms are implemented for these Green functions: :maxdepth: 2 concepts + meshes + the_four_basic_GFs fourier cookbook/contents diff --git a/doc/reference/c++/gf/fourier.rst b/doc/reference/c++/gf/fourier.rst index 79ae42df..1e6fc101 100644 --- a/doc/reference/c++/gf/fourier.rst +++ b/doc/reference/c++/gf/fourier.rst @@ -3,13 +3,95 @@ Fourier transforms ################### + + Convention -============== +========== - .. math:: \tilde f(\omega)=\int_{-\infty}^\infty dt f(t)e^{i\omega t} +For real time/frequency: - .. math:: f(t)=\int_{-\infty}^\infty \frac{d\omega}{2\pi} \tilde f(\omega)e^{-i\omega t} + :label: _TF_R + .. math:: \tilde G(\omega)=\int_{-\infty}^\infty dt G(t)e^{i\omega t} + :label: _inv_TF_R + .. math:: G(t)=\int_{-\infty}^\infty \frac{d\omega}{2\pi} \tilde G(\omega)e^{-i\omega t} + +For Matsubara (imaginary) time/frequency: + + :label: _TF_I + .. math:: \tilde G(i\omega_n)=\int_{0}^\beta d\tau G(t)e^{i\omega_n \tau} + + :label: _inv_TF_I + .. math:: G(\tau)=\sum_{n=-\infty}^\infty \frac{1}{\beta} \tilde G(i\omega_n)e^{-i\omega_n \tau} + +The :math:`\omega_n`'s are :math:`\frac{(2n+1)\pi}{\beta}` for fermions, :math:`\frac{2n\pi}{\beta}` for bosons (as :math:`G(\tau+\beta)=-G(\tau)` for fermions, :math:`G(\tau)` for bosons). + + + +The FFTW library +================ + +Documentation on FFTW is on https://www.fftw.org. +FFTW is a C subroutine library for computing the discrete Fourier transform (DFT) in one or more dimensions, of arbitrary input size, and of both real and complex data. +It will be used to calculate the (inverse) Fourier transform, in real/imaginary time/frequency, using the fact that the GF values are stored for a finite amount of regularly spaced values. + +The DFT transforms of a sequence of :math:`N` complex numbers :math:`f_0...,f_{N-1}` into a sequence of :math:`N` complex numbers :math:`\tilde f_0...,\tilde f_{N-1}` according to the formula: + :label: _DFT + .. math:: \tilde f_m = \sum_{k=0}^{N-1} f_k e^{-i 2 \pi m k / N}. +The inverse DFT formula is + :label: _inv_DFT + .. math:: f_k = \frac{1}{N} \sum_{m=0}^{N-1} \tilde f_m e^{i 2 \pi m k / N}. + + + +Implementation in real time/frequency using FFTW +================================================ + +The real time mesh parameters are :math:`t_{min}`, :math:`\delta t` and :math:`N_t`. +For the real frequency mesh, they are :math:`\omega_{min}`, :math:`\delta \omega` and :math:`N_\omega`. +The Fourier transform requires :math:`N_\omega=N_t` and :math:`\delta t \delta \omega= \frac{2\pi}{N_t}`. +The times are :math:`t_k=t_{min}+k\delta t` and the frequencies :math:`\omega_m=\omega_{min}+m\delta \omega`. + +By approximating Eq. :ref:`TF_R` by + .. math:: \tilde G(\omega_m) = \delta t \sum_{k=0}^{N_t} G(t_k) e^{i\omega_m t_k}, +we recognize a DFT (Eq. :ref:`DFT`). To calculate it using FFTW, we first need to prepare the input: + .. math:: f_k = G(t_k) e^{i \omega_{min}t_k}, +then to do the DFT and finally to modify the output to obtain :math:`\tilde G(\omega_m)` as + .. math:: \tilde G(\omega_m) = \delta t \tilde f_m e^{i t_{min}(\omega_m-\omega_{min})}. + +Similarly, the inverse transformation is obtained by approximating Eq. :ref:`eq_inv_TF_R` by + .. math:: G(t_k)=\frac{\delta\omega}{2\pi}\sum_{m=0}^{N_\omega} \tilde G(\omega_m)e^{-i\omega_m t_k}, +we recognize an inverse DFT (Eq. :ref:`inv_DFT`). To calculate it using FFTW, we first need to prepare the input: + .. math:: \tilde f_m = \tilde G(\omega_m) e^{-i t_{min}\omega_m}, +then to do the inverse DFT and finally to modify the output to obtain :math:`G(t_k)` as + .. math:: G(t_k) = \frac{1}{N_t \delta t}f_k e^{-i \omega_{min}(t_k-t_{min})}, + + + +Implementation in imaginary time/frequency using FFTW +===================================================== + + +The imaginary time mesh parameters are :math:`\beta` and :math:`N_\tau`, plus a tag ``half_bins``, ``full_bins`` or ``without_last``. +In the ``full_bins`` case, one point of the time GF has to be removed for the fourier transform. +From these parameters, we deduce :math:`\delta\tau=\beta/N_\tau` + +CHAPTER NOT FINISHED !!!! It seems that only real GF's in time are considered (w_n is always >0)... + +For the imaginary frequency mesh, they are :math:`n_{min}`, :math:`\beta` and :math:`N_\omega`. +From them, we deduce :math:`\delta\omega=\frac{2\pi}{\beta}`. +The Fourier transform requires :math:`N_\omega=N_\tau`. +The times are :math:`\tau_k=\tau_{min}+k\delta\tau` and the frequencies :math:`\omega_n=\omega_{min}+n\delta \omega`. +:math:`\tau_{min}` is either 0 or :math:`\delta\tau/2` depending on the mesh kind. +:math:`\omega_{min}` is either :math:`\frac{2\pi(n_{min}+1)}{\beta}` or :math:`\frac{2\pi n_{min}}{\beta}` depending on the statistic. + +We approximate the TF and its inverse by + .. math:: \tilde G(i\omega_n) = \delta\tau \sum_{k=0}^{N_\tau} G(\tau_k)e^{i\omega_n \tau_k} + .. math:: G(\tau_k) = \sum_{n=0}^{N_\tau} \frac{1}{\beta} \tilde G(i\omega_n)e^{-i\omega_n \tau_k} + +We use for the TF: + .. math:: f_k = G(\tau_k) e^{i \omega_{min}\tau_k}, + .. math:: \tilde G(i\omega_m) = \frac{\beta}{N_\tau} \tilde f_m e^{i \tau_{min}(\omega_m-\omega_{min})}. Effect of a TF on the tail =========================== @@ -33,6 +115,9 @@ We use the following Fourier tranforms: For the inverse Fourier transform, the inverse procedure is used. +In the library, :math:`a` is optimized according to the mesh properties (its size :math:`L=G.mesh().size()` and its precision :math:`\delta = G.mesh().delta()`). +The requirements are :math:`a \gg \delta\omega` and :math:`a \ll L\delta\omega`, or equivalently :math:`a \gg \delta t` and :math:`a \ll L\delta t`. +Thus, we chose :math:`a=\sqrt{L}\delta\omega` diff --git a/doc/reference/c++/gf/meshes.rst b/doc/reference/c++/gf/meshes.rst new file mode 100644 index 00000000..3527b957 --- /dev/null +++ b/doc/reference/c++/gf/meshes.rst @@ -0,0 +1,72 @@ +.. highlight:: c + + + +Meshes +####### + + +The linear meshes +================== + + +The mesh kind +-------------- + +This option is particularly important for the Matsubara Green functions in imaginary time. + +Briefly, if we want to describe a function on an interval: + +* ``full_bins`` includes both endpoints, + +* ``half_bins`` includes none of the endpoints + +* ``without_last`` includes only the first endpoint. + +We then have to be careful for example when we fourier transform the function (to not take twice the same point). + + +The four basic meshes +===================== + + +Real time +---------- + +The domain is the set of real numbers. +By default, the mesh kind is ``full_bins``. + +Be careful to the value of a function at a point in case of discontinuities: is its value equal to the limit from below ? To the limit from above ? By none of these limits ? + + +Real frequency +--------------- + +The domain is the set of real numbers. +By default, the mesh kind is ``full_bins``. + + +Matsubara time +--------------- + +The domain is (approximatively) the set of real numbers between 0 and :math:`\beta`. +In fact, other points are also in the domain, but the values at these points are given by the values on this restricted domain. +:math:`G(\tau+\beta)=-G(\tau)` for fermions, :math:`G(\tau+\beta)=G(\tau)` for bosons. + +The limits from above or below at these both points can be different. +Depending on what one needs, we can choose ``full_bins``, ``half_bins`` or ``without_last``. + + +Matsubara frequency +-------------------- + +The domain is discrete. The Matsubara frequencies are :math:`\omega_n=\frac{(2n+1)\pi}{beta}` for fermions and :math:`\omega_n=\frac{2n\pi}{beta}` for bosons. + + + + + + + + + diff --git a/doc/reference/c++/gf/the_four_basic_GFs.rst b/doc/reference/c++/gf/the_four_basic_GFs.rst new file mode 100644 index 00000000..6e4b1161 --- /dev/null +++ b/doc/reference/c++/gf/the_four_basic_GFs.rst @@ -0,0 +1,46 @@ +.. highlight:: c + + +The four reference Green functions +################################## + +Real time +---------- + +``make_gf(double tmin, double tmax, size_t n_points, tqa::mini_vector shape)`` + +``make_gf(double tmin, double tmax, size_t n_points, tqa::mini_vector shape, mesh_kind mk)`` + + +Real frequency +--------------- + +``make_gf(MeshType && m, tqa::mini_vector shape, local::tail_view const & t)`` + +``make_gf(double wmin, double wmax, size_t n_freq, tqa::mini_vector shape)`` + +``make_gf(double wmin, double wmax, size_t n_freq, tqa::mini_vector shape, mesh_kind mk)`` + + +Matsubara time +--------------- + +``make_gf(MeshType && m, tqa::mini_vector shape, local::tail_view const & t)`` + +``make_gf(double beta, statistic_enum S, tqa::mini_vector shape, size_t Nmax=1025, mesh_kind mk= half_bins)`` + +``make_gf(double beta, statistic_enum S, tqa::mini_vector shape, size_t Nmax, mesh_kind mk, local::tail_view const & t)`` + + +Matsubara frequency +-------------------- + +``make_gf(MeshType && m, tqa::mini_vector shape, local::tail_view const & t)`` + +``make_gf(double beta, statistic_enum S, tqa::mini_vector shape)`` + +``make_gf(double beta, statistic_enum S, tqa::mini_vector shape, size_t Nmax)`` + +``make_gf(double beta, statistic_enum S, tqa::mini_vector shape, size_t Nmax, local::tail_view const & t)`` + +