CederGroupHub / smol

Statistical Mechanics on Lattices
https://cedergrouphub.github.io/smol/
Other
62 stars 14 forks source link

[Bug]: Fail to parse the element or species on prim cell #475

Open ghalibalfaza opened 2 months ago

ghalibalfaza commented 2 months ago

Email (Optional)

ghalib.alfaza@gmail.com

Version

0.5.3

Which OS(es) are you using?

What happened?

I am just following the tutorial but error happened at the third steps. Any help would be greatly appreciated, thanks! Screenshot 2024-07-03 170123

Code snippet

+*In[1]:*+
[source, ipython3]
----
import numpy as np
import json
from monty.serialization import loadfn
from pymatgen.core.structure import Structure
from smol.cofe import ClusterSubspace, StructureWrangler, ClusterExpansion, RegressionData
----

+*In[2]:*+
[source, ipython3]
----
lno_prim = loadfn("C:/proj/oxide/ce/lno_prim.json")
print(lno_prim)
----

+*Out[2]:*+
----
Full Formula (Li0.5 Ni1 O2)
Reduced Formula: Li0.5Ni1O2
abc   :   2.969848   2.969848   5.143928
angles:  73.221350  73.221347  60.000002
pbc   :       True       True       True
Sites (4)
  #  SP                     a     b     c
---  ------------------  ----  ----  ----
  0  Li+:0.5             0     0     0
  1  Ni3+:0.5, Ni4+:0.5  0.5   0.5   0.5
  2  O2-                 0.75  0.75  0.75
  3  O2-                 0.25  0.25  0.25
----

+*In[3]:*+
[source, ipython3]
----
subspace = ClusterSubspace.from_cutoffs(
    lno_prim,
    cutoffs={2: 5, 3: 4.1},
    basis='sinusoid',
    supercell_size='O2-'
)
----

+*Out[3]:*+
----

    ---------------------------------------------------------------------------

    TypeError                                 Traceback (most recent call last)

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\periodic_table.py:1534, in get_el_sp(obj)
       1533 try:
    -> 1534     return DummySpecies.from_str(obj)  # type: ignore
       1535 except Exception:

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\periodic_table.py:1434, in DummySpecies.from_str(cls, species_string)
       1422 """Get a Dummy from a string representation.
       1423 
       1424 Args:
       (...)
       1432     ValueError if species_string cannot be interpreted.
       1433 """
    -> 1434 if match := re.search(r"([A-ZAa-z]*)([0-9.]*)([+\-]*)(.*)", species_string):
       1435     sym = match[1]

    File ~\AppData\Local\anaconda3\Lib\re\__init__.py:176, in search(pattern, string, flags)
        174 """Scan through string looking for a match to the pattern, returning
        175 a Match object, or None if no match was found."""
    --> 176 return _compile(pattern, flags).search(string)

    TypeError: expected string or bytes-like object, got 'SiteSpace'

    During handling of the above exception, another exception occurred:

    ValueError                                Traceback (most recent call last)

    Cell In[3], line 1
    ----> 1 subspace = ClusterSubspace.from_cutoffs(
          2     lno_prim,
          3     cutoffs={2: 5, 3: 4.1},
          4     basis='sinusoid',
          5     supercell_size='O2-'
          6 )

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\clusterspace.py:303, in ClusterSubspace.from_cutoffs(cls, structure, cutoffs, basis, orthonormal, use_concentration, supercell_matcher, site_matcher, num_threads, **matcher_kwargs)
        301 expansion_structure = Structure.from_sites(sites_to_expand)
        302 # get orbits within given cutoffs
    --> 303 orbits = cls._gen_orbits_from_cutoffs(
        304     expansion_structure, cutoffs, symops, basis, orthonormal, use_concentration
        305 )
        306 return cls(
        307     structure=structure,
        308     expansion_structure=expansion_structure,
       (...)
        314     **matcher_kwargs,
        315 )

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\clusterspace.py:1337, in ClusterSubspace._gen_orbits_from_cutoffs(exp_struct, cutoffs, symops, basis, orthonorm, use_conc)
       1334 nbits = np.array([len(b) - 1 for b in site_spaces])
       1336 # Generate singlet/point orbits
    -> 1337 orbits[1] = ClusterSubspace._gen_point_orbits(
       1338     exp_struct, site_bases, nbits, symops
       1339 )
       1341 if len(cutoffs) == 0:  # return singlets only if no cutoffs provided
       1342     return orbits

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\clusterspace.py:1373, in ClusterSubspace._gen_point_orbits(exp_struct, site_bases, nbits, symops)
       1369 pt_orbits = []
       1370 for nbit, site, sbasis in zip(nbits, exp_struct, site_bases):
       1371     # Coordinates of point terms must stay in [0, 1] to guarantee
       1372     # correct math of the following algorithm.
    -> 1373     new_orbit = Orbit(
       1374         [np.mod(site.frac_coords, 1)],
       1375         exp_struct.lattice,
       1376         [list(range(nbit))],
       1377         [sbasis],
       1378         symops,
       1379     )
       1380     if new_orbit not in pt_orbits:
       1381         pt_orbits.append(new_orbit)

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\orbit.py:106, in Orbit.__init__(self, cluster_coords, lattice, bits, site_bases, structure_symops)
        103 self._flat_corr_tensors = None
        105 # Create basecluster
    --> 106 self.base_cluster = Cluster(
        107     [site_basis.site_space for site_basis in site_bases],
        108     cluster_coords,
        109     lattice,
        110 )

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\cluster.py:60, in Cluster.__init__(self, site_spaces, frac_coords, lattice)
         58 self._centroid = centroid - shift
         59 self._frac_coords = frac_coords - shift
    ---> 60 self._sites = tuple(
         61     Site(site_space, coords)
         62     for site_space, coords in zip(
         63         site_spaces, lattice.get_cartesian_coords(frac_coords)
         64     )
         65 )
         66 self._lattice = lattice
         67 self.id = None

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\cluster.py:61, in <genexpr>(.0)
         58 self._centroid = centroid - shift
         59 self._frac_coords = frac_coords - shift
         60 self._sites = tuple(
    ---> 61     Site(site_space, coords)
         62     for site_space, coords in zip(
         63         site_spaces, lattice.get_cartesian_coords(frac_coords)
         64     )
         65 )
         66 self._lattice = lattice
         67 self.id = None

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\sites.py:66, in Site.__init__(self, species, coords, properties, label, skip_checks)
         64 if not isinstance(species, Composition):
         65     try:
    ---> 66         species = Composition({get_el_sp(species): 1})  # type: ignore[arg-type]
         67     except TypeError:
         68         species = Composition(species)

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\periodic_table.py:1536, in get_el_sp(obj)
       1534     return DummySpecies.from_str(obj)  # type: ignore
       1535 except Exception:
    -> 1536     raise ValueError(f"Can't parse Element or Species from {obj!r}")

    ValueError: Can't parse Element or Species from Li+0.5 vacA0+0.5

----

Log output

TypeError                                 Traceback (most recent call last)

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\periodic_table.py:1534, in get_el_sp(obj)
       1533 try:
    -> 1534     return DummySpecies.from_str(obj)  # type: ignore
       1535 except Exception:

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\periodic_table.py:1434, in DummySpecies.from_str(cls, species_string)
       1422 """Get a Dummy from a string representation.
       1423 
       1424 Args:
       (...)
       1432     ValueError if species_string cannot be interpreted.
       1433 """
    -> 1434 if match := re.search(r"([A-ZAa-z]*)([0-9.]*)([+\-]*)(.*)", species_string):
       1435     sym = match[1]

    File ~\AppData\Local\anaconda3\Lib\re\__init__.py:176, in search(pattern, string, flags)
        174 """Scan through string looking for a match to the pattern, returning
        175 a Match object, or None if no match was found."""
    --> 176 return _compile(pattern, flags).search(string)

    TypeError: expected string or bytes-like object, got 'SiteSpace'

    During handling of the above exception, another exception occurred:

    ValueError                                Traceback (most recent call last)

    Cell In[3], line 1
    ----> 1 subspace = ClusterSubspace.from_cutoffs(
          2     lno_prim,
          3     cutoffs={2: 5, 3: 4.1},
          4     basis='sinusoid',
          5     supercell_size='O2-'
          6 )

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\clusterspace.py:303, in ClusterSubspace.from_cutoffs(cls, structure, cutoffs, basis, orthonormal, use_concentration, supercell_matcher, site_matcher, num_threads, **matcher_kwargs)
        301 expansion_structure = Structure.from_sites(sites_to_expand)
        302 # get orbits within given cutoffs
    --> 303 orbits = cls._gen_orbits_from_cutoffs(
        304     expansion_structure, cutoffs, symops, basis, orthonormal, use_concentration
        305 )
        306 return cls(
        307     structure=structure,
        308     expansion_structure=expansion_structure,
       (...)
        314     **matcher_kwargs,
        315 )

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\clusterspace.py:1337, in ClusterSubspace._gen_orbits_from_cutoffs(exp_struct, cutoffs, symops, basis, orthonorm, use_conc)
       1334 nbits = np.array([len(b) - 1 for b in site_spaces])
       1336 # Generate singlet/point orbits
    -> 1337 orbits[1] = ClusterSubspace._gen_point_orbits(
       1338     exp_struct, site_bases, nbits, symops
       1339 )
       1341 if len(cutoffs) == 0:  # return singlets only if no cutoffs provided
       1342     return orbits

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\clusterspace.py:1373, in ClusterSubspace._gen_point_orbits(exp_struct, site_bases, nbits, symops)
       1369 pt_orbits = []
       1370 for nbit, site, sbasis in zip(nbits, exp_struct, site_bases):
       1371     # Coordinates of point terms must stay in [0, 1] to guarantee
       1372     # correct math of the following algorithm.
    -> 1373     new_orbit = Orbit(
       1374         [np.mod(site.frac_coords, 1)],
       1375         exp_struct.lattice,
       1376         [list(range(nbit))],
       1377         [sbasis],
       1378         symops,
       1379     )
       1380     if new_orbit not in pt_orbits:
       1381         pt_orbits.append(new_orbit)

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\orbit.py:106, in Orbit.__init__(self, cluster_coords, lattice, bits, site_bases, structure_symops)
        103 self._flat_corr_tensors = None
        105 # Create basecluster
    --> 106 self.base_cluster = Cluster(
        107     [site_basis.site_space for site_basis in site_bases],
        108     cluster_coords,
        109     lattice,
        110 )

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\cluster.py:60, in Cluster.__init__(self, site_spaces, frac_coords, lattice)
         58 self._centroid = centroid - shift
         59 self._frac_coords = frac_coords - shift
    ---> 60 self._sites = tuple(
         61     Site(site_space, coords)
         62     for site_space, coords in zip(
         63         site_spaces, lattice.get_cartesian_coords(frac_coords)
         64     )
         65 )
         66 self._lattice = lattice
         67 self.id = None

    File ~\AppData\Local\anaconda3\Lib\site-packages\smol\cofe\space\cluster.py:61, in <genexpr>(.0)
         58 self._centroid = centroid - shift
         59 self._frac_coords = frac_coords - shift
         60 self._sites = tuple(
    ---> 61     Site(site_space, coords)
         62     for site_space, coords in zip(
         63         site_spaces, lattice.get_cartesian_coords(frac_coords)
         64     )
         65 )
         66 self._lattice = lattice
         67 self.id = None

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\sites.py:66, in Site.__init__(self, species, coords, properties, label, skip_checks)
         64 if not isinstance(species, Composition):
         65     try:
    ---> 66         species = Composition({get_el_sp(species): 1})  # type: ignore[arg-type]
         67     except TypeError:
         68         species = Composition(species)

    File ~\AppData\Local\anaconda3\Lib\site-packages\pymatgen\core\periodic_table.py:1536, in get_el_sp(obj)
       1534     return DummySpecies.from_str(obj)  # type: ignore
       1535 except Exception:
    -> 1536     raise ValueError(f"Can't parse Element or Species from {obj!r}")

    ValueError: Can't parse Element or Species from Li+0.5 vacA0+0.5

----

Code of Conduct

lbluque commented 1 month ago

Thanks for reporting this @ghalibalfaza. I'll have a look at it.

I suspect this might be a change in pymatgen. What pymatgen version do you have installed?

qchempku2017 commented 1 month ago

Dear @ghalibalfaza , thank you for reporting this! I have received several compliants on this issue. I will have a further look when I have time. @kamronald please also take a look at your convenience if possible, thank you!

qchempku2017 commented 1 month ago

@ghalibalfaza Also as a quick work-around, you may try to install smol from git repo instead of pypi. After cloning the repo to your local machine, try "pip install -r requirements.txt", then "pip install ./"

kamronald commented 4 weeks ago

Hi @ghalibalfaza, just found a solution for this in PR #485. Sorry for the delay

qchempku2017 commented 3 weeks ago

@kamronald @ghalibalfaza Maybe we can close this issue now?