├── .gitignore ├── Fortran90 ├── DIIS.f90 ├── HF.f90 ├── HF.py ├── Makefile ├── RHF.f90 ├── UHF.f90 ├── basis.py ├── constants.f90 ├── core.f90 ├── density.f90 ├── dynamics.f90 ├── electronic.f90 ├── energy.f90 ├── factorial.f90 ├── force.f90 ├── gaussian.f90 ├── init.f90 ├── input.f90 ├── kinetic.f90 ├── la.f90 ├── molecules │ ├── CH4.in │ ├── CO.in │ ├── FH.in │ ├── H2.in │ ├── H2O.in │ └── N2.in ├── multipole.f90 ├── nuclear.f90 ├── output.f90 ├── overlap.f90 └── tests │ ├── BOMD_test.f90 │ ├── DIIS_test.f90 │ ├── H2O_test.f90 │ ├── H2_test.f90 │ ├── HeH_test.f90 │ ├── N2.in │ ├── N2_test.f90 │ ├── boys_test.f90 │ ├── classicalMD_test.f90 │ ├── core_test.f90 │ ├── eigs_test.f90 │ ├── electronic_test.f90 │ ├── factorial_test.f90 │ ├── force_test.f90 │ ├── gaussian_test.f90 │ ├── input_test.f90 │ ├── kinetic_test.f90 │ ├── linearsystem_test.f90 │ ├── nuclear_test.f90 │ └── overlap_test.f90 ├── LICENSE ├── Python ├── HF.py ├── RHF.py ├── basis.py ├── integrals.py ├── matrices.py └── molecules.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | 4 | *.mod 5 | 6 | *.out 7 | 8 | *.pyc 9 | 10 | __pycache__/matrices2.cpython-34.pyc 11 | 12 | __pycache__/integrals2.cpython-34.pyc 13 | 14 | *_f.in 15 | 16 | *.x 17 | 18 | *.xyz 19 | 20 | *.in 21 | 22 | *.in 23 | 24 | *.in~ 25 | -------------------------------------------------------------------------------- /Fortran90/HF.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM HF 21 | 22 | USE INPUT 23 | USE RHF 24 | USE UHF 25 | USE FORCES 26 | USE MULTIPOLE 27 | 28 | IMPLICIT NONE 29 | 30 | CHARACTER (len=50) :: fname ! Input filename 31 | INTEGER :: nargs ! Number of input arguments 32 | 33 | INTEGER :: i ! Loop index 34 | 35 | ! System an basis set sizes 36 | INTEGER :: Ne ! Number of electrons 37 | INTEGER :: Nn ! Number of nuclei 38 | INTEGER :: K ! Basis set size 39 | INTEGER :: c ! Contractions (TODO) 40 | 41 | ! System and basis set informations 42 | CHARACTER (len=5) :: calculation ! Calculation 43 | CHARACTER (len=3) :: method ! Method 44 | REAL*8, allocatable, dimension(:,:) :: Rn ! Atomic potisions 45 | INTEGER, allocatable, dimension(:) :: Zn ! Atomic charges 46 | REAL*8, allocatable, dimension(:,:) :: basis_R ! Basis functions' centers 47 | INTEGER, allocatable, dimension(:,:) :: basis_L ! Basis functions' angular momenta 48 | REAL*8, allocatable, dimension(:,:) :: basis_A ! Contraction exponential coefficients 49 | REAL*8, allocatable, dimension(:,:) :: basis_D ! Contaction linear coefficients 50 | INTEGER, allocatable, dimension(:) :: basis_idx ! Basis set atomic index 51 | 52 | REAL*8, allocatable, dimension(:,:) :: P ! Final density matrix 53 | 54 | REAL*8, dimension(3) :: mu ! Dipole 55 | REAL*8, allocatable, dimension(:,:) :: force ! Forces acting on nuclei 56 | 57 | REAL*8 :: final_E ! Total converged energy 58 | 59 | ! -------------------------- 60 | ! READ COMMAND LINE ARGUMENT 61 | ! -------------------------- 62 | 63 | nargs = IARGC() 64 | 65 | IF (nargs .LT. 1) THEN 66 | WRITE(*,*) "NO INPUT FILE!" 67 | CALL EXIT(-1) 68 | END IF 69 | 70 | CALL GETARG(1, fname) 71 | 72 | WRITE(*,*) fname 73 | 74 | ! ------------------------------------------------ 75 | ! LOAD SYSTEM AND BASIS SET INFORMATIONS FROM FILE 76 | ! ------------------------------------------------ 77 | 78 | CALL load(fname,calculation,method,Ne,Nn,K,c,Rn,Zn,basis_R,basis_L,basis_A,basis_D,basis_idx) 79 | 80 | ! ------------------------ 81 | ! TOTAL ENERGY CALCULATION 82 | ! ------------------------ 83 | 84 | IF (calculation .EQ. "SP") THEN 85 | 86 | ALLOCATE(P(K,K)) 87 | 88 | ! ----------------------- 89 | ! RESTRICTED HARTREE-FOCK 90 | ! ----------------------- 91 | IF (method .EQ. "RHF ") THEN 92 | 93 | IF (MODULO(Ne,2) .NE. 0) THEN 94 | WRITE(*,*) "ERROR: Restricted calculation with an odd number of electrons." 95 | CALL EXIT(-1) 96 | END IF 97 | 98 | WRITE(*,*) "----------------------------" 99 | WRITE(*,*) "RHF TOTAL ENERGY CALCULATION" 100 | WRITE(*,*) "----------------------------" 101 | WRITE(*,*) 102 | WRITE(*,*) 103 | WRITE(*,*) 104 | 105 | 106 | 107 | CALL RHF_DIIS(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,Zn,Rn,final_E,P,.TRUE.) 108 | 109 | CALL dipole(K,c,Nn,basis_D,basis_A,basis_L,basis_R,P,Rn,Zn,mu) 110 | 111 | WRITE(*,*) 112 | WRITE(*,*) "Dipole:", mu 113 | 114 | ! ------------------------- 115 | ! UNRESTRICTED HARTREE-FOCK 116 | ! ------------------------- 117 | ELSE IF (method .EQ. "UHF ") THEN 118 | 119 | WRITE(*,*) "----------------------------" 120 | WRITE(*,*) "UHF TOTAL ENERGY CALCULATION" 121 | WRITE(*,*) "----------------------------" 122 | WRITE(*,*) 123 | WRITE(*,*) 124 | WRITE(*,*) 125 | 126 | CALL UHF_SCF(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,Zn,Rn,final_E,P,.TRUE.) 127 | 128 | CALL dipole(K,c,Nn,basis_D,basis_A,basis_L,basis_R,P,Rn,Zn,mu) 129 | 130 | WRITE(*,*) 131 | WRITE(*,*) "Dipole:", mu 132 | 133 | ELSE 134 | WRITE(*,*) "ERROR: Invalid method for single point (SP) calculation." 135 | CALL EXIT(-1) 136 | END IF 137 | 138 | DEALLOCATE(P) 139 | 140 | ! ----------------- 141 | ! FORCE CALCULATION 142 | ! ----------------- 143 | 144 | ELSE IF (calculation .EQ. "FORCE") THEN 145 | 146 | ALLOCATE(force(Nn,3)) 147 | 148 | ! ----------------------- 149 | ! RESTRICTED HARTREE-FOCK 150 | ! ----------------------- 151 | IF (method .EQ. "RHF ") THEN 152 | 153 | IF (MODULO(Ne,2) .NE. 0) THEN 154 | WRITE(*,*) "ERROR: Restricted calculation with an odd number of electrons." 155 | CALL EXIT(-1) 156 | END IF 157 | 158 | WRITE(*,*) "-----------------------" 159 | WRITE(*,*) "FORCE CALCULATION (RHF)" 160 | WRITE(*,*) "-----------------------" 161 | WRITE(*,*) 162 | 163 | CALL force_fd(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,Rn,force,1D-4,method) 164 | 165 | WRITE(*,*) "Forces:" 166 | 167 | DO i = 1, Nn 168 | WRITE(*,*) "Atom", i, force(i,:) 169 | END DO 170 | 171 | 172 | ! ------------------------- 173 | ! UNRESTRICTED HARTREE-FOCK 174 | ! ------------------------- 175 | ELSE IF (method .EQ. "UHF") THEN 176 | 177 | WRITE(*,*) "-----------------------" 178 | WRITE(*,*) "FORCE CALCULATION (UHF)" 179 | WRITE(*,*) "-----------------------" 180 | WRITE(*,*) 181 | 182 | CALL force_fd(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,Rn,force,1D-4,method) 183 | 184 | WRITE(*,*) "Forces:" 185 | 186 | DO i = 1, Nn 187 | WRITE(*,*) "Atom", i, force(i,:) 188 | END DO 189 | 190 | ELSE 191 | WRITE(*,*) "ERROR: Invalid method for force (FORCE) calculation." 192 | CALL EXIT(-1) 193 | END IF 194 | 195 | DEALLOCATE(force) 196 | 197 | ELSE 198 | WRITE(*,*) "ERROR: Invalid calculation." 199 | END IF 200 | 201 | DEALLOCATE(Rn,Zn,basis_R,basis_L,basis_A,basis_D,basis_idx) ! Deallocate allocated memory 202 | 203 | END PROGRAM HF 204 | -------------------------------------------------------------------------------- /Fortran90/HF.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | from basis import * 19 | 20 | import os 21 | import sys 22 | 23 | class Atom: 24 | """ 25 | Class representing an atom. 26 | """ 27 | 28 | def __init__(self,name,R,Z,orbitals): 29 | """ 30 | Initializer for ATOM 31 | 32 | INPUT: 33 | NAME: Name of the element 34 | R: Position (cartesian coordinates, atomic units) 35 | Z: Atomic charge 36 | ORBITALS: list of orbitals for this atom 37 | """ 38 | 39 | self.name = name 40 | self.R = R 41 | self.orbitals = orbitals 42 | self.Z = Z 43 | 44 | class STO3G(): 45 | """ 46 | STO-3G minimal basis set. 47 | """ 48 | def __init__(self,atoms): 49 | """ 50 | Initializer for STO3G 51 | 52 | INPUT: 53 | ATOMS: list of atoms 54 | 55 | Source 56 | 57 | Modern Quantum Chemistry 58 | Szabo and Ostlund 59 | Dover 60 | 1989 61 | """ 62 | 63 | # Exponential coefficients for the Gaussian orbitals 64 | self.zeta1 = { "H":1.24, 65 | "He":1.6875, 66 | "Li":2.69, 67 | "Be":3.68, 68 | "B":4.68, 69 | "C":5.67, 70 | "N":6.67, 71 | "O":7.66, 72 | "F":8.65} 73 | self.zeta2 = { "Li":0.75, 74 | "Be":1.10, 75 | "B":1.45, 76 | "C":1.72, 77 | "N":1.95, 78 | "O":2.25, 79 | "F":2.55} 80 | 81 | self.STO3G = [] 82 | 83 | atom_idx = 0 # Atom index (start from 1) 84 | 85 | for a in atoms: # For every atom 86 | 87 | atom_idx += 1 88 | 89 | for o in a.orbitals: # For every atomic orbital 90 | if o == "1s": 91 | a1 = 0.109818 * self.zeta1[a.name]**2 92 | a2 = 0.405771 * self.zeta1[a.name]**2 93 | a3 = 2.22766 * self.zeta1[a.name]**2 94 | d1 = 0.444635 95 | d2 = 0.535328 96 | d3 = 0.154329 97 | 98 | self.STO3G.append({ "AOn":a.name,# 99 | "AOt":o, 100 | "Aidx":atom_idx,# 101 | "R":a.R,# 102 | "lx":0,# 103 | "ly":0,# 104 | "lz":0,# 105 | "a":(a1,a2,a3),# 106 | "d":(d1,d2,d3)}) 107 | 108 | if o == "2s": 109 | a1 = 0.0751386 * self.zeta2[a.name]**2 110 | a2 = 0.231031 * self.zeta2[a.name]**2 111 | a3 = 0.994203 * self.zeta2[a.name]**2 112 | d1 = 0.700115 113 | d2 = 0.399513 114 | d3 = -0.0999672 115 | 116 | self.STO3G.append({ "AOn":a.name, 117 | "AOt":o, 118 | "Aidx":atom_idx, 119 | "R":a.R, 120 | "lx":0, 121 | "ly":0, 122 | "lz":0, 123 | "a":(a1,a2,a3), 124 | "d":(d1,d2,d3)}) 125 | 126 | if o == "2p": 127 | a1 = 0.0751386 * self.zeta2[a.name]**2 128 | a2 = 0.231031 * self.zeta2[a.name]**2 129 | a3 = 0.994203 * self.zeta2[a.name]**2 130 | d1 = 0.391957 131 | d2 = 0.607684 132 | d3 = 0.1559163 133 | 134 | self.STO3G.append({ "AOn":a.name, 135 | "AOt":o, 136 | "Aidx":atom_idx, 137 | "R":a.R, 138 | "lx":1, 139 | "ly":0, 140 | "lz":0, 141 | "a":(a1,a2,a3), 142 | "d":(d1,d2,d3)}) 143 | self.STO3G.append({ "AOn":a.name, 144 | "AOt":o, 145 | "Aidx":atom_idx, 146 | "R":a.R, 147 | "lx":0, 148 | "ly":1, 149 | "lz":0, 150 | "a":(a1,a2,a3), 151 | "d":(d1,d2,d3)}) 152 | self.STO3G.append({ "AOn":a.name, 153 | "AOt":o, 154 | "Aidx":atom_idx, 155 | "R":a.R, 156 | "lx":0, 157 | "ly":0, 158 | "lz":1, 159 | "a":(a1,a2,a3), 160 | "d":(d1,d2,d3)}) 161 | 162 | self.K = len(self.STO3G) 163 | 164 | def basis(self): 165 | """ 166 | Return the basis set. 167 | """ 168 | 169 | return self.STO3G 170 | 171 | def info(self): 172 | """ 173 | Print informations about the bais set. 174 | """ 175 | print("########################") 176 | print("STO-3G MINIMAL BASIS SET") 177 | print("########################\n") 178 | 179 | for b in self.STO3G: 180 | print(b["AOn"] + " orbital:") 181 | print(" " + b["AOt"] + ":") 182 | print(" R = ", b["R"]) 183 | print(" lx = " + str(b["lx"])) 184 | print(" ly = " + str(b["ly"])) 185 | print(" lz = " + str(b["lz"])) 186 | print(" alpha = ", b["a"]) 187 | print(" d = ", b["d"],'\n') 188 | 189 | 190 | class IO: 191 | """ 192 | Prepare input file for Fortran program. 193 | """ 194 | def __init__(self,fname): 195 | 196 | # Open input file 197 | try: 198 | self.ifile = open(fname,'r') 199 | except IOError: 200 | print("ERROR: Impossible to open the input file.") 201 | sys.exit(-1) 202 | 203 | # Create name for the output file 204 | fnameout = os.path.splitext(fname)[0] + "_f.in" 205 | 206 | # Open output file 207 | try: 208 | self.ofile = open(fnameout, 'w') # Open output file (fortran input file) 209 | except IOError: 210 | print("ERROR: Impossible to open the output file.") 211 | sys.exit(-1) 212 | 213 | # Occupied orbitals 214 | self.orbitals = { "H" : ["1s"], 215 | "He" : ["1s"], 216 | "C" : ["1s","2s","2p"], 217 | "N" : ["1s","2s","2p"], 218 | "O" : ["1s","2s","2p"], 219 | "F" : ["1s","2s","2p"]} 220 | 221 | # Nuclear charges 222 | self.charges = { "H" : 1, 223 | "He" : 2, 224 | "C" : 6, 225 | "N" : 7, 226 | "O" : 8, 227 | "F" : 9 } 228 | 229 | self.read() # Read from file 230 | 231 | def __del__(self): 232 | self.ifile.close() # Close file input file 233 | self.ofile.close() # Close output file 234 | 235 | def read(self): 236 | 237 | self.calculation = self.ifile.readline().strip() # Calculation (SP, FORCE, BOMD) 238 | 239 | if self.calculation not in ["SP","FORCE"]: 240 | print("ERROR: This calculation is not implemented.") 241 | sys.exit(-1) 242 | 243 | line = self.ifile.readline().strip() 244 | 245 | self.method = line.split('/')[0] # Method (RHF/UHF) 246 | 247 | # Check validity of method 248 | if self.method not in ["RHF","UHF"]: 249 | print("ERROR: This method is not implemented.") 250 | sys.exit(-1) 251 | 252 | self.bsname = line.split('/')[-1] # Basis set name 253 | 254 | self.atoms = [] # List of atoms composing the system 255 | 256 | self.Ne = int(self.ifile.readline().strip()) # Number of electrons 257 | 258 | if (self.method == "RHF" and self.Ne % 2 != 0): 259 | print("ERROR: Odd number of electrons for a RHF calculation.") 260 | sys.exit(-1) 261 | 262 | self.Nn = 0 # Number of nuclei 263 | 264 | for line in self.ifile: 265 | name, rx, ry, rz = line.split() 266 | 267 | a = Atom(name,[rx,ry,rz],self.charges[name],self.orbitals[name]) 268 | 269 | self.atoms.append(a) 270 | 271 | self.Nn += 1 272 | 273 | 274 | if self.bsname == "STO-3G": 275 | self.bs = STO3G(self.atoms) 276 | self.contractions = 3 277 | else: 278 | print("ERROR: This basis set is not implemented.") 279 | sys.exit(-1) 280 | 281 | # TODO: Check that the number of electrons can be contained in the orbitals 282 | 283 | def fortran_input(self): 284 | self.ofile.write(self.calculation + os.linesep) # Calculation 285 | self.ofile.write(self.method + os.linesep) # Method 286 | self.ofile.write(str(self.Ne) + os.linesep) # Number of electrons 287 | self.ofile.write(str(self.Nn) + os.linesep) # Number of nuclei 288 | self.ofile.write(str(self.bs.K) + os.linesep) # Number of basis set 289 | self.ofile.write(str(self.contractions) + os.linesep) # Number of contractions 290 | 291 | for a in self.atoms: 292 | Rx = "%+.10e" % float(a.R[0]) 293 | Ry = "%+.10e" % float(a.R[1]) 294 | Rz = "%+.10e" % float(a.R[2]) 295 | 296 | Z = "%i" % a.Z 297 | 298 | line = Rx + ' ' + Ry + ' ' + Rz + ' ' + Z +os.linesep 299 | 300 | self.ofile.write(line) 301 | 302 | basis = self.bs.basis() 303 | 304 | for b in basis: 305 | # Basis function center 306 | Rx = "%+.10e" % float(b["R"][0]) 307 | Ry = "%+.10e" % float(b["R"][1]) 308 | Rz = "%+.10e" % float(b["R"][2]) 309 | 310 | # Basis function angular momenta 311 | lx = "%i" % b["lx"] 312 | ly = "%i" % b["ly"] 313 | lz = "%i" % b["lz"] 314 | 315 | line = Rx + ' ' + Ry + ' ' + Rz + ' ' + lx + ' ' + ly + ' ' + lz 316 | 317 | coeff_a = '' 318 | 319 | for ca in b["a"]: 320 | coeff_a += ' ' + "%+.10e" % float(ca) 321 | 322 | coeff_d = '' 323 | 324 | for cd in b["d"]: 325 | coeff_d += ' ' + "%+.10e" % float(cd) 326 | 327 | line += coeff_a + coeff_d 328 | 329 | line += ' ' + "%i" % b["Aidx"] + os.linesep 330 | 331 | self.ofile.write(line) 332 | 333 | self.ofile.flush() # Ensure the content is written on the file 334 | 335 | 336 | if __name__ == "__main__": 337 | fin = sys.argv[1] # Python input file 338 | 339 | io = IO(fin) # Create input/output object 340 | io.fortran_input() # Create Fortran input file 341 | 342 | ffin = os.path.splitext(fin)[0] + "_f.in" # Fortran input file name 343 | 344 | os.system("./HF.x " + ffin) # Call Fortran Hartree-Fock program 345 | 346 | os.system("rm " + ffin) # Remove input for Fortran program 347 | -------------------------------------------------------------------------------- /Fortran90/Makefile: -------------------------------------------------------------------------------- 1 | COMP = gfortran 2 | FLAGS = -Wall -O3 3 | LIBS = -L/opt/local/lib/ -lslatec -llapack -lblas -latlas 4 | 5 | ######## 6 | # MAIN # 7 | ######## 8 | 9 | HF: 10 | $(COMP) $(FLAGS) $(LIBS) input.f90 output.f90 constants.f90 factorial.f90 gaussian.f90 la.f90 overlap.f90 multipole.f90 kinetic.f90 nuclear.f90 core.f90 electronic.f90 density.f90 energy.f90 init.f90 DIIS.f90 RHF.f90 UHF.f90 force.f90 HF.f90 -o HF.x 11 | 12 | 13 | ################################ 14 | 15 | dynamics: BOMD 16 | 17 | molecules: H2Test HeHTest H2OTest 18 | 19 | tests: factorialTest gaussianTest 20 | 21 | BOMD: 22 | $(COMP) $(FLAGS) $(LIBS) input.f90 output.f90 constants.f90 factorial.f90 gaussian.f90 la.f90 overlap.f90 multipole.f90 kinetic.f90 nuclear.f90 core.f90 electronic.f90 density.f90 energy.f90 init.f90 DIIS.f90 RHF.f90 UHF.f90 force.f90 dynamics.f90 tests/BOMD_test.f90 -o BOMD.x 23 | 24 | factorialTest: 25 | $(COMP) $(FLAGS) $(LIBS) factorial.f90 tests/factorial_test.f90 -o factorialTest.x 26 | 27 | gaussianTest: 28 | $(COMP) $(FLAGS) $(LIBS) factorial.f90 gaussian.f90 tests/gaussian_test.f90 -o gaussianTest.x 29 | 30 | H2Test: 31 | $(COMP) $(FLAGS) $(LIBS) constants.f90 factorial.f90 gaussian.f90 overlap.f90 kinetic.f90 nuclear.f90 core.f90 electronic.f90 utils.f90 density.f90 energy.f90 RHF.f90 input.f90 tests/H2_test.f90 -o H2Test.x 32 | 33 | HeHTest: 34 | $(COMP) $(FLAGS) $(LIBS) constants.f90 factorial.f90 gaussian.f90 overlap.f90 kinetic.f90 nuclear.f90 core.f90 electronic.f90 utils.f90 density.f90 energy.f90 RHF.f90 input.f90 tests/HeH_test.f90 -o HeHTest.x 35 | 36 | H2OTest: 37 | $(COMP) $(FLAGS) $(LIBS) constants.f90 factorial.f90 gaussian.f90 overlap.f90 kinetic.f90 nuclear.f90 core.f90 electronic.f90 utils.f90 density.f90 energy.f90 RHF.f90 input.f90 tests/H2O_test.f90 -o H2OTest.x 38 | 39 | clean: 40 | rm -f *.mod 41 | 42 | cleanall: 43 | rm -f *.mod *.x 44 | -------------------------------------------------------------------------------- /Fortran90/basis.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | 19 | class Atom: 20 | """ 21 | Class representing an atom. 22 | """ 23 | 24 | def __init__(self,name,R,Z,orbitals): 25 | """ 26 | Initializer for ATOM 27 | 28 | INPUT: 29 | NAME: Name of the element 30 | R: Position (cartesian coordinates, atomic units) 31 | Z: Atomic charge 32 | ORBITALS: list of orbitals for this atom 33 | """ 34 | 35 | self.name = name 36 | self.R = R 37 | self.orbitals = orbitals 38 | self.Z = Z 39 | 40 | class STO3G(): 41 | """ 42 | STO-3G minimal basis set. 43 | """ 44 | def __init__(self,atoms): 45 | """ 46 | Initializer for STO3G 47 | 48 | INPUT: 49 | ATOMS: list of atoms 50 | 51 | Source 52 | 53 | Modern Quantum Chemistry 54 | Szabo and Ostlund 55 | Dover 56 | 1989 57 | """ 58 | 59 | # Exponential coefficients for the Gaussian orbitals 60 | self.zeta1 = { "H":1.24, 61 | "He":2.0925, 62 | "Li":2.69, 63 | "Be":3.68, 64 | "B":4.68, 65 | "C":5.67, 66 | "N":6.67, 67 | "O":7.66, 68 | "F":8.65} 69 | self.zeta2 = { "Li":0.75, 70 | "Be":1.10, 71 | "B":1.45, 72 | "C":1.72, 73 | "N":1.95, 74 | "O":2.25, 75 | "F":2.55} 76 | 77 | self.STO3G = [] 78 | 79 | for a in atoms: # For every atom 80 | for o in a.orbitals: # For every atomic orbital 81 | if o == "1s": 82 | a1 = 0.109818 * self.zeta1[a.name]**2 83 | a2 = 0.405771 * self.zeta1[a.name]**2 84 | a3 = 2.22766 * self.zeta1[a.name]**2 85 | d1 = 0.444635 86 | d2 = 0.535328 87 | d3 = 0.154329 88 | 89 | self.STO3G.append({ "AOn":a.name,# 90 | "AOt":o,# 91 | "R":a.R,# 92 | "lx":0,# 93 | "ly":0,# 94 | "lz":0,# 95 | "a":(a1,a2,a3),# 96 | "d":(d1,d2,d3)}) 97 | 98 | if o == "2s": 99 | a1 = 0.0751386 * self.zeta2[a.name]**2 100 | a2 = 0.231031 * self.zeta2[a.name]**2 101 | a3 = 0.994203 * self.zeta2[a.name]**2 102 | d1 = 0.700115 103 | d2 = 0.399513 104 | d3 = -0.0999672 105 | 106 | self.STO3G.append({ "AOn":a.name, 107 | "AOt":o, 108 | "R":a.R, 109 | "lx":0, 110 | "ly":0, 111 | "lz":0, 112 | "a":(a1,a2,a3), 113 | "d":(d1,d2,d3)}) 114 | 115 | if o == "2p": 116 | a1 = 0.0751386 * self.zeta2[a.name]**2 117 | a2 = 0.231031 * self.zeta2[a.name]**2 118 | a3 = 0.994203 * self.zeta2[a.name]**2 119 | d1 = 0.391957 120 | d2 = 0.607684 121 | d3 = 0.1559163 122 | 123 | self.STO3G.append({ "AOn":a.name, 124 | "AOt":o, 125 | "R":a.R, 126 | "lx":1, 127 | "ly":0, 128 | "lz":0, 129 | "a":(a1,a2,a3), 130 | "d":(d1,d2,d3)}) 131 | self.STO3G.append({ "AOn":a.name, 132 | "AOt":o, 133 | "R":a.R, 134 | "lx":0, 135 | "ly":1, 136 | "lz":0, 137 | "a":(a1,a2,a3), 138 | "d":(d1,d2,d3)}) 139 | self.STO3G.append({ "AOn":a.name, 140 | "AOt":o, 141 | "R":a.R, 142 | "lx":0, 143 | "ly":0, 144 | "lz":1, 145 | "a":(a1,a2,a3), 146 | "d":(d1,d2,d3)}) 147 | 148 | self.K = len(self.STO3G) 149 | 150 | def basis(self): 151 | """ 152 | Return the basis set. 153 | """ 154 | 155 | return self.STO3G 156 | 157 | def info(self): 158 | """ 159 | Print informations about the bais set. 160 | """ 161 | print("########################") 162 | print("STO-3G MINIMAL BASIS SET") 163 | print("########################\n") 164 | 165 | for b in self.STO3G: 166 | print(b["AOn"] + " orbital:") 167 | print(" " + b["AOt"] + ":") 168 | print(" R = ", b["R"]) 169 | print(" lx = " + str(b["lx"])) 170 | print(" ly = " + str(b["ly"])) 171 | print(" lz = " + str(b["lz"])) 172 | print(" alpha = ", b["a"]) 173 | print(" d = ", b["d"],'\n') 174 | 175 | 176 | if __name__ == "__main__": 177 | 178 | u""" 179 | Results compared with 180 | 181 | Modern Quantum Chemistry 182 | Szabo and Ostlund 183 | Dover 184 | 1989 185 | 186 | and 187 | 188 | The Mathematica Journal 189 | Evaluation of Gaussian Molecular Integrals 190 | I. Overlap Integrals 191 | Minhhuy Hô and Julio Manuel Hernández-Pérez 192 | 2012 193 | """ 194 | 195 | # HeH+ 196 | atoms = [Atom("H",(0,0,0),["1s"]),Atom("He",(0,0,1.4),["1s"])] 197 | 198 | # Create the basis set 199 | sto3g = STO3G(atoms) 200 | 201 | # Display informations 202 | sto3g.info() 203 | 204 | print("\n\n\n\n\n") 205 | 206 | # H2O 207 | atoms = [ Atom("H",(0,+1.43233673,-0.96104039),["1s"]), 208 | Atom("H",(0,-1.43233673,-0.96104039),["1s"]), 209 | Atom("O",(0,0,0.24026010),["1s","2s","2p"])] 210 | 211 | # Create the basis set 212 | sto3g = STO3G(atoms) 213 | 214 | # Display informations 215 | sto3g.info() 216 | -------------------------------------------------------------------------------- /Fortran90/constants.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE CONSTANTS 21 | 22 | IMPLICIT NONE 23 | 24 | REAL*8, PARAMETER :: PI = 4. * ATAN(1.) ! PI 25 | 26 | END MODULE CONSTANTS 27 | -------------------------------------------------------------------------------- /Fortran90/core.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE CORE 21 | 22 | USE KINETIC, only: T_kinetic 23 | USE NUCLEAR, only: V_nuclear 24 | USE OUTPUT, only: print_real_matrix 25 | 26 | IMPLICIT NONE 27 | 28 | CONTAINS 29 | 30 | SUBROUTINE H_core(Kf,c,Nn,basis_D,basis_A,basis_L,basis_R,Rn,Zn,H,verbose) 31 | 32 | ! TODO Allow flexibility for basis sets other than STO-3G 33 | INTEGER, intent(in) :: c ! Number of contractions per basis function 34 | 35 | LOGICAL, intent(in):: verbose 36 | 37 | ! INPUT 38 | INTEGER, intent(in) :: Kf ! Number of basis functions 39 | INTEGER, intent(in) :: Nn ! Total number of nuclei 40 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Basis set niclear positions 41 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Basis set angular momenta 42 | REAL*8, dimension(Kf,3), intent(in) :: basis_D ! Basis set contraction coefficients 43 | REAL*8, dimension(Kf,3), intent(in) :: basis_A ! Basis set exponential contraction coefficients 44 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 45 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges (> 0) 46 | 47 | ! INTERMEDIATE VARIABLE 48 | REAL*8, dimension(Kf,Kf) :: V ! Matrix storing total potential components 49 | REAL*8, dimension(Kf,Kf) :: M ! Matrix storing one-atom potential conponents 50 | INTEGER :: i ! Loop index 51 | 52 | ! OUTPUT 53 | REAL*8, dimension(Kf,Kf), intent(out) :: H ! Core Hamiltonian 54 | 55 | H(:,:) = 0.0D0 56 | 57 | V(:,:) = 0.0D0 58 | 59 | CALL T_kinetic(Kf,c,basis_D,basis_A,basis_L,basis_R,H) 60 | 61 | IF (verbose) THEN 62 | WRITE(*,*) "Kinetic energy matrix T:" 63 | CALL print_real_matrix(Kf,Kf,H) 64 | END IF 65 | 66 | DO i = 1, Nn 67 | M(:,:) = 0.0D0 68 | 69 | CALL V_nuclear(Kf,c,basis_D,basis_A,basis_L,basis_R,M,Rn(i,1:3),Zn(i)) 70 | 71 | IF (verbose) THEN 72 | WRITE(*,*) "Nuclear attraction matrix V:", i 73 | CALL print_real_matrix(Kf,Kf,M) 74 | END IF 75 | 76 | V = V + M 77 | END DO 78 | 79 | IF (verbose) THEN 80 | WRITE(*,*) "Total nuclear attraction matrix V:", i 81 | CALL print_real_matrix(Kf,Kf,V) 82 | END IF 83 | 84 | H = H + V 85 | 86 | END SUBROUTINE H_core 87 | 88 | SUBROUTINE density() 89 | 90 | END SUBROUTINE density 91 | 92 | END MODULE CORE 93 | -------------------------------------------------------------------------------- /Fortran90/density.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE DENSITY 21 | 22 | IMPLICIT NONE 23 | 24 | CONTAINS 25 | 26 | ! -------------- 27 | ! DENSITY MATRIX 28 | ! -------------- 29 | SUBROUTINE P_density(Kf,Ne,C,P) 30 | ! ---------------------------------------------------------- 31 | ! Compute the density matrix from the optimized coefficients 32 | ! ---------------------------------------------------------- 33 | ! 34 | ! Source: 35 | ! Szabo and Ostlund 36 | ! Modern Quantum Chemistry 37 | ! Doever 38 | ! 1989 39 | ! 40 | ! ----------------------------------------------------------- 41 | 42 | IMPLICIT NONE 43 | 44 | ! INPUT 45 | INTEGER, intent(in) :: Kf ! Number of basis functions 46 | INTEGER, intent(in) :: Ne ! Number of electrons 47 | REAL*8, dimension(Kf,Kf), intent(in) :: C ! Coefficients matrix 48 | 49 | ! INTERMEDIATE VARIABLES 50 | INTEGER :: i, j, k ! Loop coefficients 51 | 52 | ! OUTPUT 53 | REAL*8, dimension(Kf,Kf), intent(out) :: P ! Density matrix 54 | 55 | P(:,:) = 0.0D0 56 | 57 | DO i = 1, Kf 58 | DO j = 1, Kf 59 | DO k = 1, Ne / 2 ! TODO Only in RHF 60 | P(i,j) = P(i,j) + 2.0D0 * C(i,k) * C(j,k) 61 | END DO 62 | END DO 63 | END DO 64 | 65 | END SUBROUTINE P_density 66 | 67 | ! ------------------- 68 | ! SPIN DENSITY MATRIX 69 | ! ------------------- 70 | SUBROUTINE P_density_spin(Kf,Ne,C,P) 71 | ! ---------------------------------------------------------- 72 | ! Compute the density matrix from the optimized coefficients 73 | ! ---------------------------------------------------------- 74 | ! 75 | ! Source: 76 | ! Szabo and Ostlund 77 | ! Modern Quantum Chemistry 78 | ! Doever 79 | ! 1989 80 | ! 81 | ! ----------------------------------------------------------- 82 | 83 | IMPLICIT NONE 84 | 85 | ! INPUT 86 | INTEGER, intent(in) :: Kf ! Number of basis functions 87 | INTEGER, intent(in) :: Ne ! Number of electrons 88 | REAL*8, dimension(Kf,Kf), intent(in) :: C ! Coefficients matrix 89 | 90 | ! INTERMEDIATE VARIABLES 91 | INTEGER :: i, j, k ! Loop coefficients 92 | 93 | ! OUTPUT 94 | REAL*8, dimension(Kf,Kf), intent(out) :: P ! Density matrix 95 | 96 | P(:,:) = 0.0D0 97 | 98 | DO i = 1, Kf 99 | DO j = 1, Kf 100 | DO k = 1, Ne 101 | P(i,j) = P(i,j) + C(i,k) * C(j,k) 102 | END DO 103 | END DO 104 | END DO 105 | 106 | END SUBROUTINE P_density_spin 107 | 108 | ! ------------------------- 109 | ! DENSITY MATRIX DIFFERENCE 110 | ! ------------------------- 111 | FUNCTION delta_P(Kf,Pold,Pnew) result(delta) 112 | ! ---------------------------------------------------------- 113 | ! Compute density matrix difference as convergence criterion 114 | ! ---------------------------------------------------------- 115 | ! 116 | ! Source: 117 | ! A. Szabo and N. S. Ostlund 118 | ! Modern Quantum Chemistry 119 | ! Dover 120 | ! 1996 121 | ! 122 | ! ----------------------------------------------------------- 123 | 124 | IMPLICIT NONE 125 | 126 | ! INPUT 127 | INTEGER, intent(in) :: Kf ! Basis set size 128 | REAL*8, dimension(Kf,Kf), intent(in) :: Pold ! Old density matrix 129 | REAL*8, dimension(Kf,Kf), intent(in) :: Pnew ! New density matix 130 | 131 | ! INTERMEDIATE VARIABLES 132 | INTEGER :: i, j 133 | 134 | ! OUTPUT 135 | REAL*8 :: delta ! Sum of matrix elements square differences 136 | 137 | delta = 0 138 | 139 | 140 | DO i = 1, Kf 141 | DO j = 1, Kf 142 | delta = delta + (Pold(i,j)-Pnew(i,j))**2 143 | END DO 144 | END DO 145 | 146 | delta = DSQRT(delta / Kf**2) 147 | 148 | END FUNCTION delta_P 149 | 150 | END MODULE DENSITY 151 | -------------------------------------------------------------------------------- /Fortran90/dynamics.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE DYNAMICS 21 | ! ---------------------------------------------------------- 22 | ! DYNAMICS 23 | ! ---------------------------------------------------------- 24 | ! 25 | ! Performs classical and Born-Oppenheimer molecular dynamics 26 | ! using the velocity Verlet integration algorithm. 27 | ! 28 | !----------------------------------------------------------- 29 | 30 | USE FORCES, only: force_fd 31 | USE RHF, only: RHF_SCF 32 | 33 | IMPLICIT NONE 34 | 35 | CONTAINS 36 | 37 | ! -------------------- 38 | ! POSITION PROPAGATION 39 | ! -------------------- 40 | SUBROUTINE position_prop(Nn,mass,pos,vel,force_t,dt) 41 | ! ---------------------------------------------------------------------- 42 | ! Update the position of every particle according to the force at time t 43 | ! ---------------------------------------------------------------------- 44 | 45 | IMPLICIT NONE 46 | 47 | ! INPUT 48 | INTEGER, intent(in) :: Nn ! Number of nuclei (number of moving particles) 49 | REAL*8, dimension(Nn) :: mass ! Nuclear masses 50 | REAL*8, intent(in) :: dt ! Integration time step 51 | REAL*8, dimension(Nn,3), intent(in) :: force_t ! Force acting on nuclei (PES gradient) at time t 52 | REAL*8, dimension(Nn,3), intent(in) :: vel ! Nuclear velocities at time t 53 | 54 | ! INPUT/OUTPUT 55 | REAL*8, dimension(Nn,3), intent(inout) :: pos ! Nuclear positions 56 | 57 | ! INTERMEDIATE VARIABLES 58 | INTEGER :: i ! Loop index 59 | 60 | ! Update positions of all atoms 61 | DO i = 1, Nn 62 | pos(i,:) = pos(i,:) + vel(i,:) * dt + 0.5D0 * force_t(i,:) / mass(i) * dt**2.0D0 63 | END DO 64 | 65 | END SUBROUTINE 66 | 67 | ! -------------------- 68 | ! VELOCITY PROPAGATION 69 | ! -------------------- 70 | SUBROUTINE velocity_prop(Nn,mass,vel,force_t,force_tdt,dt) 71 | 72 | IMPLICIT NONE 73 | 74 | ! INPUT 75 | INTEGER, intent(in) :: Nn ! Number of nuclei (number of moving particles) 76 | REAL*8, dimension(Nn) :: mass ! Nuclear masses 77 | REAL*8, intent(in) :: dt ! Integration time step 78 | REAL*8, dimension(Nn,3), intent(in) :: force_t ! Force acting on nuclei (PES gradient) at time t 79 | REAL*8, dimension(Nn,3), intent(in) :: force_tdt ! Force acting on nuclei (PES gradient) at time t+dt 80 | 81 | ! INPUT/OUTPUT 82 | REAL*8, dimension(Nn,3), intent(inout) :: vel ! Nuclear velocities 83 | 84 | ! INTERMEDIATE VARIABLES 85 | INTEGER :: i ! Loop index 86 | 87 | ! Update velocities of all atoms 88 | DO i = 1, Nn 89 | vel(i,:) = vel(i,:) + 0.5D0 * (force_t(i,:) + force_tdt(i,:)) / mass(i) * dt 90 | END DO 91 | 92 | END SUBROUTINE 93 | 94 | 95 | ! ---------------------------- 96 | ! CLASSICAL MOLECULAR DYNAMICS 97 | ! ---------------------------- 98 | SUBROUTINE classical_step(Nn,mass,pos,vel,force_t,dU,dt) 99 | 100 | IMPLICIT NONE 101 | 102 | ! INPUT 103 | INTEGER, intent(in) :: Nn ! Number of nuclei (number of moving particles) 104 | REAL*8, dimension(Nn) :: mass ! Nuclear masses 105 | REAL*8, intent(in) :: dt ! Integration time step 106 | 107 | ! INPUT/OUTPUT 108 | REAL*8, dimension(Nn,3), intent(inout) :: pos ! Nuclear positions 109 | REAL*8, dimension(Nn,3), intent(inout) :: vel ! Nuclear velocities 110 | REAL*8, dimension(Nn,3), intent(inout) :: force_t ! Force acting on nuclei (PES gradient) at time t 111 | 112 | ! INTERMEDIATE VARIABLES 113 | REAL*8, dimension(Nn,3) :: force_tdt ! Force acting on nuclei (PES gradient) at time t+dt 114 | 115 | ! For classical MD we need an analytical description of the PES 116 | INTERFACE 117 | FUNCTION dU(Nn,pos) 118 | INTEGER, intent(in) :: Nn 119 | REAL*8, dimension(Nn,3), intent(in) :: pos 120 | REAL*8, dimension(Nn,3) :: dU 121 | END FUNCTION 122 | END INTERFACE 123 | 124 | ! Update positions 125 | CALL position_prop(Nn,mass,pos,vel,force_t,dt) ! Use forces at time t 126 | 127 | ! Compute forces at time t+dt 128 | force_tdt = (-1) * dU(Nn,pos) ! POS has been updated by POSITION_PROP 129 | 130 | ! Update velocities 131 | CALL velocity_prop(Nn,mass,vel,force_t,force_tdt,dt) 132 | 133 | force_t = force_tdt ! Store the force at t+dt for the next step 134 | 135 | END SUBROUTINE classical_step 136 | 137 | ! ----------------------------------- 138 | ! BORN-OPPENHEIMER MOLECULAR DYNAMICS 139 | ! ----------------------------------- 140 | SUBROUTINE BO_step(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,mass,pos,vel,force_t,dt,method) 141 | ! ---------------------------------------------------------------------------------------------------------- 142 | ! Perform a step of Born-Oppenheimer Molecular Dynamics using Hartree-Fock solution of Schrödinger equation. 143 | ! ---------------------------------------------------------------------------------------------------------- 144 | 145 | IMPLICIT NONE 146 | 147 | ! INPUT 148 | INTEGER, intent(in) :: Kf ! Basis set size 149 | INTEGER, intent(in) :: c ! Number of contractions 150 | INTEGER, intent(in) :: Ne ! Number of electrons 151 | INTEGER, intent(in) :: Nn ! Number of nuclei 152 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Angular momenta of basis set Gaussians 153 | REAL*8, dimension(Kf,c), intent(in) :: basis_D, basis_A ! Basis set coefficients 154 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges 155 | INTEGER, dimension(Kf), intent(in) :: basis_idx ! Basis set atom index (link between basis set function and atoms) 156 | REAL*8, dimension(Nn) :: mass ! Nuclear masses 157 | REAL*8, intent(in) :: dt ! Integration time step 158 | CHARACTER (len=3), intent(in) :: method ! Total energy calculation method (RHF, UHF) 159 | 160 | ! INPUT/OUTPUT 161 | REAL*8, dimension(Nn,3), intent(inout) :: pos ! Nuclear positions 162 | REAL*8, dimension(Nn,3), intent(inout) :: vel ! Nuclear velocities 163 | REAL*8, dimension(Nn,3), intent(inout) :: force_t ! Force acting on nuclei (PES gradient) at time t 164 | REAL*8, dimension(Kf,3), intent(inout) :: basis_R ! Basis set centers 165 | 166 | ! INTERMEDIATE VARIABLES 167 | REAL*8, dimension(Nn,3) :: force_tdt ! Force acting on nuclei (PES gradient) at time t+dt 168 | INTEGER i, idx 169 | 170 | ! PARAMETERS 171 | REAL*8, PARAMETER :: delta = 1e-6 ! Finite difference step for forces 172 | 173 | ! ------------------------ 174 | ! Update nuclear position 175 | ! ------------------------ 176 | 177 | CALL position_prop(Nn,mass,pos,vel,force_t,dt) ! Use forces at time t 178 | 179 | ! ----------------------------------------------------------- 180 | ! Update basis set centers according to new nuclear positions 181 | ! ----------------------------------------------------------- 182 | 183 | DO i = 1, Kf 184 | idx = basis_idx(i) 185 | 186 | basis_R(i,:) = pos(idx,:) ! Displace basis set center at new atomic position 187 | END DO 188 | 189 | ! --------------------------------------- 190 | ! Compute forces at new nuclear positions 191 | ! --------------------------------------- 192 | 193 | CALL force_fd(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,pos,force_tdt,delta,method) 194 | 195 | ! ------------------------- 196 | ! Update nuclear velocities 197 | ! ------------------------- 198 | 199 | CALL velocity_prop(Nn,mass,vel,force_t,force_tdt,dt) 200 | 201 | ! ---------------------------------- 202 | ! Store new forces for the next step 203 | ! ---------------------------------- 204 | 205 | force_t = force_tdt ! Store the force at t+dt for the next step 206 | 207 | END SUBROUTINE BO_step 208 | 209 | END MODULE DYNAMICS 210 | -------------------------------------------------------------------------------- /Fortran90/energy.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE ENERGY 21 | 22 | IMPLICIT NONE 23 | 24 | CONTAINS 25 | 26 | FUNCTION E_electronic(Kf,P,F,H) result(E_el) 27 | ! - 28 | ! 29 | ! - 30 | ! 31 | ! Source: 32 | ! A. Szabo and N. Ostlund 33 | ! 34 | ! - 35 | 36 | IMPLICIT NONE 37 | 38 | ! INPUT 39 | INTEGER, intent(in) :: Kf 40 | REAL*8, dimension(Kf,Kf), intent(in) :: P ! Density matrix 41 | REAL*8, dimension(Kf,Kf), intent(in) :: F ! Fock operator 42 | REAL*8, dimension(Kf,Kf), intent(in) :: H ! Core Hamiltonian 43 | 44 | ! INTERMEDIATE VARIABLES 45 | INTEGER :: i, j ! Loop indices 46 | 47 | ! OUTPUT 48 | REAL*8 :: E_el ! Electronic energy 49 | 50 | E_el = 0.0D0 51 | 52 | DO i = 1, Kf 53 | DO j = 1, Kf 54 | E_el = E_el + 0.5D0 * P(j,i) * (H(i,j) + F(i,j)) 55 | END DO 56 | END DO 57 | 58 | END FUNCTION E_electronic 59 | 60 | FUNCTION E_electronic_spin(Kf,Pa,Fa,Pb,Fb,H) result(E_el) 61 | 62 | IMPLICIT NONE 63 | 64 | ! INPUT 65 | INTEGER, intent(in) :: Kf 66 | REAL*8, dimension(Kf,Kf), intent(in) :: Pa ! Density matrix (alpha spin) 67 | REAL*8, dimension(Kf,Kf), intent(in) :: Pb ! Density matrix (beta spin) 68 | REAL*8, dimension(Kf,Kf), intent(in) :: Fa ! Fock operator (alpha spin) 69 | REAL*8, dimension(Kf,Kf), intent(in) :: Fb ! Fock operator (beta spin) 70 | REAL*8, dimension(Kf,Kf), intent(in) :: H ! Core Hamiltonian 71 | 72 | ! INTERMEDIATE VARIABLES 73 | INTEGER :: i, j ! Loop indices 74 | REAL*8, dimension(Kf,Kf) :: Ptot ! Total density matrix 75 | 76 | ! OUTPUT 77 | REAL*8 :: E_el ! Electronic energy 78 | 79 | Ptot = Pa + Pb 80 | 81 | E_el = 0.0D0 82 | 83 | DO i = 1, Kf 84 | DO j = 1, Kf 85 | E_el = E_el + Ptot(j,i) * H(i,j) + Pa(j,i) * Fa(i,j) + Pb(j,i) * Fb(i,j) 86 | END DO 87 | END DO 88 | 89 | E_el = 0.5D0 * E_el 90 | 91 | END FUNCTION E_electronic_spin 92 | 93 | 94 | FUNCTION E_nuclear(Nn,Rn,Zn) result(E_nu) 95 | 96 | IMPLICIT NONE 97 | 98 | ! INPUT 99 | INTEGER, intent(in) :: Nn ! Total number of nuclei 100 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges 101 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 102 | 103 | ! INTERMEDIATE VARIABLES 104 | INTEGER :: i, j ! Loop variables 105 | 106 | ! OUTPUT 107 | REAl*8 :: E_nu ! Nuclear energy 108 | 109 | E_nu = 0.0D0 110 | 111 | DO i = 1, Nn 112 | DO j = i + 1, Nn 113 | E_nu = E_nu + Zn(i) * Zn(j) / NORM2(Rn(i,1:3) - Rn(j,1:3)) 114 | END DO 115 | END DO 116 | 117 | END FUNCTION E_nuclear 118 | 119 | FUNCTION E_tot(Kf,Nn,Rn,Zn,P,F,H) 120 | IMPLICIT NONE 121 | 122 | ! INPUT 123 | INTEGER, intent(in) :: Kf ! Basis set size 124 | INTEGER, intent(in) :: Nn ! Total number of nuclei 125 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges 126 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 127 | REAL*8, dimension(Kf,Kf), intent(in) :: P ! Density matrix 128 | REAL*8, dimension(Kf,Kf), intent(in) :: F ! Fock operator 129 | REAL*8, dimension(Kf,Kf), intent(in) :: H ! Core Hamiltonian 130 | 131 | ! OUTPUT 132 | REAL*8 :: E_tot 133 | 134 | E_tot = E_nuclear(Nn,Rn,Zn) + E_electronic(Kf,P,F,H) 135 | 136 | END FUNCTION E_tot 137 | 138 | FUNCTION E_tot_spin(Kf,Nn,Rn,Zn,Pa,Pb,Fa,Fb,H) result(E_tot) 139 | IMPLICIT NONE 140 | 141 | ! INPUT 142 | INTEGER, intent(in) :: Kf ! Basis set size 143 | INTEGER, intent(in) :: Nn ! Total number of nuclei 144 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges 145 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 146 | REAL*8, dimension(Kf,Kf), intent(in) :: Pa ! Density matrix (alpha spin) 147 | REAL*8, dimension(Kf,Kf), intent(in) :: Fa ! Fock operator (alpha spin) 148 | REAL*8, dimension(Kf,Kf), intent(in) :: Pb ! Density matrix (beta spin) 149 | REAL*8, dimension(Kf,Kf), intent(in) :: Fb ! Fock operator (beta spin) 150 | REAL*8, dimension(Kf,Kf), intent(in) :: H ! Core Hamiltonian 151 | 152 | ! OUTPUT 153 | REAL*8 :: E_tot 154 | 155 | E_tot = E_nuclear(Nn,Rn,Zn) + E_electronic_spin(Kf,Pa,Fa,Pb,Fb,H) 156 | 157 | END FUNCTION E_tot_spin 158 | 159 | 160 | 161 | END MODULE ENERGY 162 | -------------------------------------------------------------------------------- /Fortran90/factorial.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE FACT 21 | 22 | IMPLICIT NONE 23 | 24 | CONTAINS 25 | ! --------- 26 | ! FACTORIAL 27 | ! --------- 28 | FUNCTION factorial(n) result(fact) 29 | IMPLICIT NONE 30 | 31 | ! INPUT 32 | INTEGER, intent(in) :: n 33 | 34 | ! INTERMEDIATE VARIABLE 35 | INTEGER :: i 36 | 37 | ! OUTPUT 38 | INTEGER :: fact 39 | 40 | fact = 1 41 | 42 | DO i = 2, n 43 | fact = fact * i 44 | END DO 45 | 46 | END FUNCTION factorial 47 | 48 | 49 | 50 | ! ---------- 51 | ! FACTORIAL2 52 | ! ---------- 53 | FUNCTION factorial2(n) result(fact2) 54 | IMPLICIT NONE 55 | 56 | ! INPUT 57 | INTEGER, intent(in) :: n 58 | 59 | ! INTERMEDIATE VARIABLE 60 | INTEGER :: i 61 | 62 | ! OUTPUT 63 | INTEGER :: fact2 64 | 65 | IF (n == -1) THEN 66 | fact2 = 1 67 | ELSE IF (MOD(n,2) == 0) THEN ! EVEN NUMBER 68 | fact2 = 1 69 | 70 | DO i = 2, n, 2 71 | fact2 = fact2 * i 72 | END DO 73 | ELSE ! ODD NUMBER 74 | fact2 = 1 75 | 76 | DO i = 1, n, 2 77 | fact2 = fact2 * i 78 | END DO 79 | END IF 80 | 81 | END FUNCTION factorial2 82 | 83 | 84 | 85 | ! -------------------- 86 | ! BINOMIAL COEFFICIENT 87 | ! -------------------- 88 | FUNCTION binom(n,k) 89 | IMPLICIT NONE 90 | 91 | ! INPUT 92 | INTEGER, intent(in) :: n, k 93 | 94 | ! OUTPUT 95 | INTEGER :: binom 96 | 97 | binom = factorial(n) 98 | binom = binom / factorial(k) 99 | binom = binom / factorial(n-k) 100 | 101 | END FUNCTION binom 102 | 103 | END MODULE FACT 104 | -------------------------------------------------------------------------------- /Fortran90/force.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE FORCES 21 | ! ------------------------------------------- 22 | ! FORCES 23 | ! ------------------------------------------- 24 | ! 25 | ! Compute electronic forces acting on nuclei. 26 | ! 27 | !-------------------------------------------- 28 | 29 | USE RHF 30 | USE UHF 31 | 32 | IMPLICIT NONE 33 | 34 | CONTAINS 35 | 36 | SUBROUTINE displace_basis(Kf,basis_R,basis_idx,idx,dir,delta,basis_RR) 37 | ! ----------------------------------------------------- 38 | ! Displace basis functions on atom IDX in direction DIR 39 | ! ----------------------------------------------------- 40 | 41 | IMPLICIT NONE 42 | 43 | ! INPUT 44 | INTEGER, intent(in) :: Kf ! Basis set size 45 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Centers of basis set Gaussians 46 | INTEGER, dimension(Kf), intent(in):: basis_idx ! Basis set atom index 47 | INTEGER, intent(in) :: idx ! Atom index (displace basis functions at atom idx) 48 | INTEGER, intent(in) :: dir ! Direction of displacement (1=x, 2=y, 3=z) 49 | REAL*8, intent(in) :: delta ! Displacement 50 | 51 | ! INTERMEDIATE VARIABLES 52 | INTEGER:: i ! Loop index 53 | 54 | ! OUTPUT 55 | REAL*8, dimension(Kf,3) :: basis_RR ! Displaced basis set 56 | 57 | basis_RR = basis_R ! Initialize displaced basis centers at original ones 58 | 59 | DO i = 1, Kf 60 | IF (basis_idx(i) .EQ. idx) THEN 61 | ! Displace basis set center along DIR 62 | basis_RR(i,dir) = basis_R(i,dir) + delta 63 | END IF 64 | END DO 65 | 66 | END SUBROUTINE 67 | 68 | SUBROUTINE force_idx_fd(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,Rn,idx,force,delta,method) 69 | ! ------------------------------------------------------------------------ 70 | ! Compute forces on atom IDX by finite difference (computationally costly) 71 | ! ------------------------------------------------------------------------ 72 | 73 | ! TODO: Subroutine that computes force along given direction (x, y or z) 74 | 75 | ! INPUT 76 | INTEGER, intent(in) :: Kf ! Basis set size 77 | INTEGER, intent(in) :: Ne ! Number of electrons 78 | INTEGER, intent(in) :: Nn ! Number of nuclei 79 | INTEGER, intent(in) :: c ! Number of contractions 80 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Angular momenta of basis set Gaussians 81 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Centers of basis set Gaussians 82 | REAL*8, dimension(Kf,c), intent(in) :: basis_D, basis_A ! Basis set coefficients 83 | INTEGER, dimension(Kf), intent(in):: basis_idx ! Basis set atom index 84 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 85 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges 86 | INTEGER, intent(in) :: idx ! Atom index (compute forces for atom idx) 87 | REAL*8, intent(in) :: delta ! Step size 88 | CHARACTER (len=3), intent(in) :: method ! Method (RHF or UHF) 89 | 90 | ! OUTPUT 91 | REAL*8, dimension(Nn,3), intent(out) :: force ! Vector of forces (on every atom) 92 | 93 | ! INTERMEDIATE VARIABLES 94 | REAL*8, dimension(3) :: dx 95 | REAL*8, dimension(3) :: dy 96 | REAL*8, dimension(3) :: dz 97 | REAL*8 :: dEp, dEm 98 | REAL*8, dimension(Nn,3) :: Rnp, Rnm 99 | REAL*8, dimension(Kf,3) :: basis_RR ! Displaced basis set 100 | REAl*8, dimension(Kf,Kf) :: P ! Density matrix 101 | 102 | ! PARAMETERS 103 | LOGICAL, PARAMETER :: scf_verbose = .FALSE. 104 | 105 | ! -------------- 106 | ! INITIALIZATION 107 | ! -------------- 108 | 109 | dx = (/delta,0.0D0,0.0D0/) 110 | dy = (/0.0D0,delta,0.0D0/) 111 | dz = (/0.0D0,0.0D0,delta/) 112 | 113 | ! ------------- 114 | ! FORCE ALONG X 115 | ! ------------- 116 | 117 | dEp = 0.0D0 118 | dEm = 0.0D0 119 | 120 | ! Displace atom and basis set at new atomic position 121 | 122 | Rnp = Rn 123 | Rnp(idx,:) = Rn(idx,:) + dx 124 | 125 | CALL displace_basis(Kf,basis_R,basis_idx,idx,1,delta,basis_RR) 126 | 127 | ! Total energy calculation at new atomic position 128 | 129 | IF (method .EQ. "RHF") THEN 130 | CALL RHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnp,dEp,P,scf_verbose) 131 | END IF 132 | 133 | IF (method .EQ. "UHF") THEN 134 | CALL UHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnp,dEp,P,scf_verbose) 135 | END IF 136 | 137 | ! Displace atom and basis set at new atomic position 138 | 139 | Rnm = Rn 140 | Rnm(idx,:) = Rn(idx,:) - dx 141 | 142 | CALL displace_basis(Kf,basis_R,basis_idx,idx,1,-delta,basis_RR) 143 | 144 | ! Total energy calculation at new atomic position 145 | 146 | IF (method .EQ. "RHF") THEN 147 | CALL RHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnm,dEm,P,scf_verbose) 148 | END IF 149 | 150 | IF (method .EQ. "UHF") THEN 151 | CALL UHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnm,dEm,P,scf_verbose) 152 | END IF 153 | 154 | ! Compute force along x 155 | 156 | force(idx,1) = - (dEp - dEm) / (2.0D0 * delta) !finite_difference(dEp,dEm,Rnp(idx,1),Rnm(idx,1)) 157 | 158 | ! ------------- 159 | ! FORCE ALONG Y 160 | ! ------------- 161 | 162 | dEp = 0.0D0 163 | dEm = 0.0D0 164 | 165 | ! Displace atom and basis set at new atomic position 166 | 167 | Rnp = Rn 168 | Rnp(idx,:) = Rn(idx,:) + dy 169 | 170 | CALL displace_basis(Kf,basis_R,basis_idx,idx,2,delta,basis_RR) 171 | 172 | ! Total energy calculation at new atomic position 173 | 174 | IF (method .EQ. "RHF") THEN 175 | CALL RHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnp,dEp,P,scf_verbose) 176 | END IF 177 | 178 | IF (method .EQ. "UHF") THEN 179 | CALL UHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnp,dEp,P,scf_verbose) 180 | END IF 181 | 182 | ! Displace atom and basis set at new atomic position 183 | 184 | Rnm = Rn 185 | Rnm(idx,:) = Rn(idx,:) - dy 186 | 187 | CALL displace_basis(Kf,basis_R,basis_idx,idx,2,-delta,basis_RR) 188 | 189 | ! Total energy calculation at new atomic position 190 | 191 | IF (method .EQ. "RHF") THEN 192 | CALL RHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnm,dEm,P,scf_verbose) 193 | END IF 194 | 195 | IF (method .EQ. "UHF") THEN 196 | CALL UHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnm,dEm,P,scf_verbose) 197 | END IF 198 | 199 | ! Compute force along y 200 | 201 | force(idx,2) = - (dEp - dEm) / (2.0D0 * delta) !finite_difference(dEp,dEm,Rnp(idx,2),Rnm(idx,2)) 202 | 203 | ! ------------- 204 | ! FORCE ALONG Z 205 | ! ------------- 206 | 207 | dEp = 0.0D0 208 | dEm = 0.0D0 209 | 210 | ! Displace atom and basis set at new atomic position 211 | 212 | Rnp = Rn 213 | Rnp(idx,:) = Rn(idx,:) + dz 214 | 215 | CALL displace_basis(Kf,basis_R,basis_idx,idx,3,delta,basis_RR) 216 | 217 | ! Total energy calculation at new atomic position 218 | 219 | IF (method .EQ. "RHF") THEN 220 | CALL RHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnp,dEp,P,scf_verbose) 221 | END IF 222 | 223 | IF (method .EQ. "UHF") THEN 224 | CALL UHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnp,dEp,P,scf_verbose) 225 | END IF 226 | 227 | ! Displace atom and basis set at new atomic position 228 | 229 | Rnm = Rn 230 | Rnm(idx,:) = Rn(idx,:) - dz 231 | 232 | CALL displace_basis(Kf,basis_R,basis_idx,idx,3,-delta,basis_RR) 233 | 234 | ! Total energy calculation at new atomic position 235 | 236 | IF (method .EQ. "RHF") THEN 237 | CALL RHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnm,dEm,P,scf_verbose) 238 | END IF 239 | 240 | IF (method .EQ. "UHF") THEN 241 | CALL UHF_DIIS(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_RR,Zn,Rnm,dEm,P,scf_verbose) 242 | END IF 243 | 244 | ! Compute force along z 245 | 246 | force(idx,3) = - (dEp - dEm) / (2.0D0 * delta) !finite_difference(dEp,dEm,Rnp(idx,3),Rnm(idx,3)) 247 | 248 | END SUBROUTINE 249 | 250 | SUBROUTINE force_fd(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,Rn,force,delta,method) 251 | ! ------------------------------------------------------------------------- 252 | ! Compute forces on all atoms by finite difference (computationally costly) 253 | ! ------------------------------------------------------------------------- 254 | 255 | IMPLICIT NONE 256 | 257 | ! INPUT 258 | INTEGER, intent(in) :: Kf ! Basis set size 259 | INTEGER, intent(in) :: Ne ! Number of electrons 260 | INTEGER, intent(in) :: Nn ! Number of nuclei 261 | INTEGER, intent(in) :: c ! Number of contractions 262 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Angular momenta of basis set Gaussians 263 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Centers of basis set Gaussians 264 | REAL*8, dimension(Kf,c), intent(in) :: basis_D, basis_A ! Basis set coefficients 265 | INTEGER, dimension(Kf), intent(in):: basis_idx ! Basis set atom index 266 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 267 | INTEGER, dimension(Nn), intent(in) :: Zn ! Nuclear charges 268 | REAL*8, intent(in) :: delta ! Step size 269 | CHARACTER (len=3), intent(in) :: method ! Method (RHF or UHF) 270 | 271 | ! OUTPUT 272 | REAL*8, dimension(Nn,3), intent(out) :: force ! Vector of forces (on every atom) 273 | 274 | ! INTERMEDIATE VARIABLES 275 | INTEGER :: i 276 | 277 | ! Loop on every atom of the system 278 | DO i = 1, Nn 279 | CALL force_idx_fd(Kf,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,Rn,i,force,delta,method) 280 | END DO 281 | 282 | END SUBROUTINE force_fd 283 | 284 | END MODULE FORCES 285 | -------------------------------------------------------------------------------- /Fortran90/gaussian.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE GAUSSIAN 21 | 22 | USE CONSTANTS, only : PI 23 | USE FACT 24 | 25 | IMPLICIT NONE 26 | 27 | CONTAINS 28 | 29 | ! ------------------------ 30 | ! Compute Gaussian product 31 | ! ------------------------ 32 | SUBROUTINE gaussian_product(aa,bb,Ra,Rb,pp,Rp,cp) 33 | IMPLICIT NONE 34 | 35 | ! INPUT 36 | REAL*8, intent(in) :: aa, bb ! Gaussian exponential coefficients 37 | REAL*8, dimension(3), intent(in) :: Ra, Rb ! Gaussian centers 38 | 39 | ! INTERMEDIATE VARIABLE 40 | REAL*8, dimension(3) :: Rab ! Differente between Gaussian centers 41 | 42 | ! OUTPUT 43 | REAL*8, intent(out) :: pp ! Gaussian product exponential coefficient 44 | REAL*8, intent(out) :: cp ! Gaussian product coefficient 45 | REAL*8, dimension(3), intent(out) :: Rp ! Gaussian product center 46 | 47 | ! Compute Gaussian product exponential coefficient 48 | pp = aa + bb 49 | 50 | ! Compute difference between Gaussian centers 51 | Rab = Ra - Rb 52 | 53 | ! Compute Gaussian product coefficient 54 | cp = DOT_PRODUCT(Rab,Rab) 55 | cp = - aa * bb / pp * cp 56 | cp = EXP(cp) 57 | 58 | ! Compute Gaussian product center 59 | Rp = (aa * Ra + bb * Rb) / pp 60 | 61 | END SUBROUTINE gaussian_product 62 | 63 | 64 | 65 | ! -------------------------------------------------------------------- 66 | ! Norm of Cartesian Gaussian integrals with arbitrary angular momentum 67 | ! -------------------------------------------------------------------- 68 | FUNCTION norm(ax,ay,az,aa) result(N) 69 | IMPLICIT NONE 70 | 71 | ! INPUT 72 | INTEGER, intent(in) :: ax, ay, az ! Cartesian Gaussian angular momenta projections 73 | REAL*8, intent(in) :: aa ! Gaussian exponential coefficient 74 | 75 | ! OUTPUT 76 | REAL*8 :: N ! Normalization factor 77 | 78 | N = (2 * aa / PI)**(3.0D0 / 4.0D0) * (4.0D0 * aa)**((ax + ay + az) / 2.0D0) 79 | N = N / SQRT(REAL(factorial2(2 * ax - 1) * factorial2(2 * ay - 1) * factorial2(2 * az - 1))) 80 | 81 | END FUNCTION norm 82 | 83 | END MODULE GAUSSIAN 84 | -------------------------------------------------------------------------------- /Fortran90/init.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE INIT 21 | ! --------------------------------- 22 | ! INITIAL GUESS FOR THE FOCK MATRIX 23 | ! --------------------------------- 24 | 25 | IMPLICIT NONE 26 | 27 | CONTAINS 28 | 29 | ! ---------- 30 | ! CORE GUESS 31 | ! ---------- 32 | SUBROUTINE core_guess(Kf,Hc,F) 33 | ! ---------------------------- 34 | ! Core Hamiltonian 35 | ! ---------------------------- 36 | ! 37 | ! Source: 38 | ! A. Szabo and N. S. Ostlund 39 | ! Modern Quantum Chemistry 40 | ! Dover 41 | ! 1996 42 | ! 43 | !----------------------------- 44 | 45 | IMPLICIT NONE 46 | 47 | ! INPUT 48 | INTEGER, intent(in) :: Kf ! Basis set size 49 | REAL*8, dimension(Kf,Kf), intent(in) :: Hc ! Core Hamiltonian 50 | 51 | ! OUTPUT 52 | REAL*8, dimension(Kf,Kf), intent(out) :: F ! Initial Guess for the Fock operator 53 | 54 | ! Initial guess: Core Hamiltonian 55 | F = Hc 56 | 57 | END SUBROUTINE core_guess 58 | 59 | 60 | 61 | ! ------------ 62 | ! HÜCKEL GUESS 63 | ! ------------ 64 | SUBROUTINE huckel_guess(Kf,Hc,S,F,cst) 65 | ! ----------------------------------------------------- 66 | ! Extended Hückel Theory 67 | ! ----------------------------------------------------- 68 | ! 69 | ! Source: 70 | ! Extended Hückel and Slater’s rule initial guess for 71 | ! real space grid-based density functional theory 72 | ! M. Lee, K. Leiter, C. Eisner, J. Crone and J. Knap 73 | ! Computational and Theoretical Chemistry 74 | ! 2015 75 | ! 76 | !------------------------------------------------------ 77 | 78 | IMPLICIT NONE 79 | 80 | ! INPUT 81 | INTEGER, intent(in) :: Kf ! Basis set size 82 | REAL*8, dimension(Kf,Kf),intent(in) :: S ! Overlap matrix 83 | REAL*8, dimension(Kf,Kf), intent(in) :: Hc ! Core Hamiltonian 84 | Real*8, intent(in) :: cst ! Multiplicative constant in Hückel model 85 | 86 | ! INTERMEDIATE VARIABLES 87 | INTEGER :: i, j ! Loop indices 88 | 89 | ! OUTPUT 90 | REAL*8, dimension(Kf,Kf), intent(out) :: F ! Initial Guess for the Fock operator 91 | 92 | F(:,:) = 0.0D0 93 | 94 | DO i = 1,Kf 95 | DO j = 1,Kf 96 | F(i,j) = cst * S(i,j) * 0.5D0 * (Hc(i,i) + Hc(j,j)) 97 | END DO 98 | END DO 99 | 100 | END SUBROUTINE huckel_guess 101 | 102 | 103 | END MODULE INIT 104 | -------------------------------------------------------------------------------- /Fortran90/input.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE INPUT 21 | 22 | IMPLICIT NONE 23 | 24 | CONTAINS 25 | 26 | SUBROUTINE load(fname,calculation,method,Ne,Nn,K,c,Rn,Zn,basis_R,basis_L,basis_A,basis_D,basis_idx) 27 | 28 | IMPLICIT NONE 29 | 30 | ! OUTPUT 31 | CHARACTER (len=*), intent(out):: calculation ! Calculation name 32 | CHARACTER (len=*), intent(out):: method ! Method 33 | INTEGER, intent(out) :: Ne ! Number of electrons 34 | INTEGER, intent(out) :: Nn ! Number of nuclei 35 | INTEGER, intent(out) :: K ! Basis set size 36 | INTEGER, intent(out) :: c ! Contractions (TODO: split valence basis set) 37 | CHARACTER(len=*), intent(in) :: fname ! Input file name 38 | 39 | ! INTERMEDIATE VARIABLES 40 | INTEGER :: i ! Loop index 41 | 42 | ! ALLOCATABLE 43 | REAL*8, allocatable, dimension(:,:) :: Rn ! Atomic potisions 44 | INTEGER, allocatable, dimension(:) :: Zn ! Atomic chatges 45 | REAL*8, allocatable, dimension(:,:) :: basis_R ! Basis functions' centers 46 | INTEGER, allocatable, dimension(:,:) :: basis_L ! Basis functions' angular momenta 47 | REAL*8, allocatable, dimension(:,:) :: basis_A ! Contraction exponential coefficients 48 | REAL*8, allocatable, dimension(:,:) :: basis_D ! Conttaction linear coefficients 49 | INTEGER, allocatable, dimension(:) :: basis_idx ! Basis set atom index 50 | 51 | WRITE(*,*) "Opening file: ", fname 52 | 53 | ! Open file containing system and basis set informations 54 | OPEN(unit=100,file=fname,form="formatted",status="old",action="read") 55 | 56 | READ(100,*) calculation 57 | READ(100,*) method 58 | READ(100,*) Ne 59 | READ(100,*) Nn 60 | READ(100,*) K 61 | READ(100,*) C 62 | 63 | ! Allocate arrays once we know system's and basis set's specifications (Ne,Nn,K,c) 64 | ALLOCATE(Rn(Nn,3)) 65 | ALLOCATE(Zn(Nn)) 66 | ALLOCATE(basis_R(K,3)) 67 | ALLOCATE(basis_L(K,3)) 68 | ALLOCATE(basis_A(K,c)) 69 | ALLOCATE(basis_D(K,c)) 70 | ALLOCATE(basis_idx(K)) 71 | 72 | ! Read atomic positions 73 | DO i = 1, Nn 74 | READ(100,*) Rn(i,:), Zn(i) 75 | END DO 76 | 77 | ! Read basis set informations 78 | DO i = 1, K 79 | READ(100,*) basis_R(i,:), basis_L(i,:), basis_A(i,:), basis_D(i,:), basis_idx(i) 80 | END DO 81 | 82 | CLOSE(unit=100) ! Close the file 83 | 84 | END SUBROUTINE load 85 | 86 | END MODULE INPUT 87 | -------------------------------------------------------------------------------- /Fortran90/kinetic.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE KINETIC 21 | 22 | USE CONSTANTS 23 | USE GAUSSIAN 24 | USE OVERLAP, only: Si 25 | 26 | IMPLICIT NONE 27 | 28 | CONTAINS 29 | 30 | FUNCTION Ki(ac,a1,a2,bc,b1,b2,aa,bb,Ra,Rb,Ra1,Rb1,Ra2,Rb2,Rc,R1,R2,cp) 31 | ! ---------------------------------------------------------------------------------------------- 32 | ! Compute kinetic energy between two unnormalized Cartesian Gaussian functions along direction i 33 | ! ---------------------------------------------------------------------------------------------- 34 | 35 | IMPLICIT NONE 36 | 37 | ! INPUT 38 | INTEGER, intent(in) :: ac, a1, a2, bc, b1, b2 ! Cartesia Gaussian angular momenta 39 | REAL*8, intent(in) :: aa, bb ! Gaussian exponential coefficients 40 | REAL*8, intent(in) :: Ra, Rb, Ra1, Rb1, Ra2, Rb2 ! Gaussian centers' coordinates 41 | REAL*8, intent(in) :: Rc, R1, R2 ! Gaussian product center coordinates 42 | REAL*8, intent(in) :: cp ! Gaussian product coefficient 43 | 44 | ! INTERMEDIATE VARIABLE 45 | REAL*8 :: k 46 | 47 | ! OUTPUT 48 | REAL*8 :: Ki 49 | 50 | k = 0.0D0 51 | k = k + ac * bc * Si(ac - 1,bc - 1,aa,bb,Ra,Rb,Rc) 52 | k = k - 2 * aa * bc * Si(ac + 1,bc - 1,aa,bb,Ra,Rb,Rc) 53 | k = k - 2 * ac * bb * Si(ac - 1,bc + 1,aa,bb,Ra,Rb,Rc) 54 | k = k + 4 * aa * bb * Si(ac + 1,bc + 1,aa,bb,Ra,Rb,Rc) 55 | k = k * 0.5D0 56 | 57 | Ki = 1 58 | Ki = Ki * cp * (PI / (aa + bb))**(3.0D0/2.0D0) * k 59 | Ki = Ki * Si(a1,b1,aa,bb,Ra1,Rb1,R1) 60 | Ki = Ki * Si(a2,b2,aa,bb,Ra2,Rb2,R2) 61 | 62 | END FUNCTION Ki 63 | 64 | 65 | 66 | FUNCTION kinetic_coeff(ax,ay,az,bx,by,bz,aa,bb,Ra,Rb) result(K) 67 | ! ----------------------------------------------------------------- 68 | ! Compute kinetic integral between two Cartesian Gaussian functions 69 | ! ----------------------------------------------------------------- 70 | ! 71 | ! Source: 72 | ! The Mathematica Journal 73 | ! Evaluation of Gaussian Molecular Integrals 74 | ! II. Kinetic-Energy Integrals 75 | ! Minhhuy Hô and Julio Manuel Hernández-Pérez 76 | ! 77 | ! ----------------------------------------------------------------- 78 | 79 | IMPLICIT NONE 80 | 81 | ! INPUT 82 | INTEGER, intent(in) :: ax, ay, az, bx, by, bz ! Angular momentum coefficients 83 | REAL*8, intent(in) :: aa, bb ! Exponential Gaussian coefficients 84 | REAL*8, dimension(3), intent(in) :: Ra, Rb ! Gaussian centers 85 | 86 | ! INTERMEDIATE VARIABLE 87 | REAL*8 :: pp ! Gaussian produc exponential coefficient 88 | REAL*8, dimension(3) :: Rp ! Gaussian produc center 89 | REAL*8 :: cp ! Gaussian product multiplicative constant 90 | 91 | ! OUTPUT 92 | REAL*8 :: K 93 | 94 | CALL gaussian_product(aa,bb,Ra,Rb,pp,Rp,cp) ! Compute PP, RP and CP 95 | 96 | K = 0 97 | K = K + Ki(ax,ay,az,bx,by,bz,aa,bb,Ra(1),Rb(1),Ra(2),Rb(2),Ra(3),Rb(3),Rp(1),Rp(2),Rp(3),cp) ! Kx 98 | K = K + Ki(ay,az,ax,by,bz,bx,aa,bb,Ra(2),Rb(2),Ra(3),Rb(3),Ra(1),Rb(1),Rp(2),Rp(3),Rp(1),cp) ! Ky 99 | K = K + Ki(az,ax,ay,bz,bx,by,aa,bb,Ra(3),Rb(3),Ra(1),Rb(1),Ra(2),Rb(2),Rp(3),Rp(1),Rp(2),cp) ! Kz 100 | K = K * norm(ax,ay,az,aa) * norm(bx,by,bz,bb) 101 | 102 | END FUNCTION kinetic_coeff 103 | 104 | ! -------------- 105 | ! KINETIC MATRIX 106 | ! -------------- 107 | SUBROUTINE T_kinetic(Kf,c,basis_D,basis_A,basis_L,basis_R,T) 108 | ! ---------------------------------------------- 109 | ! Compute kinetic matrix between basis function. 110 | ! ---------------------------------------------- 111 | 112 | IMPLICIT NONE 113 | 114 | ! TODO Allow flexibility for basis sets other than STO-3G 115 | INTEGER, intent(in) :: c ! Number of contractions per basis function 116 | 117 | ! INPUT 118 | INTEGER, intent(in) :: Kf ! Number of basis functions 119 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Basis set niclear positions 120 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Basis set angular momenta 121 | REAL*8, dimension(Kf,3), intent(in) :: basis_D ! Basis set contraction coefficients 122 | REAL*8, dimension(Kf,3), intent(in) :: basis_A ! Basis set exponential contraction coefficients 123 | 124 | ! INTERMEDIATE VARIABLES 125 | INTEGER :: i,j,k,l 126 | REAL*8 :: tmp 127 | 128 | ! OUTPUT 129 | REAL*8, dimension(Kf,Kf), intent(out) :: T 130 | 131 | T(:,:) = 0.0D0 132 | 133 | DO i = 1,Kf 134 | DO j = 1,Kf 135 | DO k = 1,c 136 | DO l = 1,c 137 | tmp = basis_D(i,k) * basis_D(j,l) 138 | tmp = tmp * kinetic_coeff( basis_L(i,1),& ! lx for basis function i 139 | basis_L(i,2),& ! ly for basis function i 140 | basis_L(i,3),& ! lz for basis function i 141 | basis_L(j,1),& ! lx for basis function j 142 | basis_L(j,2),& ! ly for basis function j 143 | basis_L(j,3),& ! lz for basis function j 144 | basis_A(i,k),& ! Exponential coefficient for basis function i, contraction k 145 | basis_A(j,l),& ! Exponential coefficient for basis function j, contraction l 146 | basis_R(i,:),& ! Center of basis function i 147 | basis_R(j,:)) ! Center of basis function j 148 | 149 | T(i,j) = T(i,j) + tmp 150 | END DO ! l 151 | END DO ! k 152 | END DO ! j 153 | END DO ! i 154 | 155 | END SUBROUTINE T_kinetic 156 | 157 | 158 | END MODULE KINETIC 159 | -------------------------------------------------------------------------------- /Fortran90/la.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE LA 21 | ! -------------- 22 | ! LINEAR ALGEBRA 23 | ! -------------- 24 | 25 | IMPLICIT NONE 26 | 27 | CONTAINS 28 | 29 | ! ------------------ 30 | ! EIGENVALUE PROBLEM 31 | ! ------------------ 32 | SUBROUTINE EIGS(d,M,V,lambda) 33 | ! ------------------------------------- 34 | ! Solve eigenvalue problem using LAPACK 35 | ! ------------------------------------- 36 | 37 | IMPLICIT NONE 38 | 39 | ! INPUT 40 | INTEGER, intent(in) :: d ! Dimension of M (d x d) 41 | REAL*8, dimension(d,d),intent(in) :: M ! Matrix M 42 | 43 | ! INTERMEDIATE VARIABLES 44 | INTEGER, PARAMETER :: LWMAX = 10000 ! Maximal workspace size 45 | INTEGER :: LWORK ! Query optimal workspace size () 46 | INTEGER :: INFO ! Information flag for DSYEV 47 | REAL*8, dimension(LWMAX) :: WORK 48 | 49 | ! OUTPUT 50 | REAL*8, dimension(d,d), intent(out) :: V ! Eigenvectors 51 | REAL*8, dimension(d), intent(out) :: lambda ! Eigenvalues 52 | 53 | V = M 54 | 55 | LWORK = -1 56 | CALL DSYEV('V','U', d, V, d, lambda, WORK, LWORK, INFO ) ! Query optimal workspace size 57 | LWORK = MIN(LWMAX, INT(WORK(1))) * 2 * d ! Optimal workspace size 58 | ! See (http://www.netlib.org/lapack/lug/node120.html) 59 | 60 | CALL DSYEV('V','U', d, V, d, lambda, WORK, LWORK, INFO ) ! Solve the eigenvalue problem 61 | 62 | IF (INFO .NE. 0) THEN 63 | WRITE(*,*) "ERROR: IMPOSSIBLE TO SOLVE THE EIGENVALUE PROBLEM!" 64 | CALL EXIT(-1) 65 | END IF 66 | 67 | END SUBROUTINE EIGS 68 | 69 | ! ------------------- 70 | ! SOLVE LINEAR SYSTEM 71 | ! ------------------- 72 | SUBROUTINE LINEAR_SYSTEM(d,A,b,x,INFO) 73 | ! ----------------------------- 74 | ! Solve the linear system AX=B. 75 | ! ----------------------------- 76 | 77 | IMPLICIT NONE 78 | 79 | ! INPUT 80 | INTEGER, intent(in) :: d ! Dimension of A and B 81 | REAL*8, dimension(d,d), intent(in) :: A ! Matrix A 82 | REAL*8, dimension(d), intent(in) :: b ! Vector b 83 | 84 | ! INTERMEDIATE VARIABLES 85 | INTEGER, dimension(d) :: IPIV ! Pivots 86 | 87 | ! OUTPUT 88 | REAL*8, dimension(d), intent(out) :: x ! Solution 89 | INTEGER, intent(out) :: INFO ! Information flag for DGESV 90 | 91 | x = b ! The solution contains the RHS in entry 92 | 93 | CALL DGESV(d,1,A,d,IPIV,x,d,INFO) 94 | 95 | !IF (INFO .NE. 0) THEN 96 | ! WRITE(*,*) "ERROR: IMPOSSIBLE TO SOLVE THE LINEAR SYSTEM!" 97 | ! CALL EXIT(-1) 98 | !END IF 99 | 100 | END SUBROUTINE LINEAR_SYSTEM 101 | 102 | END MODULE LA 103 | -------------------------------------------------------------------------------- /Fortran90/molecules/CH4.in: -------------------------------------------------------------------------------- 1 | SP 2 | RHF/STO-3G 3 | 10 4 | C 0.000000 0.000000 0.000000 5 | H 0.000000 0.000000 2.050000 6 | H 1.932773 0.000000 -0.683292 7 | H -0.966387 -1.673831 -0.683292 8 | H -0.966387 1.673831 -0.683292 -------------------------------------------------------------------------------- /Fortran90/molecules/CO.in: -------------------------------------------------------------------------------- 1 | SP 2 | RHF/STO-3G 3 | 14 4 | C 0.000 0.000 0.000 5 | O 2.132 0.000 0.000 6 | -------------------------------------------------------------------------------- /Fortran90/molecules/FH.in: -------------------------------------------------------------------------------- 1 | SP 2 | RHF/STO-3G 3 | 10 4 | F 1.733 0.000 0.000 5 | H 0.000 0.000 0.000 6 | -------------------------------------------------------------------------------- /Fortran90/molecules/H2.in: -------------------------------------------------------------------------------- 1 | SP 2 | UHF/STO-3G 3 | 2 4 | H 1.4000 0.0000 0.0000 5 | H 0.0000 0.0000 0.0000 6 | -------------------------------------------------------------------------------- /Fortran90/molecules/H2O.in: -------------------------------------------------------------------------------- 1 | SP 2 | UHF/STO-3G 3 | 10 4 | H +1.4305507125 0.0000000000 0.0000000000 5 | H -1.4305507125 0.0000000000 0.0000000000 6 | O +0.0000000000 1.1072513982 0.0000000000 -------------------------------------------------------------------------------- /Fortran90/molecules/N2.in: -------------------------------------------------------------------------------- 1 | SP 2 | RHF/STO-3G 3 | 14 4 | N 2.074 0.000 0.000 5 | N 0.000 0.000 0.000 6 | -------------------------------------------------------------------------------- /Fortran90/multipole.f90: -------------------------------------------------------------------------------- 1 | MODULE MULTIPOLE 2 | 3 | USE CONSTANTS 4 | USE FACT 5 | USE GAUSSIAN 6 | USE OVERLAP 7 | 8 | IMPLICIT NONE 9 | 10 | CONTAINS 11 | 12 | 13 | FUNCTION Sije(e,a,b,aa,bb,Rai,Rbi,Rpi,Rci) 14 | ! -------------------------------------------------- 15 | ! Compute dipole moment of order E along direction I 16 | ! -------------------------------------------------- 17 | ! 18 | ! Source: 19 | ! T. Helgaker, P. Jørgensen and J. Olsen 20 | ! Molecular Electronic-Structure Theory 21 | ! Wiley 22 | ! 2000 23 | ! 24 | ! --------------------------------------------------- 25 | 26 | IMPLICIT NONE 27 | 28 | ! INPUT 29 | INTEGER, intent(in) :: e ! Dipole order 30 | INTEGER, intent(in) :: a,b ! Angular momentum coefficients of the Gaussians along direction i 31 | REAL*8, intent(in) :: aa, bb ! Exponential coefficients of the Gaussians 32 | REAL*8, intent(in) :: Rai, Rbi ! Centers of the Gaussians 33 | REAL*8, intent(in) :: Rpi ! Center of Gaussian product 34 | REAL*8, intent(in) :: Rci ! Center of the multipole 35 | 36 | ! INTERMEDIATE VARIABLE 37 | REAL*8, dimension(-1:a+1,-1:b+1,-1:e+1) :: S ! Vector of overlap coefficients 38 | INTEGER :: i, j, k 39 | REAL*8 :: factor 40 | 41 | ! OUTPUT 42 | REAL*8 :: Sije ! Dipole integral 43 | 44 | S(-1,:,:) = 0.0D0 45 | S(:,-1,:) = 0.0D0 46 | S(:,:,-1) = 0.0D0 47 | 48 | S(0,0,0) = S00(aa,bb,Rai,Rbi) 49 | 50 | DO i = 0, a 51 | DO j = 0, b 52 | DO k = 0, e 53 | factor = 1.0D0 / (2 * (aa+bb)) * (i * S(i-1,j,k) + j * S(i,j-1,k) + k * S(i,j,k-1)) 54 | 55 | S(i+1,j,k) = (Rpi - Rai) * S(i,j,k) + factor 56 | S(i,j+1,k) = (Rpi - Rbi) * S(i,j,k) + factor 57 | S(i,j,k+1) = (Rpi - Rci) * S(i,j,k) + factor 58 | END DO 59 | END DO 60 | END DO 61 | 62 | Sije = S(a,b,e) 63 | 64 | END FUNCTION Sije 65 | 66 | FUNCTION multipole_coeff_OS(ax,ay,az,bx,by,bz,aa,bb,Ra,Rb,e,f,g,Rc) result(S) 67 | ! ------------------------------------------------------------------- 68 | ! Compute multipole integral between two Cartesian Gaussian functions 69 | ! ------------------------------------------------------------------- 70 | ! 71 | ! Source: 72 | ! T. Helgaker, P. Jørgensen and J. Olsen 73 | ! Molecular Electronic-Structure Theory 74 | ! Wiley 75 | ! 2000 76 | ! 77 | ! ------------------------------------------------------------------- 78 | 79 | IMPLICIT NONE 80 | 81 | ! INPUT 82 | INTEGER, intent(in) :: ax, ay, az, bx, by, bz ! Angular momentum coefficients 83 | REAL*8, intent(in) :: aa, bb ! Exponential Gaussian coefficients 84 | REAL*8, dimension(3), intent(in) :: Ra, Rb ! Gaussian centers 85 | INTEGER , intent(in) :: e, f, g ! Multipole order along x, y and z 86 | REAL*8, dimension(3), intent(in) :: Rc ! Multipole center 87 | 88 | ! INTERMEDIATE VARIABLES 89 | REAL*8 :: pp ! Gaussian produc exponential coefficient 90 | REAL*8, dimension(3) :: Rp ! Gaussian produc center 91 | REAL*8 :: cp ! Gaussian product multiplicative constant 92 | 93 | ! OUTPUT 94 | REAL*8 :: S 95 | 96 | CALL gaussian_product(aa,bb,Ra,Rb,pp,Rp,cp) ! Compute PP, RP and CP 97 | 98 | S = 1 99 | S = S * Sije(e,ax,bx,aa,bb,Ra(1),Rb(1),Rp(1),Rc(1)) ! Overlap along x 100 | S = S * Sije(f,ay,by,aa,bb,Ra(2),Rb(2),Rp(2),Rc(2)) ! Overlap along y 101 | S = S * Sije(g,az,bz,aa,bb,Ra(3),Rb(3),Rp(3),Rc(3)) ! Overlap along z 102 | S = S * norm(ax,ay,az,aa) * norm(bx,by,bz,bb) ! Normalization of Gaussian functions 103 | 104 | END FUNCTION multipole_coeff_OS 105 | 106 | SUBROUTINE S_multipole_i(Kf,c,basis_D,basis_A,basis_L,basis_R,dir,e,R,S) 107 | ! ---------------------------------------------- 108 | ! Compute overlap matrix between basis function. 109 | ! ---------------------------------------------- 110 | 111 | IMPLICIT NONE 112 | 113 | ! TODO Allow flexibility for basis sets other than STO-3G 114 | INTEGER, intent(in) :: c ! Number of contractions per basis function 115 | 116 | ! INPUT 117 | INTEGER, intent(in) :: Kf ! Number of basis functions 118 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Basis set niclear positions 119 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Basis set angular momenta 120 | REAL*8, dimension(Kf,3), intent(in) :: basis_D ! Basis set contraction coefficients 121 | REAL*8, dimension(Kf,3), intent(in) :: basis_A ! Basis set exponential contraction coefficients 122 | REAL*8, dimension(3), intent(in) :: R ! Multipole center 123 | INTEGER, intent(in) :: dir ! Multipole direction 124 | INTEGER, intent(in) :: e ! Multipole exponent along direction DIR 125 | 126 | ! INTERMEDIATE VARIABLES 127 | INTEGER :: i,j,k,l 128 | REAL*8 :: tmp 129 | INTEGER, dimension(3) :: multi_dir ! Mulrtipole exponent along direction DIR 130 | 131 | ! OUTPUT 132 | REAL*8, dimension(Kf,Kf), intent(out) :: S 133 | 134 | IF (dir .EQ. 1) THEN 135 | 136 | multi_dir = (/e, 0, 0/) 137 | 138 | ELSE IF (dir .EQ. 2) THEN 139 | 140 | multi_dir = (/0, e, 0/) 141 | 142 | ELSE IF (dir .EQ. 3) THEN 143 | 144 | multi_dir = (/0, 0, e/) 145 | 146 | END IF 147 | 148 | S(:,:) = 0.0D0 149 | 150 | DO i = 1,Kf 151 | DO j = 1,Kf 152 | DO k = 1,c 153 | DO l = 1,c 154 | tmp = basis_D(i,k) * basis_D(j,l) 155 | tmp = tmp * multipole_coeff_OS( basis_L(i,1),& ! lx for basis function i 156 | basis_L(i,2),& ! ly for basis function i 157 | basis_L(i,3),& ! lz for basis function i 158 | basis_L(j,1),& ! lx for basis function j 159 | basis_L(j,2),& ! ly for basis function j 160 | basis_L(j,3),& ! lz for basis function j 161 | basis_A(i,k),& ! Exponential coefficient for basis function i, contraction k 162 | basis_A(j,l),& ! Exponential coefficient for basis function j, contraction l 163 | basis_R(i,:),& ! Center of basis function i 164 | basis_R(j,:),& ! Center of basis function j 165 | multi_dir(1),& ! Multipole exponent along x 166 | multi_dir(2),& ! Multipole exponent along y 167 | multi_dir(3),& ! Multipole exponent along z 168 | R) ! Multipole center 169 | 170 | S(i,j) = S(i,j) + tmp 171 | END DO ! l 172 | END DO ! k 173 | END DO ! j 174 | END DO ! i 175 | 176 | END SUBROUTINE S_multipole_i 177 | 178 | SUBROUTINE dipole(Kf,c,Nn,basis_D,basis_A,basis_L,basis_R,P,Rn,Zn,mu) 179 | ! ---------------------------- 180 | ! Compute multipole vector 181 | ! ---------------------------- 182 | ! 183 | ! Source: 184 | ! A. Szabo and N. S. Ostlund 185 | ! Modern Quantum Chemistry 186 | ! Dover 187 | ! 1996 188 | ! 189 | ! ---------------------------- 190 | 191 | ! TODO Allow flexibility for basis sets other than STO-3G 192 | INTEGER, intent(in) :: c ! Number of contractions per basis function 193 | 194 | ! INPUT 195 | INTEGER, intent(in) :: Kf ! Number of basis functions 196 | INTEGER, intent(in) :: Nn ! Number of nuclei 197 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Basis set niclear positions 198 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Basis set angular momenta 199 | REAL*8, dimension(Kf,3), intent(in) :: basis_D ! Basis set contraction coefficients 200 | REAL*8, dimension(Kf,3), intent(in) :: basis_A ! Basis set exponential contraction coefficients 201 | REAL*8, dimension(Kf,Kf), intent(in) :: P ! Density matrix 202 | REAL*8, dimension(Nn,3), intent(in) :: Rn ! Nuclear positions 203 | INTEGER, dimension(Nn), intent(in) :: Zn 204 | 205 | ! INTERMEDIATE VARIABLES 206 | REAL*8, dimension(Kf,Kf) :: S 207 | REAL*8, dimension(3) :: R 208 | INTEGER :: i, j, k 209 | 210 | ! OUTPUT 211 | REAL*8, dimension(3), intent(out) :: mu 212 | 213 | mu(:) = 0.0D0 214 | 215 | R(:) = 0.0D0 216 | 217 | ! ----------- 218 | ! X component 219 | ! ----------- 220 | CALL S_multipole_i(Kf,c,basis_D,basis_A,basis_L,basis_R,1,1,R,S) 221 | 222 | DO i = 1, Kf 223 | DO j = 1, Kf 224 | mu(1) = mu(1) - P(i,j) * S(j,i) 225 | END DO 226 | END DO 227 | 228 | ! ----------- 229 | ! Y component 230 | ! ----------- 231 | CALL S_multipole_i(Kf,c,basis_D,basis_A,basis_L,basis_R,2,1,R,S) 232 | 233 | DO i = 1, Kf 234 | DO j = 1, Kf 235 | mu(2) = mu(2) - P(i,j) * S(j,i) 236 | END DO 237 | END DO 238 | 239 | ! ----------- 240 | ! Z component 241 | ! ----------- 242 | CALL S_multipole_i(Kf,c,basis_D,basis_A,basis_L,basis_R,3,1,R,S) 243 | 244 | DO i = 1, Kf 245 | DO j = 1, Kf 246 | mu(3) = mu(3) - P(i,j) * S(j,i) 247 | END DO 248 | END DO 249 | 250 | ! Take into account nuclear charges 251 | DO k = 1, Nn 252 | mu = mu + Zn(k) * Rn(k,:) 253 | END DO 254 | 255 | END SUBROUTINE 256 | 257 | 258 | END MODULE MULTIPOLE 259 | -------------------------------------------------------------------------------- /Fortran90/nuclear.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE NUCLEAR 21 | 22 | USE FACT 23 | USE CONSTANTS 24 | USE GAUSSIAN 25 | 26 | IMPLICIT NONE 27 | 28 | !REAL*8 :: xx 29 | !INTEGER :: nunu 30 | 31 | CONTAINS 32 | FUNCTION f(j,l,m,a,b) 33 | !---------------------------------------- 34 | ! Expansion coefficient. 35 | !---------------------------------------- 36 | ! 37 | ! Source: 38 | ! Handbook of Computational Chemistry 39 | ! David Cook 40 | ! Oxford University Press 41 | ! 1998 42 | ! 43 | !---------------------------------------- 44 | 45 | ! INPUT 46 | INTEGER, intent(in) :: j, l, m 47 | REAL*8, intent(in) :: a, b 48 | 49 | ! INTERMEDIATE VARIABLES 50 | INTEGER :: k ! Loop index 51 | REAl*8 :: tmp ! Temporary product 52 | 53 | ! OUTPUT 54 | REAL*8 :: f 55 | 56 | f = 0.0D0 57 | 58 | DO k = MAX(0,j-m), MIN(j,l) 59 | tmp = 1.0D0 60 | tmp = tmp * binom(l,k) * binom(m,j-k) 61 | tmp = tmp * a**(l-k) * b**(m+k-j) 62 | 63 | f = f + tmp 64 | END DO 65 | 66 | END FUNCTION f 67 | 68 | ! ------------- 69 | ! BOYS FUNCTION 70 | ! ------------- 71 | FUNCTION boys(nu,x) 72 | ! ------------------------------------------------------------------------ 73 | ! Compute boys function (different strategies for different x) 74 | ! ------------------------------------------------------------------------ 75 | ! 76 | ! Source: 77 | ! On the evaluation of Boys functions using downward recursion relation 78 | ! B. A. Mamedov 79 | ! Journal of Mathematical Chemistry 80 | ! 2004 81 | ! 82 | ! ------------------------------------------------------------------------ 83 | 84 | IMPLICIT NONE 85 | 86 | REAL*8, EXTERNAL :: DGAMIT 87 | 88 | ! INPUT 89 | INTEGER, intent(in) :: nu ! Boys' index 90 | REAL*8, intent(in) :: x 91 | 92 | ! INTERMEDIATE VARIABLES 93 | !REAL*8 :: prod 94 | !REAL*8 :: sum 95 | !REAL*8 :: sumold 96 | !INTEGER :: idx 97 | 98 | ! OUTPUT 99 | REAL*8 :: boys 100 | 101 | boys = 0.0D0 102 | 103 | IF (x .LE. 1e-6) THEN ! First order Taylor expansion of the integrand 104 | 105 | boys = 1.0D0 / (2.0D0 * nu + 1.0D0) - x / (2.0D0 * nu + 3.0D0) 106 | 107 | ELSE 108 | 109 | boys = 0.5D0 * DGAMIT(nu + 0.5D0, x) * GAMMA(nu + 0.5D0) 110 | 111 | END IF 112 | 113 | END FUNCTION boys 114 | 115 | FUNCTION A(l,r,i,l1,l2,Ra,Rb,Rc,Rp,eps) 116 | ! ------------------------------------- 117 | ! Factor A 118 | ! ------------------------------------- 119 | ! 120 | ! Source: 121 | ! Handbook of Computational Chemistry 122 | ! David Cook 123 | ! Oxford University Press 124 | ! 1998 125 | ! 126 | !-------------------------------------- 127 | 128 | ! INPUT 129 | INTEGER, intent(in) :: l, r, i , l1, l2 130 | REAL*8, intent(in) :: Ra, Rb, Rc, Rp, eps 131 | 132 | ! OUTPUT 133 | REAL*8 :: A 134 | 135 | A = 1.0D0 136 | A = A * (-1)**(l) 137 | A = A * f(l,l1,l2,Rp-Ra,Rp-Rb) 138 | A = A * (-1)**i 139 | A = A * factorial(l) 140 | A = A * (Rp-Rc)**(l - 2*r - 2*i) 141 | A = A * eps**(r+i) 142 | A = A / factorial(r) 143 | A = A / factorial(i) 144 | A = A / factorial(l - 2*r - 2*i) 145 | 146 | END FUNCTION A 147 | 148 | 149 | FUNCTION nuclear_coeff(ax,ay,az,bx,by,bz,aa,bb,Ra,Rb,Rn,Zn) result(Vnn) 150 | ! ------------------------------------------------------------------------- 151 | ! Compute electon-nucleus integral between two Cartesian Gaussian functions 152 | ! ------------------------------------------------------------------------- 153 | ! 154 | ! Source: 155 | ! Handbook of Computational Chemistry 156 | ! David Cook 157 | ! Oxford University Press 158 | ! 1998 159 | ! 160 | !-------------------------------------------------------------------------- 161 | 162 | ! INPUT 163 | INTEGER, intent(in) :: ax, ay, az, bx, by, bz ! Angular momentum coefficients 164 | REAL*8, intent(in) :: aa, bb ! Exponential Gaussian coefficients 165 | REAL*8, dimension(3), intent(in) :: Ra, Rb ! Gaussian centers 166 | REAL*8, dimension(3), intent(in) :: Rn ! Nuclear position 167 | INTEGER, intent(in) :: Zn ! Nuclear charge 168 | 169 | ! INTERMEDIATE VARIABLES 170 | REAL*8 :: eps 171 | REAL*8 :: g ! Gaussian produc exponential coefficient 172 | REAL*8, dimension(3) :: Rp ! Gaussian produc center 173 | REAL*8 :: cp ! Gaussian product multiplicative constant 174 | INTEGER :: l, r, i, m, s, j, n, t, k ! Loop indices 175 | REAL*8 :: AAx, AAy, AAz ! Temporary calls to FUNCTION A 176 | INTEGER :: nu ! Boys function index 177 | 178 | ! OUTPUT 179 | REAL*8 :: Vnn ! Nuclear matrix element 180 | 181 | CALL gaussian_product(aa,bb,Ra,Rb,g,Rp,cp) 182 | 183 | eps = 1.0D0 / (4.0D0 * g) 184 | 185 | Vnn = 0.0D0 186 | 187 | DO l = 0, ax+bx 188 | DO r = 0, FLOOR(l / 2.0) 189 | DO i = 0, FLOOR((l - 2*r)/2.0) 190 | AAx = A(l,r,i,ax,bx,Ra(1),Rb(1),Rn(1),Rp(1),eps) 191 | 192 | DO m = 0, ay+by 193 | DO s = 0, FLOOR(m / 2.0) 194 | DO j = 0, FLOOR((m - 2*s)/2.0) 195 | AAy = A(m,s,j,ay,by,Ra(2),Rb(2),Rn(2),Rp(2),eps) 196 | 197 | DO n = 0, az+bz 198 | DO t = 0, FLOOR(n / 2.0) 199 | DO k = 0, FLOOR((n - 2*t)/2.0) 200 | AAz = A(n,t,k,az,bz,Ra(3),Rb(3),Rn(3),Rp(3),eps) 201 | 202 | nu = l + m + n - 2 * (r + s + t) - (i + j + k) 203 | 204 | Vnn = Vnn + AAx * AAy * AAz * boys(nu,g*DOT_PRODUCT(Rp-Rn,Rp-Rn)) 205 | 206 | END DO ! k 207 | END DO ! t 208 | END DO ! n 209 | END DO ! j 210 | END DO ! s 211 | END DO ! m 212 | END DO ! i 213 | END DO ! r 214 | END DO ! l 215 | 216 | Vnn = Vnn * (-Zn) * norm(ax,ay,az,aa) * norm(bx,by,bz,bb) * cp * 2.0D0 * PI / g 217 | 218 | END FUNCTION nuclear_coeff 219 | 220 | 221 | ! -------------------------------- 222 | ! NUCLEUS-ELECRON POTENTIAL MATRIX 223 | ! -------------------------------- 224 | SUBROUTINE V_nuclear(Kf,c,basis_D,basis_A,basis_L,basis_R,Vn,Rnn,Znn) 225 | ! ------------------------------------------ 226 | ! Compute nucleus-electrona potential matrix 227 | ! ------------------------------------------ 228 | 229 | IMPLICIT NONE 230 | 231 | ! INPUT 232 | INTEGER, intent(in) :: Kf ! Number of basis functions 233 | INTEGER, intent(in) :: c ! Number of contractions (TODO) 234 | REAL*8, dimension(Kf,3), intent(in) :: basis_R ! Basis set niclear positions 235 | INTEGER, dimension(Kf,3), intent(in) :: basis_L ! Basis set angular momenta 236 | REAL*8, dimension(Kf,c), intent(in) :: basis_D ! Basis set contraction coefficients 237 | REAL*8, dimension(Kf,c), intent(in) :: basis_A ! Basis set exponential contraction coefficients 238 | REAL*8, dimension(3), intent(in) :: Rnn ! Nuclear position 239 | INTEGER, intent(in) :: Znn ! Nuclear charge (> 0) 240 | 241 | ! INTERMEDIATE VARIABLES 242 | INTEGER :: i,j,k,l 243 | REAL*8 :: tmp 244 | 245 | ! OUTPUT 246 | REAL*8, dimension(Kf,Kf), intent(out) :: Vn ! Nucleus-electron potential matrix 247 | 248 | Vn(:,:) = 0.0D0 249 | 250 | DO i = 1,Kf 251 | DO j = 1,Kf 252 | DO k = 1,c 253 | DO l = 1,c 254 | tmp = basis_D(i,k) * basis_D(j,l) 255 | tmp = tmp * nuclear_coeff( basis_L(i,1),& ! lx for basis function i 256 | basis_L(i,2),& ! ly for basis function i 257 | basis_L(i,3),& ! lz for basis function i 258 | basis_L(j,1),& ! lx for basis function j 259 | basis_L(j,2),& ! ly for basis function j 260 | basis_L(j,3),& ! lz for basis function j 261 | basis_A(i,k),& ! Exponential coefficient for basis function i, contraction k 262 | basis_A(j,l),& ! Exponential coefficient for basis function j, contraction l 263 | basis_R(i,:),& ! Center of basis function i 264 | basis_R(j,:),& ! Center of basis function j 265 | Rnn,Znn) ! Nuclear position and nuclear charge 266 | 267 | Vn(i,j) = Vn(i,j) + tmp 268 | END DO ! l 269 | END DO ! k 270 | END DO ! j 271 | END DO ! i 272 | 273 | END SUBROUTINE V_nuclear 274 | 275 | 276 | END MODULE NUCLEAR 277 | -------------------------------------------------------------------------------- /Fortran90/output.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | MODULE OUTPUT 21 | 22 | IMPLICIT NONE 23 | 24 | CONTAINS 25 | 26 | ! -------------- 27 | ! PRINT MATRICES 28 | ! -------------- 29 | 30 | SUBROUTINE print_real_matrix(r,c,M) 31 | ! ---------------------------------------------- 32 | ! Print RxC matrix M containing REAL*8 elements. 33 | ! ---------------------------------------------- 34 | 35 | IMPLICIT NONE 36 | 37 | ! INPUT 38 | INTEGER, intent(in) :: r, c 39 | REAL*8, dimension(r,c), intent(in) :: M 40 | 41 | ! VARIABLES 42 | INTEGER :: i 43 | 44 | DO i = 1, r 45 | WRITE(*,'(20G16.6)') M(i,1:c) 46 | END DO 47 | 48 | END SUBROUTINE print_real_matrix 49 | 50 | 51 | 52 | SUBROUTINE print_real_vector(d,v) 53 | ! --------------------------------------------------------- 54 | ! Print vector V of dimension D containing REAL*8 elements. 55 | ! --------------------------------------------------------- 56 | 57 | IMPLICIT NONE 58 | 59 | ! INPUT 60 | INTEGER, intent(in) :: d 61 | REAL*8, dimension(d), intent(in) :: v 62 | 63 | ! INTERMEDIATE VARIABLES 64 | INTEGER :: i 65 | 66 | DO i = 1, d 67 | WRITE(*,'(20G16.6)') v(i) 68 | END DO 69 | 70 | END SUBROUTINE print_real_vector 71 | 72 | SUBROUTINE print_integer_matrix(r,c,M) 73 | ! ----------------------------------------------- 74 | ! Print RxC matrix M containing INTEGER elements. 75 | ! ----------------------------------------------- 76 | 77 | IMPLICIT NONE 78 | 79 | ! INPUT 80 | INTEGER, intent(in) :: r, c 81 | INTEGER, dimension(r,c), intent(in) :: M 82 | 83 | ! VARIABLES 84 | INTEGER :: i 85 | 86 | DO i = 1, r 87 | WRITE(*,'(20I16)') M(i,1:c) 88 | END DO 89 | 90 | END SUBROUTINE print_integer_matrix 91 | 92 | 93 | 94 | 95 | ! --------------------------- 96 | ! ELECTRON-ELECTRON INTEGRALS 97 | ! --------------------------- 98 | SUBROUTINE print_ee_list(Kf,ee) 99 | ! -------------------------------------- 100 | ! Print electron-electron integral list. 101 | ! -------------------------------------- 102 | 103 | IMPLICIT NONE 104 | 105 | ! INPUT 106 | INTEGER, intent(in) :: Kf ! Basis set size 107 | REAL*8, dimension(Kf,Kf,Kf,Kf) :: ee ! List of electron-electron integrals 108 | 109 | ! INTERMEDIATE VARIABLES 110 | INTEGER :: i, j, k, l ! Loop indices 111 | 112 | DO i = 1,Kf 113 | DO j = 1,Kf 114 | DO k = 1,Kf 115 | DO l = 1,Kf 116 | 117 | WRITE(*,*) "(", i, j, k, l, ") ", ee(i,j,k,l) 118 | 119 | END DO ! l 120 | END DO ! k 121 | END DO ! j 122 | END DO ! i 123 | 124 | END SUBROUTINE print_ee_list 125 | 126 | 127 | 128 | ! ------------- 129 | ! APPEND TO XYZ 130 | ! ------------- 131 | SUBROUTINE append_xyz(Nn,atoms,pos,unit) 132 | ! ---------------------------------------------------- 133 | ! Append nuclear positions to XYZ trajectory file 134 | ! ---------------------------------------------------- 135 | ! 136 | ! Note: 137 | ! Nuclear positions in the XYZ file are in Angstroms 138 | ! 139 | ! ---------------------------------------------------- 140 | 141 | IMPLICIT NONE 142 | 143 | ! INPUT 144 | INTEGER, intent(in) :: Nn ! Number of particles 145 | CHARACTER(len=2), dimension(Nn), intent(in) :: atoms ! Atom type 146 | REAL*8, dimension(Nn,3), intent(in) :: pos ! Particles' position 147 | INTEGER, intent(in) :: unit ! Output unit 148 | 149 | ! INTERMEDIATE VARIABLES 150 | INTEGER :: i ! Loop index 151 | 152 | WRITE(unit,*) Nn 153 | WRITE(unit,*) ! TODO: add step number 154 | DO i = 1, Nn 155 | WRITE(unit,*) atoms(i), pos(i,:) * 0.529177249 156 | END DO 157 | 158 | END SUBROUTINE 159 | 160 | END MODULE OUTPUT 161 | -------------------------------------------------------------------------------- /Fortran90/tests/BOMD_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM BOMD_test 21 | 22 | USE INPUT 23 | USE DYNAMICS 24 | USE OUTPUT 25 | 26 | IMPLICIT NONE 27 | 28 | ! System an basis set sizes 29 | INTEGER :: Ne ! Number of electrons 30 | INTEGER :: Nn ! Number of nuclei 31 | INTEGER :: K ! Basis set size 32 | INTEGER :: c ! Contractions (TODO) 33 | 34 | ! System and basis set informations 35 | REAL*8, allocatable, dimension(:,:) :: pos ! Atomic potisions 36 | INTEGER, allocatable, dimension(:) :: Zn ! Atomic charges 37 | REAL*8, allocatable, dimension(:,:) :: basis_R ! Basis functions' centers 38 | INTEGER, allocatable, dimension(:) :: basis_idx ! Basis set atomic index 39 | INTEGER, allocatable, dimension(:,:) :: basis_L ! Basis functions' angular momenta 40 | REAL*8, allocatable, dimension(:,:) :: basis_A ! Contraction exponential coefficients 41 | REAL*8, allocatable, dimension(:,:) :: basis_D ! Conttaction linear coefficients 42 | 43 | REAL*8, allocatable, dimension(:,:) :: F ! Forces 44 | 45 | CHARACTER (len=5) :: calculation ! Type of calculation 46 | CHARACTER (len=3) :: method ! Type of calculation 47 | 48 | REAL*8, allocatable, dimension(:,:) :: vel ! Nuclear velocities 49 | REAL*8, allocatable, dimension(:) :: mass ! Nuclear mass 50 | CHARACTER(len=2), allocatable, dimension(:) :: atoms ! Atom name 51 | 52 | ! BOMD parameters 53 | 54 | INTEGER :: i 55 | INTEGER, PARAMETER :: steps = 1000 56 | REAL*8, PARAMETER:: dt = 1e-3 57 | 58 | ! ------------------------------------------------ 59 | ! LOAD SYSTEM AND BASIS SET INFORMATIONS FROM FILE 60 | ! ------------------------------------------------ 61 | 62 | CALL load("tests/H2_f_stretched.in",calculation,method,Ne,Nn,K,c,pos,Zn,basis_R,basis_L,basis_A,basis_D,basis_idx) 63 | 64 | ALLOCATE(F(Nn,3),mass(Nn),vel(Nn,3),atoms(Nn)) 65 | 66 | vel(1,:) = (/0.0D0, 0.0D0, 0.0D0/) 67 | vel(2,:) = (/0.0D0, 0.0D0, 0.0D0/) 68 | 69 | mass = (/1.008D0, 1.0008D0/) 70 | 71 | atoms = (/"H","H"/) 72 | 73 | ! ---- 74 | ! BOMD 75 | ! ---- 76 | 77 | ! Initial force 78 | CALL force_fd(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,pos,F,1D-4,"UHF") 79 | 80 | OPEN(unit=123,file="BOMD.xyz",form="formatted",status="new",action="write") ! Open file 123 81 | 82 | DO i = 1, steps 83 | WRITE(*,*) "Step", i 84 | WRITE(*,*) "Distance: ", DSQRT(DOT_PRODUCT(pos(1,:)-pos(2,:),pos(1,:)-pos(2,:))) 85 | CALL append_xyz(Nn,atoms,pos,123) 86 | CALL BO_step(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,mass,pos,vel,F,dt,"UHF") 87 | END DO 88 | 89 | CLOSE(unit=123) ! Close file 123 90 | 91 | ! --- 92 | ! END 93 | ! --- 94 | 95 | DEALLOCATE(pos,Zn,basis_R,basis_L,basis_A,basis_D,F,vel,mass) ! Deallocate allocated memory 96 | 97 | END PROGRAM BOMD_test 98 | -------------------------------------------------------------------------------- /Fortran90/tests/DIIS_test.f90: -------------------------------------------------------------------------------- 1 | PROGRAM DIIS_test 2 | 3 | USE DIIS 4 | USE OUTPUT 5 | 6 | IMPLICIT NONE 7 | 8 | REAL*8, dimension(3,3) :: A 9 | REAL*8, dimension(3*3) :: B 10 | REAL*8, dimension(3,3) :: C 11 | REAL*8, dimension(3,3) :: D 12 | REAL*8, dimension(3*3) :: E 13 | REAL*8, allocatable, dimension(:,:) :: F 14 | REAL*8 :: maxerr 15 | REAL*8, allocatable, dimension(:) :: w 16 | REAL*8, allocatable, dimension(:,:) :: Elist 17 | REAL*8, allocatable, dimension(:,:,:) :: Mlist 18 | 19 | INTEGER :: info, dim, i, j 20 | 21 | A(1,:) = (/1.0D0, 2.0D0, 3.0D0/) 22 | A(2,:) = (/4.0D0, 5.0D0, 6.0D0/) 23 | A(3,:) = (/7.0D0, 8.0D0, 9.0D0/) 24 | 25 | WRITE(*,*) "Matrix A:" 26 | CALL print_real_matrix(3,3,A) 27 | 28 | CALL ravel(3,A,B) 29 | 30 | WRITE(*,*) 31 | WRITE(*,*) "Vector B (ravel(A)):" 32 | 33 | CALL print_real_vector(3*3,B) 34 | 35 | A(1,:) = (/0.0D0, 1.0D0, 0.0D0/) 36 | A(2,:) = (/-1.0D0, 0.0D0, 0.0D0/) 37 | A(3,:) = (/0.0D0, 0.0D0, 1.0D0/) 38 | 39 | C(1,:) = (/1.0D0, 0.0D0, 0.0D0/) 40 | C(2,:) = (/0.0D0, 0.0D0, 1.0D0/) 41 | C(3,:) = (/0.0D0, -1.0D0, 0.0D0/) 42 | 43 | D(1,:) = (/1.0D0, 0.0D0, 0.0D0/) 44 | D(2,:) = (/0.0D0, 1.0D0, 0.0D0/) 45 | D(3,:) = (/0.0D0, 0.0D0, 1.0D0/) 46 | 47 | CALL DIIS_error(3,A,C,D,D,E,maxerr) 48 | 49 | WRITE(*,*) 50 | WRITE(*,*) "Error matrix:" 51 | 52 | CALL print_real_matrix(3,3,MATMUL(A,MATMUL(C,D)) - MATMUL(D,MATMUL(C,A))) 53 | 54 | WRITE(*,*) 55 | WRITE(*,*) "Error E:" 56 | 57 | CALL print_real_vector(3*3,E) 58 | 59 | WRITE(*,*) 60 | WRITE(*,*) "Maxerr: ", maxerr 61 | 62 | CALL addError(3,1,Elist,E) 63 | CALL addError(3,2,Elist,E) 64 | CALL addError(3,3,Elist,E) 65 | 66 | WRITE(*,*) 67 | WRITE(*,*) "Elist(1):" 68 | 69 | CALL print_real_vector(3*3,Elist(1,:)) 70 | 71 | WRITE(*,*) 72 | WRITE(*,*) "Elist(2):" 73 | 74 | CALL print_real_vector(3*3,Elist(2,:)) 75 | 76 | WRITE(*,*) 77 | WRITE(*,*) "Elist(3):" 78 | 79 | CALL print_real_vector(3*3,Elist(3,:)) 80 | 81 | WRITE(*,*) 82 | WRITE(*,*) "Elist:" 83 | 84 | CALL print_real_matrix(3,3*3,Elist) 85 | 86 | ALLOCATE(F(4,4),w(3)) 87 | 88 | CALL DIIS_B(3,elist,3,F) 89 | 90 | WRITE(*,*) 91 | WRITE(*,*) "Matrix F:" 92 | 93 | CALL print_real_matrix(4,4,F) 94 | 95 | dim = 4 96 | info = -1 97 | 98 | DO WHILE(info .NE. 0) 99 | 100 | CALL DIIS_weigts(dim,F,w,info) 101 | 102 | IF (info .NE. 0) THEN 103 | WRITE(*,*) 104 | WRITE(*,*) "IMPOSSIBLE TO SOLVE THE LINEAR SYSTEM: REDUCING MATRIX F" 105 | 106 | CALL DIIS_reduce_B(dim,F) 107 | 108 | dim = dim - 1 109 | 110 | WRITE(*,*) 111 | WRITE(*,*) "Reduced matrix F:" 112 | 113 | CALL print_real_matrix(dim,dim,F) 114 | 115 | DEALLOCATE(w) 116 | ALLOCATE(w(dim-1)) 117 | END IF 118 | 119 | END DO 120 | 121 | WRITE(*,*) 122 | WRITE(*,*) "Weights:" 123 | 124 | CALL print_real_vector(dim-1,w) 125 | 126 | CALL addFock(3,1,Mlist,A) 127 | CALL addFock(3,2,Mlist,2*A) 128 | CALL addFock(3,3,Mlist,3*A) 129 | 130 | j = 3 131 | 132 | A(:,:) = 0.0D0 133 | 134 | DO i = 1,dim-1 135 | 136 | A = A + w(i) * Mlist(j,:,:) 137 | 138 | j = j - 1 139 | 140 | END DO 141 | 142 | WRITE(*,*) 143 | WRITE(*,*) "New operator A:" 144 | 145 | CALL print_real_matrix(3,3,A) 146 | 147 | END PROGRAM DIIS_test 148 | -------------------------------------------------------------------------------- /Fortran90/tests/H2O_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM HF_H2O 21 | 22 | USE RHF 23 | 24 | IMPLICIT NONE 25 | 26 | INTEGER, PARAMETER :: c = 3 27 | 28 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 29 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for O 30 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for O 31 | 32 | ! ----------------- 33 | ! BASIS SET FOR H2O 34 | ! ----------------- 35 | INTEGER, PARAMETER :: K = 7 ! Number of basis functions 36 | INTEGER, PARAMETER :: Nn = 3 ! Number of nuclei 37 | 38 | INTEGER, dimension(K,3) :: basis_L ! Angular momenta of basis set Gaussians 39 | REAL*8, dimension(K,3) :: basis_R ! Centers of basis set Gaussians 40 | REAL*8, dimension(K,c) :: basis_D, basis_A ! Basis set coefficients 41 | 42 | ! ------------ 43 | ! MOLECULE H2O 44 | ! ------------ 45 | 46 | REAL*8, dimension(Nn,3) :: Rn ! Nuclear positions 47 | INTEGER, dimension(Nn) :: Zn ! Nuclear charges 48 | 49 | INTEGER, PARAMETER :: Ne = 10 ! Total number of electrons 50 | 51 | REAL*8 :: final_E ! Total converged energy 52 | 53 | Rn(1,1:3) = (/1.809*SIN(104.52/180*PI/2.0D0), 0.0D0, 0.0D0/) ! Position of first H atom 54 | Rn(2,1:3) = (/-1.809*SIN(104.52/180*PI/2.0D0), 0.0D0, 0.0D0/) ! Position of the second H atom 55 | Rn(3,1:3) = (/0.0D0, 1.809*COS(104.52/180*PI/2.0D0), 0.0D0/) ! Position of the O atom 56 | 57 | Zn = (/1, 1, 8/) 58 | 59 | basis_R(1,1:3) = Rn(1,1:3) ! Center of H1 1s 60 | basis_R(2,1:3) = Rn(2,1:3) ! Center of H2 1s 61 | basis_R(3,1:3) = Rn(3,1:3) ! Center of O 1s 62 | basis_R(4,1:3) = Rn(3,1:3) ! Center of O 2s 63 | basis_R(5,1:3) = Rn(3,1:3) ! Center of O 2px 64 | basis_R(6,1:3) = Rn(3,1:3) ! Center of O 2py 65 | basis_R(7,1:3) = Rn(3,1:3) ! Center of O 2pz 66 | 67 | basis_L(1,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 68 | basis_L(2,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 69 | basis_L(3,1:3) = (/0, 0, 0/) ! Angular momenta for O 1s 70 | basis_L(4,1:3) = (/0, 0, 0/) ! Angular momenta for O 2s 71 | basis_L(5,1:3) = (/1, 0, 0/) ! Angular momenta for O 2px 72 | basis_L(6,1:3) = (/0, 1, 0/) ! Angular momenta for O 2py 73 | basis_L(7,1:3) = (/0, 0, 1/) ! Angular momenta for O 2pz 74 | 75 | basis_D(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 76 | basis_D(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 77 | basis_D(3,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 78 | basis_D(4,1:c) = (/0.700115D0, 0.399513D0, -0.0999672D0/) 79 | basis_D(5,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 80 | basis_D(6,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 81 | basis_D(7,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 82 | 83 | basis_A(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 84 | basis_A(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 85 | basis_A(3,1:c) = (/0.109818D0 * zeta_O_1**2, 0.405771 * zeta_O_1**2, 2.22766 * zeta_O_1**2/) 86 | basis_A(4,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 87 | basis_A(5,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 88 | basis_A(6,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 89 | basis_A(7,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 90 | 91 | ! ------------------------ 92 | ! TOTAL ENERGY CALCULATION 93 | ! ------------------------ 94 | 95 | CALL RHF_SCF(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,Zn,Rn,final_E,.TRUE.) 96 | 97 | END PROGRAM HF_H2O 98 | -------------------------------------------------------------------------------- /Fortran90/tests/H2_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM HF_H2 21 | 22 | USE RHF 23 | 24 | IMPLICIT NONE 25 | 26 | INTEGER, PARAMETER :: c = 3 27 | 28 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 29 | 30 | ! ------------------ 31 | ! BASIS SET FOR HeH+ 32 | ! ------------------ 33 | INTEGER, PARAMETER :: K = 2 ! Number of basis functions 34 | INTEGER, PARAMETER :: Nn = 2 ! Number of nuclei 35 | 36 | INTEGER, dimension(K,3) :: basis_L ! Angular momenta of basis set Gaussians 37 | REAL*8, dimension(K,3) :: basis_R ! Centers of basis set Gaussians 38 | REAL*8, dimension(K,c) :: basis_D, basis_A ! Basis set coefficients 39 | 40 | ! ----------- 41 | ! MOLECULE H2 42 | ! ----------- 43 | 44 | REAL*8, dimension(Nn,3) :: Rn ! Nuclear positions 45 | INTEGER, dimension(Nn) :: Zn ! Nuclear charges 46 | 47 | INTEGER, PARAMETER :: Ne = 2 ! Total number of electrons 48 | 49 | REAL*8 :: final_E ! Total converged energy 50 | 51 | Rn(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 52 | Rn(2,1:3) = (/1.4D0, 0.0D0, 0.0D0/) ! Position of the second H atom 53 | 54 | Zn = (/1, 1/) 55 | 56 | basis_R(1,1:3) = Rn(1,1:3) ! Position of first H atom 57 | basis_R(2,1:3) = Rn(2,1:3) ! Position of the second H atom 58 | 59 | basis_L(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 60 | basis_L(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 61 | 62 | basis_D(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 63 | basis_D(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 64 | 65 | basis_A(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 66 | basis_A(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 67 | 68 | ! ------------------------ 69 | ! TOTAL ENERGY CALCULATION 70 | ! ------------------------ 71 | 72 | CALL RHF_SCF(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,Zn,Rn,final_E,.TRUE.) 73 | 74 | END PROGRAM HF_H2 75 | -------------------------------------------------------------------------------- /Fortran90/tests/HeH_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM HF 21 | 22 | USE RHF 23 | 24 | IMPLICIT NONE 25 | 26 | INTEGER, PARAMETER :: c = 3 27 | 28 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 29 | REAL*8, PARAMETER :: zeta_He = 2.0925D0 ! STO coefficient correction for He 30 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for He 31 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for He 32 | 33 | ! ------------------ 34 | ! BASIS SET FOR HeH+ 35 | ! ------------------ 36 | INTEGER, PARAMETER :: K = 2 ! Number of basis functions 37 | INTEGER, PARAMETER :: Nn = 2 ! Number of nuclei 38 | 39 | INTEGER, dimension(K,3) :: basis_L ! Angular momenta of basis set Gaussians 40 | REAL*8, dimension(K,3) :: basis_R ! Centers of basis set Gaussians 41 | REAL*8, dimension(K,c) :: basis_D, basis_A ! Basis set coefficients 42 | 43 | ! ------------- 44 | ! MOLECULE HeH+ 45 | ! ------------- 46 | 47 | REAL*8, dimension(Nn,3) :: Rn ! Nuclear positions 48 | INTEGER, dimension(Nn) :: Zn ! Nuclear charges 49 | 50 | INTEGER, PARAMETER :: Ne = 2 ! Total number of electrons 51 | 52 | REAL*8 :: final_E ! Total converged energy 53 | 54 | Rn(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 55 | Rn(2,1:3) = (/1.4632D0, 0.0D0, 0.0D0/) ! Position of the second H atom 56 | 57 | Zn = (/1, 2/) 58 | 59 | basis_R(1,1:3) = Rn(1,1:3) ! Position of the H atom 60 | basis_R(2,1:3) = Rn(2,1:3) ! Position of the He atom 61 | 62 | basis_L(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 63 | basis_L(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 64 | 65 | basis_D(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 66 | basis_D(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 67 | 68 | basis_A(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 69 | basis_A(2,1:c) = (/0.109818D0 * zeta_He**2, 0.405771 * zeta_He**2, 2.22766 * zeta_He**2/) 70 | 71 | ! ------------------------ 72 | ! TOTAL ENERGY CALCULATION 73 | ! ------------------------ 74 | 75 | CALL RHF_SCF(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,Zn,Rn,final_E,.TRUE.) 76 | 77 | END PROGRAM HF 78 | -------------------------------------------------------------------------------- /Fortran90/tests/N2.in: -------------------------------------------------------------------------------- 1 | STO-3G 2 | 14 3 | N 2.074 0.000 0.000 4 | N 0.000 0.000 0.000 5 | -------------------------------------------------------------------------------- /Fortran90/tests/N2_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM HF_N2 21 | 22 | USE INPUT 23 | USE RHF 24 | 25 | IMPLICIT NONE 26 | 27 | ! System an basis set sizes 28 | INTEGER :: Ne ! Number of electrons 29 | INTEGER :: Nn ! Number of nuclei 30 | INTEGER :: K ! Basis set size 31 | INTEGER :: c ! Contractions (TODO) 32 | 33 | ! System and basis set informations 34 | REAL*8, allocatable, dimension(:,:) :: Rn ! Atomic potisions 35 | INTEGER, allocatable, dimension(:) :: Zn ! Atomic charges 36 | REAL*8, allocatable, dimension(:,:) :: basis_R ! Basis functions' centers 37 | INTEGER, allocatable, dimension(:,:) :: basis_L ! Basis functions' angular momenta 38 | REAL*8, allocatable, dimension(:,:) :: basis_A ! Contraction exponential coefficients 39 | REAL*8, allocatable, dimension(:,:) :: basis_D ! Conttaction linear coefficients 40 | 41 | REAL*8 :: final_E ! Total converged energy 42 | 43 | ! ------------------------------------------------ 44 | ! LOAD SYSTEM AND BASIS SET INFORMATIONS FROM FILE 45 | ! ------------------------------------------------ 46 | 47 | CALL load("tests/N2_f.in",Ne,Nn,K,c,Rn,Zn,basis_R,basis_L,basis_A,basis_D) 48 | 49 | ! ------------------------ 50 | ! TOTAL ENERGY CALCULATION 51 | ! ------------------------ 52 | 53 | CALL RHF_SCF(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,Zn,Rn,final_E,.TRUE.) 54 | 55 | DEALLOCATE(Rn,Zn,basis_R,basis_L,basis_A,basis_D) ! Deallocate allocated memory 56 | 57 | END PROGRAM HF_N2 58 | -------------------------------------------------------------------------------- /Fortran90/tests/boys_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM boys_test 21 | 22 | USE NUCLEAR, only: boys 23 | 24 | ! ------------------------------------------------------------------------ 25 | ! 26 | ! Source: 27 | ! On the evaluation of Boys functions using downward recursion relation 28 | ! B. A. Mamedov 29 | ! Journal of Mathematical Chemistry 30 | ! 2004 31 | ! 32 | ! ------------------------------------------------------------------------ 33 | 34 | WRITE(*,*) 8, 16, boys(8,16.0D0) 35 | WRITE(*,*) 15, 27, boys(15,27.0D0) 36 | WRITE(*,*) 20, 30, boys(2,30.0D0) 37 | WRITE(*,*) 25, 13, boys(25,13.0D0) 38 | WRITE(*,*) 75, 30, boys(75,30.0D0) 39 | 40 | WRITE(*,*) 41 | 42 | WRITE(*,*) 8, 42, boys(8,42.0D0) 43 | WRITE(*,*) 16, 50, boys(16,50.0D0) 44 | WRITE(*,*) 21, 56, boys(21,56.0D0) 45 | WRITE(*,*) 12, 60, boys(12,60.0D0) 46 | WRITE(*,*) 18, 58, boys(18,58.0D0) 47 | 48 | WRITE(*,*) 49 | WRITE(*,*) 8, 63, boys(8,63.0D0) 50 | WRITE(*,*) 33, 85, boys(33,85.0D0) 51 | WRITE(*,*) 100, 120, boys(100,120.0D0) 52 | 53 | 54 | END PROGRAM boys_test 55 | -------------------------------------------------------------------------------- /Fortran90/tests/classicalMD_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM classicalMD 21 | 22 | USE DYNAMICS, only: classical_step 23 | USE OUTPUT 24 | 25 | IMPLICIT NONE 26 | 27 | INTEGER, PARAMETER :: steps = 1000 28 | REAL*8, PARAMETER:: dt = 1e-3 29 | 30 | INTEGER :: i ! Loop index 31 | 32 | INTEGER, PARAMETER :: Nn = 3 33 | CHARACTER(len=2), dimension(Nn) :: atoms 34 | REAL*8, dimension(Nn,3) :: pos 35 | REAL*8, dimension(Nn,3) :: vel 36 | REAL*8, dimension(Nn,3) :: force 37 | REAL*8, dimension(Nn) :: mass 38 | 39 | atoms = (/"H","H"/) 40 | 41 | pos(1,:) = (/0.0D0, 0.0D0, 0.0D0/) 42 | pos(2,:) = (/1.2*1.0D0, 0.0D0, 0.0D0/) 43 | pos(3,:) = (/0.5*1.0D0, 1.3*1.0D0, 0.0D0/) 44 | 45 | vel(1,:) = (/0.0D0, 0.0D0, 0.0D0/) 46 | vel(2,:) = (/0.0D0, 0.0D0, 0.0D0/) 47 | vel(3,:) = (/0.0D0, 0.0D0, 0.0D0/) 48 | 49 | force = (-1) * dU(Nn,pos) ! Compute the initial force 50 | 51 | mass = (/1.0D0, 1.0D0, 10.0D0/) 52 | 53 | OPEN(unit=123,file="classicalMD.xyz",form="formatted",status="new",action="write") ! Open file 123 54 | 55 | DO i = 1, steps 56 | CALL append_xyz(Nn,atoms,pos,123) 57 | CALL classical_step(Nn,mass,pos,vel,force,dU,dt) 58 | END DO 59 | 60 | CLOSE(unit=123) ! Close file 123 61 | 62 | CONTAINS 63 | FUNCTION dU(Nn,pos) 64 | 65 | ! INPUT 66 | INTEGER, intent(in) :: Nn ! Number of particles 67 | REAL*8, dimension(Nn,3), intent(in) :: pos ! Particle's position 68 | 69 | ! OUTPUT 70 | REAL*8, dimension(Nn,3) :: dU ! Gradient of the PES 71 | 72 | ! PARAMETERS 73 | REAL*8, PARAMETER :: k = 500 ! Spring constant (TODO: different force constant for different interactions) 74 | REAL*8, PARAMETER :: d = 1 ! Equilibrium distance (TODO: different equilibrium distance for different interactions) 75 | 76 | ! INTERMEDIATE VARIABLES 77 | REAL*8 :: r, dx, dy, dz 78 | INTEGER :: i, j ! Loop indices 79 | 80 | dU(:,:) = 0.0D0 81 | 82 | DO i = 1, Nn-1 83 | DO j = i+1, Nn 84 | dx = pos(i,1) - pos(j,1) 85 | dy = pos(i,2) - pos(j,2) 86 | dz = pos(i,3) - pos(j,3) 87 | 88 | r = DSQRT(dx**2 + dy**2 + dz**2) 89 | 90 | dU(i,1) = dU(i,1) - k * (d - r) / r * dx 91 | dU(i,2) = dU(i,2) - k * (d - r) / r * dy 92 | dU(i,3) = dU(i,3) - k * (d - r) / r * dz 93 | 94 | dU(j,1) = dU(j,1) + k * (d - r) / r * dx 95 | dU(j,2) = dU(j,2) + k * (d - r) / r * dy 96 | dU(j,3) = dU(j,3) + k * (d - r) / r * dz 97 | END DO 98 | END DO 99 | 100 | 101 | END FUNCTION 102 | 103 | END PROGRAM classicalMD 104 | -------------------------------------------------------------------------------- /Fortran90/tests/core_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM core_test 21 | 22 | USE CORE 23 | USE OUTPUT, only: print_real_matrix 24 | 25 | IMPLICIT NONE 26 | 27 | INTEGER, PARAMETER :: c = 3 ! Number of contractions (STO-3G) 28 | 29 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 30 | REAL*8, PARAMETER :: zeta_He = 2.0925D0 ! STO coefficient correction for He 31 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for He 32 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for He 33 | 34 | ! ---------------- 35 | ! BASIS SET FOR H2 36 | ! ---------------- 37 | INTEGER, PARAMETER :: K_H2 = 2 ! Number of basis functions 38 | INTEGER, PARAMETER :: Nn_H2 = 2 ! Number of nuclei 39 | 40 | INTEGER, dimension(K_H2,3) :: basis_L_H2 ! Angular momenta of basis set Gaussians 41 | REAL*8, dimension(K_H2,3) :: basis_R_H2 ! Centers of basis set Gaussians 42 | REAL*8, dimension(K_H2,c) :: basis_D_H2, basis_A_H2 ! Basis set coefficients 43 | 44 | REAL*8, dimension(K_H2,K_H2) :: Hcore_H2 ! Core Hamiltonian 45 | 46 | REAL*8, dimension(Nn_H2,3) :: R_H2 ! Nuclear positions 47 | INTEGER, dimension(Nn_H2) :: Zn_H2 ! Nuclear charges 48 | 49 | ! ------------------ 50 | ! BASIS SET FOR HeH+ 51 | ! ------------------ 52 | INTEGER, PARAMETER :: K_HeH = 2 ! Number of basis functions 53 | INTEGER, PARAMETER :: Nn_HeH = 2 ! Number of nuclei 54 | 55 | INTEGER, dimension(K_HeH,3) :: basis_L_HeH ! Angular momenta of basis set Gaussians 56 | REAL*8, dimension(K_HeH,3) :: basis_R_HeH ! Centers of basis set Gaussians 57 | REAL*8, dimension(K_HeH,c) :: basis_D_HeH, basis_A_HeH ! Basis set coefficients 58 | 59 | REAL*8, dimension(K_HeH,K_HeH) :: Hcore_HeH ! Core Hamiltonian 60 | 61 | REAL*8, dimension(Nn_HeH,3) :: R_HeH ! Nuclear positions 62 | INTEGER, dimension(Nn_HeH) :: Zn_HeH ! Nuclear charges 63 | 64 | ! ----------------- 65 | ! BASIS SET FOR H2O 66 | ! ----------------- 67 | INTEGER, PARAMETER :: K_H2O = 7 ! Number of basis functions 68 | INTEGER, PARAMETER :: Nn_H2O = 3 ! Number of nuclei 69 | 70 | INTEGER, dimension(K_H2O,3) :: basis_L_H2O ! Angular momenta of basis set Gaussians 71 | REAL*8, dimension(K_H2O,3) :: basis_R_H2O ! Centers of basis set Gaussians 72 | REAL*8, dimension(K_H2O,c) :: basis_D_H2O, basis_A_H2O ! Basis set coefficients 73 | 74 | REAL*8, dimension(K_H2O,K_H2O) :: Hcore_H2O ! Core Hamiltonian 75 | 76 | REAL*8, dimension(Nn_H2O,3) :: R_H2O ! Nuclear positions 77 | INTEGER, dimension(Nn_H2O) :: Zn_H2O ! Nuclear charges 78 | 79 | ! ----------- 80 | ! MOLECULE H2 81 | ! ----------- 82 | 83 | R_H2(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 84 | R_H2(2,1:3) = (/1.4D0, 0.0D0, 0.0D0/) ! Position of the second H atom 85 | 86 | Zn_H2 = (/1, 1/) 87 | 88 | basis_R_H2(1,1:3) = R_H2(1,1:3) 89 | basis_R_H2(2,1:3) = R_H2(2,1:3) 90 | 91 | basis_L_H2(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 92 | basis_L_H2(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 93 | 94 | basis_D_H2(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 95 | basis_D_H2(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 96 | 97 | basis_A_H2(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 98 | basis_A_H2(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 99 | 100 | WRITE(*,*) "###########" 101 | WRITE(*,*) "Molecule H2" 102 | WRITE(*,*) "###########" 103 | 104 | CALL H_core(K_H2,Nn_H2,basis_D_H2,basis_A_H2,basis_L_H2,basis_R_H2,R_H2,Zn_H2,Hcore_H2) 105 | 106 | WRITE(*,*) "Core Hamiltonian:" 107 | CALL print_real_matrix(K_H2,K_H2,Hcore_H2) 108 | 109 | ! ------------ 110 | ! MOLECULE He+ 111 | ! ------------ 112 | 113 | R_HeH(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 114 | R_HeH(2,1:3) = (/1.4632D0, 0.0D0, 0.0D0/) ! Position of the second H atom 115 | 116 | Zn_HeH = (/1, 2/) 117 | 118 | basis_R_HeH(1,1:3) = R_HeH(1,1:3) ! Position of the H atom 119 | basis_R_HeH(2,1:3) = R_HeH(2,1:3) ! Position of the He atom 120 | 121 | basis_L_HeH(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 122 | basis_L_HeH(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 123 | 124 | basis_D_HeH(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 125 | basis_D_HeH(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 126 | 127 | basis_A_HeH(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 128 | basis_A_HeH(2,1:c) = (/0.109818D0 * zeta_He**2, 0.405771 * zeta_He**2, 2.22766 * zeta_He**2/) 129 | 130 | WRITE(*,*) "#############" 131 | WRITE(*,*) "Molecule HeH+" 132 | WRITE(*,*) "#############" 133 | 134 | CALL H_core(K_HeH,Nn_HeH,basis_D_HeH,basis_A_HeH,basis_L_HeH,basis_R_HeH,R_HeH,Zn_HeH,Hcore_HeH) 135 | 136 | WRITE(*,*) "Core Hamiltonian:" 137 | CALL print_real_matrix(K_HeH,K_HeH,Hcore_HeH) 138 | 139 | ! ------------ 140 | ! MOLECULE H2O 141 | ! ------------ 142 | 143 | R_H2O(1,1:3) = (/0.0D0, 1.43233673D0, -0.96104039D0/) ! Position of first H atom 144 | R_H2O(2,1:3) = (/0.0D0, -1.43233673D0, -0.96104039D0/) ! Position of the second H atom 145 | R_H2O(3,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) 146 | 147 | Zn_H2O = (/1, 1, 8/) 148 | 149 | basis_R_H2O(1,1:3) = R_H2O(1,1:3) ! Center of H1 1s 150 | basis_R_H2O(2,1:3) = R_H2O(2,1:3) ! Center of H2 1s 151 | basis_R_H2O(3,1:3) = R_H2O(3,1:3) ! Center of O 1s 152 | basis_R_H2O(4,1:3) = R_H2O(3,1:3) ! Center of O 2s 153 | basis_R_H2O(5,1:3) = R_H2O(3,1:3) ! Center of O 2px 154 | basis_R_H2O(6,1:3) = R_H2O(3,1:3) ! Center of O 2py 155 | basis_R_H2O(7,1:3) = R_H2O(3,1:3) ! Center of O 2pz 156 | 157 | basis_L_H2O(1,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 158 | basis_L_H2O(2,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 159 | basis_L_H2O(3,1:3) = (/0, 0, 0/) ! Angular momenta for O 1s 160 | basis_L_H2O(4,1:3) = (/0, 0, 0/) ! Angular momenta for O 2s 161 | basis_L_H2O(5,1:3) = (/1, 0, 0/) ! Angular momenta for O 2px 162 | basis_L_H2O(6,1:3) = (/0, 1, 0/) ! Angular momenta for O 2py 163 | basis_L_H2O(7,1:3) = (/0, 0, 1/) ! Angular momenta for O 2pz 164 | 165 | basis_D_H2O(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 166 | basis_D_H2O(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 167 | basis_D_H2O(3,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 168 | basis_D_H2O(4,1:c) = (/0.700115D0, 0.399513D0, -0.0999672D0/) 169 | basis_D_H2O(5,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 170 | basis_D_H2O(6,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 171 | basis_D_H2O(7,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 172 | 173 | basis_A_H2O(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 174 | basis_A_H2O(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 175 | basis_A_H2O(3,1:c) = (/0.109818D0 * zeta_O_1**2, 0.405771 * zeta_O_1**2, 2.22766 * zeta_O_1**2/) 176 | basis_A_H2O(4,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 177 | basis_A_H2O(5,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 178 | basis_A_H2O(6,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 179 | basis_A_H2O(7,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 180 | 181 | WRITE(*,*) "############" 182 | WRITE(*,*) "Molecule H2O" 183 | WRITE(*,*) "############" 184 | 185 | CALL H_core(K_H2O,Nn_H2O,basis_D_H2O,basis_A_H2O,basis_L_H2O,basis_R_H2O,R_H2O,Zn_H2O,Hcore_H2O) 186 | 187 | WRITE(*,*) "Core Hamiltonian:" 188 | CALL print_real_matrix(K_H2O,K_H2O,Hcore_H2O) 189 | 190 | END PROGRAM core_test 191 | -------------------------------------------------------------------------------- /Fortran90/tests/eigs_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM eigs_test 21 | 22 | USE LA, only: EIGS 23 | USE OUTPUT, only: print_real_matrix 24 | 25 | INTEGER, PARAMETER :: d = 2 26 | 27 | REAL*8, dimension(d,d) :: A 28 | REAL*8, dimension(d,d) :: V 29 | REAL*8, dimension(d) :: l 30 | 31 | A(1,:) = (/-1.53866, -0.515838/) 32 | A(2,:) = (/-0.515838, -2.43973/) 33 | 34 | CALL EIGS(d,A,V,l) 35 | 36 | WRITE(*,*) "Matrix A" 37 | CALL print_real_matrix(d,d,A) 38 | 39 | WRITE(*,*) "Matrix V" 40 | CALL print_real_matrix(d,d,V) 41 | 42 | WRITE(*,*) "Vector l" 43 | CALL print_real_matrix(d,1,l) 44 | 45 | END PROGRAM eigs_test 46 | -------------------------------------------------------------------------------- /Fortran90/tests/electronic_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM electronic_test 21 | 22 | USE ELECTRONIC 23 | USE OUTPUT, only: print_ee_list 24 | 25 | IMPLICIT NONE 26 | 27 | ! TODO allows flexibility 28 | INTEGER, PARAMETER :: c = 3 ! Number of contractions (STO-3G) 29 | 30 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 31 | REAL*8, PARAMETER :: zeta_He = 2.0925D0 ! STO coefficient correction for He 32 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for He 33 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for He 34 | 35 | ! ------------------ 36 | ! BASIS SET FOR HeH+ 37 | ! ------------------ 38 | INTEGER, PARAMETER :: K_HeH = 2 ! Number of basis functions 39 | INTEGER, PARAMETER :: Nn_HeH = 2 ! Number of nuclei 40 | 41 | INTEGER, dimension(K_HeH,3) :: basis_L_HeH ! Angular momenta of basis set Gaussians 42 | REAL*8, dimension(K_HeH,3) :: basis_R_HeH ! Centers of basis set Gaussians 43 | REAL*8, dimension(K_HeH,c) :: basis_D_HeH, basis_A_HeH ! Basis set coefficients 44 | 45 | REAL*8, dimension(K_HeH,K_HeH) :: Vn1_HeH ! Nucleus-electron interaction matrix 46 | REAL*8, dimension(K_HeH,K_HeH) :: Vn2_HeH ! Nucleus-electron interaction matrix 47 | 48 | REAL*8, dimension(Nn_HeH,3) :: R_HeH ! Nuclear positions 49 | INTEGER, dimension(Nn_HeH) :: Zn_HeH ! Nuclear charges 50 | 51 | ! ------------- 52 | ! MOLECULE HeH+ 53 | ! ------------- 54 | 55 | REAL*8, dimension(K_HeH,K_HeH,K_HeH,K_HeH) :: ee_HeH 56 | 57 | R_HeH(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 58 | R_HeH(2,1:3) = (/1.4632D0, 0.0D0, 0.0D0/) ! Position of the second H atom 59 | 60 | Zn_HeH = (/1, 2/) 61 | 62 | basis_R_HeH(1,1:3) = R_HeH(1,1:3) ! Position of the H atom 63 | basis_R_HeH(2,1:3) = R_HeH(2,1:3) ! Position of the He atom 64 | 65 | basis_L_HeH(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 66 | basis_L_HeH(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 67 | 68 | basis_D_HeH(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 69 | basis_D_HeH(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 70 | 71 | basis_A_HeH(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 72 | basis_A_HeH(2,1:c) = (/0.109818D0 * zeta_He**2, 0.405771 * zeta_He**2, 2.22766 * zeta_He**2/) 73 | 74 | WRITE(*,*) "#############" 75 | WRITE(*,*) "Molecule HeH+" 76 | WRITE(*,*) "#############" 77 | 78 | CALL ee_list(K_HeH,basis_D_HeH,basis_A_HeH,basis_L_HeH,basis_R_HeH,ee_HeH) 79 | 80 | WRITE(*,*) "HeH+ electron-electron integrals:" 81 | CALL print_ee_list(K_HeH,ee_HeH) 82 | 83 | END PROGRAM electronic_test 84 | -------------------------------------------------------------------------------- /Fortran90/tests/factorial_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM factorial_test 21 | 22 | USE FACT 23 | 24 | IMPLICIT NONE 25 | 26 | INTEGER :: i 27 | INTEGER, PARAMETER :: N = 10 28 | 29 | DO i = 0,N 30 | WRITE(*,*) i, "! =", factorial(i) 31 | END DO 32 | 33 | DO i = -1,N 34 | WRITE(*,*) i, "! =", factorial2(i) 35 | END DO 36 | 37 | DO i = 0,N 38 | WRITE(*,*) "binom(10,", i, ") =", binom(10,i) 39 | END DO 40 | END PROGRAM factorial_test 41 | -------------------------------------------------------------------------------- /Fortran90/tests/force_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM force_test 21 | 22 | USE INPUT 23 | USE RHF 24 | USE FORCES 25 | 26 | IMPLICIT NONE 27 | 28 | ! System an basis set sizes 29 | INTEGER :: Ne ! Number of electrons 30 | INTEGER :: Nn ! Number of nuclei 31 | INTEGER :: K ! Basis set size 32 | INTEGER :: c ! Contractions (TODO) 33 | 34 | ! System and basis set informations 35 | REAL*8, allocatable, dimension(:,:) :: Rn ! Atomic potisions 36 | INTEGER, allocatable, dimension(:) :: Zn ! Atomic charges 37 | REAL*8, allocatable, dimension(:,:) :: basis_R ! Basis functions' centers 38 | INTEGER, allocatable, dimension(:) :: basis_idx ! Basis set atomic index 39 | INTEGER, allocatable, dimension(:,:) :: basis_L ! Basis functions' angular momenta 40 | REAL*8, allocatable, dimension(:,:) :: basis_A ! Contraction exponential coefficients 41 | REAL*8, allocatable, dimension(:,:) :: basis_D ! Conttaction linear coefficients 42 | 43 | REAL*8, allocatable, dimension(:,:) :: F ! Forces 44 | 45 | CHARACTER (len=4) :: calculation ! Type of calculation 46 | 47 | ! ------------------------------------------------ 48 | ! LOAD SYSTEM AND BASIS SET INFORMATIONS FROM FILE 49 | ! ------------------------------------------------ 50 | 51 | CALL load("tests/H2O_f.in",calculation,Ne,Nn,K,c,Rn,Zn,basis_R,basis_L,basis_A,basis_D,basis_idx) 52 | 53 | ! ----- 54 | ! FORCE 55 | ! ----- 56 | 57 | ALLOCATE(F(Nn,3)) 58 | 59 | ! Compute force on all atoms 60 | CALL force_fd(K,c,Ne,Nn,basis_D,basis_A,basis_L,basis_R,basis_idx,Zn,Rn,F,1D-4) 61 | 62 | WRITE(*,*) "######" 63 | WRITE(*,*) "FORCES" 64 | WRITE(*,*) "######" 65 | CALL print_real_matrix(Nn,3,F) 66 | 67 | ! --- 68 | ! END 69 | ! --- 70 | 71 | DEALLOCATE(Rn,Zn,basis_R,basis_L,basis_A,basis_D,F) ! Deallocate allocated memory 72 | 73 | END PROGRAM force_test 74 | -------------------------------------------------------------------------------- /Fortran90/tests/gaussian_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM gaussian_test 21 | 22 | USE GAUSSIAN 23 | 24 | IMPLICIT NONE 25 | 26 | REAL*8 :: aa = 1.0D0, bb = 2.0D0 ! Gaussian exponential coefficients 27 | REAL*8, dimension(3) :: Ra = (/0.0D0,0.0D0,0.0D0/), Rb = (/1.0D0,1.0D0,1.0D0/) 28 | 29 | REAL :: Na, Nb 30 | 31 | Na = norm(0,0,0,aa) 32 | Nb = norm(0,0,0,bb) 33 | 34 | WRITE(*,*) "Na = ", Na 35 | WRITE(*,*) "Nb = ", Nb 36 | 37 | END PROGRAM gaussian_test 38 | -------------------------------------------------------------------------------- /Fortran90/tests/input_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM input_test 21 | 22 | USE INPUT 23 | USE OUTPUT 24 | 25 | IMPLICIT NONE 26 | 27 | ! System an basis set sizes 28 | INTEGER :: Ne ! Number of electrons 29 | INTEGER :: Nn ! Number of nuclei 30 | INTEGER :: K ! Basis set size 31 | INTEGER :: c ! Contractions (TODO: split valence basis set) 32 | 33 | ! System and basis set informations 34 | REAL*8, allocatable, dimension(:,:) :: R ! Atomic potisions 35 | INTEGER, allocatable, dimension(:) :: Z ! Atomic charges 36 | REAL*8, allocatable, dimension(:,:) :: basis_R ! Basis functions' centers 37 | INTEGER, allocatable, dimension(:,:) :: basis_L ! Basis functions' angular momenta 38 | REAL*8, allocatable, dimension(:,:) :: basis_A ! Contraction exponential coefficients 39 | REAL*8, allocatable, dimension(:,:) :: basis_D ! Conttaction linear coefficients 40 | 41 | CALL load("tests/N2_f.in",Ne,Nn,K,c,R,Z,basis_R,basis_L,basis_A,basis_D) 42 | 43 | CALL print_real_matrix(Nn,3,R) 44 | CALL print_integer_matrix(Nn,1,Z) 45 | CALL print_real_matrix(K,3,basis_R) 46 | CALL print_integer_matrix(K,3,basis_L) 47 | CALL print_real_matrix(K,c,basis_A) 48 | CALL print_real_matrix(K,c,basis_D) 49 | 50 | DEALLOCATE(R,Z,basis_R,basis_L,basis_A,basis_D) 51 | 52 | 53 | END PROGRAM input_test 54 | -------------------------------------------------------------------------------- /Fortran90/tests/kinetic_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM kinetic_test 21 | 22 | USE KINETIC 23 | USE OUTPUT, only: print_real_matrix 24 | USE CONSTANTS 25 | 26 | IMPLICIT NONE 27 | 28 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 29 | REAL*8, PARAMETER :: zeta_He = 2.0925D0 ! STO coefficient correction for He 30 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for He 31 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for He 32 | 33 | ! ---------------- 34 | ! BASIS SET FOR H2 35 | ! ---------------- 36 | INTEGER, PARAMETER :: K_H2 = 2 ! Number of basis functions 37 | 38 | INTEGER, dimension(K_H2,3) :: basis_L_H2 ! Angular momenta of basis set Gaussians 39 | REAL*8, dimension(K_H2,3) :: basis_R_H2 ! Centers of basis set Gaussians 40 | REAL*8, dimension(K_H2,c) :: basis_D_H2, basis_A_H2 ! Basis set coefficients 41 | 42 | REAL*8, dimension(K_H2,K_H2) :: T_H2 ! Overlap matrix 43 | 44 | ! ------------------ 45 | ! BASIS SET FOR HeH+ 46 | ! ------------------ 47 | INTEGER, PARAMETER :: K_HeH = 2 ! Number of basis functions 48 | 49 | INTEGER, dimension(K_HeH,3) :: basis_L_HeH ! Angular momenta of basis set Gaussians 50 | REAL*8, dimension(K_HeH,3) :: basis_R_HeH ! Centers of basis set Gaussians 51 | REAL*8, dimension(K_HeH,c) :: basis_D_HeH, basis_A_HeH ! Basis set coefficients 52 | 53 | REAL*8, dimension(K_HeH,K_HeH) :: T_HeH ! Overlap matrix 54 | 55 | ! ----------------- 56 | ! BASIS SET FOR H2O 57 | ! ----------------- 58 | INTEGER, PARAMETER :: K_H2O = 7 ! Number of basis functions 59 | 60 | INTEGER, dimension(K_H2O,3) :: basis_L_H2O ! Angular momenta of basis set Gaussians 61 | REAL*8, dimension(K_H2O,3) :: basis_R_H2O ! Centers of basis set Gaussians 62 | REAL*8, dimension(K_H2O,c) :: basis_D_H2O, basis_A_H2O ! Basis set coefficients 63 | 64 | REAL*8, dimension(K_H2O,K_H2O) :: T_H2O ! Overlap matrix 65 | 66 | ! ----------- 67 | ! MOLECULE H2 68 | ! ----------- 69 | 70 | basis_R_H2(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 71 | basis_R_H2(2,1:3) = (/1.4D0, 0.0D0, 0.0D0/) ! Position of the second H atom 72 | 73 | basis_L_H2(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 74 | basis_L_H2(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 75 | 76 | basis_D_H2(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 77 | basis_D_H2(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 78 | 79 | basis_A_H2(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 80 | basis_A_H2(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 81 | 82 | CALL T_kinetic(K_H2,basis_D_H2,basis_A_H2,basis_L_H2,basis_R_H2,T_H2) 83 | 84 | WRITE(*,*) "Kinetic matrix T:" 85 | CALL print_real_matrix(K_H2,K_H2,T_H2) 86 | 87 | ! ------------ 88 | ! MOLECULE He+ 89 | ! ------------ 90 | 91 | basis_R_HeH(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of the H atom 92 | basis_R_HeH(2,1:3) = (/1.4632D0, 0.0D0, 0.0D0/) ! Position of the He atom 93 | 94 | basis_L_HeH(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 95 | basis_L_HeH(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 96 | 97 | basis_D_HeH(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 98 | basis_D_HeH(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 99 | 100 | basis_A_HeH(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 101 | basis_A_HeH(2,1:c) = (/0.109818D0 * zeta_He**2, 0.405771 * zeta_He**2, 2.22766 * zeta_He**2/) 102 | 103 | CALL T_kinetic(K_HeH,basis_D_HeH,basis_A_HeH,basis_L_HeH,basis_R_HeH,T_HeH) 104 | 105 | WRITE(*,*) "Kinetic matrix T:" 106 | CALL print_real_matrix(K_HeH,K_HeH,T_HeH) 107 | 108 | ! ------------ 109 | ! MOLECULE H2O 110 | ! ------------ 111 | 112 | basis_R_H2O(1,1:3) = (/0.0D0, 1.43233673D0, -0.96104039D0/) ! Center of H1 1s 113 | basis_R_H2O(2,1:3) = (/0.0D0, -1.43233673D0, -0.96104039D0/) ! Center of H2 1s 114 | basis_R_H2O(3,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 1s 115 | basis_R_H2O(4,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2s 116 | basis_R_H2O(5,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2px 117 | basis_R_H2O(6,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2py 118 | basis_R_H2O(7,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2pz 119 | 120 | basis_L_H2O(1,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 121 | basis_L_H2O(2,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 122 | basis_L_H2O(3,1:3) = (/0, 0, 0/) ! Angular momenta for O 1s 123 | basis_L_H2O(4,1:3) = (/0, 0, 0/) ! Angular momenta for O 2s 124 | basis_L_H2O(5,1:3) = (/1, 0, 0/) ! Angular momenta for O 2px 125 | basis_L_H2O(6,1:3) = (/0, 1, 0/) ! Angular momenta for O 2py 126 | basis_L_H2O(7,1:3) = (/0, 0, 1/) ! Angular momenta for O 2pz 127 | 128 | basis_D_H2O(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 129 | basis_D_H2O(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 130 | basis_D_H2O(3,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 131 | basis_D_H2O(4,1:c) = (/0.700115D0, 0.399513D0, -0.0999672D0/) 132 | basis_D_H2O(5,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 133 | basis_D_H2O(6,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 134 | basis_D_H2O(7,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 135 | 136 | basis_A_H2O(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 137 | basis_A_H2O(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 138 | basis_A_H2O(3,1:c) = (/0.109818D0 * zeta_O_1**2, 0.405771 * zeta_O_1**2, 2.22766 * zeta_O_1**2/) 139 | basis_A_H2O(4,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 140 | basis_A_H2O(5,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 141 | basis_A_H2O(6,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 142 | basis_A_H2O(7,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 143 | 144 | CALL T_kinetic(K_H2O,basis_D_H2O,basis_A_H2O,basis_L_H2O,basis_R_H2O,T_H2O) 145 | 146 | WRITE(*,*) "Kinetic matrix T:" 147 | CALL print_real_matrix(K_H2O,K_H2O,T_H2O) 148 | 149 | END PROGRAM kinetic_test 150 | -------------------------------------------------------------------------------- /Fortran90/tests/linearsystem_test.f90: -------------------------------------------------------------------------------- 1 | PROGRAM ls 2 | ! -------------------------------------- 3 | ! Solve linear system of equations AX=B. 4 | ! -------------------------------------- 5 | ! 6 | ! Results compared with MATLAB(R) 7 | ! 8 | ! -------------------------------------- 9 | 10 | USE LA 11 | USE OUTPUT 12 | 13 | IMPLICIT NONE 14 | 15 | INTEGER, PARAMETER :: d = 3 16 | 17 | REAL*8, dimension(d,d) :: A 18 | REAL*8, dimension(d) :: b 19 | REAL*8, dimension(d) :: x 20 | 21 | A(1,:) = (/1.0D0, 0.0D0, 0.0D0/) 22 | A(2,:) = (/0.0D0, 2.0D0, 0.0D0/) 23 | A(3,:) = (/0.0D0, 0.0D0, 3.0D0/) 24 | 25 | b = (/1.0D0,2.0D0,3.0D0/) 26 | 27 | CALL LINEAR_SYSTEM(d,A,b,x) 28 | 29 | CALL print_real_matrix(1,d,x) 30 | 31 | A(1,:) = (/1.0D0, 2.0D0, 3.0D0/) 32 | A(2,:) = (/-2.0D0, 3.0D0, -5.0D0/) 33 | A(3,:) = (/0.0D0, 7.0D0, -4.0D0/) 34 | 35 | b = (/-2.0D0,5.0D0,6.0D0/) 36 | 37 | CALL LINEAR_SYSTEM(d,A,b,x) 38 | 39 | CALL print_real_matrix(1,d,x) 40 | 41 | A(1,:) = (/-9.0D0, 2.0D0, 3.0D0/) 42 | A(2,:) = (/-2.0D0, -3.0D0, -5.0D0/) 43 | A(3,:) = (/0.0D0, 7.0D0, -4.0D0/) 44 | 45 | b = (/-2.0D0,-4.0D0,6.0D0/) 46 | 47 | CALL LINEAR_SYSTEM(d,A,b,x) 48 | 49 | CALL print_real_matrix(1,d,x) 50 | 51 | END PROGRAM ls 52 | -------------------------------------------------------------------------------- /Fortran90/tests/nuclear_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM nuclear_test 21 | 22 | USE NUCLEAR 23 | USE OUTPUT, only: print_real_matrix 24 | 25 | IMPLICIT NONE 26 | 27 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 28 | REAL*8, PARAMETER :: zeta_He = 2.0925D0 ! STO coefficient correction for He 29 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for He 30 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for He 31 | 32 | ! ---------------- 33 | ! BASIS SET FOR H2 34 | ! ---------------- 35 | INTEGER, PARAMETER :: K_H2 = 2 ! Number of basis functions 36 | INTEGER, PARAMETER :: Nn_H2 = 2 ! Number of nuclei 37 | 38 | INTEGER, dimension(K_H2,3) :: basis_L_H2 ! Angular momenta of basis set Gaussians 39 | REAL*8, dimension(K_H2,3) :: basis_R_H2 ! Centers of basis set Gaussians 40 | REAL*8, dimension(K_H2,c) :: basis_D_H2, basis_A_H2 ! Basis set coefficients 41 | 42 | REAL*8, dimension(K_H2,K_H2) :: Vn1_H2 ! Nucleus-electron interaction matrix 43 | REAL*8, dimension(K_H2,K_H2) :: Vn2_H2 ! Nucleus-electron interaction matrix 44 | 45 | REAL*8, dimension(Nn_H2,3) :: R_H2 ! Nuclear positions 46 | INTEGER, dimension(Nn_H2) :: Zn_H2 ! Nuclear charges 47 | 48 | ! ------------------ 49 | ! BASIS SET FOR HeH+ 50 | ! ------------------ 51 | INTEGER, PARAMETER :: K_HeH = 2 ! Number of basis functions 52 | INTEGER, PARAMETER :: Nn_HeH = 2 ! Number of nuclei 53 | 54 | INTEGER, dimension(K_HeH,3) :: basis_L_HeH ! Angular momenta of basis set Gaussians 55 | REAL*8, dimension(K_HeH,3) :: basis_R_HeH ! Centers of basis set Gaussians 56 | REAL*8, dimension(K_HeH,c) :: basis_D_HeH, basis_A_HeH ! Basis set coefficients 57 | 58 | REAL*8, dimension(K_HeH,K_HeH) :: Vn1_HeH ! Nucleus-electron interaction matrix 59 | REAL*8, dimension(K_HeH,K_HeH) :: Vn2_HeH ! Nucleus-electron interaction matrix 60 | 61 | REAL*8, dimension(Nn_HeH,3) :: R_HeH ! Nuclear positions 62 | INTEGER, dimension(Nn_HeH) :: Zn_HeH ! Nuclear charges 63 | 64 | ! ----------------- 65 | ! BASIS SET FOR H2O 66 | ! ----------------- 67 | INTEGER, PARAMETER :: K_H2O = 7 ! Number of basis functions 68 | INTEGER, PARAMETER :: Nn_H2O = 3 ! Number of nuclei 69 | 70 | INTEGER, dimension(K_H2O,3) :: basis_L_H2O ! Angular momenta of basis set Gaussians 71 | REAL*8, dimension(K_H2O,3) :: basis_R_H2O ! Centers of basis set Gaussians 72 | REAL*8, dimension(K_H2O,c) :: basis_D_H2O, basis_A_H2O ! Basis set coefficients 73 | 74 | REAL*8, dimension(K_H2O,K_H2O) :: Vn1_H2O ! Nucleus-electron interaction matrix 75 | REAL*8, dimension(K_H2O,K_H2O) :: Vn2_H2O ! Nucleus-electron interaction matrix 76 | REAL*8, dimension(K_H2O,K_H2O) :: Vn3_H2O ! Nucleus-electron interaction matrix 77 | 78 | REAL*8, dimension(Nn_H2O,3) :: R_H2O ! Nuclear positions 79 | INTEGER, dimension(Nn_H2O) :: Zn_H2O ! Nuclear charges 80 | 81 | ! ----------- 82 | ! MOLECULE H2 83 | ! ----------- 84 | 85 | R_H2(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 86 | R_H2(2,1:3) = (/1.4D0, 0.0D0, 0.0D0/) ! Position of the second H atom 87 | 88 | Zn_H2 = (/1, 1/) 89 | 90 | basis_R_H2(1,1:3) = R_H2(1,1:3) 91 | basis_R_H2(2,1:3) = R_H2(2,1:3) 92 | 93 | basis_L_H2(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 94 | basis_L_H2(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 95 | 96 | basis_D_H2(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 97 | basis_D_H2(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 98 | 99 | basis_A_H2(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 100 | basis_A_H2(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 101 | 102 | WRITE(*,*) "###########" 103 | WRITE(*,*) "Molecule H2" 104 | WRITE(*,*) "###########" 105 | 106 | CALL V_nuclear(K_H2,basis_D_H2,basis_A_H2,basis_L_H2,basis_R_H2,Vn1_H2,R_H2(1,1:3),Zn_H2(1)) 107 | 108 | WRITE(*,*) "Nuclear matrix V1:" 109 | CALL print_real_matrix(K_H2,K_H2,Vn1_H2) 110 | 111 | CALL V_nuclear(K_H2,basis_D_H2,basis_A_H2,basis_L_H2,basis_R_H2,Vn2_H2,R_H2(2,1:3),Zn_H2(2)) 112 | 113 | WRITE(*,*) "Nuclear matrix V2:" 114 | CALL print_real_matrix(K_H2,K_H2,Vn2_H2) 115 | 116 | ! ------------ 117 | ! MOLECULE He+ 118 | ! ------------ 119 | 120 | R_HeH(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 121 | R_HeH(2,1:3) = (/1.4632D0, 0.0D0, 0.0D0/) ! Position of the second H atom 122 | 123 | Zn_HeH = (/1, 2/) 124 | 125 | basis_R_HeH(1,1:3) = R_HeH(1,1:3) ! Position of the H atom 126 | basis_R_HeH(2,1:3) = R_HeH(2,1:3) ! Position of the He atom 127 | 128 | basis_L_HeH(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 129 | basis_L_HeH(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 130 | 131 | basis_D_HeH(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 132 | basis_D_HeH(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 133 | 134 | basis_A_HeH(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 135 | basis_A_HeH(2,1:c) = (/0.109818D0 * zeta_He**2, 0.405771 * zeta_He**2, 2.22766 * zeta_He**2/) 136 | 137 | WRITE(*,*) "#############" 138 | WRITE(*,*) "Molecule HeH+" 139 | WRITE(*,*) "#############" 140 | 141 | CALL V_nuclear(K_HeH,basis_D_HeH,basis_A_HeH,basis_L_HeH,basis_R_HeH,Vn1_HeH,R_HeH(1,1:3),Zn_HeH(1)) 142 | 143 | WRITE(*,*) "Nuclear matrix V1:" 144 | CALL print_real_matrix(K_HeH,K_HeH,Vn1_HeH) 145 | 146 | CALL V_nuclear(K_HeH,basis_D_HeH,basis_A_HeH,basis_L_HeH,basis_R_HeH,Vn2_HeH,R_HeH(2,1:3),Zn_HeH(2)) 147 | 148 | WRITE(*,*) "Nuclear matrix V2:" 149 | CALL print_real_matrix(K_HeH,K_HeH,Vn2_HeH) 150 | 151 | ! ------------ 152 | ! MOLECULE H2O 153 | ! ------------ 154 | 155 | R_H2O(1,1:3) = (/0.0D0, 1.43233673D0, -0.96104039D0/) ! Position of first H atom 156 | R_H2O(2,1:3) = (/0.0D0, -1.43233673D0, -0.96104039D0/) ! Position of the second H atom 157 | R_H2O(3,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) 158 | 159 | Zn_H2O = (/1, 1, 8/) 160 | 161 | basis_R_H2O(1,1:3) = R_H2O(1,1:3) ! Center of H1 1s 162 | basis_R_H2O(2,1:3) = R_H2O(2,1:3) ! Center of H2 1s 163 | basis_R_H2O(3,1:3) = R_H2O(3,1:3) ! Center of O 1s 164 | basis_R_H2O(4,1:3) = R_H2O(3,1:3) ! Center of O 2s 165 | basis_R_H2O(5,1:3) = R_H2O(3,1:3) ! Center of O 2px 166 | basis_R_H2O(6,1:3) = R_H2O(3,1:3) ! Center of O 2py 167 | basis_R_H2O(7,1:3) = R_H2O(3,1:3) ! Center of O 2pz 168 | 169 | basis_L_H2O(1,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 170 | basis_L_H2O(2,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 171 | basis_L_H2O(3,1:3) = (/0, 0, 0/) ! Angular momenta for O 1s 172 | basis_L_H2O(4,1:3) = (/0, 0, 0/) ! Angular momenta for O 2s 173 | basis_L_H2O(5,1:3) = (/1, 0, 0/) ! Angular momenta for O 2px 174 | basis_L_H2O(6,1:3) = (/0, 1, 0/) ! Angular momenta for O 2py 175 | basis_L_H2O(7,1:3) = (/0, 0, 1/) ! Angular momenta for O 2pz 176 | 177 | basis_D_H2O(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 178 | basis_D_H2O(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 179 | basis_D_H2O(3,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 180 | basis_D_H2O(4,1:c) = (/0.700115D0, 0.399513D0, -0.0999672D0/) 181 | basis_D_H2O(5,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 182 | basis_D_H2O(6,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 183 | basis_D_H2O(7,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 184 | 185 | basis_A_H2O(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 186 | basis_A_H2O(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 187 | basis_A_H2O(3,1:c) = (/0.109818D0 * zeta_O_1**2, 0.405771 * zeta_O_1**2, 2.22766 * zeta_O_1**2/) 188 | basis_A_H2O(4,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 189 | basis_A_H2O(5,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 190 | basis_A_H2O(6,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 191 | basis_A_H2O(7,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 192 | 193 | WRITE(*,*) "BASIS A H2O" 194 | CALL print_real_matrix(K_H2O,c,basis_A_H2O) 195 | 196 | WRITE(*,*) "############" 197 | WRITE(*,*) "Molecule H2O" 198 | WRITE(*,*) "############" 199 | 200 | CALL V_nuclear(K_H2O,basis_D_H2O,basis_A_H2O,basis_L_H2O,basis_R_H2O,Vn1_H2O,R_H2O(1,1:3),Zn_H2O(1)) 201 | CALL V_nuclear(K_H2O,basis_D_H2O,basis_A_H2O,basis_L_H2O,basis_R_H2O,Vn2_H2O,R_H2O(2,1:3),Zn_H2O(2)) 202 | CALL V_nuclear(K_H2O,basis_D_H2O,basis_A_H2O,basis_L_H2O,basis_R_H2O,Vn3_H2O,R_H2O(3,1:3),Zn_H2O(3)) 203 | 204 | WRITE(*,*) "Total nuclear matrix V:" 205 | CALL print_real_matrix(K_H2O,K_H2O,Vn1_H2O + Vn2_H2O + Vn3_H2O) 206 | 207 | END PROGRAM nuclear_test 208 | -------------------------------------------------------------------------------- /Fortran90/tests/overlap_test.f90: -------------------------------------------------------------------------------- 1 | ! -------------------------------------------------------------------- 2 | ! 3 | ! Copyright (C) 2015 Rocco Meli 4 | ! 5 | ! This program is free software: you can redistribute it and/or modify 6 | ! it under the terms of the GNU General Public License as published by 7 | ! the Free Software Foundation, either version 3 of the License, or 8 | ! (at your option) any later version. 9 | ! 10 | ! This program is distributed in the hope that it will be useful, 11 | ! but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ! GNU General Public License for more details. 14 | ! 15 | ! You should have received a copy of the GNU General Public License 16 | ! along with this program. If not, see . 17 | ! 18 | ! --------------------------------------------------------------------- 19 | 20 | PROGRAM overlap_test 21 | 22 | USE OVERLAP 23 | USE OUTPUT, only: print_real_matrix 24 | USE CONSTANTS 25 | 26 | IMPLICIT NONE 27 | 28 | REAL*8, PARAMETER :: zeta_H = 1.24D0 ! STO coefficient correction for H 29 | REAL*8, PARAMETER :: zeta_He = 2.0925D0 ! STO coefficient correction for He 30 | REAL*8, PARAMETER :: zeta_O_1 = 7.66D0 ! STO coefficient correction for He 31 | REAL*8, PARAMETER :: zeta_O_2 = 2.25D0 ! STO coefficient correction for He 32 | 33 | ! ---------------- 34 | ! BASIS SET FOR H2 35 | ! ---------------- 36 | INTEGER, PARAMETER :: K_H2 = 2 ! Number of basis functions 37 | 38 | INTEGER, dimension(K_H2,3) :: basis_L_H2 ! Angular momenta of basis set Gaussians 39 | REAL*8, dimension(K_H2,3) :: basis_R_H2 ! Centers of basis set Gaussians 40 | REAL*8, dimension(K_H2,c) :: basis_D_H2, basis_A_H2 ! Basis set coefficients 41 | 42 | REAL*8, dimension(K_H2,K_H2) :: S_H2 ! Overlap matrix 43 | 44 | ! ------------------ 45 | ! BASIS SET FOR HeH+ 46 | ! ------------------ 47 | INTEGER, PARAMETER :: K_HeH = 2 ! Number of basis functions 48 | 49 | INTEGER, dimension(K_HeH,3) :: basis_L_HeH ! Angular momenta of basis set Gaussians 50 | REAL*8, dimension(K_HeH,3) :: basis_R_HeH ! Centers of basis set Gaussians 51 | REAL*8, dimension(K_HeH,c) :: basis_D_HeH, basis_A_HeH ! Basis set coefficients 52 | 53 | REAL*8, dimension(K_HeH,K_HeH) :: S_HeH ! Overlap matrix 54 | 55 | ! ----------------- 56 | ! BASIS SET FOR H2O 57 | ! ----------------- 58 | INTEGER, PARAMETER :: K_H2O = 7 ! Number of basis functions 59 | 60 | INTEGER, dimension(K_H2O,3) :: basis_L_H2O ! Angular momenta of basis set Gaussians 61 | REAL*8, dimension(K_H2O,3) :: basis_R_H2O ! Centers of basis set Gaussians 62 | REAL*8, dimension(K_H2O,c) :: basis_D_H2O, basis_A_H2O ! Basis set coefficients 63 | 64 | REAL*8, dimension(K_H2O,K_H2O) :: S_H2O ! Overlap matrix 65 | 66 | ! ----------- 67 | ! MOLECULE H2 68 | ! ----------- 69 | 70 | basis_R_H2(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of first H atom 71 | basis_R_H2(2,1:3) = (/1.4D0, 0.0D0, 0.0D0/) ! Position of the second H atom 72 | 73 | basis_L_H2(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 74 | basis_L_H2(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 75 | 76 | basis_D_H2(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 77 | basis_D_H2(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 78 | 79 | basis_A_H2(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 80 | basis_A_H2(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 81 | 82 | CALL S_overlap(K_H2,basis_D_H2,basis_A_H2,basis_L_H2,basis_R_H2,S_H2) 83 | 84 | WRITE(*,*) "Overlap matrix S:" 85 | CALL print_real_matrix(K_H2,K_H2,S_H2) 86 | 87 | ! ------------ 88 | ! MOLECULE He+ 89 | ! ------------ 90 | 91 | basis_R_HeH(1,1:3) = (/0.0D0, 0.0D0, 0.0D0/) ! Position of the H atom 92 | basis_R_HeH(2,1:3) = (/1.4632D0, 0.0D0, 0.0D0/) ! Position of the He atom 93 | 94 | basis_L_HeH(1,1:3) = (/0, 0, 0/) ! Angular momenta for the first basis function 95 | basis_L_HeH(2,1:3) = (/0, 0, 0/) ! Angular momenta for the second basis function 96 | 97 | basis_D_HeH(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 98 | basis_D_HeH(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 99 | 100 | basis_A_HeH(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 101 | basis_A_HeH(2,1:c) = (/0.109818D0 * zeta_He**2, 0.405771 * zeta_He**2, 2.22766 * zeta_He**2/) 102 | 103 | CALL S_overlap(K_HeH,basis_D_HeH,basis_A_HeH,basis_L_HeH,basis_R_HeH,S_HeH) 104 | 105 | WRITE(*,*) "Overlap matrix S:" 106 | CALL print_real_matrix(K_HeH,K_HeH,S_HeH) 107 | 108 | ! ------------ 109 | ! MOLECULE H2O 110 | ! ------------ 111 | 112 | basis_R_H2O(1,1:3) = (/0.0D0, 1.43233673D0, -0.96104039D0/) ! Center of H1 1s 113 | basis_R_H2O(2,1:3) = (/0.0D0, -1.43233673D0, -0.96104039D0/) ! Center of H2 1s 114 | basis_R_H2O(3,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 1s 115 | basis_R_H2O(4,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2s 116 | basis_R_H2O(5,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2px 117 | basis_R_H2O(6,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2py 118 | basis_R_H2O(7,1:3) = (/0.0D0, 0.0D0, 0.24026010D0/) ! Center of O 2pz 119 | 120 | basis_L_H2O(1,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 121 | basis_L_H2O(2,1:3) = (/0, 0, 0/) ! Angular momenta for H 1s 122 | basis_L_H2O(3,1:3) = (/0, 0, 0/) ! Angular momenta for O 1s 123 | basis_L_H2O(4,1:3) = (/0, 0, 0/) ! Angular momenta for O 2s 124 | basis_L_H2O(5,1:3) = (/1, 0, 0/) ! Angular momenta for O 2px 125 | basis_L_H2O(6,1:3) = (/0, 1, 0/) ! Angular momenta for O 2py 126 | basis_L_H2O(7,1:3) = (/0, 0, 1/) ! Angular momenta for O 2pz 127 | 128 | basis_D_H2O(1,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 129 | basis_D_H2O(2,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 130 | basis_D_H2O(3,1:c) = (/0.444635D0, 0.535328D0, 0.154329D0 /) 131 | basis_D_H2O(4,1:c) = (/0.700115D0, 0.399513D0, -0.0999672D0/) 132 | basis_D_H2O(5,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 133 | basis_D_H2O(6,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 134 | basis_D_H2O(7,1:c) = (/0.391957D0, 0.607684D0, 0.1559163D0/) 135 | 136 | basis_A_H2O(1,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 137 | basis_A_H2O(2,1:c) = (/0.109818D0 * zeta_H**2, 0.405771 * zeta_H**2, 2.22766 * zeta_H**2/) 138 | basis_A_H2O(3,1:c) = (/0.109818D0 * zeta_O_1**2, 0.405771 * zeta_O_1**2, 2.22766 * zeta_O_1**2/) 139 | basis_A_H2O(4,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 140 | basis_A_H2O(5,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 141 | basis_A_H2O(6,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 142 | basis_A_H2O(7,1:c) = (/0.0751386D0 * zeta_O_2**2, 0.231031 * zeta_O_2**2, 0.994203 * zeta_O_2**2/) 143 | 144 | CALL S_overlap(K_H2O,basis_D_H2O,basis_A_H2O,basis_L_H2O,basis_R_H2O,S_H2O) 145 | 146 | WRITE(*,*) "Overlap matrix S:" 147 | CALL print_real_matrix(K_H2O,K_H2O,S_H2O) 148 | 149 | 150 | 151 | END PROGRAM overlap_test 152 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015 Rocco Meli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Python/HF.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | from RHF import * 19 | 20 | from matrices import * 21 | from integrals import * 22 | from basis import * 23 | from molecules import * 24 | 25 | import numpy as np 26 | import numpy.linalg as la 27 | 28 | ########################### 29 | ########################### 30 | ########################### 31 | 32 | mol = H2O # Molecule 33 | bs = sto3g_H2O # Basis set 34 | N = 10 # Number of electrons 35 | 36 | maxiter = 100 # Maximal number of iteration 37 | 38 | verbose = True # Print each SCF step 39 | 40 | ########################### 41 | ########################### 42 | ########################### 43 | 44 | # Basis set size 45 | K = bs.K 46 | 47 | print("Computing overlap matrix S...") 48 | S = S_overlap(bs) 49 | 50 | if verbose: 51 | print(S) 52 | 53 | print("Computing orthogonalization matrix X...") 54 | X = X_transform(S) 55 | 56 | if verbose: 57 | print(X) 58 | 59 | print("Computing core Hamiltonian...") 60 | Hc = H_core(bs,mol) 61 | 62 | if verbose: 63 | print(Hc) 64 | 65 | print("Computing two-electron integrals...") 66 | ee = EE_list(bs) 67 | 68 | if verbose: 69 | print_EE_list(ee) 70 | 71 | Pnew = np.zeros((K,K)) 72 | P = np.zeros((K,K)) 73 | 74 | converged = False 75 | 76 | print(" ##################") 77 | print(" Starting SCF cycle") 78 | print(" ##################") 79 | 80 | iter = 1 81 | while not converged and iter <= maxiter: 82 | print("\n\n\n#####\nSCF cycle " + str(iter) + ":") 83 | print("#####") 84 | 85 | Pnew, F, E = RHF_step(bs,mol,N,Hc,X,P,ee,verbose) # Perform an SCF step 86 | 87 | # Print results of the SCF step 88 | print("\nTotal energy:", energy_tot(P,F,Hc,mol),"\n") 89 | print(" Orbital energies:") 90 | print(" ", np.diag(E)) 91 | 92 | # Check convergence of the SCF cycle 93 | if delta_P(P,Pnew) < 1e-12: 94 | converged = True 95 | 96 | print("\n\n\nTOTAL ENERGY:", energy_tot(P,F,Hc,mol)) # Print final, total energy 97 | 98 | if iter == maxiter: 99 | print("SCF NOT CONVERGED!") 100 | 101 | P = Pnew 102 | 103 | iter += 1 104 | -------------------------------------------------------------------------------- /Python/RHF.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | from matrices import * 19 | 20 | import numpy.linalg as la 21 | 22 | def RHF_step(basis,molecule,N,H,X,P_old,ee,verbose=False): 23 | """ 24 | Restricted Hartree-Fock self-consistent field setp. 25 | 26 | INPUT: 27 | BASIS: basis set 28 | MOLECULE: molecule, collection of atom object 29 | N: Number of electrons 30 | H: core Hamiltonian 31 | X: tranformation matrix 32 | P_OLD: Old density matrix 33 | EE: List of electron-electron Integrals 34 | VERBOSE: verbose flag (set True to print everything on screen) 35 | """ 36 | 37 | if verbose: 38 | print("\nDensity matrix P:") 39 | print(P_old) 40 | 41 | G = G_ee(basis,molecule,P_old,ee) # Compute electron-electron interaction matrix 42 | 43 | if verbose: 44 | print("\nG matrix:") 45 | print(G) 46 | 47 | F = H + G # Compute Fock matrix 48 | 49 | if verbose: 50 | print("\nFock matrix:") 51 | print(F) 52 | 53 | Fx = np.dot(X.conj().T,np.dot(F,X)) # Compute Fock matrix in the orthonormal basis set (S=I in this set) 54 | 55 | if verbose: 56 | print("\nFock matrix in orthogonal orbital basis:") 57 | print(Fx) 58 | 59 | e, Cx = la.eigh(Fx) # Compute eigenvalues and eigenvectors of the Fock matrix 60 | 61 | # Sort eigenvalues from smallest to highest (needed to compute P correctly) 62 | idx = e.argsort() 63 | e = e[idx] 64 | Cx = Cx[:,idx] 65 | 66 | if verbose: 67 | print("\nCoefficients in orthogonal orbital basis:") 68 | print(Cx) 69 | 70 | e = np.diag(e) # Extract orbital energies as vector 71 | 72 | if verbose: 73 | print("\nEnergies in orthogonal orbital basis:") 74 | print(e) 75 | 76 | C = np.dot(X,Cx) # Transform coefficient matrix in the orthonormal basis to the original basis 77 | 78 | if verbose: 79 | print("\nCoefficients:") 80 | print(C) 81 | 82 | Pnew = P_density(C,N) # Compute the new density matrix 83 | 84 | return Pnew, F, e 85 | 86 | def delta_P(P_old,P_new): 87 | """ 88 | Compute the difference between two density matrices. 89 | 90 | INTPUT: 91 | P_OLD: Olde density matrix 92 | P_NEW: New density matrix 93 | OUTPUT: 94 | DELTA: difference between the two density matrices 95 | 96 | Source: 97 | Modern Quantum Chemistry 98 | Szabo and Ostlund 99 | Dover 100 | 1989 101 | """ 102 | delta = 0 103 | 104 | n = P_old.shape[0] 105 | 106 | for i in range(n): 107 | for j in range(n): 108 | delta += (P_old[i,j] - P_new[i,j])**2 109 | 110 | return (delta / 4.)**(0.5) 111 | 112 | def energy_el(P,F,H): 113 | """ 114 | Compute electronic energy. 115 | 116 | INPUT: 117 | P: Density matrix 118 | F: Fock matrix 119 | H: Core Hamiltonian 120 | 121 | Source: 122 | Modern Quantum Chemistry 123 | Szabo and Ostlund 124 | Dover 125 | 1989 126 | """ 127 | 128 | # Size of the basis set 129 | K = P.shape[0] 130 | 131 | E = 0 132 | 133 | for i in range(K): 134 | for j in range(K): 135 | E += 0.5 * P[i,j] * (H[i,j] + F[i,j]) 136 | 137 | return E 138 | 139 | def energy_n(molecule): 140 | """ 141 | Compute nuclear energy (classical nucleus-nucleus repulsion) 142 | 143 | INPUT: 144 | MOLECULE: molecule, as a collection of atoms 145 | OUTPUT: 146 | ENERGY_N: Nuclear energy 147 | """ 148 | 149 | en = 0 150 | 151 | for i in range(len(molecule)): 152 | for j in range(i+1,len(molecule)): 153 | # Select atoms from molecule 154 | atomi = molecule[i] 155 | atomj = molecule[j] 156 | 157 | # Extract distance from atom 158 | Ri = np.asarray(atomi.R) 159 | Rj = np.asarray(atomj.R) 160 | 161 | en += atomi.Z * atomj.Z / la.norm(Ri - Rj) 162 | 163 | return en 164 | 165 | def energy_tot(P,F,H,molecule): 166 | """ 167 | Compute total energy (electronic plus nuclear). 168 | 169 | INPUT: 170 | P: Density matrix 171 | F: Fock matrix 172 | H: Core Hamiltonian 173 | MOLECULE: molecule, as a collection of atoms 174 | OUTPUT: 175 | ENERGY_TOT: total energy 176 | """ 177 | return energy_el(P,F,H) + energy_n(molecule) 178 | -------------------------------------------------------------------------------- /Python/basis.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | 19 | class Atom: 20 | """ 21 | Class representing an atom. 22 | """ 23 | 24 | def __init__(self,name,R,Z,orbitals): 25 | """ 26 | Initializer for ATOM 27 | 28 | INPUT: 29 | NAME: Name of the element 30 | R: Position (cartesian coordinates, atomic units) 31 | Z: Atomic charge 32 | ORBITALS: list of orbitals for this atom 33 | """ 34 | 35 | self.name = name 36 | self.R = R 37 | self.orbitals = orbitals 38 | self.Z = Z 39 | 40 | class STO3G(): 41 | """ 42 | STO-3G minimal basis set. 43 | """ 44 | def __init__(self,atoms): 45 | """ 46 | Initializer for STO3G 47 | 48 | INPUT: 49 | ATOMS: list of atoms 50 | 51 | Source 52 | 53 | Modern Quantum Chemistry 54 | Szabo and Ostlund 55 | Dover 56 | 1989 57 | """ 58 | 59 | # Exponential coefficients for the Gaussian orbitals 60 | self.zeta1 = { "H":1.24, 61 | "He":2.0925, 62 | "Li":2.69, 63 | "Be":3.68, 64 | "B":4.68, 65 | "C":5.67, 66 | "N":6.67, 67 | "O":7.66, 68 | "F":8.65} 69 | self.zeta2 = { "Li":0.75, 70 | "Be":1.10, 71 | "B":1.45, 72 | "C":1.72, 73 | "N":1.95, 74 | "O":2.25, 75 | "F":2.55} 76 | 77 | self.STO3G = [] 78 | 79 | for a in atoms: # For every atom 80 | for o in a.orbitals: # For every atomic orbital 81 | if o == "1s": 82 | a1 = 0.109818 * self.zeta1[a.name]**2 83 | a2 = 0.405771 * self.zeta1[a.name]**2 84 | a3 = 2.22766 * self.zeta1[a.name]**2 85 | d1 = 0.444635 86 | d2 = 0.535328 87 | d3 = 0.154329 88 | 89 | self.STO3G.append({ "AOn":a.name,# 90 | "AOt":o,# 91 | "R":a.R,# 92 | "lx":0,# 93 | "ly":0,# 94 | "lz":0,# 95 | "a":(a1,a2,a3),# 96 | "d":(d1,d2,d3)}) 97 | 98 | if o == "2s": 99 | a1 = 0.0751386 * self.zeta2[a.name]**2 100 | a2 = 0.231031 * self.zeta2[a.name]**2 101 | a3 = 0.994203 * self.zeta2[a.name]**2 102 | d1 = 0.700115 103 | d2 = 0.399513 104 | d3 = -0.0999672 105 | 106 | self.STO3G.append({ "AOn":a.name, 107 | "AOt":o, 108 | "R":a.R, 109 | "lx":0, 110 | "ly":0, 111 | "lz":0, 112 | "a":(a1,a2,a3), 113 | "d":(d1,d2,d3)}) 114 | 115 | if o == "2p": 116 | a1 = 0.0751386 * self.zeta2[a.name]**2 117 | a2 = 0.231031 * self.zeta2[a.name]**2 118 | a3 = 0.994203 * self.zeta2[a.name]**2 119 | d1 = 0.391957 120 | d2 = 0.607684 121 | d3 = 0.1559163 122 | 123 | self.STO3G.append({ "AOn":a.name, 124 | "AOt":o, 125 | "R":a.R, 126 | "lx":1, 127 | "ly":0, 128 | "lz":0, 129 | "a":(a1,a2,a3), 130 | "d":(d1,d2,d3)}) 131 | self.STO3G.append({ "AOn":a.name, 132 | "AOt":o, 133 | "R":a.R, 134 | "lx":0, 135 | "ly":1, 136 | "lz":0, 137 | "a":(a1,a2,a3), 138 | "d":(d1,d2,d3)}) 139 | self.STO3G.append({ "AOn":a.name, 140 | "AOt":o, 141 | "R":a.R, 142 | "lx":0, 143 | "ly":0, 144 | "lz":1, 145 | "a":(a1,a2,a3), 146 | "d":(d1,d2,d3)}) 147 | 148 | self.K = len(self.STO3G) 149 | 150 | def basis(self): 151 | """ 152 | Return the basis set. 153 | """ 154 | 155 | return self.STO3G 156 | 157 | def info(self): 158 | """ 159 | Print informations about the bais set. 160 | """ 161 | print("########################") 162 | print("STO-3G MINIMAL BASIS SET") 163 | print("########################\n") 164 | 165 | for b in self.STO3G: 166 | print(b["AOn"] + " orbital:") 167 | print(" " + b["AOt"] + ":") 168 | print(" R = ", b["R"]) 169 | print(" lx = " + str(b["lx"])) 170 | print(" ly = " + str(b["ly"])) 171 | print(" lz = " + str(b["lz"])) 172 | print(" alpha = ", b["a"]) 173 | print(" d = ", b["d"],'\n') 174 | 175 | 176 | if __name__ == "__main__": 177 | 178 | """ 179 | Results compared with 180 | 181 | Modern Quantum Chemistry 182 | Szabo and Ostlund 183 | Dover 184 | 1989 185 | 186 | and 187 | 188 | The Mathematica Journal 189 | Evaluation of Gaussian Molecular Integrals 190 | I. Overlap Integrals 191 | Minhhuy Hô and Julio Manuel Hernández-Pérez 192 | 2012 193 | """ 194 | 195 | # HeH+ 196 | atoms = [Atom("H",(0,0,0),["1s"]),Atom("He",(0,0,1.4),["1s"])] 197 | 198 | # Create the basis set 199 | sto3g = STO3G(atoms) 200 | 201 | # Display informations 202 | sto3g.info() 203 | 204 | print("\n\n\n\n\n") 205 | 206 | # H2O 207 | atoms = [ Atom("H",(0,+1.43233673,-0.96104039),["1s"]), 208 | Atom("H",(0,-1.43233673,-0.96104039),["1s"]), 209 | Atom("O",(0,0,0.24026010),["1s","2s","2p"])] 210 | 211 | # Create the basis set 212 | sto3g = STO3G(atoms) 213 | 214 | # Display informations 215 | sto3g.info() 216 | -------------------------------------------------------------------------------- /Python/matrices.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | from basis import * 19 | from integrals import * 20 | 21 | import numpy.linalg as la 22 | 23 | def S_overlap(basis): 24 | """ 25 | Compute overlap matrix S. 26 | 27 | INPUT: 28 | BASIS: basis set 29 | OUTPUT: 30 | S: Overlap matrix 31 | """ 32 | 33 | # Size of the basis set 34 | K = basis.K 35 | 36 | # List of basis functions 37 | B = basis.basis() 38 | 39 | S = np.zeros((K,K)) 40 | 41 | for i,b1 in enumerate(B): 42 | for j,b2 in enumerate(B): 43 | for a1,d1 in zip(b1["a"],b1["d"]): 44 | for a2,d2 in zip(b2["a"],b2["d"]): 45 | R1 = b1["R"] 46 | R2 = b2["R"] 47 | 48 | tmp = d1.conjugate()*d2 49 | tmp *= overlap(b1["lx"],b1["ly"],b1["lz"],b2["lx"],b2["ly"],b2["lz"],a1,a2,R1,R2) 50 | 51 | S[i,j] += tmp 52 | 53 | return S 54 | 55 | def X_transform(S): 56 | """ 57 | Compute the transformation matrix X using canonical orthogonalization. 58 | 59 | INPUT: 60 | S: Overlap matrix 61 | OUTPUT: 62 | X: Transformation matrix 63 | 64 | Source: 65 | Modern Quantum Chemistry 66 | Szabo and Ostlund 67 | Dover 68 | 1989 69 | """ 70 | 71 | s, U = la.eig(S) 72 | 73 | s = np.diag(s**(-1./2.)) 74 | 75 | X = np.dot(U,s) 76 | 77 | return X 78 | 79 | def T_kinetic(basis): 80 | """ 81 | Compute kinetic matrix T. 82 | 83 | INPUT: 84 | BASIS: basis set 85 | OUTPUT: 86 | T: Kinetic matrix 87 | """ 88 | # Size of the basis set 89 | K = basis.K 90 | 91 | # List of basis functions 92 | B = basis.basis() 93 | 94 | T = np.zeros((K,K)) 95 | 96 | for i,b1 in enumerate(B): 97 | for j,b2 in enumerate(B): 98 | for a1,d1 in zip(b1["a"],b1["d"]): 99 | for a2,d2 in zip(b2["a"],b2["d"]): 100 | R1 = b1["R"] 101 | R2 = b2["R"] 102 | 103 | tmp = d1.conjugate()*d2 104 | tmp *= kinetic(b1["lx"],b1["ly"],b1["lz"],b2["lx"],b2["ly"],b2["lz"],a1,a2,R1,R2) 105 | 106 | T[i,j] += tmp 107 | 108 | return T 109 | 110 | def V_nuclear(basis,atom): 111 | """ 112 | Compute nuclear-electron potential energy matrix Vn. 113 | 114 | INPUT: 115 | BASIS: basis set 116 | ATOM: atom specifications (position and charge) 117 | OUTPUT: 118 | VN: Nuclear-attraction matrix for atom ATOM 119 | """ 120 | # Size of the basis set 121 | K = basis.K 122 | 123 | # List of basis functions 124 | B = basis.basis() 125 | 126 | # Nuclear coordinates 127 | Rn = atom.R 128 | 129 | # Nuclear charge 130 | Zn = atom.Z 131 | 132 | 133 | Vn = np.zeros((K,K)) 134 | 135 | for i,b1 in enumerate(B): 136 | for j,b2 in enumerate(B): 137 | for a1,d1 in zip(b1["a"],b1["d"]): 138 | for a2,d2 in zip(b2["a"],b2["d"]): 139 | R1 = b1["R"] 140 | R2 = b2["R"] 141 | 142 | tmp = d1.conjugate()*d2 143 | tmp *= nuclear(b1["lx"],b1["ly"],b1["lz"],b2["lx"],b2["ly"],b2["lz"],a1,a2,R1,R2,Rn,Zn) 144 | 145 | Vn[i,j] += tmp 146 | 147 | return Vn 148 | 149 | def H_core(basis,molecule): 150 | """ 151 | Compute core Hamiltonian (sum of T and all the VN) 152 | 153 | INPUT: 154 | BASIS: basis set 155 | MOLECULE: molecule, collection of atom objects 156 | OUTPUT: 157 | (T + VN): Core Hamitlonian 158 | """ 159 | T = T_kinetic(basis) 160 | 161 | print("Kinetic energy") 162 | print(T) 163 | 164 | # Size of the basis set 165 | K = basis.K 166 | 167 | Vn = np.zeros((K,K)) 168 | 169 | Vnn = np.zeros((K,K)) 170 | 171 | for atom in molecule: 172 | Vnn = V_nuclear(basis,atom) 173 | 174 | print("Nuclear attraction Vn") 175 | print(Vnn) 176 | 177 | Vn += Vnn 178 | 179 | print("Total nuclear attraction matrix") 180 | print(Vn) 181 | 182 | return T + Vn 183 | 184 | def P_density(C,N): 185 | """ 186 | Compute dansity matrix. 187 | 188 | INPUT: 189 | C: Matrix of coefficients 190 | N: Number of electrons 191 | OUTPUT: 192 | P: density matrix 193 | 194 | Source: 195 | Modern Quantum Chemistry 196 | Szabo and Ostlund 197 | Dover 198 | 1989 199 | """ 200 | 201 | # Size of the basis set 202 | K = C.shape[0] 203 | 204 | P = np.zeros((K,K)) 205 | 206 | for i in range(K): 207 | for j in range(K): 208 | for k in range(int(N/2)): #TODO Only for RHF 209 | P[i,j] += 2 * C[i,k] * C[j,k].conjugate() 210 | 211 | return P 212 | 213 | def G_ee(basis,molecule,P,ee): 214 | """ 215 | Compute core Hamiltonian matrix. 216 | 217 | INPUT: 218 | BASIS: Basis set. 219 | MOLECULE: Collection of atoms 220 | P: Density matrix 221 | EE: Two-electron integrals 222 | OUTPUT: 223 | G: Electron-electron interaction matrix 224 | """ 225 | 226 | # Size of the basis set 227 | K = basis.K 228 | 229 | G = np.zeros((K,K)) 230 | 231 | for i in range(K): 232 | for j in range(K): 233 | for k in range(K): 234 | for l in range(K): 235 | G[i,j] += P[k,l] * (ee[i,j,k,l] - 0.5 * ee[i,l,k,j]) 236 | 237 | return G 238 | 239 | if __name__ == "__main__": 240 | 241 | """ 242 | Results compared with 243 | 244 | Modern Quantum Chemistry 245 | Szabo and Ostlund 246 | Dover 247 | 1989 248 | 249 | and 250 | 251 | The Mathematica Journal 252 | Evaluation of Gaussian Molecular Integrals 253 | I. Overlap Integrals 254 | Minhhuy Hô and Julio Manuel Hernández-Pérez 255 | 2012 256 | 257 | and 258 | 259 | The Mathematica Journal 260 | Evaluation of Gaussian Molecular Integrals 261 | II. Kinetic-Energy Integrals 262 | Minhhuy Hô and Julio Manuel Hernández-Pérez 263 | 2013 264 | 265 | and 266 | 267 | The Mathematica Journal 268 | Evaluation of Gaussian Molecular Integrals 269 | III. Nuclear-Electron attraction Integrals 270 | Minhhuy Hô and Julio Manuel Hernández-Pérez 271 | 2014 272 | """ 273 | 274 | # H2 275 | H2 = [Atom("H",(0,0,0),1,["1s"]),Atom("H",(0,0,1.4),1,["1s"])] 276 | 277 | # Create the basis set 278 | sto3g_H2 = STO3G(H2) 279 | 280 | # Compute matrices 281 | S_H2 = S_overlap(sto3g_H2) 282 | T_H2 = T_kinetic(sto3g_H2) 283 | Vn1_H2 = V_nuclear(sto3g_H2,H2[0]) 284 | Vn2_H2 = V_nuclear(sto3g_H2,H2[1]) 285 | H_core_H2 = H_core(sto3g_H2,H2) 286 | 287 | print("###########") 288 | print("H2 molecule") 289 | print("###########") 290 | 291 | print("\nOverlap matrix S:") 292 | print(S_H2) 293 | 294 | print("\nKinetic matrix T:") 295 | print(T_H2) 296 | 297 | print("\nElectron-nucleus interaction " + H2[0].name + " :") 298 | print(Vn1_H2) 299 | 300 | print("\nElectron-nucleus interaction " + H2[1].name + " :") 301 | print(Vn2_H2) 302 | 303 | print("\nCore Hamiltonian:") 304 | print(H_core_H2) 305 | 306 | # HeH+ 307 | HeH = [Atom("H",(0,0,0),1,["1s"]),Atom("He",(0,0,1.4632),2,["1s"])] 308 | 309 | # Create the basis set 310 | sto3g_HeH = STO3G(HeH) 311 | 312 | # Compute matrices 313 | S_HeH = S_overlap(sto3g_HeH) 314 | T_HeH = T_kinetic(sto3g_HeH) 315 | Vn1_HeH = V_nuclear(sto3g_HeH,HeH[0]) 316 | Vn2_HeH = V_nuclear(sto3g_HeH,HeH[1]) 317 | H_core_HeH = H_core(sto3g_HeH,HeH) 318 | 319 | print("\n\n\n") 320 | print("############") 321 | print("HeH molecule") 322 | print("############") 323 | 324 | print("\nOverlap matrix S:") 325 | print(S_HeH) 326 | 327 | print("\nKinetic matrix T:") 328 | print(T_HeH) 329 | 330 | print("\nElectron-nucleus interaction " + HeH[0].name + " :") 331 | print(Vn1_HeH) 332 | 333 | print("\nElectron-nucleus interaction " + HeH[1].name + " :") 334 | print(Vn2_HeH) 335 | 336 | print("\nCore Hamiltonian:") 337 | print(H_core_HeH) 338 | 339 | # H2O 340 | H2O = [ Atom("H",(0,+1.43233673,-0.96104039),1,["1s"]), 341 | Atom("H",(0,-1.43233673,-0.96104039),1,["1s"]), 342 | Atom("O",(0,0,0.24026010),8,["1s","2s","2p"])] 343 | 344 | sto3g_H2O = STO3G(H2O) 345 | 346 | # Overlap matrix 347 | S_H2O = S_overlap(sto3g_H2O) 348 | T_H2O = T_kinetic(sto3g_H2O) 349 | Vn1_H2O = V_nuclear(sto3g_H2O,H2O[0]) 350 | Vn2_H2O = V_nuclear(sto3g_H2O,H2O[1]) 351 | Vn3_H2O = V_nuclear(sto3g_H2O,H2O[2]) 352 | 353 | Vn_H2O = Vn1_H2O + Vn2_H2O + Vn3_H2O 354 | 355 | H_core_H2O = H_core(sto3g_H2O,H2O) 356 | 357 | print("\n\n\n") 358 | print("############") 359 | print("H2O molecule") 360 | print("############") 361 | 362 | print("\nOverlap matrix S:") 363 | print(S_H2O) 364 | 365 | print("\nKinetic matrix T:") 366 | print(T_H2O) 367 | 368 | print("\nTotal electron-nucleus interaction:") 369 | print(Vn_H2O) 370 | 371 | print("\nCore hamiltonian:") 372 | print(H_core_H2O) 373 | -------------------------------------------------------------------------------- /Python/molecules.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (C) 2015 Rocco Meli 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | """ 17 | 18 | from basis import * 19 | 20 | import numpy as np 21 | 22 | # H2 23 | H2 = [Atom("H",(0,0,0),1,["1s"]),Atom("H",(0,0,1.4),1,["1s"])] 24 | sto3g_H2 = STO3G(H2) 25 | 26 | # HeH+ 27 | HeH = [Atom("He",(0,0,1.4632),2,["1s"]),Atom("H",(0,0,0),1,["1s"])] 28 | sto3g_HeH = STO3G(HeH) 29 | 30 | # He 31 | He = [Atom("He",(0,0,0),2,["1s"])] 32 | sto3g_He = STO3G(He) 33 | 34 | # B 35 | Be = [Atom("Be",(0,0,0),4,["1s","2s"])] 36 | sto3g_Be = STO3G(Be) 37 | 38 | # N2 39 | N2 = [ Atom("N",(0,0,0),7,["1s","2s","2p"]), 40 | Atom("N",(0,0,2.074),7,["1s","2s","2p"])] 41 | sto3g_N2 = STO3G(N2) 42 | 43 | # HF 44 | HF = [ Atom("H",(0,0,0),1,["1s"]), 45 | Atom("F",(0,0,1.807),9,["1s","2s","2p"])] 46 | sto3g_HF = STO3G(HF) 47 | 48 | # B 49 | O = [Atom("O",(0,0,0),8,["1s","2s","2p"])] 50 | sto3g_O = STO3G(O) 51 | 52 | # H2O 53 | # Szabo and Ostlund 54 | H2O = [ Atom("H",(1.809*np.sin(104.52/180*np.pi/2),0,0),1,["1s"]), 55 | Atom("H",(-1.809*np.sin(104.52/180*np.pi/2),0,0),1,["1s"]), 56 | Atom("O",(0,1.809*np.cos(104.52/180*np.pi/2),0),8,["1s","2s","2p"])] 57 | # Mathematica Journal 58 | #H2O = [ Atom("H",(0,1.43233673,-0.96104039),1,["1s"]), 59 | # Atom("H",(0,-1.43233673,-0.96104039),1,["1s"]), 60 | # Atom("O",(0,0,0.24026010),8,["1s","2s","2p"])] 61 | sto3g_H2O = STO3G(H2O) 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hartree-Fock 2 | 3 | Hartree-Fock code for total energy calculations within Pople's STO-3G basis set. 4 | 5 | 6 | ### Details 7 | 8 | The general implementation follows Reference [1]. One- and two-electron integrals were originally implemented using analytical results as explained in Reference [2] (very slow). Overlap and multipole integrals are now implemented using the Obara-Saika scheme as presented in Reference [3]. 9 | 10 | ### Disclaimer 11 | 12 | This program was written in 2015 for the class *Computational Methods in Molecular Quantum Mechanics* at *Ecole Polytechnique Fédérale de Lausanne* and was awarded the maximum grade. 13 | 14 | It was my very first Fortran program, therefor the coding style might be completely off. My Python skill were also very much in development back then. 15 | 16 | ## Python 17 | 18 | First iteration of the program. Restricted Hartree-Fock (RHF) calculations only. Extremely slow. 19 | 20 | ## Fortran90 21 | 22 | Second iteration of the program. RHF and Unrestricted Hartree-Fock (UHF). Much faster, because of compiler optimization. 23 | 24 | Total energy derivatives with respect to nuclear coordinates are computed only using finite differences (no analytical derivatives, very inefficient). Born-Oppenheimer molecular dynamics (BOMD) is not working properly. 25 | 26 | 27 | ## Known Bugs 28 | 29 | - BOMD is not working 30 | 31 | ## TODO 32 | 33 | - Reduce libraries requirements 34 | - Faster implementation of one- and two-electron integrals 35 | - Analytical derivatives 36 | - Fix BOMD 37 | - Visualization of molecular orbitals 38 | 39 | ## References 40 | 41 | [1] A. Szabo and N. S. Ostlund, *Modern Quantum Chemistry: Introduction to Advanced Electronic Structure Theory*, Dover Publications (1996). 42 | 43 | [2] D. Cook, *Handbook of Computational Chemistry*, Oxford University Press (1998). 44 | 45 | [3] T. Helgaker, P. Jørgensen and J. Olsen, *Molecular Electronic-Structure Theory*, Wiley (2000).* 46 | --------------------------------------------------------------------------------