3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-25 05:43:40 +01:00

work on doc for gf, and details.

- little details : code cleaning, clang formatting,  along
with documentation writing for c++ gf.
- separated the mesh in small class for better doc.
- work on documentation : reorganize specialisation, ...
This commit is contained in:
Olivier Parcollet 2013-12-30 22:31:36 +01:00
parent 59b969dbd3
commit bdac3e159c
49 changed files with 1987 additions and 1389 deletions

View File

@ -521,7 +521,7 @@ EXCLUDE_PATTERNS =
# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
EXCLUDE_SYMBOLS = *::*details::* EXCLUDE_SYMBOLS = *::*details::*, _aux*, *::gfs_implementation::*
# The EXAMPLE_PATH tag can be used to specify one or more files or # The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see # directories that contain example code fragments that are included (see

View File

@ -19,9 +19,9 @@ TRIQS (**T**\oolbox for **R**\esearch on **I**\nteracting **Q**\uantum **S**\yst
is a scientific project providing a set of C++ and Python libraries to develop new tools is a scientific project providing a set of C++ and Python libraries to develop new tools
for the study of interacting quantum systems. for the study of interacting quantum systems.
The goal of this toolkit is to provide condensed matter physicists with The goal of this toolkit is to provide our team with
some high level, efficient and simple to use libraries in C++ and Python, some high level, efficient and simple to use libraries in C++ and Python,
and to promote the use of modern programming techniques in our field. and to promote the use of modern programming techniques.
TRIQS is free software (GPL). TRIQS is free software (GPL).
@ -29,7 +29,7 @@ TRIQS applications
----------------------- -----------------------
Based on the TRIQS toolkit, several :ref:`full-fledged applications <applications>` Based on the TRIQS toolkit, several :ref:`full-fledged applications <applications>`
are also maintained by the TRIQS collaboration. They allow for example to are also available. They allow for example to
solve a generic quantum impurity model or to run a complete LDA+DMFT solve a generic quantum impurity model or to run a complete LDA+DMFT
calculation. calculation.

View File

@ -4,28 +4,49 @@
.. _install_on_osx_lion: .. _install_on_osx_lion:
Installing required libraries on Mac OS X Installing required libraries on Mac OS X [EXPERIMENTAL]
========================================= ==============================================================
This is an installation guide for Os X Mountain Lion. Disclaimer
It may work for older -------------
versions of Mac OS X but previous versions of Mac OS X are not supported.
NB: The installation of TRIQS under previous versions of OS X requires installing clang (via Xcode). We provide here some instructions to install and use TRIQS on OS X.
(On Mountain Lion, clang (llvm) replaces gcc as the default C++ compiler).
We strongly recommend the following installation procedure, which provides a clean way to set up all dependencies, so that all While the installation of TRIQS itself is as straightforward as on Linux systems,
of them are compatible with each other. Only the installation via homebrew is supported for the Mac. the installation of the standard scientific libraries used by TRIQS
(mpi, hdf5, boost, fftw, ipython, ....) is not as simple as in e.g. Debian/Ubuntu,
where they are packaged with the distribution itself (i.e. "part of the system").
.. warning:: This general problem of scientific computing on OS X is clearly
illustrated by the large number of third-party attempts
to provide "easy" installation of scientific libraries :
brew, macports, fink, Enthought Python distribution.
In our experience, none of this solution is perfect, nor complete or stable : they are still
very far from the quality and stability of a Linux distribution like Debian/Ubuntu.
It *almost* works, but at the end, there are some issues, sometimes severe,
in the way scientific librairies are installed.
(e.g. currently the default version of mpi and hdf5 installed by brew are in conflict :
the simple mpi "Hello World" crashes when linked with hdf5_cpp).
Moreover, because there is no notion of "distribution" (except in Enthought, which unfortunately is incomplete),
the versions of the libraries are always changing e.g. in brew.
As a result, the installation instructions may work on one day, and suddenly stop to work
the day after.
While this has a priori **nothing to do with TRIQS** and its applications, it clearly impacts its installation and usage.
We are looking for a more robust solution to this OS X installation mess; **help welcome !**.
In the following, we describe an installation procedure which worked (at least one day),
on 10.8 and 10.9 (at least on the Mac of one of the developer !).
Because brew evolve with time, there is no notion of distribution on Mac, like e.g. Ubuntu.
So, while the procedure worked at some point, there can be no guarantee that it still does.
Installation of the dependencies Installation of the dependencies
-------------------------------- --------------------------------
We describe an installation procedure which is known to have worked at least one day,
on 10.8 and 10.9, (at least on the Mac of one of the developer !).
1. Install `homebrew <http://mxcl.github.io/homebrew/>`_. 1. Install `homebrew <http://mxcl.github.io/homebrew/>`_.
Run ``brew doctor`` and resolve potential conflicts before continuing. Run ``brew doctor`` and resolve potential conflicts before continuing.
@ -33,7 +54,8 @@ Installation of the dependencies
2. Install XCode (directly from the Mac store). In Preferences/Downloads, install "Command Line tools". 2. Install XCode (directly from the Mac store). In Preferences/Downloads, install "Command Line tools".
3. Install several packages which are needed: :: 3. Install several packages which are needed: ::
brew tap homebrew/science
brew install cmake brew install cmake
brew install gfortran brew install gfortran
brew install --enable-cxx hdf5 brew install --enable-cxx hdf5
@ -42,11 +64,9 @@ Installation of the dependencies
brew install open-mpi brew install open-mpi
brew install zmq brew install zmq
brew install python brew install python
brew install doxygen
#brew formula has been repaired, since boost installation of mpi.python is a complete mess
#brew formula has been repaired. Temporary using our own #which needs to be fixed manually (except in Debian/Ubuntu where it is correct).
#until this is back in the master.
#When 1.55 is out, the regular brew formula should work again ...
### brew install boost --without-single --with-mpi --with-c++11 ### brew install boost --without-single --with-mpi --with-c++11
brew install http://ipht.cea.fr/triqs/formulas/boost.rb --without-single --with-mpi --with-c++11 -v brew install http://ipht.cea.fr/triqs/formulas/boost.rb --without-single --with-mpi --with-c++11 -v
@ -69,22 +89,32 @@ Installation of the dependencies
6. If you wish to compile the documentation locally, install sphinx, its dependencies and mathjax: :: 6. If you wish to compile the documentation locally, install sphinx, its dependencies and mathjax: ::
brew install doxygen
pip install sphinx pip install sphinx
easy_install pyparsing==1.5.7 easy_install pyparsing==1.5.7
git clone https://github.com/mathjax/MathJax.git MathJax git clone https://github.com/mathjax/MathJax.git MathJax
NB : you need pyparsing <=1.5.7 since apparently v.2.0 works only for python 3. NB : you need pyparsing <=1.5.7 since apparently v.2.0 works only for python 3.
7. If you wish to build the documentation locally,
configure TRIQS with the option -DPython_use_mpi4py=ON (workaround boost.mpi.python bug).
8. **Set up** the environment variable, e.g. in your ~/.bash_profile (workaround for issue #43) ::
export HDF5_DEBUG="all"
or your code will crash when launched without mpirun
(due to a bug in hdf5 C++/ openmpi, nothing to do with TRIQS, so we can not fix it).
Possible issues Possible issues
--------------- ---------------
If you encounter the following error: :: * If you encounter the following error: ::
/usr/local/include/ft2build.h:56:38: error: freetype/config/ftheader.h: No such file or directory /usr/local/include/ft2build.h:56:38: error: freetype/config/ftheader.h: No such file or directory
in the installation of matplotlib, you need to pass the proper include path. Locate the freetype directory in the installation of matplotlib, you need to pass the proper include path. Locate the freetype directory
with the header file and pass the include path through ``CPPFLAGS``: :: with the header file and pass the include path through ``CPPFLAGS``: ::
CPPFLAGS=-I/usr/X11/include/freetype2/ pip install git+https://github.com/matplotlib/matplotlib.git#egg=matplotlib-dev CPPFLAGS=-I/usr/X11/include/freetype2/ pip install git+https://github.com/matplotlib/matplotlib.git#egg=matplotlib-dev

View File

@ -1,10 +1,10 @@
# Doxygen sources # Doxygen sources
set_property(GLOBAL APPEND PROPERTY DOXYGEN_SOURCES set_property(GLOBAL APPEND PROPERTY DOXYGEN_SOURCES
${TRIQS_SOURCE_DIR}/triqs/arrays/h5/simple_read_write.hpp #${TRIQS_SOURCE_DIR}/triqs/arrays/h5/simple_read_write.hpp
${TRIQS_SOURCE_DIR}/triqs/arrays/h5/array_stack.hpp ${TRIQS_SOURCE_DIR}/triqs/arrays/h5/array_stack.hpp
${TRIQS_SOURCE_DIR}/triqs/h5/group.hpp ${TRIQS_SOURCE_DIR}/triqs/h5/group.hpp
${TRIQS_SOURCE_DIR}/triqs/arrays/array.hpp # ${TRIQS_SOURCE_DIR}/triqs/arrays/array.hpp
${TRIQS_SOURCE_DIR}/triqs/arrays/matrix.hpp #${TRIQS_SOURCE_DIR}/triqs/arrays/matrix.hpp
${TRIQS_SOURCE_DIR}/triqs/arrays/vector.hpp #${TRIQS_SOURCE_DIR}/triqs/arrays/vector.hpp
) )

View File

@ -1,3 +1,10 @@
# Doxygen sources # Doxygen sources
set_property(GLOBAL APPEND PROPERTY DOXYGEN_SOURCES ${TRIQS_SOURCE_DIR}/triqs/gfs/gf.hpp) SET(TRIQS_GFS_SRC_DIR ${TRIQS_SOURCE_DIR}/triqs/gfs)
set_property(GLOBAL APPEND PROPERTY DOXYGEN_SOURCES
${TRIQS_GFS_SRC_DIR}/meshes/linear.hpp
${TRIQS_GFS_SRC_DIR}/meshes/matsubara_freq.hpp
${TRIQS_GFS_SRC_DIR}/meshes/matsubara_time.hpp
${TRIQS_GFS_SRC_DIR}/meshes/product.hpp
${TRIQS_GFS_SRC_DIR}/refreq.hpp
${TRIQS_GFS_SRC_DIR}/domains/matsubara.hpp
)

View File

@ -5,18 +5,17 @@
Interaction with CLEF expressions Interaction with CLEF expressions
============================================ ============================================
* The gf containers and their view classes can be used with the :doc:`../clef/contents` library : The gf containers and their view classes can be used with the :doc:`../clef/contents` library :
* They can be called with CLEF expressions. * They can be called with CLEF expressions.
* :doc:`Automatic assignment<../clef/assign>` has been set up. * :doc:`Automatic assignment<../clef/assign>` has been set up.
* Using the CLEF library offers a quick and efficient way to fill an array with multiple advantages : Using the CLEF library offers a quick and efficient way to fill an array with multiple advantages :
* It is simpler and more readeable than a series of for loops. * It is simpler and more readeable than a series of for loops.
* It is usually more optimal since the for loops are automatically written in the TraversalOrder of the array. * It is more optimal since the loops are automatically written in the best order for memory traversal.
**Example** :
* **Example** :
.. compileblock:: .. compileblock::
@ -36,9 +35,6 @@ Interaction with CLEF expressions
.. note:: .. note::
The syntax uses a <<, not = since the array is not assigned to an expression
but filled by the evaluation thereof.
The LHS uses () and not brackets, even though it is on the mesh, because of the strange C++ limitation The LHS uses () and not brackets, even though it is on the mesh, because of the strange C++ limitation
that [] can not be overloaded for several variables... that [] can not be overloaded for several variables...

View File

@ -37,22 +37,21 @@ Domain
* **Purpose** : The domain of definition of a function. It is a mathematical definition of the domain, * **Purpose** : The domain of definition of a function. It is a mathematical definition of the domain,
and does not contain any mesh, or details on its representation in a computer. and does not contain any mesh, or details on its representation in a computer.
* **Refines** : RegularType, BoostSerializable, H5-serializable. * **Refines** : RegularType.
* **Definition** : * **Definition** :
+----------------------------------------------------------------------------+---------------------------------------------------------------------+ +----------+--------------------------------------------------------------------+
| Elements | Comment | | Elements | Comment |
+============================================================================+=====================================================================+ +==========+====================================================================+
| point_t | Type of element in the domain (int, int, double, k_vector, ...) as | | point_t | Type of element in the domain (int, int, double, k_vector, ...) as |
| | in the call of a function over this domain. In particular, in | | | in the call of a function over this domain. |
| | Matsubara, it is a complex. | +----------+--------------------------------------------------------------------+
+----------------------------------------------------------------------------+---------------------------------------------------------------------+
* **Examples** : * **Examples** :
* Matsubara frequencies (boson/fermion)
* Matsubara time * Matsubara time
* Matsubara frequencies (boson/fermion) : in this case, point_t is `matsubara_freq`, a simple type containing (n, beta, statistics).
* Real frequencies * Real frequencies
* Real time * Real time
* Brillouin zone * Brillouin zone
@ -75,9 +74,7 @@ PureFunctionOnDomain
+--------------------------------------+----------------------------------------------------------+ +--------------------------------------+----------------------------------------------------------+
| Elements | Comment | | Elements | Comment |
+======================================+==========================================================+ +======================================+==========================================================+
| domain_t | Type of the Domain represented, modelling Domain concept | | domain_t const & domain() const | Returns the domain (deduced as domain_t) |
+--------------------------------------+----------------------------------------------------------+
| domain_t const & domain() const | Returns the domain |
+--------------------------------------+----------------------------------------------------------+ +--------------------------------------+----------------------------------------------------------+
| operator (domain_t::point_t) const | Calling for all elements of the Domain (including infty | | operator (domain_t::point_t) const | Calling for all elements of the Domain (including infty |
| | if it is in the domain... | | | if it is in the domain... |
@ -99,38 +96,44 @@ Mesh
It does not really need to be a mesh : e.g. if the function is represented on a polynomial basis, It does not really need to be a mesh : e.g. if the function is represented on a polynomial basis,
it is the parameters of this representation (max number of coordinates, e.g.) it is the parameters of this representation (max number of coordinates, e.g.)
* **Refines** : RegularType, HasConstIterator BoostSerializable, H5-serializable, Printable. * **Refines** : RegularType, H5-serializable, Printable.
* **Definition** : * **Definition** :
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| Elements | Comment | | Elements | Comment |
+==============================================================+===============================================================================+ +=======================================================+===============================================================================+
| domain_t | Type of the Domain represented, modeling the Domain concept | | domain_t | Type of the Domain represented, modeling the Domain concept |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| domain_t const & domain() const | Access to the domain | | domain_t const & domain() const | Access to the domain |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| index_t | Type of indices of a point on the grid. Typically a tuple of long or a long | | index_t | Type of indices of a point on the grid. Typically a tuple of long or a long |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| size_t size() const | The number of points in the mesh. | | long size() const | The number of points in the mesh. |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| domain_t::point_t index_to_point(index_t) const | From the index of a mesh point, compute the corresponding point in the domain | | domain_t::point_t index_to_point(index_t) const | From the index of a mesh point, compute the corresponding point in the domain |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| size_t index_to_linear(index_t const &) const | Flattening the index of the mesh into a contiguous linear index | | long index_to_linear(index_t const &) const | Flattening the index of the mesh into a contiguous linear index |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| mesh_point_t | A type modelling MeshPoint concept (see below). | | mesh_point_t | A type modeling MeshPoint concept (see below). |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| mesh_point_t operator[](index_t const & index ) const | From an index, return a mesh_point_t containing this a ref to this mesh and | | mesh_point_t operator[](index_t const & index ) const | From an index, return a mesh_point_t containing this a ref to this mesh and |
| | the index. | | | the index. |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| free function | | | mesh_pt_generator<mesh_t> const_iterator | A generator of all the mesh points. |
| foreach ( mesh_t, lambda) | ??????????????????????????????????? | +-------------------------------------------------------+-------------------------------------------------------------------------------+
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ | const_iterator begin()/end() const | Standard access to iterator on the mesh Standard access to iterator on the |
| mesh_pt_generator<mesh_t> iterator | A generator of all the mesh points. | | cbegin()/cend() const | mesh |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +-------------------------------------------------------+-------------------------------------------------------------------------------+
| const_iterator begin()/end() const | Standard access to iterator on the mesh |
| const_iterator cbegin()/cend() const | Standard access to iterator on the mesh |
+--------------------------------------------------------------+-------------------------------------------------------------------------------+ +---------------------------+-----------------------------------------------------------+
| Free functions | Comment |
+===========================+===========================================================+
| void foreach (mesh_t, F) | If F is a function of synopsis |
| | auto F( mesh_t::mesh_point_t) |
| | it calls F for each point on the mesh, in arbitrary order |
+---------------------------+-----------------------------------------------------------+
.. _Concept_MeshPoint: .. _Concept_MeshPoint:
@ -193,4 +196,3 @@ one can write naturally ::
// In this expression, w is casted to the domain_t::point_t, here a complex<double> // In this expression, w is casted to the domain_t::point_t, here a complex<double>
// which allows to evaluate the function // which allows to evaluate the function

View File

@ -3,7 +3,7 @@
Green functions Green functions
================= =================
The TRIQS library provides a generic container `gf` and its view `gf_view`, to store and manipulate The TRIQS library provides a generic container `gf` and its views `gf_view` and `gf_const_view`, to store and manipulate
various Green functions. various Green functions.
.. warning:: .. warning::
@ -15,11 +15,11 @@ various Green functions.
intro intro
gf_and_view gf_and_view
gf_part_eval_curry gf_special
slicing clef
concepts
meshes
tail tail
fourier fourier
gf_misc concepts
implementation_notes implementation_notes

View File

@ -6,22 +6,64 @@ Fourier transforms
The Fourier transforms from real and imaginary frequencies to times, and inverse, are currently implemented, The Fourier transforms from real and imaginary frequencies to times, and inverse, are currently implemented,
along with the analogous transformation from the Legendre expansion to imaginary time and frequencies. along with the analogous transformation from the Legendre expansion to imaginary time and frequencies.
Synopsis and example Synopsis
====================== =========
**Synopsis** :: **Synopsis** ::
lazy_object fourier (gf<imfreq,Target,Opt> const &) auto fourier (gf<imfreq,Target,Opt> const &)
lazy_object fourier (gf_const_view<imfreq,Target,Opt> const &) auto fourier (gf_view<imfreq,Target,Opt> const &)
auto fourier (gf_const_view<imfreq,Target,Opt> const &)
lazy_object inverse_fourier (gf<imfreq,Target,Opt> const &) auto inverse_fourier (gf<imfreq,Target,Opt> const &)
lazy_object inverse_fourier (gf_const_view<imfreq,Target,Opt> const &) auto inverse_fourier (gf_view<imfreq,Target,Opt> const &)
auto inverse_fourier (gf_const_view<imfreq,Target,Opt> const &)
gf<imfreq, Target, Opt> make_gf_from_fourier(gf<imtime, Target, Opt> const&);
gf<imfreq, Target, Opt> make_gf_from_fourier(gf_view<imtime, Target, Opt> const&);
gf<imfreq, Target, Opt> make_gf_from_fourier(gf_const_view<imtime, Target, Opt> const&);
gf<imtime, Target, Opt> make_gf_from_inverse_fourier(gf<imfreq, Target, Opt> const&);
gf<imtime, Target, Opt> make_gf_from_inverse_fourier(gf_view<imfreq, Target, Opt> const&);
gf<imtime, Target, Opt> make_gf_from_inverse_fourier(gf_const_view<imfreq, Target, Opt> const&);
**fourier, inverse_fourier**
The fourier/inverse_fourier functions do **not** perform the Fourier transformation, The fourier/inverse_fourier functions do **not** perform the Fourier transformation,
but returns a small lazy object (basically saying "Fourier Transform of XXX"), but returns a small lazy object (basically saying "Fourier Transform of XXX"),
which is then used in an assignment of a *view* of a gf. which is then used in an assignment of a *view* of a gf.
The reason is the following: when putting e.g. a Fourier transform of a function in time, say gt,
into a Green function in frequencies, say gw, we want to say something like::
gw = fourier(gt); // ??? (1)
However, if the fourier function performs the transformation, how could it know the details
of the mesh of gw ? That information is not available when calling *fourier*.
Since *fourier* returns a small lazy object, the library can then rewrite (1) internally into something like ::
call_the_fourier_implementation(gt, gw);
where all the information about the mesh of gw is now available to the implementation.
Moreover, since fourier(gt) does not possess a domain (for the same reason), (1)
makes no sense : RHS of gf assignment requires a domain (cf concepts).
We therefore use *a view* as LHS::
gw() = fourier(gt); // correct usage.
**make_gf_from_fourier, make_gf_from_inverse_fourier**
In the case where we want to create a *new* container from the fourier transform of gt,
we can use the function make_gf_from_fourier, in which choice is explicitly made to generate a new gf with the same number of points in the mesh.
(Cf example below).
DOC TO BE FINISHED.
Example Example
=========
.. compileblock:: .. compileblock::
@ -36,21 +78,14 @@ Example
triqs::clef::placeholder<0> om_; triqs::clef::placeholder<0> om_;
gw (om_) << 1/(om_-a); gw (om_) << 1/(om_-a);
gt() = inverse_fourier(gw); // fills the *View* with the contents of the FFT. // fills a full *view* of gt with the contents of the FFT
// NB : the mesh must have the same size. // NB : the mesh of gt *must* have the same size as the mesh of gw.
gt() = inverse_fourier(gw);
// make a new fresh gf, with the same size mesh, from the FFT of gt // make a new fresh gf, with the same size mesh, from the FFT of gt
auto gw2 = make_gf_from_fourier(gt); auto gw2 = make_gf_from_fourier(gt);
} }
Note that :
* the LHS of the = must be a view, since the RHS can not compute the domain of the function
(how many points to use ?).
* In the make_gf_from_fourier function, choice is explicitly made to generate a new gf with the same number of points in the mesh.
Convention Convention
=========== ===========
@ -69,7 +104,7 @@ For Matsubara (imaginary) time/frequency:
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 :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).
*
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1

View File

@ -2,8 +2,8 @@
.. _gf_and_view: .. _gf_and_view:
gf and gf_view gf and views
================= ==============
**Synopsis**: **Synopsis**:
@ -30,6 +30,9 @@ Template parameters
| Opt | void | option_t | Currently unused | | Opt | void | option_t | Currently unused |
+-----------------------------------------+-------------------------------+-------------------------------+--------------------------------------+ +-----------------------------------------+-------------------------------+-------------------------------+--------------------------------------+
The various specializations of the container and its views are decribed in in the :ref:`specializations<gf_special>` page.
The *Variable* template parameter can take the following values : The *Variable* template parameter can take the following values :
+--------------------------+--------------------------------------------+ +--------------------------+--------------------------------------------+
@ -62,39 +65,6 @@ The *Target* template parameter can take the following values :
| tensor_valued<R> | The function is tensor valued with rank | | tensor_valued<R> | The function is tensor valued with rank |
+-------------------------+-----------------------------------------------------+ +-------------------------+-----------------------------------------------------+
.. _gf_special:
Specializations
-------------------
+-------------------------+-------------------------------+-------------------------------+---------------------------+
| Variable/Target | matrix_valued | scalar_valued | gf_valued |
+=========================+===============================+===============================+===========================+
| imfreq | :doc:`gf_imfreq` | :doc:`gf_imfreq_s` | |
+-------------------------+-------------------------------+-------------------------------+---------------------------+
| imtime | :doc:`gf_imtime` | :doc:`gf_imtime_s` | |
+-------------------------+-------------------------------+-------------------------------+---------------------------+
| refreq | :doc:`gf_refreq` | :doc:`gf_refreq_s` | |
+-------------------------+-------------------------------+-------------------------------+---------------------------+
| retime | :doc:`gf_retime` | :doc:`gf_retime_s` | |
+-------------------------+-------------------------------+-------------------------------+---------------------------+
| block_index | | | :doc:`block_gf<gf_block>` |
+-------------------------+-------------------------------+-------------------------------+---------------------------+
| cartesian_product<M...> | :doc:`gf_product<gf_product>` | :doc:`gf_product<gf_product>` | |
+-------------------------+-------------------------------+-------------------------------+---------------------------+
.. toctree::
:hidden:
:maxdepth: 1
gf_imfreq
gf_imfreq_s
gf_refreq
gf_imtime
gf_retime
gf_block
gf_product
Member types Member types
-------------------------------------- --------------------------------------
@ -165,13 +135,15 @@ Non-member functions
------------------------ ------------------------
+---------------------------------+-------------------------------------------+ +----------------------------------------------------------------------+------------------------------------------------------------+
| Member function | Meaning | | Member function | Meaning |
+=================================+===========================================+ +======================================================================+============================================================+
| :ref:`swap<gf_swap>` | Swap of 2 containers | | :ref:`swap<gf_swap>` | Swap of 2 containers |
+---------------------------------+-------------------------------------------+ +----------------------------------------------------------------------+------------------------------------------------------------+
| :ref:`operator\<\<<gf_stream>` | Writing to stream | | :ref:`operator\<\<<gf_stream>` | Writing to stream |
+---------------------------------+-------------------------------------------+ +----------------------------------------------------------------------+------------------------------------------------------------+
| :ref:`reinterpret_scalar_valued_gf_as_matrix_valued<gf_reinterpret>` | Reinterpret a scalar_valued gf as a 1x1 matrix_valued view |
+----------------------------------------------------------------------+------------------------------------------------------------+
.. toctree:: .. toctree::
@ -180,16 +152,5 @@ Non-member functions
stream stream
swap swap
Interaction with CLEF expressions
-------------------------------------
The gf containers and their view classes can be :doc:`used with the CLEF Library <clef>`.
.. toctree::
:hidden:
clef

View File

@ -2,15 +2,15 @@
.. _gf_block: .. _gf_block:
block_gf<G> (alias of gf<block_index, G>) Block Green functions
=================================================== =======================
This is a specialisation of :ref:`gf_and_view` for block functions. This is a specialisation of :ref:`gf_and_view` for block functions.
A block Green function is nothing but Green function on a discrete domain representing the A block Green function is nothing but Green function on a discrete domain representing the
block indices, and whose value is a Green function itself. block indices, and whose value is itself a Green function.
For convenience, for following aliases are provided :: For convenience, the following aliases are provided ::
template<typename ... T> using block_gf = gf <block_index, gf<T...>>; template<typename ... T> using block_gf = gf <block_index, gf<T...>>;
template<typename ... T> using block_gf_view = gf_view <block_index, gf<T...>>; template<typename ... T> using block_gf_view = gf_view <block_index, gf<T...>>;

View File

@ -2,39 +2,81 @@
.. _gf_imfreq: .. _gf_imfreq:
gf<imfreq> Matsubara frequencies
========================================================== ==========================================================
This is a specialisation of :ref:`gf<gf_and_view>` for imaginary Matsubara frequencies.
This is a specialisation of :ref:`gf_and_view` for imaginary Matsubara frequencies. Synopsis
------------
.. code::
gf<imfreq, Target, Opt>
The *Target* template parameter can take the following values :
+-------------------------+-----------------------------------------------------+
| Target | Meaning |
+=========================+=====================================================+
| scalar_valued | The function is scalar valued (double, complex...). |
+-------------------------+-----------------------------------------------------+
| matrix_valued [default] | The function is matrix valued. |
+-------------------------+-----------------------------------------------------+
Domain & mesh Domain & mesh
---------------- ----------------
The domain is :doxy:`matsubara_freq_domain<triqs::gfs::matsubara_domain>`.
The Matsubara frequencies are :math:`\omega_n=\frac{(2n+1)\pi}{\beta}` for fermions and :math:`\omega_n=\frac{2n\pi}{\beta}` for bosons.
The mesh is :doxy:`matsubara_freq_mesh<triqs::gfs::matsubara_freq_mesh>`.
Singularity Singularity
------------- -------------
:ref:`gf_tail`. The singularity is a high frequency expansion, :ref:`gf_tail`.
Interpolation method Evaluation method
--------------------- ---------------------
None * No interpolation.
* Return type :
* If Target==scalar_valued : a complex
* If Target==matrix_valued : an object modeling ImmutableMatrix concept.
* When the point is outside of the mesh, the evaluation of the gf returns :
* the evaluation of the high frequency tail if no_tail is not set.
* 0 otherwise
Data storage Data storage
--------------- ---------------
* `data_t` : 3d array (C ordered) of complex<double>. * If Target==scalar_valued :
* `data_t` : 1d array of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh. * g.data()(i) is the value of g for the i-th point of the mesh.
* If Target==matrix_valued :
* `data_t` : 3d array (C ordered) of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh.
HDF5 storage convention HDF5 storage convention
--------------------------- ---------------------------
h5 tag : `ImFreq` h5 tag : `ImFreq`
TODO : DECIDE if we have 2 tag, one for scalar, one for matrix....
Examples Examples
--------- ---------
@ -43,25 +85,37 @@ Examples
.. compileblock:: .. compileblock::
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using triqs::clef::placeholder; using namespace triqs::gfs;
int main(){ int main(){
double beta=10; double beta=10;
int Nfreq =100; int Nfreq =100;
// --- first a matrix_valued function ------------
// First give information to build the mesh, second to build the target // First give information to build the mesh, second to build the target
auto GF1 = gf<imfreq> { {beta,Fermion,Nfreq}, {1,1} }; auto g1 = gf<imfreq> { {beta,Fermion,Nfreq}, {1,1} };
// or a more verbose/explicit form ... // or a more verbose/explicit form ...
auto GF2 = gf<imfreq> { gf_mesh<imfreq>{beta,Fermion,Nfreq}, make_shape(1,1) }; auto g2 = gf<imfreq> { gf_mesh<imfreq>{beta,Fermion,Nfreq}, make_shape(1,1) };
// Filling the gf with something... // Filling the gf with something...
placeholder<0> wn_; triqs::clef::placeholder<0> wn_;
GF1(wn_) << 1/ (wn_ + 2); g1(wn_) << 1/ (wn_ + 2);
// evaluation at n=3 // evaluation at n=3
std::cout << GF1(3) << " == "<< 1/ ( 1_j * std::acos(-1) / beta * (2*3+1) + 2) << std::endl; std::cout << g1(3) << " == "<< 1/ ( 1_j * M_PI / beta * (2*3+1) + 2) << std::endl;
// the high frequency expansion was automatically computed. // the high frequency expansion was automatically computed.
std::cout << GF1.singularity() << std::endl; //std::cout << g1.singularity() << std::endl; // a bit verbose..
// --- a scalar_valued function ------------
// same a before, but without the same of the target space ...
auto g3 = gf<imfreq,scalar_valued> { {beta,Fermion,Nfreq} };
auto g4 = gf<imfreq,scalar_valued> { gf_mesh<imfreq>{beta,Fermion,Nfreq} };
g3(wn_) << 1/ (wn_ + 2);
// evaluation at n=3.
std::cout << g3(3) << " == "<< 1/ ( 1_j * std::acos(-1) / beta * (2*3+1) + 2) << std::endl;
} }

View File

@ -1,66 +0,0 @@
.. highlight:: c
.. _gf_imfreq_s:
gf<imfreq, scalar_valued>
==========================================================
This is a specialisation of :ref:`gf_and_view` for imaginary Matsubara frequencies.
Domain & mesh
----------------
Singularity
-------------
:ref:`gf_tail`.
Interpolation method
---------------------
None
Data storage
---------------
* `data_t` : 1d array (C ordered) of complex<double>.
* g.data()(i) is the value of g for the i-th point of the mesh.
HDF5 storage convention
---------------------------
h5 tag : `ImFreq_s`
Examples
---------
.. compileblock::
#include <triqs/gfs.hpp>
using namespace triqs::gfs; using triqs::clef::placeholder;
int main(){
double beta=10;
int Nfreq =100;
// First give information to build the mesh, second to build the target
auto GF1 = gf<imfreq,scalar_valued> { {beta,Fermion,Nfreq} };
// or a more verbose/explicit form ...
auto GF2 = gf<imfreq,scalar_valued> { gf_mesh<imfreq>{beta,Fermion,Nfreq} };
// Filling the gf with something...
placeholder<0> wn_;
GF1(wn_) << 1/ (wn_ + 2);
// evaluation at n=3
std::cout << GF1(3) << " == "<< 1/ ( 1_j * std::acos(-1) / beta * (2*3+1) + 2) << std::endl;
// the high frequency expansion was automatically computed.
std::cout << GF1.singularity() << std::endl;
}

View File

@ -2,29 +2,81 @@
.. _gf_imtime: .. _gf_imtime:
gf<imtime> Matsubara imaginary time
=================================================== ==========================================================
This is a specialisation of :ref:`gf_and_view` for imaginary Matsubara time. This is a specialisation of :ref:`gf<gf_and_view>` for imaginary Matsubara time.
Synopsis
------------
.. code::
gf<imtime, Target, Opt>
The *Target* template parameter can take the following values :
+-------------------------+-----------------------------------------------------+
| Target | Meaning |
+=========================+=====================================================+
| scalar_valued | The function is scalar valued (double, complex...). |
+-------------------------+-----------------------------------------------------+
| matrix_valued [default] | The function is matrix valued. |
+-------------------------+-----------------------------------------------------+
Domain & mesh Domain & mesh
---------------- ----------------
The domain is the set of real numbers between 0 and :math:`\beta`
since the function is periodic (resp. antiperiodic) for bosons (resp. fermions), i.e.
* :math:`G(\tau+\beta)=-G(\tau)` for fermions
* :math:`G(\tau+\beta)=G(\tau)` for bosons.
The domain is implemented in the class :doxy:`matsubara_time_domain<triqs::gfs::matsubara_domain>`.
The mesh is :doxy:`matsubara_time_mesh<triqs::gfs::matsubara_time_mesh>`.
Singularity Singularity
------------- -------------
Interpolation method The singularity is a high frequency expansion, :ref:`gf_tail`.
Evaluation method
--------------------- ---------------------
None. * Use a linear interpolation between the two closest point of the mesh.
* Return type :
* If Target==scalar_valued : a complex
* If Target==matrix_valued : an object modeling ImmutableMatrix concept.
* When the point is outside of the mesh, the evaluation of the gf returns :
* the evaluation of the high frequency tail if no_tail is not set.
* 0 otherwise
Data storage Data storage
--------------- ---------------
* `data_t` : 3d array (C ordered) of complex<double>. * If Target==scalar_valued :
* `data_t` : 1d array of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh. * g.data()(i) is the value of g for the i-th point of the mesh.
* If Target==matrix_valued :
* `data_t` : 3d array (C ordered) of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh.
TO DO : complex OR DOUBLE : FIX and document !!
HDF5 storage convention HDF5 storage convention
--------------------------- ---------------------------
@ -38,24 +90,38 @@ Examples
.. compileblock:: .. compileblock::
#include <triqs/gfs.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using triqs::clef::placeholder; using namespace triqs::gfs;
int main(){ int main(){
double beta=10, a = 1; double beta=10, a = 1;
int n_times=5; int n_times=1000;
// --- first a matrix_valued function ------------
// First give information to build the mesh, second to build the target // First give information to build the mesh, second to build the target
auto GF1 = gf<imtime> { {beta,Fermion,n_times}, {1,1} }; auto g1 = gf<imtime, matrix_valued, no_tail> { {beta,Fermion,n_times}, {1,1} };
// or a more verbose/explicit form ... // or a more verbose/explicit form ...
auto GF2 = gf<imtime> { gf_mesh<imtime>{beta,Fermion,n_times}, make_shape(1,1) }; auto g2 = gf<imtime> { gf_mesh<imtime>{beta,Fermion,n_times}, make_shape(1,1) };
// Filling the gf with something...
placeholder<0> tau_;
//GF1(tau_) << exp ( - a * tau_) / (1 + exp(- beta * a));
// evaluation at n=3 // Filling the gf with something... COMMENT HERE : ok only because of no_tail
std::cout << make_matrix(GF1(3)) << " == "<< exp ( - a * 3) / (1 + exp(- beta * a)) << std::endl; triqs::clef::placeholder<0> tau_;
g1(tau_) << exp ( - a * tau_) / (1 + exp(- beta * a));
// evaluation at tau=3.2
std::cout << triqs::arrays::make_matrix(g1(3.2)) << " == "<< exp ( - a * 3.2) / (1 + exp(- beta * a)) << std::endl;
// --- a scalar_valued function ------------
// same a before, but without the same of the target space ...
auto g3 = gf<imtime, scalar_valued, no_tail> { {beta,Fermion,n_times} };
g3(tau_) << exp ( - a * tau_) / (1 + exp(- beta * a));
// evaluation at tau=3.2
std::cout << g3(3.2) << " == "<< exp ( - a * 3.2) / (1 + exp(- beta * a)) << std::endl;
} }

View File

@ -0,0 +1,66 @@
.. highlight:: c
.. _gf_legendre:
Legendre representation
==========================================================
This is a specialisation of :ref:`gf<gf_and_view>` for Legendre polynomial expansion.
Synopsis
------------
.. code::
gf<legendre, Target, Opt>
The *Target* template parameter can take the following values :
+-------------------------+-----------------------------------------------------+
| Target | Meaning |
+=========================+=====================================================+
| scalar_valued | The function is scalar valued (double, complex...). |
+-------------------------+-----------------------------------------------------+
| matrix_valued [default] | The function is matrix valued. |
+-------------------------+-----------------------------------------------------+
Domain & mesh
----------------
TO BE WRITTEN
Singularity
-------------
None
Evaluation method
---------------------
TO BE WRITTEN
Data storage
---------------
TO BE WRITTEN
HDF5 storage convention
---------------------------
h5 tag : `Legendre`
Examples
---------
.. compileblock::
#include <triqs/gfs.hpp>
using namespace triqs::gfs;
int main() {
// We want a 2x2 matrix valued function on this mesh...
//auto g = gf<legendre> { {wmin, wmax, n_freq}, {2,2} };
};

View File

@ -2,8 +2,8 @@
.. _gf_product: .. _gf_product:
Green functions on cartesian product domains Multiple variables
=================================================== ===================
.. warning:: .. warning::
@ -41,7 +41,18 @@ HDF5 storage convention
For convenience, in hdf5 files, the arrays has higher dimension, For convenience, in hdf5 files, the arrays has higher dimension,
so that the first indices are *not* flatten. EXPLAIN. so that the first indices are *not* flatten. EXPLAIN.
Functional techniques
------------------------
See :
.. toctree::
:maxdepth: 1
gf_part_eval_curry
Examples Examples
--------- ---------
.. compileblock:: .. compileblock::
@ -76,14 +87,5 @@ Examples
} }
See also :
.. toctree::
:maxdepth: 1
gf_part_eval_curry

View File

@ -2,29 +2,75 @@
.. _gf_refreq: .. _gf_refreq:
gf<refreq> Real frequencies
=================================================== ==========================================================
This is a specialisation of :ref:`gf_and_view` for imaginary Matsubara frequencies. This is a specialisation of :ref:`gf<gf_and_view>` for real frequencies.
Synopsis
------------
.. code::
gf<refreq, Target, Opt>
The *Target* template parameter can take the following values :
+-------------------------+-----------------------------------------------------+
| Target | Meaning |
+=========================+=====================================================+
| scalar_valued | The function is scalar valued (double, complex...). |
+-------------------------+-----------------------------------------------------+
| matrix_valued [default] | The function is matrix valued. |
+-------------------------+-----------------------------------------------------+
Domain & mesh Domain & mesh
---------------- ----------------
CORRECT THIS !! PUT OUT THE C++ impl for doxy doc
The domain is :doxy:`matsubara_freq_domain<triqs::gfs::matsubara_domain>`.
The mesh is :doxy:`matsubara_freq_mesh<triqs::gfs::matsubara_freq_mesh>`.
Singularity Singularity
------------- -------------
Interpolation method The singularity is a high frequency expansion, :ref:`gf_tail`.
Evaluation method
--------------------- ---------------------
Linear interpolation on the mesh. * Linear interpolation on the mesh.
* Return type :
* If Target==scalar_valued : a complex
* If Target==matrix_valued : an object modeling ImmutableMatrix concept.
* When the point is outside of the mesh, the evaluation of the gf returns :
* the evaluation of the high frequency tail if no_tail is not set.
* 0 otherwise
Data storage Data storage
--------------- ---------------
* `data_t` : 3d array (C ordered) of complex<double>. * If Target==scalar_valued :
* `data_t` : 1d array of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh. * g.data()(i) is the value of g for the i-th point of the mesh.
* If Target==matrix_valued :
* `data_t` : 3d array (C ordered) of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh.
HDF5 storage convention HDF5 storage convention
--------------------------- ---------------------------
@ -36,7 +82,7 @@ Examples
.. compileblock:: .. compileblock::
#include <triqs/gfs/refreq.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
int main() { int main() {

View File

@ -0,0 +1,24 @@
.. highlight:: c
.. _gf_reinterpret:
Target reinterpretation
=========================
**Synopsis** ::
gf_view<Variable, matrix_valued, Opt>
reinterpret_scalar_valued_gf_as_matrix_valued(gf_view<Variable, scalar_valued, Opt>);
gf_view<Variable, matrix_valued, Opt>
reinterpret_scalar_valued_gf_as_matrix_valued(gf<Variable, scalar_valued, Opt> &);
gf_const view<Variable, matrix_valued, Opt>
reinterpret_scalar_valued_gf_as_matrix_valued(gf_const_view<Variable, scalar_valued, Opt>);
gf_const_view<Variable, matrix_valued, Opt>
reinterpret_scalar_valued_gf_as_matrix_valued(gf<Variable, scalar_valued, Opt> const &);
Given a gf or a view, scalar_valued, it returns a view of a 1x1 matrix_valued function on the same data.

View File

@ -2,29 +2,76 @@
.. _gf_retime: .. _gf_retime:
gf<retime> Real time
=================================================== ===================================================
This is a specialisation of :ref:`gf_and_view` for imaginary Matsubara frequencies. This is a specialisation of :ref:`gf_and_view` for imaginary Matsubara frequencies.
Synopsis
------------
.. code::
gf<retime, Target, Opt>
The *Target* template parameter can take the following values :
+-------------------------+-----------------------------------------------------+
| Target | Meaning |
+=========================+=====================================================+
| scalar_valued | The function is scalar valued (double, complex...). |
+-------------------------+-----------------------------------------------------+
| matrix_valued [default] | The function is matrix valued. |
+-------------------------+-----------------------------------------------------+
Domain & mesh Domain & mesh
---------------- ----------------
CORRECT THIS !! PUT OUT THE C++ impl for doxy doc
The domain is :doxy:`matsubara_freq_domain<triqs::gfs::matsubara_domain>`.
The mesh is :doxy:`matsubara_freq_mesh<triqs::gfs::matsubara_freq_mesh>`.
Singularity Singularity
------------- -------------
Interpolation method The singularity is a high frequency expansion, :ref:`gf_tail`.
Evaluation method
--------------------- ---------------------
Linear interpolation on the mesh. * Linear interpolation on the mesh.
* Return type :
* If Target==scalar_valued : a complex
* If Target==matrix_valued : an object modeling ImmutableMatrix concept.
* When the point is outside of the mesh, the evaluation of the gf returns :
* the evaluation of the high frequency tail if no_tail is not set.
* 0 otherwise
Data storage Data storage
--------------- ---------------
* `data_t` : 3d array (C ordered) of complex<double>. * If Target==scalar_valued :
* `data_t` : 1d array of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh. * g.data()(i) is the value of g for the i-th point of the mesh.
* If Target==matrix_valued :
* `data_t` : 3d array (C ordered) of complex<double>.
* g.data()(i, range(), range()) is the value of g for the i-th point of the mesh.
HDF5 storage convention HDF5 storage convention
--------------------------- ---------------------------
@ -36,7 +83,7 @@ Examples
.. compileblock:: .. compileblock::
#include <triqs/gfs/retime.hpp> #include <triqs/gfs.hpp>
using namespace triqs::gfs; using namespace triqs::gfs;
int main() { int main() {

View File

@ -0,0 +1,21 @@
.. _gf_special:
Specializations
-------------------
In this section, we describe the various specializations of the generic container *gf*.
We concentrate only on specific properties, since every specialization has the members and functions described
for :ref:`gf container<gf_and_view:>`.
.. toctree::
:maxdepth: 1
gf_imfreq
gf_imtime
gf_refreq
gf_retime
gf_block
gf_legendre
gf_product

View File

@ -1,9 +1,10 @@
.. highlight:: c .. highlight:: c
Domains & Meshes
##################
Meshes The :doxy:`full C++ documentation<triqs::gfs::matsubara_freq_mesh>` is available here.
#######
The linear meshes The linear meshes
@ -100,23 +101,6 @@ The domain is the set of real numbers.
By default, the mesh kind is ``full_bins``. 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.
Products of meshes Products of meshes
=================== ===================

View File

@ -27,9 +27,7 @@
namespace triqs { namespace triqs {
namespace arrays { namespace arrays {
/** /// The implementation class
* The implementation class
*/
template <typename T, int R> class array_stack_impl { template <typename T, int R> class array_stack_impl {
static const size_t dim = R; static const size_t dim = R;
static const bool base_is_array = dim > 0; static const bool base_is_array = dim > 0;

View File

@ -25,6 +25,7 @@
#include "../retime.hpp" #include "../retime.hpp"
#include "../imtime.hpp" #include "../imtime.hpp"
#include "../meshes/product.hpp" #include "../meshes/product.hpp"
#include "./tool.hpp"
namespace triqs { namespace gfs { namespace triqs { namespace gfs {

View File

@ -0,0 +1,43 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2012 by M. Ferrero, O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once
#include "../gf.hpp"
namespace triqs { namespace gfs {
// make_gf and make_gf_view forward any args to them
template <typename Variable, typename Target = matrix_valued, typename Opt = void, typename... U>
gf<Variable, Target, Opt> make_gf(gf_mesh<Variable, Opt> m, U &&... x) {
return gfs_implementation::factories<Variable, Target, Opt>::make_gf(std::move(m), std::forward<U>(x)...);
}
template <typename Variable, typename Target = matrix_valued, typename Opt = void, typename... U>
gf<Variable, Target, Opt> make_gf(U &&... x) {
return gfs_implementation::factories<Variable, Target, Opt>::make_gf(std::forward<U>(x)...);
}
template <typename Variable, typename Target = matrix_valued, typename Opt = void, typename... U>
gf_view<Variable, Target, Opt> make_gf_view(U &&... x) {
return gfs_implementation::factories<Variable, Target, Opt>::make_gf_view(std::forward<U>(x)...);
}
}}

View File

@ -24,6 +24,7 @@
#include "../gf.hpp" #include "../gf.hpp"
#include "../retime.hpp" #include "../retime.hpp"
#include "../meshes/product.hpp" #include "../meshes/product.hpp"
#include "./tool.hpp"
namespace triqs { namespace gfs { namespace triqs { namespace gfs {

View File

@ -18,23 +18,22 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_DOMAIN_R_H #pragma once
#define TRIQS_GF_DOMAIN_R_H
#include "../tools.hpp" #include "../tools.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
/// The domain /// The domain
struct R_domain { struct R_domain {
typedef double point_t; using point_t = double;
bool operator == (R_domain const & D) const { return true; } bool operator==(R_domain const& D) const { return true; }
friend void h5_write (h5::group fg, std::string subgroup_name, R_domain const & d) {} friend void h5_write(h5::group fg, std::string subgroup_name, R_domain const& d) {}
friend void h5_read (h5::group fg, std::string subgroup_name, R_domain & d){ } friend void h5_read(h5::group fg, std::string subgroup_name, R_domain& d) {}
friend class boost::serialization::access; friend class boost::serialization::access;
template<class Archive> void serialize(Archive & ar, const unsigned int version) {} template <class Archive> void serialize(Archive& ar, const unsigned int version) {}
}; };
}
}} }
#endif

View File

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
@ -19,61 +18,67 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_DISCRETE_DOMAIN_H #pragma once
#define TRIQS_GF_DISCRETE_DOMAIN_H
#include "../tools.hpp" #include "../tools.hpp"
#include <map> #include <map>
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
/// The domain
class discrete_domain { class discrete_domain {
size_t Nmax; int Nmax;
std::vector<std::string> _names;// name of the points (e.g. for block) std::vector<std::string> _names; // optional name of the points (e.g. for block)
std::map<std::string,int> _inv_names; std::map<std::string, int> _inv_names; // table inverting the previous vector
void init_inv() { void init_inv() {
for (size_t i =0; i<Nmax; ++i) { _inv_names[_names[i]]=i;} int i = 0;
} for (auto const& x : _names) _inv_names[x] = i++;
}
public: public:
typedef long point_t; using point_t = int;
size_t size() const { return Nmax;}; int size() const {
discrete_domain (size_t Nmax_=1) : Nmax(Nmax_) { return Nmax;
for (size_t i =0; i<Nmax; ++i) { std::stringstream fs; fs<<i; _names.push_back(fs.str());} };
discrete_domain(int Nmax_ = 1) : Nmax(Nmax_) {
for (int i = 0; i < Nmax; ++i) {
std::stringstream fs;
fs << i;
_names.push_back(fs.str());
}
init_inv(); init_inv();
} }
discrete_domain (std::vector<std::string> && Names) : Nmax(Names.size()), _names(Names) {init_inv(); } discrete_domain(std::vector<std::string> Names) : Nmax(Names.size()), _names(std::move(Names)) { init_inv(); }
discrete_domain (std::vector<std::string> const & Names) : Nmax(Names.size()), _names(Names) { init_inv();} discrete_domain(std::initializer_list<std::string> const& Names) : Nmax(Names.size()), _names(Names) { init_inv(); }
discrete_domain (std::initializer_list<std::string> const & Names) : Nmax(Names.size()), _names(Names) { init_inv();}
std::vector<std::string> const & names() const { return _names;} std::vector<std::string> const& names() const { return _names; }
int index_from_name(std::string const & s) const { return _inv_names.at(s);} int index_from_name(std::string const& s) const { return _inv_names.at(s); }
bool operator == (discrete_domain const & D) const { return (Nmax == D.Nmax);} bool operator==(discrete_domain const& D) const { return (Nmax == D.Nmax); }
/// Write into HDF5 /// Write into HDF5
friend void h5_write (h5::group fg, std::string subgroup_name, discrete_domain const & d) { friend void h5_write(h5::group fg, std::string subgroup_name, discrete_domain const& d) {
h5::group gr = fg.create_group(subgroup_name); h5::group gr = fg.create_group(subgroup_name);
h5_write(gr,"n_max",d.Nmax); h5_write(gr, "n_max", d.Nmax);
// THE NAME ARE MISSING
} }
/// Read from HDF5 /// Read from HDF5
friend void h5_read (h5::group fg, std::string subgroup_name, discrete_domain & d){ friend void h5_read(h5::group fg, std::string subgroup_name, discrete_domain& d) {
h5::group gr = fg.open_group(subgroup_name); h5::group gr = fg.open_group(subgroup_name);
long n; int n;
h5_read(gr,"n_max",n); h5_read(gr, "n_max", n);
d = discrete_domain(n); d = discrete_domain(n);
// NAME ARE MISSING
} }
// BOOST Serialization // BOOST Serialization
friend class boost::serialization::access; friend class boost::serialization::access;
template<class Archive> template <class Archive> void serialize(Archive& ar, const unsigned int version) {
void serialize(Archive & ar, const unsigned int version) { ar& boost::serialization::make_nvp("n_max", Nmax);
ar & boost::serialization::make_nvp("n_max",Nmax); ar& boost::serialization::make_nvp("names", _names);
ar & boost::serialization::make_nvp("names",_names); ar& boost::serialization::make_nvp("names_inv", _inv_names);
} }
}; };
}
}} }
#endif

View File

@ -1,4 +1,3 @@
/******************************************************************************* /*******************************************************************************
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
@ -19,60 +18,59 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_LEGENDRE_DOMAIN_H #pragma once
#define TRIQS_GF_LEGENDRE_DOMAIN_H
#include "../tools.hpp" #include "../tools.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
/// The domain
class legendre_domain { class legendre_domain {
public: public:
double beta; double beta;
statistic_enum statistic; statistic_enum statistic;
size_t Nmax; size_t Nmax;
typedef long point_t; using point_t = long;
size_t size() const { return Nmax;}; size_t size() const {
return Nmax;
};
legendre_domain (double beta_ = 1, statistic_enum stat_ = Fermion, size_t Nmax_=1) : beta(beta_), statistic(stat_), Nmax(Nmax_) {} legendre_domain(double beta_ = 1, statistic_enum stat_ = Fermion, size_t Nmax_ = 1)
: beta(beta_), statistic(stat_), Nmax(Nmax_) {}
bool operator == (legendre_domain const & D) const { bool operator==(legendre_domain const& D) const {
return ((std::abs(beta - D.beta)<1.e-15) && (statistic == D.statistic) && (Nmax == D.Nmax)); return ((std::abs(beta - D.beta) < 1.e-15) && (statistic == D.statistic) && (Nmax == D.Nmax));
} }
/// Write into HDF5 /// Write into HDF5
friend void h5_write (h5::group fg, std::string subgroup_name, legendre_domain const & d) { friend void h5_write(h5::group fg, std::string subgroup_name, legendre_domain const& d) {
h5::group gr = fg.create_group(subgroup_name); h5::group gr = fg.create_group(subgroup_name);
h5_write(gr,"n_max",d.Nmax); h5_write(gr, "n_max", d.Nmax);
h5_write(gr,"beta",d.beta); h5_write(gr, "beta", d.beta);
h5_write(gr,"statistic",(d.statistic==Fermion ? "F" : "B")); h5_write(gr, "statistic", (d.statistic == Fermion ? "F" : "B"));
} }
/// Read from HDF5 /// Read from HDF5
friend void h5_read (h5::group fg, std::string subgroup_name, legendre_domain & d){ friend void h5_read(h5::group fg, std::string subgroup_name, legendre_domain& d) {
h5::group gr = fg.open_group(subgroup_name); h5::group gr = fg.open_group(subgroup_name);
long n; double beta; std::string statistic; long n;
h5_read(gr,"n_max",n); double beta;
h5_read(gr,"beta",beta); std::string statistic;
h5_read(gr,"statistic",statistic); h5_read(gr, "n_max", n);
d = legendre_domain(beta,(statistic=="F" ? Fermion : Boson),n); h5_read(gr, "beta", beta);
h5_read(gr, "statistic", statistic);
d = legendre_domain(beta, (statistic == "F" ? Fermion : Boson), n);
} }
// BOOST Serialization // BOOST Serialization
friend class boost::serialization::access; friend class boost::serialization::access;
template<class Archive> template <class Archive> void serialize(Archive& ar, const unsigned int version) {
void serialize(Archive & ar, const unsigned int version) { ar& boost::serialization::make_nvp("n_max", Nmax);
ar & boost::serialization::make_nvp("n_max",Nmax); ar& boost::serialization::make_nvp("beta", beta);
ar & boost::serialization::make_nvp("beta",beta); ar& boost::serialization::make_nvp("statistic", statistic);
ar & boost::serialization::make_nvp("statistic",statistic);
} }
}; };
}
}} }
#endif

View File

@ -18,26 +18,33 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_DOMAIN_MATSUBARA_H #pragma once
#define TRIQS_GF_DOMAIN_MATSUBARA_H
#include "../tools.hpp" #include "../tools.hpp"
#include <triqs/utility/arithmetic_ops_by_cast.hpp> #include <triqs/utility/arithmetic_ops_by_cast.hpp>
namespace triqs { namespace triqs {
namespace gfs { namespace gfs {
// --------------- One matsubara frequency, with its arithmetics ------------------------- /**
// all operations are done by casting to complex, except addition and substraction of matsubara_freq * A matsubara frequency, i.e.
* * n : int, the index
* * beta : double, the temperature inverse
* * statistic : Fermion or Boson
*
* * Can be casted into a complex.
*
* * Every operations is done by casting to complex, except addition and substraction of matsubara_freq, which return matsubara_freq
* and work on the index
**/
struct matsubara_freq : public utility::arithmetic_ops_by_cast_disable_same_type<matsubara_freq, std::complex<double>> { struct matsubara_freq : public utility::arithmetic_ops_by_cast_disable_same_type<matsubara_freq, std::complex<double>> {
int n; int n;
double beta; double beta;
statistic_enum statistic; statistic_enum statistic;
matsubara_freq() : n(0), beta(1), statistic(Fermion) {} matsubara_freq() : n(0), beta(1), statistic(Fermion) {}
matsubara_freq(int const &n_, double beta_, statistic_enum stat_) : n(n_), beta(beta_), statistic(stat_) {} matsubara_freq(int n_, double beta_, statistic_enum stat_) : n(n_), beta(beta_), statistic(stat_) {}
using cast_t = std::complex<double>; using cast_t = std::complex<double>;
operator cast_t() const { operator cast_t() const {
return {0, M_PI * (2 * n + (statistic == Fermion ? 1 : 0)) / beta}; return {0, M_PI * (2 * n + statistic) / beta};
} }
}; };
@ -50,7 +57,7 @@ namespace gfs {
} }
inline matsubara_freq operator-(matsubara_freq const &mp) { inline matsubara_freq operator-(matsubara_freq const &mp) {
return {-(mp.n + mp.statistic==Fermion ? 1: 0), mp.beta, mp.statistic}; return {-(mp.n + mp.statistic == Fermion ? 1 : 0), mp.beta, mp.statistic};
} }
//--------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------
@ -59,12 +66,12 @@ namespace gfs {
using point_t = typename std::conditional<IsFreq, std::complex<double>, double>::type; using point_t = typename std::conditional<IsFreq, std::complex<double>, double>::type;
double beta; double beta;
statistic_enum statistic; statistic_enum statistic;
matsubara_domain() = default; matsubara_domain(double beta, statistic_enum s) : beta(beta), statistic(s) {
matsubara_domain(double Beta, statistic_enum s) : beta(Beta), statistic(s) {
if (beta < 0) TRIQS_RUNTIME_ERROR << "Matsubara domain construction : beta <0 : beta =" << beta << "\n"; if (beta < 0) TRIQS_RUNTIME_ERROR << "Matsubara domain construction : beta <0 : beta =" << beta << "\n";
} }
matsubara_domain() : matsubara_domain(1, Fermion) {}
matsubara_domain(matsubara_domain const &) = default; matsubara_domain(matsubara_domain const &) = default;
matsubara_domain(matsubara_domain<!IsFreq> const &x) : beta(x.beta), statistic(x.statistic) {} matsubara_domain(matsubara_domain<!IsFreq> const &x) : matsubara_domain(x.beta, x.statistic) {}
bool operator==(matsubara_domain const &D) const { return ((std::abs(beta - D.beta) < 1.e-15) && (statistic == D.statistic)); } bool operator==(matsubara_domain const &D) const { return ((std::abs(beta - D.beta) < 1.e-15) && (statistic == D.statistic)); }
/// Write into HDF5 /// Write into HDF5
@ -91,7 +98,9 @@ namespace gfs {
ar &boost::serialization::make_nvp("statistic", statistic); ar &boost::serialization::make_nvp("statistic", statistic);
} }
}; };
}
} using matsubara_freq_domain = matsubara_domain<true>;
#endif using matsubara_time_domain = matsubara_domain<false>;
}
}

View File

@ -18,19 +18,18 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_DOM_PRODUCT_H #pragma once
#define TRIQS_GF_DOM_PRODUCT_H
#include "../tools.hpp" #include "../tools.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
template<typename... Domains> template <typename... Domains> struct domain_product {
struct domain_product { using point_t = std::tuple<typename Domains::point_t...>;
typedef std::tuple<typename Domains::point_t...> point_t; std::tuple<Domains...> domains;
std::tuple<Domains...> domains; domain_product() = default;
domain_product() = default; domain_product(Domains const&... doms) : domains(doms...) {}
domain_product(Domains const & ... doms) : domains(doms...) {} friend bool operator==(domain_product const& D1, domain_product const& D2) { return D1.domains == D2.domains; }
friend bool operator == (domain_product const & D1, domain_product const & D2) { return D1.domains == D2.domains;} // implement boost serializable, hdf5 if needed... (done at the mesh level).
}; };
}
}} }
#endif

View File

@ -1,8 +1,8 @@
/******************************************************************************* /*******************************************************************************
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2013 by O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -18,57 +18,62 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_EVALUATOR_H #pragma once
#define TRIQS_GF_EVALUATOR_H
#include "./tools.hpp" #include "./tools.hpp"
#include "./gf.hpp" #include "./gf.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs_implementation { namespace gfs {
namespace gfs_implementation {
// simple evaluation : take the point on the grid... // simple evaluation : take the point on the grid...
struct evaluator_grid_simple { struct evaluator_grid_simple {
long n; long n;
evaluator_grid_simple() = default; evaluator_grid_simple() = default;
template <typename MeshType, typename PointType> evaluator_grid_simple(MeshType const &m, PointType const &p) { n = p; }
template<typename MeshType, typename PointType> template <typename F> auto operator()(F const &f) const DECL_AND_RETURN(f(n));
evaluator_grid_simple (MeshType const & m, PointType const & p) { n=p; }
template<typename F> auto operator()(F const & f) const DECL_AND_RETURN(f (n));
};
// a linear interpolation
struct evaluator_grid_linear_interpolation {
double w1, w2; size_t n1, n2;
evaluator_grid_linear_interpolation() = default;
template<typename MeshType, typename PointType>
evaluator_grid_linear_interpolation (MeshType const & m, PointType const & p, double prefactor=1) {
bool in; double w;
std::tie(in, n1, w) = windowing(m,p);
if (!in) TRIQS_RUNTIME_ERROR <<" Evaluation out of bounds";
w1 = prefactor * (1-w); w2 = prefactor * w; n2 = n1 +1;
}
template<typename F> auto operator()(F const & f) const DECL_AND_RETURN(w1 * f(n1) + w2 * f (n2));
};
// the evaluator for various types.
template<typename MeshType> struct evaluator_fnt_on_mesh;
// can not use inherited constructors, too recent...
#define TRIQS_INHERIT_AND_FORWARD_CONSTRUCTOR(NEWCLASS,CLASS) : CLASS { template<typename ...T> NEWCLASS(T &&... t) : CLASS(std::forward<T>(t)...){};};
//
template<typename Variable>
struct evaluator_one_var {
public :
static constexpr int arity = 1;
evaluator_one_var() = default;
template<typename G> auto operator()(G const * g, double x) const DECL_AND_RETURN(evaluator_fnt_on_mesh<Variable> (g->mesh(),x)(on_mesh(*g)));
template<typename G> typename G::singularity_t const & operator()(G const * g,freq_infty const &) const {return g->singularity();}
}; };
// a linear interpolation
struct evaluator_grid_linear_interpolation {
double w1, w2;
size_t n1, n2;
evaluator_grid_linear_interpolation() = default;
template <typename MeshType, typename PointType>
evaluator_grid_linear_interpolation(MeshType const &m, PointType const &p, double prefactor = 1) {
bool in;
double w;
std::tie(in, n1, w) = windowing(m, p);
if (!in) TRIQS_RUNTIME_ERROR << " Evaluation out of bounds";
w1 = prefactor * (1 - w);
w2 = prefactor * w;
n2 = n1 + 1;
}
template <typename F> auto operator()(F const &f) const DECL_AND_RETURN(w1 *f(n1) + w2 *f(n2));
};
// the evaluator for various types.
template <typename MeshType> struct evaluator_fnt_on_mesh;
// can not use inherited constructors, too recent...
#define TRIQS_INHERIT_AND_FORWARD_CONSTRUCTOR(NEWCLASS, CLASS) : CLASS { \
template <typename... T> NEWCLASS(T &&... t) : CLASS(std::forward<T>(t)...) {}; \
};
//
template <typename Variable> struct evaluator_one_var {
public:
static constexpr int arity = 1;
evaluator_one_var() = default;
template <typename G>
auto operator()(G const *g, double x) const DECL_AND_RETURN(evaluator_fnt_on_mesh<Variable>(g -> mesh(), x)(on_mesh(*g)));
template <typename G> typename G::singularity_t const &operator()(G const *g, freq_infty const &) const {
return g->singularity();
}
};
} }
}} }
#endif }

View File

@ -18,8 +18,7 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_GFBASECLASS_H #pragma once
#define TRIQS_GF_GFBASECLASS_H
#include <triqs/utility/first_include.hpp> #include <triqs/utility/first_include.hpp>
#include <triqs/utility/std_vector_expr_template.hpp> #include <triqs/utility/std_vector_expr_template.hpp>
#include <triqs/utility/factory.hpp> #include <triqs/utility/factory.hpp>
@ -29,7 +28,8 @@
#include "./tools.hpp" #include "./tools.hpp"
#include "./data_proxies.hpp" #include "./data_proxies.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
using utility::factory; using utility::factory;
using arrays::make_shape; using arrays::make_shape;
using triqs::make_clone; using triqs::make_clone;
@ -48,48 +48,43 @@ namespace triqs { namespace gfs {
using gf_const_view = gf_view<Variable, Target, Opt, true>; using gf_const_view = gf_view<Variable, Target, Opt, true>;
// the implementation class // the implementation class
template<typename Variable, typename Target, typename Opt, bool IsView, bool IsConst> class gf_impl; template <typename Variable, typename Target, typename Opt, bool IsView, bool IsConst> class gf_impl;
// various implementation traits // various implementation traits
namespace gfs_implementation { // never use using of this... namespace gfs_implementation { // never use using of this...
// evaluator regroup functions to evaluate the function. // evaluator regroup functions to evaluate the function.
template<typename Variable, typename Target, typename Opt> struct evaluator{ static constexpr int arity = 0;}; template <typename Variable, typename Target, typename Opt> struct evaluator {
static constexpr int arity = 0;
};
// closest_point mechanism // closest_point mechanism
template<typename Variable, typename Target, typename Opt> struct get_closest_point; template <typename Variable, typename Target, typename Opt> struct get_closest_point;
// singularity // singularity
template<typename Variable, typename Target, typename Opt> struct singularity { typedef nothing type;}; template <typename Variable, typename Target, typename Opt> struct singularity {
using type = nothing;
};
// symmetry // symmetry
template<typename Variable, typename Target, typename Opt> struct symmetry { typedef nothing type;}; template <typename Variable, typename Target, typename Opt> struct symmetry {
using type = nothing;
};
// data_proxy contains function to manipulate the data array, but no data itself. // data_proxy contains function to manipulate the data array, but no data itself.
// this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf, ...) // this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf,
template<typename Variable, typename Target, typename Opt, typename Enable = void> struct data_proxy; // ...)
template <typename Variable, typename Target, typename Opt, typename Enable = void> struct data_proxy;
// Traits to read/write in hdf5 files. Can be specialized for some case (Cf block). Defined below // Traits to read/write in hdf5 files. Can be specialized for some case (Cf block). Defined below
template <typename Variable, typename Target, typename Opt> struct h5_name; // value is a const char template <typename Variable, typename Target, typename Opt> struct h5_name; // value is a const char
template <typename Variable, typename Target, typename Opt> struct h5_rw; template <typename Variable, typename Target, typename Opt> struct h5_rw;
// factories regroup all factories (constructors..) for all types of gf. Defaults implemented below. // factories regroup all factories (constructors..) for all types of gf. Defaults implemented below.
template <typename Variable, typename Target, typename Opt> struct factories; template <typename Variable, typename Target, typename Opt> struct factories;
} // gfs_implementation } // gfs_implementation
// OBSOLETE : kept for backward compatibility only. Do not document.
// make_gf and make_gf_view forward any args to them
template <typename Variable, typename Target=matrix_valued, typename Opt=void, typename ... U>
gf<Variable,Target,Opt> make_gf(gf_mesh<Variable,Opt> m, U && ... x)
{ return gfs_implementation::factories<Variable,Target,Opt>::make_gf(std::move(m),std::forward<U>(x)...);}
template <typename Variable, typename Target=matrix_valued, typename Opt=void, typename ... U>
gf<Variable,Target,Opt> make_gf(U && ... x) { return gfs_implementation::factories<Variable,Target,Opt>::make_gf(std::forward<U>(x)...);}
template <typename Variable, typename Target=matrix_valued, typename Opt=void, typename ... U>
gf_view<Variable,Target,Opt> make_gf_view(U && ... x) { return gfs_implementation::factories<Variable,Target,Opt>::make_gf_view(std::forward<U>(x)...);}
// The trait that "marks" the Green function // The trait that "marks" the Green function
TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableGreenFunction); TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableGreenFunction);
@ -102,288 +97,297 @@ namespace triqs { namespace gfs {
// overload get_shape for a vector to simplify code below in gf block case. // overload get_shape for a vector to simplify code below in gf block case.
template <typename T> long get_shape(std::vector<T> const &x) { return x.size(); } template <typename T> long get_shape(std::vector<T> const &x) { return x.size(); }
/// A common implementation class for gf and gf_view. They will only redefine contructor and = ... /// A common implementation class for gf and gf_view. They will only redefine contructor and = ...
template <typename Variable, typename Target, typename Opt, bool IsView, bool IsConst> template <typename Variable, typename Target, typename Opt, bool IsView, bool IsConst>
class gf_impl : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction) { class gf_impl : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction) {
static_assert(!(!IsView && IsConst), "Internal error"); static_assert(!(!IsView && IsConst), "Internal error");
public : public:
typedef gf_view<Variable,Target,Opt> mutable_view_type; using mutable_view_type = gf_view<Variable, Target, Opt>;
typedef gf_const_view<Variable,Target,Opt> const_view_type; using const_view_type = gf_const_view<Variable, Target, Opt>;
typedef typename std::conditional <IsConst, const_view_type, mutable_view_type>::type view_type; using view_type = typename std::conditional<IsConst, const_view_type, mutable_view_type>::type;
typedef gf<Variable,Target,Opt> regular_type; using regular_type = gf<Variable, Target, Opt>;
typedef Variable variable_t; using variable_t = Variable;
typedef Target target_t; using target_t = Target;
typedef Opt option_t; using option_t = Opt;
typedef gf_mesh<Variable,Opt> mesh_t; using mesh_t = gf_mesh<Variable, Opt>;
typedef typename mesh_t::domain_t domain_t; using domain_t = typename mesh_t::domain_t;
typedef typename mesh_t::mesh_point_t mesh_point_t; using mesh_point_t = typename mesh_t::mesh_point_t;
typedef typename mesh_t::index_t mesh_index_t; using mesh_index_t = typename mesh_t::index_t;
typedef typename gfs_implementation::symmetry<Variable,Target,Opt>::type symmetry_t; using symmetry_t = typename gfs_implementation::symmetry<Variable, Target, Opt>::type;
typedef gfs_implementation::evaluator<Variable,Target,Opt> evaluator_t; using evaluator_t = gfs_implementation::evaluator<Variable, Target, Opt>;
typedef gfs_implementation::data_proxy<Variable,Target,Opt> data_proxy_t; using data_proxy_t = gfs_implementation::data_proxy<Variable, Target, Opt>;
typedef typename data_proxy_t::storage_t data_regular_t; using data_regular_t = typename data_proxy_t::storage_t;
typedef typename data_proxy_t::storage_view_t data_view_t; using data_view_t = typename data_proxy_t::storage_view_t;
typedef typename data_proxy_t::storage_const_view_t data_const_view_t; using data_const_view_t = typename data_proxy_t::storage_const_view_t;
typedef typename std::conditional<IsView, typename std::conditional<IsConst, data_const_view_t, data_view_t>::type, using data_t = typename std::conditional<IsView, typename std::conditional<IsConst, data_const_view_t, data_view_t>::type,
data_regular_t>::type data_t; data_regular_t>::type;
typedef typename gfs_implementation::singularity<Variable,Target,Opt>::type singularity_non_view_t; using singularity_non_view_t = typename gfs_implementation::singularity<Variable, Target, Opt>::type;
typedef typename view_type_if_exists_else_type<singularity_non_view_t>::type singularity_view_t; using singularity_view_t = typename view_type_if_exists_else_type<singularity_non_view_t>::type;
typedef typename std::conditional<IsView, singularity_view_t, singularity_non_view_t>::type singularity_t; using singularity_t = typename std::conditional<IsView, singularity_view_t, singularity_non_view_t>::type;
mesh_t const & mesh() const { return _mesh;} mesh_t const &mesh() const { return _mesh; }
domain_t const & domain() const { return _mesh.domain();} domain_t const &domain() const { return _mesh.domain(); }
data_t & data() { return _data;} data_t &data() { return _data; }
data_t const & data() const { return _data;} data_t const &data() const { return _data; }
singularity_t & singularity() { return _singularity;} singularity_t &singularity() { return _singularity; }
singularity_t const & singularity() const { return _singularity;} singularity_t const &singularity() const { return _singularity; }
symmetry_t const & symmetry() const { return _symmetry;} symmetry_t const &symmetry() const { return _symmetry; }
evaluator_t const & get_evaluator() const { return _evaluator;} evaluator_t const &get_evaluator() const { return _evaluator; }
auto get_data_shape() const DECL_AND_RETURN(get_shape(this->data())); auto get_data_shape() const DECL_AND_RETURN(get_shape(this -> data()));
protected: protected:
mesh_t _mesh; mesh_t _mesh;
data_t _data; data_t _data;
singularity_t _singularity; singularity_t _singularity;
symmetry_t _symmetry; symmetry_t _symmetry;
evaluator_t _evaluator; evaluator_t _evaluator;
data_proxy_t _data_proxy; data_proxy_t _data_proxy;
// --------------------------------Constructors ----------------------------------------------- // --------------------------------Constructors -----------------------------------------------
// all protected but one, this is an implementation class, see gf/gf_view later for public one // all protected but one, this is an implementation class, see gf/gf_view later for public one
gf_impl() {} // all arrays of zero size (empty) gf_impl() {} // all arrays of zero size (empty)
public : //everyone can make a copy and a move (for clef lib in particular, this one needs to be public) public: // everyone can make a copy and a move (for clef lib in particular, this one needs to be public)
gf_impl(gf_impl const &x) gf_impl(gf_impl const &x)
: _mesh(x.mesh()), : _mesh(x.mesh()),
_data(factory<data_t>(x.data())), _data(factory<data_t>(x.data())),
_singularity(factory<singularity_t>(x.singularity())), _singularity(factory<singularity_t>(x.singularity())),
_symmetry(x.symmetry()), _symmetry(x.symmetry()),
_evaluator(x._evaluator) {} _evaluator(x._evaluator) {}
gf_impl(gf_impl &&) = default; gf_impl(gf_impl &&) = default;
protected: protected:
template <typename G> template <typename G>
gf_impl(G &&x, bool) // bool to disambiguate gf_impl(G &&x, bool) // bool to disambiguate
: _mesh(x.mesh()), : _mesh(x.mesh()),
_data(factory<data_t>(x.data())), _data(factory<data_t>(x.data())),
_singularity(factory<singularity_t>(x.singularity())), _singularity(factory<singularity_t>(x.singularity())),
_symmetry(x.symmetry()), _symmetry(x.symmetry()),
_evaluator(x.get_evaluator()) {} _evaluator(x.get_evaluator()) {}
template <typename M, typename D, typename S, typename SY, typename EV> template <typename M, typename D, typename S, typename SY, typename EV>
gf_impl(M &&m, D &&dat, S &&sing, SY &&sy, EV &&ev) gf_impl(M &&m, D &&dat, S &&sing, SY &&sy, EV &&ev)
: _mesh(std::forward<M>(m)), : _mesh(std::forward<M>(m)),
_data(std::forward<D>(dat)), _data(std::forward<D>(dat)),
_singularity(std::forward<S>(sing)), _singularity(std::forward<S>(sing)),
_symmetry(std::forward<SY>(sy)), _symmetry(std::forward<SY>(sy)),
_evaluator(std::forward<EV>(ev)) {} _evaluator(std::forward<EV>(ev)) {}
void operator = (gf_impl const & rhs) = delete; // done in derived class. void operator=(gf_impl const &rhs) = delete; // done in derived class.
void swap_impl (gf_impl & b) noexcept { void swap_impl(gf_impl &b) noexcept {
using std::swap; using std::swap;
swap(this->_mesh, b._mesh); swap(this->_mesh, b._mesh);
swap(this->_data, b._data); swap(this->_data, b._data);
swap(this->_singularity, b._singularity); swap(this->_singularity, b._singularity);
swap(this->_symmetry, b._symmetry); swap(this->_symmetry, b._symmetry);
swap(this->_evaluator, b._evaluator); swap(this->_evaluator, b._evaluator);
} }
public: public:
// ------------- All the call operators -----------------------------
// ------------- All the call operators ----------------------------- // First, a simple () returns a view, like for an array...
const_view_type operator()() const { return *this; }
view_type operator()() { return *this; }
// First, a simple () returns a view, like for an array... /// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when
const_view_type operator()() const { return *this; } /// there is at least one lazy argument ...
view_type operator()() { return *this; } template <typename... Args> // match any argument list, picking out the first type : () is not permitted
typename std::add_const<typename boost::lazy_disable_if_c< // disable the template if one the following conditions it true
(sizeof...(Args) == 0) || clef::is_any_lazy<Args...>::value ||
((sizeof...(Args) != evaluator_t::arity) && (evaluator_t::arity != -1)) // if -1 : no check
,
std::result_of<evaluator_t(gf_impl *, Args...)> // what is the result type of call
>::type // end of lazy_disable_if
>::type // end of add_Const
operator()(Args &&... args) const {
return _evaluator(this, std::forward<Args>(args)...);
}
/// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when template <typename... Args> typename clef::_result_of::make_expr_call<gf_impl &, Args...>::type operator()(Args &&... args) & {
/// there is at least one lazy argument ... return clef::make_expr_call(*this, std::forward<Args>(args)...);
template <typename... Args> // match any argument list, picking out the first type : () is not permitted }
typename std::add_const<typename boost::lazy_disable_if_c< // disable the template if one the following conditions it true
(sizeof...(Args) == 0) || clef::is_any_lazy<Args...>::value ||
((sizeof...(Args) != evaluator_t::arity) && (evaluator_t::arity != -1)) // if -1 : no check
,
std::result_of<evaluator_t(gf_impl *, Args...)> // what is the result type of call
>::type // end of lazy_disable_if
>::type // end of add_Const
operator()(Args &&... args) const {
return _evaluator(this, std::forward<Args>(args)...);
}
template <typename... Args> template <typename... Args>
typename clef::_result_of::make_expr_call<gf_impl &, Args...>::type operator()(Args &&... args) & { typename clef::_result_of::make_expr_call<gf_impl const &, Args...>::type operator()(Args &&... args) const &{
return clef::make_expr_call(*this, std::forward<Args>(args)...); return clef::make_expr_call(*this, std::forward<Args>(args)...);
} }
template <typename... Args> template <typename... Args> typename clef::_result_of::make_expr_call<gf_impl, Args...>::type operator()(Args &&... args) && {
typename clef::_result_of::make_expr_call<gf_impl const &, Args...>::type operator()(Args &&... args) const &{ return clef::make_expr_call(std::move(*this), std::forward<Args>(args)...);
return clef::make_expr_call(*this, std::forward<Args>(args)...); }
}
template <typename... Args> typename clef::_result_of::make_expr_call<gf_impl, Args...>::type operator()(Args &&... args) && { // ------------- All the [] operators -----------------------------
return clef::make_expr_call(std::move(*this), std::forward<Args>(args)...); // [] and access to the grid point
} using r_type = typename std::result_of<data_proxy_t(data_t &, size_t)>::type;
using cr_type = typename std::result_of<data_proxy_t(data_t const &, size_t)>::type;
// ------------- All the [] operators ----------------------------- r_type operator[](mesh_index_t const &arg) { return _data_proxy(_data, _mesh.index_to_linear(arg)); }
// [] and access to the grid point cr_type operator[](mesh_index_t const &arg) const { return _data_proxy(_data, _mesh.index_to_linear(arg)); }
typedef typename std::result_of<data_proxy_t(data_t &, size_t)>::type r_type;
typedef typename std::result_of<data_proxy_t(data_t const &, size_t)>::type cr_type;
r_type operator[] (mesh_index_t const & arg) { return _data_proxy(_data,_mesh.index_to_linear(arg));} r_type operator[](mesh_point_t const &x) { return _data_proxy(_data, x.linear_index()); }
cr_type operator[] (mesh_index_t const & arg) const { return _data_proxy(_data,_mesh.index_to_linear(arg));} cr_type operator[](mesh_point_t const &x) const { return _data_proxy(_data, x.linear_index()); }
r_type operator[] (mesh_point_t const & x) { return _data_proxy(_data, x.linear_index());} template <typename... U> r_type operator[](closest_pt_wrap<U...> const &p) {
cr_type operator[] (mesh_point_t const & x) const { return _data_proxy(_data, x.linear_index());} return _data_proxy(_data,
_mesh.index_to_linear(gfs_implementation::get_closest_point<Variable, Target, Opt>::invoke(this, p)));
}
template <typename... U> cr_type operator[](closest_pt_wrap<U...> const &p) const {
return _data_proxy(_data,
_mesh.index_to_linear(gfs_implementation::get_closest_point<Variable, Target, Opt>::invoke(this, p)));
}
template<typename ... U> template <typename Arg>
r_type operator[] (closest_pt_wrap<U...> const & p) { return _data_proxy(_data, _mesh.index_to_linear( gfs_implementation::get_closest_point<Variable,Target,Opt>::invoke(this,p)));} typename clef::_result_of::make_expr_subscript<gf_impl const &, Arg>::type operator[](Arg &&arg) const &{
template<typename ... U> return clef::make_expr_subscript(*this, std::forward<Arg>(arg));
cr_type operator[] (closest_pt_wrap<U...> const & p) const { return _data_proxy(_data, _mesh.index_to_linear( gfs_implementation::get_closest_point<Variable,Target,Opt>::invoke(this,p)));} }
template<typename Arg> template <typename Arg> typename clef::_result_of::make_expr_subscript<gf_impl &, Arg>::type operator[](Arg &&arg) & {
typename clef::_result_of::make_expr_subscript<gf_impl const &,Arg>::type return clef::make_expr_subscript(*this, std::forward<Arg>(arg));
operator[](Arg && arg) const & { return clef::make_expr_subscript(*this,std::forward<Arg>(arg));} }
template<typename Arg> template <typename Arg> typename clef::_result_of::make_expr_subscript<gf_impl, Arg>::type operator[](Arg &&arg) && {
typename clef::_result_of::make_expr_subscript<gf_impl &,Arg>::type return clef::make_expr_subscript(std::move(*this), std::forward<Arg>(arg));
operator[](Arg && arg) & { return clef::make_expr_subscript(*this,std::forward<Arg>(arg));} }
template<typename Arg> /// --------------------- A direct access to the grid point --------------------------
typename clef::_result_of::make_expr_subscript<gf_impl,Arg>::type template <typename... Args> r_type on_mesh(Args &&... args) {
operator[](Arg && arg) && { return clef::make_expr_subscript(std::move(*this),std::forward<Arg>(arg));} return _data_proxy(_data, _mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));
}
/// --------------------- A direct access to the grid point -------------------------- template <typename... Args> cr_type on_mesh(Args &&... args) const {
template<typename... Args> return _data_proxy(_data, _mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));
r_type on_mesh (Args&&... args) { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));} }
template<typename... Args> // The on_mesh little adaptor ....
cr_type on_mesh (Args&&... args) const { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward<Args>(args)...)));} private:
struct _on_mesh_wrapper_const {
gf_impl const &f;
template <typename... Args> cr_type operator()(Args &&... args) const { return f.on_mesh(std::forward<Args>(args)...); }
};
struct _on_mesh_wrapper {
gf_impl &f;
template <typename... Args> r_type operator()(Args &&... args) const { return f.on_mesh(std::forward<Args>(args)...); }
};
// The on_mesh little adaptor .... public:
private: _on_mesh_wrapper_const friend on_mesh(gf_impl const &f) {
struct _on_mesh_wrapper_const { return {f};
gf_impl const &f; }
template <typename... Args> cr_type operator()(Args &&... args) const { return f.on_mesh(std::forward<Args>(args)...); } _on_mesh_wrapper friend on_mesh(gf_impl &f) {
}; return {f};
struct _on_mesh_wrapper { }
gf_impl &f;
template <typename... Args> r_type operator()(Args &&... args) const { return f.on_mesh(std::forward<Args>(args)...); }
};
public: //----------------------------- HDF5 -----------------------------
_on_mesh_wrapper_const friend on_mesh(gf_impl const &f) {
return {f};
}
_on_mesh_wrapper friend on_mesh(gf_impl &f) {
return {f};
}
//----------------------------- HDF5 ----------------------------- friend std::string get_triqs_hdf5_data_scheme(gf_impl const &g) {
return "Gf" + gfs_implementation::h5_name<Variable, Target, Opt>::invoke();
}
friend std::string get_triqs_hdf5_data_scheme(gf_impl const & g) { return "Gf" + gfs_implementation::h5_name<Variable,Target,Opt>::invoke();} friend class gfs_implementation::h5_rw<Variable, Target, Opt>;
friend class gfs_implementation::h5_rw<Variable,Target,Opt>; /// Write into HDF5
friend void h5_write(h5::group fg, std::string subgroup_name, gf_impl const &g) {
auto gr = fg.create_group(subgroup_name);
gr.write_triqs_hdf5_data_scheme(g);
gfs_implementation::h5_rw<Variable, Target, Opt>::write(gr, g);
}
/// Write into HDF5 /// Read from HDF5
friend void h5_write (h5::group fg, std::string subgroup_name, gf_impl const & g) { friend void h5_read(h5::group fg, std::string subgroup_name, gf_impl &g) {
auto gr = fg.create_group(subgroup_name); auto gr = fg.open_group(subgroup_name);
gr.write_triqs_hdf5_data_scheme(g); // Check the attribute or throw
gfs_implementation::h5_rw<Variable,Target,Opt>::write(gr, g); auto tag_file = gr.read_triqs_hdf5_data_scheme();
} auto tag_expected = get_triqs_hdf5_data_scheme(g);
if (tag_file != tag_expected)
TRIQS_RUNTIME_ERROR << "h5_read : mismatch of the tag TRIQS_HDF5_data_scheme tag in the h5 group : found " << tag_file
<< " while I expected " << tag_expected;
gfs_implementation::h5_rw<Variable, Target, Opt>::read(gr, g);
}
/// Read from HDF5 //----------------------------- BOOST Serialization -----------------------------
friend void h5_read (h5::group fg, std::string subgroup_name, gf_impl & g) { friend class boost::serialization::access;
auto gr = fg.open_group(subgroup_name); template <class Archive> void serialize(Archive &ar, const unsigned int version) {
// Check the attribute or throw ar &boost::serialization::make_nvp("data", _data);
auto tag_file = gr.read_triqs_hdf5_data_scheme(); ar &boost::serialization::make_nvp("singularity", _singularity);
auto tag_expected= get_triqs_hdf5_data_scheme(g); ar &boost::serialization::make_nvp("mesh", _mesh);
if (tag_file != tag_expected) ar &boost::serialization::make_nvp("symmetry", _symmetry);
TRIQS_RUNTIME_ERROR<< "h5_read : mismatch of the tag TRIQS_HDF5_data_scheme tag in the h5 group : found "<<tag_file << " while I expected "<< tag_expected; }
gfs_implementation::h5_rw<Variable,Target,Opt>::read(gr, g);
}
//----------------------------- BOOST Serialization -----------------------------
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & boost::serialization::make_nvp("data",_data);
ar & boost::serialization::make_nvp("singularity",_singularity);
ar & boost::serialization::make_nvp("mesh",_mesh);
ar & boost::serialization::make_nvp("symmetry",_symmetry);
}
/// print
friend std::ostream & operator << (std::ostream & out, gf_impl const & x) { return out<<(IsView ? "gf_view": "gf");}
friend std::ostream & triqs_nvl_formal_print(std::ostream & out, gf_impl const & x) { return out<<(IsView ? "gf_view": "gf");}
/// print
friend std::ostream &operator<<(std::ostream &out, gf_impl const &x) { return out << (IsView ? "gf_view" : "gf"); }
friend std::ostream &triqs_nvl_formal_print(std::ostream &out, gf_impl const &x) { return out << (IsView ? "gf_view" : "gf"); }
}; };
// -------------------------Interaction with the CLEF library : auto assignement implemnetation-------------------------------------- // -------------------------Interaction with the CLEF library : auto assignement implementation -----------------
// auto assignment of the gf (gf(om_) << expression fills the functions by evaluation of expression) // auto assignment of the gf (gf(om_) << expression fills the functions by evaluation of expression)
template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView> template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView>
void triqs_clef_auto_assign(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs) { void triqs_clef_auto_assign(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs) {
triqs_clef_auto_assign_impl(g, rhs, typename std::is_base_of<tag::composite, gf_mesh<Variable,Opt>>::type()); triqs_clef_auto_assign_impl(g, rhs, typename std::is_base_of<tag::composite, gf_mesh<Variable, Opt>>::type());
assign_from_expression(g.singularity(), rhs); assign_from_expression(g.singularity(), rhs);
// access to the data . Beware, we view it as a *matrix* NOT an array... (crucial for assignment to scalars !) // access to the data . Beware, we view it as a *matrix* NOT an array... (crucial for assignment to scalars !)
// if f is an expression, replace the placeholder with a simple tail. If f is a function callable on freq_infty, // if f is an expression, replace the placeholder with a simple tail. If f is a function callable on freq_infty,
// it uses the fact that tail_non_view_t can be casted into freq_infty // it uses the fact that tail_non_view_t can be casted into freq_infty
} }
// enable the writing g[om_] << .... also // enable the writing g[om_] << .... also
template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView> template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView>
void triqs_clef_auto_assign_subscript(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs) { void triqs_clef_auto_assign_subscript(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs) {
triqs_clef_auto_assign(g, rhs); triqs_clef_auto_assign(g, rhs);
} }
template <bool B, typename G, typename RHS> template <bool B, typename G, typename RHS>
void triqs_gf_clef_auto_assign_impl_aux_assign(G &&g, RHS &&rhs, std::integral_constant<bool, B>) { void triqs_gf_clef_auto_assign_impl_aux_assign(G &&g, RHS &&rhs, std::integral_constant<bool, B>) {
std::forward<G>(g) = std::forward<RHS>(rhs); std::forward<G>(g) = std::forward<RHS>(rhs);
} }
template <typename G, bool B, typename Expr, int... Is> template <typename G, bool B, typename Expr, int... Is>
void triqs_gf_clef_auto_assign_impl_aux_assign(G &&g, clef::make_fun_impl<Expr, Is...> &&rhs, std::integral_constant<bool, B>) { void triqs_gf_clef_auto_assign_impl_aux_assign(G &&g, clef::make_fun_impl<Expr, Is...> &&rhs, std::integral_constant<bool, B>) {
triqs_clef_auto_assign_impl(std::forward<G>(g), std::forward<clef::make_fun_impl<Expr, Is...>>(rhs), std::integral_constant<bool, B>()); triqs_clef_auto_assign_impl(std::forward<G>(g), std::forward<clef::make_fun_impl<Expr, Is...>>(rhs),
} std::integral_constant<bool, B>());
}
template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView> template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView>
void triqs_clef_auto_assign_impl(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs, void triqs_clef_auto_assign_impl(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs,
std::integral_constant<bool, false>) { std::integral_constant<bool, false>) {
for (auto const &w : g.mesh()) { for (auto const &w : g.mesh()) {
triqs_gf_clef_auto_assign_impl_aux_assign(g[w], rhs(w), std::integral_constant<bool, false>()); triqs_gf_clef_auto_assign_impl_aux_assign(g[w], rhs(w), std::integral_constant<bool, false>());
//(*this)[w] = rhs(w); //(*this)[w] = rhs(w);
}
} }
}
template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView> template <typename RHS, typename Variable, typename Target, typename Opt, bool IsView>
void triqs_clef_auto_assign_impl(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs, void triqs_clef_auto_assign_impl(gf_impl<Variable, Target, Opt, IsView, false> &g, RHS const &rhs,
std::integral_constant<bool, true>) { std::integral_constant<bool, true>) {
for (auto const &w : g.mesh()) { for (auto const &w : g.mesh()) {
triqs_gf_clef_auto_assign_impl_aux_assign(g[w], triqs::tuple::apply(rhs, w.components_tuple()), std::integral_constant<bool, true>()); triqs_gf_clef_auto_assign_impl_aux_assign(g[w], triqs::tuple::apply(rhs, w.components_tuple()),
//(*this)[w] = triqs::tuple::apply(rhs, w.components_tuple()); std::integral_constant<bool, true>());
} //(*this)[w] = triqs::tuple::apply(rhs, w.components_tuple());
} }
}
// -------------------------The regular class of GF -------------------------------------------------------- // -------------------------The regular class of GF --------------------------------------------------------
template<typename Variable, typename Target, typename Opt> class gf : public gf_impl<Variable,Target,Opt,false, false> { template <typename Variable, typename Target, typename Opt> class gf : public gf_impl<Variable, Target, Opt, false, false> {
typedef gf_impl<Variable,Target,Opt,false,false> B; using B = gf_impl<Variable, Target, Opt, false, false>;
typedef gfs_implementation::factories<Variable,Target,Opt> factory; using factory = gfs_implementation::factories<Variable, Target, Opt>;
public :
public:
gf() : B() {} gf() : B() {}
gf(gf const &g) : B(g) {} gf(gf const &g) : B(g) {}
gf(gf &&g) noexcept : B(std::move(g)) {} gf(gf &&g) noexcept : B(std::move(g)) {}
gf(gf_view<Variable, Target, Opt> const &g) : B(g, bool{}) {} gf(gf_view<Variable, Target, Opt> const &g) : B(g, bool {}) {}
gf(gf_const_view<Variable, Target, Opt> const &g) : B(g, bool{}) {} gf(gf_const_view<Variable, Target, Opt> const &g) : B(g, bool {}) {}
template <typename GfType> template <typename GfType>
gf(GfType const &x, typename std::enable_if<ImmutableGreenFunction<GfType>::value>::type *dummy = 0) gf(GfType const &x, typename std::enable_if<ImmutableGreenFunction<GfType>::value>::type *dummy = 0)
@ -394,50 +398,64 @@ namespace triqs { namespace gfs {
gf(typename B::mesh_t m, typename B::data_t dat, typename B::singularity_view_t const &si, typename B::symmetry_t const &s) gf(typename B::mesh_t m, typename B::data_t dat, typename B::singularity_view_t const &si, typename B::symmetry_t const &s)
: B(std::move(m), std::move(dat), si, s, typename B::evaluator_t{}) {} : B(std::move(m), std::move(dat), si, s, typename B::evaluator_t{}) {}
typedef typename factory::target_shape_t target_shape_t; using target_shape_t = typename factory::target_shape_t;
gf(typename B::mesh_t m, target_shape_t shape = target_shape_t{} ): gf(typename B::mesh_t m, target_shape_t shape = target_shape_t{})
B(std::move(m), factory::make_data(m,shape), factory::make_singularity(m,shape), typename B::symmetry_t {}, typename B::evaluator_t{}) {} : B(std::move(m), factory::make_data(m, shape), factory::make_singularity(m, shape), typename B::symmetry_t{},
typename B::evaluator_t{}) {}
friend void swap (gf & a, gf & b) noexcept { a.swap_impl (b);} friend void swap(gf &a, gf &b) noexcept { a.swap_impl(b); }
gf & operator = (gf const & rhs) { *this = gf(rhs); return *this;} // use move = gf &operator=(gf const &rhs) {
gf & operator = (gf & rhs) { *this = gf(rhs); return *this;} // use move = *this = gf(rhs);
gf & operator = (gf && rhs) noexcept { swap(*this,rhs); return *this;} return *this;
} // use move =
template<typename RHS> void operator = (RHS && rhs) { gf &operator=(gf &rhs) {
this->_mesh = rhs.mesh(); *this = gf(rhs);
this->_data.resize(get_gf_data_shape(rhs)); return *this;
for (auto const & w: this->mesh()) { (*this)[w] = rhs[w]; } } // use move =
this->_singularity = rhs.singularity(); gf &operator=(gf &&rhs) noexcept {
// to be implemented : there is none in the gf_expr in particular.... swap(*this, rhs);
//this->_symmetry = rhs.symmetry(); return *this;
} }
template <typename RHS> void operator=(RHS &&rhs) {
this->_mesh = rhs.mesh();
this->_data.resize(get_gf_data_shape(rhs));
for (auto const &w : this->mesh()) {
(*this)[w] = rhs[w];
}
this->_singularity = rhs.singularity();
// to be implemented : there is none in the gf_expr in particular....
// this->_symmetry = rhs.symmetry();
}
}; };
// --------------------------The const View class of GF ------------------------------------------------------- // --------------------------The const View class of GF -------------------------------------------------------
template<typename Variable, typename Target, typename Opt> class gf_view<Variable,Target,Opt,true> : public gf_impl<Variable,Target,Opt,true,true> { template <typename Variable, typename Target, typename Opt>
typedef gf_impl<Variable,Target,Opt,true,true> B; class gf_view<Variable, Target, Opt, true> : public gf_impl<Variable, Target, Opt, true, true> {
public : using B = gf_impl<Variable, Target, Opt, true, true>;
public:
gf_view() = delete; gf_view() = delete;
gf_view(gf_view const &g) : B(g) {} gf_view(gf_view const &g) : B(g) {}
gf_view(gf_view &&g) noexcept : B(std::move(g)) {} gf_view(gf_view &&g) noexcept : B(std::move(g)) {}
gf_view(gf_impl<Variable, Target, Opt, true, true> const &g) : B(g, bool{}) {} // from a const_view gf_view(gf_impl<Variable, Target, Opt, true, true> const &g) : B(g, bool {}) {} // from a const_view
gf_view(gf_impl<Variable, Target, Opt, true, false> const &g) : B(g, bool{}) {} // from a view gf_view(gf_impl<Variable, Target, Opt, true, false> const &g) : B(g, bool {}) {} // from a view
gf_view(gf_impl<Variable, Target, Opt, false, false> const &g) : B(g, bool{}) {} // from a const gf gf_view(gf_impl<Variable, Target, Opt, false, false> const &g) : B(g, bool {}) {} // from a const gf
gf_view(gf_impl<Variable, Target, Opt, false, false> &g) : B(g, bool{}) {} // from a gf & gf_view(gf_impl<Variable, Target, Opt, false, false> &g) : B(g, bool {}) {} // from a gf &
gf_view(gf_impl<Variable, Target, Opt, false, false> &&g) noexcept : B(std::move(g), bool{}) {} // from a gf && gf_view(gf_impl<Variable, Target, Opt, false, false> &&g) noexcept : B(std::move(g), bool {}) {} // from a gf &&
template <typename D> template <typename D>
gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s) gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s)
: B(m, factory<typename B::data_t>(dat), t, s, typename B::evaluator_t{}) {} : B(m, factory<typename B::data_t>(dat), t, s, typename B::evaluator_t{}) {}
void rebind(gf_view const &X) noexcept { void rebind(gf_view const &X) noexcept {
this->_mesh = X._mesh; this->_symmetry = X._symmetry; this->_mesh = X._mesh;
this->_data_proxy.rebind(this->_data,X); this->_symmetry = X._symmetry;
this->_data_proxy.rebind(this->_data, X);
this->_singularity.rebind(X._singularity); this->_singularity.rebind(X._singularity);
} }
@ -445,33 +463,36 @@ namespace triqs { namespace gfs {
rebind(gf_view{X}); rebind(gf_view{X});
} }
gf_view & operator = (gf_view const & ) = delete; gf_view &operator=(gf_view const &) = delete;
}; // class gf_const_view }; // class gf_const_view
// ------------------------- The View class of GF ------------------------------------------------------- // ------------------------- The View class of GF -------------------------------------------------------
template<typename Variable, typename Target, typename Opt> class gf_view<Variable,Target,Opt,false> : public gf_impl<Variable,Target,Opt,true,false> { template <typename Variable, typename Target, typename Opt>
typedef gf_impl<Variable,Target,Opt,true,false> B; class gf_view<Variable, Target, Opt, false> : public gf_impl<Variable, Target, Opt, true, false> {
public : using B = gf_impl<Variable, Target, Opt, true, false>;
public:
gf_view() = delete; gf_view() = delete;
gf_view(gf_view const &g) : B(g) {} gf_view(gf_view const &g) : B(g) {}
gf_view(gf_view &&g) noexcept : B(std::move(g)) {} gf_view(gf_view &&g) noexcept : B(std::move(g)) {}
gf_view(gf_impl<Variable, Target, Opt, true, true> const &g) = delete; // from a const view : impossible gf_view(gf_impl<Variable, Target, Opt, true, true> const &g) = delete; // from a const view : impossible
gf_view(gf_impl<Variable, Target, Opt, true, false> const &g) : B(g, bool{}) {} // from a view gf_view(gf_impl<Variable, Target, Opt, true, false> const &g) : B(g, bool {}) {} // from a view
gf_view(gf_impl<Variable, Target, Opt, false, false> const &g) = delete; // from a const gf : impossible gf_view(gf_impl<Variable, Target, Opt, false, false> const &g) = delete; // from a const gf : impossible
gf_view(gf_impl<Variable, Target, Opt, false, false> &g) : B(g, bool{}) {} // from a gf & gf_view(gf_impl<Variable, Target, Opt, false, false> &g) : B(g, bool {}) {} // from a gf &
gf_view(gf_impl<Variable, Target, Opt, false, false> &&g) noexcept : B(std::move(g), bool{}) {} // from a gf && gf_view(gf_impl<Variable, Target, Opt, false, false> &&g) noexcept : B(std::move(g), bool {}) {} // from a gf &&
template <typename D> template <typename D>
gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s) gf_view(typename B::mesh_t const &m, D const &dat, typename B::singularity_view_t const &t, typename B::symmetry_t const &s)
: B(m, factory<typename B::data_t>(dat), t, s, typename B::evaluator_t{}) {} : B(m, factory<typename B::data_t>(dat), t, s, typename B::evaluator_t{}) {}
friend void swap (gf_view & a, gf_view & b) noexcept { a.swap_impl (b);} friend void swap(gf_view &a, gf_view &b) noexcept { a.swap_impl(b); }
void rebind(gf_view const &X) noexcept { void rebind(gf_view const &X) noexcept {
this->_mesh = X._mesh; this->_symmetry = X._symmetry; this->_mesh = X._mesh;
this->_data_proxy.rebind(this->_data,X); this->_symmetry = X._symmetry;
this->_data_proxy.rebind(this->_data, X);
this->_singularity.rebind(X._singularity); this->_singularity.rebind(X._singularity);
} }
@ -487,89 +508,93 @@ namespace triqs { namespace gfs {
}; // class gf_view }; // class gf_view
// delegate = so that I can overload it for specific RHS... // delegate = so that I can overload it for specific RHS...
template<typename Variable, typename Target, typename Opt, typename RHS> template <typename Variable, typename Target, typename Opt, typename RHS>
DISABLE_IF(arrays::is_scalar<RHS>) triqs_gf_view_assign_delegation( gf_view<Variable,Target,Opt> g, RHS const & rhs) { DISABLE_IF(arrays::is_scalar<RHS>) triqs_gf_view_assign_delegation(gf_view<Variable, Target, Opt> g, RHS const &rhs) {
if (!(g.mesh() == rhs.mesh())) TRIQS_RUNTIME_ERROR<<"Gf Assignment in View : incompatible mesh"<<g.mesh() << " vs "<< rhs.mesh(); if (!(g.mesh() == rhs.mesh()))
for (auto const & w: g.mesh()) g[w] = rhs[w]; TRIQS_RUNTIME_ERROR << "Gf Assignment in View : incompatible mesh" << g.mesh() << " vs " << rhs.mesh();
g.singularity() = rhs.singularity(); for (auto const &w : g.mesh()) g[w] = rhs[w];
} g.singularity() = rhs.singularity();
}
template<typename Variable, typename Target, typename Opt, typename T> template <typename Variable, typename Target, typename Opt, typename T>
ENABLE_IF(arrays::is_scalar<T>) triqs_gf_view_assign_delegation( gf_view<Variable,Target,Opt> g, T const & x) { ENABLE_IF(arrays::is_scalar<T>) triqs_gf_view_assign_delegation(gf_view<Variable, Target, Opt> g, T const &x) {
gf_view<Variable,Target,Opt>::data_proxy_t::assign_to_scalar(g.data(), x); gf_view<Variable, Target, Opt>::data_proxy_t::assign_to_scalar(g.data(), x);
g.singularity() = x; g.singularity() = x;
} }
// tool for lazy transformation // tool for lazy transformation
template <typename Tag, typename D, typename Target = matrix_valued, typename Opt=void> struct gf_keeper { template <typename Tag, typename D, typename Target = matrix_valued, typename Opt = void> struct gf_keeper {
gf_const_view<D, Target, Opt> g; gf_const_view<D, Target, Opt> g;
}; };
// ---------------------------------- slicing ------------------------------------ // ---------------------------------- slicing ------------------------------------
// slice // slice
template <typename Variable, typename Target, typename Opt, bool IsConst, typename... Args> template <typename Variable, typename Target, typename Opt, bool IsConst, typename... Args>
gf_view<Variable, matrix_valued, Opt, IsConst> slice_target(gf_view<Variable, Target, Opt, IsConst> g, Args &&... args) { gf_view<Variable, matrix_valued, Opt, IsConst> slice_target(gf_view<Variable, Target, Opt, IsConst> g, Args &&... args) {
static_assert(std::is_same<Target, matrix_valued>::value, "slice_target only for matrix_valued GF's"); static_assert(std::is_same<Target, matrix_valued>::value, "slice_target only for matrix_valued GF's");
using arrays::range; using arrays::range;
return {g.mesh(), g.data()(range(), std::forward<Args>(args)...), return {g.mesh(), g.data()(range(), std::forward<Args>(args)...),
slice_target(g.singularity(), std::forward<Args>(args)...), g.symmetry()}; slice_target(g.singularity(), std::forward<Args>(args)...), g.symmetry()};
} }
template <typename Variable, typename Target, typename Opt, typename... Args> template <typename Variable, typename Target, typename Opt, typename... Args>
gf_view<Variable, matrix_valued, Opt> slice_target(gf<Variable, Target, Opt> &g, Args &&... args) { gf_view<Variable, matrix_valued, Opt> slice_target(gf<Variable, Target, Opt> &g, Args &&... args) {
return slice_target(g(), std::forward<Args>(args)...); return slice_target(g(), std::forward<Args>(args)...);
} }
template <typename Variable, typename Target, typename Opt, typename... Args> template <typename Variable, typename Target, typename Opt, typename... Args>
gf_const_view<Variable, matrix_valued, Opt> slice_target(gf<Variable, Target, Opt> const &g, Args &&... args) { gf_const_view<Variable, matrix_valued, Opt> slice_target(gf<Variable, Target, Opt> const &g, Args &&... args) {
return slice_target(g(), std::forward<Args>(args)...); return slice_target(g(), std::forward<Args>(args)...);
} }
// slice to scalar // slice to scalar
template <typename Variable, typename Target, typename Opt, bool IsConst, typename... Args> template <typename Variable, typename Target, typename Opt, bool IsConst, typename... Args>
gf_view<Variable, scalar_valued, Opt, IsConst> slice_target_to_scalar(gf_view<Variable, Target, Opt, IsConst> g, gf_view<Variable, scalar_valued, Opt, IsConst> slice_target_to_scalar(gf_view<Variable, Target, Opt, IsConst> g,
Args &&... args) { Args &&... args) {
static_assert(std::is_same<Target, matrix_valued>::value, "slice_target only for matrix_valued GF's"); static_assert(std::is_same<Target, matrix_valued>::value, "slice_target only for matrix_valued GF's");
using arrays::range; using arrays::range;
return {g.mesh(), g.data()(range(), std::forward<Args>(args)...), return {g.mesh(), g.data()(range(), std::forward<Args>(args)...),
slice_target(g.singularity(), range(args, args + 1)...), g.symmetry()}; slice_target(g.singularity(), range(args, args + 1)...), g.symmetry()};
} }
template <typename Variable, typename Target, typename Opt, typename... Args> template <typename Variable, typename Target, typename Opt, typename... Args>
gf_view<Variable, scalar_valued, Opt> slice_target_to_scalar(gf<Variable, Target, Opt> &g, Args &&... args) { gf_view<Variable, scalar_valued, Opt> slice_target_to_scalar(gf<Variable, Target, Opt> &g, Args &&... args) {
return slice_target_to_scalar(g(), std::forward<Args>(args)...); return slice_target_to_scalar(g(), std::forward<Args>(args)...);
} }
template <typename Variable, typename Target, typename Opt, typename... Args> template <typename Variable, typename Target, typename Opt, typename... Args>
gf_const_view<Variable, scalar_valued, Opt> slice_target_to_scalar(gf<Variable, Target, Opt> const &g, Args &&... args) { gf_const_view<Variable, scalar_valued, Opt> slice_target_to_scalar(gf<Variable, Target, Opt> const &g, Args &&... args) {
return slice_target_to_scalar(g(), std::forward<Args>(args)...); return slice_target_to_scalar(g(), std::forward<Args>(args)...);
} }
// a scalar_valued gf can be viewed as a 1x1 matrix // ---------------------------------- target reinterpretation ------------------------------------
template <typename Variable, typename Opt, bool IsConst>
gf_view<Variable, matrix_valued, Opt, IsConst> // a scalar_valued gf can be viewed as a 1x1 matrix
reinterpret_scalar_valued_gf_as_matrix_valued(gf_view<Variable, scalar_valued, Opt, IsConst> g) { template <typename Variable, typename Opt, bool IsConst>
typedef typename gf_view<Variable, matrix_valued, Opt, IsConst>::data_view_t a_t; gf_view<Variable, matrix_valued, Opt, IsConst>
auto a = a_t{typename a_t::indexmap_type(join(g.data().shape(), make_shape(1, 1))), g.data().storage()}; reinterpret_scalar_valued_gf_as_matrix_valued(gf_view<Variable, scalar_valued, Opt, IsConst> g) {
return {g.mesh(), a, g.singularity(), g.symmetry()}; using a_t = typename gf_view<Variable, matrix_valued, Opt, IsConst>::data_view_t;
} auto a = a_t{typename a_t::indexmap_type(join(g.data().shape(), make_shape(1, 1))), g.data().storage()};
return {g.mesh(), a, g.singularity(), g.symmetry()};
}
template <typename Variable, typename Opt> template <typename Variable, typename Opt>
gf_view<Variable, matrix_valued, Opt> reinterpret_scalar_valued_gf_as_matrix_valued(gf<Variable, scalar_valued, Opt> &g) { gf_view<Variable, matrix_valued, Opt> reinterpret_scalar_valued_gf_as_matrix_valued(gf<Variable, scalar_valued, Opt> &g) {
return reinterpret_scalar_valued_gf_as_matrix_valued(g()); return reinterpret_scalar_valued_gf_as_matrix_valued(g());
} }
template <typename Variable, typename Opt> template <typename Variable, typename Opt>
gf_const_view<Variable, matrix_valued, Opt> gf_const_view<Variable, matrix_valued, Opt>
reinterpret_scalar_valued_gf_as_matrix_valued(gf<Variable, scalar_valued, Opt> const &g) { reinterpret_scalar_valued_gf_as_matrix_valued(gf<Variable, scalar_valued, Opt> const &g) {
return reinterpret_scalar_valued_gf_as_matrix_valued(g()); return reinterpret_scalar_valued_gf_as_matrix_valued(g());
} }
/* /*
template<typename Variable1,typename Variable2, typename Target, typename Opt, bool V, typename... Args> template<typename Variable1,typename Variable2, typename Target, typename Opt, bool V, typename... Args>
gf_view<Variable2,Target,Opt> slice_mesh (gf_impl<Variable1,Target,Opt,V> const & g, Args... args) { gf_view<Variable2,Target,Opt> slice_mesh (gf_impl<Variable1,Target,Opt,V> const & g, Args... args) {
return gf_view<Variable2,Target,Opt>(g.mesh().slice(args...), g.data()(g.mesh().slice_get_range(args...),arrays::ellipsis()), g.singularity(), g.symmetry()); return gf_view<Variable2,Target,Opt>(g.mesh().slice(args...), g.data()(g.mesh().slice_get_range(args...),arrays::ellipsis()),
g.singularity(), g.symmetry());
}*/ }*/
namespace gfs_implementation { // implement some default traits namespace gfs_implementation { // implement some default traits
@ -578,9 +603,9 @@ namespace triqs { namespace gfs {
// ----- tensor_valued // ----- tensor_valued
template <int R, typename Var, typename Opt> struct factories<Var, tensor_valued<R>, Opt> { template <int R, typename Var, typename Opt> struct factories<Var, tensor_valued<R>, Opt> {
typedef gf<Var, tensor_valued<R>, Opt> gf_t; using gf_t = gf<Var, tensor_valued<R>, Opt>;
typedef tqa::mini_vector<size_t, R> target_shape_t; using target_shape_t = arrays::mini_vector<size_t, R>;
typedef typename gf_t::mesh_t mesh_t; using mesh_t = typename gf_t::mesh_t;
static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) { static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) {
typename gf_t::data_t A(shape.front_append(m.size())); typename gf_t::data_t A(shape.front_append(m.size()));
@ -595,9 +620,9 @@ namespace triqs { namespace gfs {
// ----- matrix_valued // ----- matrix_valued
template <typename Var, typename Opt> struct factories<Var, matrix_valued, Opt> { template <typename Var, typename Opt> struct factories<Var, matrix_valued, Opt> {
typedef gf<Var, matrix_valued, Opt> gf_t; using gf_t = gf<Var, matrix_valued, Opt>;
typedef tqa::mini_vector<size_t, 2> target_shape_t; using target_shape_t = arrays::mini_vector<size_t, 2>;
typedef typename gf_t::mesh_t mesh_t; using mesh_t = typename gf_t::mesh_t;
static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) { static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) {
typename gf_t::data_t A(shape.front_append(m.size())); typename gf_t::data_t A(shape.front_append(m.size()));
@ -612,7 +637,7 @@ namespace triqs { namespace gfs {
// ----- scalar_valued // ----- scalar_valued
template <typename Var, typename Opt> struct factories<Var, scalar_valued, Opt> { template <typename Var, typename Opt> struct factories<Var, scalar_valued, Opt> {
typedef gf<Var, scalar_valued, Opt> gf_t; using gf_t = gf<Var, scalar_valued, Opt>;
struct target_shape_t { struct target_shape_t {
target_shape_t front_pop() const { // this make the get_target_shape function works in this case... target_shape_t front_pop() const { // this make the get_target_shape function works in this case...
return {}; return {};
@ -620,8 +645,8 @@ namespace triqs { namespace gfs {
target_shape_t() = default; target_shape_t() = default;
template <typename T> target_shape_t(utility::mini_vector<T, 0>) {} template <typename T> target_shape_t(utility::mini_vector<T, 0>) {}
}; };
typedef typename gf_t::mesh_t mesh_t; using mesh_t = typename gf_t::mesh_t;
static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) { static typename gf_t::data_t make_data(mesh_t const &m, target_shape_t shape) {
typename gf_t::data_t A(m.size()); typename gf_t::data_t A(m.size());
@ -633,7 +658,7 @@ namespace triqs { namespace gfs {
} }
}; };
// --------------------- hdf5 --------------------------------------- // --------------------- hdf5 ---------------------------------------
// scalar function : just add a _s // scalar function : just add a _s
template <typename Variable, typename Opt> struct h5_name<Variable, scalar_valued, Opt> { template <typename Variable, typename Opt> struct h5_name<Variable, scalar_valued, Opt> {
static std::string invoke() { return h5_name<Variable, matrix_valued, Opt>::invoke() + "_s"; } static std::string invoke() { return h5_name<Variable, matrix_valued, Opt>::invoke() + "_s"; }
@ -657,14 +682,12 @@ namespace triqs { namespace gfs {
} }
}; };
} // gfs_implementation } // gfs_implementation
}
}
}}
// same as for arrays : views can not be swapped by the std::swap. Delete it // same as for arrays : views can not be swapped by the std::swap. Delete it
namespace std { namespace std {
template <typename Variable, typename Target, typename Opt, bool C1, bool C2> template <typename Variable, typename Target, typename Opt, bool C1, bool C2>
void swap(triqs::gfs::gf_view<Variable, Target, Opt, C1> &a, triqs::gfs::gf_view<Variable, Target, Opt, C2> &b) = delete; void swap(triqs::gfs::gf_view<Variable, Target, Opt, C1> &a, triqs::gfs::gf_view<Variable, Target, Opt, C2> &b) = delete;
} }
#include "./gf_expr.hpp" #include "./gf_expr.hpp"
#endif

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2012 by M. Ferrero, O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -18,8 +18,7 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_MATSUBARA_FREQ_H #pragma once
#define TRIQS_GF_MATSUBARA_FREQ_H
#include "./tools.hpp" #include "./tools.hpp"
#include "./gf.hpp" #include "./gf.hpp"
#include "./local/tail.hpp" #include "./local/tail.hpp"
@ -32,22 +31,18 @@ namespace gfs {
struct imfreq {}; struct imfreq {};
template <typename Opt> struct gf_mesh<imfreq, Opt> : matsubara_freq_mesh { template <typename Opt> struct gf_mesh<imfreq, Opt> : matsubara_freq_mesh {
using B = matsubara_freq_mesh; template <typename... T> gf_mesh(T &&... x) : matsubara_freq_mesh(std::forward<T>(x)...) {}
static double m1(double beta) { return std::acos(-1) / beta; } //using matsubara_freq_mesh::matsubara_freq_mesh;
gf_mesh() = default;
gf_mesh(B const &x) : B(x) {} // enables also construction from another Opt
gf_mesh(typename B::domain_t const &d, int Nmax = 1025, bool positive_only = true) : B(d, Nmax, positive_only) {}
gf_mesh(double beta, statistic_enum S, int Nmax = 1025) : gf_mesh({beta, S}, Nmax) {}
}; };
namespace gfs_implementation { namespace gfs_implementation {
// singularity // singularity
template <> struct singularity<imfreq, matrix_valued, void> { template <> struct singularity<imfreq, matrix_valued, void> {
typedef local::tail type; using type = local::tail;
}; };
template <> struct singularity<imfreq, scalar_valued, void> { template <> struct singularity<imfreq, scalar_valued, void> {
typedef local::tail type; using type = local::tail;
}; };
// h5 name // h5 name
@ -124,10 +119,13 @@ namespace gfs {
#ifdef __clang__ #ifdef __clang__
// to generate a clearer error message ? . Only ok on clang ? // to generate a clearer error message ? . Only ok on clang ?
template<int n> struct error { static_assert(n>0, "Green function can not be evaluated on a complex number !");}; template <int n> struct error {
static_assert(n > 0, "Green function can not be evaluated on a complex number !");
};
template <typename G> template <typename G> error<0> operator()(G const *g, std::complex<double>) const {
error<0> operator()(G const *g, std::complex<double>) const { return {};} return {};
}
#endif #endif
template <typename G> typename G::singularity_t const &operator()(G const *g, freq_infty const &) const { template <typename G> typename G::singularity_t const &operator()(G const *g, freq_infty const &) const {
@ -142,4 +140,3 @@ namespace gfs {
} // gfs_implementation } // gfs_implementation
} }
} }
#endif

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2012 by M. Ferrero, O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -18,83 +18,89 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_MATSUBARA_TIME_H #pragma once
#define TRIQS_GF_MATSUBARA_TIME_H
#include "./tools.hpp" #include "./tools.hpp"
#include "./gf.hpp" #include "./gf.hpp"
#include "./local/tail.hpp" #include "./local/tail.hpp"
#include "./local/no_tail.hpp" #include "./local/no_tail.hpp"
#include "./domains/matsubara.hpp" #include "./domains/matsubara.hpp"
#include "./meshes/linear.hpp" #include "./meshes/matsubara_time.hpp"
#include "./evaluators.hpp" #include "./evaluators.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
struct imtime {}; struct imtime {};
// gf_mesh type and its factories template <typename Opt> struct gf_mesh<imtime, Opt> : matsubara_time_mesh {
template <typename Opt> struct gf_mesh<imtime, Opt> : linear_mesh<matsubara_domain<false>> { template <typename... T> gf_mesh(T &&... x) : matsubara_time_mesh(std::forward<T>(x)...) {}
typedef linear_mesh<matsubara_domain<false>> B; // using matsubara_time_mesh::matsubara_time_mesh;
gf_mesh() = default;
gf_mesh(B const &x) : B(x) {} // enables also construction from another Opt
gf_mesh(typename B::domain_t d, int n_time_slices, mesh_kind mk = half_bins) : B(d, 0, d.beta, n_time_slices, mk) {}
gf_mesh(double beta, statistic_enum S, int n_time_slices, mesh_kind mk = half_bins) : gf_mesh({beta, S}, n_time_slices, mk) {}
}; };
namespace gfs_implementation { namespace gfs_implementation {
// singularity. If no_tail is given, then it is the default (nothing) // singularity. If no_tail is given, then it is the default (nothing)
template<> struct singularity<imtime,matrix_valued,void> { typedef local::tail type;}; template <> struct singularity<imtime, matrix_valued, void> {
template<> struct singularity<imtime,scalar_valued,void> { typedef local::tail type;}; using type = local::tail;
};
template <> struct singularity<imtime, scalar_valued, void> {
using type = local::tail;
};
// h5 name // h5 name
template<typename Opt> struct h5_name<imtime,matrix_valued,Opt> { static std::string invoke(){ return "ImTime";}}; template <typename Opt> struct h5_name<imtime, matrix_valued, Opt> {
static std::string invoke() { return "ImTime"; }
};
/// --------------------------- data access --------------------------------- /// --------------------------- data access ---------------------------------
template<typename Opt> struct data_proxy<imtime,matrix_valued,Opt> : data_proxy_array<double,3> {}; template <typename Opt> struct data_proxy<imtime, matrix_valued, Opt> : data_proxy_array<double, 3> {};
template<typename Opt> struct data_proxy<imtime,scalar_valued,Opt> : data_proxy_array<double,1> {}; template <typename Opt> struct data_proxy<imtime, scalar_valued, Opt> : data_proxy_array<double, 1> {};
/// --------------------------- closest mesh point on the grid --------------------------------- /// --------------------------- closest mesh point on the grid ---------------------------------
template<typename Opt, typename Target> template <typename Opt, typename Target> struct get_closest_point<imtime, Target, Opt> {
struct get_closest_point <imtime,Target,Opt> { // index_t is int
// index_t is int template <typename G, typename T> static int invoke(G const *g, closest_pt_wrap<T> const &p) {
template<typename G, typename T> double x = (g->mesh().kind() == half_bins ? double(p.value) : double(p.value) + 0.5 * g->mesh().delta());
static int invoke(G const * g, closest_pt_wrap<T> const & p) { int n = std::floor(x / g->mesh().delta());
double x = (g->mesh().kind()==half_bins ? double(p.value) : double(p.value)+ 0.5*g->mesh().delta()); return n;
int n = std::floor(x/g->mesh().delta()); }
return n; };
}
};
/// --------------------------- evaluator --------------------------------- /// --------------------------- evaluator ---------------------------------
// this one is specific because of the beta-antiperiodicity for fermions // this one is specific because of the beta-antiperiodicity for fermions
template<> template <> struct evaluator_fnt_on_mesh<imtime> {
struct evaluator_fnt_on_mesh<imtime> { double w1, w2;
double w1, w2; long n; long n;
evaluator_fnt_on_mesh() = default; evaluator_fnt_on_mesh() = default;
evaluator_fnt_on_mesh (gf_mesh<imtime> const & m, double tau) { evaluator_fnt_on_mesh(gf_mesh<imtime> const &m, double tau) {
double beta = m.domain().beta; double beta = m.domain().beta;
int p = std::floor(tau/beta); int p = std::floor(tau / beta);
tau -= p*beta; tau -= p * beta;
double w; bool in; double w;
std::tie(in, n, w) = windowing(m,tau); bool in;
if (!in) TRIQS_RUNTIME_ERROR <<" Evaluation out of bounds"; std::tie(in, n, w) = windowing(m, tau);
if ((m.domain().statistic == Fermion) && (p%2==1)) {w2 = -w; w1 = w-1;} else { w2 = w; w1 = 1-w;} if (!in) TRIQS_RUNTIME_ERROR << " Evaluation out of bounds";
if ((m.domain().statistic == Fermion) && (p % 2 == 1)) {
w2 = -w;
w1 = w - 1;
} else {
w2 = w;
w1 = 1 - w;
} }
}
template<typename F> auto operator()(F const & f) const DECL_AND_RETURN(w1 * f(n) + w2 * f (n+1)); template <typename F> auto operator()(F const &f) const DECL_AND_RETURN(w1 *f(n) + w2 *f(n + 1));
}; };
// now evaluator // now evaluator
template<typename Opt, typename Target> struct evaluator<imtime,Target,Opt> : evaluator_one_var<imtime>{}; template <typename Opt, typename Target> struct evaluator<imtime, Target, Opt> : evaluator_one_var<imtime> {};
} // gfs_implementation. } // gfs_implementation.
}
}} }
#endif

View File

@ -32,7 +32,7 @@ namespace gfs {
struct impl_worker { struct impl_worker {
tqa::vector<dcomplex> g_in, g_out; arrays::vector<dcomplex> g_in, g_out;
dcomplex oneFermion(dcomplex a, double b, double tau, double beta) { dcomplex oneFermion(dcomplex a, double b, double tau, double beta) {
return -a * (b >= 0 ? exp(-b * tau) / (1 + exp(-beta * b)) : exp(b * (beta - tau)) / (1 + exp(beta * b))); return -a * (b >= 0 ? exp(-b * tau) / (1 + exp(-beta * b)) : exp(b * (beta - tau)) / (1 + exp(beta * b)));

View File

@ -44,8 +44,10 @@ namespace gfs {
void triqs_gf_view_assign_delegation(gf_view<imtime, matrix_valued> g, gf_keeper<tags::fourier, imfreq, matrix_valued> const& L); void triqs_gf_view_assign_delegation(gf_view<imtime, matrix_valued> g, gf_keeper<tags::fourier, imfreq, matrix_valued> const& L);
// The version without tail : only possible in one direction // The version without tail : only possible in one direction
void triqs_gf_view_assign_delegation(gf_view<imfreq, scalar_valued, no_tail> g, gf_keeper<tags::fourier, imtime, scalar_valued, no_tail> const& L); void triqs_gf_view_assign_delegation(gf_view<imfreq, scalar_valued, no_tail> g,
void triqs_gf_view_assign_delegation(gf_view<imfreq, matrix_valued, no_tail> g, gf_keeper<tags::fourier, imtime, matrix_valued, no_tail> const& L); gf_keeper<tags::fourier, imtime, scalar_valued, no_tail> const& L);
void triqs_gf_view_assign_delegation(gf_view<imfreq, matrix_valued, no_tail> g,
gf_keeper<tags::fourier, imtime, matrix_valued, no_tail> const& L);
template <typename Opt> gf_mesh<imfreq, Opt> make_mesh_fourier_compatible(gf_mesh<imtime, Opt> const& m) { template <typename Opt> gf_mesh<imfreq, Opt> make_mesh_fourier_compatible(gf_mesh<imtime, Opt> const& m) {
int L = m.size() - (m.kind() == full_bins ? 1 : 0); int L = m.size() - (m.kind() == full_bins ? 1 : 0);
@ -59,23 +61,20 @@ namespace gfs {
} }
template <typename Target, typename Opt, bool V, bool C> template <typename Target, typename Opt, bool V, bool C>
gf_view<imfreq, Target, Opt> make_gf_from_fourier(gf_impl<imtime, Target, Opt, V, C> const& gt) { gf<imfreq, Target, Opt> make_gf_from_fourier(gf_impl<imtime, Target, Opt, V, C> const& gt) {
auto gw = gf<imfreq, Target, Opt>{make_mesh_fourier_compatible(gt.mesh()), get_target_shape(gt)}; auto gw = gf<imfreq, Target, Opt>{make_mesh_fourier_compatible(gt.mesh()), get_target_shape(gt)};
gw() = fourier(gt); gw() = fourier(gt);
return gw; return gw;
} }
template <typename Target, typename Opt, bool V, bool C> template <typename Target, typename Opt, bool V, bool C>
gf_view<imtime, Target, Opt> make_gf_from_inverse_fourier(gf_impl<imfreq, Target, Opt, V, C> const& gw, gf<imtime, Target, Opt> make_gf_from_inverse_fourier(gf_impl<imfreq, Target, Opt, V, C> const& gw, mesh_kind mk = full_bins) {
mesh_kind mk = full_bins) {
auto gt = gf<imtime, Target, Opt>{make_mesh_fourier_compatible(gw.mesh(), mk), get_target_shape(gw)}; auto gt = gf<imtime, Target, Opt>{make_mesh_fourier_compatible(gw.mesh(), mk), get_target_shape(gw)};
gt() = inverse_fourier(gw); gt() = inverse_fourier(gw);
return gt; return gt;
} }
} }
}
namespace triqs {
namespace clef { namespace clef {
TRIQS_CLEF_MAKE_FNT_LAZY(fourier); TRIQS_CLEF_MAKE_FNT_LAZY(fourier);
TRIQS_CLEF_MAKE_FNT_LAZY(inverse_fourier); TRIQS_CLEF_MAKE_FNT_LAZY(inverse_fourier);

View File

@ -35,7 +35,7 @@ namespace triqs { namespace gfs {
struct impl_worker { struct impl_worker {
tqa::vector<dcomplex> g_in, g_out; arrays::vector<dcomplex> g_in, g_out;
void direct (gf_view<refreq,scalar_valued> gw, gf_const_view<retime,scalar_valued> gt){ void direct (gf_view<refreq,scalar_valued> gw, gf_const_view<retime,scalar_valued> gt){
@ -83,7 +83,7 @@ namespace triqs { namespace gfs {
const double a = gw.mesh().delta() * sqrt( double(L) ); const double a = gw.mesh().delta() * sqrt( double(L) );
auto ta = gw(freq_infty()); auto ta = gw(freq_infty());
tqa::vector<dcomplex> g_in(L), g_out(L); arrays::vector<dcomplex> g_in(L), g_out(L);
dcomplex t1 = ta(1)(0,0), t2 = ta.get_or_zero(2)(0,0); dcomplex t1 = ta(1)(0,0), t2 = ta.get_or_zero(2)(0,0);
dcomplex a1 = (t1 + I * t2/a )/2., a2 = (t1 - I * t2/a )/2.; dcomplex a1 = (t1 + I * t2/a )/2., a2 = (t1 - I * t2/a )/2.;

View File

@ -24,20 +24,20 @@
namespace triqs { namespace gfs { namespace triqs { namespace gfs {
dcomplex F(dcomplex a,double b,double Beta) {return -a/(1+exp(-Beta*b));} dcomplex F(dcomplex a,double b,double Beta) {return -a/(1+exp(-Beta*b));}
using tqa::array; using arrays::array;
//------------------------------------------------------- //-------------------------------------------------------
// For Imaginary Matsubara Frequency functions // For Imaginary Matsubara Frequency functions
// ------------------------------------------------------ // ------------------------------------------------------
tqa::matrix<double> density( gf_view<imfreq> const & G) { arrays::matrix<double> density( gf_view<imfreq> const & G) {
dcomplex I(0,1); dcomplex I(0,1);
auto sh = G.data().shape().front_pop(); auto sh = G.data().shape().front_pop();
auto Beta = G.domain().beta; auto Beta = G.domain().beta;
local::tail_view t = G(freq_infty()); local::tail_view t = G(freq_infty());
if (!t.is_decreasing_at_infinity()) TRIQS_RUNTIME_ERROR<<" density computation : Green Function is not as 1/omega or less !!!"; if (!t.is_decreasing_at_infinity()) TRIQS_RUNTIME_ERROR<<" density computation : Green Function is not as 1/omega or less !!!";
const size_t N1=sh[0], N2 = sh[1]; const size_t N1=sh[0], N2 = sh[1];
tqa::array<dcomplex,2> dens_part(sh), dens_tail(sh), dens(sh); arrays::array<dcomplex,2> dens_part(sh), dens_tail(sh), dens(sh);
tqa::matrix<double> res(sh); arrays::matrix<double> res(sh);
dens_part()=0;dens()=0;dens_tail()=0; dens_part()=0;dens()=0;dens_tail()=0;
for (size_t n1=0; n1<N1;n1++) for (size_t n1=0; n1<N1;n1++)
for (size_t n2=0; n2<N2;n2++) { for (size_t n2=0; n2<N2;n2++) {
@ -70,10 +70,10 @@ namespace triqs { namespace gfs {
} }
tqa::matrix<double> density( gf_view<legendre> const & gl) { arrays::matrix<double> density( gf_view<legendre> const & gl) {
auto sh = gl.data().shape().front_pop(); auto sh = gl.data().shape().front_pop();
tqa::matrix<double> res(sh); arrays::matrix<double> res(sh);
res() = 0.0; res() = 0.0;
for (auto l : gl.mesh()) { for (auto l : gl.mesh()) {
@ -102,21 +102,21 @@ namespace triqs { namespace gfs {
} }
// Impose a discontinuity G(\tau=0)-G(\tau=\beta) // Impose a discontinuity G(\tau=0)-G(\tau=\beta)
void enforce_discontinuity(gf_view<legendre> & gl, tqa::array_view<double,2> disc) { void enforce_discontinuity(gf_view<legendre> & gl, arrays::array_view<double,2> disc) {
double norm = 0.0; double norm = 0.0;
tqa::vector<double> t(gl.data().shape()[0]); arrays::vector<double> t(gl.data().shape()[0]);
for (int i=0; i<t.size(); ++i) { for (int i=0; i<t.size(); ++i) {
t(i) = triqs::utility::legendre_t(i,1) / gl.domain().beta; t(i) = triqs::utility::legendre_t(i,1) / gl.domain().beta;
norm += t(i)*t(i); norm += t(i)*t(i);
} }
tqa::array<double,2> corr(disc.shape()); corr() = 0; arrays::array<double,2> corr(disc.shape()); corr() = 0;
for (auto l : gl.mesh()) { for (auto l : gl.mesh()) {
corr += t(l.index()) * gl[l]; corr += t(l.index()) * gl[l];
} }
tqa::range R; arrays::range R;
for (auto l : gl.mesh()) { for (auto l : gl.mesh()) {
gl.data()(l.index(),R,R) += (disc - corr) * t(l.index()) / norm; gl.data()(l.index(),R,R) += (disc - corr) * t(l.index()) / norm;
} }

View File

@ -32,9 +32,9 @@ namespace triqs {
// For Imaginary Matsubara Frequency functions // For Imaginary Matsubara Frequency functions
// ------------------------------------------------------ // ------------------------------------------------------
tqa::matrix<double> density(gf_view<imfreq> const & g); arrays::matrix<double> density(gf_view<imfreq> const & g);
tqa::matrix<double> density(gf_view<legendre> const & g); arrays::matrix<double> density(gf_view<legendre> const & g);
local::tail_view get_tail(gf_const_view<legendre> gl, int size, int omin); local::tail_view get_tail(gf_const_view<legendre> gl, int size, int omin);
@ -43,7 +43,7 @@ namespace triqs {
// For anything that has the ImmutableGfMatsubaraFreq concept, create such a function and compute // For anything that has the ImmutableGfMatsubaraFreq concept, create such a function and compute
// Here I choose to create G and call the function to avoid creating one code for each expression... // Here I choose to create G and call the function to avoid creating one code for each expression...
//template<typename GfType> //template<typename GfType>
//TYPE_ENABLE_IF (tqa::matrix<double>, ImmutableGfMatsubaraFreq<GfType>) //TYPE_ENABLE_IF (arrays::matrix<double>, ImmutableGfMatsubaraFreq<GfType>)
//density( GfType const & G) { return density( gf_view<imfreq>(G));} //density( GfType const & G) { return density( gf_view<imfreq>(G));}
} }

View File

@ -18,86 +18,84 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_MESH_DISCRETE_H #pragma once
#define TRIQS_GF_MESH_DISCRETE_H
#include "./mesh_tools.hpp" #include "./mesh_tools.hpp"
#include "../domains/discrete.hpp" #include "../domains/discrete.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
template<typename Domain> template <typename Domain> struct discrete_mesh {
struct discrete_mesh {
typedef Domain domain_t; using domain_t = Domain;
typedef size_t index_t; using index_t = long;
discrete_mesh(domain_t dom) : _dom(std::move(dom)) {} discrete_mesh(domain_t dom) : _dom(std::move(dom)) {}
discrete_mesh() = default; discrete_mesh() = default;
domain_t const &domain() const { return _dom; } domain_t const &domain() const { return _dom; }
size_t size() const {return _dom.size();} long size() const { return _dom.size(); }
/// Conversions point <-> index <-> discrete_index /// Conversions point <-> index <-> discrete_index
size_t index_to_point (index_t ind) const {return ind;} long index_to_point(index_t ind) const { return ind; }
size_t index_to_linear(index_t ind) const {return ind;} long index_to_linear(index_t ind) const { return ind; }
/// The wrapper for the mesh point /// The wrapper for the mesh point
class mesh_point_t : tag::mesh_point,public utility::arithmetic_ops_by_cast<mesh_point_t, size_t> { class mesh_point_t : tag::mesh_point, public utility::arithmetic_ops_by_cast<mesh_point_t, long> {
discrete_mesh const * m; discrete_mesh const *m;
index_t _index; index_t _index;
public: public:
mesh_point_t() = default; mesh_point_t() = default;
mesh_point_t( discrete_mesh const & mesh, index_t const & index_): m(&mesh), _index(index_) {} mesh_point_t(discrete_mesh const &mesh, index_t const &index_) : m(&mesh), _index(index_) {}
void advance() { ++_index;} void advance() { ++_index; }
typedef size_t cast_t; using cast_t = long;
operator cast_t() const { return m->index_to_point(_index);} operator cast_t() const { return m->index_to_point(_index); }
size_t linear_index() const { return _index;} long linear_index() const { return _index; }
size_t index() const { return _index;} long index() const { return _index; }
bool at_end() const { return (_index == m->size());} bool at_end() const { return (_index == m->size()); }
void reset() {_index =0;} void reset() { _index = 0; }
};
/// Accessing a point of the mesh
mesh_point_t operator[](index_t i) const { return mesh_point_t (*this,i);}
mesh_point_t operator[](std::string const & s) const { return mesh_point_t (*this,_dom.index_from_name(s));}
/// Iterating on all the points...
typedef mesh_pt_generator<discrete_mesh> const_iterator;
const_iterator begin() const { return const_iterator (this);}
const_iterator end() const { return const_iterator (this, true);}
const_iterator cbegin() const { return const_iterator (this);}
const_iterator cend() const { return const_iterator (this, true);}
/// Mesh comparison
bool operator == (discrete_mesh const & M) const { return (_dom == M._dom) ;}
bool operator != (discrete_mesh const & M) const { return !(operator==(M)); }
/// Write into HDF5
friend void h5_write (h5::group fg, std::string subgroup_name, discrete_mesh const & m) {
h5::group gr = fg.create_group(subgroup_name);
h5_write(gr,"domain",m.domain());
}
/// Read from HDF5
friend void h5_read (h5::group fg, std::string subgroup_name, discrete_mesh & m){
h5::group gr = fg.open_group(subgroup_name);
typename discrete_mesh::domain_t dom;
h5_read(gr,"domain",dom);
m = discrete_mesh(std::move(dom));
}
// BOOST Serialization
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & boost::serialization::make_nvp("domain",_dom);
}
friend std::ostream &operator <<(std::ostream &sout, discrete_mesh const & m){return sout << "Discrete Mesh"; }
private:
domain_t _dom;
}; };
}}
#endif /// Accessing a point of the mesh
mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); }
mesh_point_t operator[](std::string const &s) const { return mesh_point_t(*this, _dom.index_from_name(s)); }
/// Iterating on all the points...
using const_iterator = mesh_pt_generator<discrete_mesh>;
const_iterator begin() const { return const_iterator(this); }
const_iterator end() const { return const_iterator(this, true); }
const_iterator cbegin() const { return const_iterator(this); }
const_iterator cend() const { return const_iterator(this, true); }
/// Mesh comparison
bool operator==(discrete_mesh const &M) const { return (_dom == M._dom); }
bool operator!=(discrete_mesh const &M) const { return !(operator==(M)); }
/// Write into HDF5
friend void h5_write(h5::group fg, std::string subgroup_name, discrete_mesh const &m) {
h5::group gr = fg.create_group(subgroup_name);
h5_write(gr, "domain", m.domain());
}
/// Read from HDF5
friend void h5_read(h5::group fg, std::string subgroup_name, discrete_mesh &m) {
h5::group gr = fg.open_group(subgroup_name);
typename discrete_mesh::domain_t dom;
h5_read(gr, "domain", dom);
m = discrete_mesh(std::move(dom));
}
// BOOST Serialization
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int version) {
ar &boost::serialization::make_nvp("domain", _dom);
}
friend std::ostream &operator<<(std::ostream &sout, discrete_mesh const &m) { return sout << "Discrete Mesh"; }
private:
domain_t _dom;
};
}
}

View File

@ -18,8 +18,7 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_MESH_LINEAR_H #pragma once
#define TRIQS_GF_MESH_LINEAR_H
#include "./mesh_tools.hpp" #include "./mesh_tools.hpp"
namespace triqs { namespace triqs {
namespace gfs { namespace gfs {
@ -31,15 +30,21 @@ namespace gfs {
without_last without_last
}; };
/**
* Linear mesh
*/
template <typename Domain> struct linear_mesh { template <typename Domain> struct linear_mesh {
typedef Domain domain_t; using domain_t = Domain;
typedef size_t index_t; using index_t = long;
typedef typename domain_t::point_t domain_pt_t; using domain_pt_t = typename domain_t::point_t;
static_assert(!std::is_base_of<std::complex<double>, domain_pt_t>::value,
"Internal error : can not use Linear Mesh in this case");
linear_mesh() : _dom(), L(0), a_pt(0), b_pt(0), xmin(0), xmax(0), del(0), meshk(half_bins) {} linear_mesh() : _dom(), L(0), a_pt(0), b_pt(0), xmin(0), xmax(0), del(0), meshk(half_bins) {}
explicit linear_mesh(domain_t dom, double a, double b, size_t n_pts, mesh_kind mk) explicit linear_mesh(domain_t dom, double a, double b, long n_pts, mesh_kind mk)
: _dom(std::move(dom)), L(n_pts), a_pt(a), b_pt(b), meshk(mk) { : _dom(std::move(dom)), L(n_pts), a_pt(a), b_pt(b), meshk(mk) {
switch (mk) { switch (mk) {
case half_bins: case half_bins:
@ -59,23 +64,17 @@ namespace gfs {
} }
domain_t const &domain() const { return _dom; } domain_t const &domain() const { return _dom; }
size_t size() const { return L; } long size() const { return L; }
double delta() const { return del; } double delta() const { return del; }
double x_max() const { return xmax; } double x_max() const { return xmax; }
double x_min() const { return xmin; } double x_min() const { return xmin; }
mesh_kind kind() const { return meshk; } mesh_kind kind() const { return meshk; }
/// Conversions point <-> index <-> linear_index /// Conversions point <-> index <-> linear_index
domain_pt_t index_to_point(index_t ind) const { domain_pt_t index_to_point(index_t ind) const { return xmin + ind * del; }
return embed(xmin + ind * del, std::integral_constant<bool, std::is_base_of<std::complex<double>, domain_pt_t>::value>());
}
private: // multiply by I is the type is a complex ....
domain_pt_t embed(double x, std::false_type) const { return x; }
domain_pt_t embed(double x, std::true_type) const { return std::complex<double>(0, x); }
public: public:
size_t index_to_linear(index_t ind) const { return ind; } long index_to_linear(index_t ind) const { return ind; }
/// The wrapper for the mesh point /// The wrapper for the mesh point
class mesh_point_t : tag::mesh_point, public utility::arithmetic_ops_by_cast<mesh_point_t, domain_pt_t> { class mesh_point_t : tag::mesh_point, public utility::arithmetic_ops_by_cast<mesh_point_t, domain_pt_t> {
@ -86,24 +85,22 @@ namespace gfs {
mesh_point_t() : m(nullptr) {} mesh_point_t() : m(nullptr) {}
mesh_point_t(linear_mesh const &mesh, index_t const &index_) : m(&mesh), _index(index_) {} mesh_point_t(linear_mesh const &mesh, index_t const &index_) : m(&mesh), _index(index_) {}
void advance() { ++_index; } void advance() { ++_index; }
typedef domain_pt_t cast_t; using cast_t = domain_pt_t;
operator cast_t() const { return m->index_to_point(_index); } operator cast_t() const { return m->index_to_point(_index); }
size_t linear_index() const { return _index; } long linear_index() const { return _index; }
size_t index() const { return _index; } long index() const { return _index; }
bool at_end() const { return (_index == m->size()); } bool at_end() const { return (_index == m->size()); }
void reset() { _index = 0; } void reset() { _index = 0; }
}; };
/// Accessing a point of the mesh /// Accessing a point of the mesh
mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); } mesh_point_t operator[](index_t i) const {
return {*this, i};
private: }
static double real_or_imag(domain_pt_t x, std::false_type) { return x; }
static double real_or_imag(domain_pt_t x, std::true_type) { return imag(x); }
public: public:
/// Iterating on all the points... /// Iterating on all the points...
typedef mesh_pt_generator<linear_mesh> const_iterator; using const_iterator = mesh_pt_generator<linear_mesh>;
const_iterator begin() const { return const_iterator(this); } const_iterator begin() const { return const_iterator(this); }
const_iterator end() const { return const_iterator(this, true); } const_iterator end() const { return const_iterator(this, true); }
const_iterator cbegin() const { return const_iterator(this); } const_iterator cbegin() const { return const_iterator(this); }
@ -142,7 +139,7 @@ namespace gfs {
h5::group gr = fg.open_group(subgroup_name); h5::group gr = fg.open_group(subgroup_name);
typename linear_mesh::domain_t dom; typename linear_mesh::domain_t dom;
double a, b; double a, b;
size_t L; long L;
int k; int k;
mesh_kind mk; mesh_kind mk;
h5_read(gr, "domain", dom); h5_read(gr, "domain", dom);
@ -181,17 +178,15 @@ namespace gfs {
private: private:
domain_t _dom; domain_t _dom;
size_t L; long L;
double a_pt, b_pt; double a_pt, b_pt, xmin, xmax, del;
double xmin, xmax;
double del;
mesh_kind meshk; mesh_kind meshk;
}; };
// UNUSED // UNUSED, only in deprecated code...
/// Simple approximation of a point of the domain by a mesh point. No check /// Simple approximation of a point of the domain by a mesh point. No check
template <typename D> size_t get_closest_mesh_pt_index(linear_mesh<D> const &mesh, typename D::point_t const &x) { template <typename D> long get_closest_mesh_pt_index(linear_mesh<D> const &mesh, typename D::point_t const &x) {
double a = (x - mesh.x_min()) / mesh.delta(); double a = (x - mesh.x_min()) / mesh.delta();
return std::floor(a); return std::floor(a);
} }
@ -212,5 +207,4 @@ namespace gfs {
} }
} }
} }
#endif

View File

@ -25,47 +25,75 @@
namespace triqs { namespace triqs {
namespace gfs { namespace gfs {
//----------------------------------- The mesh -----------------------------------------
struct matsubara_freq_mesh { struct matsubara_freq_mesh {
///
using domain_t = matsubara_domain<true>; using domain_t = matsubara_domain<true>;
using index_t = int; ///
using index_t = long;
///
using domain_pt_t = typename domain_t::point_t; using domain_pt_t = typename domain_t::point_t;
/// Constructor
matsubara_freq_mesh() : _dom(), n_max(0), _positive_only(true) {} matsubara_freq_mesh() : _dom(), n_max(0), _positive_only(true) {}
explicit matsubara_freq_mesh(domain_t dom, int n_pts, bool positive_only = true) /// Constructor
matsubara_freq_mesh(domain_t dom, int n_pts=1025, bool positive_only = true)
: _dom(std::move(dom)), n_max(n_pts), _positive_only(positive_only) {} : _dom(std::move(dom)), n_max(n_pts), _positive_only(positive_only) {}
/// Constructor
matsubara_freq_mesh(double beta, statistic_enum S, int Nmax = 1025, bool positive_only = true)
: matsubara_freq_mesh({beta, S}, Nmax, positive_only) {}
/// Copy constructor
matsubara_freq_mesh(matsubara_freq_mesh const &) = default;
/// The corresponding domain
domain_t const &domain() const { return _dom; } domain_t const &domain() const { return _dom; }
/** \brief First value of the index
*
* 0 if positive_only is true
* else :
* For fermions : -Nmax +1
* For Bosons : -Nmax
**/
int index_start() const { return -(_positive_only ? 0 : n_max + (_dom.statistic == Fermion)); } int index_start() const { return -(_positive_only ? 0 : n_max + (_dom.statistic == Fermion)); }
size_t size() const { return (_positive_only ? n_max : 2 * n_max + (_dom.statistic == Boson ? 1 : 2)); }
/// Conversions point <-> index <-> linear_index /// Size (linear) of the mesh
domain_pt_t index_to_point(index_t ind) const { long size() const { return (_positive_only ? n_max : 2 * n_max + (_dom.statistic == Boson ? 1 : 2)); }
return 1_j * M_PI * (2 * ind + (_dom.statistic == Fermion ? 1 : 0)) / _dom.beta;
}
public: /// From an index of a point in the mesh, returns the corresponding point in the domain
int index_to_linear(index_t ind) const { return ind + index_start(); } domain_pt_t index_to_point(index_t ind) const { return 1_j * M_PI * (2 * ind + _dom.statistic == Fermion) / _dom.beta; }
/// The mesh point /// Flatten the index in the positive linear index for memory storage (almost trivial here).
long index_to_linear(index_t ind) const { return ind + index_start(); }
/**
* The mesh point
*
* * NB : the mesh point is also in this case a matsubara_freq.
**/
struct mesh_point_t : tag::mesh_point, matsubara_freq { struct mesh_point_t : tag::mesh_point, matsubara_freq {
index_t index_start, index_stop;
mesh_point_t() = default; mesh_point_t() = default;
mesh_point_t(matsubara_freq_mesh const &mesh, index_t const &index_) mesh_point_t(matsubara_freq_mesh const &mesh, index_t const &index_)
: matsubara_freq(index_, mesh.domain().beta, mesh.domain().statistic), : matsubara_freq(index_, mesh.domain().beta, mesh.domain().statistic),
index_start(mesh.index_start()), index_start(mesh.index_start()),
index_stop(mesh.index_start() + mesh.size() - 1) {} index_stop(mesh.index_start() + mesh.size() - 1) {}
void advance() { ++n; } void advance() { ++n; }
size_t linear_index() const { return n; } long linear_index() const { return n; }
size_t index() const { return n; } long index() const { return n; }
bool at_end() const { return (n == index_stop); } bool at_end() const { return (n == index_stop); }
void reset() { n = index_start; } void reset() { n = index_start; }
private:
index_t index_start, index_stop;
}; };
/// Accessing a point of the mesh /// Accessing a point of the mesh from its index
mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); } mesh_point_t operator[](index_t i) const {
return {*this, i};
}
/// Iterating on all the points... /// Iterating on all the points...
using const_iterator = mesh_pt_generator<matsubara_freq_mesh>; using const_iterator = mesh_pt_generator<matsubara_freq_mesh>;
@ -74,7 +102,6 @@ namespace gfs {
const_iterator cbegin() const { return const_iterator(this); } const_iterator cbegin() const { return const_iterator(this); }
const_iterator cend() const { return const_iterator(this, true); } const_iterator cend() const { return const_iterator(this, true); }
/// Mesh comparison
bool operator==(matsubara_freq_mesh const &M) const { bool operator==(matsubara_freq_mesh const &M) const {
return (std::make_tuple(_dom, n_max, _positive_only, n_max) == std::make_tuple(M._dom, M.n_max, M._positive_only, n_max)); return (std::make_tuple(_dom, n_max, _positive_only, n_max) == std::make_tuple(M._dom, M.n_max, M._positive_only, n_max));
} }
@ -86,8 +113,7 @@ namespace gfs {
h5_write(gr, "domain", m.domain()); h5_write(gr, "domain", m.domain());
h5_write(gr, "size", m.size()); h5_write(gr, "size", m.size());
if (m._positive_only) { if (m._positive_only) {
// h5_write(gr, "start_at_0", m._positive_only); // kept ONLY for backward compatibility of archives
// kept for backward compatibility
auto beta = m.domain().beta; auto beta = m.domain().beta;
h5_write(gr, "min", Fermion ? M_PI / beta : 0); h5_write(gr, "min", Fermion ? M_PI / beta : 0);
h5_write(gr, "max", ((Fermion ? 1 : 0) + 2 * m.size()) * M_PI / beta); h5_write(gr, "max", ((Fermion ? 1 : 0) + 2 * m.size()) * M_PI / beta);
@ -109,14 +135,15 @@ namespace gfs {
m = matsubara_freq_mesh{std::move(dom), L, s}; m = matsubara_freq_mesh{std::move(dom), L, s};
} }
// BOOST Serialization
friend class boost::serialization::access; friend class boost::serialization::access;
/// BOOST Serialization
template <class Archive> void serialize(Archive &ar, const unsigned int version) { template <class Archive> void serialize(Archive &ar, const unsigned int version) {
ar &boost::serialization::make_nvp("domain", _dom); ar &boost::serialization::make_nvp("domain", _dom);
ar &boost::serialization::make_nvp("size", n_max); ar &boost::serialization::make_nvp("size", n_max);
ar &boost::serialization::make_nvp("kind", _positive_only); ar &boost::serialization::make_nvp("kind", _positive_only);
} }
/// Simple print (just blabla and the size)
friend std::ostream &operator<<(std::ostream &sout, matsubara_freq_mesh const &m) { friend std::ostream &operator<<(std::ostream &sout, matsubara_freq_mesh const &m) {
return sout << "Matsubara Freq Mesh of size " << m.size(); return sout << "Matsubara Freq Mesh of size " << m.size();
} }
@ -126,6 +153,19 @@ namespace gfs {
int n_max; int n_max;
bool _positive_only; bool _positive_only;
}; };
//-------------------------------------------------------
/** \brief foreach for this mesh
*
* @param m : a mesh
* @param F : a function of synopsis auto F (matsubara_freq_mesh::mesh_point_t)
*
* Calls F on each point of the mesh, in arbitrary order.
**/
template <typename Lambda> void foreach(matsubara_freq_mesh const &m, Lambda F) {
for (auto const &w : m) F(w);
}
} }
} }

View File

@ -0,0 +1,56 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2013 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once
#include "./mesh_tools.hpp"
#include "../domains/matsubara.hpp"
#include "./linear.hpp"
namespace triqs {
namespace gfs {
struct matsubara_time_mesh : linear_mesh<matsubara_time_domain> {
private:
using B = linear_mesh<matsubara_time_domain>;
public:
matsubara_time_mesh() = default;
matsubara_time_mesh(matsubara_time_mesh const &x) = default;
matsubara_time_mesh(matsubara_time_domain d, int n_time_slices, mesh_kind mk = half_bins) : B(d, 0, d.beta, n_time_slices, mk) {}
matsubara_time_mesh(double beta, statistic_enum S, int n_time_slices, mesh_kind mk = half_bins)
: matsubara_time_mesh({beta, S}, n_time_slices, mk) {}
};
//-------------------------------------------------------
/** \brief foreach for this mesh
*
* @param m : a mesh
* @param F : a function of synopsis auto F (matsubara_time_mesh::mesh_point_t)
*
* Calls F on each point of the mesh, in arbitrary order.
**/
template <typename Lambda> void foreach(matsubara_time_mesh const &m, Lambda F) {
for (auto const &w : m) F(w);
}
}
}

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2012 by M. Ferrero, O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -18,170 +18,254 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_MESH_PRODUCT_H #pragma once
#define TRIQS_GF_MESH_PRODUCT_H
#include "./mesh_tools.hpp" #include "./mesh_tools.hpp"
#include "../domains/product.hpp" #include "../domains/product.hpp"
#include <triqs/utility/tuple_tools.hpp> #include <triqs/utility/tuple_tools.hpp>
#include <triqs/utility/mini_vector.hpp> #include <triqs/utility/mini_vector.hpp>
#include <triqs/utility/c14.hpp> #include <triqs/utility/c14.hpp>
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
template<typename... Meshes> struct mesh_product : tag::composite { /** Cartesian product of meshes
typedef domain_product<typename Meshes::domain_t ... > domain_t; */
typedef std::c14::tuple<typename Meshes::index_t ... > index_t; template <typename... Meshes> struct mesh_product : tag::composite {
typedef std::tuple<Meshes...> m_tuple_t; using domain_t = domain_product<typename Meshes::domain_t...>;
typedef std::tuple<typename Meshes::mesh_point_t ...> m_pt_tuple_t; using index_t = std::c14::tuple<typename Meshes::index_t...>;
typedef typename domain_t::point_t domain_pt_t; using m_tuple_t = std::tuple<Meshes...>;
using m_pt_tuple_t = std::tuple<typename Meshes::mesh_point_t...>;
using domain_pt_t = typename domain_t::point_t;
static constexpr int dim = sizeof...(Meshes); static constexpr int dim = sizeof...(Meshes);
mesh_product () {} mesh_product() {}
mesh_product (Meshes const & ... meshes) : m_tuple(meshes...), _dom(meshes.domain()...) {} mesh_product(Meshes const &... meshes) : m_tuple(meshes...), _dom(meshes.domain()...) {}
domain_t const & domain() const { return _dom;} domain_t const &domain() const { return _dom; }
m_tuple_t const & components() const { return m_tuple;} m_tuple_t const &components() const { return m_tuple; }
m_tuple_t & components() { return m_tuple;} m_tuple_t &components() { return m_tuple; }
/// size of the mesh is the product of size
struct _aux0 { template<typename M> size_t operator()(M const & m, size_t R) { return R*m.size();}};
size_t size() const { return triqs::tuple::fold(_aux0(), m_tuple, 1);}
/// Conversions point <-> index <-> linear_index
struct _aux1 { template<typename P, typename M, typename I> void operator()(P & p, M const & m, I const& i) {p = m.index_to_point(i);}};
typename domain_t::point_t index_to_point(index_t const & ind) const { domain_pt_t res; triqs::tuple::apply_on_zip(_aux1(), res,m_tuple,ind); return res;}
// index[0] + component[0].size * (index[1] + component[1].size* (index[2] + ....))
struct _aux2 { template<typename I, typename M> size_t operator()(M const & m, I const & i,size_t R) {return m.index_to_linear(i) + R * m.size();}};
size_t index_to_linear(index_t const & ii) const { return triqs::tuple::fold_on_zip(_aux2(), reverse(m_tuple), reverse(ii), size_t(0)); }
// size_t index_to_linear(index_t const & ii) const { return triqs::tuple::fold_on_zip([](auto const &m, auto const &i, auto R){return m.index_to_linear(i) + R * m.size();} , m_tuple, ii, size_t(0)); }
// Same but a tuple of mesh_point_t
struct _aux3 { template<typename P, typename M> size_t operator()(M const & m, P const & p,size_t R) {return p.linear_index() + R * m.size();}};
size_t mp_to_linear(m_pt_tuple_t const & mp) const { return triqs::tuple::fold_on_zip(_aux3(), reverse(m_tuple), reverse(mp), size_t(0)); }
//
struct _aux4 { template< typename M, typename V> V * operator()(M const & m, V * v) {*v = m.size(); return ++v;}};
utility::mini_vector<size_t,dim> all_size_as_mini_vector () const {
utility::mini_vector<size_t,dim> res;
triqs::tuple::fold(_aux4(), m_tuple, &res[0] );
return res;
}
// Same but a variadic list of mesh_point_t
template<typename ... MP> size_t mesh_pt_components_to_linear(MP const & ... mp) const {
static_assert(std::is_same< std::tuple<MP...>, m_pt_tuple_t>::value, "Call incorrect ");
//static_assert(std::is_same< std::tuple<typename std::remove_cv<typename std::remove_reference<MP>::type>::type...>, m_pt_tuple_t>::value, "Call incorrect ");
return mp_to_linear(std::forward_as_tuple(mp...));
} // speed test ? or make a variadic fold...
/// The wrapper for the mesh point
class mesh_point_t : tag::mesh_point{
const mesh_product * m;
m_pt_tuple_t _c; bool _atend;
struct F2 { template<typename M> typename M::mesh_point_t operator()(M const & m, typename M::index_t const & i) const { return m[i];}};
struct F1 { template<typename M> typename M::mesh_point_t operator()(M const & m) const { return m[typename M::index_t()];}};
public :
mesh_point_t() = default;
mesh_point_t(mesh_product const & m_, index_t index_ ) : m(&m_), _c (triqs::tuple::apply_on_zip(F2(), m_.m_tuple, index_)), _atend(false) {}
mesh_point_t(mesh_product const & m_) : m(&m_), _c (triqs::tuple::apply(F1(), m_.m_tuple)), _atend(false) {}
m_pt_tuple_t const & components_tuple() const { return _c;}
size_t linear_index() const { return m->mp_to_linear(_c);}
const mesh_product * mesh() const { return m;}
typedef domain_pt_t cast_t;
operator cast_t() const { return m->index_to_point(index);}
// index[0] +=1; if index[0]==m.component[0].size() { index[0]=0; index[1] +=1; if ....} and so on until dim
struct _aux1 { template<typename P> bool operator()(P & p, bool done)
{if (done) return true; p.advance(); if (p.at_end()) {p.reset(); return false;} return true;}
};
void advance() { triqs::tuple::fold(_aux1(), _c, false);}
//index_t index() const { return _index;} // not implemented yet
bool at_end() const { return _atend;}
struct _aux{ template<typename M> size_t operator()(M & m,size_t ) { m.reset(); return 0;}};
void reset() { _atend = false; triqs::tuple::fold(_aux(), _c,0);}
};// end mesh_point_t
/// Accessing a point of the mesh
mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i);}
mesh_point_t operator()(typename Meshes::index_t ... i) const { return (*this)[std::make_tuple(i...)];}
/// Iterating on all the points...
typedef mesh_pt_generator<mesh_product> const_iterator;
const_iterator begin() const { return const_iterator (this);}
const_iterator end() const { return const_iterator (this, true);}
const_iterator cbegin() const { return const_iterator (this);}
const_iterator cend() const { return const_iterator (this, true);}
/// Mesh comparison
friend bool operator == (mesh_product const & M1, mesh_product const & M2) { return M1.m_tuple==M2.m_tuple; }
/// Write into HDF5
struct _auxh5w {
h5::group gr; _auxh5w( h5::group gr_) : gr(gr_) {} //icc has yet another bug on new initialization form with {}...
template<typename M> size_t operator()(M const & m, size_t N) { std::stringstream fs;fs <<"MeshComponent"<< N; h5_write(gr,fs.str(), m); return N+1; }
};
friend void h5_write (h5::group fg, std::string subgroup_name, mesh_product const & m) {
h5::group gr = fg.create_group(subgroup_name);
//h5_write(gr,"domain",m.domain());
triqs::tuple::fold(_auxh5w(gr), m.components(), size_t(0));
}
/// Read from HDF5
struct _auxh5r {
h5::group gr;_auxh5r( h5::group gr_) : gr(gr_) {}
template<typename M> size_t operator()(M & m, size_t N) { std::stringstream fs;fs <<"MeshComponent"<< N; h5_read(gr,fs.str(), m); return N+1; }
};
friend void h5_read (h5::group fg, std::string subgroup_name, mesh_product & m){
h5::group gr = fg.open_group(subgroup_name);
//h5_read(gr,"domain",m._dom);
triqs::tuple::fold(_auxh5r(gr), m.components(), size_t(0));
}
// BOOST Serialization
friend class boost::serialization::access;
template<typename Archive> struct _aux_ser {
Archive & ar;_aux_ser( Archive & ar_) : ar(ar_) {}
template<typename M> size_t operator()(M & m, size_t N) {
std::stringstream fs;fs <<"MeshComponent"<< N;
ar & boost::serialization::make_nvp(fs.str().c_str(),m);
return N+1;
}
};
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
triqs::tuple::fold(_aux_ser<Archive>(ar), m_tuple, size_t(0));
}
friend std::ostream &operator <<(std::ostream &sout, mesh_product const & m){return sout << "Product Mesh"; }
private: private:
m_tuple_t m_tuple; struct _aux0 {
domain_t _dom; template <typename M> size_t operator()(M const &m, size_t R) { return R * m.size(); }
};
public:
/// size of the mesh is the product of size
size_t size() const { return triqs::tuple::fold(_aux0(), m_tuple, 1); }
private:
struct _aux1 {
template <typename P, typename M, typename I> void operator()(P &p, M const &m, I const &i) { p = m.index_to_point(i); }
};
public:
/// Conversions point <-> index <-> linear_index
typename domain_t::point_t index_to_point(index_t const &ind) const {
domain_pt_t res;
triqs::tuple::apply_on_zip(_aux1(), res, m_tuple, ind);
return res;
}
private:
struct _aux2 {
template <typename I, typename M> size_t operator()(M const &m, I const &i, size_t R) {
return m.index_to_linear(i) + R * m.size();
}
};
public:
/// Flattening index to linear : index[0] + component[0].size * (index[1] + component[1].size* (index[2] + ....))
size_t index_to_linear(index_t const &ii) const {
return triqs::tuple::fold_on_zip(_aux2(), reverse(m_tuple), reverse(ii), size_t(0));
}
// size_t index_to_linear(index_t const & ii) const { return triqs::tuple::fold_on_zip([](auto const &m, auto const &i, auto R)
//{return m.index_to_linear(i) + R * m.size();} , m_tuple, ii, size_t(0)); }
private:
struct _aux3 {
template <typename P, typename M> size_t operator()(M const &m, P const &p, size_t R) {
return p.linear_index() + R * m.size();
}
};
public:
/// Flattening index to linear : index[0] + component[0].size * (index[1] + component[1].size* (index[2] + ....))
size_t mp_to_linear(m_pt_tuple_t const &mp) const {
return triqs::tuple::fold_on_zip(_aux3(), reverse(m_tuple), reverse(mp), size_t(0));
}
//
private:
struct _aux4 {
template <typename M, typename V> V *operator()(M const &m, V *v) {
*v = m.size();
return ++v;
}
};
public:
utility::mini_vector<size_t, dim> all_size_as_mini_vector() const {
utility::mini_vector<size_t, dim> res;
triqs::tuple::fold(_aux4(), m_tuple, &res[0]);
return res;
}
// Same but a variadic list of mesh_point_t
template <typename... MP> size_t mesh_pt_components_to_linear(MP const &... mp) const {
static_assert(std::is_same<std::tuple<MP...>, m_pt_tuple_t>::value, "Call incorrect ");
// static_assert(std::is_same< std::tuple<typename std::remove_cv<typename std::remove_reference<MP>::type>::type...>,
// m_pt_tuple_t>::value, "Call incorrect ");
return mp_to_linear(std::forward_as_tuple(mp...));
} // speed test ? or make a variadic fold...
/// The wrapper for the mesh point
class mesh_point_t : tag::mesh_point {
const mesh_product *m;
m_pt_tuple_t _c;
bool _atend;
struct F2 {
template <typename M> typename M::mesh_point_t operator()(M const &m, typename M::index_t const &i) const { return m[i]; }
};
struct F1 {
template <typename M> typename M::mesh_point_t operator()(M const &m) const { return m[typename M::index_t()]; }
};
public:
mesh_point_t() = default;
mesh_point_t(mesh_product const &m_, index_t index_)
: m(&m_), _c(triqs::tuple::apply_on_zip(F2(), m_.m_tuple, index_)), _atend(false) {}
mesh_point_t(mesh_product const &m_) : m(&m_), _c(triqs::tuple::apply(F1(), m_.m_tuple)), _atend(false) {}
m_pt_tuple_t const &components_tuple() const { return _c; }
size_t linear_index() const { return m->mp_to_linear(_c); }
const mesh_product *mesh() const { return m; }
using cast_t = domain_pt_t;
operator cast_t() const { return m->index_to_point(index); }
// index[0] +=1; if index[0]==m.component[0].size() { index[0]=0; index[1] +=1; if ....} and so on until dim
private:
struct _aux1 {
template <typename P> bool operator()(P &p, bool done) {
if (done) return true;
p.advance();
if (!p.at_end()) return true;
p.reset();
return false;
}
};
public:
void advance() { triqs::tuple::fold(_aux1(), _c, false); }
// index_t index() const { return _index;} // not implemented yet
bool at_end() const { return _atend; }
private:
struct _aux {
template <typename M> size_t operator()(M &m, size_t) {
m.reset();
return 0;
}
};
public:
void reset() {
_atend = false;
triqs::tuple::fold(_aux(), _c, 0);
}
}; // end mesh_point_t
/// Accessing a point of the mesh
mesh_point_t operator[](index_t i) const { return mesh_point_t(*this, i); }
mesh_point_t operator()(typename Meshes::index_t... i) const { return (*this)[std::make_tuple(i...)]; }
/// Iterating on all the points...
using const_iterator = mesh_pt_generator<mesh_product>;
const_iterator begin() const { return const_iterator(this); }
const_iterator end() const { return const_iterator(this, true); }
const_iterator cbegin() const { return const_iterator(this); }
const_iterator cend() const { return const_iterator(this, true); }
/// Mesh comparison
friend bool operator==(mesh_product const &M1, mesh_product const &M2) { return M1.m_tuple == M2.m_tuple; }
private:
/// Write into HDF5
struct _auxh5w {
h5::group gr;
_auxh5w(h5::group gr_) : gr(gr_) {} // icc has yet another bug on new initialization form with {}...
template <typename M> size_t operator()(M const &m, size_t N) {
std::stringstream fs;
fs << "MeshComponent" << N;
h5_write(gr, fs.str(), m);
return N + 1;
}
};
friend void h5_write(h5::group fg, std::string subgroup_name, mesh_product const &m) {
h5::group gr = fg.create_group(subgroup_name);
// h5_write(gr,"domain",m.domain());
triqs::tuple::fold(_auxh5w(gr), m.components(), size_t(0));
}
/// Read from HDF5
struct _auxh5r {
h5::group gr;
_auxh5r(h5::group gr_) : gr(gr_) {}
template <typename M> size_t operator()(M &m, size_t N) {
std::stringstream fs;
fs << "MeshComponent" << N;
h5_read(gr, fs.str(), m);
return N + 1;
}
};
friend void h5_read(h5::group fg, std::string subgroup_name, mesh_product &m) {
h5::group gr = fg.open_group(subgroup_name);
// h5_read(gr,"domain",m._dom);
triqs::tuple::fold(_auxh5r(gr), m.components(), size_t(0));
}
// BOOST Serialization
friend class boost::serialization::access;
template <typename Archive> struct _aux_ser {
Archive &ar;
_aux_ser(Archive &ar_) : ar(ar_) {}
template <typename M> size_t operator()(M &m, size_t N) {
std::stringstream fs;
fs << "MeshComponent" << N;
ar &boost::serialization::make_nvp(fs.str().c_str(), m);
return N + 1;
}
};
template <class Archive> void serialize(Archive &ar, const unsigned int version) {
triqs::tuple::fold(_aux_ser<Archive>(ar), m_tuple, size_t(0));
}
friend std::ostream &operator<<(std::ostream &sout, mesh_product const &m) { return sout << "Product Mesh"; }
private:
m_tuple_t m_tuple;
domain_t _dom;
}; };
template<int pos, typename P> template <int pos, typename P> auto get_index(P const &p) DECL_AND_RETURN(std::get<pos>(p.components_tuple()).index());
auto get_index(P const & p) DECL_AND_RETURN( std::get<pos>(p.components_tuple()).index());
template <int pos, typename P>
auto get_point(P const &p)
DECL_AND_RETURN(std::get<pos>(p.mesh() -> components()).index_to_point(std::get<pos>(p.components_tuple()).index()));
template <int pos, typename P> auto get_component(P const &p) DECL_AND_RETURN(std::get<pos>(p.components_tuple()));
template<int pos, typename P>
auto get_point(P const & p) DECL_AND_RETURN( std::get<pos>( p.mesh()->components() ).index_to_point( std::get<pos>(p.components_tuple()).index() ) );
template<int pos, typename P>
auto get_component(P const & p) DECL_AND_RETURN( std::get<pos>(p.components_tuple()));
// Given a composite mesh m , and a linear array of storage A // Given a composite mesh m , and a linear array of storage A
// reinterpret_linear_array(m,A) returns a d-dimensionnal view of the array // reinterpret_linear_array(m,A) returns a d-dimensionnal view of the array
// with indices egal to the indices of the components of the mesh. // with indices egal to the indices of the components of the mesh.
// Very useful for slicing, currying functions. // Very useful for slicing, currying functions.
template<typename ... Meshes, typename T, ull_t OptionsFlags, ull_t To, int R , bool B, bool C> template <typename... Meshes, typename T, ull_t OptionsFlags, ull_t To, int R, bool B, bool C>
arrays::array_view<T, sizeof...(Meshes)+ R-1,OptionsFlags,To,true,C> arrays::array_view<T, sizeof...(Meshes) + R - 1, OptionsFlags, To, true, C>
reinterpret_linear_array(mesh_product<Meshes...> const & m, arrays::array_view<T,R,OptionsFlags,To,B,C> A) { reinterpret_linear_array(mesh_product<Meshes...> const &m, arrays::array_view<T, R, OptionsFlags, To, B, C> A) {
return { {join (m.all_size_as_mini_vector(), get_shape(A).front_pop())}, A.storage()}; return {{join(m.all_size_as_mini_vector(), get_shape(A).front_pop())}, A.storage()};
} }
}
}} }
#endif

View File

@ -0,0 +1,49 @@
/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2013 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once
#include "./mesh_tools.hpp"
#include "./linear.hpp"
namespace triqs {
namespace gfs {
/** A linear mesh on a segment on R */
struct segment_mesh : linear_mesh<R_domain> {
using B = linear_mesh<R_domain>;
segment_mesh() = default;
segment_mesh(double x_min, double x_max, int n_freq, mesh_kind mk = full_bins) : B(typename B::domain_t(), x_min, x_max, n_freq, mk) {}
};
//-------------------------------------------------------
/** \brief foreach for this mesh
*
* @param m : a mesh
* @param F : a function of synopsis auto F (matsubara_time_mesh::mesh_point_t)
*
* Calls F on each point of the mesh, in arbitrary order.
**/
template <typename Lambda> void foreach(segment_mesh const &m, Lambda F) {
for (auto const &w : m) F(w);
}
}
}

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2013 by O. Parcollet * Copyright (C) 2013 by O. Parcollet
@ -18,86 +18,86 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_PRODUCT_H #pragma once
#define TRIQS_GF_PRODUCT_H
#include "./tools.hpp" #include "./tools.hpp"
#include "./gf.hpp" #include "./gf.hpp"
#include "./meshes/product.hpp" #include "./meshes/product.hpp"
#include "./evaluators.hpp" #include "./evaluators.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
template<typename ... Ms> struct cartesian_product{ template <typename... Ms> struct cartesian_product {
typedef std::tuple<Ms...> type; using type = std::tuple<Ms...>;
static constexpr size_t size = sizeof...(Ms); static constexpr size_t size = sizeof...(Ms);
}; };
// use alias // use alias
template<typename ... Ms> struct cartesian_product <std::tuple<Ms...>> : cartesian_product<Ms...>{}; template <typename... Ms> struct cartesian_product<std::tuple<Ms...>> : cartesian_product<Ms...> {};
// the mesh is simply a cartesian product // the mesh is simply a cartesian product
template<typename Opt, typename ... Ms> struct gf_mesh<cartesian_product<Ms...>,Opt> : mesh_product< gf_mesh<Ms,Opt> ... > { template <typename Opt, typename... Ms> struct gf_mesh<cartesian_product<Ms...>, Opt> : mesh_product<gf_mesh<Ms, Opt>...> {
typedef mesh_product< gf_mesh<Ms,Opt> ... > B; // using mesh_product< gf_mesh<Ms,Opt> ... >::mesh_product< gf_mesh<Ms,Opt> ... > ;
typedef std::tuple<Ms...> mesh_name_t; using B = mesh_product<gf_mesh<Ms, Opt>...>;
gf_mesh() = default; gf_mesh() = default;
gf_mesh (gf_mesh<Ms,Opt> ... ms) : B {std::move(ms)...} {} gf_mesh(gf_mesh<Ms, Opt>... ms) : B{std::move(ms)...} {}
}; };
namespace gfs_implementation { namespace gfs_implementation {
/// --------------------------- hdf5 --------------------------------- /// --------------------------- hdf5 ---------------------------------
// h5 name : name1_x_name2_..... // h5 name : name1_x_name2_.....
template<typename Opt, typename ... Ms> struct h5_name<cartesian_product<Ms...>,matrix_valued,Opt> { template <typename Opt, typename... Ms> struct h5_name<cartesian_product<Ms...>, matrix_valued, Opt> {
static std::string invoke(){ static std::string invoke() {
return triqs::tuple::fold( return triqs::tuple::fold([](std::string a, std::string b) { return a + std::string(b.empty() ? "" : "_x_") + b; },
[](std::string a, std::string b) { return a + std::string(b.empty()?"" : "_x_") + b;}, std::make_tuple(h5_name<Ms, matrix_valued, Opt>::invoke()...), std::string());
std::make_tuple(h5_name<Ms,matrix_valued,Opt>::invoke()...),
std::string());
} }
}; };
template<typename Opt, int R, typename ... Ms> struct h5_name<cartesian_product<Ms...>,tensor_valued<R>,Opt> : h5_name<cartesian_product<Ms...>,matrix_valued,Opt> {}; template <typename Opt, int R, typename... Ms>
struct h5_name<cartesian_product<Ms...>, tensor_valued<R>, Opt> : h5_name<cartesian_product<Ms...>, matrix_valued, Opt> {};
// a slight difference with the generic case : reinterpret the data array to avoid flattening the variables // a slight difference with the generic case : reinterpret the data array to avoid flattening the variables
template <typename Opt, int R, typename ... Ms> template <typename Opt, int R, typename... Ms> struct h5_rw<cartesian_product<Ms...>, tensor_valued<R>, Opt> {
struct h5_rw<cartesian_product<Ms...>,tensor_valued<R>,Opt> { using g_t = gf<cartesian_product<Ms...>, tensor_valued<R>, Opt>;
typedef gf<cartesian_product<Ms...>,tensor_valued<R>,Opt> g_t;
static void write (h5::group gr, typename g_t::const_view_type g) { static void write(h5::group gr, typename g_t::const_view_type g) {
h5_write(gr,"data",reinterpret_linear_array(g.mesh(), g().data())); h5_write(gr, "data", reinterpret_linear_array(g.mesh(), g().data()));
h5_write(gr,"singularity",g._singularity); h5_write(gr, "singularity", g._singularity);
h5_write(gr,"mesh",g._mesh); h5_write(gr, "mesh", g._mesh);
h5_write(gr,"symmetry",g._symmetry); h5_write(gr, "symmetry", g._symmetry);
} }
template<bool IsView> template <bool IsView>
static void read (h5::group gr, gf_impl<cartesian_product<Ms...>,tensor_valued<R>,Opt,IsView,false> & g) { static void read(h5::group gr, gf_impl<cartesian_product<Ms...>, tensor_valued<R>, Opt, IsView, false> &g) {
using G_t= gf_impl<cartesian_product<Ms...>,tensor_valued<R>,Opt,IsView,false> ; using G_t = gf_impl<cartesian_product<Ms...>, tensor_valued<R>, Opt, IsView, false>;
h5_read(gr,"mesh",g._mesh); h5_read(gr, "mesh", g._mesh);
auto arr = arrays::array<typename G_t::data_t::value_type, sizeof...(Ms)+ R>{}; auto arr = arrays::array<typename G_t::data_t::value_type, sizeof...(Ms) + R>{};
h5_read(gr,"data",arr); h5_read(gr, "data", arr);
auto sh = arr.shape(); auto sh = arr.shape();
arrays::mini_vector<size_t,R+1> sh2; arrays::mini_vector<size_t, R + 1> sh2;
sh2[0] = g._mesh.size(); sh2[0] = g._mesh.size();
for (int u=1; u<R+1; ++u) sh2[u] = sh[sizeof...(Ms)-1+u]; for (int u = 1; u < R + 1; ++u) sh2[u] = sh[sizeof...(Ms) - 1 + u];
g._data = arrays::array<typename G_t::data_t::value_type, R+1>{sh2, std::move(arr.storage())}; g._data = arrays::array<typename G_t::data_t::value_type, R + 1>{sh2, std::move(arr.storage())};
h5_read(gr,"singularity",g._singularity); h5_read(gr, "singularity", g._singularity);
h5_read(gr,"symmetry",g._symmetry); h5_read(gr, "symmetry", g._symmetry);
} }
};
};
/// --------------------------- data access --------------------------------- /// --------------------------- data access ---------------------------------
template<typename Opt, typename ... Ms> struct data_proxy<cartesian_product<Ms...>,scalar_valued,Opt> : data_proxy_array<std::complex<double>,1> {}; template <typename Opt, typename... Ms>
template<typename Opt, typename ... Ms> struct data_proxy<cartesian_product<Ms...>,matrix_valued,Opt> : data_proxy_array<std::complex<double>,3> {}; struct data_proxy<cartesian_product<Ms...>, scalar_valued, Opt> : data_proxy_array<std::complex<double>, 1> {};
template<int R, typename Opt, typename ... Ms> struct data_proxy<cartesian_product<Ms...>,tensor_valued<R>,Opt> : data_proxy_array<std::complex<double>,R+1> {}; template <typename Opt, typename... Ms>
struct data_proxy<cartesian_product<Ms...>, matrix_valued, Opt> : data_proxy_array<std::complex<double>, 3> {};
template <int R, typename Opt, typename... Ms>
struct data_proxy<cartesian_product<Ms...>, tensor_valued<R>, Opt> : data_proxy_array<std::complex<double>, R + 1> {};
/// --------------------------- evaluator --------------------------------- /// --------------------------- evaluator ---------------------------------
/** /**
* This the multi-dimensional evaluator. * This the multi-dimensional evaluator.
* It combine the evaluator of each components, as long as they are a linear form * It combine the evaluator of each components, as long as they are a linear form
* eval(g, x) = \sum_i w_i g( n_i(x)) , with w some weight and n_i some points on the grid. * eval(g, x) = \sum_i w_i g( n_i(x)) , with w some weight and n_i some points on the grid.
* Mathematically, it is written as (example of evaluating g(x1,x2,x3,x4)). * Mathematically, it is written as (example of evaluating g(x1,x2,x3,x4)).
* Notation : eval(X) : g -> g(X) * Notation : eval(X) : g -> g(X)
@ -110,54 +110,63 @@ namespace triqs { namespace gfs {
* p_i are points on the grids, x_i points in the domain. * p_i are points on the grids, x_i points in the domain.
* *
* Unrolling the formula gives (for 2 variables, with 2 points interpolation) * Unrolling the formula gives (for 2 variables, with 2 points interpolation)
* eval(xa,xb) (g) = eval (xa) ( binder ( g, (), (xb)) ) = w_1(xa) binder ( g, (), (xb))( n_1(xa)) + w_2(xa) binder ( g, (), (xb))( n_2(xa)) * eval(xa,xb) (g) = eval (xa) ( binder ( g, (), (xb)) ) =
* = w_1(xa) ( eval(xb)( binder ( g, (n_1(xa) ), ()))) + 1 <-> 2 * w_1(xa) binder ( g, (), (xb))( n_1(xa)) + w_2(xa) binder ( g, (), (xb))( n_2(xa))
* = w_1(xa) ( W_1(xb) * binder ( g, (n_1(xa) ), ())(N_1(xb)) + 1<->2 ) + 1 <-> 2 * = w_1(xa) ( eval(xb)( binder ( g, (n_1(xa) ), ()))) + 1 <-> 2
* = w_1(xa) ( W_1(xb) * g[n_1(xa), N_1(xb)] + 1<->2 ) + 1 <-> 2 * = w_1(xa) ( W_1(xb) * binder ( g, (n_1(xa) ), ())(N_1(xb)) + 1<->2 ) + 1 <-> 2
* = w_1(xa) ( W_1(xb) * g[n_1(xa), N_1(xb)] + W_2(xb) * g[n_1(xa), N_2(xb)] ) + 1 <-> 2 * = w_1(xa) ( W_1(xb) * g[n_1(xa), N_1(xb)] + 1<->2 ) + 1 <-> 2
* = w_1(xa) ( W_1(xb) * g[n_1(xa), N_1(xb)] + W_2(xb) * g[n_1(xa), N_2(xb)] ) + 1 <-> 2
* which is the expected formula * which is the expected formula
*/ */
// implementation : G = gf, Tn : tuple of n points, Ev : tuple of evaluators (the evals functions), pos = counter from #args-1 =>0 // implementation : G = gf, Tn : tuple of n points, Ev : tuple of evaluators (the evals functions),
// pos = counter from #args-1 =>0
// NB : the tuple is build in reverse with respect to the previous comment. // NB : the tuple is build in reverse with respect to the previous comment.
template<typename G, typename Tn, typename Ev, int pos> struct binder; template <typename G, typename Tn, typename Ev, int pos> struct binder;
template<int pos, typename G, typename Tn, typename Ev> template <int pos, typename G, typename Tn, typename Ev> binder<G, Tn, Ev, pos> make_binder(G const *g, Tn tn, Ev const &ev) {
binder<G,Tn,Ev,pos> make_binder(G const * g, Tn tn, Ev const & ev) { return binder<G,Tn,Ev,pos>{g, std::move(tn), ev}; } return binder<G, Tn, Ev, pos>{g, std::move(tn), ev};
}
template<typename G, typename Tn, typename Ev, int pos> struct binder { template <typename G, typename Tn, typename Ev, int pos> struct binder {
G const * g; Tn tn; Ev const & evals; G const *g;
auto operator()(size_t p) const DECL_AND_RETURN( std::get<pos>(evals) ( make_binder<pos-1>(g, triqs::tuple::push_front(tn,p), evals) )); Tn tn;
Ev const &evals;
auto operator()(size_t p) const
DECL_AND_RETURN(std::get<pos>(evals)(make_binder<pos - 1>(g, triqs::tuple::push_front(tn, p), evals)));
}; };
template<typename G, typename Tn, typename Ev> struct binder<G,Tn,Ev,-1> { template <typename G, typename Tn, typename Ev> struct binder<G, Tn, Ev, -1> {
G const * g; Tn tn; Ev const & evals; G const *g;
auto operator()(size_t p) const DECL_AND_RETURN( triqs::tuple::apply(on_mesh(*g), triqs::tuple::push_front(tn,p))); Tn tn;
Ev const &evals;
auto operator()(size_t p) const DECL_AND_RETURN(triqs::tuple::apply(on_mesh(*g), triqs::tuple::push_front(tn, p)));
}; };
// now the multi d evaluator itself. // now the multi d evaluator itself.
template<typename Target, typename Opt, typename ... Ms> template <typename Target, typename Opt, typename... Ms> struct evaluator<cartesian_product<Ms...>, Target, Opt> {
struct evaluator<cartesian_product<Ms...>,Target,Opt> { static constexpr int arity = sizeof...(Ms);
static constexpr int arity = sizeof...(Ms); mutable std::tuple<evaluator_fnt_on_mesh<Ms>...> evals;
mutable std::tuple< evaluator_fnt_on_mesh<Ms> ... > evals;
struct _poly_lambda {// replace by a polymorphic lambda in C++14 struct _poly_lambda { // replace by a polymorphic lambda in C++14
template<typename A, typename B, typename C> void operator()(A & a, B const & b, C const & c) const { a = A{b,c};} template <typename A, typename B, typename C> void operator()(A &a, B const &b, C const &c) const {
}; a = A{b, c};
}
template<typename G, typename ... Args>
//std::complex<double> operator() (G const * g, Args && ... args) const {
auto operator() (G const * g, Args && ... args) const
-> decltype (std::get<sizeof...(Args)-1>(evals) (make_binder<sizeof...(Args)-2> (g, std::make_tuple(), evals) ))
// when do we get C++14 decltype(auto) ...!?
{
static constexpr int R = sizeof...(Args);
// build the evaluators, as a tuple of ( evaluator<Ms> ( mesh_component, args))
triqs::tuple::call_on_zip(_poly_lambda(), evals, g->mesh().components(), std::make_tuple(args...));
return std::get<R-1>(evals) (make_binder<R-2> (g, std::make_tuple(), evals) );
}
}; };
} // gf_implementation template <typename G, typename... Args>
}} // std::complex<double> operator() (G const * g, Args && ... args) const {
#endif auto operator()(G const *g, Args &&... args)
const -> decltype(std::get<sizeof...(Args) - 1>(evals)(make_binder<sizeof...(Args) - 2>(g, std::make_tuple(), evals)))
// when do we get C++14 decltype(auto) ...!?
{
static constexpr int R = sizeof...(Args);
// build the evaluators, as a tuple of ( evaluator<Ms> ( mesh_component, args))
triqs::tuple::call_on_zip(_poly_lambda(), evals, g->mesh().components(), std::make_tuple(args...));
return std::get<R - 1>(evals)(make_binder<R - 2>(g, std::make_tuple(), evals));
}
};
} // gf_implementation
}
}

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2012 by M. Ferrero, O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -18,47 +18,52 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_FREQ_H #pragma once
#define TRIQS_GF_FREQ_H
#include "./tools.hpp" #include "./tools.hpp"
#include "./gf.hpp" #include "./gf.hpp"
#include "./local/tail.hpp" #include "./local/tail.hpp"
#include "./domains/R.hpp" #include "./domains/R.hpp"
#include "./meshes/linear.hpp" #include "./meshes/segment.hpp"
#include "./evaluators.hpp" #include "./evaluators.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
struct refreq {}; struct refreq {};
template<typename Opt> struct gf_mesh<refreq,Opt> : linear_mesh<R_domain> { template <typename Opt> struct gf_mesh<refreq, Opt> : segment_mesh {
typedef linear_mesh<R_domain> B; template <typename... T> gf_mesh(T &&... x) : segment_mesh(std::forward<T>(x)...) {}
gf_mesh() = default; //using segment_mesh::segment_mesh;
gf_mesh (double wmin, double wmax, int n_freq, mesh_kind mk=full_bins) :
B(typename B::domain_t(), wmin, wmax, n_freq, mk){}
}; };
namespace gfs_implementation { namespace gfs_implementation {
// singularity // singularity
template<typename Opt> struct singularity<refreq,matrix_valued,Opt> { typedef local::tail type;}; template <typename Opt> struct singularity<refreq, matrix_valued, Opt> {
template<typename Opt> struct singularity<refreq,scalar_valued,Opt> { typedef local::tail type;}; using type = local::tail;
};
template <typename Opt> struct singularity<refreq, scalar_valued, Opt> {
using type = local::tail;
};
// h5 name // h5 name
template<typename Opt> struct h5_name<refreq,matrix_valued,Opt> { static std::string invoke(){ return "ReFreq";}}; template <typename Opt> struct h5_name<refreq, matrix_valued, Opt> {
static std::string invoke() { return "ReFreq"; }
};
/// --------------------------- evaluator --------------------------------- /// --------------------------- evaluator ---------------------------------
template<> struct evaluator_fnt_on_mesh<refreq> TRIQS_INHERIT_AND_FORWARD_CONSTRUCTOR(evaluator_fnt_on_mesh, evaluator_grid_linear_interpolation); template <>
struct evaluator_fnt_on_mesh<refreq> TRIQS_INHERIT_AND_FORWARD_CONSTRUCTOR(evaluator_fnt_on_mesh,
evaluator_grid_linear_interpolation);
template<typename Opt, typename Target> struct evaluator<refreq,Target,Opt> : evaluator_one_var<refreq>{}; template <typename Opt, typename Target> struct evaluator<refreq, Target, Opt> : evaluator_one_var<refreq> {};
/// --------------------------- data access --------------------------------- /// --------------------------- data access ---------------------------------
template<typename Opt> struct data_proxy<refreq,matrix_valued,Opt> : data_proxy_array<std::complex<double>,3> {}; template <typename Opt> struct data_proxy<refreq, matrix_valued, Opt> : data_proxy_array<std::complex<double>, 3> {};
template<typename Opt> struct data_proxy<refreq,scalar_valued,Opt> : data_proxy_array<std::complex<double>,1> {}; template <typename Opt> struct data_proxy<refreq, scalar_valued, Opt> : data_proxy_array<std::complex<double>, 1> {};
} }
}} }
#endif }

View File

@ -2,7 +2,7 @@
* *
* TRIQS: a Toolbox for Research in Interacting Quantum Systems * TRIQS: a Toolbox for Research in Interacting Quantum Systems
* *
* Copyright (C) 2012 by M. Ferrero, O. Parcollet * Copyright (C) 2012-2013 by O. Parcollet
* *
* TRIQS is free software: you can redistribute it and/or modify it under the * TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software * terms of the GNU General Public License as published by the Free Software
@ -18,44 +18,50 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_ONE_REAL_TIME_H #pragma once
#define TRIQS_GF_ONE_REAL_TIME_H
#include "./tools.hpp" #include "./tools.hpp"
#include "./gf.hpp" #include "./gf.hpp"
#include "./local/tail.hpp" #include "./local/tail.hpp"
#include "./domains/R.hpp" #include "./domains/R.hpp"
#include "./meshes/linear.hpp" #include "./meshes/segment.hpp"
#include "./evaluators.hpp" #include "./evaluators.hpp"
namespace triqs { namespace gfs { namespace triqs {
namespace gfs {
struct retime {}; struct retime {};
template<typename Opt> struct gf_mesh<retime,Opt> : linear_mesh<R_domain> { template <typename Opt> struct gf_mesh<retime, Opt> : segment_mesh {
typedef linear_mesh<R_domain> B; template <typename... T> gf_mesh(T &&... x) : segment_mesh(std::forward<T>(x)...) {}
gf_mesh() = default; //using segment_mesh::segment_mesh;
gf_mesh(double tmin, double tmax, int n_points, mesh_kind mk=full_bins) : B (typename B::domain_t(), tmin, tmax, n_points, mk){}
}; };
namespace gfs_implementation { namespace gfs_implementation {
// singularity // singularity
template<typename Opt> struct singularity<retime,matrix_valued,Opt> { typedef local::tail type;}; template <typename Opt> struct singularity<retime, matrix_valued, Opt> {
template<typename Opt> struct singularity<retime,scalar_valued,Opt> { typedef local::tail type;}; using type = local::tail;
};
template <typename Opt> struct singularity<retime, scalar_valued, Opt> {
using type = local::tail;
};
// h5 name // h5 name
template<typename Opt> struct h5_name<retime,matrix_valued,Opt> { static std::string invoke(){ return "ReTime";}}; template <typename Opt> struct h5_name<retime, matrix_valued, Opt> {
static std::string invoke() { return "ReTime"; }
};
/// --------------------------- evaluator --------------------------------- /// --------------------------- evaluator ---------------------------------
template<> struct evaluator_fnt_on_mesh<retime> TRIQS_INHERIT_AND_FORWARD_CONSTRUCTOR(evaluator_fnt_on_mesh, evaluator_grid_linear_interpolation); template <>
struct evaluator_fnt_on_mesh<retime> TRIQS_INHERIT_AND_FORWARD_CONSTRUCTOR(evaluator_fnt_on_mesh,
evaluator_grid_linear_interpolation);
template<typename Opt, typename Target> struct evaluator<retime,Target,Opt> : evaluator_one_var<retime>{}; template <typename Opt, typename Target> struct evaluator<retime, Target, Opt> : evaluator_one_var<retime> {};
/// --------------------------- data access --------------------------------- /// --------------------------- data access ---------------------------------
template<typename Opt> struct data_proxy<retime,matrix_valued,Opt> : data_proxy_array<std::complex<double>,3> {}; template <typename Opt> struct data_proxy<retime, matrix_valued, Opt> : data_proxy_array<std::complex<double>, 3> {};
template<typename Opt> struct data_proxy<retime,scalar_valued,Opt> : data_proxy_array<std::complex<double>,1> {}; template <typename Opt> struct data_proxy<retime, scalar_valued, Opt> : data_proxy_array<std::complex<double>, 1> {};
} // gfs_implementation } // gfs_implementation
}} }
#endif }

View File

@ -18,90 +18,89 @@
* TRIQS. If not, see <http://www.gnu.org/licenses/>. * TRIQS. If not, see <http://www.gnu.org/licenses/>.
* *
******************************************************************************/ ******************************************************************************/
#ifndef TRIQS_GF_TOOLS_H #pragma once
#define TRIQS_GF_TOOLS_H #include <triqs/arrays.hpp>
#include <triqs/utility/first_include.hpp>
#include <utility>
#include <boost/iterator/iterator_facade.hpp>
#include <triqs/clef.hpp>
#include <triqs/arrays/array.hpp>
#include <triqs/arrays/matrix.hpp>
#include <triqs/arrays/h5/simple_read_write.hpp>
#include "triqs/utility/complex_ops.hpp" #include "triqs/utility/complex_ops.hpp"
#include <triqs/utility/view_tools.hpp> #include <triqs/utility/view_tools.hpp>
#include <triqs/utility/expression_template_tools.hpp> #include <triqs/utility/expression_template_tools.hpp>
#include <triqs/h5.hpp> #include <utility>
#include <boost/iterator/iterator_facade.hpp>
namespace triqs { namespace gfs { namespace triqs {
namespace tqa= triqs::arrays; namespace gfs {
namespace mpl=boost::mpl; namespace mpl = boost::mpl;
namespace tag { struct composite{}; struct mesh_point{};} namespace tag {
struct composite {};
struct scalar_valued {}; struct mesh_point {};
template<int R> struct tensor_valued {static_assert( R>0, "tensor_valued only for rank >0");};
struct matrix_valued{};
//------------------------------------------------------
typedef std::complex<double> dcomplex;
enum statistic_enum {Boson,Fermion};
struct freq_infty{}; // the point at infinity
//------------------------------------------------------
inline std::vector<std::string> split(const std::string &s, char delim){
std::vector<std::string> elems;
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim)) { elems.push_back(item); }
return elems;
} }
//------------------------------------------------------
template<typename ... T> struct closest_pt_wrap; // scalar_valued, matrix_valued, tensor_valued
struct scalar_valued {};
template<typename T> struct closest_pt_wrap<T> : tag::mesh_point { T value; template<typename U> explicit closest_pt_wrap(U&&x): value(std::forward<U>(x)){} };
template<typename T1, typename T2, typename ...Ts > struct closest_pt_wrap<T1,T2,Ts...> : tag::mesh_point { template <int R> struct tensor_valued {
std::tuple<T1,T2,Ts...> value_tuple; static_assert(R > 0, "tensor_valued only for rank >0");
template<typename ... U> explicit closest_pt_wrap(U&& ... x): value_tuple (std::forward<U>(x) ... ){}
}; };
template<typename ... T> closest_pt_wrap<T...> closest_mesh_pt(T && ... x) { return closest_pt_wrap<T...> (std::forward<T>(x)...);} struct matrix_valued {};
//------------------------------------------------------ //------------------------------------------------------
using dcomplex = std::complex<double>;
/** The statistics : Boson or Fermion
*/
enum statistic_enum {
Boson,
Fermion
};
struct freq_infty {}; // the point at infinity
//------------------------------------------------------
template <typename... T> struct closest_pt_wrap;
template <typename T> struct closest_pt_wrap<T> : tag::mesh_point {
T value;
template <typename U> explicit closest_pt_wrap(U &&x) : value(std::forward<U>(x)) {}
};
template <typename T1, typename T2, typename... Ts> struct closest_pt_wrap<T1, T2, Ts...> : tag::mesh_point {
std::tuple<T1, T2, Ts...> value_tuple;
template <typename... U> explicit closest_pt_wrap(U &&... x) : value_tuple(std::forward<U>(x)...) {}
};
template <typename... T> closest_pt_wrap<T...> closest_mesh_pt(T &&... x) {
return closest_pt_wrap<T...>{std::forward<T>(x)...};
}
//------------------------------------------------------
// A simple replacement of tail when there is none to maintain generic code simple...
struct nothing { struct nothing {
template<typename... Args> explicit nothing(Args&&...) {} // takes anything, do nothing.. template <typename... Args> explicit nothing(Args &&...) {} // takes anything, do nothing..
nothing() {} nothing() {}
typedef nothing view_type; using view_type = nothing;
typedef nothing regular_type; using regular_type = nothing;
void rebind (nothing){} void rebind(nothing) {}
template< typename RHS> void operator=(RHS && ) {} template <typename RHS> void operator=(RHS &&) {}
friend void h5_write (h5::group, std::string subgroup_name, nothing ) {} friend void h5_write(h5::group, std::string subgroup_name, nothing) {}
friend void h5_read (h5::group, std::string subgroup_name, nothing ) {} friend void h5_read(h5::group, std::string subgroup_name, nothing) {}
// BOOST Serialization
friend class boost::serialization::access; friend class boost::serialization::access;
template<class Archive> template <class Archive> void serialize(Archive &ar, const unsigned int version) {}
void serialize(Archive & ar, const unsigned int version) { friend nothing operator+(nothing, nothing) { return nothing(); }
} template <typename RHS> friend void assign_from_expression(nothing &, RHS) {}
friend nothing operator +( nothing, nothing) { return nothing();} };
template<typename RHS> friend void assign_from_expression(nothing & ,RHS) {}
}; template <typename... T> nothing slice_target(nothing, T...) { return nothing(); }
template <typename T> nothing operator+(nothing, T const &) { return nothing(); }
template <typename... T> nothing slice_target(nothing, T...) { return nothing(); } template <typename T> nothing operator-(nothing, T const &) { return nothing(); }
template <typename T> nothing operator+(nothing, T const &) { return nothing(); } template <typename T> nothing operator*(nothing, T const &) { return nothing(); }
template <typename T> nothing operator-(nothing, T const &) { return nothing(); } template <typename T> nothing operator/(nothing, T const &) { return nothing(); }
template <typename T> nothing operator*(nothing, T const &) { return nothing(); } template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator+(T const &, nothing) { return nothing(); }
template <typename T> nothing operator/(nothing, T const &) { return nothing(); } template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator-(T const &, nothing) { return nothing(); }
template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator+(T const &, nothing) { return nothing(); } template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator*(T const &, nothing) { return nothing(); }
template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator-(T const &, nothing) { return nothing(); } template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator/(T const &, nothing) { return nothing(); }
template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator*(T const &, nothing) { return nothing(); } }
template <typename T> TYPE_DISABLE_IF(nothing, std::is_same<T, nothing>) operator/(T const &, nothing) { return nothing(); } }
}}
#endif