Open bocklund opened 2 years ago
Hi @bocklund,
I think this can be resolved by using the Structure.add_site_property()
function, which is the preferred method of adding magnetic moments (and other site properties, like selective dynamics). I personally would recommend against trying to "manually" specify site properties, as they get stripped the moment you modify the structure.
Here is your patched example:
from pymatgen.core import Structure
from pymatgen.io.vasp.sets import DictSet
struct = Structure.from_str("""Cr2
1.0
2.849623 0.000000 0.000000
0.000000 2.849623 0.000000
0.000000 0.000000 2.849623
Cr
2
direct
0.000000 0.000000 0.000000 Cr
0.500000 0.500000 0.500000 Cr""", fmt="POSCAR")
# See here!
struct.add_site_property("magmom",[-5,5])
assert all(hasattr(site, "magmom") for site in struct.sites) # passes
assert all(hasattr(site, "magmom") for site in struct.get_sorted_structure().sites) # passes
from pymatgen.io.vasp.sets import MPStaticSet
assert all(hasattr(site, "magmom") for site in MPStaticSet(struct).structure.sites) # passes
assert all(hasattr(site, "magmom") for site in MPStaticSet(struct, sort_structure=False).structure.sites) # passes
This also confused me when I started out. I think that means we should make the documentation clearer.
Thank you @arosen93, understood. add_site_property
seems to be the solution. Your PR in #2342 is definitely helpful, but I didn't know that the add_site_property
method existed and so the improved docs/examples may not have helped me in this case.
My thought process was that the code around the exception that I got in DictSet
accessed magmom
as an attribute, so the principle of least surprise would suggest that I can interact with site properties as I would attributes. It seems like there's some asymmetry in that Site.__getattr__
is overridden to access Site.properties
, but there's not a symmetric Site.__setattr__
method that sets Site.properties
.
I think this is a reasonable point. I would like to see the ability to do as you suggested because it is, arguably, the most intuitive route. I won't be able to make PR for this one, but perhaps you or someone else can improve upon that functionality.
@mkhorton -- I think this can be closed, but it's worth considering if a separate issue should be opened to address the pain point that @bocklund brought up.
Thanks for the reminder @arosen93, and thanks @bocklund for bringing this up -- it's true, I actually have not used the .magmom
attribute myself and agree this looks confusing.
It seems like there's some asymmetry in that Site.getattr is overridden to access Site.properties, but there's not a symmetric Site.setattr method that sets Site.properties.
This seems like the fundamental cause. I would not close this issue until this has been addressed.
Describe the bug The
Structure.get_sorted_structure
method seems to clobbermagmom
attributes. As a consequence, allDictSet
subclasses don't allow setting magnetic moments using site properties by default, since the default keyword argumentsort_structure=True
calls this method.To Reproduce
Expected behavior
These two lines should produce (effectively) the same INCAR with a correctly set MAGMOM tag: