コード例 #1
0
ファイル: system.py プロジェクト: ryanabbit/horton
    def from_file(cls, *args, **kwargs):
        """Create a System object from a file.

           A list of filenames may be provided, which will be loaded in that
           order. Each file complements or overrides the information loaded
           from a previous file in the list. Furthermore, keyword arguments
           may be used to specify additional constructor arguments.

           The ``lf`` optional argument is picked up from the kwargs list to
           contstruct (when needed) arrays to store the results loaded from
           file. When ``lf`` is not given, a DenseLinalgFactory is created by
           default.

           The filenames may also contain checkpoint files and open h5.File
           objects of checkpoint files. The last such checkpoint file will
           automatically be used as a checkpoint file for this class. If you
           want to override this behavior, provide the ``chk`` keyword argument
           (may be None).
        """
        constructor_args = {}
        lf = kwargs.get('lf')
        if lf is None:
            lf = DenseLinalgFactory()
        for fn in args:
            fn_args = load_system_args(fn, lf)
            constructor_args.update(fn_args)
        constructor_args.update(kwargs)

        # If the basis comes from an external code and some operators are
        # loaded, rows and columns may need to be reordered. Similar for the
        # orbital coefficients and the density matrices.
        permutation = constructor_args.get('permutation')
        if permutation is not None:
            cache = constructor_args.get('cache')
            if cache is not None:
                for value, tags in cache.itervalues():
                    if isinstance(value, LinalgObject):
                        value.apply_basis_permutation(permutation)
            wfn = constructor_args.get('wfn')
            if wfn is not None:
                wfn.apply_basis_permutation(permutation)
            del constructor_args['permutation']

        # After the permutation, correct for different sign conventions of the
        # orbitals
        signs = constructor_args.get('signs')
        if signs is not None:
            cache = constructor_args.get('cache')
            if cache is not None:
                for value, tags in cache.itervalues():
                    if isinstance(value, LinalgObject):
                        value.apply_basis_signs(signs)
            wfn = constructor_args.get('wfn')
            if wfn is not None:
                wfn.apply_basis_signs(signs)
            del constructor_args['signs']

        return cls(**constructor_args)
コード例 #2
0
def test_dense_two_index():
    from horton.matrix import DenseLinalgFactory, DenseTwoIndex
    lf = DenseLinalgFactory()
    c = Cache()
    op1, new = c.load('egg', alloc=(lf.create_two_index, 10))
    assert new
    assert isinstance(op1, DenseTwoIndex)
    assert op1.nbasis == 10
    op2 = c.load('egg')
    assert op1 is op2
    op3, new = c.load('egg', alloc=(lf.create_two_index, 10))
    assert not new
    assert op1 is op3
    # things that should not work
    with assert_raises(TypeError):
        op4, new = c.load('egg', alloc=(lf.create_two_index, 5))
    with assert_raises(TypeError):
        op4, new = c.load('egg', alloc=5)
    # after clearing
    op1.set_element(1, 2, 5.2)
    c.clear()
    assert op1._array[1, 2] == 0.0
    with assert_raises(KeyError):
        op4 = c.load('egg')
    op4, new = c.load('egg', alloc=(lf.create_two_index, 10))
    assert new
    assert op1 is op4
    op5 = c.load('egg')
    assert op1 is op5
    # default_nbasis
    lf.default_nbasis = 5
    with assert_raises(TypeError):
        c.load('egg', alloc=lf.create_two_index)
    c.clear()
    op6, new = c.load('egg', alloc=lf.create_two_index)
    assert new
    assert not op5 is op6
    assert op6.nbasis == 5
    # the new method of the two-index object
    op7, new = c.load('bork', alloc=op6.new)
    assert new
    assert not op5 is op7
    assert op7.nbasis == 5
コード例 #3
0
def test_dense_expansion():
    from horton.matrix import DenseLinalgFactory, DenseExpansion
    lf = DenseLinalgFactory()
    c = Cache()
    exp1, new = c.load('egg', alloc=(lf.create_expansion, 10, 9))
    assert new
    assert isinstance(exp1, DenseExpansion)
    assert exp1.nbasis == 10
    assert exp1.nfn == 9
    exp2 = c.load('egg')
    assert exp1 is exp2
    exp3, new = c.load('egg', alloc=(lf.create_expansion, 10, 9))
    assert not new
    assert exp1 is exp3
    # things that should not work
    with assert_raises(TypeError):
        exp4, new = c.load('egg', alloc=(lf.create_expansion, 5))
    with assert_raises(TypeError):
        exp4, new = c.load('egg', alloc=(lf.create_expansion, 10, 5))
    with assert_raises(TypeError):
        exp4, new = c.load('egg', alloc=5)
    # after clearing
    exp1.coeffs[1, 2] = 5.2
    c.clear()
    assert exp1.coeffs[1, 2] == 0.0
    with assert_raises(KeyError):
        exp4 = c.load('egg')
    exp4, new = c.load('egg', alloc=(lf.create_expansion, 10, 9))
    assert new
    assert exp1 is exp4
    exp5 = c.load('egg')
    assert exp1 is exp5
    # default_nbasis
    lf.set_default_nbasis(5)
    with assert_raises(TypeError):
        c.load('egg', alloc=lf.create_expansion)
    c.clear()
    exp6, new = c.load('egg', alloc=lf.create_expansion)
    assert new
    assert not exp5 is exp6
    assert exp6.nbasis == 5
    assert exp6.nfn == 5
コード例 #4
0
def test_dense_two_body():
    from horton.matrix import DenseLinalgFactory, DenseTwoBody
    lf = DenseLinalgFactory()
    c = Cache()
    op1, new = c.load('egg', alloc=(lf.create_two_body, 10))
    assert new
    assert isinstance(op1, DenseTwoBody)
    assert op1.nbasis == 10
    op2 = c.load('egg')
    assert op1 is op2
    op3, new = c.load('egg', alloc=(lf.create_two_body, 10))
    assert not new
    assert op1 is op3
    # things that should not work
    with assert_raises(TypeError):
        op4, new = c.load('egg', alloc=(lf.create_two_body, 5))
    with assert_raises(TypeError):
        op4, new = c.load('egg', alloc=5)
    # after clearing
    op1.set_element(1, 2, 1, 2, 5.2)
    c.clear()
    assert op1._array[1, 2, 1, 2] == 0.0
    with assert_raises(KeyError):
        op4 = c.load('egg')
    op4, new = c.load('egg', alloc=(lf.create_two_body, 10))
    assert new
    assert op1 is op4
    op5 = c.load('egg')
    assert op1 is op5
    # default_nbasis
    lf.set_default_nbasis(5)
    with assert_raises(TypeError):
        c.load('egg', alloc=lf.create_two_body)
    c.clear()
    op6, new = c.load('egg', alloc=lf.create_one_body)
    assert new
    assert not op5 is op6
    assert op6.nbasis == 5
コード例 #5
0
ファイル: system.py プロジェクト: ryanabbit/horton
    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()
コード例 #6
0
ファイル: project.py プロジェクト: ryanabbit/horton
def project_orbitals_mgs_low(obasis0, obasis1, exp0, exp1, eps=1e-10):
    '''Project the orbitals in ``exp0`` (wrt ``obasis0``) on ``obasis1`` and store in ``exp1`` with the modified Gram-Schmidt algorithm.

       **Arguments:**

       obasis0
            The orbital basis for the original wavefunction expansion.

       obasis1
            The new orbital basis for the projected wavefunction expansion.

       exp0
            The expansion of the original orbitals.

       exp1 (output)
            An output argument in which the projected orbitals will be stored.

       **Optional arguments:**

       eps
            A threshold for the renormalization in the Gram-Schmidt procedure

       The projection is based on the Modified Gram-Schmidt (MGS) process. In
       each iteration of the MGS, a renormalization is carried out. If the norm
       in this step is smaller than ``eps``, an error is raised.

       Note that ``exp1`` will be incomplete in several ways. The orbital
       energies are not copied. Only the occupied orbitals in ``exp0`` are
       projected. Coefficients of higher orbitals are set to zero. The orbital
       occupations are simply copied. This should be sufficient to construct
       an initial guess in a new orbital basis set based on a previous solution.

       If the number of orbitals in ``exp1`` is too small to store all projected
       orbitals, an error is raised.
    '''
    # Compute the overlap matrix of the combined orbital basis
    obasis_both = GOBasis.concatenate(obasis0, obasis1)
    lf = DenseLinalgFactory(obasis_both.nbasis)
    olp_both = lf.create_one_body()
    obasis_both.compute_overlap(olp_both)

    # Select the blocks of interest from the big overlap matrix
    olp_21 = olp_both._array[obasis0.nbasis:, :obasis0.nbasis]
    olp_22 = olp_both._array[obasis0.nbasis:, obasis0.nbasis:]

    # construct the projector
    projector = np.dot(np.linalg.pinv(olp_22), olp_21)

    # project occupied orbitals
    i1 = 0
    for i0 in xrange(exp0.nfn):
        if exp0.occupations[i0] == 0.0:
            continue
        if i1 > exp1.nfn:
            raise ProjectionError(
                'Not enough functions available in exp1 to store the projected orbitals.'
            )
        exp1.coeffs[:, i1] = np.dot(projector, exp0.coeffs[:, i0])
        exp1.occupations[i1] = exp0.occupations[i0]
        i1 += 1

    # clear all parts of exp1 that were not touched by the projection loop
    ntrans = i1
    del i1
    exp1.coeffs[:, ntrans:] = 0.0
    exp1.occupations[ntrans:] = 0.0
    exp1.energies[:] = 0.0

    # auxiliary function for the MGS algo
    def dot22(a, b):
        return np.dot(np.dot(a, olp_22), b)

    # Apply the MGS algorithm to orthogonalize the orbitals
    for i1 in xrange(ntrans):
        orb = exp1.coeffs[:, i1]

        # Subtract overlap with previous orbitals
        for j1 in xrange(i1):
            other = exp1.coeffs[:, j1]
            orb -= other * dot22(other, orb) / np.sqrt(dot22(orb, orb))

        # Renormalize
        norm = np.sqrt(dot22(orb, orb))
        if norm < eps:
            raise ProjectionError(
                'The norm of a vector in the MGS algorithm becomes too small. Orbitals are redundant in new basis.'
            )
        orb /= norm
コード例 #7
0
    def from_file(cls, *filenames, **kwargs):
        '''Load data from a file.

           **Arguments:**

           filename1, filename2, ...
                The files to load data from. When multiple files are given, data
                from the first file is overwritten by data from the second, etc.
                When one file contains sign and permutation changes for the
                orbital basis, these changes will be applied to data from all
                other files.

           **Optional arguments:**

           lf
                A LinalgFactory instance. DenseLinalgFactory is used as default.

           This routine uses the extension or prefix of the filename to
           determine the file format. It returns a dictionary with data loaded
           from the file.

           For each file format, a specialized function is called that returns a
           dictionary with data from the file.
        '''
        result = {}

        lf = kwargs.pop('lf', None)
        if lf is None:
            lf = DenseLinalgFactory()
        if len(kwargs) > 0:
            raise TypeError('Keyword argument(s) not supported: %s' %
                            kwargs.keys())

        for filename in filenames:
            if isinstance(filename, h5.Group) or filename.endswith('.h5'):
                from horton.io.internal import load_h5
                result.update(load_h5(filename))
            elif filename.endswith('.xyz'):
                from horton.io.xyz import load_xyz
                result.update(load_xyz(filename))
            elif filename.endswith('.fchk'):
                from horton.io.gaussian import load_fchk
                result.update(load_fchk(filename, lf))
            elif filename.endswith('.log'):
                from horton.io.gaussian import load_operators_g09
                result.update(load_operators_g09(filename, lf))
            elif filename.endswith('.mkl'):
                from horton.io.molekel import load_mkl
                result.update(load_mkl(filename, lf))
            elif filename.endswith('.molden.input') or filename.endswith(
                    '.molden'):
                from horton.io.molden import load_molden
                result.update(load_molden(filename, lf))
            elif filename.endswith('.cube'):
                from horton.io.cube import load_cube
                result.update(load_cube(filename))
            elif filename.endswith('.wfn'):
                from horton.io.wfn import load_wfn
                result.update(load_wfn(filename, lf))
            elif os.path.basename(filename).startswith('POSCAR'):
                from horton.io.vasp import load_poscar
                result.update(load_poscar(filename))
            elif os.path.basename(filename)[:6] in ['CHGCAR', 'AECCAR']:
                from horton.io.vasp import load_chgcar
                result.update(load_chgcar(filename))
            elif os.path.basename(filename).startswith('LOCPOT'):
                from horton.io.vasp import load_locpot
                result.update(load_locpot(filename))
            elif filename.endswith('.cp2k.out'):
                from horton.io.cp2k import load_atom_cp2k
                result.update(load_atom_cp2k(filename, lf))
            elif filename.endswith('.cif'):
                from horton.io.cif import load_cif
                result.update(load_cif(filename, lf))
            elif 'FCIDUMP' in os.path.basename(filename):
                from horton.io.molpro import load_fcidump
                result.update(load_fcidump(filename, lf))
            else:
                raise ValueError('Unknown file format for reading: %s' %
                                 filename)

        # Apply changes in orbital order and sign conventions
        if 'permutation' in result:
            for key, value in result.iteritems():
                if isinstance(value, LinalgObject):
                    value.permute_basis(result['permutation'])
            del result['permutation']
        if 'signs' in result:
            for key, value in result.iteritems():
                if isinstance(value, LinalgObject):
                    value.change_basis_signs(result['signs'])
            del result['signs']

        return cls(**result)