在下面,您将看到我的c ++代码,它使用Numerov's method解决了一维Schrödinger方程。但是我有两个问题:
这是我的代码:
#include <iostream>
#include <math.h>
#include <fstream>
#include <string>
#include <iomanip>
#include <sstream>
using namespace std;
#define pi 3.1415926535897932384626433
class ID_TISE{
public:
ID_TISE(int N_graid, int x_min, int x_max, double dx, double e_tr, double de, double e_up, double m, double h_bar, double c);
~ID_TISE();
//functions
double Potential(char, int);
double PotentialIon(char, int);
void Setk2(double *k2, double E, int N, char lr);
void Numerov(double *psi, double *k2, int N);
double diff_slope(double e_tr,int N_L, int N_R);;
string string_precision(int, int);
double x(char lr, int index);
void Numerov_Solver(double*, double*);
void id_tise();
int N_graid ;
double x_min;
double x_max;
double dx;
//set trial energy
double e_tr;
double de;
double e_up;
int N_E = 10000;
//constant
double m ;
double h_bar;
double c; // second point of the wavefunctions
//array
double *psi_l = NULL;
double *psi_r = NULL;
double *k2_l = NULL;
double *k2_r = NULL;
};
ID_TISE::ID_TISE(int N_graid, int x_min, int x_max, double dx, double e_tr, double de, double e_up, double m, double h_bar, double c){
this->N_graid = N_graid;
this->x_min = x_min;
this->x_max = x_max;
this->dx = dx;
this->e_tr =e_tr;
this->de = de;
this->e_up = e_up;
this->m = m;
this->h_bar=h_bar;
this->c=c;
psi_l = new double[N_graid];
psi_r = new double[N_graid];
k2_l = new double[N_graid];
k2_r = new double[N_graid];
}
ID_TISE::~ID_TISE(){
delete[] psi_l;
delete[] psi_r;
delete[] k2_l;
delete[] k2_r;
}
void ID_TISE::id_tise(){
ofstream fout;
int im = int(N_graid/2);
int N_R = N_graid - im + 2;
int N_L = im + 2;
//initialization left solution
psi_l[0] = 0.0;
psi_l[1] = c;
//initialization right solution
psi_r[0] = 0.0;
psi_r[1] = c;
int ii = 0, inode = 0, inodeUp = 1;
while(e_tr < e_up){
double ds1 = diff_slope(e_tr,N_L,N_R);
e_tr += de;
double ds2 = diff_slope(e_tr,N_L,N_R);
if(ds1*ds2 < 0.0){
if(e_tr < -9.0e-7 || e_tr > 9.0e-7){ // to prevent reaching to E = 0
cout <<"E_"<<ii++ <<" = "<< e_tr << endl;
Normalizer(psi_r,im);
Normalizer(psi_l,im);
fout.open("psi_"+string_precision(ii,0)+ ".dat");
if(e_tr < 0){
if(inode%2 != 0.){
for(int i = 0; i < im; i++)
fout << x('l',i) << "\t" << -psi_l[i] << endl;
}
else{
for(int i = 0; i < im; i++)
fout << x('l',i) << "\t" << psi_l[i] << endl;
}
for(int i = im-1; i > -1; i--)
fout << x('r',i) << "\t" << psi_r[i] << endl;
inode++;
}
else{
if(inodeUp%2 == 0.){
for(int i = 0; i < im; i++)
fout << x('l',i) << "\t" << -psi_l[i] << endl;
}
else{
for(int i = 0; i < im; i++)
fout << x('l',i) << "\t" << psi_l[i] << endl;
}
for(int i = im-1; i > -1; i--)
fout << x('r',i) << "\t" << psi_r[i] << endl;
inodeUp++;
}
fout.close();
}
}
else continue;
}
}
void ID_TISE::Normalizer(double *psi,int N){
double sum = 0.;
for(int i=0 ; i<N ; i++)
sum += psi[i]*psi[i]*dx;
sum=sqrt(sum);
for(int i=0 ; i<N ; i++){
psi[i]=psi[i]/sum;
}
}
void ID_TISE::Numerov(double *psi, double *k2 , int N){
double h12 = (dx*dx)/12.;
for(int i = 1; i < N; i++){
psi[i+1] = (2.*(1.-5.*h12*k2[i])*psi[i] - (1. + h12*k2[i-1])*psi[i-1])/(1. + h12*k2[i+1]);
}
}
void ID_TISE::Setk2(double *k2, double E, int N, char lr){
for(int i = 0; i < N; i++){
if(E > 0)
k2[i] = (2.*m/(h_bar*h_bar))*(E - PotentialIon(lr,i));
else
k2[i] = (2.*m/(h_bar*h_bar))*(E - Potential(lr,i));
}
}
double ID_TISE::Potential(char lr, int index){
return -1./sqrt(x(lr, index)*x(lr, index)+2.);
}
double ID_TISE::PotentialIon(char lr, int index){
return 0.;
}
double ID_TISE::x(char lr, int index){
if(lr == 'l')
return x_min + (index)*dx; // dx = h
else
return x_max - (index)*dx; // the right solution
}
double ID_TISE::diff_slope(double e_tr, int N_L, int N_R){
double dslope;
//initialization left solution
psi_l[0] = 0.0;
psi_l[1] = c;
//initialization right solution
psi_r[0] = 0.0;
psi_r[1] = c;
Setk2(k2_l, e_tr, N_L, 'l');
Setk2(k2_r, e_tr, N_R, 'r');
Numerov(psi_l, k2_l, N_L);
Numerov(psi_r, k2_r, N_R);
double y_m = (psi_l[N_L-1]+psi_r[N_R-1])/2.;
dslope = (2.*y_m - psi_l[N_L - 3] - psi_r[N_R - 3])/(dx*psi_r[N_R - 2]);
return dslope;
}
string ID_TISE::string_precision(int value, int n_digits){
if(n_digits < 6) n_digits = 6;
ostringstream out;
out << fixed<<setprecision(n_digits) << value;
return out.str();
}
int main(){
int N_graid = 500000;
double x_min = -500;
double x_max = -x_min;
double dx = (x_max - x_min)/(N_graid-1);
//set trial energy
double e_tr = -0.6;
double de = 0.000001;
double e_up = 1.0;
//constant
double m = 1.;
double h_bar = 1.;
double c = 0.00000001; // second point of the wavefunctions
ID_TISE &id_tise = *(new ID_TISE(N_graid,x_min,x_max,dx,e_tr,de,e_up,m,h_bar,c));
id_tise.id_tise();
}