pyiron / pyiron_atomistics

pyiron_atomistics - an integrated development environment (IDE) for atomistic simulation in computational materials science.
https://pyiron-atomistics.readthedocs.io
BSD 3-Clause "New" or "Revised" License
43 stars 15 forks source link

VASP POTCAR POSCAR sorting is inconsistent #988

Open Leimeroth opened 1 year ago

Leimeroth commented 1 year ago

For some structure VASP writes inconsistent POTCAR and POSCAR input, because the POSCAR is ordered alphabetically, but the POTCAR is not. I believe this is caused by #943, which removed ordering POTCARs. This is a really horrible silent failure and definitely feels like something that should get catched by unittests. As far as I can tell every calculation that has a not alphabetically ordered structure done using pyiron with VASP since than is incorrect.

EDIT: tagging a few of you since this seems somewhat urgent @jan-janssen @pmrv @ligerzero-ai @liamhuber

ligerzero-ai commented 1 year ago

Hi, I’ll take a look today. Sorry about the inconvenience!

pmrv commented 1 year ago

I've tried to quickly reproduce it with the code below, there it seems that both POTCAR/POSCAR are still alphabetically sorted. Can it be an issue that the sorting back is not working?

from pyiron import Project

pr = Project('VASP')

alb = pr.create.structure.bulk('Al', a=2, cubic=True)

alb.get_species_symbols()

alb.get_chemical_elements()

alb.species

alb[1] = 'B'

alb.get_species_symbols()

alb.get_chemical_elements()

alb.species

bal = pr.create.structure.bulk('B', crystalstructure='fcc', a=2, cubic=True)

bal.get_species_symbols()

bal.get_chemical_elements()

bal.species

bal[1] = 'Al'

bal.get_species_symbols()

bal.get_chemical_elements()

bal.species

jalb = pr.create.job.Vasp('alb')
jbal = pr.create.job.Vasp('bal')

jalb.structure = alb
jbal.structure = bal

jalb._create_working_directory()

jalb.write_input()

jbal._create_working_directory()

jbal.write_input()

jalb['POSCAR']

jbal['POSCAR']

(copied from my notebook just now, but it should make sense when you paste it back.)

Leimeroth commented 1 year ago

Your code perfectly shows the problem @pmrv. Have a look at the written POTCAR and POSCAR files for the job"bal". The POSCAR is written as Al B, while the POTCAR writes PAW_PBE B PAW_PBE Al PAW_PBE B

Leimeroth commented 1 year ago

The problem is that get_species_symbols, .species etc. are still ordered, but the actual POTCAR is not

Leimeroth commented 1 year ago

For now I will merge #989 to make sure that pyiron is usable with VASP at all. I think the goal was to allow POSCARs in arbitrary orders. However, that change also requires a rewrite of the write_poscar function.

pmrv commented 1 year ago

Your code perfectly shows the problem @pmrv. Have a look at the written POTCAR and POSCAR files for the job"bal". The POSCAR is written as Al B, while the POTCAR writes PAW_PBE B PAW_PBE Al PAW_PBE B

So, for me both the POTCAR/POSCAR come out in the order Al, B for both jobs.

> jalb['POSCAR']
['Poscar file generated with pyiron\n',
 '1.0\n',
 '2.000000000000000 0.000000000000000 0.000000000000000\n',
 '0.000000000000000 2.000000000000000 0.000000000000000\n',
 '0.000000000000000 0.000000000000000 2.000000000000000\n',
 'Al B\n',
 '3 1\n',
 'Cartesian\n',
 '0.000000000000000 0.000000000000000 0.000000000000000\n',
 '1.000000000000000 0.000000000000000 1.000000000000000\n',
 '1.000000000000000 1.000000000000000 0.000000000000000\n',
 '0.000000000000000 1.000000000000000 1.000000000000000\n']

> jbal['POSCAR']
jbal['POSCAR']

['Poscar file generated with pyiron\n',
 '1.0\n',
 '2.000000000000000 0.000000000000000 0.000000000000000\n',
 '0.000000000000000 2.000000000000000 0.000000000000000\n',
 '0.000000000000000 0.000000000000000 2.000000000000000\n',
 'Al B\n',
 '1 3\n',
 'Cartesian\n',
 '0.000000000000000 1.000000000000000 1.000000000000000\n',
 '0.000000000000000 0.000000000000000 0.000000000000000\n',
 '1.000000000000000 0.000000000000000 1.000000000000000\n',
 '1.000000000000000 1.000000000000000 0.000000000000000\n']

> [l for l in jbal['POTCAR'] if 'TITEL' in l]
['   TITEL  = PAW_PBE Al 04Jan2001\n', '   TITEL  = PAW_PBE B 06Sep2000\n']

> [l for l in jalb['POTCAR'] if 'TITEL' in l]
['   TITEL  = PAW_PBE Al 04Jan2001\n', '   TITEL  = PAW_PBE B 06Sep2000\n']

When I diff the POTCARs from both jobs, they are equal. I also don't see the three elements that you mentioned. I'm checking right now if the bug only became active in a different version or so.

pmrv commented 1 year ago

Ok, I can reproduce now. Version 0.2.62 doesn't show the bug yet and the reverted main also not.

pmrv commented 1 year ago

FWIW, jobs can be checked if they have messed up ordering with

def check_affected(job):
    """Returns True if POTCAR/POSCAR element orderings are not consistent."""
    potcar_order = [l.strip().split()[3] for l in job['POTCAR'] if 'TITEL' in l]
    poscar_order = job['POSCAR'][5].strip().split()
    for s, t in zip(potcar_order, poscar_order):
        if s != t:
            return True
    return False