3
0
mirror of https://github.com/triqs/dft_tools synced 2024-10-31 11:13:46 +01:00

gf: fix matsubara_freq and mesh_pt

- cleaner implementation, solve some bugs...
This commit is contained in:
Olivier Parcollet 2013-11-20 15:11:29 +01:00
parent 9ce291d640
commit 17ab555213
11 changed files with 114 additions and 90 deletions

View File

@ -60,13 +60,9 @@ required and optional parameters. Default values are provided for optional param
.. code-block:: c
parameter_defaults pdef;
pdef.required
( "Beta", double(), "Inverse temperature")
;
pdef.optional
( "N_time", int(100), "Number of time points")
( "N_freq", int(200), "Number of frequencies")
pdef.required("Beta", double(), "Inverse temperature")
.optional("N_time", int(100), "Number of time points")
.optional("N_freq", int(200), "Number of frequencies")
;
The default_parameters object serves two main purposes: Firstly, the input parameters can

View File

@ -62,7 +62,6 @@ template<typename T> void test( T val=1 ) {
int main(int argc, char **argv) {
conj (8);
test<int>();
test<long>();
test<double>();

View File

@ -139,9 +139,9 @@
[[2.71828,7.38906]
[20.0855,54.5982]]
(make_matrix(conj(A))) --->
[[(1,0),(3,0),(5,0)]
[(2,0),(4,0),(6,0)]
[(3,0),(5,0),(7,0)]]
[[1,3,5]
[2,4,6]
[3,5,7]]
(A) --->
[[(1,0),(3,0),(5,0)]
[(2,0),(4,0),(6,0)]

View File

@ -25,9 +25,10 @@
namespace triqs { namespace arrays {
// complex conjugation for integers
inline int conj(int const& x) { return x; }
inline long conj(long const& x) { return x; }
inline long long conj(long long const& x) { return x; }
inline int conj(int x) { return x; }
inline long conj(long x) { return x; }
inline long long conj(long long x) { return x; }
inline double conj(double x) { return x; }
//C++14 will simply be ...
//template <typename A> decltype(auto) abs(A && a) { return map( [](auto const &x) { using std::abs; return abs(a);}, std::forward<A>(a));}

View File

@ -21,7 +21,7 @@
#ifndef TRIQS_GF_DOMAIN_MATSUBARA_H
#define TRIQS_GF_DOMAIN_MATSUBARA_H
#include "../tools.hpp"
#include "../meshes/mesh_tools.hpp"
#include <triqs/utility/arithmetic_ops_by_cast.hpp>
namespace triqs {
namespace gfs {
@ -29,10 +29,11 @@ namespace gfs {
// --------------- One matsubara frequency, with its arithmetics -------------------------
// all operations are done by casting to complex, except addition and substraction of matsubara_freq
struct matsubara_freq : public arith_ops_by_cast<matsubara_freq, std::complex<double>> {
struct matsubara_freq : public utility::arithmetic_ops_by_cast_disable_same_type<matsubara_freq, std::complex<double>> {
int n;
double beta;
statistic_enum statistic;
matsubara_freq() : n(0), beta(1), statistic(Fermion) {}
matsubara_freq(int const &n_, double beta_, statistic_enum stat_) : n(n_), beta(beta_), statistic(stat_) {}
using cast_t = std::complex<double>;
operator cast_t() const {
@ -40,42 +41,17 @@ namespace gfs {
}
};
inline matsubara_freq operator+(matsubara_freq const &x, matsubara_freq const &y) {
inline matsubara_freq operator+(matsubara_freq const &x, matsubara_freq const &y) {
return {x.n + y.n + (x.statistic & y.statistic), x.beta, ((x.statistic ^ y.statistic) == 1 ? Fermion : Boson)};
}
inline matsubara_freq operator-(matsubara_freq const &x, matsubara_freq const &y) {
// std::cout << x.n - y.n - (~x.statistic & y.statistic)<< std::endl;
return {x.n - y.n - (~x.statistic & y.statistic), x.beta, ((x.statistic ^ y.statistic) == 1 ? Fermion : Boson)};
}
/*
#define IMPL_OP(OP) \
template <typename Y> auto operator OP(matsubara_freq const &x, Y &&y)->decltype(std::complex<double>{}) { \
return std::complex<double>(x) OP std::forward<Y>(y); \
} \
template <typename Y> \
auto operator OP(Y &&y, matsubara_freq const &x)->decltype(std::forward<Y>(y) OP std::complex<double>{}) { \
return std::forward<Y>(y) OP std::complex<double>(x); \
inline matsubara_freq operator-(matsubara_freq const &mp) {
return {-(mp.n + mp.statistic==Fermion ? 1: 0), mp.beta, mp.statistic};
}
IMPL_OP(+);
IMPL_OP(-);
IMPL_OP(*);
IMPL_OP(/ );
#undef IMPL_OP
*/
/*
* template <typename Y> auto operator OP(matsubara_freq const &x, Y &&y)->decltype(std::complex<double>{}) { \
return std::complex<double>(x) OP std::forward<Y>(y); \
} \
template <typename Y> \
auto operator OP(Y &&y, matsubara_freq const &x) \
->TYPE_DISABLE_IF(decltype(std::forward<Y>(y) OP std::complex<double>{}), \
std::is_same<typename std::remove_cv<typename std::remove_reference<Y>::type>::type, matsubara_freq>) { \
return std::forward<Y>(y) OP std::complex<double>(x); \
}
*/
//---------------------------------------------------------------------------------------------------------
/// The domain

View File

@ -109,9 +109,26 @@ namespace gfs {
return r;
}
// does not work on gcc 4.8.1 ???
/* template <typename G>
auto operator()(G const *g, matsubara_freq const &f) const
DECL_AND_RETURN(_call_impl(g, f, Target{}, std::integral_constant<bool, std::is_same<Opt, no_tail>::value>{}));
*/
template <typename G>
auto operator()(G const *g, matsubara_freq const &f) const
DECL_AND_RETURN(_call_impl(g, f, Target{}, std::integral_constant<bool, std::is_same<Opt, no_tail>::value>{}));
typename std::conditional<std::is_same<Target, matrix_valued>::value, arrays::matrix_const_view<std::complex<double>>,
std::complex<double>>::type
operator()(G const *g, matsubara_freq const &f) const {
return _call_impl(g, f, Target{}, std::integral_constant<bool, std::is_same<Opt, no_tail>::value>{});
}
#ifdef __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 <typename G>
error<0> operator()(G const *g, std::complex<double>) const { return {};}
#endif
template <typename G> typename G::singularity_t const &operator()(G const *g, freq_infty const &) const {
return g->singularity();

View File

@ -42,7 +42,7 @@ namespace triqs { namespace gfs {
size_t index_to_linear(index_t ind) const {return ind;}
/// The wrapper for the mesh point
class mesh_point_t : tag::mesh_point,public arith_ops_by_cast<mesh_point_t, size_t> {
class mesh_point_t : tag::mesh_point,public utility::arithmetic_ops_by_cast<mesh_point_t, size_t> {
discrete_mesh const * m;
index_t _index;
public:

View File

@ -82,7 +82,7 @@ namespace gfs {
size_t index_to_linear(index_t ind) const { return ind; }
/// The wrapper for the mesh point
class mesh_point_t : tag::mesh_point, public arith_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> {
linear_mesh const *m;
index_t _index;

View File

@ -49,22 +49,14 @@ namespace gfs {
size_t index_to_linear(index_t ind) const { return ind; }
/// The wrapper for the mesh point
struct mesh_point_t : tag::mesh_point, public arith_ops_by_cast<mesh_point_t, matsubara_freq> {
index_t n;
double beta;
statistic_enum statistic;
struct mesh_point_t : tag::mesh_point, matsubara_freq {
index_t n_max;
mesh_point_t()= default;
mesh_point_t() = default;
mesh_point_t(matsubara_freq_mesh const &mesh, index_t const &index_)
: n(index_), beta(mesh.domain().beta), statistic(mesh.domain().statistic), n_max(mesh.size()) {}
: matsubara_freq(index_, mesh.domain().beta, mesh.domain().statistic), n_max(mesh.size()) {}
mesh_point_t(index_t const &index_, double beta_, statistic_enum stat_, index_t n_max_)
: n(index_), beta(beta_), statistic(stat_), n_max(n_max_) {}
: matsubara_freq(index_, beta_, stat_), n_max(n_max_) {}
void advance() { ++n; }
using cast_t = domain_pt_t;
operator cast_t() const { return 1_j * M_PI * (2 * n + (statistic == Fermion ? 1 : 0)) / beta; }
using cast1_t = matsubara_freq;
operator cast1_t() const { return {n,beta,statistic};}
size_t linear_index() const { return n; }
size_t index() const { return n; }
bool at_end() const { return (n == n_max); }
@ -92,7 +84,7 @@ namespace gfs {
h5::group gr = fg.create_group(subgroup_name);
h5_write(gr, "domain", m.domain());
h5_write(gr, "size", m.size());
//h5_write(gr, "start_at_0", m._positive_only);
// h5_write(gr, "start_at_0", m._positive_only);
// kept for backward compatibility
auto beta = m.domain().beta;
h5_write(gr, "min", Fermion ? M_PI / beta : 0);
@ -108,7 +100,7 @@ namespace gfs {
bool s = true;
h5_read(gr, "domain", dom);
h5_read(gr, "size", L);
//h5_read(gr, "start_at_0", s);
// h5_read(gr, "start_at_0", s);
m = matsubara_freq_mesh{std::move(dom), L, s};
}
@ -129,7 +121,6 @@ namespace gfs {
int n_max;
bool _positive_only;
};
}
}
}

View File

@ -21,35 +21,11 @@
#ifndef TRIQS_GF_MESHTOOLS_H
#define TRIQS_GF_MESHTOOLS_H
#include "../tools.hpp"
#include <triqs/utility/arithmetic_ops_by_cast.hpp>
namespace triqs {
namespace gfs {
// Derive from this object using CRTP to provide arithmetic operation by casting the final object to C
// by not forwarding x, I assume the cast is a simple value, not a matrix, but this is ok
template <typename Derived, typename C> struct arith_ops_by_cast {};
#define IMPL_OP(OP) \
template <typename D, typename C, typename Y> \
auto operator OP(arith_ops_by_cast<D, C> const& x, Y&& y)->decltype(std::declval<C>() OP std::forward<Y>(y)) { \
return C(static_cast<D const&>(x)) OP std::forward<Y>(y); \
} \
template <typename D, typename C, typename Y> \
auto operator OP(Y&& y, arith_ops_by_cast<D, C> const& x) \
->TYPE_DISABLE_IF(decltype(std::forward<Y>(y) OP std::declval<C>()), \
std::is_same<typename std::remove_cv<typename std::remove_reference<Y>::type>::type, D>) { \
return std::forward<Y>(y) OP C(static_cast<D const&>(x)); \
}
IMPL_OP(+);
IMPL_OP(-);
IMPL_OP(*);
IMPL_OP(/ );
#undef IMPL_OP
//------------------------------------------------------
template<typename MeshType>
class mesh_pt_generator :
public boost::iterator_facade< mesh_pt_generator<MeshType>, typename MeshType::mesh_point_t , boost::forward_traversal_tag,
@ -70,6 +46,5 @@ namespace gfs {
typename MeshType::domain_t::point_t to_point() const { return pt;}
};
}}
#endif

View File

@ -0,0 +1,69 @@
/*******************************************************************************
*
* 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
namespace triqs {
namespace utility {
// Derive from this object using CRTP to provide arithmetic operation by casting the final object to C
// by not forwarding x, I assume the cast is a simple value, not a matrix, but this is ok
template <typename Derived, typename C> struct arithmetic_ops_by_cast {};
#define IMPL_OP(OP) \
template <typename D, typename C, typename Y> \
auto operator OP(arithmetic_ops_by_cast<D, C> const &x, Y &&y)->decltype(std::declval<C>() OP std::forward<Y>(y)) { \
return C(static_cast<D const &>(x)) OP std::forward<Y>(y); \
} \
template <typename D, typename C, typename Y> \
auto operator OP(Y &&y, arithmetic_ops_by_cast<D, C> const &x) \
->TYPE_DISABLE_IF(decltype(std::forward<Y>(y) OP std::declval<C>()), \
std::is_base_of<D, typename std::remove_cv<typename std::remove_reference<Y>::type>::type>) { \
return std::forward<Y>(y) OP C(static_cast<D const &>(x)); \
}
IMPL_OP(+);
IMPL_OP(-);
IMPL_OP(*);
IMPL_OP(/ );
#undef IMPL_OP
// Same thing, but disallow the operations with the type itself
template <typename Derived, typename C> struct arithmetic_ops_by_cast_disable_same_type {};
#define IMPL_OP(OP) \
template <typename D, typename C, typename Y> \
auto operator OP(arithmetic_ops_by_cast_disable_same_type<D, C> const &x, Y &&y) \
->TYPE_DISABLE_IF(decltype(std::declval<C>() OP std::forward<Y>(y)), \
std::is_base_of<D, typename std::remove_cv<typename std::remove_reference<Y>::type>::type>) { \
return C(static_cast<D const &>(x)) OP std::forward<Y>(y); \
} \
template <typename D, typename C, typename Y> \
auto operator OP(Y &&y, arithmetic_ops_by_cast_disable_same_type<D, C> const &x) \
->TYPE_DISABLE_IF(decltype(std::forward<Y>(y) OP std::declval<C>()), \
std::is_base_of<D, typename std::remove_cv<typename std::remove_reference<Y>::type>::type>) { \
return std::forward<Y>(y) OP C(static_cast<D const &>(x)); \
}
IMPL_OP(+);
IMPL_OP(-);
IMPL_OP(*);
IMPL_OP(/ );
#undef IMPL_OP
}
}