/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2011 by M. Ferrero, O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see .
*
******************************************************************************/
#include "tight_binding.hpp"
#include
#include
#include "grid_generator.hpp"
#include "functors.hpp"
namespace triqs { namespace lattice_tools {
using namespace std;
using namespace tqa;
//------------------------------------------------------
array_view hopping_stack (tight_binding const & TB, array_view const & k_stack) {
auto TK = Fourier(TB);
array res(TB.n_bands(), TB.n_bands(), k_stack.len(1));
for(size_t i = 0; i energies_on_bz_path(tight_binding const & TB, K_view_type K1, K_view_type K2, size_t n_pts) {
auto TK = Fourier(TB);
const size_t norb=TB.lattice().n_orbitals();
const size_t ndim=TB.lattice().dim();
array eval(norb,n_pts);
K_type dk = (K2 - K1)/double(n_pts), k = K1;
for (size_t i =0; i energies_on_bz_grid(tight_binding const & TB, size_t n_pts) {
auto TK = Fourier(TB);
const size_t norb=TB.lattice().n_orbitals();
const size_t ndim=TB.lattice().dim();
grid_generator grid(ndim,n_pts);
array eval(norb,grid.size());
for (; grid ; ++grid) {
eval(range(),grid.index()) = linalg::eigenvalues( TK( (*grid) (range(0,ndim))), false);
}
return eval;
}
//------------------------------------------------------
std::pair, array > dos(tight_binding const & TB, size_t nkpts, size_t neps) {
// The Fourier transform of TK
// auto TK = Fourier(TB); // C++0x ....
auto TK = Fourier(TB);
// loop on the BZ
const size_t ndim=TB.lattice().dim();
const size_t norb=TB.lattice().n_orbitals();
grid_generator grid(ndim,nkpts);
array tempeval(norb);
array evec(norb,norb,grid.size());
array eval(norb,grid.size());
if (norb ==1)
for (; grid ; ++grid) {
double ee = real(TK( (*grid) (range(0,ndim)))(0,0));
eval(0,grid.index()) =ee;
evec(0,0,grid.index()) =1;
}
else
for (; grid ; ++grid) {
//cerr<<" index = "< eval_sl = eval(range(),grid.index());
array_view evec_sl = evec(range(),range(),grid.index());
std::tie (eval_sl,evec_sl) = linalg::eigenelements( TK( (*grid) (range(0,ndim)))); //, true);
//cerr<< " point "<< *grid << " value "<< eval_sl<< endl; //" "<< (*grid) (range(0,ndim)) << endl;
}
// define the epsilon mesh, etc.
array epsilon(neps);
double epsmax = tqa::max_element(eval);
double epsmin = tqa::min_element(eval);
double deps=(epsmax-epsmin)/neps;
//for (size_t i =0; i< neps; ++i) epsilon(i)= epsmin+i/(neps-1.0)*(epsmax-epsmin);
for (size_t i =0; i< neps; ++i) epsilon(i)=epsmin+(i+0.5)*deps;
// bin the eigenvalues according to their energy
// NOTE: a is defined as an integer. it is the index for the DOS.
//REPORT <<"Starting Binning ...."< rho (neps,norb);rho()=0;
for(size_t l=0;l, array > dos_patch(tight_binding const & TB, const array & triangles, size_t neps, size_t ndiv) {
// WARNING: This version only works for a single band Hamiltonian in 2 dimensions!!!!
// triangles is an array of points defining the triangles of the patch
// neps in the number of bins in energy
// ndiv in the number of divisions used to divide the triangles
//const size_t ndim=TB.lattice().dim();
//const size_t norb=TB.lattice().n_orbitals();
int ntri = triangles.len(0)/3;
array dos(neps);
// Check consistency
const size_t ndim=TB.lattice().dim();
//const size_t norb=TB.lattice().n_orbitals();
if (ndim !=2) TRIQS_RUNTIME_ERROR<<"dos_patch : dimension 2 only !";
if (triangles.len(1) != ndim) TRIQS_RUNTIME_ERROR<<"dos_patch : the second dimension of the 'triangle' array in not "< thop(1,1);
array energ(nk), weight(nk);
// a, b, c are the corners of the triangle
// g the center of gravity taken from a
array a(ndim), b(ndim), c(ndim), g(ndim), rv(ndim);
int pt = 0;
double s, t;
// The Fourier transform of TK
auto TK = Fourier(TB);
// loop over the triangles
for (int tri = 0; tri < ntri; tri++) {
a = triangles(pt,range());
pt++;
b = triangles(pt,range());
pt++;
c = triangles(pt,range());
pt++;
g = ((a+b+c)/3.0-a)/double(ndiv);
// the area around a k point might be different from one triangle to the other
// so I use it to weight the sum in the dos
double area = abs(0.5*((b(0)-a(0))*(c(1)-a(1))-(b(1)-a(1))*(c(0)-a(0)))/(ndiv*ndiv));
for (size_t i = 0; iepsmax) epsmax=energ(k_index);
if (energ(k_index) epsilon(neps);
double deps=(epsmax-epsmin)/neps;
for (size_t i =0; i< neps; ++i) epsilon(i)= epsmin+i/(neps-1.0)*(epsmax-epsmin);
// bin the eigenvalues according to their energy
int ind;
double totalweight(0.0);
dos() = 0.0;
for (size_t j = 0; j < nk; j++) {
ind=int((energ(j)-epsmin)/deps);
if (ind == int(neps)) ind--;
dos(ind) += weight(j);
totalweight += weight(j);
}
dos /= deps;// Normalize the DOS
return std::make_pair(epsilon, dos);
}
}}