10
10
#except ImportError as exc:
11
11
# raise ImportError("ase not installed. Try `pip install ase`.") from exc
12
12
from pathlib import Path
13
- #from inspect import isclass
14
13
#from multiprocessing import Pool
15
14
#from typing import Type, Any, Optional, Union
16
15
#from enum import IntEnum
21
20
#from monty.functools import lazy_property
22
21
#from monty.json import MontyEncoder
23
22
#from monty.collections import AttrDict
24
- #from pymatgen.io.ase import AseAtomsAdaptor
25
23
#from ase import units
26
24
#from ase.atoms import Atoms
27
25
#from ase.io.trajectory import write_traj, Trajectory
28
26
from ase .io import read
29
27
#from ase.calculators.calculator import Calculator
30
28
#from ase.io.vasp import write_vasp_xdatcar, write_vasp
31
- #from ase.neb import NEB
32
29
#from ase.stress import voigt_6_to_full_3x3_strain
33
30
#from ase.calculators.calculator import PropertyNotImplementedError
34
31
from ase .calculators .singlepoint import SinglePointCalculator
38
35
from abipy .electrons .gsr import GsrFile
39
36
#from abipy.tools.iotools import workdir_with_prefix, PythonScript, yaml_safe_load_path
40
37
from abipy .tools .typing import PathLike
38
+ import abipy .flowtk .qutils as qu
41
39
#from abipy.tools.serialization import HasPickleIO
42
40
#from abipy.tools.context_managers import Timer
43
41
#from abipy.tools.parallel import get_max_nprocs, pool_nprocs_pmode
@@ -90,6 +88,7 @@ def __init__(self, filepaths: list[PathLike]):
90
88
for ext in self .SUPPORTED_EXTS :
91
89
if all (f .endswith (ext ) for f in self .filepaths ):
92
90
self .ext = ext
91
+ break
93
92
else :
94
93
raise ValueError (f"Cannot detect extension from filepaths, should be in: { self .SUPPORTED_EXTS } " )
95
94
@@ -146,6 +145,38 @@ def yield_atoms(self):
146
145
yield atoms
147
146
148
147
148
+ def check_vasp_success (vasprun , outcar , verbose : int = 0 ) -> bool :
149
+ """
150
+ Check if a VASP calculation completed successfully.
151
+
152
+ Returns:
153
+ bool: True if the calculation completed successfully, False otherwise.
154
+ """
155
+ def my_print (* args , ** kwargs )
156
+ if verbose : print (* args , ** kwargs )
157
+
158
+ from pymatgen .io .vasp .outputs import Vasprun , Outcar
159
+ try :
160
+ # vasprun = Vasprun(f"{directory}/vasprun.xml")
161
+ if not vasprun .converged :
162
+ my_print ("Calculation did not converge." )
163
+ return False
164
+
165
+ #outcar = Outcar(f"{directory}/OUTCAR")
166
+ if outcar .run_stats .get ("Elapsed time (sec)" ):
167
+ my_print ("Calculation completed in {} seconds." .format (outcar .run_stats ["Elapsed time (sec)" ]))
168
+ else :
169
+ my_print ("Elapsed time not found in OUTCAR." )
170
+ return False
171
+
172
+ my_print ("Calculation completed successfully." )
173
+ return True
174
+
175
+ except Exception as e :
176
+ my_print (f"Error checking calculation status: { e } " )
177
+ return False
178
+
179
+
149
180
150
181
class SinglePointRunner :
151
182
"""
@@ -154,13 +185,23 @@ class SinglePointRunner:
154
185
runner.collect_xyz("foo.xyz")
155
186
"""
156
187
157
- def __init__ (self , traj_path : PathLike , topdir : PathLike , traj_range : range ,
158
- abinitio_code : str , slurm_template : PathLike , ** kwargs ):
188
+ def __init__ (self , traj_path : PathLike , topdir : PathLike , traj_range : range ,
189
+ abinitio_code : str , slurm_template : PathLike , verbose = 0 , ** kwargs ):
190
+ """
191
+ """
159
192
self .traj_path = traj_path
160
193
self .topdir = Path (str (topdir )).absolute ()
161
194
self .traj_range = traj_range
195
+ if not isinstance (traj_range ):
196
+ raise TypeError (f"Got type{ traj_range } instead of range" )
162
197
self .abinitio_code = abinitio_code
198
+ if not ps .path .exists (self .slurm_template ):
199
+ s = qu .get_slurm_template ()
200
+ open (slurm_template , "wt" ).write (s )
201
+ raise RuntimeError ("" )
202
+
163
203
self .slurm_template = open (slurm_template , "rt" ).read ()
204
+ self .verbose = int (verbose )
164
205
self .kwargs = kwargs
165
206
166
207
def __str__ (self ) -> str :
@@ -176,19 +217,18 @@ def to_string(self, verbose=0) -> str:
176
217
def sbatch (self ):
177
218
"""
178
219
"""
179
- from abipy .flowtk .qutils import slurm_sbatch
180
-
181
220
if not self .topdir .exists (): self .topdir .mkdir ()
182
221
183
222
for index in self .traj_range :
184
223
workdir = self .topdir / f"SINGLEPOINT_{ index } "
185
224
if workdir .exists ():
225
+ print ("{workdir=} already exists. Ignoring it" )
186
226
continue
187
227
188
- workdir .mkdir ()
189
228
atoms = read (self .traj_path , index = index )
190
229
structure = Structure .as_structure (atoms )
191
230
script_filepath = workdir / "run.sh"
231
+ workdir .mkdir ()
192
232
193
233
if self .abinitio_code == "vasp" :
194
234
# Generate VASP input files using the Materials Project settings for a single-point calculation
@@ -202,7 +242,7 @@ def sbatch(self):
202
242
with open (script_filepath , "wt" ) as fh :
203
243
fh .write (self .slurm_template )
204
244
205
- slurm_sbatch (script_filepath )
245
+ qu . slurm_sbatch (script_filepath )
206
246
207
247
def write_xyz (self , xyz_filepath : PathLike , dryrun = False ) -> None :
208
248
"""
0 commit comments