def get_symmetry_info_with_elements(elements, basis_functions=None, threshold=0.1): if basis_functions is None: basis_functions = [set_basis(e) for e in elements] assert isinstance(threshold, float) with msym.Context(elements=elements, basis_functions=basis_functions) as ctx: point_group = ctx.find_symmetry() symm_elements = ctx.symmetrize_elements() symm_atoms = msym_elements_to_atoms_dict(symm_elements) results = { 'point_group': point_group, 'symm_atoms': symm_atoms, 'symmetry_operations': symmetry_operations_to_dict( ctx.symmetry_operations), # symmetry operations 'subrepresentation_spaces': subrepresentation_spaces_to_dict(ctx.subrepresentation_spaces, ctx.elements), # subspace 'table': ctx.character_table.table, # table as numpy array 'character_table_symmetry_operations': symmetry_operations_to_dict( ctx.character_table.symmetry_operations ), # representative symmetry operations 'symmetry_species': symmetry_species_to_dict( ctx.character_table.symmetry_species), # symmetry species } return results
def show_symmetry_species(self): if msym is None: raise ImportError('no libmsym installation found') bs = self.basis_set elements = [msym.Element(coordinates = Coord, charge = int(Charge)) for Coord, Charge in zip(bs.center_coordinates, bs.center_charges)] basis_functions = [msym.RealSphericalHarmonic(element = elements[element_id-1], n = n + l, l = l, m = m) for [element_id, n, l, m] in bs.contracted_ids] with msym.Context(elements = elements, basis_functions = basis_functions) as ctx: point_group = ctx.find_symmetry() species_names = [s.name for s in ctx.character_table.symmetry_species] coefficients = np.asarray(self.coefficients) for offset in range(0,self.n_orb): mo = coefficients[:,offset] #mo /= np.linalg.norm(mo) species_components = ctx.symmetry_species_components(mo) print(offset,': ',' + '.join(['%f %s' % k for k in zip(species_components, species_names) if k[0] > 1.0e-6]))
def symmetrize(self): """ Symmetrizes the wavefunction """ if msym is None: raise ImportError('no libmsym installation found') bs = self.basis_set elements = [msym.Element(coordinates = Coord, charge = int(Charge)) for Coord, Charge in zip(bs.center_coordinates, bs.center_charges)] basis_functions = [msym.RealSphericalHarmonic(element = elements[element_id-1], n = n + l, l = l, m = m) for [element_id, n, l, m] in bs.contracted_ids] Smat_ao = np.asmatrix(self.basis_set.overlap) symorb = {} with msym.Context(elements = elements, basis_functions = basis_functions) as ctx: point_group = ctx.find_symmetry() species = ctx.character_table.symmetry_species species_names = [s.name for s in species] for kind in self.mo.keys(): # remove overlap C_mo = np.asmatrix(self.mo[kind].coefficients) s,U = np.linalg.eigh(C_mo.T*C_mo) U_lowdin = U * np.diag(1/np.sqrt(s)) * U.T C_mo = C_mo * U_lowdin (salcs, species, partner_functions) = ctx.symmetrize_wavefunctions(C_mo.T) # orthonormalize s,U = np.linalg.eigh(salcs * Smat_ao * salcs.T) U_lowdin = U * np.diag(1/np.sqrt(s)) * U.T C_mo = C_mo * U_lowdin symorb[kind] = OrbitalSet(C_mo, energies=self.mo[kind].energies, irreps=self.mo[kind].irreps, basis_set=self.mo[kind].basis_set) return Wavefunction(symorb, self.basis_set, n_sym=self.n_sym, n_bas=self.n_bas)
def salcorb(self, kind='restricted'): """ generate a set of initial molecular orbitals from SALCs """ if msym is None: raise ImportError('no libmsym installation found') symorb = {} Smat_ao = np.asmatrix(self.basis_set.overlap) Fmat_ao = np.asmatrix(self.basis_set.fockint) bs = self.basis_set elements = [msym.Element(coordinates = Coord, charge = int(Charge)) for Coord, Charge in zip(bs.center_coordinates, bs.center_charges)] basis_functions = [msym.RealSphericalHarmonic(element = elements[element_id-1], n = n + l, l = l, m = m) for [element_id, n, l, m] in bs.contracted_ids] E_salcs = np.empty(len(basis_functions)) supsym = np.empty(len(basis_functions), dtype=np.int_) with msym.Context(elements = elements, basis_functions = basis_functions) as ctx: point_group = ctx.find_symmetry() species_names = [s.name for s in ctx.character_table.symmetry_species] (C_salcs, salc_species, partner_functions) = ctx.salcs C_salcs = C_salcs.T salc_components = np.array([pf.dim for pf in partner_functions]) salc_sc = [(s, np.sort(np.unique(salc_components[salc_species == s]))) for s in np.unique(salc_species)] salc_sci = {} for (species, components) in salc_sc: salc_sci.update({(species,c):len(salc_sci) + i for i, c in enumerate(components)}) comp_head, *comp_tail = components select_species = species == salc_species select_comp = {c:np.where(np.all([select_species, salc_components == c], axis=0))[0] for c in components} Cmat = {c:C_salcs[:,select_comp[c]] for c in components} Smat_mo = Cmat[comp_head].T * Smat_ao * Cmat[comp_head] # average out symmetry breaking in overlap for component in comp_tail: Smat_mo += Cmat[component].T * Smat_ao * Cmat[component] Smat_mo /= len(components) # orthonormalize overlap s,U = np.linalg.eigh(Smat_mo) U_lowdin = U * np.diag(1/np.sqrt(s)) * U.T for component in components: Cmat[component] = Cmat[component] * U_lowdin # average out symmetry breaking in metric Fock Fmat_mo = Cmat[comp_head].T * Smat_ao.T * Fmat_ao * Smat_ao * Cmat[comp_head] for component in comp_tail: Fmat_mo += Cmat[component].T * Smat_ao.T * Fmat_ao * Smat_ao * Cmat[component] Fmat_mo /= len(components) # diagonalize metric Fock f,U = np.linalg.eigh(Fmat_mo) for component in components: Cmat[component] = Cmat[component] * U # update components, energies and supsym select = select_comp[component] supsym[select] = salc_sci[(species,component)] C_salcs[:,select] = Cmat[component] E_salcs[select] = f salc_order = np.argsort(E_salcs) for kind in self.mo.keys(): symorb[kind] = OrbitalSet(C_salcs[:,salc_order], energies=E_salcs[salc_order], irreps=supsym[salc_order], basis_set=self.mo[kind].basis_set) return Wavefunction(symorb, self.basis_set, n_sym=self.n_sym, n_bas=self.n_bas)
basis_function = msym.RealSphericalHarmonic(element=element, name="1s") element.basis_functions = [basis_function] return basis_function basis_functions = [set_basis(e) for e in elements] #msym.init(library_location='/path_to_libmsym_library/libmsym.dylib') # e.g. for OS X without libmsym in dload path #with msym.Context() as ctx: # ctx.elements = elements # point_group = ctx.find_symmetry() # selements = ctx.symmetrize_elements() # write_xyz(args.outfile, selements, comment + " symmetrized by libmsym according to point group " + point_group) with msym.Context(elements=elements, basis_functions=basis_functions) as ctx: point_group = ctx.find_symmetry() selements = ctx.symmetrize_elements() write_xyz( args.outfile, selements, comment + " symmetrized by libmsym according to point group " + point_group) ctx.symmetry_operations #symmetry operations ctx.subrepresentation_spaces # subspace ctx.subrepresentation_spaces[ 0].symmetry_species #symmetry species of space (index into character table) ctx.subrepresentation_spaces[0].salcs # salcs that span space ctx.subrepresentation_spaces[0].salcs[ 0].basis_functions # basis functions for salc ctx.subrepresentation_spaces[0].salcs[ 0].partner_functions # numpy array of partner functions expressed in terms of basis_functions coefficients