Program Listing for File lattice_model.hpp¶
↰ Return to documentation for file (src_qcm/lattice_model.hpp)
#ifndef lattice_model_hpp
#define lattice_model_hpp
#include <string>
#include <map>
#include <memory>
#include <optional>
#include "qcm_ED.hpp"
#include "lattice3D.hpp"
#include "vector3D.hpp"
#include "lattice_operator.hpp"
#include "Green_function.hpp"
#include "parameter_set.hpp"
#include "lattice_hybrid.hpp"
struct site{
size_t cluster; // cluster index of the site (starts at 0)
size_t index_within_cluster; //
int orb; // orbital label
vector3D<int64_t> position; // position of site in the repeated unit
};
struct cluster{
size_t n_sites;
size_t offset;
vector3D<int64_t> position;
int ref;
int mixing;
bool conj;
int sys_start;
int nsys;
};
struct neighbor_match{
int s2;
int ni;
int ni_opp;
};
struct System{
size_t n_sites;
size_t n_bath;
string name;
int clus;
int mixing;
size_t n_sym;
};
struct lattice_model{
basis3D dual;
basis3D phys;
basis3D physdual;
basis3D superdual;
bool bath_exists;
bool is_closed;
int mixing;
int n_mixed;
int spatial_dimension;
int nsys;
lattice3D superlattice;
lattice3D unit_cell;
map<string, shared_ptr<lattice_operator>> term;
map<vector3D<int64_t>,size_t> folded_position_map;
map<vector3D<int64_t>,size_t> position_map;
size_t dim_GF;
size_t dim_reduced_GF;
size_t Lc;
size_t n_band;
string name;
vector<cluster> clusters;
vector<System> systems;
vector<int> inequiv;
vector<int> is_nambu_index; // 1 if the index is of Nambu type, 0 otherwise
vector<pair<int, int>> bonds; // list of NN bonds
vector<shared_ptr<lattice_operator>> one_body_ops;
vector<site> sites;
vector<size_t> s_; // dimensions of the Green functions for each cluster
vector<size_t> GF_dims; // dimensions of the Green functions for each cluster
vector<size_t> GF_offset; // position of the cluster #i in GF index space (depends on mixing)
vector<size_t> opposite_neighbor;
vector<size_t> reduced_Green_index; // lattice Green index (n_band*n_mixed) associated with full Green index (n_mixed*n_sites)
vector<vector<vector<Complex>>> pauli;
vector<vector3D<double>> Green_to_position; // position associated (in superlattice basis) with each Green function index
vector<vector3D<int64_t>> neighbor;
struct tile_group {
size_t n_intra;
vector<array<size_t,3>> entries;
};
vector<tile_group> tiling_data;
shared_ptr<parameter_set> param_set;
vector<string> sector_strings;
string hybrid_file;
shared_ptr<lattice_hybrid> hybrid;
static bool model_consolidated;
lattice_model();
double Potthoff_functional();
int neighbor_index(vector3D<int64_t>& R);
matrix<Complex> periodize(const vector3D<double> &k, matrix<Complex> &mat);
pair<string, int> name_and_label(string &S, bool cut = false);
size_t to_GF_index(size_t I, size_t spin, bool anomalous, bool spin_down);
template<typename T> void build_cluster_operators(lattice_operator& op);
vector<Complex> periodize(const vector3D<double> &k, vector<Complex> &mat);
void add_anomalous_elements(vector<lattice_matrix_element>& E, int s1, int s2, int ni, int ni_opp, Complex z, latt_op_type SC);
void add_chemical_potential();
void anomalous_operator(const string &name, vector3D<int64_t> &link, complex<double> amplitude, int orb1, int orb2, const string& type);
void close_model(bool force=false);
void density_wave(const string &name, vector3D<int64_t> &link, complex<double> amplitude, int orb, vector3D<double> Q, double phase, const string& type);
void explicit_operator(const string &name, const string &type, const vector<tuple<vector3D<int64_t>, vector3D<int64_t>, complex<double>>> &elem, int tau, int sigma);
matrix<Complex> compact_tiling(const matrix<Complex>& A, const vector3D<double>& k);
std::optional<neighbor_match> find_second_site(int s1, const vector3D<int64_t>& link);
void neighbor_census();
void prepare_tiling_data();
void hopping_operator(const string &name, vector3D<int64_t> &link, double amplitude, int orb1, int orb2, int tau, int sigma);
void current_operator(const string &name, vector3D<int64_t> &link, double amplitude, int b1, int b2, int dir, bool pau=true);
void interaction_operator(const string &name, vector3D<int64_t> &link, double amplitude, int orb1, int orb2, const string &type);
void one_body_matrix(lattice_operator& op);
void post_parameter_consolidate(size_t label);
void pre_operator_consolidate();
void print(ostream& fout, bool asy_operators=false, bool asy_labels=false, bool asy_orb=false, bool asy_neighbors=false, bool asy_working_basis=false);
matrix<Complex> lattice_hybridization(int iw, int ik);
};
template<typename T>
void lattice_model::build_cluster_operators(lattice_operator& op)
{
op.in_cluster.assign(clusters.size(), true);
// loop over clusters
set<string> is_built;
for(int s=0; s<nsys; s++){
int c = systems[s].clus;
if(is_built.count(systems[s].name) and op.is_density_wave == false) continue;
// selecting the matrix elements
auto data = ED::model_size(systems[s].name);
size_t n_orb = get<0>(data) + get<1>(data);
vector<matrix_element<T>> elem;
for(auto& e : op.elements){
if(sites[e.site2].cluster == c and sites[e.site1].cluster == c and e.neighbor == 0){
matrix_element<T> X(sites[e.site1].index_within_cluster + e.spin1*n_orb, sites[e.site2].index_within_cluster + e.spin2*n_orb, native<T>(e.v));
elem.push_back(X);
}
if(global_bool("periodic")){
if(sites[e.site2].cluster == c and sites[e.site1].cluster == c and e.neighbor != 0){
matrix_element<T> X(sites[e.site1].index_within_cluster + e.spin1*n_orb, sites[e.site2].index_within_cluster + e.spin2*n_orb, native<T>(e.v));
elem.push_back(X);
}
}
}
if(elem.size() == 0){
op.in_cluster[c] = false;
if(global_bool("verb_warning"))
cout << "WARNING : operator " << op.name << " has no element in cluster " << c+1 << endl;
continue;
}
else{
is_built.insert(systems[s].name);
if(global_bool("verb_Hilbert")) cout << "building operator " << op.name << " on cluster no " << c+1 << " (model " << systems[s].name << ")" << endl;
}
string opname = op.name;
if(op.is_density_wave){
opname += '@' + to_string(c+1);
}
switch(op.type){
case latt_op_type::one_body:
ED::new_operator(systems[s].name, opname, string("one-body"), elem);
break;
case latt_op_type::singlet :
case latt_op_type::dz :
case latt_op_type::dy :
case latt_op_type::dx :
ED::new_operator(systems[s].name, opname, string("anomalous"), elem);
break;
case latt_op_type::Hubbard:
ED::new_operator(systems[s].name, opname, string("interaction"), elem);
break;
case latt_op_type::Hund:
ED::new_operator(systems[s].name, opname, string("Hund"), elem);
break;
case latt_op_type::Heisenberg:
ED::new_operator(systems[s].name, opname, string("Heisenberg"), elem);
break;
case latt_op_type::X:
ED::new_operator(systems[s].name, opname, string("X"), elem);
break;
case latt_op_type::Y:
ED::new_operator(systems[s].name, opname, string("Y"), elem);
break;
case latt_op_type::Z:
ED::new_operator(systems[s].name, opname, string("Z"), elem);
break;
}
}
}
#endif /* lattice_model_hpp */