mcodev31 / libmsym

molecular point group symmetry lib
MIT License
73 stars 33 forks source link

How to add basis functions with the python interface #11

Closed rfkspada closed 6 years ago

rfkspada commented 6 years ago

Hi libmsym developers,

I am trying to use the python interface to create SALCs. First, I find the point group, so I guess the library is linked correctly. I am having trouble using the python binding to add basis functions to generate the SALCS.

I can see in the example that the basis function is added with the function:

def set_basis(element):  
    basis_function = msym.RealSphericalHarmonic(element = element, name = "1s")  
    element.basis_functions = [basis_function]  
    return basis_function

But this works for one basis set. Lets say I want to create SALCS for Li2 with 1s, 2s and 2p orbitals, the following does not work:

def set_basis_msym(element):
   basis_function = msym.RealSphericalHarmonic(element = element,n=2,l=1,m=1, name = "2px")
   basis_function = msym.RealSphericalHarmonic(element = element,n=2,l=1,m=0, name = "2pz")
   basis_function = msym.RealSphericalHarmonic(element = element,n=2,l=1,m=-1, name = "2py")
   basis_function = msym.RealSphericalHarmonic(element = element,n=2,l=0,m=0, name = "2s")
   basis_function = msym.RealSphericalHarmonic(element = element,n=1,l=0,m=0, name = "1s")
   element.basis_functions = [basis_function]
   return basis_function

I get only a 2x2 matrix for SALCS, that means that I am overwriting the information in the basis_function variable and adding only 1s orbitals.

Also, I could not find the basis_function inside the element class. Sorry if I missed something.

What is the correct way to add more than one basis function for each element?

Thanks in advance.

mcodev31 commented 6 years ago

This is more related to general python code than libmsym but:

The elements contain a list of basis functions (element.basis_functions = [basis_function]) Your code is just repeatedly assigning to a local variable, the last of which is then used. You need to assign to different variables along the lines of:

def set_basis_msym(element):
   px = msym.RealSphericalHarmonic(element = element,name = "2px")
   pz = msym.RealSphericalHarmonic(element = element,name = "2pz")
   py = msym.RealSphericalHarmonic(element = element,name = "2py")
   s2 = msym.RealSphericalHarmonic(element = element,name = "2s")
   s1 = msym.RealSphericalHarmonic(element = element,name = "1s")
   bf_list = [px,pz,py,s2,s1]
   element.basis_functions = bf_list
   return bf_list

Since the above now returns a list you need to flatten the list of basis functions you provide to the context:

basis_functions = [f for e in elements for f in set_basis_msym(e)]
...
with msym.Context(elements = elements, basis_functions = basis_functions) as ctx: