Skip to content

Commit 093f900

Browse files
committed
enh: enabled writing without selective dynamics
Signed-off-by: Nick Papior <[email protected]>
1 parent 2141819 commit 093f900

File tree

2 files changed

+39
-39
lines changed

2 files changed

+39
-39
lines changed

sisl/io/vasp/car.py

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

2525
@sile_fh_open()
26-
def write_geometry(self, geometry, dynamic=True):
26+
def write_geometry(self, geometry, dynamic=None):
2727
r""" Writes the geometry to the contained file
2828
2929
Parameters
3030
----------
3131
geometry : Geometry
3232
geometry to be written to the file
33-
dynamic : bool or list, optional
33+
dynamic : None, bool or list, optional
3434
define which atoms are dynamic in the VASP run (default is True,
35-
which means all atoms are dynamic)
35+
which means all atoms are dynamic).
36+
If None, the resulting file will not contain any dynamic flags
3637
3738
Examples
3839
--------
3940
>>> car = carSileVASP('POSCAR', 'w')
4041
>>> geom = geom.graphene()
42+
>>> geom.write(car) # regular car without Selective Dynamics
4143
>>> geom.write(car, dynamic=False) # fix all atoms
4244
>>> geom.write(car, dynamic=[False, (True, False, True)]) # fix 1st and y coordinate of 2nd
4345
"""
@@ -52,10 +54,8 @@ def write_geometry(self, geometry, dynamic=True):
5254

5355
# Write unit-cell
5456
fmt = (' ' + '{:18.9f}' * 3) + '\n'
55-
tmp = np.zeros([3], np.float64)
5657
for i in range(3):
57-
tmp[:3] = geometry.cell[i, :]
58-
self._write(fmt.format(*tmp))
58+
self._write(fmt.format(*geometry.cell[i]))
5959

6060
# Figure out how many species
6161
pt = PeriodicTable()
@@ -78,19 +78,24 @@ def write_geometry(self, geometry, dynamic=True):
7878
self._write(fmt.format(*s))
7979
fmt = ' {:d}' * len(d) + '\n'
8080
self._write(fmt.format(*d))
81-
self._write('Selective dynamics\n')
81+
if dynamic is None:
82+
# We write in direct mode
83+
dynamic = [None] * len(geometry)
84+
def todyn(fix):
85+
return '\n'
86+
else:
87+
self._write('Selective dynamics\n')
88+
b2s = {True: 'T', False: 'F'}
89+
def todyn(fix):
90+
if isinstance(fix, bool):
91+
return ' {0} {0} {0}\n'.format(b2s[fix])
92+
return ' {} {} {}\n'.format(b2s[fix[0]], b2s[fix[1]], b2s[fix[2]])
8293
self._write('Cartesian\n')
8394

8495
if isinstance(dynamic, bool):
8596
dynamic = [dynamic] * len(geometry)
8697

87-
b2s = {True: 'T', False: 'F'}
88-
def todyn(fix):
89-
if isinstance(fix, bool):
90-
return '{0} {0} {0}\n'.format(b2s[fix])
91-
return '{} {} {}\n'.format(b2s[fix[0]], b2s[fix[1]], b2s[fix[2]])
92-
93-
fmt = '{:18.9f} ' * 3
98+
fmt = '{:18.9f}' * 3
9499
for ia in geometry:
95100
self._write(fmt.format(*geometry.xyz[ia, :]) + todyn(dynamic[ia]))
96101

@@ -115,12 +120,13 @@ def read_supercell(self):
115120
def read_geometry(self, ret_dynamic=False):
116121
r""" Returns Geometry object from the CONTCAR/POSCAR file
117122
118-
Possibly also return the dynamics (if present)
123+
Possibly also return the dynamics (if present).
119124
120125
Parameters
121126
----------
122127
ret_dynamic : bool, optional
123-
also read selective dynamics (if present), if not, a list of True will be returned
128+
also return selective dynamics (if present), if not, None will
129+
be returned.
124130
"""
125131
sc = self.read_supercell()
126132

@@ -148,25 +154,26 @@ def read_geometry(self, ret_dynamic=False):
148154
for spec, nsp in zip(species, species_count)
149155
for i in range(nsp)]
150156

151-
# Read whether this is selective or direct
152-
# Currently direct is not used
157+
# Number of atoms
158+
na = len(atom)
159+
160+
# check whether this is Selective Dynamics
153161
opt = self.readline()
154-
dynamics = False
155162
if opt[0] in 'Ss':
156163
dynamics = True
164+
# pre-create the dynamic list
165+
dynamic = np.empty([na, 3], dtype=np.bool_)
157166
opt = self.readline()
167+
else:
168+
dynamics = False
169+
dynamic = None
158170

159171
# Check whether this is in fractional or direct
160-
# coordinates
172+
# coordinates (Direct == fractional)
161173
cart = False
162174
if opt[0] in 'CcKk':
163175
cart = True
164176

165-
# Number of atoms
166-
na = len(atom)
167-
# pre-create the dynamic list
168-
dynamic = [[False] * 3] * na
169-
170177
xyz = _a.emptyd([na, 3])
171178
for ia in range(na):
172179
line = self.readline().split()
@@ -183,7 +190,7 @@ def read_geometry(self, ret_dynamic=False):
183190
# The POT/CONT-CAR does not contain information on the atomic species
184191
geom = Geometry(xyz=xyz, atom=atom, sc=sc)
185192
if ret_dynamic:
186-
return geom, np.array(dynamic, dtype=np.bool_)
193+
return geom, dynamic
187194
return geom
188195

189196
def ArgumentParser(self, p=None, *args, **kwargs):

sisl/io/vasp/tests/test_car.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,6 @@ def test_geometry_car_allsame(sisl_tmp):
3939
assert carSileVASP(f).read_geometry() == geom
4040

4141

42-
def test_geometry_car_allsame(sisl_tmp):
43-
f = sisl_tmp('test_read_write.POSCAR', _dir)
44-
45-
atoms = Atom[1]
46-
xyz = np.random.rand(10, 3)
47-
geom = Geometry(xyz, atoms, 100)
48-
49-
geom.write(carSileVASP(f, 'w'))
50-
51-
assert carSileVASP(f).read_geometry() == geom
52-
53-
5442
def test_geometry_car_dynamic(sisl_tmp):
5543
f = sisl_tmp('test_dynamic.POSCAR', _dir)
5644

@@ -60,14 +48,19 @@ def test_geometry_car_dynamic(sisl_tmp):
6048

6149
read = carSileVASP(f)
6250

51+
# no dynamic (direct geometry)
6352
geom.write(carSileVASP(f, 'w'))
6453
g, dyn = read.read_geometry(ret_dynamic=True)
65-
assert np.all(dyn)
54+
assert dyn is None
6655

6756
geom.write(carSileVASP(f, 'w'), dynamic=False)
6857
g, dyn = read.read_geometry(ret_dynamic=True)
6958
assert not np.any(dyn)
7059

60+
geom.write(carSileVASP(f, 'w'), dynamic=True)
61+
g, dyn = read.read_geometry(ret_dynamic=True)
62+
assert np.all(dyn)
63+
7164
dynamic = [False] * len(geom)
7265
dynamic[0] = [True, False, True]
7366
geom.write(carSileVASP(f, 'w'), dynamic=dynamic)

0 commit comments

Comments
 (0)