1#ifndef HUBBARDMODELSU2CHARGE_H_ 
    2#define HUBBARDMODELSU2CHARGE_H_ 
   10#include "Geometry2D.h"  
   47    typedef Eigen::Matrix<complex<
double>,Eigen::Dynamic,Eigen::Dynamic> 
MatrixType;
 
   66        size_t Lcell = 
P.size();
 
   68        for (
size_t l=0; l<
N_sites; ++l) 
N_phys += 
P.get<
size_t>(
"Ly",l%Lcell);
 
   69        this->
calc(P.get<
size_t>(
"maxPower"));
 
   78    template<
typename Symmetry_> 
 
   80                               PushType<
SiteOperator<Symmetry_,complex<double>>,complex<double>>& pushlist, std::vector<std::vector<std::string>>& labellist, 
 
   81                               const BC boundary=BC::OPEN);
 
   95    {
"t",1.+0.i}, {
"tPrime",0.i}, {
"tRung",1.+0.i}, {
"tPrimePrime",0.i},
 
   98    {
"V",0.}, {
"Vrung",0.},
 
   99    {
"Jz",0.}, {
"Jzrung",0.}, {
"Jxy",0.}, {
"Jxyrung",0.}, 
 
  100    {
"J",0.}, {
"Jperp",0.},
 
  101    {
"Bz",0.}, {
"Bx",0.},
 
  102    {
"X",0.}, {
"Xrung",0.},
 
  103    {
"REMOVE_DOUBLE",
false}, {
"REMOVE_EMPTY",
false}, {
"REMOVE_UP",
false}, {
"REMOVE_DN",
false}, {
"mfactor",1}, {
"k",0},
 
  104    {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}
 
  109    {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",11ul}, {
"eps_svd",1e-7},
 
  110    {
"Dincr_abs", 4ul}, {
"Dincr_per", 2ul}, {
"Dincr_rel", 1.1},
 
  111    {
"min_Nsv",0ul}, {
"max_Nrich",-1},
 
  112    {
"max_halfsweeps",24ul}, {
"min_halfsweeps",6ul},
 
  113    {
"Minit",1ul}, {
"Qinit",1ul}, {
"Mlimit",500ul},
 
  114    {
"tol_eigval",1e-7}, {
"tol_state",1e-6},
 
  124    ParamHandler P(params,defaults);
 
  125    size_t Lcell = P.size();
 
  127    for (
size_t l=0; l<N_sites; ++l)
 
  129        N_phys += P.get<
size_t>(
"Ly",l%Lcell);
 
  130        setLocBasis(F[l].get_basis().qloc(),l);
 
  133    param1d U = P.fill_array1d<
double>(
"U", 
"Uorb", F[0].orbitals(), 0);
 
  134    if (isfinite(U.a.sum()))
 
  136        this->set_name(
"Hubbard");
 
  140        this->set_name(
"U=∞-Hubbard");
 
  144    std::vector<std::vector<std::string>> labellist;
 
  148    this->construct_from_pushlist(pushlist, labellist, Lcell);
 
  151    this->precalc_TwoSiteData();
 
  154template<
typename Symmetry_>
 
  158    std::size_t Lcell = 
P.size();
 
  162    for (std::size_t loc=0; loc<
N_sites; ++loc)
 
  168        std::size_t orbitals       = 
F[loc].orbitals();
 
  169        std::size_t next_orbitals  = 
F[lp1].orbitals();
 
  170        std::size_t nextn_orbitals = 
F[lp2].orbitals();
 
  171        std::size_t nnextn_orbitals = 
F[lp3].orbitals();
 
  174        ss << 
"Ly=" << 
P.get<
size_t>(
"Ly",loc%Lcell);
 
  175        labellist[loc].push_back(ss.str());
 
  177        auto push_full = [&
N_sites, &loc, &
F, &
P, &pushlist, &labellist, &boundary] (
string xxxFull, 
string label,
 
  178                                                                                     const vector<SiteOperatorQ<Symmetry_,MatrixType>> &first,
 
  179                                                                                     const vector<vector<SiteOperatorQ<Symmetry_,MatrixType>>> &last,
 
  180                                                                                     vector<complex<double>> factor, 
 
  182                                                                                     bool FERMIONIC) -> 
void 
  184            ArrayXXcd Full = 
P.get<Eigen::ArrayXXcd>(xxxFull);
 
  185            vector<vector<std::pair<size_t,complex<double>> > > R = Geometry2D::rangeFormat(Full);
 
  187            if (
static_cast<bool>(boundary)) {assert(R.size() ==   
N_sites and 
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
 
  188            else                             {assert(R.size() >= 2*
N_sites and 
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
 
  190            for (
size_t j=0; j<first.size(); j++)
 
  191            for (
size_t h=0; h<R[loc].size(); ++h)
 
  193                size_t range = R[loc][h].first;
 
  194                complex<double> value = R[loc][h].second;
 
  198                    vector<SiteOperatorQ<Symmetry_,MatrixType> > ops(range+1);
 
  200                    for (
size_t i=1; i<range; ++i)
 
  202                        if (FERMIONIC) {ops[i] = 
F[(loc+i)%
N_sites].sign().template cast<complex<double>>();}
 
  203                        else {ops[i] = 
F[(loc+i)%
N_sites].
Id().template cast<complex<double>>();}
 
  205                    ops[range] = last[j][(loc+range)%
N_sites];
 
  206                    complex<double> total_value = factor[j] * value;
 
  207                    if (CONJ[j]) total_value = conj(total_value);
 
  208                    pushlist.push_back(std::make_tuple(loc, ops, total_value));
 
  213            ss << 
label << 
"(" << Geometry2D::hoppingInfo(Full) << 
")";
 
  214            labellist[loc].push_back(ss.str());
 
  220            vector<SiteOperatorQ<Symmetry_,MatrixType> > cup_ranges(
N_sites);
 
  222            vector<SiteOperatorQ<Symmetry_,MatrixType> > cdn_ranges(
N_sites);
 
  223            for (
size_t i=0; i<
N_sites; i++)
 
  226                cup_ranges[i] = 
F[i].c(
UP,
G[i],0).template cast<complex<double> >();
 
  228            for (
size_t i=0; i<
N_sites; i++)
 
  231                cdn_ranges[i] = 
F[i].c(
DN,
G[i],0).template cast<complex<double> >();
 
  234            vector<SiteOperatorQ<Symmetry_,MatrixType> >          frst {cdagup_sign_local, cdagdn_sign_local};
 
  235            vector<vector<SiteOperatorQ<Symmetry_,MatrixType> > > last {cup_ranges,        cdn_ranges};
 
  236            push_full(
"tFull", 
"tᵢⱼ", frst, last, {-std::sqrt(2.),-std::sqrt(2.)}, {
false, 
false}, 
PROP::FERMIONIC);
 
  240            vector<SiteOperatorQ<Symmetry_,MatrixType> > first {
F[loc].Sp(0).template cast<complex<double>>(), 
 
  241                                                                F[loc].
Sm(0).template cast<complex<double>>(), 
 
  242                                                                F[loc].
Sz(0).template cast<complex<double>>()};
 
  243            vector<SiteOperatorQ<Symmetry_,MatrixType> > Sp_ranges(
N_sites);
 
  244            vector<SiteOperatorQ<Symmetry_,MatrixType> > Sm_ranges(
N_sites);
 
  245            vector<SiteOperatorQ<Symmetry_,MatrixType> > Sz_ranges(
N_sites);
 
  246            for (
size_t i=0; i<
N_sites; i++)
 
  248                Sp_ranges[i] = 
F[i].Sp(0).template cast<complex<double>>();;
 
  249                Sm_ranges[i] = 
F[i].Sm(0).template cast<complex<double>>();;
 
  250                Sz_ranges[i] = 
F[i].Sz(0).template cast<complex<double>>();;
 
  253            vector<vector<SiteOperatorQ<Symmetry_,MatrixType> > > last {Sm_ranges, Sp_ranges, Sz_ranges};
 
  254            push_full(
"Jfull", 
"Jᵢⱼ", first, last, {0.5,0.5,1.}, {
false, 
false, 
false}, 
PROP::BOSONIC);
 
  258        param1d Uph = 
P.fill_array1d<
double>(
"Uph", 
"Uphorb", orbitals, loc%Lcell);
 
  259        param1d V = 
P.fill_array1d<
double>(
"V", 
"Vorb", orbitals, loc%Lcell);
 
  262        param2d tPerp = 
P.fill_array2d<complex<double> >(
"tRung", 
"t", 
"tPerp", orbitals, loc%Lcell, 
P.get<
bool>(
"CYLINDER"));
 
  263        param2d Jxyperp = 
P.fill_array2d<
double>(
"JxyRung", 
"Jxy", 
"JxyPerp", orbitals, loc%Lcell, 
P.get<
bool>(
"CYLINDER"));
 
  264        param2d Jzperp = 
P.fill_array2d<
double>(
"JzRung", 
"Jz", 
"JzPerp", orbitals, loc%Lcell, 
P.get<
bool>(
"CYLINDER"));
 
  265        param2d Jperp = 
P.fill_array2d<
double>(
"JRung", 
"J", 
"JPerp", orbitals, loc%Lcell, 
P.get<
bool>(
"CYLINDER"));
 
  266        param1d Bz = 
P.fill_array1d<
double>(
"Bz", 
"Bzorb", orbitals, loc%Lcell);
 
  267        param1d Bx = 
P.fill_array1d<
double>(
"Bx", 
"Bxorb", orbitals, loc%Lcell);
 
  269        labellist[loc].push_back(Uph.label);
 
  272        labellist[loc].push_back(tPerp.label);
 
  273        labellist[loc].push_back(Jxyperp.label);
 
  274        labellist[loc].push_back(Jzperp.label);
 
  275        labellist[loc].push_back(Jperp.label);
 
  276        labellist[loc].push_back(Bz.label);
 
  277        labellist[loc].push_back(Bx.label);
 
  279        ArrayXXcd Vperp = 
F[loc].ZeroHopping();
 
  281        auto sum_array = [] (
const ArrayXXcd& a1, 
const ArrayXXcd& a2)
 
  283            ArrayXXcd res(a1.rows(), a1.cols());
 
  284            for (
int i=0; i<a1.rows(); ++i)
 
  285            for (
int j=0; j<a1.rows(); ++j)
 
  287                res(i,j) = a1(i,j) + a2(i,j);
 
  294            F[loc].
template HubbardHamiltonian<complex<double>,Symmetry_>(Uph.a.cast<complex<double>>(), 
 
  295                                                                          tPerp.a.cast<complex<double>>(), 
 
  296                                                                          Vperp.cast<complex<double>>(), 
 
  297                                                                          sum_array(Jperp.a.cast<complex<double>>(),Jzperp.a.cast<complex<double>>()), 
 
  298                                                                          sum_array(Jperp.a.cast<complex<double>>(),Jxyperp.a.cast<complex<double>>()), 
 
  299                                                                          Bz.a.cast<complex<double>>(), 
 
  300                                                                          Bx.a.cast<complex<double>>())
 
  302        pushlist.push_back(std::make_tuple(loc, Hloc, 1.+0.i));
 
std::enable_if< Dummy::IS_SPIN_SU2() and!Dummy::IS_CHARGE_SU2(), Mpo< Sym::SU2< Sym::ChargeSU2 >, complex< double > > >::type P(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::ChargeSU2 >, complex< double > > >::type Sz(size_t locx, size_t locy=0) const
Mpo< Sym::SU2< Sym::ChargeSU2 >, complex< double > > Id() const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::ChargeSU2 >, complex< double > > >::type Sm(size_t locx, size_t locy=0) const
vector< FermionBase< Sym::SU2< Sym::ChargeSU2 > > > F
DMRG::VERBOSITY::OPTION VERB
MpoTerms< Symmetry, OtherScalar > cast()
void calc(const std::size_t power)
static std::vector< T > get_N_site_interaction(T const &Op0, Operator const &... Ops)
void precalc_TwoSiteData(bool FORCE=false)
PeierlsHubbardSU2charge(Mpo< Symmetry, complex< double > > &Mpo_input, const vector< Param > ¶ms)
static qarray< 1 > singlet(int N=0)
Sym::SU2< Sym::ChargeSU2 > Symmetry
static void set_operators(const std::vector< FermionBase< Symmetry_ > > &F, const vector< SUB_LATTICE > &G, const ParamHandler &P, PushType< SiteOperator< Symmetry_, complex< double > >, complex< double > > &pushlist, std::vector< std::vector< std::string > > &labellist, const BC boundary=BC::OPEN)
static const map< string, any > sweep_defaults
static constexpr int spinfac
static const map< string, any > defaults
PeierlsHubbardSU2charge()
Eigen::Matrix< complex< double >, Eigen::Dynamic, Eigen::Dynamic > MatrixType
static constexpr MODEL_FAMILY FAMILY
#define MAKE_TYPEDEFS(MODEL)
void finalize(bool PRINT_STATS=false)