-
Notifications
You must be signed in to change notification settings - Fork 887
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle invalid selective dynamics info in POSCAR #3539
Handle invalid selective dynamics info in POSCAR #3539
Conversation
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
We implemented this warning after talking to @rnels12 and @QuantumChemist . If this happens, the POTCARs are not read correctly and the results you get are wrong. Of course, you can implement a fix but I am not sure what you are intending to do: generating POTCARs without the line? |
Btw, many of the pymatgen implementations have been used for the above LOBSTER paper. 🙃 |
Side note: we should test if the latest LOBSTER version fixes this. If so, I would not spend time on this fix. |
This comment was marked as resolved.
This comment was marked as resolved.
@naik-aakash might also be able to give further input and could probably check if the latest LOBSTER fixes the issue.
Btw, We work on a JOSS at the moment. (Basically now would be a perfect time for a contribution) |
And, yes, the fix mentioned above is essentially the fix that we implemented manually. |
Hi @DanielYang59, I can test if the latest LOBSTER version fixes this issue and update you here asap |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
I don't have time to implement a fix. Sorry. Let's just see if the latest LOBSTER resolves it. Thanks in any case. |
This comment was marked as off-topic.
This comment was marked as off-topic.
with pytest.warns(BadIncarWarning) as record: | ||
incar = Incar( | ||
{ | ||
"ADDGRID": True, | ||
"ALGO": "Normal", | ||
"AMIN": 0.01, | ||
"AMIX": 0.2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify the test INCAR a bit, keep only one entry of each data type.
False, | ||
"f", | ||
], # Should be a list of bools | ||
"M_CONSTR": [True, 1, "string"], # Should be a list of real numbers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type checkings for the values of "LATTICE_CONSTRAINTS" and "M_CONSTR" were not implemented, as there isn't definition for the type of list elements in incar_parameters.json
(such as List[bool]
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know that it's possible to do more careful type checking the way with the current framework (e.g., LATTICE_CONSTRAINTS : Sequence[bool, bool, bool]
) but that's good to note.
assert "PHON_TLIST: is_a_str is not a list" in record[4].message.args | ||
assert record[0].message.args[0] == "Cannot find NBAND in the list of INCAR tags" | ||
assert record[1].message.args[0] == "METAGGA: Cannot find SCAM in the list of values" | ||
assert record[2].message.args[0] == "EDIFF: (5+1j) is not a float" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning for "EDIFF": 5 + 1j, # value should be a float
was missing
@esoteric-ephemera if you have time, could you take a quick look at why def test_is_valid(self):
> assert self.psingle_Fe.is_valid
E AssertionError: assert False
E + where False = PotcarSingle(symbol='Fe', functional='PBE', TITEL='PAW_PBE Fe 06Sep2000', VRHFIN='Fe: d7 s1', n_valence_elec=8).is_valid |
I noticed another test is failing too @esoteric-ephemera : ============================================================ FAILURES =============================================================
_________________________________________________ TestPotcarSingle.test_is_valid __________________________________________________
self = <tests.io.vasp.test_inputs.TestPotcarSingle testMethod=test_is_valid>
def test_is_valid(self):
> assert self.psingle_Fe.is_valid
E AssertionError: assert False
E + where False = PotcarSingle(symbol='Fe', functional='PBE', TITEL='PAW_PBE Fe 06Sep2000', VRHFIN='Fe: d7 s1', n_valence_elec=8).is_valid
E + where PotcarSingle(symbol='Fe', functional='PBE', TITEL='PAW_PBE Fe 06Sep2000', VRHFIN='Fe: d7 s1', n_valence_elec=8) = <tests.io.vasp.test_inputs.TestPotcarSingle testMethod=test_is_valid>.psingle_Fe
tests\io\vasp\test_inputs.py:1165: AssertionError
___________________________________ TestPotcarSingle.test_multi_potcar_with_and_without_sha256 ____________________________________
self = <tests.io.vasp.test_inputs.TestPotcarSingle testMethod=test_multi_potcar_with_and_without_sha256>
def test_multi_potcar_with_and_without_sha256(self):
filename = f"{FAKE_POTCAR_DIR}/POT_GGA_PAW_PBE_54/POTCAR.Fe_O.gz"
potcars = Potcar.from_file(filename)
# Still need to test the if POTCAR can be read.
# No longer testing for hashes
for psingle in potcars:
if psingle.hash_sha256_from_file:
assert psingle.sha256_computed_file_hash == psingle.hash_sha256_from_file
else:
> assert psingle.is_valid
E AssertionError: assert False
E + where False = PotcarSingle(symbol='Fe_pv', functional='PBE', TITEL='PAW_PBE Fe_pv 02Aug2007', VRHFIN='Fe: 3pd7s1', n_valence_elec=14).is_valid
tests\io\vasp\test_inputs.py:1218: AssertionError
------------------------------------------------------ Captured stderr call -------------------------------------------------------
D:\GitHub\pymatgen\pymatgen\io\vasp\inputs.py:1784: UnknownPotcarWarning: POTCAR data with symbol Fe_pv is not known to pymatgen. Your POTCAR may be corrupted or pymatgen's POTCAR database is incomplete.
warnings.warn(
D:\GitHub\pymatgen\pymatgen\io\vasp\inputs.py:1784: UnknownPotcarWarning: POTCAR data with symbol O is not known to pymatgen. Your POTCAR may be corrupted or pymatgen's POTCAR database is incomplete.
warnings.warn( But I think we should not be cramming too many topics into a single PR? |
…] | Any", variable has type "tuple[Any, ...]") [assignment]'"
@@ -321,7 +321,7 @@ def from_str(cls, data, default_names=None, read_velocities=True) -> Poscar: | |||
raise ValueError("Empty POSCAR") | |||
|
|||
# Parse positions | |||
lines = tuple(clean_lines(chunks[0].split("\n"), remove_empty_lines=False)) | |||
lines = list(clean_lines(chunks[0].split("\n"), remove_empty_lines=False)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed the mypy
type annotation error: pymatgen\io\vasp\inputs.py:481: error: Incompatible types in assignment (expression has type "list[str]", variable has type "tuple[Any, ...]") [assignment]
@@ -312,7 +312,7 @@ def from_str(cls, data, default_names=None, read_velocities=True) -> Poscar: | |||
Poscar object. | |||
""" | |||
# "^\s*$" doesn't match lines with no whitespace | |||
chunks = re.split(r"\n\s*\n", data.rstrip(), flags=re.MULTILINE) | |||
chunks: list[str] = re.split(r"\n\s*\n", data.rstrip(), flags=re.MULTILINE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed another mypy
error: pymatgen\io\vasp\inputs.py:481: error: Incompatible types in assignment (expression has type "list[str] | Any", variable has type "tuple[Any, ...]") [assignment]
There is one last pymatgen/pymatgen/io/vasp/inputs.py Lines 434 to 472 in 12ab947
I got: pymatgen\io\vasp\inputs.py:468: error: Item "None" of "list[Any] | None" has no attribute "append" [union-attr]
pymatgen\io\vasp\inputs.py:474: error: Item "None" of "list[Any] | None" has no attribute "append" [union-attr]
pymatgen\io\vasp\inputs.py:496: error: Item "None" of "list[Any] | None" has no attribute "append" [union-attr] A simple example to reproduce this type annotation error: met_condition = True
if met_condition:
foo = []
for i in range(3):
foo.append(i)
else:
foo = None I got If I change it to: from typing import Union
met_condition = True
if met_condition:
foo: Union[list, None] = []
for i in range(3):
foo.append(i)
else:
foo = None then the error message would become: Do you have any suggestions? @janosh Thanks! |
instead of setting to - if velocities is not None:
+ if velocities: and likewise for the other variables |
Thanks a lot @janosh. Updated and confirmed to fix the |
@DanielYang59, see my comment above, these tests pass outside this PR. They're failing because of changes made by this PR that are easy to fix - opened a PR on your fork to fix it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks a lot @DanielYang59! this is much appreciated. 👍
Thanks a lot for reviewing @janosh and everyone for giving me suggestions @esoteric-ephemera @JaGeo @rkingsbury |
Summary
Major changes:
from_str
method when invalid selective dynamics info would found in POSCAR, to resolve POSCAR is ignoring selective dynamics #3008.check_params
method.test_check_params
oftests/io/test_inputs.py
.Minor changes:
from_file
Analysis of "Invalid selective dynamics info in POSCAR"
In the second POSCAR provided in #3008:
Which interprets to:
Seems intended by
pymatgen
(anything other than "T" would be treated "F"):pymatgen/pymatgen/io/vasp/inputs.py
Lines 430 to 431 in 8aa1cf8
I looked into the
VASP
source codeposcar.F (version 5.4.4.pl2)
line385
to392
(I cannot paste the code here for copyright reasons), which defines the parsing mechanism of POSCAR byVASP
. And it seemsVASP
reads the 3-5 (0-indexed) elements of the position line as selective dynamics, which deems such POSCAR invalid.Selective dynamics
tag dropped when all DOFs relaxedRegarding the 1st POSCAR in the original issue. There is:
pymatgen/pymatgen/io/vasp/inputs.py
Lines 121 to 124 in 8aa1cf8
So selective dynamics array would only be kept when there exists at least one degree of freedom (DOF) frozen. And the user used an example POSCAR where all DOFs are relaxed.
Should we issue a warning to avoid confusion? I think it's unnecessary (but why would people relax all DOFs and toggle selective dynamics at the same time in the first place).
TODO list