Program Listing for File rabiAndersonSC.hpp#
↰ Return to documentation for file (models/rabiAndersonSC.hpp
)
#pragma once
#include "models/fermionBasis.hpp"
#include "nrgcore/qOperator.hpp"
#include "nrgcore/qsymmetry.hpp"
#include "utils/qmatrix.hpp"
#include <algorithm>
#include <cmath>
#include <complex>
#include <cstddef>
#include <iostream>
#include <map>
#include <optional>
#include <string>
#include <vector>
class rabiAndersonSC : public fermionBasis {
// This class is the same as the rabi-Anderson Model.
// Except the fact that We now have Superconductor
// in the system. So Spin is now only conserved quatity
// and charge isn't conserved any more.
// CHECK: The class for the Wilson chaini has to be consistent.
public:
explicit rabiAndersonSC(const std::map<std::string, double> ¶ms) {
createBasis(params); // create the basis in nstates x nstates
}
[[nodiscard]] std::vector<std::vector<int>> get_basis() const { return n_Q; }
[[nodiscard]] std::vector<std::vector<double>> get_eigenvaluesQ() const {
return eigenvalues_Q;
}
[[nodiscard]] std::vector<double> get_chi_Q() const { return chi_Q; }
//
std::vector<std::vector<double>> eigenvalues_Q;
std::vector<double> chi_Q;
std::vector<std::vector<int>> n_Q;
// ########################################
private:
void createBasis(const std::map<std::string, double> ¶ms) {
double gammaZero = params.at("gammaZero");
double epsilonTrion = params.at("epsilonTrion");
double omega = params.at("Omega");
double epsilonD = params.at("epsilonImpurity");
double UCoulumb = params.at("UColoumbImpurity");
double UTrion = params.at("UColoumbTrion");
std::cout << "=======Models Parameter=========" << std::endl;
for (const auto ¶ : params) {
std::cout << para.first << ": " << para.second << "\n";
}
std::cout << "================================" << std::endl;
createFermionBasis();
std::cout << "FermionBasis Size" << fermionOprMat.size() << "\n";
// trion particle
auto trionHole = fermionOprMat[4].cTranspose().dot(fermionOprMat[4]);
auto nDown = fermionOprMat[3].dot(fermionOprMat[3].cTranspose());
auto nUp = fermionOprMat[2].dot(fermionOprMat[2].cTranspose());
// ########################################################
auto Hamiltonian =
// Impurity Onsite Energy
(nDown + nUp) * epsilonD +
nDown.dot(nUp) * UCoulumb
// Trion Onsite Energy
+ (trionHole)*epsilonTrion + // Trion onsite
(nDown + nUp).dot(trionHole) * (-UTrion) + //
// Wilson Site coupling
(fermionOprMat[0].dot(fermionOprMat[2].cTranspose()) +
fermionOprMat[2].dot(fermionOprMat[0].cTranspose()) +
fermionOprMat[1].dot(fermionOprMat[3].cTranspose()) +
fermionOprMat[3].dot(fermionOprMat[1].cTranspose())) *
gammaZero
// Trion coupling
+ (fermionOprMat[2].dot(fermionOprMat[4].cTranspose()) +
fermionOprMat[4].dot(fermionOprMat[2].cTranspose())) *
omega;
// End
//
//
// create_QuantumNspinCharge();
// Main change happen here because of SC.
// Spin (S_z) only conserved quantity.
std::vector<std::vector<size_t>> spinIndex({{0, 2, 4}, // UpSpin
{1, 3}} // Down Spin
);
create_QuantumSpinOnly(spinIndex);
create_Block_structure();
// Only S_z is quatized
// ####################################################################
n_Q = get_unique_Qnumbers();
// set chi_Q
chi_Q.clear();
for (auto ai : n_Q) {
double t_charge = std::accumulate(ai.begin(), ai.end(), 0);
chi_Q.push_back(std::pow(-1., t_charge));
}
//
// set foperator
auto h_blocked = get_block_Hamiltonian(Hamiltonian);
// std::cout << "h_blocked: " << h_blocked << std::endl;
// std::cout << "Hamiltonian: " << Hamiltonian << std::endl;
// Diagonalize the hamilton
eigenvalues_Q.clear();
eigenvalues_Q.resize(n_Q.size(), {});
for (size_t i = 0; i < n_Q.size(); i++) {
eigenvalues_Q[i] = (h_blocked.get(i, i)).value()->diag();
}
std::cout << "Eigenvalues: " << eigenvalues_Q << std::endl;
// TODO: rotate the f operator
// ####################################################################
f_dag_operator = get_block_operators({fermionOprMat[0], fermionOprMat[1]});
std::cout << "f_dag_operators: " << f_dag_operator.size() << std::endl;
std::vector<qOperator> topr(f_dag_operator.size(), qOperator());
for (size_t ip = 0; ip < f_dag_operator.size(); ip++) {
for (size_t i = 0; i < n_Q.size(); i++) {
for (size_t j = 0; j < n_Q.size(); j++) {
auto tfopr = f_dag_operator[ip].get(i, j);
if (tfopr) {
topr[ip].set((h_blocked.get(i, i))
.value()
->cTranspose()
.dot(*tfopr.value())
.dot(*(h_blocked.get(j, j)).value()),
i, j);
}
}
}
}
f_dag_operator = topr;
}
// ######################################
};