%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
import subprocess
inp = '''!HF RHF 6-31G
* int 0 1
C 0 0 0 0 0 0
C 1 0 0 %s 0 0
H 1 2 0 1.08439 111.200 0
H 1 2 3 1.08439 111.200 120
H 1 2 3 1.08439 111.200 -120
H 2 1 3 1.08439 111.200 180
H 2 1 5 1.08439 111.200 120
H 2 1 5 1.08439 111.200 -120
*
'''
def run_orca(inp, suffix):
with open('orca_%s.inp' % suffix, 'w') as outfile:
outfile.write(inp)
p = subprocess.Popen(str('/srv/databases/orca/orca orca_%s.inp' % suffix),
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out=p.communicate()[0]
lines = out.splitlines()
# extract energy: FINAL SINGLE POINT ENERGY'
# and return it as float
for s in out.splitlines():
if s.startswith("FINAL SINGLE POINT ENERGY"):
return(float(s[len("FINAL SINGLE POINT ENERGY"):]))
cc_length = []
cc_energy = []
for n in range(20):
length = (1.52986 - 0.02 * 10) + 0.02 * n
cc_length.append(length)
energy = run_orca(inp % length, '_cc_' + str(length))
cc_energy.append(energy)
def plot(x_o, y_o):
#function is f(x)=k(b-x)^2 + a
fitfunc = lambda p, x: p[0]*pow(p[1]-x,2) + p[2] # Target function
errfunc = lambda p, x, y: fitfunc(p, x) - y # Error function
p0 = [1,1, -79] # Initial guess for the parameters
p1, success = optimize.leastsq(errfunc, p0[:], args=(x_o, y_o))
print "Optimized params:", p1
#Plot it
plt.plot(x_o, y_o, "ro", x_o, fitfunc(p1, x_o), "r-", c='blue', alpha=0.5)
# plt.xlim(1,2)
plt.show()
plot(cc_length, cc_energy)
inp = '''!HF RHF 6-31G
* int 0 1
C 0 0 0 0 0 0
C 1 0 0 1.52986 0 0
H 1 2 0 1.08439 %s 0
H 1 2 3 1.08439 111.200 120
H 1 2 3 1.08439 111.200 -120
H 2 1 3 1.08439 111.200 180
H 2 1 5 1.08439 111.200 120
H 2 1 5 1.08439 111.200 -120
*
'''
hcc_length = []
hcc_energy = []
for n in range(41):
length = 109.2 + 0.1 * n
hcc_length.append(length)
energy = run_orca(inp % length, '_hcc_' + str(length))
hcc_energy.append(energy)
plot(hcc_length, hcc_energy)
inp = '''!HF RHF 6-31G
* int 0 1
C 0 0 0 0 0 0
C 1 0 0 1.52986 0 0
H 1 2 0 1.08439 111.200 0
H 1 2 3 1.08439 111.200 120
H 1 2 3 1.08439 111.200 -120
H 2 1 3 1.08439 111.200 %s
H 2 1 5 1.08439 111.200 120
H 2 1 5 1.08439 111.200 -120
*
'''
tcc_length = []
tcc_energy = []
for n in range(-180, 181, 12):
length = n
tcc_length.append(length)
energy = run_orca(inp % length, '_tcc_' + str(length))
tcc_energy.append(energy)
plt.plot(tcc_length, tcc_energy, "ro", c='blue', alpha=0.5)
print(tcc_energy)
Функция имеет три минимума. Для некоторых значений угла энергия не посчиталась.
Увеличим шаг до 0.1 ангстрема при расчёте связи
inp = '''!HF RHF 6-31G
* int 0 1
C 0 0 0 0 0 0
C 1 0 0 %s 0 0
H 1 2 0 1.08439 111.200 0
H 1 2 3 1.08439 111.200 120
H 1 2 3 1.08439 111.200 -120
H 2 1 3 1.08439 111.200 180
H 2 1 5 1.08439 111.200 120
H 2 1 5 1.08439 111.200 -120
*
'''
ecc_length = []
ecc_energy = []
for n in range(20):
length = (1.52986 - 0.1 * 10) + 0.1 * n
ecc_length.append(length)
energy = run_orca(inp % length, '_ext_cc_' + str(length))
ecc_energy.append(energy)
plot(ecc_length, ecc_energy)
Наблюдаемую зависимость можно аппроксимировать гиперболой.