Package: posym
PoSymA point symmetry analysis tool written in python designed for theoretical chemistry.
This tool makes use of continuous symmetry ideas to provide a robust implementation
to compute the symmetry of different objects. This library is designed to be easily
extendable to other objects by subclassing theSymmetryBaseclass.FeaturesUse as simple calculator for irreducible representations supporting direct sum and productContinuous symmetry measures (CSM) expressed in the basis or irreducible representationDetermine symmetry of:normal modesfunctions defined in gaussian basis (molecular orbitals, electronic densities, operators)wave functions defined as a slater determinantwave functions defined as linear combination of slater determinants (Multi-reference/CI)Autogenerated high precision symmetry tablesCompatibility with PyQchem (http://www.github.com/abelcarreras/pyqchem)RequisitesnumpyscipypandasyamlUse as a simple symmetry calculationPosym allows to create basic continuous symmetry python objects that can be operated using
direct sum (+) and direct product (*).fromposymimportPointGroup,SymmetryObjectpg=PointGroup(group='Td')print(pg)a1=SymmetryObject(group='Td',rep='A1')a2=SymmetryObject(group='Td',rep='A2')e=SymmetryObject(group='Td',rep='E')t1=SymmetryObject(group='Td',rep='T1')print('t1 * t1:',t1*t1)print('t1 * e:',t1*e)print('e * (e + a1):',e*(e+a1))Determine the symmetry of normal modesSymmetry objects can be obtained from normal modes usingSymmetryModes.fromposymimportSymmetryNormalModescoordinates=[[0.00000,0.0000000,-0.0808819],[-1.43262,0.0000000,-1.2823700],[1.43262,0.0000000,-1.2823700]]symbols=['O','H','H']normal_modes=[[[0.,0.,-0.075],[-0.381,-0.,0.593],[0.381,-0.,0.593]],# mode 1[[-0.,-0.,0.044],[-0.613,-0.,-0.35],[0.613,0.,-0.35]],# mode 2[[-0.073,-0.,-0.],[0.583,0.,0.397],[0.583,0.,-0.397]]]# mode 3frequencies=[1737.01,3988.5,4145.43]sym_modes_gs=SymmetryNormalModes(group='c2v',coordinates=coordinates,modes=normal_modes,symbols=symbols)foriinrange(len(normal_modes)):print('Mode{:2}:{:8.3f}:'.format(i+1,frequencies[i]),sym_modes_gs.get_state_mode(i))print('Total symmetry: ',sym_modes_gs)Determine the symmetry of a molecular geometryContinuous symmetry measure (CSM) is obtained usingmeasuremethod.fromposymimportSymmetryMoleculecoordinates=[[0.0000000000,0.0000000000,0.0000000000],[0.5541000000,0.7996000000,0.4965000000],[0.6833000000,-0.8134000000,-0.2536000000],[-0.7782000000,-0.3735000000,0.6692000000],[-0.4593000000,0.3874000000,-0.9121000000]]symbols=['C','H','H','H','H']sym_geom=SymmetryMolecule(group='Td',coordinates=coordinates,symbols=symbols)print('Symmetry measure Td : ',sym_geom.measure)sym_geom=SymmetryMolecule(group='C3v',coordinates=coordinates,symbols=symbols)print('Symmetry measure C3v : ',sym_geom.measure)sym_geom=SymmetryMolecule(group='C4v',coordinates=coordinates,symbols=symbols)print('Symmetry measure C4v : ',sym_geom.measure)Define basis set functions in gaussian basisDefine basis function as linear combination of gaussian that act as normal python functionsfromposym.basisimportPrimitiveGaussian,BasisFunction# Oxigen atomsa=PrimitiveGaussian(alpha=130.70932)sb=PrimitiveGaussian(alpha=23.808861)sc=PrimitiveGaussian(alpha=6.4436083)s_O=BasisFunction([sa,sb,sc],[0.154328969,0.535328136,0.444634536],center=[0.0000000000,0.000000000,-0.0808819])# Bohrsa=PrimitiveGaussian(alpha=5.03315132)sb=PrimitiveGaussian(alpha=1.1695961)sc=PrimitiveGaussian(alpha=0.3803890)s2_O=BasisFunction([sa,sb,sc],[-0.099967228,0.399512825,0.700115461],center=[0.0000000000,0.000000000,-0.0808819])pxa=PrimitiveGaussian(alpha=5.0331513,l=[1,0,0])pxb=PrimitiveGaussian(alpha=1.1695961,l=[1,0,0])pxc=PrimitiveGaussian(alpha=0.3803890,l=[1,0,0])pya=PrimitiveGaussian(alpha=5.0331513,l=[0,1,0])pyb=PrimitiveGaussian(alpha=1.1695961,l=[0,1,0])pyc=PrimitiveGaussian(alpha=0.3803890,l=[0,1,0])pza=PrimitiveGaussian(alpha=5.0331513,l=[0,0,1])pzb=PrimitiveGaussian(alpha=1.1695961,l=[0,0,1])pzc=PrimitiveGaussian(alpha=0.3803890,l=[0,0,1])px_O=BasisFunction([pxa,pxb,pxc],[0.155916268,0.6076837186,0.3919573931],center=[0.0000000000,0.000000000,-0.0808819])py_O=BasisFunction([pya,pyb,pyc],[0.155916268,0.6076837186,0.3919573931],center=[0.0000000000,0.000000000,-0.0808819])pz_O=BasisFunction([pza,pzb,pzc],[0.155916268,0.6076837186,0.3919573931],center=[0.0000000000,0.000000000,-0.0808819])# Hydrogen atomssa=PrimitiveGaussian(alpha=3.42525091)sb=PrimitiveGaussian(alpha=0.62391373)sc=PrimitiveGaussian(alpha=0.1688554)s_H=BasisFunction([sa,sb,sc],[0.154328971,0.535328142,0.444634542],center=[-1.43262,0.000000000,-1.28237])s2_H=BasisFunction([sa,sb,sc],[0.154328971,0.535328142,0.444634542],center=[1.43262,0.000000000,-1.28237])basis_set=[s_O,s2_O,px_O,py_O,pz_O,s_H,s2_H]# Operate with basis functions in analytic formpx_O2=px_O*px_Oprint('integral from -inf to inf:',px_O2.integrate)# plot functionsfrommatplotlibimportpyplotaspltimportnumpyasnpxrange=np.linspace(-5,5,100)plt.plot(xrange,[s_O(x,0,0)forxinxrange],label='s_O')plt.plot(xrange,[px_O(x,0,0)forxinxrange],label='px_O')plt.legend()Create molecular orbitals from basis setDefine molecular orbitals straightforwardly from molecular orbitals coefficients using usual operators# Orbital 1o1=s_O*0.994216442+s2_O*0.025846814+px_O*0.0+py_O*0.0+pz_O*-0.004164076+s_H*-0.005583712+s2_H*-0.005583712# Orbital 2o2=s_O*0.23376666+s2_O*-0.844456594+px_O*0.0+py_O*0.0+pz_O*0.122829781+s_H*-0.155593214+s2_H*-0.155593214# Orbital 3o3=s_O*0.0+s2_O*0.0+px_O*0.612692349+py_O*0.0+pz_O*0.0+s_H*-0.44922168+s2_H*0.449221684# Orbital 4o4=s_O*-0.104033343+s2_O*0.538153649+px_O*0.0+py_O*0.0+pz_O*0.755880259+s_H*-0.295107107+s2_H*-0.2951071074# Orbital 5o5=s_O*0.0+s2_O*0.0+px_O*0.0+py_O*-1.0+pz_O*0.0+s_H*0.0+s2_H*0.0# Orbital 6o6=s_O*-0.125818566+s2_O*0.820120983+px_O*0.0+py_O*0.0+pz_O*-0.763538862+s_H*-0.769155124+s2_H*-0.769155124# Check orthogonalityprint('<o1|o1>: ',(o1*o1).integrate)print('<o2|o2>: ',(o2*o2).integrate)print('<o1|o2>: ',(o1*o2).integrate)Analyze symmetry of molecular orbitalsGet symmetry of molecular orbitals defined asBasisFunctiontype objectsfromposymimportSymmetryGaussianLinearsym_o1=SymmetryGaussianLinear('c2v',o1)sym_o2=SymmetryGaussianLinear('c2v',o2)sym_o3=SymmetryGaussianLinear('c2v',o3)sym_o4=SymmetryGaussianLinear('c2v',o4)sym_o5=SymmetryGaussianLinear('c2v',o5)sym_o6=SymmetryGaussianLinear('c2v',o6)print('Symmetry O1: ',sym_o1)print('Symmetry O2: ',sym_o2)print('Symmetry O3: ',sym_o3)print('Symmetry O4: ',sym_o4)print('Symmetry O5: ',sym_o5)print('Symmetry O6: ',sym_o6)# Operate molecular orbitals symmetries to get the symmetry of non-degenerate wave functions# restricted close shellsym_wf_gs=sym_o1*sym_o1*sym_o2*sym_o2*sym_o3*sym_o3*sym_o4*sym_o4*sym_o5*sym_o5print('Symmetry WF (ground state): ',sym_wf_gs)# restricted open shellsym_wf_excited_1=sym_o1*sym_o1*sym_o2*sym_o2*sym_o3*sym_o3*sym_o4*sym_o4*sym_o5*sym_o6print('Symmetry WF (excited state 1): ',sym_wf_excited_1)# restricted close shellsym_wf_excited_2=sym_o1*sym_o1*sym_o2*sym_o2*sym_o3*sym_o3*sym_o4*sym_o4*sym_o6*sym_o6print('Symmetry WF (excited state 2): ',sym_wf_excited_2)Combine with PyQchem to create useful automationsPyQchem (https://github.com/abelcarreras/PyQchem) is a Python interface
for Q-Chem (https://www.q-chem.com). PyQchem can be used to obtain
wave functions and normal modes as Python objects that can be directly used in Posym.frompyqchemimportget_output_from_qchem,QchemInput,Structurefrompyqchem.parsers.basicimportbasic_parser_qchemfromposymimportSymmetryGaussianLinear# convenient functions to connect pyqchem - posymfromposym.toolsimportget_basis_set,build_orbital# define moleculesbutadiene=Structure(coordinates=[[-1.07076839,-2.13175980,0.03234382],[-0.53741536,-3.05918866,0.04995793],[-2.14073783,-2.12969357,0.04016267],[-0.39112115,-0.95974916,0.00012984],[0.67884827,-0.96181542,-0.00769025],[-1.15875076,0.37505495,-0.02522296],[-0.62213437,1.30041753,-0.05065831],[-2.51391203,0.37767199,-0.01531698],[-3.04726506,1.30510083,-0.03293196],[-3.05052841,-0.54769055,0.01011971]],symbols=['C','H','H','C','H','C','H','C','H','H'])# create qchem inputqc_input=QchemInput(butadiene,jobtype='sp',exchange='hf',basis='sto-3g',)# calculate and parse qchem outputdata,ee=get_output_from_qchem(qc_input,read_fchk=True,processors=4,parser=basic_parser_qchem)# extract required information from Q-Chem calculationcoordinates=ee['structure'].get_coordinates()mo_coefficients=ee['coefficients']['alpha']basis=ee['basis']# print resultsprint('Molecular orbitals (alpha) symmetry')basis_set=get_basis_set(coordinates,basis)fori,orbital_coeffinenumerate(mo_coefficients):orbital=build_orbital(basis_set,orbital_coeff)sym_orbital=SymmetryGaussianLinear('c2v',orbital)print('Symmetry O{}: '.format(i+1),sym_orbital)Compute the symmetry of wave functions defined as a Slater determinantUseSymmetryWaveFunctionclass to determine the symmetry of a wave function
from a set of occupied molecular orbitals defined asBasisFunctionobjectsfromposymimportSymmetrySingleDeterminantfromposym.toolsimportbuild_orbital# get orbitals from basis set and MO coefficientsorbital1=build_orbital(basis_set,coefficients['alpha'][0])# A1orbital2=build_orbital(basis_set,coefficients['alpha'][1])# A1orbital3=build_orbital(basis_set,coefficients['alpha'][2])# T1orbital4=build_orbital(basis_set,coefficients['alpha'][3])# T1orbital5=build_orbital(basis_set,coefficients['alpha'][4])# T1wf_sym=SymmetrySingleDeterminant('Td',alpha_orbitals=[orbital1,orbital2,orbital5],beta_orbitals=[orbital1,orbital2,orbital4],center=[0,0,0])print('Configuration 1: ',wf_sym)# T1 + T2wf_sym=SymmetrySingleDeterminant('Td',alpha_orbitals=[orbital1,orbital2,orbital3],beta_orbitals=[orbital1,orbital2,orbital3],center=[0,0,0])print('Configuration 2: ',wf_sym)# A1 + ECompute the symmetry of multi-reference wave functionsUseSymmetryWaveFunctionCIclass to determine the symmetry of multi-reference wave function
(defined as a liner combination of Slater determinants) from a set of
occupied molecular orbitals defined asBasisFunctionobjects and aconfigurationsdictionary.fromposymimportSymmetryMultiDeterminantconfigurations=[{'amplitude':-0.03216,'occupations':{'alpha':[1,1,0,0,1],'beta':[1,1,1,0,0]}},{'amplitude':0.70637,'occupations':{'alpha':[1,1,0,1,0],'beta':[1,1,1,0,0]}},{'amplitude':0.03216,'occupations':{'alpha':[1,1,1,0,0],'beta':[1,1,0,0,1]}},{'amplitude':-0.70637,'occupations':{'alpha':[1,1,1,0,0],'beta':[1,1,0,1,0]}}]wf_sym=SymmetryMultiDeterminant('Td',orbitals=[orbital1,orbital2,orbital3,orbital4,orbital5],configurations=configurations,center=[0,0,0])print('State 1: ',wf_sym)# T1Try aninteractive examplein Google ColabBibliographyThis software is based on the theory described in the following works:Pinsky M, Dryzun C, Casanova D, Alemany P, Avnir D, J Comput Chem. 29:2712-21 (2008)[link]Pinsky M, Casanova D, Alemany P, Alvarez S, Avnir D, Dryzun C, Kizner Z, Sterkin A. J Comput Chem. 29:190-7 (2008)[link]Casanova D, Alemany P. Phys Chem Chem Phys. 12(47):15523–9 (2010)[link]Casanova D, Alemany P, Falceto A, Carreras A, Alvarez S. J Comput Chem 34(15):1321–31 (2013)[link]A. Carreras, E. Bernuz, X. Marugan, M. Llunell, P. Alemany, Chem. Eur. J. 25, 673 – 691 (2019)[link]Contact infoAbel Carrerasabelcarreras83@gmail.comDonostia International Physics Center (DIPC)Donostia-San Sebastian (Spain)