Example #1
0
    def __init__(self, terms, external=None):
        '''
           **Arguments:**

           terms
                The terms in the Hamiltonian.

           **Optional arguments:**

           external
                A dictionary with external energy contributions that do not
                depend on the wavefunction, e.g. nuclear-nuclear interactions
                or QM/MM mechanical embedding terms. Use ``nn`` as key for the
                nuclear-nuclear term.
        '''
        # check arguments:
        if len(terms) == 0:
            raise ValueError(
                'At least one term must be present in the Hamiltonian.')

        # Assign attributes
        self.terms = list(terms)
        self.external = {} if external is None else external

        # Create a cache for shared intermediate results. This cache should only
        # be used for derived quantities that depend on the wavefunction and
        # need to be updated at each SCF cycle.
        self.cache = Cache()
Example #2
0
    def __init__(self, lf, nbasis, occ_model=None, norb=None):
        """
           **Arguments:**

           lf
                A LinalgFactory instance.

           nbasis
                The number of basis functions.

           **Optional arguments:**

           occ_model
                A model to assign new occupation numbers when the orbitals are
                updated by a diagonalization of a Fock matrix.

           norb
               the number of orbitals (occupied + virtual). When not given,
               it is set to nbasis.
        """
        self._lf = lf
        self._nbasis = nbasis
        self._occ_model = occ_model
        if norb is None:
            self._norb = nbasis
        else:
            self._norb = norb
        # The cache is used to store different representations of the
        # wavefunction, i.e. as expansion, as density matrix or both.
        self._cache = Cache()
        # Write some screen log
        self._log_init()
Example #3
0
    def __init__(self, lf, occ_model, projector):
        '''Localize canonical HF orbitals.

           **Arguments:**

           lf
                A LinalgFactory instance.

           occ_model
                Occupation model.

           Projector
                Projectors for atomic basis function. A list of TwoIndex
                instances.

           **Optional arguments:**

        '''
        self._lf = lf
        self._proj = projector
        self._nocc = occ_model.noccs[0]
        self._nbasis = lf.default_nbasis
        self._nvirt = (lf.default_nbasis - occ_model.noccs[0])
        self._cache = Cache()
        self._locblock = None
        self._popmatrix = None
Example #4
0
    def __init__(self, system, grid, local, slow, lmax, moldens=None):
        '''
           **Arguments:**

           system
                The system to be partitioned.

           grid
                The integration grid

           local
                Whether or not to use local (non-periodic) grids.

           slow
                When ``True``, also the AIM properties are computed that use the
                AIM overlap operators.

           lmax
                The maximum angular momentum in multipole expansions.

           **Optional arguments:**

           moldens
                The all-electron density grid data.
        '''
        JustOnceClass.__init__(self)
        self._system = system
        self._grid = grid
        self._local = local
        self._slow = slow
        self._lmax = lmax

        # Caching stuff, to avoid recomputation of earlier results
        self._cache = Cache()
        # Caching of work arrays to avoid reallocation
        if moldens is not None:
            self._cache.dump('moldens', moldens)

        # Initialize the subgrids
        if local:
            self._init_subgrids()

        # Some screen logging
        self._init_log_base()
        self._init_log_scheme()
        self._init_log_memory()
        if log.do_medium:
            log.blank()
Example #5
0
    def __init__(self, lf, occ_model, npairs=None, nvirt=None):
        '''
           **Arguments:**

           lf
                A LinalgFactory instance.

           occ_model
                Occupation model

           **Optional arguments:**

           npairs
                Number of electron pairs, if not specified,
                npairs = number of occupied orbitals

           nvirt
                Number of virtual orbitals, if not specified,
                nvirt = (nbasis-npairs)
        '''
        check_type('pairs', npairs, int, type(None))
        check_type('virtuals', nvirt, int, type(None))
        self._lf = lf
        self._nocc = occ_model.noccs[0]
        self._nbasis = lf.default_nbasis
        if npairs is None:
            npairs = occ_model.noccs[0]
        elif npairs >= lf.default_nbasis:
            raise ValueError(
                'Number of electron pairs (%i) larger than number of basis functions (%i)'
                % (npairs, self.nbasis))
        if nvirt is None:
            nvirt = (lf.default_nbasis - npairs)
        elif nvirt >= lf.default_nbasis:
            raise ValueError(
                'Number of virtuals (%i) larger than number of basis functions (%i)'
                % (nvirt, self.nbasis))
        self._npairs = npairs
        self._nvirt = nvirt
        self._cache = Cache()
        self._ecore = 0
        self._geminal = lf.create_two_index(npairs, nvirt)
        self._lagrange = lf.create_two_index(npairs, nvirt)
Example #6
0
    def __init__(self,
                 coordinates,
                 numbers,
                 obasis=None,
                 grid=None,
                 wfn=None,
                 lf=None,
                 cache=None,
                 extra=None,
                 cell=None,
                 pseudo_numbers=None,
                 chk=None):
        """
           **Arguments:**

           coordinates
                A (N, 3) float numpy array with Cartesian coordinates of the
                atoms.

           numbers
                A (N,) int numpy vector with the atomic numbers.

           **Optional arguments:**

           obasis
                A string or an instance of either the basis set or basis set
                description classes, e.g. 'STO-3G', GOBasisDesc('STO-3G'), ...
                for the orbitals.

           grid
                A grid object used for molecular integration.

           wfn
                A wavefunction object.

           lf
                A LinalgFactory instance. When not given, a DenseLinalgFactory
                is used by default.

           cache
                A cache object with computed results that depend on other
                attributes of the system class. Cached items should be tagged
                according to the attributes they depend on:

                    - ``o``: obasis
                    - ``c``: coordinates
                    - ``g``: grid

                When given as a dictionary, each value must consist of two
                items: the object to be cached and the tags.

           extra
                A dictionary with additional information about the system. The
                keys must be strings.

           cell
                A Cell object that describes the (generally triclinic) periodic
                boundary conditions. So far, this is nearly nowhere supported in
                Horton, so don't get too excited.

           pseudo_numbers
                The core charges of the pseudo potential, if applicable

           chk
                A filename for the checkpoint file or an open h5.File object.
                If the file does not exist yet, it will be created. If the file
                already exists, it must be an HDF5 file that is structured
                such that it adheres to the format that Horton creates itself.
                If chk is an open h5.File object, it will not be closed when the
                System instance is deleted.
        """

        # A) Assign all attributes
        self._coordinates = np.array(coordinates, dtype=float, copy=False)
        self._numbers = np.array(numbers, dtype=int, copy=False)
        # some checks
        if len(self._coordinates.shape
               ) != 2 or self._coordinates.shape[1] != 3:
            raise TypeError(
                'coordinates argument must be a 2D array with three columns')
        if len(self._numbers.shape) != 1:
            raise TypeError('numbers must a vector of integers.')
        if self._numbers.shape[0] != self._coordinates.shape[0]:
            raise TypeError(
                'numbers and coordinates must have compatible array shapes.')
        #
        self._grid = grid
        #
        self._wfn = wfn
        #
        if cache is None:
            self._cache = Cache()
        elif isinstance(cache, Cache):
            self._cache = cache
        elif isinstance(cache, dict):
            self._cache = Cache()
            for key, (value, tags) in cache.iteritems():
                self._cache.dump(key, value, tags=tags)
        else:
            raise TypeError('Could not interpret the cache argument.')
        #
        if lf is None:
            self._lf = DenseLinalgFactory()
        else:
            self._lf = lf
        #
        if extra is None:
            self._extra = {}
        else:
            self._extra = extra
        #
        self._obasis = None
        self._obasis_desc = None
        if obasis is not None:
            self.update_obasis(obasis)

        self._cell = cell
        self._pseudo_numbers = pseudo_numbers

        # The checkpoint file
        self._chk = None
        self._close_chk = False
        self.assign_chk(chk)

        self._log_init()
Example #7
0
    def __init__(self, coordinates, numbers, pseudo_numbers, grid, moldens, spindens, local, lmax):
        '''
           **Arguments:**

           coordinates
                An array (N, 3) with centers for the atom-centered grids.

           numbers
                An array (N,) with atomic numbers.

           pseudo_numbers
                An array (N,) with effective charges. When set to None, this
                defaults to``numbers.astype(float)``.

           grid
                The integration grid

           moldens
                The spin-summed electron density on the grid.

           spindens
                The spin difference density on the grid. (Can be None)

           local
                Whether or not to use local (non-periodic) subgrids for atomic
                integrals.

           lmax
                The maximum angular momentum in multipole expansions.
        '''

        # Init base class
        JustOnceClass.__init__(self)

        # Some type checking for first three arguments
        natom, coordinates, numbers, pseudo_numbers = typecheck_geo(coordinates, numbers, pseudo_numbers)
        self._natom = natom
        self._coordinates = coordinates
        self._numbers = numbers
        self._pseudo_numbers = pseudo_numbers

        # Assign remaining arguments as attributes
        self._grid = grid
        self._moldens = moldens
        self._spindens = spindens
        self._local = local
        self._lmax = lmax

        # Caching stuff, to avoid recomputation of earlier results
        self._cache = Cache()

        # Initialize the subgrids
        if local:
            self._init_subgrids()

        # Some screen logging
        self._init_log_base()
        self._init_log_scheme()
        self._init_log_memory()
        if log.do_medium:
            log.blank()
Example #8
0
    def __init__(self, system, terms, grid=None, idiot_proof=True):
        '''
           **Arguments:**

           system
                The System object for which the energy must be computed.

           terms
                The terms in the Hamiltonian.

           **Optional arguments:**

           grid
                The integration grid, in case some terms need one.

           idiot_proof
                When set to False, the kinetic energy, external potential and
                Hartree terms are not added automatically and a error is raised
                when no exchange is present.
        '''
        # check arguments:
        if len(terms) == 0:
            raise ValueError(
                'At least one term must be present in the Hamiltonian.')
        for term in terms:
            if term.require_grid and grid is None:
                raise TypeError(
                    'The term %s requires a grid, but not grid is given.' %
                    term)

        # Assign attributes
        self.system = system
        self.terms = list(terms)
        self.grid = grid

        if idiot_proof:
            # Check if an exchange term is present
            if not any(term.exchange for term in self.terms):
                raise ValueError(
                    'No exchange term is given and idiot_proof option is set to True.'
                )
            # Add standard terms if missing
            #  1) Kinetic energy
            if sum(isinstance(term, KineticEnergy) for term in terms) == 0:
                self.terms.append(KineticEnergy())
            #  2) Hartree (or HatreeFock, which is a subclass of Hartree)
            if sum(isinstance(term, Hartree) for term in terms) == 0:
                self.terms.append(Hartree())
            #  3) External Potential
            if sum(isinstance(term, ExternalPotential) for term in terms) == 0:
                self.terms.append(ExternalPotential())

        # Create a cache for shared intermediate results. This cache should only
        # be used for derived quantities that depend on the wavefunction and
        # need to be updated at each SCF cycle.
        self.cache = Cache()

        # bind the terms to this hamiltonian such that certain shared
        # intermediated results can be reused for the sake of efficiency.
        for term in self.terms:
            term.set_hamiltonian(self)