3
0
mirror of https://github.com/triqs/dft_tools synced 2024-11-01 19:53:45 +01:00
dft_tools/triqs/gfs/tools.hpp
Olivier Parcollet 0a1285405c [gfs] Lattice fourier, multivar G, curry, tail
- Add Fourier for lattice.
  - Add regular_bz_mesh, cyclic_lattice, and their FFT.

- rm freq_infty.
- The gf can now be evaluated on a tail_view, which result in composing the tail.
- Fix the following issue :
  g(om_) << g(om_ +1)
  will recompose the tail correctly.
- TODO : TEST THIS NEW FEATURE IN DETAIL.

- Work on singularity for G(x, omega)

 - Separate the factory for singularity from the data factory in gf.
 - overload assign_from_functoin (renamed).
 - Fix singularity_t and co in the gf (const issue).

- Clean tail, add tail_const_view
 - add m_tail for x -> tail on any mesh
 - test curry + fourier works on k
2014-10-18 21:20:35 +02:00

207 lines
7.4 KiB
C++

/*******************************************************************************
*
* 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 <triqs/arrays.hpp>
#include "triqs/utility/complex_ops.hpp"
#include <triqs/utility/view_tools.hpp>
#include <triqs/utility/expression_template_tools.hpp>
#include <utility>
#include <boost/iterator/iterator_facade.hpp>
namespace triqs {
namespace gfs {
namespace mpl = boost::mpl;
namespace tag {
struct composite {};
struct mesh_point {};
}
// scalar_valued, matrix_valued, tensor_valued
struct scalar_valued {};
template <int R> struct tensor_valued {
static_assert(R > 0, "tensor_valued only for rank >0");
};
struct matrix_valued {};
//------------------------------------------------------
using dcomplex = std::complex<double>;
/** The statistics : Boson or Fermion
*/
enum statistic_enum {
Boson,
Fermion
};
//------------------------------------------------------
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 indice struct
// Replace empty state by optional ?
struct indices_2 {
std::vector<std::vector<std::string>> ind;
indices_2() = default;
indices_2(std::vector<std::vector<std::string>> _ind) : ind(std::move(_ind)) {}
// from a size
indices_2(int L) : indices_2(arrays::mini_vector<int, 2>{L, L}) {};
// from a shape
indices_2(arrays::mini_vector<int, 2> const & shape) : ind(2) {
for (int i = 0; i < shape[0]; ++i) ind[0].push_back(std::to_string(i));
for (int i = 0; i < shape[1]; ++i) ind[1].push_back(std::to_string(i));
}
// indices from a vector<T> : L and R are the same.
template <typename T> indices_2(std::vector<T> const & _ind) : ind(2) {
for (auto const &i : _ind) ind[0].push_back(std::to_string(i));
ind[1] = ind[0];
}
bool is_empty() const { return ind.size() == 0; }
void resize(int s) { ind.resize(s);}
template <typename G> bool check_size(G *g) const {
return (is_empty() ||
((ind.size() == 2) && (ind[0].size() == get_target_shape(*g)[0]) && (ind[1].size() == get_target_shape(*g)[1])));
}
std::vector<std::string> operator[](int i) const {
if (is_empty())
return std::vector<std::string> {};
else
return ind[i];
}
arrays::range convert_index(std::string const &s, int l_r) const {
if (!is_empty()) {
auto b = ind[l_r].begin(), e = ind[l_r].end();
auto it = std::find(b, e, s);
if (it != e) return it - b;
}
TRIQS_RUNTIME_ERROR << "There are no string indices for this Green function";
}
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int version) { ar &TRIQS_MAKE_NVP("ind", ind); }
friend void h5_write(h5::group fg, std::string subgroup_name, indices_2 const &g) {
if (g.is_empty()) return;
auto gr = fg.create_group(subgroup_name);
h5_write(gr, "left", g.ind[0]);
h5_write(gr, "right", g.ind[1]);
}
friend void h5_read(h5::group fg, std::string subgroup_name, indices_2 &g) {
h5::group gr = fg; // no default construction
try {
gr = fg.open_group(subgroup_name);
}
catch (...) {
g = indices_2{}; // empty, no file
return;
}
g.resize(2);
h5_read(gr, "left", g.ind[0]);
h5_read(gr, "right", g.ind[1]);
}
};
// inline indices_2 slice(indices_2 const & ind, arrays::range rl, arrays::range rr) {
// return {};
// }
inline indices_2 slice(indices_2 const &ind, arrays::range rl, arrays::range rr) {
if (ind.is_empty()) return {};
return {}; // MODIFY : slice the indices !!!
TRIQS_RUNTIME_ERROR << "Not implemented : slice of string indices";
}
inline indices_2 transpose(indices_2 const &x) {
return std::vector<std::vector<std::string>> {x.ind[1],x.ind[0]};
}
//------------------------------------------------------
// A simple replacement of tail when there is none to maintain generic code simple...
struct nothing {
template <typename... Args> explicit nothing(Args &&...) {} // takes anything, do nothing..
nothing() {}
using const_view_type = nothing;
using view_type = nothing;
using regular_type = nothing;
void rebind(nothing) {}
template <typename RHS> void operator=(RHS &&) {}
friend void h5_write(h5::group, std::string subgroup_name, nothing) {}
friend void h5_read(h5::group, std::string subgroup_name, nothing) {}
template <typename... A> friend nothing slice(nothing, A...) { return nothing(); }
friend class boost::serialization::access;
template <class Archive> void serialize(Archive &ar, const unsigned int version) {}
friend nothing operator+(nothing, nothing) { return nothing(); }
template <typename RHS> friend void assign_singularity_from_function(nothing &, RHS) {}
template<typename A> bool check_size(A) {return true;}
bool is_empty() const { return false;}
};
// Check if T is nothing
template <typename T> constexpr bool is_nothing() { return std::is_same<nothing, T>::value; }
template<int ... pos, typename ...T> nothing partial_eval(nothing, T&&...) { return {};}
inline nothing transpose(nothing) { return {};}
inline nothing inverse(nothing) { return {};}
inline nothing conj(nothing) { return {};}
template <typename T> nothing compose(nothing,T&) { return {};}
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> 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(); }
}
}