def brillouinize(self, kmesh=None, kgrid=None): if not hasattr(self, 'kpoints') or len(self.kpoints) == 0: qtk.exit('kpoints information not available') else: if not hasattr(self, 'kpoints_symmetrized'): k_old = self.kpoints[:,:3] b_old = self.band else: k_old = self.kpoints_symmetrized[:,:3] b_old = self.band_symmetrized if kgrid is None and kmesh is not None: try: kgrid, new_band = self._spg_grid(k_old, b_old, kmesh) except: try: kgrid, new_band = self._ase_grid(k_old, b_old, kmesh) except Exception as e: qtk.exit('kpoint generation failed') elif kmesh is None and kgrid is not None: new_band = self._kgrid_template(kgrid) if not hasattr(self, 'kpoints_symmetrized'): self.kpoints_symmetrized = self.kpoints self.band_symmetrized = self.band self.kpoints = kgrid self.band = new_band
def __init__(self, *args, **kwargs): if len(args) == 1 and args[0] > 0: self.base_dim = args[0] elif len(args) == 0 or args[0] == 0: fxyz = open(kwargs['xyz'], "r") self.base_dim = int(fxyz.readline()) fxyz.close() if 'xyz' in kwargs: self.data = cm.coulomb_matrix(kwargs['xyz'], self.base_dim) self.name = re.sub('.*\/', '', kwargs['xyz']) self.name = re.sub('\.xyz', '', self.name) else: qtk.exit("CoulombMatrix: input mode is not specified") # set row norm matrix NORM = np.vstack([sum(self.data), range(self.base_dim)]).T # sort NORM by row norm NORM = NORM[NORM[:, 0].argsort()] # reverse array order NORM = NORM[::-1] # extract new row order sortRow = NORM[:, 1].astype(int) # rearrange Coulomb matrix self.data = self.data[:, sortRow][sortRow]
def brillouinize(self, kmesh=None, kgrid=None): if not hasattr(self, 'kpoints') or len(self.kpoints) == 0: qtk.exit('kpoints information not available') else: if not hasattr(self, 'kpoints_symmetrized'): k_old = self.kpoints[:, :3] b_old = self.band else: k_old = self.kpoints_symmetrized[:, :3] b_old = self.band_symmetrized if kgrid is None and kmesh is not None: try: kgrid, new_band = self._spg_grid(k_old, b_old, kmesh) except: try: kgrid, new_band = self._ase_grid(k_old, b_old, kmesh) except Exception as e: qtk.exit('kpoint generation failed: %s' % e) elif kmesh is None and kgrid is not None: new_band = self._kgrid_template(kgrid) if not hasattr(self, 'kpoints_symmetrized'): self.kpoints_symmetrized = self.kpoints self.band_symmetrized = self.band self.kpoints = kgrid self.band = new_band
def gr(self, type1=None, type2=None, **kwargs): """ Radial distribution funciton 1) Default: calculate all pairwise distances 2) If one atom type specified: calculate only for one type e.g: g_OO for water 3) If two atom types specified: calculate distances between two specified atom types """ if 'dr' not in kwargs: kwargs['dr'] = 0.005 if np.sum(abs(self.cell - np.diag(np.diag(self.cell)))) != 0: qtk.exit("radial distribution is only implemented "+\ "for orthorhmbic cell") if 't_start' not in kwargs: kwargs['t_start'] = 0 def distance_list(list1, list2): traj = self.position[kwargs['t_start']:] size_t, size_n, _ = traj.shape size = size_t * size_n * 3 flatTraj = list(traj.reshape([size])) cell = list(np.diag(self.cell)) if list1 == list2: return dl1(flatTraj, size_t, size_n, list1, list2, cell, kwargs['dr']) else: return dl2(flatTraj, size_t, size_n, list1, list2, cell, kwargs['dr']) # the case for two atom types specifed if type2: # if two specified types differ if type1 != type2: list1 = [i for i in range(self.N) \ if self.type_list[i] == type1] list2 = [i for i in range(self.N) \ if self.type_list[i] == type2] return distance_list(list1, list2) else: list1 = [i for i in range(self.N) \ if self.type_list[i] == type1] return distance_list(list1, list1) # for the case only one type specified elif type1: list1 = [i for i in range(self.N) \ if self.type_list[i] == type1] return distance_list(list1, list1) # default case: else: list1 = range(self.N) return distance_list(list1, list1)
def FirstOrderRun(inp, program=qtk.setting.qmcode, **kwargs): if program == 'cpmd': inpdir, inpname, psinp, new_run, kwargs\ = qmDir(inp, **kwargs) if new_run: if 'rst' in kwargs: rst = kwargs['rst'] del kwargs['rst'] else: rst = 'RESTART.1' ref = kwargs['ref_path'] rst_src = os.path.join(ref, rst) if not os.path.exists(ref): qtk.exit("FirstOrderRun: ref_path", ref, "not found") if not os.path.exists(rst_src): qtk.exit("FirstOrderRun: RESTART file", rst_src, "not found") rst_trg = os.path.join(inpdir, 'RESTART') os.link(rst_src, rst_trg) cwd = os.getcwd() qout = qtk.QMRun(inpname, 'cpmd', inplace=True, restart=True, maxstep=1, **kwargs) return qout
def setReference(self, ref_vec): if len(ref_vec) != self.data_size: qtk.exit("number of data points not match") def set_ref(i, ref): self.data[i].ref = ref vset_ref = np.vectorize(set_ref) vset_ref(range(self.data_size), ref_vec)
def write(self, name=None, **kwargs): if 'inplace' not in kwargs: inplace = True else: inplace = kwargs['inplace'] if self.setting['program'] == 'cpmd': if name: stem, ext = os.path.splitext(name) if ext != '.psp': name = name + '.psp' if name and not inplace: name = os.path.join(qtk.setting.cpmd_pp, name) cpmd.write(self, name) elif self.setting['program'] == 'bigdft': if name and not inplace: name = os.path.join(qtk.setting.bigdft_pp, name) bigdft.write(self, name) elif self.setting['program'] == 'espresso': if name: stem, ext = os.path.splitext(name) if ext == '.psp' or ext == '.UPF': name = stem if name and not inplace: espresso_name = os.path.join(qtk.setting.espresso_pp, name + '.UPF') cpmd_name = os.path.join(qtk.setting.cpmd_pp, name + '.psp') else: espresso_name = name + '.UPF' cpmd_name = name + '.psp' espresso.write(self, cpmd_name, espresso_name) else: qtk.exit('program %s is not implemented for PP'\ % self.setting['program'])
def getDRho(self, cartesian=True, resolution='fine', new=False, occupation=None, **kwargs): if 'gridpoints' in kwargs: new = True if new or not hasattr(self, '_drho'): if not hasattr(self, '_psi'): _psi = self.getPsi(cartesian, resolution, new, **kwargs) if not hasattr(self, '_dpsi'): _dpsi = self.getDPsi(cartesian, resolution, new, **kwargs) if not hasattr(self, 'occupation'): qtk.exit("occupation number not found") self._psi, self._dpsi = _psi, _dpsi if occupation is None: occ = np.array(self.occupation) else: occ = np.array(occupation) self._drho = 2 * np.sum( self._psi[..., np.newaxis] * self._dpsi \ * occ[:, np.newaxis, np.newaxis], axis = 0 ) return self._drho
def alignSVD(self, mol, ref_list=None, tar_list=None): if type(mol) is str: try: mol = qtk.Molecule(mol) except: qtk.exit("error when reading molecule file: %s" % mol) assert issubclass(mol.__class__, qtk.Molecule) if not ref_list: ref_list = [i for i in range(self.N)] if not tar_list: tar_list = copy.deepcopy(ref_list) lst_a = self.R[ref_list] lst_b = mol.R[tar_list] center_a = np.mean(lst_a, axis=0) center_b = np.mean(lst_b, axis=0) #na = len(lst_a) na = self.N #nb = len(lst_b) nb = mol.N crd_a = self.R - np.kron(center_a, np.ones((self.N, 1))) crd_b = mol.R - np.kron(center_b, np.ones((mol.N, 1))) ref_a = lst_a - np.kron(center_a, np.ones((len(lst_a), 1))) ref_b = lst_b - np.kron(center_a, np.ones((len(lst_b), 1))) H = np.dot(np.transpose(ref_a), ref_b) U, s, V = np.linalg.svd(H) R = np.dot(np.transpose(V), np.transpose(U)) self.R = np.transpose( np.dot(R, np.transpose(crd_a))) + \ np.kron(center_b, np.ones((na, 1)) )
def _kPath(self, special_points, dk): spk = self.special_kpoints out = [] pos = 0 tick_pos = [0] tick_txt = [] for i in range(len(special_points)-1): ci = special_points[i] cf = special_points[i+1] if ci not in spk: qtk.exit("special point %c not in reconized" % ci) if cf not in spk: qtk.exit("special point %c not in reconized" % cf) if len(tick_txt) == 0: tick_txt.append("$\mathrm{" + ci + "}$") Ri = spk[ci] Rf = spk[cf] if len(out) == 0: out.append(Ri) vector = np.array(Rf) - np.array(Ri) n_points = int(ceil(np.linalg.norm(vector) / float(dk))) pos = pos + n_points tick_pos.append(pos) tick_txt.append("$\mathrm{" + cf + "}$") for i in range(1, n_points+1 ): point = list(np.round( np.array(Ri) + (i/float(n_points))*vector, decimals=3 )) out.append(point) tick_txt = [ '$\Gamma$' if x == '$\mathrm{G}$' else x for x in tick_txt] return out, [tick_pos, tick_txt]
def sort(self, order = 'Zxyz', inplace=True): odict = {'x':0, 'y':1, 'z':2} tmp = [] for o in order: if o == 'Z': tmp.insert(0, self.Z) elif o in odict: tmp.insert(0, self.R[:, odict[o]]) else: qtk.exit("sorting order '%c' not valid" % o) ind = np.lexsort(tmp) if not inplace: self = self.copy() self.R = self.R[ind] if list(self.R_scale[0]): self.R_scale = self.R_scale[ind] self.Z = list(np.array(self.Z)[ind]) self.type_list = list(np.array(self.type_list)[ind]) if len(self.string) == 0: self.string = ['' for _ in range(self.N)] self.string = list(np.array(self.string)[ind]) if order == 'Zxyz': type_list = [] self.index = [] for i in range(self.N): Zn = self.type_list[i] if Zn not in type_list: type_list.append(Zn) self.index.append(i) self.index.append(self.N) return self
def read_cif(self, name, **kwargs): xyz = open(name, 'r') content = xyz.readlines() xyz.close() l_list = filter(lambda x: '_cell_length_' in x, content) a_list = filter(lambda x: '_cell_angle_' in x, content) l = [float(filter(None, l_str.split(' '))[1]) for l_str in l_list] a = [float(filter(None, a_str.split(' '))[1]) for a_str in a_list] a = np.cos(np.array(a) * (np.pi / 180.)) fx, fy, fz = map(len, [ filter(lambda x: '_atom_site_fract_x' in x, content), filter(lambda x: '_atom_site_fract_y' in x, content), filter(lambda x: '_atom_site_fract_z' in x, content), ]) if (fx, fy, fz) != (1, 1, 1): qtk.exit("Failed! Only fractional coordingates are implemented") r_flag = filter(lambda x: '_atom_site_occupancy' in x, content) r_ind = content.index(r_flag[0]) + 1 atoms = np.array( [filter(None, r_str.split(' ')) for r_str in content[r_ind:]] ) self.periodic = True self.celldm = np.concatenate([l, a]) self.R_scale = atoms[:, 3:6].astype(float) self.R = qtk.fractional2xyz(self.R_scale, self.celldm) self.type_list = atoms[:, 0].tolist() self.Z = np.array(map(qtk.n2Z, atoms[:, 0])) self.N = len(self.Z) self.string = ['' for _ in range(self.N)] self.name = name
def coulomb_matrix(mol, n = -1, size = 0, sort = True, nuclear_charges = True): if size == 0: size = mol.N if size < mol.N: qtk.exit("matrix size too small") positions = mol.R if nuclear_charges: charges = np.array(mol.Z) else: charges = np.ones(mol.N) differences = positions[:, np.newaxis, :] \ - positions[np.newaxis, :, :] distances = np.sqrt((differences ** 2).sum(axis=-1)) distances[distances == 0] = np.nan # replace 0 for division if n != 0: invR = (distances ** n) else: invR = distances invR[np.isnan(invR)] = 0 # change 0 back for getting diagonal diag_mask = (invR == 0).astype(int) charge_mask_Zij = charges[:, np.newaxis] \ * charges[np.newaxis, :] charge_mask_2p4 = 0.5 * ((charges[:, np.newaxis] \ * charges[np.newaxis, :]) \ * diag_mask) ** 1.2 cm = invR * charge_mask_Zij + charge_mask_2p4 if sort: ind = np.argsort(cm.sum(axis=-1)) cm = cm[:, ind][ind] out = np.zeros([size, size]) out[:cm.shape[0], :cm.shape[1]] = cm return out
def mo_g09_nwchem(self): mo = self.mo_vectors ind = np.arange(len(mo[0])) itr = 0 # hard coded reordering for d and f orbitals order = { 'd': [0, 3, 4, 1, 5, 2], 'f': [0, 4, 5, 3, 9, 6, 1, 8, 7, 2], } while itr < len(mo[0]): bStr = self.basis[itr]['type'] if len(bStr) > 2: key = bStr[0] if key in order.keys(): ind_itr = ind[itr: itr+len(order[key])] ind_itr = ind_itr[order[key]] for i in range(len(order[bStr[0]])): ind[itr + i] = ind_itr[i] itr += len(order[bStr[0]]) - 1 else: qtk.exit("basis reordering for %s orbital " % key\ + "not implemented yet") itr += 1 return mo[:, ind]
def _kPath(self, special_points, dk): spk = self.special_kpoints out = [] pos = 0 tick_pos = [0] tick_txt = [] for i in range(len(special_points) - 1): ci = special_points[i] cf = special_points[i + 1] if ci not in spk: qtk.exit("special point %c not in reconized" % ci) if cf not in spk: qtk.exit("special point %c not in reconized" % cf) if len(tick_txt) == 0: tick_txt.append("$\mathrm{" + ci + "}$") Ri = spk[ci] Rf = spk[cf] if len(out) == 0: out.append(Ri) vector = np.array(Rf) - np.array(Ri) n_points = int(ceil(np.linalg.norm(vector) / float(dk))) pos = pos + n_points tick_pos.append(pos) tick_txt.append("$\mathrm{" + cf + "}$") for i in range(1, n_points + 1): point = list( np.round(np.array(Ri) + (i / float(n_points)) * vector, decimals=3)) out.append(point) tick_txt = [ '$\Gamma$' if x == '$\mathrm{G}$' else x for x in tick_txt ] return out, [tick_pos, tick_txt]
def sort(self, order = 'Zxyz'): odict = {'x':0, 'y':1, 'z':2} tmp = [] for o in order: if o == 'Z': tmp.insert(0, self.Z) elif o in odict: tmp.insert(0, self.R[:, odict[o]]) else: qtk.exit("sorting order '%c' not valid" % o) ind = np.lexsort(tmp) self.R = self.R[ind] if list(self.R_scale[0]): self.R_scale = self.R_scale[ind] self.Z = list(np.array(self.Z)[ind]) self.type_list = list(np.array(self.type_list)[ind]) self.string = list(np.array(self.string)[ind]) if order == 'Zxyz': type_list = [] self.index = [] for i in range(self.N): Zn = self.type_list[i] if Zn not in type_list: type_list.append(Zn) self.index.append(i) self.index.append(self.N)
def mo_g09_nwchem(self): mo = self.mo_vectors ind = np.arange(len(mo[0])) itr = 0 # hard coded reordering for d and f orbitals order = { 'd': [0, 3, 4, 1, 5, 2], 'f': [0, 4, 5, 3, 9, 6, 1, 8, 7, 2], } while itr < len(mo[0]): bStr = self.basis[itr]['type'] if len(bStr) > 2: key = bStr[0] if key in order.keys(): ind_itr = ind[itr:itr + len(order[key])] ind_itr = ind_itr[order[key]] for i in range(len(order[bStr[0]])): ind[itr + i] = ind_itr[i] itr += len(order[bStr[0]]) - 1 else: qtk.exit("basis reordering for %s orbital " % key\ + "not implemented yet") itr += 1 return mo[:, ind]
def getBeckeGrid(self, resolution='fine', new=False, **kwargs): """ coarse, medium, fine, veryfine, ultrafine and insane """ if not hasattr(self, 'molecule'): qtk.exit("no molecule structure found") if new or not hasattr(self, 'grid'): molecule = self.molecule coord = np.array(np.atleast_2d(molecule.R * 1.8897261245650618)) self.grid = BeckeMolGrid(coord, molecule.Z.astype(int), molecule.Z, resolution) mol_str = [] for i in range(molecule.N): atm_str = [molecule.type_list[i]] for j in range(3): atm_str.append(str(molecule.R[i, j])) mol_str.append(' '.join(atm_str)) mol_str = '; '.join(mol_str) if 'gto_kwargs' in kwargs: mol = gto.Mole(**kwargs['gto_kwargs']) else: mol = gto.Mole() #mol.build(atom=mol_str, basis=self.setting['basis_set']) if hasattr(self, 'basis_name'): basis = self.basis_name self.basisFormat() mol.build(atom=mol_str, basis=self.pybasis) self.mol = mol del_list = ['_phi', '_psi', '_dphi', '_dpsi', '_rho', '_drho'] for p in del_list: if hasattr(self, p): delattr(self, p)
def __init__(self, *args, **kwargs): if len(args) == 1 and args[0] > 0: self.base_dim = args[0] elif len(args) == 0 or args[0] == 0: fxyz = open(kwargs['xyz'], "r") self.base_dim = int(fxyz.readline()) fxyz.close() if 'xyz' in kwargs: self.data = cm.coulomb_matrix(kwargs['xyz'], self.base_dim) self.name = re.sub('.*\/','',kwargs['xyz']) self.name = re.sub('\.xyz','',self.name) else: qtk.exit("CoulombMatrix: input mode is not specified") # set row norm matrix NORM = np.vstack([sum(self.data), range(self.base_dim)]).T # sort NORM by row norm NORM=NORM[NORM[:,0].argsort()] # reverse array order NORM=NORM[::-1] # extract new row order sortRow=NORM[:,1].astype(int) # rearrange Coulomb matrix self.data = self.data[:,sortRow][sortRow]
def convE(source, units, separator=None): def returnError(ioStr, unitStr): msg = 'supported units are:\n' for key in Eh.iterkeys(): msg = msg + key + '\n' qtk.report(msg, color=None) qtk.exit(ioStr + " unit: " + unitStr + " is not reconized") EhKey = { 'ha': 'Eh', 'eh': 'Eh', 'hartree': 'Eh', 'ry': 'Ry', 'j': 'J', 'joule': 'J', 'kj/mol': 'kJ/mol', 'kjmol': 'kJ/mol', 'kjm': 'kJ/mol', 'kj': 'kJ/mol', # assume no kilo Joule! 'kcal/mol': 'kcal/mol', 'kcalmol': 'kcal/mol', 'kcal': 'kcal/mol', # assume no kcal! 'kcm': 'kcal/mol', 'ev': 'eV', 'cminv': 'cmInv', 'cminverse': 'cmInv', 'icm': 'cmInv', 'cm-1': 'cmInv', 'k': 'K', 'kelvin': 'K', } Eh = { 'Eh': 1.0, 'Ry': 2.0, 'eV': 27.211396132, 'kcal/mol': 627.509469, 'cmInv': 219474.6313705, 'K': 3.15774646E5, 'J': 4.3597443419E-18, 'kJ/mol': 2625.49962 } if not separator: separator = '-' unit = units.split(separator) if len(unit) != 2: qtk.exit("problem with unit separator '%s'" % separator) if unit[0].lower() != 'hartree' and unit[0].lower() != 'eh': if unit[0].lower() in EhKey: unit0 = EhKey[unit[0].lower()] source = source / Eh[unit0] else: returnError('input', unit[0]) if unit[1].lower() not in EhKey: returnError('output', unit[1]) else: unit1 = EhKey[unit[1].lower()] return source * Eh[unit1], unit1
def n2m(Zn): match = [m for m in mass_list.iterkeys() if m in Zn] mlen = [len(s) for s in match] if len(match) > 0: ind = np.argmax(mlen) return float(mass_list[match[ind]]) else: qtk.exit("n2Z: element type " + str(Zn) + " is not defined")
def cm_check(self, mol): ve = mol.getValenceElectrons() if (ve % 2) == (mol.multiplicity % 2): msg = "Multiplicity %d " % mol.multiplicity + \ "and %d valence electrons " % ve +\ "\n(with charge %3.1f) " % float(mol.charge) +\ "are not compatible" qtk.exit(msg)
def convE(source, units, separator=None): def returnError(ioStr, unitStr): msg = 'supported units are:\n' for key in Eh.iterkeys(): msg = msg + key + '\n' qtk.report(msg, color=None) qtk.exit(ioStr + " unit: " + unitStr + " is not reconized") EhKey = { 'ha': 'Eh', 'eh': 'Eh', 'hartree': 'Eh', 'ry': 'Ry', 'j': 'J', 'joule': 'J', 'kj/mol': 'kJ/mol', 'kjmol': 'kJ/mol', 'kjm': 'kJ/mol', 'kj': 'kJ/mol', # assume no kilo Joule! 'kcal/mol': 'kcal/mol', 'kcalmol': 'kcal/mol', 'kcal': 'kcal/mol', # assume no kcal! 'kcm': 'kcal/mol', 'ev': 'eV', 'cminv': 'cmInv', 'cminverse': 'cmInv', 'icm': 'cmInv', 'cm-1': 'cmInv', 'k': 'K', 'kelvin': 'K', } Eh = { 'Eh': 1.0, 'Ry': 2.0, 'eV': 27.211396132, 'kcal/mol': 627.509469, 'cmInv': 219474.6313705, 'K': 3.15774646E5, 'J': 4.3597443419E-18, 'kJ/mol': 2625.49962 } if not separator: separator='-' unit = units.split(separator) if len(unit) != 2: qtk.exit("problem with unit separator '%s'" % separator) if unit[0].lower() != 'hartree' and unit[0].lower() != 'eh': if unit[0].lower() in EhKey: unit0 = EhKey[unit[0].lower()] source = source / Eh[unit0] else: returnError('input', unit[0]) if unit[1].lower() not in EhKey: returnError('output', unit[1]) else: unit1 = EhKey[unit[1].lower()] return source * Eh[unit1], unit1
def qAtomicNumber(query): if type(query) == str: if z_list.has_key(query): return n2Z(query) elif type(query) == int or type(query) == float: if type_list.has_key(int(query)): return query else: qtk.exit("qAtom: element " + str(Zn) + " is not defined")
def __init__(self, *args, **kwargs): # number of atoms self.N = 0 # atom coordinates self.R = np.atleast_2d(np.array([])) self.R_scale = np.atleast_2d(np.array([])) # atom symbols self.type_list = [] # nuclear charges self.Z = [] # moelcule charge self.charge = 0 self.multiplicity = 1 # index of different atoms self.index = 0 self.bonds = {} self.bond_types = {} self.string = [] self.segments = [] self.periodic = False self.isolated = False self.scale = False self.celldm = False self.symmetry = False self.grid = False self.name = '' if 'molecule_data' not in kwargs: if len(args) == 1: mol = args[0] self.read(mol, **kwargs) elif len(args) == 2: N = len(args[0]) dim1 = np.array(args[0]).shape dim2 = np.array(args[1]).shape if dim1 == (N,) and dim2 == (N, 3): atoms = args[0] coord = np.array(args[1]) elif dim1 == (N, 3) and dim2 == (N,): atoms = args[1] coord = np.array(args[0]) else: qtk.exit('not supported declaration of molecule object.') self.addAtoms(atoms, coord) attr_list = dir(self) for string, value in kwargs.iteritems(): if string in attr_list: setattr(self, string, kwargs[string]) else: for string, value in kwargs['molecule_data'].iteritems(): setattr(self, string, value) self.ve = self.getValenceElectrons self.ne = self.getTotalElectrons
def get_index(inp_type): if inp_type: if type(inp_type) is str: Z = qtk.n2Z(inp_type) else: try: Z = int(inp_type) except Exception as err: qtk.exit("type not reconized with error:%s" % err) return np.arange(self.N)[np.asarray(self.Z) == Z]
def __init__(self, molecule, **kwargs): if not found: qtk.exit("horton module not found.") if 'wf_convergence' not in kwargs: kwargs['wf_convergence'] = 1e-06 GaussianBasisInput.__init__(self, molecule, **kwargs) self.setting.update(kwargs) self.backup() mol = IOData(coordinates=molecule.R, numbers=molecule.Z) obasis = get_gobasis(mol.coordinates, mol.numbers, self.setting['basis_set']) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers) # Create a linalg factory lf = DenseLinalgFactory(obasis.nbasis) # Compute Gaussian integrals olp = obasis.compute_overlap(lf) kin = obasis.compute_kinetic(lf) na = obasis.compute_nuclear_attraction(mol.coordinates, mol.pseudo_numbers, lf) er = obasis.compute_electron_repulsion(lf) # Create alpha orbitals exp_alpha = lf.create_expansion() # Initial guess guess_core_hamiltonian(olp, kin, na, exp_alpha) external = {'nn': compute_nucnuc(mol.coordinates, mol.pseudo_numbers)} libxc_term = RLibXCHybridGGA('xc_b3lyp') terms = [ #RTwoIndexTerm(kin, 'kin'), RDirectTerm(er, 'hartree'), RGridGroup(obasis, grid, [libxc_term]), RExchangeTerm(er, 'x_hf', libxc_term.get_exx_fraction()), RTwoIndexTerm(na, 'ne'), ] ham = REffHam(terms, external) self.ht_mol = mol self.ht_grid = grid self.ht_external = external self.ht_obasis = obasis self.ht_lf = lf self.ht_olp = olp self.ht_kin = kin self.ht_na = na self.ht_er = er self.ht_exp_alpha = exp_alpha self.ht_ham = ham
def Z2n(Z): if type_list.has_key(Z): return type_list[Z] elif type(Z) is float: return 'ATOM_%4.2f' % Z qtk.warning('Z2n: atomic number not defined, return HETATM') elif type(Z) is int: return 'ATOM_%d' % Z qtk.warning('Z2n: atomic number not defined, return HETATM') else: qtk.exit("Z2n: atomic number " + str(Z) + " is not defined")
def Z2n(Z): if type_list.has_key(Z): return type_list[Z] elif type(Z) is float: return "ATOM_%4.2f" % Z qtk.warning("Z2n: atomic number not defined, return HETATM") elif type(Z) is int: return "ATOM_%d" % Z qtk.warning("Z2n: atomic number not defined, return HETATM") else: qtk.exit("Z2n: atomic number " + str(Z) + " is not defined")
def read(self, path): fullpath = os.path.abspath(path) self.path, self.name = os.path.split(fullpath) if self.setting['program'] == 'cpmd': cpmd.read(self, path) elif self.setting['program'] == 'bigdft': bigdft.read(self, path) else: qtk.exit('program %s is not implemented for PP'\ % self.setting['program']) return self
def read_span(span): if span['type'] == 'mutation': self.mutation_list.append(self.str2data(span['index'])) self.mutation_target.append(self.str2data(span['range'])) elif span['type'] == 'stretching': self.stretching_list.append(self.str2data(span['index'])) self.stretching_direction.append(self.str2data(\ span['direction_index'])) self.stretching_range.append(self.str2data(\ span['range'], dtype='range')) else: qtk.exit(span['type'] + ' is not yet implemented')
def loadCubeList(cls, path_list, program=qtk.setting.qmcode): if program == 'cpmd': cls._file_list = path_list _para = [[name] for name in cls._file_list] if len(_para)<3*qtk.setting.cpu_count: cls._cube_list = qtk.parallelize(qtk.CUBE, _para, block_size=1) else: cls._cube_list = qtk.parallelize(qtk.CUBE, _para) else: qtk.exit("density of alchemical path is "\ +"not yet implemented for %s" % self.program)
def __init__(self, penalty, penalty_input, inpgen, mating_function, pop_size, **kwargs): # redefine some functions are necessary! opt.Optimizer.__init__(self, penalty, penalty_input, inpgen, **kwargs) self.pop_size = pop_size self.mating_function = mating_function self.mutation_rate = 0.05 if not pop_size/2 > 2: print pop_size qtk.exit("population too small")
def get_xcid(xcFlag): if type(xcFlag) is int: if xcFlag not in xc_dict.values(): qtk.exit("libxc functional id number %d is not valid" % xcFlag) else: xc_id = xcFlag elif type(xcFlag) is str: if xcFlag not in xc_dict: qtk.exit("libxc functional id %s is not valid" % xcFlag) else: xc_id = xc_dict[xcFlag] return xc_id
def __init__(self, *args, **kwargs): # number of atoms self.N = 0 # atom coordinates self.R = np.atleast_2d(np.array([])) self.R_scale = np.atleast_2d(np.array([])) # atom symbols self.type_list = [] # nuclear charges self.Z = [] # moelcule charge self.charge = 0 self.multiplicity = 1 # index of different atoms self.index = 0 self.bonds = {} self.bond_types = {} self.string = [] self.segments = [] self.periodic = False self.scale = False self.celldm = False self.symmetry = False self.grid = False self.name = '' if len(args) == 1: mol = args[0] self.read(mol, **kwargs) elif len(args) == 2: N = len(args[0]) dim1 = np.array(args[0]).shape dim2 = np.array(args[1]).shape if dim1 == (N,) and dim2 == (N, 3): atoms = args[0] coord = np.array(args[1]) elif dim1 == (N, 3) and dim2 == (N,): atoms = args[1] coord = np.array(args[0]) else: qtk.exit('not supported declaration of molecule object.') self.addAtoms(atoms, coord) attr_list = dir(self) for string, value in kwargs.iteritems(): if string in attr_list: setattr(self, string, kwargs[string]) if self.N > 0: self.ve = self.getValenceElectrons() self.ne = sum(self.Z)
def __add__(self, other): if self.R_scale.shape[1] > 0: qtk.exit('Molecule add not implemented for crystals.' + \ 'use extend/setAtoms instead') out = Molecule() out.N = self.N + other.N out.R = np.vstack([self.R, other.R]) out.Z = np.hstack([self.Z, other.Z]) out.type_list = np.hstack([self.type_list, other.type_list]) out.string = np.hstack([self.string, other.string]) out.charge = self.charge + other.charge out.name = self.name + "_" + other.name return out
def getDPsi(self, cartesian=True, resolution='fine', new=False, **kwargs): if 'gridpoints' in kwargs: new = True if new or not hasattr(self, '_dpsi'): self.getDPhi(cartesian, resolution, new, **kwargs) if not hasattr(self, 'mo_vectors'): qtk.exit('mo_vectors not found') mo = self.mo_vectors if hasattr(self, 'program'): if self.program == 'gaussian': mo = self.mo_g09_nwchem() self._dpsi = np.dot(mo, np.swapaxes(self._dphi, 0, 1)) return self._dpsi
def getRho(self, cartesian=True, resolution='fine', new=False, occupation=None, **kwargs): if 'gridpoints' in kwargs: new = True if new or not hasattr(self, '_rho'): self.getPsi(cartesian, resolution, new, **kwargs) if not hasattr(self, 'occupation'): qtk.exit("occupation number not found") if occupation is None: occ = np.array(self.occupation) else: occ = np.array(occupation) self._rho = np.sum(self._psi**2 * occ[:, np.newaxis], axis = 0) return self._rho
def getDipole(self, mo_vectors=None, cartesian=True, resolution='fine', unit='debye', component='full', new=False): if not hasattr(self, 'molecule'): qtk.exit('molecule structure not found') if mo_vectors is None: if not hasattr(self, '_rho'): try: rho = self.getRho(mo_vectors, cartesian, resolution, new=True) except: rho = self.getRho() else: rho = self._rho else: try: print 'yo' print mo_vectors rho = self.getRho(mo_vectors, cartesian, resolution, new=True) except: rho = self.getRho() try: grid = self.grid except: grid = self.ht_grid pQ = np.array( [sum(self.molecule.Z * self.molecule.R[:, i]) for i in range(3)]) pQ = pQ * 1.8897259885789 if component in ['full', 'ele']: pq = np.array( [grid.integrate(rho * grid.points[:, i]) for i in range(3)]) if component == 'full': mu = pQ - pq elif component == 'ele': mu = pq elif component == 'nuc': mu = pQ if unit == 'debye': return mu / 0.393430307 else: return mu
def mc(target_function, ccs_coord, ccs_span, inp_list, **kwargs): # if 'max_step' not in kwargs: # qtk.exit("'max_step' is missing") if 'T' not in kwargs: qtk.exit("'T' is missing") T = kwargs['T'] if 'target' not in kwargs: qtk.exit("'target' is missing") target = kwargs['target'] E_list = [] coord_list = [] itr = 0 def EcAppend(_new_E, _new_coord): E_list.append(_new_E) coord_list.append(_new_coord) itr += 1 if itr > 100: itr = 30 print list(zip(E_list, coord_list)) E_list = E_list[-30:] coord_list = coord_list[-30:] def E_average(): length = min(30, len(E_list)) return sum(E_list[-length:]) / float(length) def sample(ccs_new_coord): if type(inp_list[-1]) == dict: kwgs = inp_list[-1] args = inp_list[:-1] out = target_function(ccs_new_coord, ccs_span, *args, **kwgs) else: out = target_function(ccs_new_coord, ccs_span, *inp_list) diff = out - target boltzmann = np.exp(-abs(diff) / float(T)) rand = random.uniform(0, 1) if rand >= boltzmann: return diff, ccs_new_coord else: tmp, new_coord = ccs_span.random() sample(new_coord) EcAppend(sample(ccs_coord), ccs_coord) converge = E_average() tmp, new_coord = ccs_span.random() while converge > cutoff: new_E, new_coord = sample(new_coord) EcAppend(new_E, new_coord)
def _spg_grid(self, k_old, b_old, kmesh): shift_ind = np.argmin( np.linalg.norm(np.abs(k_old[:,:3]), axis=1) ) shift = k_old[shift_ind] lattice = self.lattice positions = self.molecule.R_scale numbers = self.molecule.Z cell = (lattice, positions, numbers) mapping, grid = spglib.get_ir_reciprocal_mesh( kmesh, cell, is_shift=shift) kgrid = grid.astype(float) / kmesh kgrid_shifted = kgrid + np.array([1,1,1]) groups_dict = {} for i in range(len(mapping)): k_id = mapping[i] if k_id not in groups_dict: groups_dict[k_id] = [i] else: groups_dict[k_id].append(i) groups = list(groups_dict.values()) new_band = np.zeros([len(kgrid), len(b_old[0])]) for i in range(len(k_old[:,:3])): k = k_old[i,:3] norm = [] for k_permute in permutations(k): norm.append(np.linalg.norm(kgrid - k_permute, axis=1)) norm.append(np.linalg.norm(kgrid + k_permute, axis=1)) for k_permute in permutations(k): norm.append(np.linalg.norm(kgrid - np.abs(k_permute), axis=1)) norm.append(np.linalg.norm(kgrid + np.abs(k_permute), axis=1)) norm = np.min(np.stack(norm), axis=0) try: key = np.where(norm < 1E-3)[0][0] except Exception as e: msg = 'kpoint miss match with error message: ' + str(e) msg = msg + '\ncurrtent kpoint: ' + str(k) qtk.exit(msg) for g in groups: if key in g: for key_g in g: new_band[key_g] = b_old[i] return kgrid, new_band
def mc(target_function, ccs_coord, ccs_span, inp_list, **kwargs): # if 'max_step' not in kwargs: # qtk.exit("'max_step' is missing") if 'T' not in kwargs: qtk.exit("'T' is missing") T = kwargs['T'] if 'target' not in kwargs: qtk.exit("'target' is missing") target = kwargs['target'] E_list = [] coord_list = [] itr = 0 def EcAppend(_new_E, _new_coord): E_list.append(_new_E) coord_list.append(_new_coord) itr += 1 if itr > 100: itr = 30 print list(zip(E_list,coord_list)) E_list = E_list[-30:] coord_list = coord_list[-30:] def E_average(): length = min(30, len(E_list)) return sum(E_list[-length:])/float(length) def sample(ccs_new_coord): if type(inp_list[-1]) == dict: kwgs = inp_list[-1] args = inp_list[:-1] out = target_function(ccs_new_coord, ccs_span, *args, **kwgs) else: out = target_function(ccs_new_coord, ccs_span, *inp_list) diff = out - target boltzmann = np.exp(-abs(diff)/float(T)) rand = random.uniform(0,1) if rand >= boltzmann: return diff, ccs_new_coord else: tmp, new_coord = ccs_span.random() sample(new_coord) EcAppend(sample(ccs_coord), ccs_coord) converge = E_average() tmp, new_coord = ccs_span.random() while converge > cutoff: new_E, new_coord = sample(new_coord) EcAppend(new_E, new_coord)
def l(self, l_in): if self.program == 'cpmd': ppstr = "_%03d.psp" % (l_in*100) out = copy.deepcopy(self.inp_base) for i in range(len(self.mutation_ind)): ind = self.mutation_ind[i] pp = self.PPString(i)+ppstr if ind < out.inp.structure.N: out.setAtom(ind+1, pp) else: out.addAtom(pp, self.mutation_crd[i]) return out else: qtk.exit("program %s is not implemented for PathScan"\ % self.program)
def _spg_grid(self, k_old, b_old, kmesh): shift_ind = np.argmin(np.linalg.norm(np.abs(k_old[:, :3]), axis=1)) shift = k_old[shift_ind] lattice = self.lattice positions = self.molecule.R_scale numbers = self.molecule.Z cell = (lattice, positions, numbers) mapping, grid = spglib.get_ir_reciprocal_mesh(kmesh, cell, is_shift=shift) kgrid = grid.astype(float) / kmesh kgrid_shifted = kgrid + np.array([1, 1, 1]) groups_dict = {} for i in range(len(mapping)): k_id = mapping[i] if k_id not in groups_dict: groups_dict[k_id] = [i] else: groups_dict[k_id].append(i) groups = list(groups_dict.values()) new_band = np.zeros([len(kgrid), len(b_old[0])]) for i in range(len(k_old[:, :3])): k = k_old[i, :3] norm = [] for k_permute in permutations(k): norm.append(np.linalg.norm(kgrid - k_permute, axis=1)) norm.append(np.linalg.norm(kgrid + k_permute, axis=1)) for k_permute in permutations(k): norm.append(np.linalg.norm(kgrid - np.abs(k_permute), axis=1)) norm.append(np.linalg.norm(kgrid + np.abs(k_permute), axis=1)) norm = np.min(np.stack(norm), axis=0) try: key = np.where(norm < 1E-3)[0][0] except Exception as e: msg = 'kpoint miss match with error message: ' + str(e) msg = msg + '\ncurrtent kpoint: ' + str(k) qtk.exit(msg) for g in groups: if key in g: for key_g in g: new_band[key_g] = b_old[i] return kgrid, new_band
def __init__(self, T, **kwargs): self.T = T if 'annealing' in kwargs: self.annealing = kwargs['annealing'] else: self.annealing = 'exp' if self.annealing and 'k_factor' not in kwargs: if self.annealing == 'exp': self.k = 1 elif self.annealing == 'fast': self.k = 1.1 elif self.annealing == 'boltz': self.k = 2.75 else: qtk.exit(self.annealing, " is not implemented") elif self.annealing: self.k = kwargs['k_factor']
def getDPsi(self, cartesian=True, resolution='fine', new=False, **kwargs): if 'gridpoints' in kwargs: new = True if new or not hasattr(self, '_dpsi'): self.getDPhi(cartesian, resolution, new, **kwargs) if 'mo_vectors' not in kwargs: if not hasattr(self, 'mo_vectors'): qtk.exit('mo_vectors not found') mo = self.mo_vectors else: mo = kwargs['mo_vectors'] if hasattr(self, 'program'): if self.program == 'gaussian': mo = self.mo_g09_nwchem() self._dpsi = np.dot(mo, np.swapaxes(self._dphi, 0, 1)) return self._dpsi
def loadAllCube(cls, path, pattern, program=qtk.setting.qmcode): """ centralized parallel CUBE loading """ if program == 'cpmd': cls._file_list = sorted(glob.glob( path + "/" + pattern + "/*.cube")) _para = [[name] for name in cls._file_list] if len(_para)<3*qtk.setting.cpu_count: cls._cube_list = qtk.parallelize(qtk.CUBE, _para, block_size=1) else: cls._cube_list = qtk.parallelize(qtk.CUBE, _para) else: qtk.exit("density of alchemical path is "\ +"not yet implemented for %s" % self.program)
def loadCube(self): # cpmd implemetation if self.program == 'cpmd': self.cube_name = sorted(glob.glob( self.path + "/" + self.pattern + "/*.cube")) if len(PathData._cube_list) > 0: _clist = PathData._cube_list _nlist = PathData._file_list self.cube_list = [_clist[_nlist.index(name)]\ for name in self.cube_name] else: _para = [[name] for name in self.cube_name] self.cube_list = qtk.parallelize(qtk.CUBE, _para, block_size=1) else: qtk.exit("density of alchemical path is "\ +"not yet implemented for %s" % self.program)
def write(self, *args, **kwargs): if len(args) > 0: _, ext = os.path.splitext(args[0]) kwargs['format'] = ext[1:] if 'format' not in kwargs: kwargs['format'] = 'xyz' if kwargs['format'] == 'xyz': self.write_xyz(*args, **kwargs) elif kwargs['format'] == 'pdb': self.write_pdb(*args, **kwargs) elif kwargs['format'] == 'ascii': self.write_ascii(*args, **kwargs) #elif kwargs['format'] == 'cyl': # self.write_cyl(*args, **kwargs) else: qtk.exit("output format: " + kwargs['format'] \ + " not reconized")
def __init__(self, cube_file = None, **kwargs): if cube_file: if not os.path.exists(cube_file): ut.exit("CUBE file:%s not found" % cube_file) self.path, self.name = os.path.split(cube_file) if 'format' not in kwargs: ext = os.path.splitext(self.name)[1] if ext == '.cube': kwargs['format'] = 'cube' elif ext == '.casino' or ext == '.dat': kwargs['format'] = 'casino' elif self.name == 'CHGCAR' or ext =='.vasp': kwargs['format'] = 'vasp' elif ext == '.fchk': kwargs['format'] = 'gaussian' else: qtk.exit("unknown extension %s" % ext) if kwargs['format'] == 'cube': self.data, self.zcoord, self.grid, self.coords\ = rq.read_cube(cube_file) elif kwargs['format'] == 'vasp': self.data, self.zcoord, self.grid = read_vasp(cube_file) elif kwargs['format'] == 'casino': self.data, self.zcoord, self.grid = read_casino(cube_file) elif kwargs['format'] == 'gaussian': self.data, self.zcoord, self.grid = \ read_gaussian(cube_file, **kwargs) self.molecule = qtk.Molecule() self.shape = self.data.shape self.molecule.R = self.zcoord[:,1:4]*0.529177249 self.molecule.Z = self.zcoord[:,0] self.molecule.N = len(self.zcoord) self.molecule.type_list = [ut.Z2n(z) for z in self.molecule.Z] self.interp = None def vec(i): return self.grid[i,1:] self.dV = np.dot(vec(1), np.cross(vec(2), vec(3))) self.V = self.dV*self.grid[1,0]*self.grid[2,0]*self.grid[3,0] else: self.grid = np.zeros([4, 4]) self.molecule = qtk.Molecule()
def _kgrid_template(self, kgrid): new_kpoints = kgrid[:, :3] k_dup = self.kpoints[:, :3] ind_key = range(len(self.kpoints)) new_band = np.zeros([len(new_kpoints), len(self.band[0])]) for i in range(len(k_dup)): k = k_dup[i] b = b_old[i] norm = np.linalg.norm(new_kpoints - k, axis=1) try: key = np.where(norm < 1E-4)[0][0] except Exception as e: print k qtk.exit('kmesh not matched with error message: %s' % str(e)) new_band[key] = b return new_band
def getDipole(self, cartesian=True, resolution='fine', unit='debye'): if not hasattr(self, 'molecule'): qtk.exit('molecule structure not found') if not hasattr(self, '_rho'): self.getRho(cartesian, resolution) pQ = np.array( [sum(self.molecule.Z * self.molecule.R[:,i]) for i in range(3)] ) pQ = pQ * 1.8897259885789 pq = np.array( [self.grid.integrate(self._rho * self.grid.points[:,i]) for i in range(3)] ) pq = pq mu = pQ - pq if unit == 'debye': return mu / 0.393430307 else: return mu