Source code for pharmaforge.interfaces.xtbio

from tblite.ase import TBLite as XTB
        

from pharmaforge.interfaces import AbstractIO


[docs] class XTBInterface(AbstractIO): """ This class is used to calculate the energies and forces for a single point calculation using XTB and the atomic simulation environment (ASE). For more information on the XTB calculator, see the ASE documentation. .. code-block:: python self.xtb_options = { "method": "GFN2-xTB", "accuracy": 1.0, "electronic_temperature": 300.0, } Parameters ---------- default : bool If True, use the default options for the XTB calculator. Default is False. options : dict A dictionary of options to pass to the XTB calculator. Default is an empty dictionary. Attributes ---------- calculator : object The XTB calculator object. allow_parallel : bool Whether to allow parallelization. Default is False. level_of_theory : str The level of theory used for the calculations. Default is "XTB". options_dict : dict A dictionary of options for the XTB calculator, that can include things not sent to the calculator. xtb_options : dict A dictionary of options for the XTB calculator, that are passed to the calculator. See Also -------- pharmaforge.interfaces.abstractio.AbstractIO : The abstract interface class for the Psi4Interface. xtb.ase.calculator.XTB : The XTB calculator object. Example ------- >>> from pharmaforge.interfaces.xtbio import XTBInterface >>> from ase import Atoms >>> h2 = Atoms('HH', positions=[(0, 0, 0), (0, 0, 1)]) >>> xtb = XTBInterface(default=True) >>> xtb.single_point(h2) (-26.300431519257398, array([[-0. , -0. , 3.24309609], ... [-0. , -0. , -3.24309609]])) """ def __init__(self, default=False, **options): """Initialize the XTBInterface class.""" self.calculator = XTB self.allow_parallel = False self.options_dict = {} if default: self.xtb_options = { "method": "GFN2-xTB", "accuracy": 1.0, "electronic_temperature": 300.0, "verbosity":0, "max-iter": 1000 } else: self.xtb_options = {} for option, value in options.items(): self.xtb_options[option] = value for key, value in options.items(): self.options_dict[key] = value hartree_per_kelvin =(3.166808578545117e-6) if "electronic_temperature" in self.xtb_options: self.xtb_options["electronic_temperature"] = float(self.xtb_options["electronic_temperature"])*hartree_per_kelvin self.level_of_theory = f"{self.xtb_options['method']}" return def _calculate(self, structure, charge=0): """Calculate the system data. Parameters ---------- structure : ase.Atoms The ASE atoms object containing the system data. Returns ------- calc : XTB The XTB calculator object. """ # tblite is annoyingly verbose, so if verbosity is set to 0, we need to catch the output if self.xtb_options.get("verbosity", 1) == 0: import os import sys from contextlib import redirect_stdout, redirect_stderr with open(os.devnull, 'w') as fnull: with redirect_stdout(fnull), redirect_stderr(fnull): structure.calc = self.calculator(charge=charge, **self.xtb_options) else: structure.calc = self.calculator(charge=charge, **self.xtb_options) return structure
[docs] def single_point(self, structure, charge=0): """Perform a single point calculation on the system. Parameters ---------- structure : ase.Atoms The ASE atoms object containing the system data. Returns ------- e : float The energy of the system. f : list The forces acting on the atoms in the system. """ calc = self._calculate(structure) e, f = self._report_data(calc) return e, f