diff --git a/python/dftd3/ase.py b/python/dftd3/ase.py index e9fbcb9b..0ba2dc62 100644 --- a/python/dftd3/ase.py +++ b/python/dftd3/ase.py @@ -40,6 +40,7 @@ method None Method to calculate dispersion for damping None Damping function to use params_tweaks None Optional dict with the damping parameters + realspace_cutoff None Optional dict to override cutoff values cache_api True Reuse generate API objects (recommended) ======================== ============ ============================================ @@ -63,6 +64,20 @@ for damping parameters of a given method and prefers special two-body only damping parameters if available! +The realspace cutoff parameters allow adjusting the distance values for which +interactions are considered + +================== =========== ========================================== + Realspace cutoff Default Description +================== =========== ========================================== + disp2 60 * Bohr Pairwise dispersion interactions + disp3 40 * Bohr Triple dispersion interactions + cn 40 * Bohr Coordination number counting +================== =========== ========================================== + +Values provided in the dict are expected to be in Angstrom. When providing values +in Bohr divide the inputs by the `ase.units.Bohr` constant. + Example ------- >>> from ase.build import molecule @@ -144,6 +159,7 @@ class DFTD3(Calculator): "method": None, "damping": None, "params_tweaks": {}, + "realspace_cutoff": {}, "cache_api": True, } @@ -235,8 +251,18 @@ def _create_api_calculator(self) -> DispersionModel: _periodic, ) - except RuntimeError: - raise InputError("Cannot construct dispersion model for dftd3") + except RuntimeError as e: + raise InputError("Cannot construct dispersion model for dftd3") from e + + try: + if self.parameters.realspace_cutoff: + disp2 = self.parameters.realspace_cutoff.get("disp2", 60.0 * Bohr) / Bohr + disp3 = self.parameters.realspace_cutoff.get("disp3", 40.0 * Bohr ) / Bohr + cn = self.parameters.realspace_cutoff.get("cn", 40.0 * Bohr ) / Bohr + + disp.set_realspace_cutoff(disp2=disp2, disp3=disp3, cn=cn) + except RuntimeError as e: + raise InputError("Cannot update realspace cutoff for dftd3") from e return disp @@ -247,8 +273,8 @@ def _create_damping_param(self) -> DampingParam: params_tweaks = self.parameters.params_tweaks if self.parameters.params_tweaks else {"method": self.parameters.get("method")} dpar = _damping_param[self.parameters.get("damping")](**params_tweaks) - except RuntimeError: - raise InputError("Cannot construct damping parameter for dftd3") + except RuntimeError as e: + raise InputError("Cannot construct damping parameter for dftd3") from e return dpar @@ -273,8 +299,8 @@ def calculate( try: _res = self._disp.get_dispersion(param=_dpar, grad=True) - except RuntimeError: - raise CalculationFailed("dftd3 could not evaluate input") + except RuntimeError as e: + raise CalculationFailed("dftd3 could not evaluate input") from e # These properties are garanteed to exist for all implemented calculators self.results["energy"] = _res.get("energy") * Hartree