/***************************************************************************
                          freeMQM-1.h  -  description
                             -------------------
    begin                : Thu Sept 17 2003
    copyright            : (C) 2003 by Brian J. Keay
    email                : ulisse2k@yahoo.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include "../routines/nrtypes_nr.h"
#include "../routines/Mat4d.h"
#include <vector>
int Nbasis,N,method;
vector<int> ubasis(1),cbasis(1);
int NS,N2S,NP,NL1,NL3,NL6,ND,MSize,NL=0;
double Ratom;
vector<double> Z(1);//Z[] = {2.0,0.0};
const int Nuc = 1;
int atoms = 1;
double Dist,dx,dy,dz;

void ReadBasisSets(vector<double> &Alpha,vector<double> &d,vector<int> &l,vector<int> &m,vector<int> &n,vector<int> &Ncontract,int &functional);
void Smatrix(Mat_O_DP &SMatr,vector<double> &Alpha,vector<int> &l,vector<int> &m,vector<int> &n);
void S_contract(Mat_O_DP &SMatrix,Mat_I_DP &SMatr,vector<double> &Alpha,vector<double> &d,vector<int> &l,vector<int> &m,vector<int> &n,vector<int> &Ncontract);
extern void CalcVMatrix(Mat_O_DP &VMatrix,Mat_I_DP &SMatrix,int MSize);      // A part of Eigen.cpp
extern void DiagMat(Mat_IO_DP &Matrix,vector<double> &Diag,int MSize);              // A part of Eigen.cpp
extern void LowdinDiag(Mat_I_DP &VMatrix,Mat_I_DP &FMatrix,Mat_O_DP &Eigen,vector<double> &Diag, int MSize);  // A part of Eigen.cpp
void KE(Mat_O_DP &Kinet2,vector<double> &Alpha,vector<int> &l,vector<int> &m,vector<int> &n);
double dSMatrix(vector<double> &Alpha,int I, int J, int l1,int m1,int n1,int l2,int m2,int n2);   // Used by KE() 
void e_nucl(Mat_O_DP &Coul2,vector<double> &Alpha,vector<int> &l,vector<int> &m,vector<int> &n);
void CalcHMatrix(Mat_O_DP &HMatrix,Mat_O_DP &KE_Contract,Mat_O_DP &e_nucl_Contract,Mat_I_DP &Kinet2,Mat_I_DP &Coul2,vector<double> &Alpha,vector<double> &d,vector<int> &l,vector<int> &m,vector<int> &n,vector<int> &Ncontract);
void ERI(Mat4D_O_DP &QMatrix2,vector<double> &Alpha,vector<int> &l,vector<int> &m,vector<int> &n);
void ERI_Contract(Mat4D_O_DP &QMatrix,Mat4D_I_DP &QMatrix2,vector<double> &Alpha,vector<double> &d,vector<int> &l,vector<int> &m,vector<int> &n,vector<int> &Ncontract);


void BuildG(Mat_O_DP &GMatrix,Mat_I_DP &DensMat,Mat4D_I_DP &QMatrix);
void BuildG4(Mat_O_DP &GMatrix,Mat_O_DP &JMatrix,Mat_O_DP &KMatrix,Vec_I_DP &C,Mat4D_I_DP &QMatrix);
int DetermineType(int R,int S,int T,int U); 
void BuildDensMat(Mat_O_DP &DensMat,Vec_I_DP &C,Mat_I_DP &SMatrix);
void CalcFockMatrix(Mat_O_DP &FMatrix,Mat_I_DP &HMatrix,Mat_I_DP &GMatrix);
void DiagFock(Vec_O_DP &C,vector<double> &Diag,Mat_I_DP &VMatrix, Mat_I_DP &FMatrix,Mat_I_DP &SMatrix,int MSize);
void DisplayEnergies(double &Energy,double &energyX,double &energyC,vector<double> &Diag,Mat_I_DP &DensMat,Mat_I_DP &HMatrix,
Mat_I_DP &GMatrix,Mat_I_DP &FMatrix,Mat_I_DP &JMatrix,Mat_I_DP &KMatrix,Vec_I_DP &C,Mat_I_DP &KE_Contract,Mat_I_DP &e_nucl_Contract);
//////////////////     Displaying and Checking     ///////////////

void CheckVMatrix(Mat_I_DP &VMatrix,Mat_I_DP &SMatrix);
//////////////////     Miscellaneous functions     ///////////////
double bico(int n, int k);
double f_(int k,int l1,int l2,double PA,double PB);
double F(int m, double X);

//////////////////     Density Functional routines     ///////////////
void R_Integrate(double &energyX,double &energyC,Mat_IO_DP &FMatrix,Vec_I_DP &C,vector<double> &Alpha,vector<double> &d,vector<int> &l,vector<int> &m,vector<int> &n,vector<int> &Ncontract,int functional);
void xyz_Integrate(double &energyX,double &energyC,Mat_IO_DP &FMatrix,Vec_I_DP &C,vector<double> &Alpha,vector<double> &d,vector<int> &l,vector<int> &m,vector<int> &n,vector<int> &Ncontract,int functional);
extern void LD0194(double* x,double* y,double* z,double* w);
double StepS(double mu);     // My addition on 19 April 2003
//////////  xc_b3lyp  23 June 2003  /////////////
extern void xc_rks_blyp(double r,double g,double &f,double &dfdra,double &dfdgaa,double &dfdgab);
extern void x_rks_b88(double r,double g,double &f,double &dfdra,double &dfdgaa);
extern void c_rks_lyp(double r,double g,double &f,double &dfdra,double &dfdgaa,double &dfdgab);
extern void c_rks_vwnrpa(double r,double &f,double &dfdra);
extern void x_rks_slater(double r,double &f,double &dfdra);
//extern void xc_rks_general(double r,double g,double lyp_wt,double vwnrpa_wt,double &f,double &dfdra,double &dfdgaa,double &dfdgab);
extern void xc_rks_general(double r,double g,double LDA_wt,double b88_wt,double lyp_wt,double vwnrpa_wt,double pz81_wt,double pbe_wt,double &f,double &dfdra,double &dfdgaa,double &dfdgab);
extern void xc_uks_blyp(double ra,double rb,double gaa,double gbb,double gab,double &f,double &dfdra,double &dfdrb,double &dfdgaa,double &dfdgbb,double &dfdgab);
extern void c_rks_pz81(double r,double &f,double &dfdra);
//extern void c_uks_pz81(double ra,double rb,double &f,double &dfdra,double &dfdrb);
extern void x_rks_pbe(double r,double g,double &f,double &dfdra,double &dfdgaa);
//extern void x_uks_pbe(double ra,double rb,double gaa,double gbb,double &f,double &dfdra,double &dfdrb,double &dfdgaa,double &dfdgbb);

