Вычисление атомных орбиталей водорода

Цель занятия: опираясь на уравнение построить электронную плотность в одно-электронном атоме и сравнить с известными программами

Работа разделена на две части: расчёт плотности в Ipython Notebook с сохранением в формате CUBE и визуализация в Pymol.

  • Запустите Jupiter Notebook или Colab .
  • В нашем notebook cначала загрузим модули scipy и numpy для эффективной работы с массивами и содержащими нужные функции
1import numpy
2import scipy.special
3import scipy.misc
1import npy2cube
  • Давайте зададим волновую функцию, попробуйте предоставить формулу в отчёте
 1def w(n,l,m,d):
 2
 3    x,y,z = numpy.mgrid[-d:d:30j,-d:d:30j,-d:d:30j]
 4
 5    r = lambda x,y,z: numpy.sqrt(x**2+y**2+z**2)
 6    theta = lambda x,y,z: numpy.arccos(z/r(x,y,z))
 7    phi = lambda x,y,z: numpy.arctan(y/x)
 8
 9    a0 = 1.
10
11    R = lambda r,n,l: (2*r/n/a0)**l * numpy.exp(-r/n/a0) * scipy.special.genlaguerre(n-l-1,2*l+1)(2*r/n/a0)
12    WF = lambda r,theta,phi,n,l,m: R(r,n,l) * scipy.special.sph_harm(m,l,phi,theta)
13    absWF = lambda r,theta,phi,n,l,m: numpy.absolute(WF(r,theta,phi,n,l,m))**2
14
15    return WF(r(x,y,z),theta(x,y,z),phi(x,y,z),n,l,m)
  • Вставьте в код комментарии про каждую внутреннюю функцию (lambda)
  • Давайте рассчитаем значения для первых трех уровней. Функция w выдает трехмерный массив из 30*30*30 элементов с неким шагом (или grid).
  • определите шаг grid при заданном диапозоне от -d до d
 1d=.....
 2step= .....
 3
 4# Зададим цикл по перебору квантовых чисел
 5
 6for n in range(0,4):
 7    for l in range(0,n):
 8        for m in range(0,l+1,1):
 9            grid= .... 
10            name='%s-%s-%s' % (n,l,m)
11            # для сохранения нужно задать координаты старта grid и шаг по каждому направлению
12            npy2cube.npy2cube(grid,(-d,....),(step,.....),name+'.cube')
  • В результате работы скрипта появятся cube файлы, попробуйте их открыть в PyMol и построить volume для них или воспользуйтесь Ipyvolume (https://github.com/maartenbreddels/ipyvolume).
  • Попробуйте изменить окраску с помощью panel в colors
  • Давайте создадим скрипт для PyMol для визуализации всех файлов
 1
 2### Откуда эти цифры? 
 3pml='''
 4### cut below here and paste into script ###
 5cmd.volume_ramp_new('ramp007', [\
 6      0.005, 0.00, 0.00, 1.00, 0.00, \
 7      0.01,  0.00, 1.00, 1.00, 0.20, \
 8      0.015, 0.00, 0.00, 1.00, 0.00, \
 9    ])
10### cut above here and paste into script ###
11'''
12
13for n in range(0,4):
14    for l in range(0,n):
15        for m in range(0,l+1,1):
16            name='%s-%s-%s' % (n,l,m)
17            # Загрузить cube файл
18            # Отобразить электронную плотность (hint: volume)
19            # Покрасить ее разумным образом 
20
21# запишите переменную в файл
22v=open(.....
  • Модифицируйте скрипт как Вам нравится для наилучшего отображения
  • Загрузите изображения в Ipython Notebook
1from IPython.display import display,Image
2display(Image=(file))
  • Рассчитаем орбитали в программе Orca. Создадим текстовый файл h.inp:
! UHF SVP XYZFile
%plots Format Cube
 MO("H-1.cube",1,0);
 MO("H-2.cube",2,0);
 MO("H-3.cube",3,0);
 MO("H-4.cube",4,0);
end
* xyz 0 4
 H 0 0 0
*

запустим Orca, это исполняемый файл /home/shad/progs/bin/orca .

1export PATH=${PATH}:/home/shad/progs/bin/
2orca h.inp
* Сравните визуально Ваши орбитали и рассчитанные программой Orca

Альтернативный способ визуализации орбиталей

  • Сохраним плотность в файл hdf5
    import h5py
    step = [cell[0]/100,cell[1]/100,cell[2]/100]
    origin = [0,0,0]
    
    with h5py.File('cube.hdf5', 'w') as f:
        oset = f.create_dataset("origin", data = origin)
        sset = f.create_dataset("step", data = step)
        dset = f.create_dataset("grid", data = e)
    
    
  • Создадим файл py, который будет запускаться из PyMol
    from chempy.brick import Brick
    from pymol import cmd
    import numpy as np
    import h5py
    
    F = h5py.File('cube.hdf5', 'r')
    
    step = F['step'][()]
    origin = F['origin'][()]
    data = F['grid'][()] 
    b = Brick.from_numpy(data, step, origin)
    
    cmd.load_brick(b, 'cone')
    volname =  'cone_volume'
    
    cmd.volume(volname, 'cone')
    
    F.close()
    

2-1-1.cube (264 KB) Andrey Golovin, 16.10.2017 21:26