Нам даны 5 файлов с разными параметрами контроля температуры:
Объект исследования - одна молекула этана. Нам был предоставлен файл с координатами этана - etane.gro. Был построен файл с топологией et.top, используя описанный ниже скрипт:
# загрузим модули
import rdkit
from rdkit import Chem
from rdkit.Chem import AllChem, Draw
from rdkit.Chem import Descriptors
from rdkit import RDConfig
from IPython.display import Image,display
import numpy as np
#создаем этан
mol=Chem.MolFromSmiles('CC')
AllChem.Compute2DCoords(mol)
m3d=Chem.AddHs(mol)
Chem.AllChem.EmbedMolecule(m3d)
AllChem.MMFFOptimizeMolecule(m3d,maxIters=500,nonBondedThresh=200 )
#прописываем связи между атомами
bonds = m3d.GetBonds()
for i,b in enumerate(bonds):
print b.GetBeginAtomIdx()+1 , b.GetEndAtomIdx()+1, 1
#углы
for b1 in m3d.GetBonds():
for b2 in m3d.GetBonds():
if b1.GetBeginAtomIdx() == b2.GetBeginAtomIdx() and b1.GetIdx() != b2.GetIdx():
print b1.GetEndAtomIdx()+1 , b1.GetBeginAtomIdx()+1, b2.GetEndAtomIdx()+1, 1
#торсионные углы
for b1 in m3d.GetBonds():
for b2 in m3d.GetBonds():
for b3 in m3d.GetBonds():
if b1.GetBeginAtomIdx() == b2.GetBeginAtomIdx() and b2.GetEndAtomIdx() == b3.GetBeginAtomIdx()and b1.GetIdx() != b2.GetIdx():
print b1.GetEndAtomIdx()+1 , b1.GetBeginAtomIdx()+1, b2.GetEndAtomIdx()+1, b3.GetEndAtomIdx()+1, 1
На основе файла ffbonded.itp, были выбраны правильные типы атомов: opls_139 для углерода и opls_140 для водорода.
import subprocess
import time
for method in ["be","vr","nh","an","sd"]:
#С помощью grompp строим файлы .tpr для запуска молдинамики
command1 = 'grompp -f %s.mdp -c etane.gro -p et.top -o et_%s.tpr' %(method,method)
subprocess.Popen(command1,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#запускаем молекулярную динамику
start = time.time()
command2 = 'mdrun -deffnm et_%s -v -nt 1' %method
subprocess.Popen(command2,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Runtime for %s-method: %s seconds" % (method,round(time.time() - start, 3)))
Самыми быстрыми оказались методы be, vr, nh ~0,012-0,013 секунд, самыми медленными an и sd ~0,026-0,035 секунд.
Визуальный анализ:
#Переводим в файл с траекторий в .pdb формат и визуализируем:
for method in ["be","vr","nh","an","sd"]:
command3 = 'echo 2 | trjconv -f et_%s.trr -s et_%s.tpr -o et_%s.pdb' %(method,method,method)
subprocess.Popen(command3,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Image(url='an.gif') #незначительные колебания относительно С-С связи, молекула не вращается
Image(url='be.gif') #появляются относительно медленные вращетельные движения
Image(url='nh.gif') #ускорение вращательного движения, подвижные CCH углы
Image(url='sd.gif') #самая быстроизменяющаяся система, поступательные и вращательные движения
Image(url='vr.gif') #поведение молекулы схоже с молекулой в системе be
Сравним потенциальную и кинетическую энергию для каждой из пяти систем:
for method in ["be","vr","nh","an","sd"]:
#создаем файл с потенциальной энергией системы
command4 = 'echo 10 | g_energy -f et_%s.edr -o et_%s_en_potential.xvg -xvg none' %(method,method)
subprocess.Popen(command4,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#с кинетической
command5 = 'echo 11 | g_energy -f et_%s.edr -o et_%s_en_kinetic.xvg -xvg none' %(method,method)
subprocess.Popen(command5,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
#для каждого метода сравниваем потенциальную и кинетическую энергии
for method in ["be","vr","nh","an","sd"]:
a_potential= np.loadtxt('et_%s_en_potential.xvg' %method)
a_kinetic= np.loadtxt('et_%s_en_kinetic.xvg' %method)
t=a_kinetic[:,0]
e_potential=a_potential[:,1]
e_kinetic=a_kinetic[:,1]
plt.plot(t, e_potential, color='grey')
plt.plot(t, e_kinetic, color='orange')
plt.title('Method %s' %method)
kin_patch = mpatches.Patch(color='orange', label='Kinetic energy')
pot_patch = mpatches.Patch(color='grey', label='Potential energy')
plt.legend(handles=[kin_patch,pot_patch])
plt.show()
Согласно полученным графикам в большинстве случаев значения кинеической и потенциальной энергий практически совпадают. Исключением явлется метод nh, где кинетическая энергия больше потенциальной. Для всех энергий на всех графиках характерны колебания. Наибольшей аплитуды они достигают в случае метода nh, наименьшей в случае an (значение самих энергией на два порядка меньше, чем у остальных методов). В случае метода be колебания к концу динамики уменьшаются.
Рассмотрим распределение длинны связи С-С за время моделирования. Сначала создадим индекс файл с одной связью. В текстовом редакторе создайте файл b.ndx со следующим содержимым:
[ b ]
1 2
И запустим утилиту по анализу связей g_bond:
for method in ["be","vr","nh","an","sd"]:
command6 = 'g_bond -f et_%s.trr -s et_%s.tpr -o bond_%s.xvg -n b.ndx -xvg none' %(method,method, method)
subprocess.Popen(command6,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Построим графики распределения длинн связей в виде гистограммы:
for method in ["be","vr","nh","an","sd"]:
bonds = np.loadtxt('bond_%s.xvg' % method)
x = bonds[:,0]
y = bonds[:,1]
width = 0.0008
plt.bar(x, y, width, color="grey")
plt.title('Length of C-C bond (%s method)' % method)
plt.xlim(0.14, 0.165)
plt.show()
Распределению Максвелла-Больцмана наиболее соответствуют распределения длин С-С связей в системах vr, sd и nh. В системах an и be длина С-С связи незначительно отклоняется от среднего значения (имеет маленькую дисперсию), что не соответсвует действительности.
Метод Андерсена (an) имеет очень маленькую амплитуду длины связи C-C, молекула не движется ни вращетельно, ни поступательно, имеет на два порядка меньшее значение энергий молекулы, работает медленнее остальных. Метод Нуза-Хувера (nh) даёт слишком сильные выбросы в значениях энергии системы. При использовании метода Берендсена (be) амплитуда C-C связи изменяется не сильно. Метод стохастической молекулярной динамики (sd) и метод Velocity rescale (vr) имеют наиболее соответствующее распределению Максвелла-Больцмана распределение длин С-С связей, но метод sd придаёт этану очень хаотичные и быстрые движения, кроме того является одним из самых медленных алгоритмов. Самым оптимальным методом является метод Velocity rescale.