surfaxe icon indicating copy to clipboard operation
surfaxe copied to clipboard

Invalid argument passed to VaspInputSet

Open wladerer opened this issue 5 months ago • 0 comments

The following script

from surfaxe.generation import generate_slabs
from pathlib import Path
import os
import warnings

warnings.filterwarnings("always")
warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
warnings.filterwarnings("ignore", message="POTCAR data")
warnings.filterwarnings("ignore", message="Overriding the POTCAR functional")

generate_slabs(structure='Sn.vasp', hkl=1, thicknesses=[5,10,15,20,25,30,35,40], vacuums=[15], make_input_files=True)

Produces this error

Traceback (most recent call last):
  File "/home/wladerer/Documents/sn/slabs.py", line 11, in <module>
    generate_slabs(structure='Sn.vasp', hkl=1, thicknesses=[5,10,15,20,25,30,35,40], vacuums=[15], make_input_files=True)
  File "/home/wladerer/github/surfaxe/surfaxe/generation.py", line 308, in generate_slabs
    slabs_to_file(list_of_slabs=unique_list_of_dicts, structure=struc, 
  File "/home/wladerer/github/surfaxe/surfaxe/io.py", line 112, in slabs_to_file
    vis = DictSet(slab['slab'], cd, **save_slabs_kwargs)
TypeError: VaspInputSet.__init__() got an unexpected keyword argument 'potcar_functional'

Using the most recent release of pymatgen on PyPI, python 3.10.12, and surfaxe that was cloned from the repo an hour ago

Currently the VaspInputSet class has the following arguments according to the documentation:

class VaspInputSet(structure: Structure | None = <property object>, config_dict: dict = <factory>, files_to_transfer: dict = <factory>, user_incar_settings: dict = <factory>, user_kpoints_settings: dict = <factory>, user_potcar_settings: dict = <factory>, constrain_total_magmom: bool = False, sort_structure: bool = True, user_potcar_functional: UserPotcarFunctional = None, force_gamma: bool = False, reduce_structure: Literal['niggli', 'LLL'] | None = None, vdw: str | None = None, use_structure_charge: bool = False, standardize: bool = False, sym_prec: float = 0.1, international_monoclinic: bool = True, validate_magmom: bool = True, inherit_incar: bool | list[str] = False, auto_kspacing: bool = False, auto_ismear: bool = False, auto_ispin: bool = False, auto_lreal: bool = False, auto_metal_kpoints: bool = False, bandgap_tol: float = 0.0001, bandgap: float | None = None, prev_incar: str | dict | None = None, prev_kpoints: str | Kpoints | None = None, _valid_potcars: Sequence[str] | None = None)

So prepending 'user' to 'potcar_functional' would suffice. My hacky workaround is updating the kwargs dict key before passing it to the function

            if make_input_files:
                # soft check if potcar directory is set 
                potcars = _check_psp_dir()
                if potcars:
                    cd = _load_config_dict(config_dict)
                    save_slabs_kwargs = {'user_potcar_functional' if k == 'potcar_functional' else k: v for k, v in save_slabs_kwargs.items()}
                    vis = DictSet(slab['slab'], cd, **save_slabs_kwargs)
                    vis.write_input(
                        r'{}/{}/{}_{}_{}'.format(bulk_name,
                            slab['hkl'],
                            slab['slab_thickness'],
                            slab['vac_thickness'],
                            slab['slab_index'])
                        )

My suggestion would to have a function that filters for these things so you can remain compliant with your documentation and the pmg functionalities even as they change. Might add some maintenance overhead though.

Thanks!

wladerer avatar Sep 06 '24 14:09 wladerer