/******************************************************************************* * * 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 . * ******************************************************************************/ #ifndef TRIQS_GF_DOMAIN_MATSUBARA_H #define TRIQS_GF_DOMAIN_MATSUBARA_H #include "../tools.hpp" #include namespace triqs { 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 utility::arithmetic_ops_by_cast_disable_same_type> { 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; operator cast_t() const { return {0, M_PI * (2 * n + (statistic == Fermion ? 1 : 0)) / beta}; } }; 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) { 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 &mp) { return {-(mp.n + mp.statistic==Fermion ? 1: 0), mp.beta, mp.statistic}; } //--------------------------------------------------------------------------------------------------------- /// The domain template struct matsubara_domain { using point_t = typename std::conditional, double>::type; double beta; statistic_enum statistic; matsubara_domain() = default; 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"; } matsubara_domain(matsubara_domain const &) = default; matsubara_domain(matsubara_domain const &x) : beta(x.beta), statistic(x.statistic) {} bool operator==(matsubara_domain const &D) const { return ((std::abs(beta - D.beta) < 1.e-15) && (statistic == D.statistic)); } /// Write into HDF5 friend void h5_write(h5::group fg, std::string subgroup_name, matsubara_domain const &d) { h5::group gr = fg.create_group(subgroup_name); h5_write(gr, "beta", d.beta); h5_write(gr, "statistic", (d.statistic == Fermion ? "F" : "B")); } /// Read from HDF5 friend void h5_read(h5::group fg, std::string subgroup_name, matsubara_domain &d) { h5::group gr = fg.open_group(subgroup_name); double beta; std::string statistic; h5_read(gr, "beta", beta); h5_read(gr, "statistic", statistic); d = matsubara_domain(beta, (statistic == "F" ? Fermion : Boson)); } // BOOST Serialization friend class boost::serialization::access; template void serialize(Archive &ar, const unsigned int version) { ar &boost::serialization::make_nvp("beta", beta); ar &boost::serialization::make_nvp("statistic", statistic); } }; } } #endif