Цель задания: определение констант ковалентных взаимодействий для молекулярной механики на основе квантово-химических расчётов.
Нам дана оптимизированная структура этана в виде z-matrix:
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 180
H 2 1 5 1.08439 111.200 120
H 2 1 5 1.08439 111.200 -120
*
'''
Для того, чтобы преобразовать её в то, что прочитает psi4, посмотрим на пример с водой:
h2o = psi4.geometry("""
O
H 1 0.96
H 1 0.96 2 104.5
""")
Т.е.
O
H 1 длина_связи_O_H
H 1 длина_связи_O_H 2 угол_H_O_H
Таким образом для матрицы этана:
C
C 1 длина_связи_С_С
H 1 длина_связи_H_C 2 валентный_угол_H_C_C
H 1 длина_связи_H_C 2 H_C_C 3 угол_H_C_C_H
H 1 длина_связи_H_C 2 H_C_C 3 угол_H_C_C_H
H 2 длина_связи_H_C 1 H_C_C 3 торсионный_угол
H 2 длина_связи_H_C 1 H_C_C 5 угол_H_C_C_H
H 2 длина_связи_H_C 1 H_C_C 5 угол_H_C_C_H
C
C 1 1.52986
H 1 1.08439 2 111.200
H 1 1.08439 2 111.200 3 120
H 1 1.08439 2 111.200 3 -120
H 2 1.08439 1 111.200 3 0
H 2 1.08439 1 111.200 5 120
H 2 1.08439 1 111.200 5 -120
Необходимо:
Получить 20 z-matrix c разными длиннами связи C-C с шагом 0.02 ангстрема для поиска варианта с минимальной энергией.
Проделать аналогичные операции для валентного угла HCС, его значения должны изменяться от 109.2 до 113.2. Сравнить полученные константы с данными из статьи о GAFF.
Проделать аналогичные операции для торсионного угла CC, его значения должны изменяться от -180 до 180 c шагом 12. Сохранить изображение и указать в отчёте количество минимумов функции.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
from scipy import optimize
from IPython.display import Image, display
import psi4
Ниже предложенный скрипт по запуску функций пакета Psi4, где
def run_psi4(inp):
m = psi4.geometry(inp)
psi4.set_options({"maxiter": 200, "fail_on_maxiter" : True})
return psi4.energy('scf/cc-pvtz', molecule = m )
def calculate_energy(bond_length):
geom = f'''
C
C 1 {bond_length}
H 1 1.08439 2 111.200
H 1 1.08439 2 111.200 3 120
H 1 1.08439 2 111.200 3 -120
H 2 1.08439 1 111.200 3 0
H 2 1.08439 1 111.200 5 120
H 2 1.08439 1 111.200 5 -120
'''
return run_psi4(geom)
print(calculate_energy(1))
-78.79588773541637
x_o=np.arange(1.3,1.7,0.02)
y_o = np.array(list(map(calculate_energy, x_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()
Optimized params: [ 0.75232916 1.55165175 -79.25655593]
C:\Users\днс\AppData\Local\Temp\ipykernel_6972\3011160597.py:13: UserWarning: color is redundantly defined by the 'color' keyword argument and the fmt string "ro" (-> color='r'). The keyword argument will take precedence. plt.plot(x_o, y_o, "ro", x_o,fitfunc(p1,x_o),"r-",c='blue',alpha=0.5) C:\Users\днс\AppData\Local\Temp\ipykernel_6972\3011160597.py:13: UserWarning: color is redundantly defined by the 'color' keyword argument and the fmt string "r-" (-> color='r'). The keyword argument will take precedence. plt.plot(x_o, y_o, "ro", x_o,fitfunc(p1,x_o),"r-",c='blue',alpha=0.5)
Оптимальная длина связи - 1.5517. В википедии - 1.5351, в статье GAFF - 1.526. Ну, немного больше.
def calculate_energy(HCC_angle):
geom = f'''
C
C 1 1.52986
H 1 1.08439 2 {HCC_angle}
H 1 1.08439 2 111.200 3 120
H 1 1.08439 2 111.200 3 -120
H 2 1.08439 1 111.200 3 0
H 2 1.08439 1 111.200 5 120
H 2 1.08439 1 111.200 5 -120
'''
return run_psi4(geom)
#Википедия говорит, что длина угла - 111.17, так что initial quess - 111
print(calculate_energy(111))
-78.85730475547705
x_o = np.arange(109.2,113.2,0.2)
y_o = np.array(list(map(calculate_energy, x_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, 111, -78] # 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(108,114)
plt.show()
Optimized params: [ 3.93927516e-05 1.11938788e+02 -7.92550798e+01]
C:\Users\днс\AppData\Local\Temp\ipykernel_6972\2182522502.py:13: UserWarning: color is redundantly defined by the 'color' keyword argument and the fmt string "ro" (-> color='r'). The keyword argument will take precedence. plt.plot(x_o, y_o, "ro", x_o,fitfunc(p1,x_o),"r-",c='blue',alpha=0.5) C:\Users\днс\AppData\Local\Temp\ipykernel_6972\2182522502.py:13: UserWarning: color is redundantly defined by the 'color' keyword argument and the fmt string "r-" (-> color='r'). The keyword argument will take precedence. plt.plot(x_o, y_o, "ro", x_o,fitfunc(p1,x_o),"r-",c='blue',alpha=0.5)
Оптимальный валентный угол - 111.9388, на Википедии - 111.17, в статье GAFF значений валентных углов нет.
def calculate_energy_torsion(HCCH_angle):
adjust = lambda x: (x + 180 + 360) % 360 - 180 if x != 180 else 180
geom = f'''
C
C 1 1.52986
H 1 1.08439 2 111.200
H 1 1.08439 2 111.200 3 120
H 1 1.08439 2 111.200 3 -120
H 2 1.08439 1 111.200 3 {HCCH_angle}
H 2 1.08439 1 111.200 3 {adjust(HCCH_angle + 120)}
H 2 1.08439 1 111.200 3 {adjust(HCCH_angle - 120)}
'''
return run_psi4(geom)
x_torsion = np.arange(-180, 181, 12)
y_torsion = np.array(list(map(calculate_energy_torsion, x_torsion)))
#Plot it
plt.plot(x_torsion, y_torsion, "ro")
plt.show()
Четыре минимума (-180, -60, 60, 180), c периодичностью 120, что соответсвует заторможенной конформации.
from IPython import display
display.Image("https://cdn.masterorganicchemistry.com/wp-content/uploads/2020/02/15-energy-diagram-for-ethane-torsional-strain-versus-dihedral-angle.gif")
<IPython.core.display.Image object>