Домашняя работа 4. Вычисление параметров молекулярной механики

Основная рабочая директория с файлами: H:83

Создаю входной файл для GAMESS "et.inp" и запускаю GAMESS:

In [2]:
with open('et.inp','w') as f:
    f.write(""" $CONTRL COORD=ZMT UNITS=ANGS   SCFTYP=RHF RUNTYP=OPTIMIZE $END
 $BASIS  GBASIS=N31 NGAUSS=6  $end
 $system mwords=2 $end
 $DATA
eth
C1
 C   
 C      1   cc 
 H      2   ch   1   cchv 
 H      2   ch   1   cch   3   d1 0
 H      2   ch   1   cch   3   d2 0
 H      1   ch   2   cch   3   d3 0
 H      1   ch   2   cch   5   d3 0
 H      1   chv  2   cch   4   d3 0

cc=1.52986
ch=1.08439
chv=1.08439
cch=111.200
cchv=111.200
d1=120
d2=-120
d3=180
 $END""")
In [3]:
%%bash
gms et.inp 1 >& et.log

GAMESS работает с файлом, можно благополучно заменять переменные из конца файла.

Изменение длины связи cc

In [4]:
with open("make_b.sh",'w') as f:
    f.write("""#!/bin/bash
cd bond
for i in {-10..10}; do 
     nb=$(echo "scale=5; 1.52986 + $i/50" | bc -l)
     sed "s/cc=1.52986/cc=$nb/" ../et.inp  > b_${i}.inp
done""")
In [5]:
%%bash
bash ./make_b.sh
In [6]:
with open("run_gamess.sh",'w') as f:
    f.write("""#!/bin/bash
cd bond
for i in {-10..10}; do 
     gms b_${i}.inp 1 > b_${i}.log
done""")
In [7]:
%%bash
bash ./run_gamess.sh
In [8]:
with open("parse_gamess_logs.sh",'w') as f:
    f.write("""#!/bin/bash
cd bond
echo "Index\tcc\tEnergy1\t\tEnergy2"
for i in {-10..10}; do 
     nb=$(echo "scale=5; 1.52986 + $i/50" | bc -l)
     echo -n "$i\t"
     echo -n "$nb\t"
     awk '/TOTAL ENERGY =/{printf "%s\t",$4}'  b_${i}.log
     echo ""
done""")
In [11]:
%%bash
bash ./parse_gamess_logs.sh > bond_test.txt
bash ./parse_gamess_logs.sh
Index	cc	Energy1		Energy2
-10	1.32986	-79.1646310247	-79.1975724229	
-9	1.34986	-79.1718840423	-79.1975724621	
-8	1.36986	-79.1780231827	-79.1975724055	
-7	1.38986	-79.1831501856	-79.1975723805	
-6	1.40986	-79.1873579799	-79.1975724017	
-5	1.42986	-79.1907314386	-79.1975724169	
-4	1.44986	-79.1933480684	-79.1975724285	
-3	1.46986	-79.1952786390	-79.1975722263	
-2	1.48986	-79.1965877597	-79.1975723548	
-1	1.50986	-79.1973344051	-79.1975724616	
0	1.52986	-79.1975723956	
1	1.54986	-79.1973508374	-79.1975723552	
2	1.56986	-79.1967145215	-79.1975723807	
3	1.58986	-79.1957042967	-79.1975723674	
4	1.60986	-79.1943573982	-79.1975724212	
5	1.62986	-79.1927077592	-79.1975724056	
6	1.64986	-79.1907862928	-79.1975724163	
7	1.66986	-79.1886211460	-79.1975724305	
8	1.68986	-79.1862379449	-79.1975723163	
9	1.70986	-79.1836600022	-79.1975724563	
10	1.72986	-79.1809085283	-79.1975724514	

Пробую построить и аппроксимировать полученные энергии. (Ссылки на хорошие гайды ipython notebook: по matplotlib и по fit-моделям в ipython notebook.

In [12]:
%matplotlib inline
In [13]:
import matplotlib.pyplot as plt
from pylab import *
from scipy.optimize import curve_fit
In [14]:
with open("bond_test.txt",'r') as f:
    inf = f.readlines()[1:]

full_l = [[float(y) for y in x.split()] for x in inf]
ind_l = [int(x.split()[0]) for x in inf]
cc = [float(x.split()[1]) for x in inf]
e1 = [float(x.split()[2]) for x in inf]
e2 = [float(x.split()[3]) if (len(x.split())>3) else float(x.split()[2]) for x in inf ]
In [15]:
figure()
plot(cc, e1, 'k.')
xlabel('cc')
ylabel('energy1')
show()
In [16]:
figure()
plot(cc, e2, 'k.')
xlabel('cc')
ylabel('energy2')
show()

Видимо, значение второй энергии из файла - не нужно нам, т.к. представляет собой какие-то случайные значения.

In [17]:
def fitfunc(x, a, b, k):
    return a + k*np.square(x-b)
#a+k(x-b)^2
fitpars, covmat = curve_fit(fitfunc,cc,e1)
variances = covmat.diagonal()
std_devs = np.sqrt(variances)

figure()
plot(cc, e1, 'k.')
plot(cc, fitfunc(cc,fitpars[0], fitpars[1],fitpars[2]), 'r-')
xlabel('cc')
ylabel('energy1')
show()
In [18]:
print fitpars
[-79.19804664   1.55137227   0.61699773]

Видим неточное совпадение точек и функции.

Изменение валентного угла CCH

Диапазон изменения: от 109.2 до 113.2.

In [19]:
with open("make_angle.sh",'w') as f:
    f.write("""#!/bin/bash
cd angle
for i in {0..20}; do 
     nb=$(echo "scale=5; 106.2 + $i*0.5" | bc -l)
     sed "s/cch=111.200/cch=$nb/" ../et.inp  > a_${i}.inp
done""")
    
with open("run_gamess_angle.sh",'w') as f:
    f.write("""#!/bin/bash
cd angle
for i in {0..20}; do 
     gms a_${i}.inp 1 > a_${i}.log
done""")
    
with open("parse_gamess_logs_angle.sh",'w') as f:
    f.write("""#!/bin/bash
cd angle
echo "Index\tcch\tEnergy1\t\tEnergy2"
for i in {0..20}; do 
     nb=$(echo "scale=5; 106.2 + $i*0.5" | bc -l)
     echo -n "$i\t"
     echo -n "$nb\t"
     awk '/TOTAL ENERGY =/{printf "%s\t",$4}' a_${i}.log
     echo ""
done""")
In [20]:
%%bash
bash ./make_angle.sh
bash ./run_gamess_angle.sh
bash ./parse_gamess_logs_angle.sh > angle_test.txt
bash ./parse_gamess_logs_angle.sh
Index	cch	Energy1		Energy2
0	106.2	-79.1911524759	-79.1975723594	
1	106.7	-79.1923670648	-79.1975724013	
2	107.2	-79.1934555169	-79.1975724049	
3	107.7	-79.1944174756	-79.1975724090	
4	108.2	-79.1952525501	-79.1975724091	
5	108.7	-79.1959603161	-79.1975724139	
6	109.2	-79.1965403165	-79.1975724139	
7	109.7	-79.1969920617	-79.1975724139	
8	110.2	-79.1973150304	-79.1975724147	
9	110.7	-79.1975086698	-79.1975724023	
10	111.2	-79.1975723956	
11	111.7	-79.1975055928	-79.1975724016	
12	112.2	-79.1973076147	-79.1975724145	
13	112.7	-79.1969777843	-79.1975724133	
14	113.2	-79.1965153911	-79.1975724119	
15	113.7	-79.1959196975	-79.1975723816	
16	114.2	-79.1951899302	-79.1975724022	
17	114.7	-79.1943252844	-79.1975724001	
18	115.2	-79.1933249229	-79.1975723766	
19	115.7	-79.1921879749	-79.1975723894	
20	116.2	-79.1909135349	-79.1975723830	

In [21]:
with open("angle_test.txt",'r') as f:
    inf = f.readlines()[1:]

full_l = [[float(y) for y in x.split()] for x in inf]
ind_l = [int(x.split()[0]) for x in inf]
cch = [float(x.split()[1]) for x in inf]
e1_a = [float(x.split()[2]) for x in inf]
e2_a = [float(x.split()[3]) if (len(x.split())>3) else float(x.split()[2]) for x in inf ]
In [22]:
figure()
plot(cch, e1_a, 'k.')
xlabel('cch')
ylabel('energy1')
show()
In [23]:
figure()
plot(cch, e2_a, 'k.')
xlabel('cch')
ylabel('energy2')
show()
In [25]:
def fitfunc(x, a, b, k):
    return a + k*np.square(x-b)
#a+k(x-b)^2
fitpars_a, covmat = curve_fit(fitfunc,cch,e1_a)

figure()
plot(cch, e1_a, 'k.')
plot(cch, fitfunc(cch,fitpars_a[0], fitpars_a[1],fitpars_a[2]), 'r-')
xlabel('cch')
ylabel('energy1')
show()
In [26]:
print fitpars_a
[ -7.91975740e+01   1.11168069e+02   2.61541580e-04]

Изменение торсионного угла d3

Диапазон изменения: от -180 до 180 c шагом 12.

In [27]:
with open("make_torsion.sh",'w') as f:
    f.write("""#!/bin/bash
cd torsion
for i in {-15..15}; do 
     nb=$(echo "scale=5; 0 + $i*12" | bc -l)
     sed "s/d3=180/d3=$nb/" ../et.inp  > t_${i}.inp
done""")
    
with open("run_gamess_torsion.sh",'w') as f:
    f.write("""#!/bin/bash
cd torsion
for i in {-15..15}; do 
     gms t_${i}.inp 1 > t_${i}.log
done""")
    
with open("parse_gamess_logs_torsion.sh",'w') as f:
    f.write("""#!/bin/bash
cd torsion
echo "Index\td3\tEnergy1\t\tEnergy2"
for i in {-15..15}; do 
     nb=$(echo "scale=5; 0 + $i*180/15" | bc -l)
     echo -n "$i\t"
     echo -n "$nb\t"
     awk '/TOTAL ENERGY =/{printf "%s\t",$4}' t_${i}.log
     echo ""
done""")
In [28]:
%%bash
bash ./make_torsion.sh
bash ./run_gamess_torsion.sh
bash ./parse_gamess_logs_torsion.sh > torsion_test.txt
bash ./parse_gamess_logs_torsion.sh
Index	d3	Energy1		Energy2
-15	-180.00000	-79.1975723956	
-14	-168.00000	-79.1971377019	-79.1975723425	
-13	-156.00000	-79.1959965141	-79.1975723548	
-12	-144.00000	-79.1945797143	-79.1975724012	
-11	-132.00000	-79.1934285581	-79.1975724125	
-10	-120.00000	-79.1929877077	-79.1931774557	
-9	-108.00000	-79.1934285581	-79.1975724121	
-8	-96.00000	-79.1945797143	-79.1975724012	
-7	-84.00000	-79.1959965141	-79.1975723548	
-6	-72.00000	-79.1971377019	-79.1975723425	
-5	-60.00000	-79.1975723956	
-4	-48.00000	-79.1971377019	-79.1975723425	
-3	-36.00000	-79.1959965141	-79.1975723548	
-2	-24.00000	-79.1945797143	-79.1975724012	
-1	-12.00000	-79.1934285581	-79.1975724119	
0	0	-79.1929877077	-79.1931774557	
1	12.00000	-79.1934285581	-79.1975724119	
2	24.00000	-79.1945797143	-79.1975724012	
3	36.00000	-79.1959965141	-79.1975723548	
4	48.00000	-79.1971377019	-79.1975723425	
5	60.00000	-79.1975723956	
6	72.00000	-79.1971377019	-79.1975723425	
7	84.00000	-79.1959965141	-79.1975723548	
8	96.00000	-79.1945797143	-79.1975724012	
9	108.00000	-79.1934285581	-79.1975724121	
10	120.00000	-79.1929877077	-79.1931774557	
11	132.00000	-79.1934285581	-79.1975724133	
12	144.00000	-79.1945797143	-79.1975724012	
13	156.00000	-79.1959965141	-79.1975723548	
14	168.00000	-79.1971377019	-79.1975723425	
15	180.00000	-79.1975723956	

In [29]:
with open("torsion_test.txt",'r') as f:
    inf = f.readlines()[1:]

full_l = [[float(y) for y in x.split()] for x in inf]
ind_l = [int(x.split()[0]) for x in inf]
d3 = [float(x.split()[1]) for x in inf]
e1_t = [float(x.split()[2]) for x in inf]
e2_t = [float(x.split()[3]) if (len(x.split())>3) else float(x.split()[2]) for x in inf ]
In [30]:
figure()
plot(d3, e1_t, 'k.')
xlabel('d3')
ylabel('energy1')
show()
In [31]:
figure()
plot(d3, e2_t, 'k.')
xlabel('d3')
ylabel('energy2')
show()

Вижу 4 минимума и 3 максимума функции энергии в зависимости от торсионного угла. energy2 из файла я не рассматриваю.

energy1 представляет собой колебательную функцию, как и можно ожидать для изменения торсионного угла. Максимумы энергии - заслоненные конформации, минимумы - заторможенные.

Увеличение шага длины связи

Итак, пробую увеличить шаг до 0.1 (было 0.02):

In [32]:
with open("make_b1.sh",'w') as f:
    f.write("""#!/bin/bash
cd bond1
for i in {-10..10}; do 
     nb=$(echo "scale=5; 1.52986 + $i*0.1" | bc -l)
     sed "s/cc=1.52986/cc=$nb/" ../et.inp  > b1_${i}.inp
done""")
    
with open("run_gamess_bond1.sh",'w') as f:
    f.write("""#!/bin/bash
cd bond1
for i in {-10..10}; do 
     gms b1_${i}.inp 1 > b1_${i}.log
done""")
    
with open("parse_gamess_logs_bond1.sh",'w') as f:
    f.write("""#!/bin/bash
cd bond1
echo "Index\tcch\tEnergy1\t\tEnergy2"
for i in {-10..10}; do 
     nb=$(echo "scale=5; 1.52986 + $i*0.1" | bc -l)
     echo -n "$i\t"
     echo -n "$nb\t"
     awk '/TOTAL ENERGY =/{printf "%s\t",$4}' b1_${i}.log
     echo ""
done""")
In [33]:
%%bash
bash ./make_b1.sh
bash ./run_gamess_bond1.sh
bash ./parse_gamess_logs_bond1.sh > bond1_test.txt
bash ./parse_gamess_logs_bond1.sh
Index	cch	Energy1		Energy2
-10	.52986	-73.5474476087	
-9	.62986	-75.7731881541	-79.1975724060	
-8	.72986	-77.1455632242	-79.1975723965	
-7	.82986	-77.9863163175	-79.1975723749	
-6	.92986	-78.5009742210	-79.1975723424	
-5	1.02986	-78.8137246711	-79.1975723508	
-4	1.12986	-79.0002302204	-79.1975724112	
-3	1.22986	-79.1073690846	-79.1975723877	
-2	1.32986	-79.1646310247	-79.1975724229	
-1	1.42986	-79.1907314386	-79.1975724169	
0	1.52986	-79.1975723956	
1	1.62986	-79.1927077592	-79.1975724056	
2	1.72986	-79.1809085283	-79.1975724514	
3	1.82986	-79.1651649017	-79.1975723153	
4	1.92986	-79.1473362757	-79.1975724314	
5	2.02986	-79.1285769046	-79.1975724137	
6	2.12986	-79.1096103579	-79.1975724154	
7	2.22986	-79.0908991339	-79.1975724154	
8	2.32986	-79.0727437909	-79.1975723840	
9	2.42986	-79.0553382833	-79.1975724148	
10	2.52986	-79.0388006063	-79.1975724153	

In [34]:
with open("bond1_test.txt",'r') as f:
    inf = f.readlines()[1:]

full_l = [[float(y) for y in x.split()] for x in inf]
ind_l = [int(x.split()[0]) for x in inf]
cc1 = [float(x.split()[1]) for x in inf]
e1_b1 = [float(x.split()[2]) for x in inf]
e2_b1 = [float(x.split()[3]) if (len(x.split())>3) else float(x.split()[2]) for x in inf ]
In [35]:
figure()
plot(cc1, e1_b1, 'k.')
xlabel('cc')
ylabel('energy1')
show()
In [36]:
figure()
plot(cc1[1:], e2_b1[1:], 'k.')
xlabel('cc')
ylabel('energy2')
show()

Из графика energy1 видно, что вид зависимости похож на гиперболу (по крайней мере в первом приближении).

In [1]:
%%bash 
# Просто часто используемая функция
rm /home/students/y11/agalicina/gamess-scratch/*