def Fdual(j_data_opt, j_data_spplus, j_data_spminus, grid_par=-6): qc_opt = read.convert_json(j_data_opt) qc_spplus = read.convert_json(j_data_spplus) qc_spminus = read.convert_json(j_data_spminus) X, Y, Z = _init_ORB_grid(qc_opt, grid_par=grid_par) dx, dy, dz = (X[10, 0, 0] - X[9, 0, 0]), (Y[0, 10, 0] - Y[0, 9, 0]), (Z[0, 0, 10] - Z[0, 0, 9]) d3r = dx * dy * dz rho_opt = core.rho_compute(qc_opt, numproc=6) rho_spplus = core.rho_compute(qc_spplus, numproc=6) rho_spminus = core.rho_compute(qc_spminus, numproc=6) delta_rho_plus = np.subtract(rho_spplus, rho_opt) delta_rho_minus = np.subtract(rho_opt, rho_spminus) delta_rho_2 = np.subtract(delta_rho_plus, delta_rho_minus) print "Rho : ", np.sum(rho_opt) * d3r, "(", np.min( rho_opt), " ... ", np.max(rho_opt), ")" print "d : ", dx, dy, dz print "P0 : ", X[0, 0, 0], Y[0, 0, 0], Z[0, 0, 0] print "P1 : ", X[-1, 0, 0], Y[0, -1, 0], Z[0, 0, -1] P = np.array([X, Y, Z]) return delta_rho_2, X, Y, Z
def Fukui(j_data_opt, j_data_sp, label=None, grid_par=-6): u"""Calculates the density differences/Fukui functions of the molecule. ** Parameters ** j_data_opt : dict Data on the optimized molecule, as deserialized from the scanlog format. j_data_sp : dict Data on the optimized molecule, as deserialized from the scanlog format. grid_par : int, optional Governs the grid to be used for voxel data. - If positive, it indicates the number of points in all 3 dimensions. - If zero, it indicates the default number of points (80). - If negative, it indicates the resolution, in Á^-1. ** Returns ** rho : numpy.ndarray The voxels containing the scalar values of the density. V : numpy.ndarray The voxels containing the scalar values of the potential. X, Y, Z : numpy.ndarray Meshgrids (as generated by numpy.mgrid), required for placing the voxels contained in rho and V. """ qc_opt = json2orbkit.convert_json(j_data_opt) qc_sp = json2orbkit.convert_json(j_data_sp) ## Get all MOs involved in transitions # MO_list = [STT[0] for T in transitions for ST in T for STT in ST[:2]] # Get all unique MO involved # MO_set = set(MO_list) ## The dictionary is needed because the MO numbers do not correspond ## to their indices in the output of rho_compute, and we can only access ## them through indices (assuming ORBKIT conserves the order of the MO ## numbers in qc.mo_spec) # tab = dict([(MO, i) for i, MO in enumerate(MO_set)]) X, Y, Z = _init_ORB_grid(qc_opt, grid_par=grid_par) dx, dy, dz = (X[10, 0, 0] - X[9, 0, 0]), (Y[0, 10, 0] - Y[0, 9, 0]), (Z[0, 0, 10] - Z[0, 0, 9]) d3r = dx * dy * dz rho_opt = core.rho_compute(qc_opt, numproc=4) rho_sp = core.rho_compute(qc_sp, numproc=4) ## Calculation of the delta rho if j_data_sp["molecule"]["charge"] < 0: delta_rho = np.subtract(rho_sp, rho_opt) elif j_data_sp["molecule"]["charge"] > 0: delta_rho = np.subtract(rho_opt, rho_sp) print("Rho : ", np.sum(rho_opt) * d3r, "(", np.min(rho_opt), " ... ", np.max(rho_opt), ")") print("d : ", dx, dy, dz) print("P0 : ", X[0, 0, 0], Y[0, 0, 0], Z[0, 0, 0]) print("P1 : ", X[-1, 0, 0], Y[0, -1, 0], Z[0, 0, -1]) P = np.array([X, Y, Z]) return delta_rho, X, Y, Z
def Fukui(j_data_opt, j_data_sp, label=None, grid_par=-6): u"""Calculates the density differences/Fukui functions of the molecule. ** Parameters ** j_data_opt : dict Data on the optimized molecule, as deserialized from the scanlog format. j_data_sp : dict Data on the optimized molecule, as deserialized from the scanlog format. grid_par : int, optional Governs the grid to be used for voxel data. - If positive, it indicates the number of points in all 3 dimensions. - If zero, it indicates the default number of points (80). - If negative, it indicates the resolution, in Á^-1. ** Returns ** rho : numpy.ndarray The voxels containing the scalar values of the density. V : numpy.ndarray The voxels containing the scalar values of the potential. X, Y, Z : numpy.ndarray Meshgrids (as generated by numpy.mgrid), required for placing the voxels contained in rho and V. """ qc_opt = read.convert_json(j_data_opt) qc_sp = read.convert_json(j_data_sp) X, Y, Z = _init_ORB_grid(qc_opt, grid_par=grid_par) dx, dy, dz = (X[10, 0, 0] - X[9, 0, 0]), (Y[0, 10, 0] - Y[0, 9, 0]), (Z[0, 0, 10] - Z[0, 0, 9]) d3r = dx * dy * dz rho_opt = core.rho_compute(qc_opt, numproc=6) rho_sp = core.rho_compute(qc_sp, numproc=6) ## Calculation of the delta rho if label == 'plus': delta_rho = np.subtract(rho_sp, rho_opt) elif label == 'minus': delta_rho = np.subtract(rho_opt, rho_sp) print "Rho : ", np.sum(rho_opt) * d3r, "(", np.min( rho_opt), " ... ", np.max(rho_opt), ")" print "d : ", dx, dy, dz print "P0 : ", X[0, 0, 0], Y[0, 0, 0], Z[0, 0, 0] print "P1 : ", X[-1, 0, 0], Y[0, -1, 0], Z[0, 0, -1] P = np.array([X, Y, Z]) return delta_rho, X, Y, Z
def calc_ao(qc, drv=None, otype=None, ofid=None, numproc=None, slice_length=None): '''Computes and saves all atomic orbital or a derivative thereof. **Parameters:** qc.geo_spec, qc.geo_info, qc.ao_spec, qc.mo_spec : See :ref:`Central Variables` for details. drv : string or list of strings {None,'x','y', 'z', 'xx', 'xy', ...}, optional If not None, a derivative calculation of the atomic orbitals is requested. otype : str or list of str, optional Specifies output file type. See :data:`otypes` for details. ofid : str, optional Specifies output file name. If None, the filename will be based on :mod:`orbkit.options.outputname`. numproc : int, optional Specifies number of subprocesses for multiprocessing. If None, uses the value from :mod:`options.numproc`. slice_length : int, optional Specifies the number of points per subprocess. If None, uses the value from :mod:`options.slice_length`. **Returns:** ao_list : numpy.ndarray, shape=((NAO,) + N) Contains the computed NAO atomic orbitals on a grid. ''' slice_length = options.slice_length if slice_length is None else slice_length numproc = options.numproc if numproc is None else numproc datalabels = qc.ao_spec.get_labels() ao_list = core.rho_compute(qc, calc_ao=True, drv=drv, slice_length=options.slice_length, numproc=options.numproc) if otype is None: return ao_list if ofid is None: ofid = '%s_AO' % (options.outputname) if not options.no_output: output_written = main_output(ao_list, qc, outputname=ofid, datalabels=qc.ao_spec.get_labels(), otype=otype, drv=drv) return ao_list
def compute_MOs(self, qc, numproc=4): self.orbkit_grid(qc) molist = core.rho_compute(qc, calc_mo=True, slice_length=self.slice_length, drv=None, numproc=numproc) return molist
def MO(j_data, MO_list, grid_par=-6): u"""Calculates the voxels representing the requested molecular orbitals of a molecule. ** Parameters ** j_data : dict Data on the molecule, deserialized from the scanlog format. MO_list : list(str) or list(int) A list containing either: - integers designating the molecular orbitals (starting from 1) - strings designating the molecular orbitals either through: - keywords (e.g. "h**o", "lumo") - ranges (e.g. "h**o-1:lumo+2") - symmetries (e.g. "5.A") grid_par : int, optional Governs the grid to be used for the voxels. - If positive, it indicates the number of points in all 3 dimensions. - If zero, it indicates the default number of points (80). - If negative, it indicates the resolution, in (A.U.)^-1. ** Returns ** out : list(numpy.ndarray) List of numpy.ndarrays, each one containing the values of the probability amplitude of a single molecular orbital at each voxel of the grid. X, Y, Z : numpy.ndarray Meshgrids (as generated by numpy.mgrid) required for positioning the voxel values contained in out. """ ## Prepare data for ORBKIT qc = read.convert_json(j_data, all_mo=True) X, Y, Z = _init_ORB_grid(qc, grid_par=grid_par) ## Get list of orbitals qc.mo_spec = read.mo_select(qc.mo_spec, MO_list)["mo_spec"] ## Calculate out = core.rho_compute(qc, calc_mo=True, numproc=6) return out, X, Y, Z
def mo_set(qc, fid_mo_list, drv=None, laplacian=None, otype=None, ofid=None, return_all=True, numproc=None, slice_length=None): '''Calculates and saves the density or the derivative thereof using selected molecular orbitals. **Parameters:** qc.geo_spec, qc.geo_info, qc.ao_spec, qc.mo_spec : See :ref:`Central Variables` for details. fid_mo_list : str Specifies the filename of the molecular orbitals list or list of molecular orbital labels (cf. :mod:`orbkit.orbitals.MOClass.select` for details). otype : str or list of str, optional Specifies output file type. See :data:`otypes` for details. ofid : str, optional Specifies output file name. If None, the filename will be based on :mod:`orbkit.options.outputname`. drv : string or list of strings {None,'x','y', 'z', 'xx', 'xy', ...}, optional If not None, a derivative calculation is requested. return_all : bool If False, no data will be returned. numproc : int, optional Specifies number of subprocesses for multiprocessing. If None, uses the value from :mod:`options.numproc`. slice_length : int, optional Specifies the number of points per subprocess. If None, uses the value from :mod:`options.slice_length`. **Returns:** datasets : numpy.ndarray, shape=((NSET,) + N) Contains the NSET molecular orbital sets on a grid. delta_datasets : numpy.ndarray, shape=((NSET,NDRV) + N) Contains the NDRV NSET molecular orbital set on a grid. This is only present if derivatives are requested. ''' #Can be an mo_spec or a list of mo_spec # For later iteration we'll make it into a list here if it is not mo_info_list = qc.mo_spec.select(fid_mo_list, flatten_input=False) drv = options.drv if drv is None else drv laplacian = options.laplacian if laplacian is None else laplacian slice_length = options.slice_length if slice_length is None else slice_length numproc = options.numproc if numproc is None else numproc if ofid is None: ofid = options.outputname datasets = [] datalabels = [] delta_datasets = [] delta_datalabels = [] cube_files = [] for i_file, mo_info in enumerate(mo_info_list): qc_select = qc.copy() qc_select.mo_spec = mo_info label = 'mo_set:' + mo_info.selection_string display('\nStarting with the molecular orbital list \n\t' + label + '\n\t(Only regarding existing and occupied mos.)\n') data = core.rho_compute(qc_select, drv=drv, laplacian=laplacian, slice_length=slice_length, numproc=numproc) if drv is None: rho = data delta_datasets = numpy.zeros((0, ) + rho.shape) elif laplacian: rho, delta_rho, laplacian_rho = data delta_datasets.extend(delta_rho) delta_datasets.append(laplacian_rho) delta_datalabels.extend( ['d^2/d%s^2 %s' % (i, label) for i in 'xyz']) delta_datalabels.append('laplacian_of_' + label) else: rho, delta_rho = data delta_datasets.extend(delta_rho) delta_datalabels.extend(['d/d%s %s' % (i, label) for i in drv]) datasets.append(rho) datalabels.append(label) datasets = numpy.array(datasets) delta_datasets = numpy.array(delta_datasets) delta_datalabels.append('mo_set') data = numpy.append(datasets, delta_datasets, axis=0) if not options.no_output: output_written = main_output(data, qc, outputname=ofid, datalabels=datalabels + delta_datalabels, otype=otype, drv=None) return data
options.quiet = True tests_home = os.path.dirname(inspect.getfile(inspect.currentframe())) folder = os.path.join(tests_home, '../outputs_for_testing/molpro') filepath = os.path.join(folder, 'h2o_rhf_sph.molden') qc = read.main_read(filepath, all_mo=True) grid.adjust_to_geo(qc, extend=2.0, step=1) grid.grid_init(is_vector=False, force=True) drv = [None, 'x', 'y', 'z', 'xx', 'xy', 'xz', 'yy', 'yz', 'zz'] data = [] for i in range(2): if i: grid.grid2vector() data.append([ rho_compute(qc, slice_length=0), rho_compute(qc, numproc=options.numproc), rho_compute(qc, laplacian=True, slice_length=0)[-1], rho_compute(qc, laplacian=True, numproc=options.numproc)[-1], rho_compute(qc, calc_mo=True, drv=drv, slice_length=0), rho_compute(qc, calc_mo=True, drv=drv, numproc=options.numproc) ]) data[1] = [grid.mv2g(d=i) for i in data[1]] for i in range(len(data[0])): equal(data[0][i], data[1][i]) filepath = os.path.join(tests_home, 'refdata_rho_compute.npz') #numpy.savez(filepath, data=data[0]) refdata = numpy.load(filepath)
print('=' * 80) print('Preparing All Subsequent Calculations') print('=' * 80 + '\n') # 1b. print('Setting up the grid...') grid.min_ = [-3.9, 0.0, -5.9] grid.max_ = [3.9, 0.0, 9.9] grid.delta_ = [0.2, 0.0, 0.2] grid.grid_init() print(grid.get_grid()) print('Computing the Molecular Orbitals and the Derivatives Thereof...\n') molist = core.rho_compute(qc, calc_mo=True, slice_length=slice_length, drv=[None, 'x', 'y', 'z', 'xx', 'yy', 'zz'], numproc=numproc) molistdrv = molist[1:4] # \nabla of MOs molistdrv2 = molist[-3:] # \nabla^2 of MOs molist = molist[0] # MOs print('\nComputing the Analytical Overlaps of the Molecular Orbitals...\n') aoom = get_ao_overlap(qc.geo_spec, qc.geo_spec, qc.ao_spec, ao_spherical=qc.ao_spherical, drv=[None, 'x', 'y', 'z']) dm_aoom = get_ao_dipole_matrix(qc, component=['x', 'y', 'z']) moom = get_mo_overlap_matrix(qc.mo_spec, qc.mo_spec, aoom[0],
def calc_mo(qc, fid_mo_list, drv=None, otype=None, ofid=None, numproc=None, slice_length=None): '''Calculates and saves the selected molecular orbitals or the derivatives thereof. **Parameters:** qc.geo_spec, qc.geo_info, qc.ao_spec, qc.mo_spec : See :ref:`Central Variables` for details. fid_mo_list : str Specifies the filename of the molecular orbitals list or list of molecular orbital labels (cf. :mod:`orbkit.read.mo_select` for details). If fid_mo_list is 'all_mo', creates a list containing all molecular orbitals. drv : int or string, {None, 'x', 'y', 'z', 0, 1, 2}, optional If not None, a derivative calculation of the atomic orbitals is requested. otype : str or list of str, optional Specifies output file type. See :data:`otypes` for details. ofid : str, optional Specifies output file name. If None, the filename will be based on :mod:`orbkit.options.outputname`. numproc : int, optional Specifies number of subprocesses for multiprocessing. If None, uses the value from :mod:`options.numproc`. slice_length : int, optional Specifies the number of points per subprocess. If None, uses the value from :mod:`options.slice_length`. **Returns:** mo_list : numpy.ndarray, shape=((NMO,) + N) Contains the NMO=len(qc.mo_spec) molecular orbitals on a grid. mo_info : dict Contains information of the selected molecular orbitals and has following Members: :mo: - List of molecular orbital labels. :mo_ii: - List of molecular orbital indices. :mo_spec: - Selected elements of mo_spec. See :ref:`Central Variables` for details. :mo_in_file: - List of molecular orbital labels within the fid_mo_list file. :sym_select: - If True, symmetry labels have been used. ''' mo_info = mo_select(qc.mo_spec, fid_mo_list, strict=True) qc_select = qc.todict() qc_select['mo_spec'] = mo_info['mo_spec'] slice_length = options.slice_length if slice_length is None else slice_length numproc = options.numproc if numproc is None else numproc # Calculate the AOs and MOs mo_list = core.rho_compute(qc_select, calc_mo=True, drv=drv, slice_length=slice_length, numproc=numproc) if otype is None: return mo_list, mo_info if ofid is None: ofid = '%s_MO' % (options.outputname) if not options.no_output: if 'h5' in otype: output.main_output(mo_list,qc.geo_info,qc.geo_spec,data_id='MO', outputname=ofid, mo_spec=qc_select['mo_spec'],drv=drv,is_mo_output=True) # Create Output cube_files = [] for i,j in enumerate(qc_select['mo_spec']): outputname = '%s_%s' % (ofid,mo_info['mo'][i]) comments = ('%s,Occ=%.1f,E=%+.4f' % (mo_info['mo'][i], j['occ_num'], j['energy'])) index = numpy.index_exp[:,i] if drv is not None else i output_written = output.main_output(mo_list[index], qc.geo_info,qc.geo_spec, outputname=outputname, comments=comments, otype=otype,omit=['h5','vmd','mayavi'], drv=drv) for i in output_written: if i.endswith('.cb'): cube_files.append(i) if 'vmd' in otype and cube_files != []: display('\nCreating VMD network file...' + '\n\t%(o)s.vmd' % {'o': ofid}) output.vmd_network_creator(ofid,cube_files=cube_files) if 'mayavi' in otype: datalabels = ['MO %(sym)s, Occ=%(occ_num).2f, E=%(energy)+.4f E_h' % i for i in qc_select['mo_spec']] if drv is not None: tmp = [] for i in drv: for j in datalabels: tmp.append('d/d%s of %s' % (i,j)) datalabels = tmp data = mo_list.reshape((-1,) + grid.get_shape()) output.main_output(data,qc.geo_info,qc.geo_spec, otype='mayavi',datalabels=datalabels) return mo_list, mo_info
def mo_set(qc, fid_mo_list, drv=None, laplacian=None, otype=None, ofid=None, return_all=True, numproc=None, slice_length=None): '''Calculates and saves the density or the derivative thereof using selected molecular orbitals. **Parameters:** qc.geo_spec, qc.geo_info, qc.ao_spec, qc.mo_spec : See :ref:`Central Variables` for details. fid_mo_list : str Specifies the filename of the molecular orbitals list or list of molecular orbital labels (cf. :mod:`orbkit.read.mo_select` for details). otype : str or list of str, optional Specifies output file type. See :data:`otypes` for details. ofid : str, optional Specifies output file name. If None, the filename will be based on :mod:`orbkit.options.outputname`. drv : int or string, {None, 'x', 'y', 'z', 0, 1, 2}, optional If not None, a derivative calculation of the atomic orbitals is requested. return_all : bool If False, no data will be returned. numproc : int, optional Specifies number of subprocesses for multiprocessing. If None, uses the value from :mod:`options.numproc`. slice_length : int, optional Specifies the number of points per subprocess. If None, uses the value from :mod:`options.slice_length`. **Returns:** datasets : numpy.ndarray, shape=((NSET,) + N) Contains the NSET molecular orbital sets on a grid. delta_datasets : numpy.ndarray, shape=((NSET,NDRV) + N) Contains the NDRV NSET molecular orbital set on a grid. This is only present if derivatives are requested. mo_info : dict Contains information of the selected molecular orbitals and has following Members: :mo: - List of molecular orbital labels. :mo_ii: - List of molecular orbital indices. :mo_spec: - Selected elements of mo_spec. See :ref:`Central Variables` for details. :mo_in_file: - List of molecular orbital labels within the fid_mo_list file. :sym_select: - If True, symmetry labels have been used. ''' mo_info = mo_select(qc.mo_spec, fid_mo_list, strict=False) qc_select = qc.todict() drv = options.drv if drv is None else drv laplacian = options.laplacian if laplacian is None else laplacian slice_length = options.slice_length if slice_length is None else slice_length numproc = options.numproc if numproc is None else numproc if ofid is None: ofid = options.outputname if 'h5' in otype and os.path.exists('%s.h5' % ofid): raise IOError('%s.h5 already exists!' % ofid) datasets = [] delta_datasets = [] cube_files = [] for i_file,j_file in enumerate(mo_info['mo_in_file']): display('Starting with the %d. element of the molecular orbital list (%s)...\n\t' % (i_file+1,fid_mo_list) + str(j_file) + '\n\t(Only regarding existing and occupied mos.)\n') qc_select['mo_spec'] = [] for i_mo,j_mo in enumerate(mo_info['mo']): if j_mo in j_file: if mo_info['sym_select']: ii_mo = numpy.argwhere(mo_info['mo_ii'] == j_mo) else: ii_mo = i_mo qc_select['mo_spec'].append(mo_info['mo_spec'][int(ii_mo)]) data = core.rho_compute(qc_select, drv=drv, laplacian=laplacian, slice_length=slice_length, numproc=numproc) datasets.append(data) if drv is None: rho = data elif laplacian: rho, delta_rho, laplacian_rho = data delta_datasets.extend(delta_rho) delta_datasets.append(laplacian_rho) else: rho, delta_rho = data delta_datasets.append(delta_rho) if options.z_reduced_density: if grid.is_vector: display('\nSo far, reducing the density is not supported for vector grids.\n') elif drv is not None: display('\nSo far, reducing the density is not supported for the derivative of the density.\n') else: rho = integrate.simps(rho, grid.x, dx=grid.delta_[0], axis=0, even='avg') rho = integrate.simps(rho, grid.y, dx=grid.delta_[1], axis=0, even='avg') if not options.no_output: if 'h5' in otype: display('Saving to Hierarchical Data Format file (HDF5)...') group = '/mo_set:%03d' % (i_file+1) display('\n\t%s.h5 in the group "%s"' % (ofid,group)) output.HDF5_creator(rho,ofid,qc.geo_info,qc.geo_spec,data_id='rho', mode='w',group=group,mo_spec=qc_select['mo_spec']) if drv is not None: for i,j in enumerate(drv): data_id = 'rho_d%s' % j output.HDF5_creator(delta_rho[i],ofid,qc.geo_info,qc.geo_spec, data_id=data_id,data_only=True,mode='a', group=group,mo_spec=qc_select['mo_spec']) if laplacian: data_id = 'rho_laplacian' output.HDF5_creator(laplacian_rho,ofid,qc.geo_info,qc.geo_spec, data_id=data_id,data_only=True,mode='a', group=group,mo_spec=qc_select['mo_spec']) fid = '%s_%03d' % (ofid, i_file+1) cube_files.append('%s.cb' % fid) comments = ('mo_set:'+','.join(j_file)) output.main_output(rho,qc.geo_info,qc.geo_spec,outputname=fid, otype=otype,omit=['h5','vmd','mayavi'], comments=comments) if drv is not None: for i,j in enumerate(drv): fid = '%s_%03d_d%s' % (ofid, i_file+1, j) cube_files.append('%s.cb' % fid) comments = ('d%s_of_mo_set:' % j + ','.join(j_file)) output.main_output(delta_rho[i],qc.geo_info,qc.geo_spec,outputname=fid, otype=otype,omit=['h5','vmd','mayavi'], comments=comments) if laplacian: fid = '%s_%03d_laplacian' % (ofid, i_file+1) cube_files.append('%s.cb' % fid) comments = ('laplacian_of_mo_set:' + ','.join(j_file)) output.main_output(laplacian_rho,qc.geo_info,qc.geo_spec,outputname=fid, otype=otype,omit=['h5','vmd','mayavi'], comments=comments) if 'vmd' in otype and cube_files != []: display('\nCreating VMD network file...' + '\n\t%(o)s.vmd' % {'o': ofid}) output.vmd_network_creator(ofid,cube_files=cube_files) datasets = numpy.array(datasets) if drv is None: if 'mayavi' in otype: output.main_output(datasets,qc.geo_info,qc.geo_spec, otype='mayavi',datalabels=mo_info['mo_in_file']) return datasets, mo_info else: delta_datasets = numpy.array(delta_datasets) if 'mayavi' in otype: datalabels = [] for i in mo_info['mo_in_file']: datalabels.extend(['d/d%s of %s' % (j,i) for j in drv]) if laplacian: datalabels.append('laplacian of %s' % i) output.main_output(delta_datasets.reshape((-1,) + grid.get_shape()), qc.geo_info,qc.geo_spec,otype='mayavi',datalabels=datalabels) return datasets, delta_datasets, mo_info
Identify the non-covalent interaction regions using the reduced density gradient ''' # open molden file and read parameters qc = read.main_read('h2o_dimer.molden',itype='molden') # Adjust the grid parameters to the molecular structure grid.adjust_to_geo(qc,extend=1.0,step=0.1) # initialize grid grid.grid_init() # print grid information display.display(grid.get_grid()) # Run orbkit rho,delta_rho = core.rho_compute(qc,drv=['x','y','z'],numproc=4) # Compute the reduced density gradient from numpy import sqrt,pi s = (1./(2*(3*pi**2)**(1/3.)) * sqrt((delta_rho**2).sum(axis=0))/(rho**(4/3.))) # Apply a density cutoff, i.e., consider only values for rho < 0.05 a.u. s[rho>0.05] = 1e3 # Write a cube file and vmd script for the reduced density gradient output.main_output(s, qc.geo_info, # atomic information qc.geo_spec, # atomic coordinates outputname='reduced_drho', otype=['cb','vmd'], iso=(-0.5,0.5) # isocontour value of s = 0.5 a.u.
def run_orbkit(use_qc=None,check_options=True,standalone=False): '''Controls the execution of all computational tasks. **Parameters:** use_qc : QCinfo, optional If not None, the reading of a quantum chemistry output is omitted and the given QCinfo class is used for all computational tasks. (See :ref:`Central Variables` in the manual for details on QCinfo.) check_options : bool, optional If True, the specified options will be validated. **Returns:** data : type and shape depend on the options. Contains orbkit's output. See :ref:`High-Level Interface` in the manual for details. ''' # Set some global variables global qc # Display program information display(lgpl_short) # Check for the correctness of orbkit.options if check_options: display('Checking orbkit.options...\n') options.check_options(display=display, interactive=False, info=True,check_io=(use_qc is None)) # Measurement of required execution time t=[time.time()] # Do we need to read out the info of all MOs? if (options.mo_set or options.calc_mo) is not False: options.all_mo = True if use_qc is None: # Read the input file qc = read.main_read(options.filename, itype=options.itype, all_mo=options.all_mo, spin=options.spin, cclib_parser=options.cclib_parser) else: # Use a user defined QCinfo class. qc = use_qc if 'native' in options.otype: output.main_output(qc, outputname=options.outputname, otype='native', ftype=options.niotype) options.otype.remove('native') if not len(options.otype): t.append(time.time()) # Final time good_bye_message(t) return display('\nSetting up the grid...') if options.grid_file is not None: # Read the grid from an external file grid.read(options.grid_file) elif options.adjust_grid is not None: # Adjust the grid to geo_spec extend,step = options.adjust_grid grid.adjust_to_geo(qc,extend=extend,step=step) elif options.random_grid: # Create a randomized grid grid.random_grid(qc.geo_spec) # Initialize grid grid.grid_init(is_vector=options.is_vector) if options.is_vector: grid.is_regular = False display(grid.get_grid()) # Display the grid if not grid.is_regular and options.center_grid is not None: raise IOError('The option --center is only supported for regular grids.') elif options.center_grid is not None: atom = grid.check_atom_select(options.center_grid,qc.geo_info,qc.geo_spec, interactive=True,display=display) # Center the grid to a specific atom and (0,0,0) if requested grid.center_grid(qc.geo_spec[atom-1],display=display) if check_options or standalone: options.check_grid_output_compatibilty() t.append(time.time()) # A new time step # The calculation of all AOs (--calc_ao) if options.calc_ao != False: data = extras.calc_ao(qc, drv=options.drv, otype=options.otype) t.append(time.time()) # Final time good_bye_message(t) return data # The calculation of selected MOs (--calc_mo) or # the density formed by selected MOs (--mo_set) if (options.mo_set or options.calc_mo) != False: # What should the program do? if options.calc_mo != False: fid_mo_list = options.calc_mo elif options.mo_set != False: fid_mo_list = options.mo_set # Call the function for actual calculation if options.calc_mo != False: data = extras.calc_mo(qc, fid_mo_list, drv=options.drv, otype=options.otype) elif options.mo_set != False: data = extras.mo_set(qc, fid_mo_list, drv=options.drv, laplacian=options.laplacian, otype=options.otype) t.append(time.time()) # Final time good_bye_message(t) return data if options.gross_atomic_density is not None: rho_atom = extras.gross_atomic_density(options.gross_atomic_density,qc, drv=options.drv) if not options.no_output: output_written = output.main_output(rho_atom, qc, outputname=options.outputname, otype=options.otype) t.append(time.time()) good_bye_message(t) return rho_atom t.append(time.time()) # A new time step # Compute the (derivative of the) electron density if options.no_slice: data = core.rho_compute_no_slice(qc, drv=options.drv, laplacian=options.laplacian, return_components = False) else: data = core.rho_compute(qc, drv=options.drv, slice_length=options.slice_length, laplacian=options.laplacian, numproc=options.numproc) if options.drv is None: rho = data elif options.laplacian: rho, delta_rho, laplacian_rho = data else: rho, delta_rho = data t.append(time.time()) # A new time step # Generate the output requested if not options.no_output: if not (options.drv is not None or options.laplacian): plt_data = rho datalabels = 'rho' else: plt_data = [rho] datalabels = ['rho'] if options.drv is not None: plt_data.extend(delta_rho) datalabels.extend(['d/d%s of %s' % (ii_d,'rho') for ii_d in options.drv]) if options.laplacian: plt_data.append(laplacian_rho) datalabels.append('laplacian of rho') output.main_output(plt_data,qc,outputname=options.outputname, otype=options.otype,datalabels=datalabels) t.append(time.time()) # Final time good_bye_message(t) # Return the computed data, i.e., rho for standard, and (rho,delta_rho) # for derivative calculations. For laplacian (rho,delta_rho,laplacian_rho) return data
# Set grid parameters grid.adjust_to_geo(qc, extend=5.0, step=0.5) # Initialize grid grid.grid_init() # Print grid information display.display(grid.get_grid()) # Choose the molecular orbitals to be calculated selected_MO = ['1.1_a', '1.5_a'] qc.mo_spec = read.mo_select(qc.mo_spec, selected_MO, strict=True)['mo_spec'] # Calculate molecular orbitals mo_list = core.rho_compute(qc, calc_mo=True, slice_length=slice_length, drv=None, numproc=numproc) # Calculate analytic derivatives of molecular orbitals mo_list_drv = core.rho_compute(qc, calc_mo=True, slice_length=slice_length, drv='xyz', numproc=numproc) # Calculate Transition Electronic Flux Densities (time independent) # Calculate the STEFD [in units of (i E_h/(hbar a_0^2))] j_stefd = -0.5 * (mo_list[numpy.newaxis, 0] * mo_list_drv[:, 1] - mo_list[numpy.newaxis, 1] * mo_list_drv[:, 0])
def calc_mo(qc, fid_mo_list, drv=None, otype=None, ofid=None, numproc=None, slice_length=None): '''Calculates and saves the selected molecular orbitals or the derivatives thereof. **Parameters:** qc.geo_spec, qc.geo_info, qc.ao_spec, qc.mo_spec : See :ref:`Central Variables` for details. fid_mo_list : str Specifies the filename of the molecular orbitals list or list of molecular orbital labels (cf. :mod:`orbkit.read.mo_select` for details). If fid_mo_list is 'all_mo', creates a list containing all molecular orbitals. drv : string or list of strings {None,'x','y', 'z', 'xx', 'xy', ...}, optional If not None, a derivative calculation of the molecular orbitals is requested. otype : str or list of str, optional Specifies output file type. See :data:`otypes` for details. ofid : str, optional Specifies output file name. If None, the filename will be based on :mod:`orbkit.options.outputname`. numproc : int, optional Specifies number of subprocesses for multiprocessing. If None, uses the value from :mod:`options.numproc`. slice_length : int, optional Specifies the number of points per subprocess. If None, uses the value from :mod:`options.slice_length`. **Returns:** mo_list : numpy.ndarray, shape=((NMO,) + N) Contains the NMO=len(qc.mo_spec) molecular orbitals on a grid. ''' mo_spec = qc.mo_spec[fid_mo_list] qc_select = qc.copy() qc_select.mo_spec = mo_spec slice_length = options.slice_length if slice_length is None else slice_length numproc = options.numproc if numproc is None else numproc # Calculate the AOs and MOs mo_list = core.rho_compute(qc_select, calc_mo=True, drv=drv, slice_length=slice_length, numproc=numproc) if otype is None: return mo_list if ofid is None: if '@' in options.outputname: outputname, group = options.outputname.split('@') else: outputname, group = options.outputname, '' outputname, autootype = os.path.splitext(outputname) ofid = '%s_MO%s@%s' % (outputname, autootype, group) if not options.no_output: output_written = main_output(mo_list, qc_select, outputname=ofid, datalabels=qc_select.mo_spec.get_labels(), otype=otype, drv=drv) return mo_list
def run_orbkit(use_qc=None, check_options=True, standalone=False): '''Controls the execution of all computational tasks. **Parameters:** use_qc : QCinfo, optional If not None, the reading of a quantum chemistry output is omitted and the given QCinfo class is used for all computational tasks. (See :ref:`Central Variables` in the manual for details on QCinfo.) check_options : bool, optional If True, the specified options will be validated. **Returns:** data : type and shape depend on the options. Contains orbkit's output. See :ref:`High-Level Interface` in the manual for details. ''' # Set some global variables global qc # Display program information display(lgpl_short) # Check for the correctness of orbkit.options if check_options: display('Checking orbkit.options...\n') options.check_options(display=display, interactive=False, info=True, check_io=(use_qc is None)) # Measurement of required execution time t = [time.time()] # Do we need to read out the info of all MOs? if (options.mo_set or options.calc_mo) is not False: options.all_mo = True if use_qc is None: # Read the input file qc = read.main_read(options.filename, itype=options.itype, all_mo=options.all_mo, spin=options.spin, cclib_parser=options.cclib_parser) else: # Use a user defined QCinfo class. qc = use_qc display('\nSetting up the grid...') if options.grid_file is not None: # Read the grid from an external file grid.read(options.grid_file) elif options.adjust_grid is not None: # Adjust the grid to geo_spec extend, step = options.adjust_grid grid.adjust_to_geo(qc, extend=extend, step=step) elif options.random_grid: # Create a randomized grid grid.random_grid(qc.geo_spec) # Initialize grid grid.grid_init(is_vector=options.is_vector) if options.is_vector: grid.is_regular = False display(grid.get_grid()) # Display the grid if not grid.is_regular and options.center_grid is not None: raise IOError( 'The option --center is only supported for regular grids.') elif options.center_grid is not None: atom = grid.check_atom_select(options.center_grid, qc.geo_info, qc.geo_spec, interactive=True, display=display) # Center the grid to a specific atom and (0,0,0) if requested grid.center_grid(qc.geo_spec[atom - 1], display=display) if check_options or standalone: options.check_grid_output_compatibilty() t.append(time.time()) # A new time step # The calculation of all AOs (--calc_ao) if options.calc_ao != False: data = extras.calc_ao(qc, drv=options.drv, otype=options.otype) t.append(time.time()) # Final time good_bye_message(t) return data # The calculation of selected MOs (--calc_mo) or # the density formed by selected MOs (--mo_set) if (options.mo_set or options.calc_mo) != False: # What should the program do? if options.calc_mo != False: fid_mo_list = options.calc_mo elif options.mo_set != False: fid_mo_list = options.mo_set # Call the function for actual calculation if options.calc_mo != False: data = extras.calc_mo(qc, fid_mo_list, drv=options.drv, otype=options.otype) elif options.mo_set != False: data = extras.mo_set(qc, fid_mo_list, drv=options.drv, laplacian=options.laplacian, otype=options.otype) t.append(time.time()) # Final time good_bye_message(t) return data if options.gross_atomic_density is not None: atom = options.gross_atomic_density rho_atom = extras.numerical_mulliken_charges(atom, qc) if not grid.is_vector: mulliken_num = rho_atom[1] rho_atom = rho_atom[0] if not options.no_output: fid = '%s.h5' % options.outputname display('\nSaving to Hierarchical Data Format file (HDF5)...' + '\n\t%(o)s' % {'o': fid}) output.hdf5_write(fid, mode='w', gname='', atom=core.numpy.array(atom), geo_info=qc.geo_info, geo_spec=qc.geo_spec, gross_atomic_density=rho_atom, x=grid.x, y=grid.y, z=grid.z) if not options.is_vector: output.hdf5_write( fid, mode='a', gname='/numerical_mulliken_population_analysis', **mulliken_num) t.append(time.time()) good_bye_message(t) return rho_atom if options.mo_tefd is not None: mos = options.mo_tefd ao_list = core.ao_creator(qc.geo_spec, qc.ao_spec) mo_tefd = [] index = [] for i, j in mos: mo_tefd.append([]) index.append([]) for ii_d in options.drv: display('\nMO-TEFD: %s->%s %s-component' % (i, j, ii_d)) tefd = extras.mo_transition_flux_density(i, j, qc, drv=ii_d, ao_list=ao_list) mo_tefd[-1].append(tefd) index[-1].append('%s->%s:%s' % (i, j, ii_d)) if not options.no_output: from numpy import array fid = '%s.h5' % options.outputname display('\nSaving to Hierarchical Data Format file (HDF5)...' + '\n\t%(o)s' % {'o': fid}) HDF5_File = output.hdf5_open(fid, mode='w') data = { 'geo_info': array(qc.geo_info), 'geo_spec': array(qc.geo_spec), 'mo_tefd:info': array(index), 'mo_tefd': array(mo_tefd), 'x': grid.x, 'y': grid.y, 'z': grid.z } output.hdf5_append(data, HDF5_File, name='') HDF5_File.close() t.append(time.time()) good_bye_message(t) return mo_tefd t.append(time.time()) # A new time step # Compute the (derivative of the) electron density if options.no_slice: data = core.rho_compute_no_slice(qc, drv=options.drv, laplacian=options.laplacian, return_components=False) else: data = core.rho_compute(qc, drv=options.drv, slice_length=options.slice_length, laplacian=options.laplacian, numproc=options.numproc) if options.drv is None: rho = data elif options.laplacian: rho, delta_rho, laplacian_rho = data else: rho, delta_rho = data # Compute the reduced electron density if requested if options.z_reduced_density: if grid.is_vector: display('\nSo far, reducing the density is not supported for ' + 'vector grids.\nSkipping the reduction...\n') elif options.drv is not None: display( '\nSo far, reducing the density is not supported for ' + 'the derivative of the density.\nSkipping the reduction...\n') else: from scipy import integrate display('\nReducing the density with respect to the z-axis.\n') rho = integrate.simps(rho, grid.x, dx=grid.delta_[0], axis=0, even='avg') rho = integrate.simps(rho, grid.y, dx=grid.delta_[1], axis=0, even='avg') t.append(time.time()) # A new time step # Generate the output requested if not options.no_output: output_written = output.main_output(rho, qc.geo_info, qc.geo_spec, outputname=options.outputname, otype=options.otype, data_id='rho', omit=['vmd', 'mayavi'], mo_spec=qc.mo_spec) if options.drv is not None: output_written.extend( output.main_output(delta_rho, qc.geo_info, qc.geo_spec, outputname=options.outputname, otype=options.otype, data_id='delta_rho', omit=['vmd', 'mayavi'], mo_spec=qc.mo_spec, drv=options.drv)) if options.laplacian: output_written.extend( output.main_output(laplacian_rho, qc.geo_info, qc.geo_spec, outputname=options.outputname + '_laplacian', otype=options.otype, data_id='laplacian_rho', omit=['vmd', 'mayavi'], mo_spec=qc.mo_spec)) if 'vmd' in options.otype: # Create VMD network display('\nCreating VMD network file...' + '\n\t%(o)s.vmd' % {'o': options.outputname}) cube_files = [] for i in output_written: if i.endswith('.cb'): cube_files.append(i) output.vmd_network_creator(options.outputname, cube_files=cube_files) t.append(time.time()) # Final time good_bye_message(t) if 'mayavi' in options.otype: plt_data = [rho] datalabels = ['rho'] if options.drv is not None: plt_data.extend(delta_rho) datalabels.extend( ['d/d%s of %s' % (ii_d, 'rho') for ii_d in options.drv]) if options.laplacian: plt_data.append(laplacian_rho) datalabels.append('laplacian of rho') output.main_output(plt_data, qc.geo_info, qc.geo_spec, otype='mayavi', datalabels=datalabels) # Return the computed data, i.e., rho for standard, and (rho,delta_rho) # for derivative calculations. For laplacian (rho,delta_rho,laplacian_rho) return data
def func(x_array, *args): '''Calls orbkit. **Parameters:** x_array : 1-D numpy.ndarray, shape[0]=ndim*npt if vectorized=True else ndim Contains the grid. args : tuple or list |args[0] : int | Contains the number of points (npt). Variable does only exist if | vectorized=True. |args[-2] : bool | If True, assumes a vectorized grid. (vectorized=True) |args[-1] : bool | If True, computes the molecular orbitals, and integrates their squared | values iteratively. ** Returns:** out : 1-D numpy.ndarray, shape[0]=ndim*npt if vectorized=True else ndim Contains the output data. ''' global count_calls, vec, rho, vec_mo, mos if args[-2]: # vectorized x_array = x_array.reshape((-1, 3)) grid.x = numpy.array(x_array[:, 0], copy=True) grid.y = numpy.array(x_array[:, 1], copy=True) grid.z = numpy.array(x_array[:, 2], copy=True) count_calls += args[0] # Number of points else: x, y, z = x_array x_array = x_array[numpy.newaxis, :] grid.x = numpy.array([x]) grid.y = numpy.array([y]) grid.z = numpy.array([z]) count_calls += 1 # We have already initialized a grid for orbkit! grid.is_initialized = True # Run orbkit out = core.rho_compute(qc, calc_mo=args[-1], slice_length=slice_length, drv=None, numproc=numproc) if save_data_values: if args[-1]: vec_mo = numpy.append(vec_mo, x_array, axis=0) mos = numpy.append(mos, out, axis=1) else: vec = numpy.append(vec, x_array, axis=0) rho = numpy.append(rho, out, axis=0) if args[-1]: # calc_mo out **= 2. return out.transpose()
def Potential(j_data, grid_par=-6): u"""Calculates the electric potential difference for the molecule. ** Parameters ** j_data : dict Data on the molecule, as deserialized from the scanlog format. grid_par : int, optional Governs the grid to be used for voxel data. - If positive, it indicates the number of points in all 3 dimensions. - If zero, it indicates the default number of points (80). - If negative, it indicates the resolution, in Á^-1. ** Returns ** rho : numpy.ndarray The voxels containing the scalar values of the density. V : numpy.ndarray The voxels containing the scalar values of the potential. X, Y, Z : numpy.ndarray Meshgrids (as generated by numpy.mgrid), required for placing the voxels contained in rho and V. """ qc = read.convert_json(j_data) X, Y, Z = _init_ORB_grid(qc, grid_par=grid_par) dx, dy, dz = (X[10, 0, 0] - X[9, 0, 0]), (Y[0, 10, 0] - Y[0, 9, 0]), (Z[0, 0, 10] - Z[0, 0, 9]) d3r = dx * dy * dz rho = core.rho_compute(qc, numproc=6) print "Rho : ", np.sum(rho) * d3r, "(", np.min(rho), " ... ", np.max( rho), ")" print "d : ", dx, dy, dz print "P0 : ", X[0, 0, 0], Y[0, 0, 0], Z[0, 0, 0] print "P1 : ", X[-1, 0, 0], Y[0, -1, 0], Z[0, 0, -1] P = np.array([X, Y, Z]) ## The potential can be separated into two terms ## V_n, the contribution from nuclear charges (positive) V_n = np.zeros(rho.shape) for i in range(len(qc.geo_spec)): ## This currently works by: ## 1. reshaping the atom position triplet to the shape of the meshgrids ## 2. calculating the norm accross the three dimensions ## 3. propagating the meshgrid shape to the charge R = np.linalg.norm(P - qc.geo_spec[i].reshape((3, 1, 1, 1)), axis=0) R[R < 0.005] = np.inf N_i = float(qc.geo_info[i, -1]) / R V_n += N_i print "V_n (", qc.geo_info[i, 0], qc.geo_info[i, -1], ") : (", np.min( N_i), ", ", np.max(N_i), ") (", np.argwhere(N_i > 250).size, ")" TIx, TIy, TIz = rho.shape Tx, Ty, Tz = X[-1, 0, 0] - X[0, 0, 0], Y[0, -1, 0] - Y[0, 0, 0], Z[0, 0, -1] - Z[0, 0, 0] ## V_r, the contribution from the electron density (negative) ## To avoid calculating the full volume integral, ## we consider rho as a kernel and apply it to ## the grid of inverse distances as though it ## were an image ## 1. Accumulate local potential V_e = np.ones(rho.shape) * rho ## Reverse rho, so that it is traversed in the ## same direction as the image matrix rho_r = rho[::-1, ::-1, ::-1].copy() ## 2. Extend grid X_, Y_, Z_ = np.mgrid[dx * (1 - TIx):dx * TIx:dx, dy * (1 - TIy):dy * TIy:dy, dz * (1 - TIz):dz * TIz:dz] print P.shape ## 3. Calculate distance grid D = np.linalg.norm(np.array([0, 0, 0]).reshape( (3, 1, 1, 1)) - np.array([X_, Y_, Z_]), axis=0) D[TIx - 1, TIy - 1, TIz - 1] = np.inf R = 1 / D ## 4. Convolute for i in xrange(TIx): ie = i + TIx for j in xrange(TIy): je = j + TIy for k in xrange(TIz): V_e[i, j, k] += (rho_r * R[i:ie, j:je, k:k + TIz]).sum() #from scipy import signal as sg #V_e += sg.fftconvolve(R, rho, "valid") V_e *= d3r return rho, V_n - V_e, X, Y, Z
options.quiet = True dx = 4.970736 grid.x = numpy.arange(3) * dx - 4.970736 grid.y = numpy.arange(3) * dx - 4.970736 grid.z = numpy.arange(3) * dx - 4.732975 grid.is_initialized = True grid.is_regular = True grid.is_vector = False tests_home = os.path.dirname(inspect.getfile(inspect.currentframe())) folder = os.path.join(tests_home, '../outputs_for_testing/gaussian') filepath = os.path.join(folder, 'h2o_rhf_sph.fchk') qc = read.main_read(filepath, all_mo=False) rho, delta_rho = rho_compute(qc, drv='xyz') rho2, delta_rho2, laplacian = rho_compute(qc, laplacian=True) equal(rho, rho2) #equal(delta_rho,delta_rho2) #BUG refdata = numpy.genfromtxt(os.path.join(folder, 'h2o_rhf_sph_grad.cube'), skip_header=9).reshape((-1, )) refrho = numpy.zeros_like(rho) refdrho = numpy.zeros((3, ) + rho.shape) c = 0 for i in range(len(grid.x)): for j in range(len(grid.y)): for k in range(len(grid.z)): refrho[i, j, k] = refdata[c] c += 1 for l in range(3):