def compute_integrals(config):
    # Get config from input parameters
    # Molecule is in this format:
    # atoms=H .0 .0 .0; H .0 .0 0.2
    # units=Angstrom
    # charge=0
    # multiplicity=1
    # where we support symbol for atom as well as number

    if 'atoms' not in config:
        raise AquaChemistryError('Atoms is missing')
    val = config['atoms']
    if val is None:
        raise AquaChemistryError('Atoms value is missing')

    charge = int(config.get('charge', '0'))
    multiplicity = int(config.get('multiplicity', '1'))
    units = __checkUnits(config.get('units', 'Angstrom'))
    mol = __parseMolecule(val, units, charge, multiplicity)
    basis = config.get('basis', 'sto3g')
    calc_type = config.get('calc_type', 'rhf').lower()

    try:
        ehf, enuke, norbs, mohij, mohijkl, orbs, orbs_energy = _calculate_integrals(
            mol, basis, calc_type)
    except Exception as exc:
        raise AquaChemistryError(
            'Failed electronic structure computation') from exc

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    # Energies and orbits
    _q_._hf_energy = ehf
    _q_._nuclear_repulsion_energy = enuke
    _q_._num_orbitals = norbs
    _q_._num_alpha = mol.nup()
    _q_._num_beta = mol.ndown()
    _q_._mo_coeff = orbs
    _q_._orbital_energies = orbs_energy
    # Molecule geometry
    _q_._molecular_charge = mol.charge
    _q_._multiplicity = mol.multiplicity
    _q_._num_atoms = len(mol)
    _q_._atom_symbol = []
    _q_._atom_xyz = np.empty([len(mol), 3])
    atoms = mol.atoms
    for _n in range(0, _q_._num_atoms):
        atuple = atoms[_n].atuple()
        _q_._atom_symbol.append(QMolecule.symbols[atuple[0]])
        _q_._atom_xyz[_n][0] = atuple[1]
        _q_._atom_xyz[_n][1] = atuple[2]
        _q_._atom_xyz[_n][2] = atuple[3]
    # 1 and 2 electron integrals
    _q_._mo_onee_ints = mohij
    _q_._mo_eri_ints = mohijkl

    return _q_
def compute_integrals(config):
    # Get config from input parameters
    # molecule is in PySCF atom string format e.g. "H .0 .0 .0; H .0 .0 0.2"
    # other parameters are as per PySCF got.Mole format

    if 'atom' not in config:
        raise AquaChemistryError('Atom is missing')
    val = config['atom']
    if val is None:
        raise AquaChemistryError('Atom value is missing')

    atom = val
    basis = config.get('basis', 'sto3g')
    unit = config.get('unit', 'Angstrom')
    charge = int(config.get('charge', '0'))
    spin = int(config.get('spin', '0'))
    max_memory = config.get('max_memory')
    if max_memory is None:
        max_memory = param.MAX_MEMORY
    calc_type = config.get('calc_type', 'rhf').lower()

    try:
        mol = gto.Mole(atom=atom, unit=unit, basis=basis, max_memory=max_memory, verbose=pylogger.QUIET)
        mol.symmetry = False
        mol.charge = charge
        mol.spin = spin
        mol.build(parse_arg=False)
        ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip, y_dip, z_dip, nucl_dip = _calculate_integrals(mol, calc_type)
    except Exception as exc:
        raise AquaChemistryError('Failed electronic structure computation') from exc

    # Create driver level molecule object and populate
    _q_ = QMolecule()
    # Energies and orbits
    _q_._hf_energy = ehf
    _q_._nuclear_repulsion_energy = enuke
    _q_._num_orbitals = norbs
    _q_._num_alpha = mol.nelec[0]
    _q_._num_beta = mol.nelec[1]
    _q_._mo_coeff = mo_coeff
    _q_._orbital_energies = orbs_energy
    # Molecule geometry
    _q_._molecular_charge = mol.charge
    _q_._multiplicity = mol.spin + 1
    _q_._num_atoms = mol.natm
    _q_._atom_symbol = []
    _q_._atom_xyz = np.empty([mol.natm, 3])
    atoms = mol.atom_coords()
    for _n in range(0, _q_._num_atoms):
        xyz = mol.atom_coord(_n)
        _q_._atom_symbol.append(mol.atom_pure_symbol(_n))
        _q_._atom_xyz[_n][0] = xyz[0]
        _q_._atom_xyz[_n][1] = xyz[1]
        _q_._atom_xyz[_n][2] = xyz[2]
    # 1 and 2 electron integrals. h1 & h2 are ready to pass to FermionicOperator
    _q_._mo_onee_ints = mohij
    _q_._mo_eri_ints = mohijkl
    # dipole integrals
    _q_._x_dip_mo_ints = x_dip
    _q_._y_dip_mo_ints = y_dip
    _q_._z_dip_mo_ints = z_dip
    # dipole moment
    _q_._nuclear_dipole_moment = nucl_dip
    _q_._reverse_dipole_sign = True

    return _q_
Exemple #3
0
    def _parse_matrix_file(self, fname, useAO2E=False):
        mel = MatEl(file=fname)
        logger.debug('MatrixElement file:\n{}'.format(mel))

        # Create driver level molecule object and populate
        _q_ = QMolecule()
        # Energies and orbits
        _q_._hf_energy = mel.scalar('ETOTAL')
        _q_._nuclear_repulsion_energy = mel.scalar('ENUCREP')
        _q_._num_orbitals = 0 # updated below from orbital coeffs size
        _q_._num_alpha = (mel.ne+mel.multip-1)//2
        _q_._num_beta = (mel.ne-mel.multip+1)//2
        _q_._molecular_charge = mel.icharg
        # Molecule geometry
        _q_._multiplicity = mel.multip
        _q_._num_atoms = mel.natoms
        _q_._atom_symbol = []
        _q_._atom_xyz = np.empty([mel.natoms, 3])
        syms = mel.ian
        xyz = np.reshape(mel.c, (_q_._num_atoms, 3))
        for _n in range(0, _q_._num_atoms):
            _q_._atom_symbol.append(QMolecule.symbols[syms[_n]])
            for _i in range(xyz.shape[1]):
                coord = xyz[_n][_i]
                if abs(coord) < 1e-10:
                    coord = 0
                _q_._atom_xyz[_n][_i] = coord

        moc = self._getMatrix(mel, 'ALPHA MO COEFFICIENTS')
        _q_._num_orbitals = moc.shape[0]
        _q_._mo_coeff = moc
        orbs_energy = self._getMatrix(mel, 'ALPHA ORBITAL ENERGIES')
        _q_._orbital_energies = orbs_energy

        # 1 and 2 electron integrals
        hcore = self._getMatrix(mel, 'CORE HAMILTONIAN ALPHA')
        logger.debug('CORE HAMILTONIAN ALPHA {}'.format(hcore.shape))
        mohij = QMolecule.oneeints2mo(hcore, moc)
        if useAO2E:
            # These are 2-body in AO. We can convert to MO via the QMolecule
            # method but using ints in MO already, as in the else here, is better
            eri = self._getMatrix(mel, 'REGULAR 2E INTEGRALS')
            logger.debug('REGULAR 2E INTEGRALS {}'.format(eri.shape))
            mohijkl = QMolecule.twoeints2mo(eri, moc)
        else:
            # These are in MO basis but by default will be reduced in size by
            # frozen core default so to use them we need to add Window=Full
            # above when we augment the config
            mohijkl = self._getMatrix(mel, 'AA MO 2E INTEGRALS')
            logger.debug('AA MO 2E INTEGRALS {}'.format(mohijkl.shape))

        _q_._mo_onee_ints = mohij
        _q_._mo_eri_ints = mohijkl

        # dipole moment
        dipints = self._getMatrix(mel, 'DIPOLE INTEGRALS')
        dipints = np.einsum('ijk->kji', dipints)
        _q_._x_dip_mo_ints = QMolecule.oneeints2mo(dipints[0], moc)
        _q_._y_dip_mo_ints = QMolecule.oneeints2mo(dipints[1], moc)
        _q_._z_dip_mo_ints = QMolecule.oneeints2mo(dipints[2], moc)

        nucl_dip = np.einsum('i,ix->x', syms, xyz)
        nucl_dip = np.round(nucl_dip, decimals=8)
        _q_._nuclear_dipole_moment = nucl_dip
        _q_._reverse_dipole_sign = True

        return _q_