-
Notifications
You must be signed in to change notification settings - Fork 0
/
my_hf.cpp
139 lines (113 loc) · 3.93 KB
/
my_hf.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
// Created by Kshitij Surjuse on 9/13/22.
//
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
//Eigen
#include <Eigen/Cholesky>
#include <Eigen/Eigenvalues>
#include <libint2.hpp>
#if !LIBINT2_CONSTEXPR_STATICS
# include <libint2/statics_definition.h>
#endif
#include <btas/btas.h>
#include <btas/tensor.h>
using namespace btas;
using std::cout;
using std::string;
using std::endl;
using libint2::Shell;
using libint2::Atom;
using libint2::BasisSet;
using libint2::Engine;
using libint2::Operator;
using std::vector;
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> Matrix;
typedef Eigen::DiagonalMatrix<double, Eigen::Dynamic, Eigen::Dynamic> DiagonalMatrix;
struct inp_params{
string scf = "RHF";
string method = "HF";
string basis= "STO-3G";
double scf_convergence = 1e-10;
int do_diis = 1;
int singles = 1;
int spin_mult = 1;
int charge = 0;
string unit = "A";
};
struct scf_results{
bool is_rhf=1;
int nelec, nbasis,no,nv , nalpha,nbeta;
Matrix C,F,Calpha,Cbeta,Falpha,Fbeta;
double scf_energy;
};
struct mp2_results{
Tensor<double> t2_mp2;
double mp2_energy;
};
vector <Atom> read_geometry(string filename , string unit);
inp_params read_input(string inp_file);
double enuc_calc(vector<Atom> atoms);
size_t nbasis(const std::vector<libint2::Shell>& shells);
scf_results RHF(BasisSet obs, vector<libint2::Atom> atoms,int Nbasis, int nelec, inp_params inpParams , double enuc);
scf_results UHF(BasisSet obs, vector<libint2::Atom> atoms,int Nbasis, int nelec, inp_params inpParams , double enuc);
Tensor<double> make_ao_ints(const std::vector<libint2::Shell>& shells);
mp2_results mp2(Tensor <double> eri,scf_results& SCF);
double ccsd(const inp_params& inpParams, const Tensor<double>& eri, const scf_results& SCF,const mp2_results& MP2);
int main(int argc, char* argv[]) {
// INPUT ARGUMENTS
string xyzfile = argv[1];
const auto inpfile = argv[2];
// INPUT PARAMETERS
inp_params inpParams = read_input(inpfile);
cout << "singles " << inpParams.singles<< endl;
cout << "method: " << inpParams.method << endl;
cout << "basis: " <<inpParams.basis << endl;
cout << "scf_convergence: " <<inpParams.scf_convergence << endl;
const std::vector<libint2::Atom> atoms= read_geometry(xyzfile , inpParams.unit);
// Print Geometry
cout<< "molecular geometry :" << "\n";
for (auto n : atoms){
cout<<n.atomic_number << std::setprecision(12) << " \t "
<< n.x << "\t " << n.y<< "\t " << n.z<< "\n";
}
// no. of electrons
int nelec=0;
for(int i=0; i< atoms.size();i++){nelec+= atoms[i].atomic_number;}
nelec -= inpParams.charge;
cout << "No. of electrons = " << nelec << endl;
// nuclear repulsion energy
auto enuc = enuc_calc(atoms);
cout << "Nuclear Repulsion energy = \t" <<enuc <<
" a.u."<< std:: setprecision(15)<< "\n";
// Construct basisset
BasisSet obs(inpParams.basis, atoms);
auto Nbasis = nbasis(obs.shells());
cout <<"Number of basis functions: "
<< Nbasis << std::setprecision(8) << "\n";
// SCF PROCEDURES
scf_results SCF;
//RHF
if(inpParams.scf == "RHF"){
SCF = RHF(obs,atoms,Nbasis,nelec,inpParams ,enuc);
}
//UHF
if(inpParams.scf == "UHF"){
SCF = UHF(obs,atoms,Nbasis,nelec,inpParams ,enuc);
}
if(inpParams.method == "MP2") {
auto eri = make_ao_ints(obs.shells());
mp2_results MP2= mp2(eri,SCF);
cout<< std::setprecision(15) << "MP2 energy: "<< MP2.mp2_energy <<endl;
}
if(inpParams.method == "CCSD"){
auto eri = make_ao_ints(obs.shells());
mp2_results MP2 = mp2(eri,SCF);
cout<< std::setprecision(15) << "MP2 energy: "<< MP2.mp2_energy <<endl;
double ecc = ccsd(inpParams,eri,SCF,MP2);
cout << "Eccsd = " << ecc << endl;
cout << "Total energy = " << SCF.scf_energy + MP2.mp2_energy + ecc << endl;
}
}