Program Listing for File sector.hpp

Return to documentation for file (src_ed/sector.hpp)

#ifndef sector_h
#define sector_h

#include <cstring>
#include "parser.hpp"

namespace HS_mixing {
  const int normal=0;
  const int anomalous=1;
  const int spin_flip=2;
  const int full=3;
  const int up_down=4;
}

void qcm_ED_throw(const std::string& s);

struct sector{
    const static int odd = 9999;
    const static int even = 10000;
    int N;
    int S;
    size_t irrep;

    sector(): N(0), S(0), irrep(0) {}

    sector(int _N, int _S, size_t _irrep): N(_N), S(_S), irrep(_irrep) {}

  // returns the number of up spins
  // N = Nup+Ndw, S = Nup-Ndw ---> Nup = (N+S)/2
  int Nup() const{
    if(N==even or S==even) return even;
    else if(N==odd or S==odd) return odd;
    else return (N+S)/2;
  }

  // returns the number of down spins
  // N = Nup+Ndw, S = Nup-Ndw ---> Ndw = (N-S)/2
  int Ndw() const{
    if(N==even or S==even) return even;
    else if(N==odd or S==odd) return odd;
    else return (N-S)/2;
  }


    sector(const string &str) {

        bool valid = true;
    int nel=0;
    string tmp_str;

    // reading N
    int loc = str.find("N");
    if(loc != string::npos){
      tmp_str = str.substr(loc);
      nel = sscanf(tmp_str.c_str(),"N%d",&N);
      if(nel == 0) valid = false;
    }
    else N = even;

    // reading S
    loc = str.find("S");
    if(loc != string::npos){
      tmp_str = str.substr(loc);
      nel = sscanf(tmp_str.c_str(),"S%d",&S);
      if(nel == 0) valid = false;
    }
    else S = even;

    // reading R
    loc = str.find("R");
    if(loc != string::npos){
      tmp_str = str.substr(loc);
      nel = sscanf(tmp_str.c_str(),"R%ld",&irrep);
      if(nel == 0) valid = false;
    }
    else irrep = 0;

    if(!valid){
      qcm_ED_throw("sector string " + str + " does not conform to standard!");
    }

        if(str.find("O") != string::npos) N = S = odd;
    if(S == even && N != even && N%2) S = odd;
    if(N == even && S != even && S%2) N = odd;

  }




    friend std::ostream & operator<<(std::ostream &flux, const sector &s){
        if(s.S == s.odd && s.N == s.odd) flux << "O";
        flux << "R" << s.irrep;
        if(s.N != s.even && s.N != s.odd) flux << ":N" << s.N;
        if(s.S != s.even && s.S != s.odd) flux << ":S" << s.S;
        return flux;
    }





    friend std::istream & operator>>(std::istream &flux, sector &s){
        char tmp_str[32];
        flux >> tmp_str;

        if(strchr(tmp_str,'R')!=nullptr){
            if(strchr(tmp_str,'S')==nullptr){
                s.S = s.even;
                if(strchr(tmp_str,'N')==nullptr) s.N = s.even;
                else sscanf(tmp_str,"R:%ld,N:%d",&s.irrep,&s.N);
        if(s.S == even && s.N != even && s.N%2) s.S = odd;
            }
            else{
                if(strchr(tmp_str,'N')==nullptr){
                    s.N = s.even;
                    sscanf(tmp_str,"R:%ld,S:%d",&s.irrep,&s.S);
          if(s.S%2) s.N = odd;
                }
                else sscanf(tmp_str,"R:%ld,N:%d,S:%d",&s.irrep,&s.N,&s.S);
            }
        }
        else{
            qcm_ED_throw("sector string " + s.name() + " does not conform to standard!");
        }
        return flux;
    }




    string name() const{
        ostringstream s;
        s << *this;
        return s.str();
    }

};


namespace std
{
    template<>
    struct less<sector>{
        bool operator()(const sector &x, const sector &y) const{
            if(x.S < y.S) return true;
            else if(x.S > y.S) return false;
            else if(x.N < y.N) return true;
            else if(x.N > y.N) return false;
            else if(x.irrep < y.irrep) return true;
            else return false;
        }
    };
}



bool operator!=(const sector &S1, const sector &S2);
bool operator==(const sector &S1, const sector &S2);
bool operator>(const sector &S1, const sector &S2);
bool operator<(const sector &S1, const sector &S2);




#endif