Program Listing for File fdmBackwardIteration.hpp#
↰ Return to documentation for file (dynamics/fdmBackwardIteration.hpp
)
#pragma once
#include "nrgcore/nrgData.hpp"
#include "nrgcore/qOperator.hpp"
#include "utils/qmatrix.hpp"
#include "utils/timer.hpp"
#include <algorithm> // std::min_element
#include <cmath>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <optional>
#include <tuple>
#include <vector>
template <typename nrgcore_type> // nrgcore_type is a type of
class fdmBackwardIteration {
public:
nrgcore_type *nrgObject;
double kBT{0}; // Temperature of nrg system i.e., in FDM formalism
// fdmBackwardIteration() {}
explicit fdmBackwardIteration(nrgcore_type *t_nrgObject // nrgcore_type
) {
setup(t_nrgObject);
this->clearKeptIndex();
}
void setup(nrgcore_type *t_nrgObject) {
lastiteration = true;
nrgObject = t_nrgObject;
}
void calcSpectrum(double energyScale) {
// Clear the operator
setCurrentIndex();
// Order of these functions are important
setRhoZero(energyScale);
// rhoDotOperators();
setReduceDensityMatrix();
}
void setReduceDensityMatrix() {
// Set reducedRho
reducedRho.clear();
for (size_t i = 0; i < nrgObject->pre_sysmQ.size(); i++) {
reducedRho.push_back( //
qmatrix<>(nrgObject->eigenvaluesQ_kept_indices[i].size(),
nrgObject->eigenvaluesQ_kept_indices[i].size(), 0));
}
// Rotate the eigen basis
for (size_t i = 0; i < nrgObject->current_sysmQ.size(); i++) {
// U. rhoZero . U.T : TODO: check
rhoZero[i] = nrgObject->current_hamiltonQ[i].dot(
rhoZero[i].dot(nrgObject->current_hamiltonQ[i].cTranspose()));
}
// Set reducedRho
for (size_t i = 0; i < nrgObject->current_sysmQ.size(); i++) {
size_t kidx = 0;
for (auto kindex : nrgObject->coupled_nQ_index[i]) {
auto ii = kindex / nrgObject->nq_bath.size(); // impurity nqi index
auto bb = kindex % nrgObject->nq_bath.size(); // bath nqi index
// create previous bath id matrix
for (size_t it : nrgObject->eigenvaluesQ_kept_indices[ii]) {
for (size_t it_p : nrgObject->eigenvaluesQ_kept_indices[ii]) {
double aa{0};
for (size_t il = 0; il < nrgObject->bath_eigenvaluesQ[bb].size();
il++) {
aa += rhoZero[i].at(
kidx + it +
nrgObject->eigenvaluesQ_kept_indices[ii].size() * il,
kidx + it_p +
nrgObject->eigenvaluesQ_kept_indices[ii].size() * il);
}
reducedRho[ii].at(it, it_p) += aa;
}
}
kidx += nrgObject->eigenvaluesQ_kept_indices[ii].size() *
nrgObject->bath_eigenvaluesQ[bb].size();
}
// End of matrix generation.
}
// double trace = std::accumulate(
// reducedRho.begin(), reducedRho.end(), 0.0,
// [](double a, const qmatrix<> &b) {
// return a + b.trace();
// });
// std::cout << "NrgItr: " << nrgObject->nrg_iterations_cnt
// << "rhoTrace: " << trace << std::endl;
// once the reduce density matrix is defined We
// set the lastiteration to be false for the next iteration
lastiteration = false;
}
void setLocalPartitionFunction() {
localGroundStateEnergy = 0;
localPartitionFunction = 0; // Ground state degenarecy
for (const auto &aa : nrgObject->eigenvaluesQ) {
if (aa.size() != 0) {
double result = *std::min_element(aa.begin(), aa.end());
localGroundStateEnergy = std::min(localGroundStateEnergy, result);
}
}
for (size_t i = 0; i < nrgObject->eigenvaluesQ.size(); i++) {
for (size_t ie = 0; ie < nrgObject->eigenvaluesQ[i].size(); ie++) {
double energy =
std::fabs(nrgObject->eigenvaluesQ[i][ie] - localGroundStateEnergy);
if (energy < energyErrorBar) {
localPartitionFunction += 1.;
}
}
} //
std::cout << "localGroundStateEnergy" << localGroundStateEnergy
<< " localPartitionFunction: " << localPartitionFunction
<< std::endl;
BoltzmannFactor = nrgObject->eigenvaluesQ;
for (size_t i = 0; i < nrgObject->current_sysmQ.size(); i++) {
for (size_t ie = 0; ie < nrgObject->eigenvaluesQ[i].size(); ie++) {
double energy =
std::fabs(nrgObject->eigenvaluesQ[i][ie] - localGroundStateEnergy);
if (energy < energyErrorBar) {
BoltzmannFactor[i][ie] = 1. / localPartitionFunction;
} else {
BoltzmannFactor[i][ie] = 0;
}
}
} //
}
auto rhoDotStaticOperators(std::vector<qOperator> *bOperator) {
// timer t1("rhoDotStaticOperators");
std::vector<double> specSum(bOperator->size(), 0.0);
//
for (size_t ip = 0; ip < bOperator->size(); ip++) {
for (size_t i = 0; i < nrgObject->eigenvaluesQ.size(); i++) {
size_t kpdim = nrgObject->eigenvaluesQ[i].size();
// std::cout << "--------------------------";
// std::cout << "idx" << idx << " idx_p" << idx_p << std::endl;
// TODO(sp): This
auto sys_opr_opt = (*bOperator)[ip].get(i, i);
if (sys_opr_opt) {
auto *sys_opr = sys_opr_opt.value();
// set kept-kept part operator
for (auto iv : currentKeptIndex[i]) {
for (auto iv_p : currentKeptIndex[i]) {
sys_opr->at(iv, iv_p) = 0;
}
}
for (size_t iv = 0; iv < kpdim; iv++) {
for (size_t iv_p = 0; iv_p < kpdim; iv_p++) {
specSum[ip] += sys_opr->at(iv, iv_p) * rhoZero[i].at(iv_p, iv);
}
}
}
// all the matrices are set
}
}
// set the matrix elements
// end of lm loop
// End of matrix generation.
// Rotate the c operator in the eigen basis
return specSum;
}
void setRhoZero(const std::vector<std::vector<double>> &tBoltzmannFactor) {
// Clear the operator
// Order of these functions are important
rhoZero.clear();
double rhoTrace = 0;
for (size_t i = 0; i < nrgObject->current_sysmQ.size(); i++) {
size_t kpdim = nrgObject->eigenvaluesQ[i].size();
// std::cout << "--------------------------";
// std::cout << "idx" << idx << " idx_p" << idx_p << std::endl;
qmatrix<> tmat(kpdim, kpdim, 0);
// Discarded states
for (size_t ie = currentKeptIndex[i].size();
ie < nrgObject->eigenvaluesQ[i].size(); ie++) {
tmat(ie, ie) = tBoltzmannFactor[i][ie];
}
// Kept states
if (!lastiteration) { // Condition for the last Wilson site
// std::cout << "Not lastiteration" << std::endl;
// Just Override the kept states
for (auto ik : currentKeptIndex[i]) {
for (auto ikp : currentKeptIndex[i]) {
tmat(ik, ikp) = reducedRho[i](ik, ikp);
}
}
}
rhoTrace += tmat.trace();
// Save the matrix
rhoZero.push_back(tmat);
}
std::cout << "NRG Itr: " << nrgObject->nrg_iterations_cnt
<< "rhoTrace: " << rhoTrace << std::endl;
// move the operator
} // End of update_system_operatorQ
void setRhoZero() {
// Clear the operator
// Order of these functions are important
// This function is called
// for setting up current rho
//
//
//
if (lastiteration) {
setLocalPartitionFunction();
}
double rhoTrace{0};
// Calc partition function of the shell ::
vecPartitions.push_back(localPartitionFunction);
rhoZero.clear();
std::cout << "Size : " << reducedRho.size() << " "
<< currentKeptIndex.size() << std::endl;
for (size_t i = 0; i < nrgObject->current_sysmQ.size(); i++) {
size_t kpdim = nrgObject->eigenvaluesQ[i].size();
// std::cout << "--------------------------";
// std::cout << "idx" << idx << " idx_p" << idx_p << std::endl;
qmatrix<> tmat(kpdim, kpdim, 0);
// Discarded states
if (lastiteration) { // Only for the laast iterationT= 0
for (size_t ie = 0; ie < nrgObject->eigenvaluesQ[i].size(); ie++) {
tmat(ie, ie) = BoltzmannFactor[i][ie];
}
}
// Kept states
if (!lastiteration) { // Condition for the last Wilson site
// Just Override the kept states
// std::cout << reducedRho[i].size() << " " <<
// currentKeptIndex[i].size()
// << std::endl;
for (auto ik : currentKeptIndex[i]) {
for (auto ikp : currentKeptIndex[i]) {
tmat(ik, ikp) = reducedRho[i](ik, ikp);
}
}
}
rhoTrace += tmat.trace();
// Save the matrix
rhoZero.push_back(tmat);
}
std::cout << "NrgItr: " << nrgObject->nrg_iterations_cnt
<< "rhoTrace: " << rhoTrace << std::endl;
// move the operator
} // End of update_system_operatorQ
//
void setTemperature(double mkBT) { kBT = mkBT; }
void setCurrentIndex() {
// This only work for the backward iteration
if (lastiteration) {
// every state is Discarded
for (size_t i = 0; i < nrgObject->current_sysmQ.size(); i++) {
currentKeptIndex.emplace_back();
}
} else {
currentKeptIndex = previoudKeptIndex;
}
previoudKeptIndex = nrgObject->eigenvaluesQ_kept_indices;
}
void clearKeptIndex() {
lastiteration = true;
BoltzmannFactor.clear();
vecPartitions.clear();
rhoZero.clear();
reducedRho.clear();
currentKeptIndex.clear();
previoudKeptIndex.clear();
}
private:
std::vector<std::vector<double>> BoltzmannFactor;
double localGroundStateEnergy{0};
double localPartitionFunction{0}; // Ground state degenarecy
std::vector<std::vector<size_t>> previoudKeptIndex;
double spWeightErrorBar{1e-20}; // We dont care for the lower value
std::vector<qmatrix<>> reducedRho;
std::vector<double> vecPartitions;
public: // Give access for openchain class
std::vector<std::vector<size_t>> currentKeptIndex;
std::vector<qmatrix<>> rhoZero;
bool lastiteration{true};
double energyErrorBar{1e-5};
};