Trouble with multiple CASTEP calls: conflicting keywords appear
I have a curious error in the CASTEP calculator, originating from what I consider to be a fairly idiomatic use of ASE.
Here's a minimal example using Python 3.6 to investigate convergence with the "BASIS_PRECISION" option:
import ase.build
from ase.calculators.castep import Castep
atoms = ase.build.molecule('H2', cell=[10, 10, 10], pbc=True)
calc = Castep(task='geometry optimisation',
kpoints_MP_grid=(1, 1, 1),
xc_functional='PBE')
atoms.set_calculator(calc)
for precision in 'COARSE', 'MEDIUM', 'FINE', 'PRECISE', 'EXTREME':
calc.param.basis_precision = precision
toten = atoms.get_total_energy()
print(f"Total energy, {precision} opt: {toten} eV")
bond_length = atoms.get_all_distances()[1, 0]
print(f"H-H distance: {bond_length} Å\n")
which yields the following output:
Total energy, COARSE opt: -31.54803754292 eV
H-H distance: 0.75806 Å
Total energy, MEDIUM opt: -31.6252731074 eV
H-H distance: 0.7556 Å
castep call stdout:
--------------------------------------------------------------------------
MPI_ABORT was invoked on rank 0 in communicator MPI_COMM_WORLD
with errorcode 1.
NOTE: invoking MPI_ABORT causes Open MPI to kill all MPI processes.
You may or may not see output from other processes, depending on
exactly when Open MPI kills them.
--------------------------------------------------------------------------
Traceback (most recent call last):
File "test.py", line 12, in <module>
toten = atoms.get_total_energy()
--- SNIP SOME BORING STUFF ---
File "/home/adamjackson/opt/ase-fork/ase/calculators/castep.py", line 1786, in run
raise RuntimeError(self._error)
RuntimeError: Error in parameters file: duplication with keywordsBASIS_PRECISION and CUT_OFF_ENERGY
Sure enough, in CASTEP/castep.param both CUT_OFF_ENERGY and BASIS_PRECISION have been defined. Presumably the problem is that both are reported in the calculation output, and this information is added to the Calculator, leaving it an an unacceptable state for further calculations. I don't understand, however, why this only blows up the second restart (i.e. the third iteration of my loop).
A suggestion to avoid this problem would be
a) when reading output apply only the CUT_OFF_ENERGY and not the BASIS_PRECISION to the updated calculator object
b) when setting BASIS_PRECISION, automatically clear the CUT_OFF_ENERGY. Adding a line calc.param.cut_off_energy = None
to my example after setting the basis precision does prevent the error.