%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
функция по запуску ORCA
import subprocess
def run_orca(inp):
with open('orca.inp', 'w') as outfile:
outfile.write(str(inp))
p = subprocess.Popen(str('/srv/databases/orca/orca orca.inp' ),
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out=p.communicate()[0]
out = str(out)
lines = out.split("\\n")
for s in lines:
if 'FINAL SINGLE POINT ENERGY' in s:
return float(s.split()[4])
варьирование длины одной из связей (C-C). Меняем значения длины связи C-C в диапазоне 1.4-1.78Å с шагом 0.02Å, рассчитываем энергию с помощью ORCA.
initial_bond=1.52986 #написано в input-файле
bonds=[]
energies=[]
bonds = np.linspace(1.4, 1.78, 20)
#for i in range(-10,11):
# bond=initial_bond+i*0.02
# bonds.append(round(bond,5))
inp = '''!HF RHF 6-31G
* int 0 1
C 0 0 0 0 0 0
C 1 0 0 %6.5f 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 6 1.08439 111.200 120
H 2 1 6 1.08439 111.200 -120
*
'''
for bond in bonds:
cur_energ=run_orca(inp % bond)
# cur_energ=run_orca(inp)
energies.append(cur_energ)
print (bonds)
print (energies)
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.ylabel('Energy, kJ/mol')
plt.xlabel('Bond length, angstrem')
# plt.xlim(1,2)
plt.show()
plot(bonds, energies)
В результате был получен график, отражающий зависимость значения энергии от длины С-С связи.
Расчет зависимости энергии от значения валентного угла HCC:
inp_2='''!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 %6.5f 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
*
'''
bonds1=[]
energies1=[]
bonds1 = np.linspace(109.2,113.2,21)
for bond1 in bonds1:
cur_energ1=run_orca(inp_2 % bond1)
# cur_energ=run_orca(inp)
energies1.append(cur_energ1)
print (bonds1)
plot(bonds1, energies1)
Расчет зависимости энергии от значения торсионного угла CC:
inp_3 = '''!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 %6.5f
H 2 1 6 1.08439 111.200 120
H 2 1 6 1.08439 111.200 -120
*
'''
bonds2=[]
energies2=[]
bonds2 = np.linspace(-180,180,31)
for bond2 in bonds2:
cur_energ2=run_orca(inp_3 % bond2)
# cur_energ=run_orca(inp)
energies2.append(cur_energ2)
print (bonds2)
plot(bonds2, energies2) #при использовании функции plot выдается странная аппроксимация. нужно зафиттить иначе
не будем использовать заданную функцию,а зафиттим с помощью косинуса
fitfunc = lambda p, x: p[0]*(np.cos(p[1]*x)) + p[2]
errfunc = lambda p, x, y: fitfunc(p, x) - y
p0 = [1, 1, 1]
p1, success = optimize.leastsq(errfunc, p0[:], args=(bonds2, energies2))
print ("Optimized params:", p1)
plt.ylabel('Energy, kJ/mol')
plt.xlabel('Bond length, angstrem')
#Plot it
plt.plot(bonds2, energies2, "ro", bonds2, fitfunc(p1,bonds2),"r-",c='blue',alpha=0.5)
plt.xlim(-190,190)
plt.show()
функция имеет четыре минимума
при расчете связи увеличим шаг до 0.1 ангстрема:
bonds4=[]
energies4=[]
bonds4 = np.linspace(0.4, 4.3, 40)
#for i in range(-10,11):
# bond=initial_bond+i*0.02
# bonds.append(round(bond,5))
inp = '''!HF RHF 6-31G
* int 0 1
C 0 0 0 0 0 0
C 1 0 0 %6.5f 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 6 1.08439 111.200 120
H 2 1 6 1.08439 111.200 -120
*
'''
for bond4 in bonds4:
cur_energ4=run_orca(inp % bond4)
# cur_energ=run_orca(inp)
energies4.append(cur_energ4)
print (bonds4)
plot(bonds4, energies4)
наблюдаемую зависимость нельзя аппроксимировать гиперболой (хотя при маленьком диапазоне казалось, что можно)