├── .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 |
--------------------------------------------------------------------------------