Skip to content

Commit 7e34a00

Browse files
committed
enh: enabled sorting of geometries before writing dcc-2019-jun
Also added that as a staticmethod to vasp objects. Signed-off-by: Nick Papior <[email protected]>
1 parent 093f900 commit 7e34a00

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

sisl/io/vasp/car.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def _setup(self, *args, **kwargs):
2323
self._scale = 1.
2424

2525
@sile_fh_open()
26-
def write_geometry(self, geometry, dynamic=None):
26+
def write_geometry(self, geometry, dynamic=None, sort=False):
2727
r""" Writes the geometry to the contained file
2828
2929
Parameters
@@ -34,6 +34,9 @@ def write_geometry(self, geometry, dynamic=None):
3434
define which atoms are dynamic in the VASP run (default is True,
3535
which means all atoms are dynamic).
3636
If None, the resulting file will not contain any dynamic flags
37+
sort : bool, optional
38+
before writing `geometry` first re-order species to
39+
have species in consecutive blocks (see `geometry_sort`)
3740
3841
Examples
3942
--------
@@ -42,7 +45,14 @@ def write_geometry(self, geometry, dynamic=None):
4245
>>> geom.write(car) # regular car without Selective Dynamics
4346
>>> geom.write(car, dynamic=False) # fix all atoms
4447
>>> geom.write(car, dynamic=[False, (True, False, True)]) # fix 1st and y coordinate of 2nd
48+
49+
See Also
50+
--------
51+
geometry_sort: method used to sort atoms in geometry
4552
"""
53+
if sort:
54+
geometry = self.geometry_sort(geometry)
55+
4656
# Check that we can write to the file
4757
sile_raise_write(self)
4858

sisl/io/vasp/sile.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,58 @@
11
"""
22
Define a common VASP Sile
33
"""
4+
import sisl._array as _a
45

56
from ..sile import Sile, SileCDF, SileBin
67

78
__all__ = ['SileVASP', 'SileCDFVASP', 'SileBinVASP']
89

910

11+
def _geometry_sort(geometry):
12+
r""" Order atoms in geometry according to species such that all of one specie is consecutive
13+
14+
When creating VASP input files (`poscarSileVASP` for instance) the equivalent
15+
``POTCAR`` file needs to contain the pseudos for each specie as they are provided
16+
in blocks.
17+
18+
I.e. for a geometry like this:
19+
.. code::
20+
21+
[Atom(6), Atom(4), Atom(6)]
22+
23+
the resulting ``POTCAR`` needs to contain the pseudo for Carbon twice.
24+
25+
This method will re-order atoms according to the species"
26+
27+
Parameters
28+
----------
29+
geometry : Geometry
30+
geometry to be re-ordered
31+
32+
Returns
33+
-------
34+
geometry: reordered geometry
35+
"""
36+
na = len(geometry)
37+
idx = _a.emptyi(na)
38+
39+
ia = 0
40+
for _, idx_s in geometry.atoms.iter(species=True):
41+
idx[ia:ia + len(idx_s)] = idx_s
42+
ia += len(idx_s)
43+
44+
assert ia == na
45+
46+
return geometry.sub(idx)
47+
48+
1049
class SileVASP(Sile):
11-
pass
50+
geometry_sort = staticmethod(_geometry_sort)
1251

1352

1453
class SileCDFVASP(SileCDF):
15-
pass
54+
geometry_sort = staticmethod(_geometry_sort)
1655

1756

1857
class SileBinVASP(SileBin):
19-
pass
58+
geometry_sort = staticmethod(_geometry_sort)

sisl/io/vasp/tests/test_car.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ def test_geometry_car_mixed(sisl_tmp):
2727
assert carSileVASP(f).read_geometry() == geom
2828

2929

30+
def test_geometry_car_sort(sisl_tmp):
31+
f = sisl_tmp('test_sort.POSCAR', _dir)
32+
33+
atoms = [Atom[1],
34+
Atom[2],
35+
Atom[2],
36+
Atom[1],
37+
Atom[1],
38+
Atom[2],
39+
Atom[3]]
40+
xyz = np.random.rand(len(atoms), 3)
41+
geom = Geometry(xyz, atoms, 100)
42+
43+
geom.write(carSileVASP(f, 'w'), sort=True)
44+
45+
assert carSileVASP(f).read_geometry() != geom
46+
geom = carSileVASP(f).geometry_sort(geom)
47+
assert carSileVASP(f).read_geometry() == geom
48+
49+
3050
def test_geometry_car_allsame(sisl_tmp):
3151
f = sisl_tmp('test_read_write.POSCAR', _dir)
3252

0 commit comments

Comments
 (0)