Задание 7. Изучение работы методов контроля температуры в молекулярной динамике

Подготовительные работы

Импортируем нужные модули.

In [1]:
from subprocess import run

Скачаем в рабочую директорию все необходимые файлы.

In [2]:
%%bash
wget http://kodomo.fbb.msu.ru/FBB/year_08/term6/etane.gro -O et.gro
wget http://kodomo.fbb.msu.ru/FBB/year_08/term6/be.mdp
wget http://kodomo.fbb.msu.ru/FBB/year_08/term6/vr.mdp
wget http://kodomo.fbb.msu.ru/FBB/year_08/term6/nh.mdp
wget http://kodomo.fbb.msu.ru/FBB/year_08/term6/an.mdp
wget http://kodomo.fbb.msu.ru/FBB/year_08/term6/sd.mdp
--2020-04-09 19:55:32--  http://kodomo.fbb.msu.ru/FBB/year_08/term6/etane.gro
Resolving kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)... 192.168.180.1
Connecting to kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)|192.168.180.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 399
Saving to: `et.gro'

     0K                                                       100% 47.4M=0s

2020-04-09 19:55:32 (47.4 MB/s) - `et.gro' saved [399/399]

--2020-04-09 19:55:32--  http://kodomo.fbb.msu.ru/FBB/year_08/term6/be.mdp
Resolving kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)... 192.168.180.1
Connecting to kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)|192.168.180.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1356 (1.3K)
Saving to: `be.mdp'

     0K .                                                     100%  120M=0s

2020-04-09 19:55:32 (120 MB/s) - `be.mdp' saved [1356/1356]

--2020-04-09 19:55:32--  http://kodomo.fbb.msu.ru/FBB/year_08/term6/vr.mdp
Resolving kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)... 192.168.180.1
Connecting to kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)|192.168.180.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1427 (1.4K)
Saving to: `vr.mdp'

     0K .                                                     100%  127M=0s

2020-04-09 19:55:32 (127 MB/s) - `vr.mdp' saved [1427/1427]

--2020-04-09 19:55:32--  http://kodomo.fbb.msu.ru/FBB/year_08/term6/nh.mdp
Resolving kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)... 192.168.180.1
Connecting to kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)|192.168.180.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1429 (1.4K)
Saving to: `nh.mdp'

     0K .                                                     100%  120M=0s

2020-04-09 19:55:32 (120 MB/s) - `nh.mdp' saved [1429/1429]

--2020-04-09 19:55:32--  http://kodomo.fbb.msu.ru/FBB/year_08/term6/an.mdp
Resolving kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)... 192.168.180.1
Connecting to kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)|192.168.180.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1426 (1.4K)
Saving to: `an.mdp'

     0K .                                                     100%  119M=0s

2020-04-09 19:55:32 (119 MB/s) - `an.mdp' saved [1426/1426]

--2020-04-09 19:55:32--  http://kodomo.fbb.msu.ru/FBB/year_08/term6/sd.mdp
Resolving kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)... 192.168.180.1
Connecting to kodomo.fbb.msu.ru (kodomo.fbb.msu.ru)|192.168.180.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1441 (1.4K)
Saving to: `sd.mdp'

     0K .                                                     100% 93.2M=0s

2020-04-09 19:55:32 (93.2 MB/s) - `sd.mdp' saved [1441/1441]

Теперь допишем заготовку файла с топологией этана. Во-первых, дописали все необходимые связи, валентные и торсионные углы. Во-вторых, поменяли типы атомов: CX на opls_135, а HX на opls_140. В-третьих, определили, что тип потенциала торсионных углов равен 3. Итоговый файл выглядит так:

In [3]:
%%bash
cat et.top
#include "/usr/share/gromacs/top/oplsaa.ff/forcefield.itp"

[ moleculetype ]
; Name            nrexcl
et            3

[ atoms ]
;   nr  type  resnr  residue  atom   cgnr     charge       mass
    1   opls_135      1    ETH      C1      1    -0.189      12.01
    2   opls_135      1    ETH      C2      2    -0.155      12.01
    3   opls_140      1    ETH      H1      3     0.059       1.008
    4   opls_140      1    ETH      H2      4     0.059       1.008
    5   opls_140      1    ETH      H3      5     0.059       1.008
    6   opls_140      1    ETH      H4      6     0.056       1.008
    7   opls_140      1    ETH      H5      7     0.056       1.008
    8   opls_140      1    ETH      H6      8     0.056       1.008
    
[ bonds ]
;  ai    aj funct  b0       kb
     1   2   1  
     1   3   1
     1   4   1  
     1   5   1  
     2   6   1  
     2   7   1  
     2   8   1  

[ angles ]
;  ai    aj    ak funct  phi0   kphi
;around c1
    3     1     4     1  
    3     1     5     1  
    4     1     5     1  
    2     1     3     1  
    2     1     4     1  
    2     1     5     1  
;around c2
    6     2     7     1  
    6     2     8     1  
    7     2     8     1  
    1     2     6     1  
    1     2     7     1  
    1     2     8     1  

[ dihedrals ]
;  ai    aj    ak    al funct  
    3    1     2     6      3  
    3    1     2     7      3 
    3    1     2     8      3  
    4    1     2     6      3  
    4    1     2     7      3 
    4    1     2     8      3  
    5    1     2     6      3  
    5    1     2     7      3 
    5    1     2     8      3  
 
[ pairs ]
; atom list for 1-4
;  ai    aj funct
   3  6
   3  7
   3  8
   4  6
   4  7
   4  8
   5  6
   5  7
   5  8

[ System ]
; any text here
first one
[ molecules ]
;Name count
 et    1

И создадим файл для подсчёта длины C-C связи.

In [4]:
%%bash
echo -e "[ b ]\n1 2" > b.ndx
In [5]:
%%bash
cat b.ndx
[ b ]
1 2

Расчёт работы термостатов

Посчитаем всё, что от нас хотят, в цикле.

In [2]:
thermo_types = ['be', 'vr', 'nh', 'an', 'sd']
In [8]:
for thermo in thermo_types:
    # configs
    run(f'grompp -f {thermo}.mdp -c et.gro -p et.top -o et_{thermo}.tpr', shell=True)
    print(thermo + '\tconfig')
    # mdrun
    run(f'mdrun -deffnm et_{thermo} -v -nt 1', shell=True)
    print(thermo + '\tmdrun')
    # pdb
    run(f'echo 0 | trjconv -f et_{thermo}.trr -s et_{thermo}.tpr -o et_{thermo}.pdb', shell=True)
    print(thermo + '\tpdb')
    # energies
    run(f'echo 10 11 | g_energy -f et_{thermo}.edr -o et_{thermo}_en.xvg -xvg none', shell=True)
    print(thermo + '\tenergies')
    # C-C bond lengths
    run(f'g_bond -f et_{thermo}.trr -s et_{thermo}.tpr -o bond_{thermo}.xvg -n b.ndx -xvg none', shell=True)
    print(thermo + '\tbond lengths')
be	config
be	mdrun
be	pdb
be	energies
be	bond lengths
vr	config
vr	mdrun
vr	pdb
vr	energies
vr	bond lengths
nh	config
nh	mdrun
nh	pdb
nh	energies
nh	bond lengths
an	config
an	mdrun
an	pdb
an	energies
an	bond lengths
sd	config
sd	mdrun
sd	pdb
sd	energies
sd	bond lengths

Визуальный анализ

Загрузим pymol. Он не заработал на kodomo, поэтому переехал к себе на ноутбук.

In [3]:
import __main__
__main__.pymol_argv = [ 'pymol', '-x' ]

import pymol
pymol.finish_launching()
from pymol import cmd
In [6]:
import os
import imageio
import time

Всего было 251 шагов.

In [11]:
for thermo in thermo_types:
    # aesthetics
    cmd.reinitialize()
    cmd.set('sphere_scale', 0.2)
    cmd.set('stick_radius', 0.1)
    cmd.set('ray_trace_mode', 3)
    cmd.set('antialias', 2)
    cmd.set('sphere_scale', 0.2)
    cmd.set('stick_radius', 0.1)
    # load data
    cmd.load(f'et_{thermo}.pdb')
    cmd.show('spheres')
    cmd.orient()
    # save images
    os.mkdir(thermo)
    cmd.mpng(os.path.join(thermo, ''), mode=2, width=640, height=480)
    while not os.path.exists(os.path.join(thermo, '0251.png')):
        time.sleep(0.1)
    # create gif    
    with imageio.get_writer(f'{thermo}.gif', mode='I', fps=30) as writer:
        for i in range(0, 251):
            image = imageio.imread(os.path.join(thermo, f'{i + 1:04}.png'))
            writer.append_data(image)

Теперь посмотрим на гифки.

In [12]:
from IPython.display import display, Image, HTML
In [14]:
thermo_names = ['Berendsen', 'V-rescale', 'Nose-Hoover', 'Andersen', 'Stochastic']
In [15]:
for thermo, name in zip(thermo_types, thermo_names):
    display(HTML(name))
    display(Image(f'{thermo}.gif', format='png'))
Berendsen
V-rescale
Nose-Hoover
Andersen
Stochastic

Мы видим, что при Андерсене молекула почти не двигается, а при стохастическом очень сильно мечется. Более правильным кажутся Ноуз-Хувер и V-rescale (там даже видно, что в заторможенной конформации этан находится дольше, чем в заслонённой). При этом, у V-rescale молекула очень сильно вращается сама по себе. Берендсен какой-то непонятный: молекула дергается почти одинаково.

Анализ энергий

In [16]:
import numpy as np
import matplotlib.pyplot as plt
In [33]:
plt.figure(figsize=(15, 10))
for i, therms in enumerate(zip(thermo_types, thermo_names)):
    thermo, name = therms
    plt.subplot(2, 3, i + 1)
    time, pot, kin = np.loadtxt(f'et_{thermo}_en.xvg').T
    plt.plot(time, kin + pot, label='total')
    plt.plot(time, pot, alpha=.7, label='potential')
    plt.plot(time, kin, alpha=.7, label='kinetic')
    plt.xlabel('Time, ps')
    plt.ylabel('Energy, kJ/mol')
    plt.title(name)
    plt.legend(title='Energies', loc='lower right')
plt.tight_layout()

Андерсен и Берендсен поддерживают полную энергию на постоянном уровне, потенциальная больше кинетической, периодические колебания. При этом энергия у Берендсена выше, чем у Андерсена. Остальные три термостата показывают большие колебания энергий (причём у Ноуз-Хувера кинетическая даже больше потенциальной, но зато часто оказывается около нуля и крайне нестабильный уровень). V-rescale и стохастический термостаты похожие по стабильности колебаний энергии, но у стохастического вклад кинетической энергии больше (потому этан в нём очень сильно двигается).

Распределение длины C-C связи

In [67]:
target = 0.1522
plt.figure(figsize=(15, 10))
for i, therms in enumerate(zip(thermo_types, thermo_names)):
    thermo, name = therms
    plt.subplot(2, 3, i + 1)
    lengths, values = np.loadtxt(f'bond_{thermo}.xvg').T
    plt.bar(lengths, values, width=0.0003, label='data')
    plt.axvline(target, color='red', label='0.1522 nm')
    plt.xlim(target - 0.02, target + 0.02)
    plt.xlabel('Bond length, nm')
    plt.title(name)
    plt.legend()
plt.tight_layout()

В поле, кажется, длина С-С связи равна 0.1522 нм. Мы видим, что пик распределения длины связи у всех термостатов где-то около этого значения. Ожидаемо, что у термостатов с меньшими колебаниями энергии (и меньшими колебаниями молекулы), меньше дисперсия распределения.

Распределение энергий

In [70]:
plt.figure(figsize=(15, 10))
for i, therms in enumerate(zip(thermo_types, thermo_names)):
    thermo, name = therms
    plt.subplot(2, 3, i + 1)
    time, pot, kin = np.loadtxt(f'et_{thermo}_en.xvg').T
    plt.hist(kin + pot, bins=100)
    plt.xlabel('Energy, kJ/mol')
    plt.title(name + ": total energy distribution")
plt.tight_layout()

У Берендсена и Ноуза-Хувера распределения напоминают экспоненциальные (как и у Больцмана). у Берендсена энергии начинаются не с 0, а с 60. Дисперсия меньше у Андерсена. В итоге, Ноуз-Хувер более реалистичен.

Обсуждение

По распределению длины C-C связи и стабильности энергии хорошим кажется Берендсен, однако Ноуз-Хувер лучше моделирует распределение Больцмана (сканирует пространство энергий). Я бы выбрал Ноуза-Хувера.