Пример #1
0
    def run(self, section):
        properties = section['properties']
        if HDF5Driver.KEY_HDF5_INPUT not in properties:
            raise AquaChemistryError('Missing hdf5 input property')

        hdf5_file = properties[HDF5Driver.KEY_HDF5_INPUT]
        if self.work_path is not None and not os.path.isabs(hdf5_file):
            hdf5_file = os.path.abspath(os.path.join(self.work_path,
                                                     hdf5_file))

        if not os.path.isfile(hdf5_file):
            raise LookupError('HDF5 file not found: {}'.format(hdf5_file))

        molecule = QMolecule(hdf5_file)
        molecule.load()
        return molecule
Пример #2
0
    def run(self, section):
        # create input
        psi4d_directory = os.path.dirname(os.path.realpath(__file__))
        template_file = psi4d_directory + '/_template.txt'
        aqua_chemistry_directory = os.path.abspath(
            os.path.join(psi4d_directory, '../..'))

        molecule = QMolecule()

        input_text = section['data'] + '\n'
        input_text += 'import sys\n'
        syspath = '[\'' + aqua_chemistry_directory + '\',\'' + '\',\''.join(
            sys.path) + '\']'

        input_text += 'sys.path = ' + syspath + ' + sys.path\n'
        input_text += 'from qmolecule import QMolecule\n'
        input_text += '_q_molecule = QMolecule("{0}")\n'.format(
            molecule.filename)

        with open(template_file, 'r') as f:
            input_text += f.read()

        fd, input_file = tempfile.mkstemp(suffix='.inp')
        os.close(fd)
        with open(input_file, 'w') as stream:
            stream.write(input_text)

        fd, output_file = tempfile.mkstemp(suffix='.out')
        os.close(fd)
        try:
            PSI4Driver._run_psi4(input_file, output_file)
            if logger.isEnabledFor(logging.DEBUG):
                with open(output_file, 'r') as f:
                    logger.debug('PSI4 output file:\n{}'.format(f.read()))
        finally:
            run_directory = os.getcwd()
            for local_file in os.listdir(run_directory):
                if local_file.endswith('.clean'):
                    os.remove(run_directory + '/' + local_file)
            try:
                os.remove('timer.dat')
            except:
                pass

            try:
                os.remove(input_file)
            except:
                pass

            try:
                os.remove(output_file)
            except:
                pass

        _q_molecule = QMolecule(molecule.filename)
        _q_molecule.load()
        # remove internal file
        _q_molecule.remove_file()
        return _q_molecule
Пример #3
0
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_
Пример #4
0
def _calculate_integrals(mol, calc_type='rhf'):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        mol : A PySCF gto.Mole object.
        calc_type: rhf, uhf, rohf
    Returns:
        ehf : Hartree-Fock energy
        enuke : Nuclear repulsion energy
        norbs : Number of orbitals
        mohij : One electron terms of the Hamiltonian.
        mohijkl : Two electron terms of the Hamiltonian.
        mo_coeff: Orbital coefficients
        orbs_energy: Orbitals energies
        x_dip_ints: x dipole moment integrals
        y_dip_ints: y dipole moment integrals
        z_dip_ints: z dipole moment integrals
        nucl_dipl : Nuclear dipole moment
    """
    enuke = gto.mole.energy_nuc(mol)

    if calc_type == 'rhf':
        mf = scf.RHF(mol)
    elif calc_type == 'rohf':
        mf = scf.ROHF(mol)
    elif calc_type == 'uhf':
        mf = scf.UHF(mol)
    else:
        raise AquaChemistryError('Invalid calc_type: {}'.format(calc_type))

    ehf = mf.kernel()

    if type(mf.mo_coeff) is tuple:
        mo_coeff = mf.mo_coeff[0]
        mo_occ   = mf.mo_occ[0]
    else:
        mo_coeff = mf.mo_coeff
        mo_occ   = mf.mo_occ

    norbs = mo_coeff.shape[0]
    orbs_energy = mf.mo_energy

    hij = mf.get_hcore()
    mohij = np.dot(np.dot(mo_coeff.T, hij), mo_coeff)

    eri = ao2mo.incore.full(mf._eri, mo_coeff, compact=False)
    mohijkl = eri.reshape(norbs, norbs, norbs, norbs)

    # dipole integrals
    mol.set_common_orig((0, 0, 0))
    ao_dip = mol.intor_symmetric('int1e_r', comp=3)
    x_dip_ints = QMolecule.oneeints2mo(ao_dip[0], mo_coeff)
    y_dip_ints = QMolecule.oneeints2mo(ao_dip[1], mo_coeff)
    z_dip_ints = QMolecule.oneeints2mo(ao_dip[2], mo_coeff)

    dm = mf.make_rdm1(mf.mo_coeff, mf.mo_occ)
    if calc_type == 'rohf' or calc_type == 'uhf':
        dm = dm[0]
    elec_dip = np.negative(np.einsum('xij,ji->x', ao_dip, dm).real)
    elec_dip = np.round(elec_dip, decimals=8)
    nucl_dip = np.einsum('i,ix->x', mol.atom_charges(), mol.atom_coords())
    nucl_dip = np.round(nucl_dip, decimals=8)
    logger.info("HF Electronic dipole moment: {}".format(elec_dip))
    logger.info("Nuclear dipole moment: {}".format(nucl_dip))
    logger.info("Total dipole moment: {}".format(nucl_dip+elec_dip))

    return ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip_ints, y_dip_ints, z_dip_ints, nucl_dip
Пример #5
0
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_
Пример #6
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_