import numpy
import scipy.special
import scipy.misc
from IPython.display import Image
import npy2cube
def npy2cube(grid, start, step, cube_f):
'''
PARAMETERS:
grid : numpy array
3-dimentional array, containing grid data
start : tuple
format: (x, y, z), coordinates of cube start point
step: tuple
format: (x, y, z), step size on 3 axes
cube_f: string
name of output .cube file
RETURNS:
void
'''
cube_string = ""
bohr_to_angs = 0.529177210859 #const
start = list(map(lambda x: x/bohr_to_angs, start))
step = list(map(lambda x: x/bohr_to_angs, step))
with open(cube_f, "w") as cube_file:
###HEADER###
cube_file.write(" CPMD CUBE FILE.\nOUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n")
cube_file.write(" 1 %f %f %f\n" %(start[0], start[1], start[2]))
cube_file.write(" %i %f 0.000000 0.000000\n" %(grid.shape[0], step[0]))
cube_file.write(" %i 0.000000 %f 0.000000\n" %(grid.shape[1], step[1]))
cube_file.write(" %i 0.000000 0.000000 %f\n" %(grid.shape[2], step[2]))
cube_file.write(" 1 0.000000 %f %f %f\n" %(start[0], start[1], start[2]))
###DATA###
i = 0
for x in range(grid.shape[0]):
for y in range(grid.shape[1]):
for z in range(grid.shape[2]):
if i < 5:
cube_file.write("%f " %(float(grid[x, y, z])))
i += 1
elif i == 5:
cube_file.write("%f\n" %(float(grid[x, y, z])))
i = 0
return 0
def w(n,l,m,d):
x,y,z = numpy.mgrid[-d:d:30j,-d:d:30j,-d:d:30j]
# переводим координаты из декартовой системы координат в сферическую
r = lambda x,y,z: numpy.sqrt(x**2+y**2+z**2) # длина вектора из (x, y, z) = радиальное расстояние
theta = lambda x,y,z: numpy.arccos(z/r(x,y,z)) # зенитный угол
phi = lambda x,y,z: numpy.arctan(y/x) # азимутальный угол
a0 = 1.
# радиальная часть волновой функции
# scipy.special.genlaguerre - обобщённый полином Лагерра степени n-l-1 ; ρ = 2*r/n/a0
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)
# wave function
WF = lambda r,theta,phi,n,l,m: R(r,n,l) * scipy.special.sph_harm(m,l,phi,theta)
# плотность вероятности волновой функции
absWF = lambda r,theta,phi,n,l,m: numpy.absolute(WF(r,theta,phi,n,l,m))**2
### может тут чего то не хватает?
###return WF(r(x,y,z),theta(x,y,z),phi(x,y,z),n,l,m)
out = WF(r(x,y,z),theta(x,y,z),phi(x,y,z),n,l,m)
return numpy.real(out) + numpy.imag(out)
# цикл по перебору квантовых чисел
for n in range(0,4):
d = 10 * n
step = d / 15
for l in range(0,n):
for m in range(0,l+1,1):
grid= w(n,l,m,d) # трехмерный массив из 30*30*30 элементов
name='%s-%s-%s' % (n,l,m)
# для сохранения нужно задать координаты старта grid и шаг по каждому направлению
npy2cube(grid,(-d, -d, -d),(step,step,step),name+'.cube')
Скрипт для pymol для визуализации .cube файлов
v = open ('v.pml', 'w')
v.write('cmd.volume_ramp_new(\'ramp007\', [\
-0.015, 1.00, 0.00, 0.00, 0.00, \
-0.01, 1.00, 1.00, 0.00, 0.20, \
-0.005, 0.00, 0.00, 1.00, 0.00, \
0.005, 0.00, 0.00, 1.00, 0.00, \
0.01, 0.00, 1.00, 1.00, 0.20, \
0.015, 0.00, 0.00, 1.00, 0.00, \
])\n')
for n in range(0,4):
for l in range(0,n):
for m in range(0,l+1,1):
name='%s-%s-%s' % (n,l,m)
lname = name+'.cube'
volname = name+'_vol'
v.write('load %s, %s\n' % (lname, name))
v.write('volume %s, %s\n' % (volname, name))
v.write('volume_color %s, ramp007\n' % (volname))
v.close()
from multiprocessing import Process
def launch_pymol():
!pymol -R &> /dev/null
Process(target=launch_pymol).start()
import xmlrpc.client as xmlrpclib
cmd = xmlrpclib.ServerProxy('http://localhost:9123')
cmd.reinitialize()
cmd.load("v.pml")
Image('4_0.png', width = 700)
Рассчитаем орбитали в ORCA. Создадим файл h.inp, запустим ORCA на kodomo.
orca = open ('orca.pml', 'w')
orca.write('cmd.volume_ramp_new(\'ramp007\', [\
-0.015, 1.00, 0.00, 0.00, 0.00, \
-0.01, 1.00, 1.00, 0.00, 0.20, \
-0.005, 0.00, 0.00, 1.00, 0.00, \
0.005, 0.00, 0.00, 1.00, 0.00, \
0.01, 0.00, 1.00, 1.00, 0.20, \
0.015, 0.00, 0.00, 1.00, 0.00, \
])\n')
for n in range(1,5):
name='H-%s' % n
volname = name+'_vol'
orca.write('load %s, %s\n' % (name+'.cube', name))
orca.write('volume %s, %s\n' % ( volname, name))
orca.write('volume_color %s, ramp007\n' % ( volname))
orca.close()
cmd.reinitialize()
cmd.load("orca.pml")
Image('4_1.png', width = 700)
Результаты выдачи ORCA схожи с полученными выше. Форма орбителей одинакова, однако соотношение их размеров в ORCA другое. По форме орбители H1 затруднительно определить ее тип, но если посмотреть на срез, то становится понятным, что это 2-0-0 (2s). H1, H3, H4 соответствуют 2p орбиталям.