Skip to content

Commit

Permalink
Merge pull request #330 from libAtoms/castep-ase323-update
Browse files Browse the repository at this point in the history
Castep ase323 update
  • Loading branch information
bernstei authored Aug 16, 2024
2 parents 403bd0d + 522b416 commit 4db7936
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
7 changes: 3 additions & 4 deletions tests/calculators/test_castep.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

pytestmark = pytest.mark.skipif("CASTEP_COMMAND" not in os.environ, reason="'CASTEP_COMMAND' not given.")


def test_castep_calculation(tmp_path):

atoms = bulk("Al", "bcc", a=4.05, cubic=True)
Expand All @@ -30,9 +29,9 @@ def test_castep_calculation(tmp_path):
)

atoms.calc = calc
assert atoms.get_potential_energy() == approx(-217.2263559019)
assert atoms.get_forces() == approx(np.array([[-0., -0., 0.], [ 0., 0., -0.]]))
assert atoms.get_stress() == approx(np.array([ 0.06361731, 0.06361731, 0.06361731,-0., 0., 0.]))
assert atoms.get_potential_energy() == approx(-217.2263559019, 2e-3)
assert atoms.get_forces() == approx(np.array([[-0., -0., 0.], [ 0., 0., -0.]]), abs=1e-4)
assert atoms.get_stress() == approx(np.array([ 0.06361731, 0.06361731, 0.06361731,-0., 0., 0.]), abs=1e-5)


def test_castep_calc_via_generic(tmp_path):
Expand Down
47 changes: 31 additions & 16 deletions wfl/calculators/castep.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,22 @@ class Castep(WFLFileIOCalculator, ASE_Castep):
**kwargs: arguments for ase.calculators.Castep.Castep
"""

implemented_properties = ["energy", "forces", "stress"]

# new default value of num_inputs_per_python_subprocess for calculators.generic,
# to override that function's built-in default of 10
wfl_generic_default_autopara_info = {"num_inputs_per_python_subprocess": 1}

def __init__(self, keep_files="default", rundir_prefix="run_CASTEP_",
workdir=None, scratchdir=None,
calculator_exec=None, **kwargs):
def __init__(
self,
keep_files="default",
rundir_prefix="run_CASTEP_",
workdir=None,
scratchdir=None,
calculator_exec=None,
**kwargs,
):

kwargs = deepcopy(kwargs)
if calculator_exec is not None:
Expand All @@ -62,11 +69,17 @@ def __init__(self, keep_files="default", rundir_prefix="run_CASTEP_",
kwargs["find_pspots"] = True

# WFLFileIOCalculator is a mixin, will call remaining superclass constructors for us
super().__init__(keep_files=keep_files, rundir_prefix=rundir_prefix,
workdir=workdir, scratchdir=scratchdir, **kwargs)


def calculate(self, atoms=None, properties=_default_properties, system_changes=all_changes):
super().__init__(
keep_files=keep_files,
rundir_prefix=rundir_prefix,
workdir=workdir,
scratchdir=scratchdir,
**kwargs,
)

def calculate(
self, atoms=None, properties=_default_properties, system_changes=all_changes
):
"""Do the calculation. Handles the working directories in addition to regular
ASE calculation operations (writing input, executing, reading_results)
Reimplements & extends GenericFileIOCalculator.calculate() for the development version of ASE
Expand All @@ -83,30 +96,32 @@ def calculate(self, atoms=None, properties=_default_properties, system_changes=a

orig_pbc = self.atoms.pbc.copy()
try:
super().calculate(atoms=atoms)
super().calculate(
atoms=atoms, properties=properties, system_changes=system_changes
)
calculation_succeeded = True
if 'DFT_FAILED_CASTEP' in atoms.info:
del atoms.info['DFT_FAILED_CASTEP']
if "DFT_FAILED_CASTEP" in atoms.info:
del atoms.info["DFT_FAILED_CASTEP"]
except Exception as exc:
atoms.info['DFT_FAILED_CASTEP'] = True
atoms.info["DFT_FAILED_CASTEP"] = True
calculation_succeeded = False
raise exc
finally:
# ASE castep calculator does not ever raise an exception when
# it fails. Instead, you get things like stress being None,
# which lead to TypeError when save_calc_results calls get_stress().
for property in properties:
result = self.get_property(property)
for prop in properties:
result = self.get_property(prop, allow_calculation=False)
if result is None:
calculation_succeeded = False
atoms.info["DFT_FAILED_CASTEP"] = True
break

# from WFLFileIOCalculator
self.clean_rundir(_default_keep_files, calculation_succeeded)

# reset pbc because Castep overwrites it to True
self.atoms.pbc = orig_pbc(False)

self.atoms.pbc = orig_pbc

def setup_calc_params(self, properties):
# calculate stress if requested
Expand Down

0 comments on commit 4db7936

Please sign in to comment.