这是C++加Eigen3实现的计算能带程序,在不优化的情况下,速度没有matlab快,甚至没有python+numpy快,但是后面会有比较多的for循环,以及通过优化后,速度会大大提升。另外需要搭配一个Python的画图程序。
测试需要加上编译器-O3优化:
g++ -std=c++11 -O3 .\Hatree-Fork.cpp -o main
#include <iostream>
#include <cmath>
#include <complex>
#include <vector>
#include <fstream>
#include <iomanip>
#include "../Eigen3/Eigen/Dense"
#define EIGEN_USE_MKL_ALL
#define EIGEN_VECTORIZE_SSE4_2
const double PI = acos(-1);
const double t = -1; // 最近邻hopping
const int N = 64; // y方向宽度
// linspace函数
std::vector<double> linspace(const double min, const double max, const int n){
std::vector<double> result;
int iterator = 0;
for (int i = 0; i <= n-2; i++){
double temp = min + i*(max-min)/(floor((double)n) - 1);
result.insert(result.begin() + iterator, temp);
iterator += 1;
}
result.insert(result.begin() + iterator, max);
return result;
}
Eigen::MatrixXcd Hamiltonian0(const double k){
Eigen::Matrix2cd T = Eigen::Matrix2cd::Zero(2,2);
Eigen::Matrix2cd Dup = Eigen::Matrix2cd::Zero(2,2);
T(0,1) = t*(1.0+exp(std::complex<double>(0,-k)));
T(1,0) = t*(1.0+exp(std::complex<double>(0,k)));
Dup(1,0) = std::complex<double>(t,0);
Eigen::Matrix2cd Ddown = Dup.transpose();
Eigen::MatrixXcd H = Eigen::MatrixXcd::Zero(2*N,2*N);
H.block<2,2>(0,0) = T;
for(int i=2;i<2*N;i+=2){
H.block<2,2>(i,i) = T;
H.block<2,2>(i-2,i) = Dup;
H.block<2,2>(i,i-2) = Ddown;
}
return H;
}
void test_band(std::vector<double>& ks){
/*
输出文件格式如下: 每一行第一列为k值,后面为对应的能量
*/
std::ofstream out("Ek.txt");
int kn = ks.size();
out<<kn<<std::endl;
for(auto k:ks){
auto Hk = Hamiltonian0(k);
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXcd> eigensolver(Hk);
//if (eigensolver.info() != Eigen::Success) abort();
out << k << " ";
for(int i = 0;i<2*N;i++){
out <<eigensolver.eigenvalues()(i)<<" ";
}
out << std::endl;
}
}
int main()
{
double t = -1;
int nk = 1024;
int N = 64;
auto ks = linspace(0,2*PI, nk);
clock_t startTime,endTime;
startTime = clock(); //计时开始
std::cout<<"------start run-------"<<std::endl;
test_band(ks);
endTime = clock();
std::cout << "The run time is: " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << std::endl;
}
画图程序
import matplotlib.pyplot as plt
import numpy as np
f = open("Ek.txt","r")
data = []
n = int(f.readline())
for i in range(n):
line = f.readline()
data.append(list(map(float,line.strip().split(" "))))
data = np.matrix(data)
k = data[:,0]
Ek = data[:,1:]
n, m = Ek.shape
for i in range(m):
plt.plot(k,Ek[:,i])
plt.show()
f.close()
来源:oschina
链接:https://my.oschina.net/u/4328465/blog/4873731