From d017784ed9b7c8ce692f39e02b4b8d24bc80b04b Mon Sep 17 00:00:00 2001 From: woodsp Date: Tue, 6 Oct 2020 12:53:17 -0400 Subject: [PATCH] Updated docstrings --- .../drivers/gaussiand/gaussiandriver.py | 12 +- qiskit/chemistry/drivers/molecule.py | 109 +++++++++--------- qiskit/chemistry/drivers/psi4d/psi4driver.py | 11 +- .../drivers/pyquanted/pyquantedriver.py | 21 ++-- .../chemistry/drivers/pyscfd/pyscfdriver.py | 23 ++-- 5 files changed, 99 insertions(+), 77 deletions(-) diff --git a/qiskit/chemistry/drivers/gaussiand/gaussiandriver.py b/qiskit/chemistry/drivers/gaussiand/gaussiandriver.py index ebf429fd6c..2666ee7bc8 100644 --- a/qiskit/chemistry/drivers/gaussiand/gaussiandriver.py +++ b/qiskit/chemistry/drivers/gaussiand/gaussiandriver.py @@ -52,9 +52,15 @@ def __init__(self, """ Args: config: A molecular configuration conforming to Gaussian™ 16 format. - molecule: molecule - basis: basis set - hf_method: Hartree-Fock Method type + molecule: A driver independent Molecule definition instance may be provided. When + a molecule is supplied the `config` parameter is ignored and the Molecule instance, + along with `basis` and `hf_method` is used to build a basic config instead. + The Molecule object is read when the driver is run and converted to the driver + dependent configuration for the computation. This allows, for example, the Molecule + geometry to be updated to compute different points. + basis: Basis set + hf_method: Hartree-Fock Method type; `rhf`, `rohf`, `uhf` + Raises: QiskitChemistryError: Invalid Input """ diff --git a/qiskit/chemistry/drivers/molecule.py b/qiskit/chemistry/drivers/molecule.py index 56c3830ea8..5674ddf5eb 100644 --- a/qiskit/chemistry/drivers/molecule.py +++ b/qiskit/chemistry/drivers/molecule.py @@ -10,12 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -This module implements an interface for a generic molecule. -It defines the composing atoms (with properties like masses, and nuclear spin), -and allows for changing the molecular geometry through given degrees of freedom -(e.g. bond-stretching, angle-bending, etc.). -""" +"""Driver-independent Molecule definition.""" from typing import Callable, Tuple, List, Optional import copy @@ -27,54 +22,59 @@ class Molecule: - """ - Molecule class + """Driver-independent Molecule definition. + + This module implements an interface for a driver-independent, i.e. generic molecule + definition. It defines the composing atoms (with properties like masses), + and allows for changing the molecular geometry through given degrees of freedom + (e.g. bond-stretching, angle-bending, etc.). The geometry as provided in the + constructor can be affected, through setting perturbations, and it is this perturbed + geometry that is supplied by the geometry getter. Setting perturbations to None will + cause the original geometry to be returned, and there is a getter to get this value + directly if its needed. """ def __init__(self, geometry: List[Tuple[str, List[float]]], - multiplicity: int, - charge: int, + multiplicity: int = 1, + charge: int = 0, degrees_of_freedom: Optional[List[Callable]] = None, masses: Optional[List[float]] = None ) -> None: """ Args: - geometry: 2d list containing atom string names - to generate PySCF molecule strings as keys and list of 3 - floats representing Cartesian coordinates as values, - in units of **Angstroms**. - multiplicity: multiplicity - charge: charge + geometry: A list of atoms defining a given molecule where each item in the list + is an atom name together with a list of 3 floats representing the x,y and z + Cartesian coordinates of the atom's position in units of **Angstrom**. + multiplicity: Multiplicity (2S+1) of the molecule + charge: Charge on the molecule degrees_of_freedom: List of functions taking a perturbation value and geometry and returns a perturbed geometry. Helper functions for typical perturbations are provided and can be used by the form itertools.partial(Molecule.stretching_potential,{'atom_pair': (1, 2)) to specify the desired degree of freedom. - masses: masses + masses: Mass of each atom the molecule may optionally be provided. Raises: ValueError: Length of masses must match length of geometries. """ + Molecule._check_consistency(geometry, masses) + self._geometry = geometry self._degrees_of_freedom = degrees_of_freedom self._multiplicity = multiplicity self._charge = charge - - self._check_masses(masses) - self._masses = masses - def _check_masses(self, masses: Optional[List[float]]): - if masses is not None and not len(masses) == len(self._geometry): - raise ValueError( - 'Length of masses must match length of geometries, ' - 'found {} and {} respectively'.format( - len(masses), - len(self._geometry) - ) - ) + self._perturbations = None # type: Optional[List[float]] + + @staticmethod + def _check_consistency(geometry: List[Tuple[str, List[float]]], + masses: Optional[List[float]]): + if masses is not None and len(masses) != len(geometry): + raise ValueError('Length of masses {} must match length of geometries {}'.format( + len(masses), len(geometry))) @classmethod def _distance_modifier(cls, @@ -321,72 +321,69 @@ def func(curr_angle, extra): return cls._bend_modifier(func, bend, geometry, atom_trio) - def get_perturbed_geom(self, - perturbations: Optional[List[float]] = None) \ - -> List[Tuple[str, List[float]]]: + def _get_perturbed_geom(self) -> List[Tuple[str, List[float]]]: """ get perturbed geometry """ - if not perturbations or not self._degrees_of_freedom: + if self.perturbations is None or self._degrees_of_freedom is None: return self._geometry + geometry = copy.deepcopy(self._geometry) - for per, dof in zip(perturbations, self._degrees_of_freedom): + for per, dof in zip(self.perturbations, self._degrees_of_freedom): geometry = dof(per, geometry) return geometry @property def units(self): - """ return units """ + """ The geometry coordinate units """ return UnitsType.ANGSTROM @property def geometry(self) -> List[Tuple[str, List[float]]]: - """ return geometry """ - return self._geometry - - @classmethod - def get_geometry_str(cls, - geometry: List[Tuple[str, List[float]]]) -> str: - """ get geometry string """ - return '; '.join([name + ' ' + ', '.join(map(str, coord)) - for (name, coord) in geometry]) - - @property - def geometry_str(self) -> str: - """ return geometry string """ - return Molecule.get_geometry_str(self.geometry) + """ Get geometry accounting for any perturbations """ + return self._get_perturbed_geom() @property def masses(self) -> Optional[List[float]]: - """ return masses """ + """ Get masses """ return self._masses @masses.setter def masses(self, value: Optional[List[float]]) -> None: - """ set masses + """ Set masses Args: value: masses Raises: ValueError: Length of masses must match length of geometries. """ - self._check_masses(value) + Molecule._check_consistency(self._geometry, value) self._masses = value @property def multiplicity(self) -> int: - """ return multiplicity """ + """ Get multiplicity """ return self._multiplicity @multiplicity.setter def multiplicity(self, value: int) -> None: - """ set multiplicity """ + """ Set multiplicity """ self._multiplicity = value @property def charge(self) -> int: - """ return charge """ + """ Get charge """ return self._charge @charge.setter def charge(self, value: int) -> None: - """ set charge """ + """ Set charge """ self._charge = value + + @property + def perturbations(self) -> Optional[List[float]]: + """ Get perturbations """ + return self._perturbations + + @perturbations.setter + def perturbations(self, value: Optional[List[float]]) -> None: + """ Set perturbations """ + self._perturbations = value diff --git a/qiskit/chemistry/drivers/psi4d/psi4driver.py b/qiskit/chemistry/drivers/psi4d/psi4driver.py index b1e26263aa..5c972f557a 100644 --- a/qiskit/chemistry/drivers/psi4d/psi4driver.py +++ b/qiskit/chemistry/drivers/psi4d/psi4driver.py @@ -49,9 +49,14 @@ def __init__(self, """ Args: config: A molecular configuration conforming to PSI4 format. - molecule: molecule - basis: basis set - hf_method: Hartree-Fock Method type + molecule: A driver independent Molecule definition instance may be provided. When + a molecule is supplied the `config` parameter is ignored and the Molecule instance, + along with `basis` and `hf_method` is used to build a basic config instead. + The Molecule object is read when the driver is run and converted to the driver + dependent configuration for the computation. This allows, for example, the Molecule + geometry to be updated to compute different points. + basis: Basis set + hf_method: Hartree-Fock Method type; `rhf`, `rohf`, `uhf` Raises: QiskitChemistryError: Invalid Input diff --git a/qiskit/chemistry/drivers/pyquanted/pyquantedriver.py b/qiskit/chemistry/drivers/pyquanted/pyquantedriver.py index 161612662c..48fd3a0489 100644 --- a/qiskit/chemistry/drivers/pyquanted/pyquantedriver.py +++ b/qiskit/chemistry/drivers/pyquanted/pyquantedriver.py @@ -54,16 +54,23 @@ def __init__(self, molecule: Optional[Molecule] = None) -> None: """ Args: - atoms: atoms list or string separated by semicolons or line breaks - units: angstrom or bohr - charge: charge - multiplicity: spin multiplicity - basis: sto3g or 6-31g or 6-31g** + atoms: Atoms list or string separated by semicolons or line breaks. Each element in the + list is an atom followed by position e.g. `H 0.0 0.0 0.5`. The preceding example + shows the `XYZ` format for position but `Z-Matrix` format is supported too here. + units: Angstrom or Bohr + charge: Charge on the molecule + multiplicity: Spin multiplicity (2S+1) + basis: Basis set; sto3g, 6-31g or 6-31g** hf_method: Hartree-Fock Method type tol: Convergence tolerance see pyquante2.scf hamiltonians and iterators maxiters: Convergence max iterations see pyquante2.scf hamiltonians and iterators, - has a min. value of 1. - molecule: molecule + has a min. value of 1. + molecule: A driver independent Molecule definition instance may be provided. When + a molecule is supplied the `atoms`, `units`, `charge` and `multiplicity` parameters + are all ignored as the Molecule instance now defines these instead. The Molecule + object is read when the driver is run and converted to the driver dependent + configuration for the computation. This allows, for example, the Molecule geometry + to be updated to compute different points. Raises: QiskitChemistryError: Invalid Input diff --git a/qiskit/chemistry/drivers/pyscfd/pyscfdriver.py b/qiskit/chemistry/drivers/pyscfd/pyscfdriver.py index e3cc9e0c34..58ab848115 100644 --- a/qiskit/chemistry/drivers/pyscfd/pyscfdriver.py +++ b/qiskit/chemistry/drivers/pyscfd/pyscfdriver.py @@ -57,18 +57,25 @@ def __init__(self, molecule: Optional[Molecule] = None) -> None: """ Args: - atom: atom list or string separated by semicolons or line breaks - unit: angstrom or bohr - charge: charge - spin: spin - basis: basis set + atom: Atom list or string separated by semicolons or line breaks. Each element in the + list is an atom followed by position e.g. `H 0.0 0.0 0.5`. The preceding example + shows the `XYZ` format for position but `Z-Matrix` format is supported too here. + unit: Angstrom or Bohr + charge: Charge on the molecule + spin: Spin (2S), in accordance with how PySCF defines a molecule in pyscf.gto.mole.Mole + basis: Basis set hf_method: Hartree-Fock Method type conv_tol: Convergence tolerance see PySCF docs and pyscf/scf/hf.py max_cycle: Max convergence cycles see PySCF docs and pyscf/scf/hf.py, - has a min. value of 1. + has a min. value of 1. init_guess: See PySCF pyscf/scf/hf.py init_guess_by_minao/1e/atom methods - max_memory: maximum memory - molecule: molecule + max_memory: Maximum memory that PySCF should use + molecule: A driver independent Molecule definition instance may be provided. When + a molecule is supplied the `atom`, `unit`, `charge` and `spin` parameters + are all ignored as the Molecule instance now defines these instead. The Molecule + object is read when the driver is run and converted to the driver dependent + configuration for the computation. This allows, for example, the Molecule geometry + to be updated to compute different points. Raises: QiskitChemistryError: Invalid Input