Skip to content

Commit d58e1be

Browse files
committed
more flexibility and prefixes
1 parent ad7f47d commit d58e1be

File tree

6 files changed

+61
-16
lines changed

6 files changed

+61
-16
lines changed

asimtools/scripts/atom_relax.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
optimizers
55
'''
66

7-
from typing import Dict, Tuple
7+
from typing import Dict, Tuple, Optional
88
import numpy as np
99
import ase.optimize
1010
from ase.io.trajectory import Trajectory
@@ -17,6 +17,7 @@ def atom_relax(
1717
optimizer: str = 'GPMin', #GPMin is fastest according to ASE docs
1818
properties: Tuple[str] = ('energy', 'forces'),
1919
fmax: float = 0.02,
20+
prefix: Optional[str] = None,
2021
) -> Dict:
2122
"""Relaxes the given tomic structure using ASE's built-in structure
2223
optimizers
@@ -39,7 +40,12 @@ def atom_relax(
3940
atoms.set_calculator(calc)
4041
logger = get_logger()
4142

42-
traj_file = 'atom_relax.traj'
43+
if prefix is not None:
44+
prefix = prefix + '_'
45+
else:
46+
prefix = ''
47+
48+
traj_file = prefix + 'atom_relax.traj'
4349
dyn = getattr(ase.optimize, optimizer)(atoms)
4450
traj = Trajectory(
4551
traj_file,
@@ -54,7 +60,7 @@ def atom_relax(
5460
logger.error('Failed to relax atoms')
5561
raise
5662

57-
image_file = 'image_output.xyz'
63+
image_file = prefix + 'image_output.xyz'
5864
atoms.write(image_file, format='extxyz')
5965

6066
energy = float(atoms.get_potential_energy())

asimtools/scripts/cell_relax.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
def cell_relax(
2020
calc_id: str,
2121
image: Dict,
22-
prefix: str = '',
2322
optimizer: str = 'BFGS',
24-
smax: float = 0.002,
23+
fmax: float = 0.002,
2524
mask: Optional[Sequence] = None,
25+
prefix: Optional[str] = None,
2626
) -> Dict:
2727
"""Relax cell using ASE Optimizer
2828
@@ -34,8 +34,8 @@ def cell_relax(
3434
:type prefix: str, optional
3535
:param optimizer: Optimizer class to use from ase.optimize, defaults to 'BFGS'
3636
:type optimizer: str, optional
37-
:param smax: Maximum stress in eV/$\AA^3$, defaults to 0.002
38-
:type smax: float, optional
37+
:param fmax: Maximum stress in eV/$\AA^3$, defaults to 0.002
38+
:type fmax: float, optional
3939
:param mask: Mask to constrain cell deformation while relaxing, defaults to None
4040
:type mask: Optional[Sequence], optional
4141
:return: Dictionary of results including, final energy, stress and output files
@@ -45,6 +45,11 @@ def cell_relax(
4545
atoms = get_atoms(**image)
4646
atoms.set_calculator(calc)
4747

48+
if prefix is not None:
49+
prefix = prefix + '_'
50+
else:
51+
prefix = ''
52+
4853
traj_file = join_names([prefix, 'cell_relax.traj'])
4954
sf = StrainFilter(atoms, mask=mask)
5055
dyn = getattr(ase.optimize, optimizer)(sf)
@@ -56,7 +61,7 @@ def cell_relax(
5661
)
5762
dyn.attach(traj)
5863
try:
59-
dyn.run(fmax=smax)
64+
dyn.run(fmax=fmax)
6065
except Exception:
6166
print('Failed to optimize atoms')
6267
raise
@@ -65,11 +70,11 @@ def cell_relax(
6570
atoms.write(image_file, format='extxyz')
6671

6772
energy = float(atoms.get_potential_energy())
68-
final_smax = float(atoms.get_stress().max())
73+
final_fmax = float(atoms.get_stress().max())
6974

7075
results = {
7176
'energy': energy,
72-
'final_smax': final_smax,
77+
'final_fmax': final_fmax,
7378
'files':{
7479
'image': image_file,
7580
'traj': traj_file,

asimtools/scripts/parity.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def parity(
199199
)
200200

201201
rmse_val = rmse(res[prop]['ref'], res[prop]['pred'])
202-
results[f'{prop}_rmse'] = rmse_val
202+
results[f'{prop}_rmse'] = float(rmse_val)
203203

204204
_, ax = plt.subplots()
205205
lims = np.array(get_axis_lims(res[prop]['ref'], res[prop]['pred']))

asimtools/scripts/singlepoint.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
'''
77

8-
from typing import Tuple, Dict
8+
from typing import Tuple, Dict, Optional
99
import logging
1010
from asimtools.calculators import load_calc
1111
from asimtools.utils import (
@@ -16,6 +16,7 @@ def singlepoint(
1616
calc_id: str,
1717
image: Dict,
1818
properties: Tuple[str] = ('energy', 'forces'),
19+
prefix: Optional[str] = None,
1920
) -> Dict:
2021
"""Evaluates the properties of a single image, currently implemented
2122
properties are energy, forces and stress
@@ -33,6 +34,11 @@ def singlepoint(
3334
atoms = get_atoms(**image)
3435
atoms.set_calculator(calc)
3536

37+
if prefix is not None:
38+
prefix = prefix + '_'
39+
else:
40+
prefix = ''
41+
3642
if 'energy' in properties:
3743
try:
3844
energy = atoms.get_potential_energy()
@@ -57,7 +63,7 @@ def singlepoint(
5763
logging.error('Failed to calculate stress')
5864
raise
5965

60-
image_file = 'image_output.xyz'
66+
image_file = prefix + 'image_output.xyz'
6167
atoms.write(image_file, format='extxyz')
6268

6369
results = {

asimtools/scripts/surface_energies/surface_energies.py

+17
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from pymatgen.core.surface import generate_all_slabs
1616
from pymatgen.io.ase import AseAtomsAdaptor as AAA
1717
from asimtools.calculators import load_calc
18+
from asimtools.scripts.atom_relax import atom_relax
1819
from asimtools.utils import (
1920
get_atoms,
2021
)
@@ -40,6 +41,7 @@ def surface_energies(
4041
image: Dict,
4142
calc_id: str,
4243
millers: Union[str,Sequence] = 'all',
44+
atom_relax_args: Optional[Dict] = None,
4345
generate_all_slabs_args: Optional[Dict] = None,
4446
) -> Dict:
4547
'''
@@ -51,6 +53,9 @@ def surface_energies(
5153
bulk = get_atoms(**image)
5254
bulk.set_calculator(calc)
5355

56+
if atom_relax_args is None:
57+
atom_relax_args = {}
58+
5459
default_pymatgen_kwargs = {
5560
'max_index': 3,
5661
'min_slab_size': 14,
@@ -83,6 +88,18 @@ def surface_energies(
8388
atoms = AAA.get_atoms(big_slab)
8489
atoms.write(f'{miller}.xyz')
8590

91+
relax_results = atom_relax(
92+
calc_id=calc_id,
93+
image={'atoms': atoms},
94+
optimizer=atom_relax_args.get('optimizer', 'BFGS'),
95+
properties=('energy','forces'),
96+
fmax=atom_relax_args.get('fmax', 0.02),
97+
prefix=f'{miller}_relaxed'
98+
)
99+
atoms = get_atoms(
100+
image_file = relax_results.get('files', {}).get('image')
101+
)
102+
86103
assert np.allclose(atoms.pbc, (True, True, True)), \
87104
f'Check pbcs for {miller}: {atoms.pbc}'
88105
assert atoms.cell[2][2] > pymargs['min_vacuum_size'] + \

asimtools/utils.py

+14-3
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def get_images(
204204
patterns: List[str] = None,
205205
images: Iterable[Atoms] = None,
206206
index: Union[str, int] = ':',
207-
skip_failed: bool = True,
207+
skip_failed: bool = False,
208208
**kwargs
209209
) -> List[Atoms]:
210210
"""Return a list of atoms objects based on the input arguments. Options \
@@ -239,6 +239,7 @@ def get_images(
239239
"Please specify file, pattern or iterable"
240240

241241
if image_file is not None:
242+
image_file = Path(image_file).resolve()
242243
images = read(image_file, index=index, **kwargs)
243244
if not isinstance(images, list):
244245
images = [images]
@@ -249,11 +250,21 @@ def get_images(
249250

250251
images = []
251252
for image_file in image_files:
253+
image_file = Path(image_file).resolve()
252254
try:
253-
new_images = read(image_file, index=index, **kwargs)
255+
new_images = read(
256+
image_file,
257+
index=index,
258+
**kwargs
259+
)
254260
except Exception as exc:
255261
if not skip_failed:
256-
raise IOError(f"Failed to read {image_file}") from exc
262+
raise IOError(
263+
f"Failed to read {image_file} from {os.getcwd()}"
264+
) from exc
265+
else:
266+
new_images = []
267+
257268
# Output of read can either be list of atoms or Atoms, depending on index
258269
if not isinstance(new_images, list):
259270
new_images = [new_images]

0 commit comments

Comments
 (0)