Esempio n. 1
0
def _setup_orbital(uni,
                   verbose,
                   vector,
                   fps,
                   icoefs,
                   log=None,
                   jcoefs=None,
                   irrep=None):
    """Boilerplate for starting the functions in this module."""
    log = log or func_log(_setup_orbital)
    t1 = datetime.now()
    nbf = len(uni.basis_functions)
    if irrep is not None:
        nbf = len(uni.basis_set_order.groupby('irrep').get_group(irrep).index)
    if verbose:
        p1 = 'Evaluating {} basis functions once.'
        log.debug(p1.format(nbf))
    vector = _determine_vector(uni, vector, irrep)
    fps = _determine_fps(uni, fps, len(vector))
    x, y, z = numerical_grid_from_field_params(fps)
    bvs = uni.basis_functions.evaluate(x, y, z, irrep=irrep, verbose=verbose)
    icoefs = _check_column(uni, 'current_momatrix', icoefs)
    icoefs = uni.current_momatrix.square(column=icoefs, irrep=irrep).values
    if jcoefs is not None:
        jcoefs = _check_column(uni, 'current_momatrix', jcoefs)
        jcoefs = uni.current_momatrix.square(column=jcoefs).values
        return t1, vector, fps, x, y, z, bvs, icoefs, jcoefs
    return t1, vector, fps, x, y, z, bvs, icoefs
Esempio n. 2
0
def add_molecular_orbitals(uni, field_params=None, mocoefs=None,
                           vector=None, frame=0, inplace=True,
                           replace=False, verbose=True, irrep=None):
    """A universe must contain basis_set, [basis_set_order], and
    momatrix attributes to use this function.  Evaluate molecular
    orbitals on a numerical grid.  Attempts to generate reasonable
    defaults if none are provided.  If vector is not provided,
    attempts to calculate vector from the orbital table, or by the
    sum of Z (Zeff) of the atoms in the atom table divided by two;
    roughly (H**O-5, LUMO+7).

    Args:
        uni (:class:`~exatomic.core.universe.Universe`): a universe
        field_params (dict): See :func:`~exatomic.algorithms.orbital_util.make_fps`
        mocoefs (str): column in uni.current_momatrix (default 'coef')
        vector (int, list, range, np.ndarray): the MO vectors to evaluate
        inplace (bool): if False, return the field obj instead of modifying uni
        replace (bool): if False, do not delete any previous fields
        irrep (int): if symmetrized, the irrep to which the orbitals belong

    Warning:
        If replace is True, removes any fields previously attached to the universe
    """
    log = func_log(add_molecular_orbitals)
    if replace and hasattr(uni, '_field'): del uni.__dict__['_field']
    t1, vector, fps, x, y, z, bvs, mocoefs = \
        _setup_orbital(uni, verbose, vector, field_params, mocoefs, irrep=irrep, log=log)
    ovs = _compute_orbital(verbose, len(x), bvs, vector, mocoefs, log=log)
    field = _make_field(ovs, fps)
    return _teardown_orbital(uni, verbose, field, t1, inplace, log=log)
Esempio n. 3
0
def _compute_orbital(verbose, npts, bvs, vector, cmat, log=None):
    log = log or func_log(_compute_orbital)
    try: ovs = _compute_orbitals_numba(npts, bvs, vector, cmat)
    except (ValueError, IndexError, AssertionError, TypingError):
        if verbose: log.error('numba eval failed, falling back to numpy')
        ovs = _compute_orbitals_numpy(npts, bvs, vector, cmat)
    return ovs
Esempio n. 4
0
def add_orb_ang_mom(uni,
                    field_params=None,
                    rcoefs=None,
                    icoefs=None,
                    frame=0,
                    orbocc=None,
                    maxes=None,
                    inplace=True,
                    norm='Nd',
                    verbose=True):
    """A universe must contain basis_set, [basis_set_order], and
    momatrix attributes to use this function.  Compute the orbital
    angular momentum.  Requires C matrices from SODIZLDENS.X.X.R,I
    files from Molcas.

    Args:
        uni (:class:`~exatomic.container.Universe`): a universe
        field_params (dict): See :func:`~exatomic.algorithms.orbital_util.make_fps`
        rcoefs (str): column in uni.current_momatrix (default 'lreal')
        icoefs (str): column in uni.current_momatrix (default 'limag')
        maxes (np.ndarray): 3x3 array of magnetic axes (default np.eye(3))
        orbocc (str): column in uni.orbital (default 'lreal')
        inplace (bool): if False, return the field obj instead of modifying uni
    """
    log = func_log(add_orb_ang_mom)
    if rcoefs is None or icoefs is None:
        raise Exception("Must specify rcoefs and icoefs")
    rcol = rcoefs
    t1, vector, fps, x, y, z, bvs, rcoefs, icoefs = \
        _setup_orbital(uni, verbose, None, field_params, rcoefs, jcoefs=icoefs)
    orbocc = rcol if orbocc is None else orbocc
    if maxes is None:
        maxes = np.eye(3)
        if verbose:
            log.debug(
                "If magnetic axes are not an identity matrix, specify maxes.")
    occvec = uni.orbital[orbocc].values
    grx = uni.basis_functions.evaluate_diff(x, y, z, cart='x', verbose=verbose)
    gry = uni.basis_functions.evaluate_diff(x, y, z, cart='y', verbose=verbose)
    grz = uni.basis_functions.evaluate_diff(x, y, z, cart='z', verbose=verbose)
    t2 = datetime.now()
    if verbose:
        p1 = 'Timing: grid evaluation  - {:>8.2f}s.'
        log.info(p1.format((t2 - t1).total_seconds()))
    curx, cury, curz = _compute_current_density(bvs,
                                                grx,
                                                gry,
                                                grz,
                                                rcoefs,
                                                icoefs,
                                                occvec,
                                                verbose=verbose)
    t3 = datetime.now()
    if verbose:
        p2 = 'Timing: current density  - {:>8.2f}s.'
        log.info(p2.format((t3 - t2).total_seconds()))
    field = _make_field(_compute_orb_ang_mom(x, y, z, curx, cury, curz, maxes),
                        fps)
    return _teardown_orbital(uni, verbose, field, t1, inplace, name='angmom')
Esempio n. 5
0
def _teardown_orbital(uni, verbose, field, t1, inplace, name='orbitals', log=None):
    """Boilerplate for finishing the functions in this module."""
    log = log or func_log(_teardown_orbital)
    if verbose:
        t2 = datetime.now()
        p2 = 'Timing: compute {:<8} - {:>8.2f}s.'
        log.info(p2.format(name, (t2-t1).total_seconds()))
    if not inplace: return field
    uni.add_field(field)
Esempio n. 6
0
def add_density(uni,
                field_params=None,
                mocoefs=None,
                orbocc=None,
                inplace=True,
                frame=0,
                norm='Nd',
                verbose=True):
    """A universe must contain basis_set, [basis_set_order], and
    momatrix attributes to use this function.  Compute a density
    with C matrix mocoefs and occupation vector orbocc.

    Args:
        uni (:class:`~exatomic.container.Universe`): a universe
        field_params (dict): See :func:`~exatomic.algorithms.orbital_util.make_fps`
        mocoefs (str): column in uni.current_momatrix (default 'coef')
        orbocc (str): column in uni.orbital (default 'occupation')
        inplace (bool): if False, return the field obj instead of modifying uni
    """
    log = func_log(add_density)
    mocol = mocoefs
    t1, vector, fps, x, y, z, bvs, mocoefs = \
        _setup_orbital(uni, verbose, None, field_params, mocoefs, log=log)
    orbocc = mocol if orbocc is None and mocol != 'coef' else orbocc
    orbocc = _check_column(uni, 'orbital', orbocc)
    vector = uni.orbital[~np.isclose(uni.orbital[orbocc], 0)].index.values
    orbocc = uni.orbital.loc[vector][orbocc].values
    ovs = _compute_orbital(verbose, len(x), bvs, vector, mocoefs, log=log)
    field = _make_field(_compute_density(ovs, orbocc), fps.loc[0])
    return _teardown_orbital(uni,
                             verbose,
                             field,
                             t1,
                             inplace,
                             name='density',
                             log=log)