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:
parent
9ce291d640
commit
17ab555213
@ -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
|
||||
|
@ -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>();
|
||||
|
@ -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)]
|
||||
|
@ -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));}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
69
triqs/utility/arithmetic_ops_by_cast.hpp
Normal file
69
triqs/utility/arithmetic_ops_by_cast.hpp
Normal 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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user