def run(self, input, output=None):
        if input is None:
            raise ACQUAChemistryError("Missing input.")

        self._parser = InputParser(input)
        self._parser.parse()
        driver_return = self._run_driver_from_parser(self._parser, False)
        if driver_return[0] == ACQUAChemistry._DRIVER_RUN_TO_HDF5:
            logger.info('No further process.')
            return {'printable': [driver_return[1]]}

        data = run_algorithm(driver_return[1], driver_return[2], True)
        if not isinstance(data, dict):
            raise ACQUAChemistryError(
                "Algorithm run result should be a dictionary")

        if logger.isEnabledFor(logging.DEBUG):
            logger.debug('Algorithm returned: {}'.format(
                json.dumps(data, indent=4)))

        convert_json_to_dict(data)
        lines, result = self._format_result(data)
        logger.info('Processing complete. Final result available')
        result['printable'] = lines

        if output is not None:
            with open(output, 'w') as f:
                for line in lines:
                    print(line, file=f)

        return result
Esempio n. 2
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 ACQUAChemistryError('Atoms is missing')
    val = config['atoms']
    if val is None:
        raise ACQUAChemistryError('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 ACQUAChemistryError('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_
Esempio n. 3
0
 def set_default_properties_for_name(self,section_name):
     if self._parser is None:
         raise ACQUAChemistryError('Input not initialized.')
         
     name = self._parser.get_section_property(section_name,InputParser.NAME)
     self._parser.delete_section_properties(section_name)
     if name is not None:
         self._parser.set_section_property(section_name,InputParser.NAME,name)
         
     value = self._parser.get_section_default_properties(section_name)
     if isinstance(value,dict):
         for property_name,property_value in value.items():
             if property_name != InputParser.NAME:
                 self._parser.set_section_property(section_name,property_name,property_value)
     else:
         if value is None:
             types = self._parser.get_section_types(section_name)
             if 'null' not in types:
                 if 'string' in types:
                     value = ''
                 elif 'object' in types:
                     value = {}
                 elif 'array' in types:
                     value = []
             
         self._parser.set_section_data(section_name,value)
    def run(self, section):
        cfg = section['data']
        if cfg is None or not isinstance(cfg, str):
            raise ACQUAChemistryError(
                "Gaussian user supplied configuration invalid: '{}'".format(
                    cfg))

        while not cfg.endswith('\n\n'):
            cfg += '\n'

        logger.debug("User supplied configuration raw: '{}'".format(
            cfg.replace('\r', '\\r').replace('\n', '\\n')))
        logger.debug('User supplied configuration\n{}'.format(cfg))

        # To the Gaussian section of the input file passed here as section['data']
        # add line '# Symm=NoInt output=(matrix,i4labels,mo2el) tran=full'
        # NB: Line above needs to be added in right context, i.e after any lines
        #     beginning with % along with any others that start with #
        # append at end the name of the MatrixElement file to be written

        fd, fname = tempfile.mkstemp(suffix='.mat')
        os.close(fd)

        cfg = self._augment_config(fname, cfg)
        logger.debug('Augmented control information:\n{}'.format(cfg))

        GaussianDriver._run_g16(cfg)

        q_mol = self._parse_matrix_file(fname)
        try:
            os.remove(fname)
        except:
            logger.warning("Failed to remove MatrixElement file " + fname)

        return q_mol
Esempio n. 5
0
 def delete_section_property(self, section_name, property_name):
     if self._parser is None:
         raise ACQUAChemistryError('Input not initialized.')
         
     self._parser.delete_section_property(section_name, property_name)
     if InputParser.is_pluggable_section(section_name) and property_name == InputParser.NAME:
         self._parser.delete_section_properties(section_name)
Esempio n. 6
0
def __parseAtom(val):
    if val is None or len(val) < 1:
        raise ACQUAChemistryError('Molecule atom format error: ' + val)

    parts = re.split('\s+', val)
    if len(parts) != 4:
        raise ACQUAChemistryError('Molecule atom format error: ' + val)

    parts[0] = parts[0].lower().capitalize()
    if not parts[0].isdigit():
        if parts[0] in QMolecule.symbols:
            parts[0] = QMolecule.symbols.index(parts[0])
        else:
            raise ACQUAChemistryError('Molecule atom symbol error: ' + parts[0])

    return int(float(parts[0])), float(parts[1]), float(parts[2]), float(parts[3])
Esempio n. 7
0
def __parseMolecule(val, units, charge, multiplicity):
    parts = [x.strip() for x in val.split(';')]
    if parts is None or len(parts) < 1:
        raise ACQUAChemistryError('Molecule format error: ' + val)
    geom = []
    for n in range(len(parts)):
        part = parts[n]
        geom.append(__parseAtom(part))

    if len(geom) < 1:
        raise ACQUAChemistryError('Molecule format error: ' + val)

    try:
        return molecule(geom, units=units, charge=charge, multiplicity=multiplicity)
    except Exception as exc:
        raise ACQUAChemistryError('Failed to create molecule') from exc
Esempio n. 8
0
 def set_section(self,section_name):
     if self._parser is None:
         raise ACQUAChemistryError('Input not initialized.')
         
     self._parser.set_section(section_name)
     value = self._parser.get_section_default_properties(section_name)
     if isinstance(value,dict):
         for property_name,property_value in value.items():
             self._parser.set_section_property(section_name,property_name,property_value)
             
         # do one more time in case schema was updated
         value = self._parser.get_section_default_properties(section_name)
         for property_name,property_value in value.items():
             self._parser.set_section_property(section_name,property_name,property_value)             
     else:
         if value is None:
             types = self._parser.get_section_types(section_name)
             if 'null' not in types:
                 if 'string' in types:
                     value = ''
                 elif 'object' in types:
                     value = {}
                 elif 'array' in types:
                     value = []
             
         self._parser.set_section_data(section_name,value)
Esempio n. 9
0
def __checkUnits(units):
    if units.lower() in ["angstrom", "ang", "a"]:
        units = 'Angstrom'
    elif units.lower() in ["bohr", "b"]:
        units = 'Bohr'
    else:
        raise ACQUAChemistryError('Molecule units format error: ' + units)
    return units
Esempio n. 10
0
def register_chemistry_operator(cls, configuration=None):
    """
    Registers a chemistry operator class
    Args:
        cls (object): chemistry operator class.
        configuration (object, optional): Pluggable configuration
    Returns:
        name: input name
    Raises:
        ACQUAChemistryError: if the class is already registered or could not be registered
    """
    _discover_on_demand()

    # Verify that the pluggable is not already registered
    if cls in [
            input.cls for input in _REGISTERED_CHEMISTRY_OPERATORS.values()
    ]:
        raise ACQUAChemistryError(
            'Could not register class {} is already registered'.format(cls))

    try:
        chem_instance = cls(configuration=configuration)
    except Exception as err:
        raise ACQUAChemistryError(
            'Could not register chemistry operator:{} could not be instantiated: {}'
            .format(cls, str(err)))

    # Verify that it has a minimal valid configuration.
    try:
        chemistry_operator_name = chem_instance.configuration['name']
    except (LookupError, TypeError):
        raise ACQUAChemistryError(
            'Could not register chemistry operator: invalid configuration')

    if chemistry_operator_name in _REGISTERED_CHEMISTRY_OPERATORS:
        raise ACQUAChemistryError(
            'Could not register class {}. Name {} {} is already registered'.
            format(
                cls, chemistry_operator_name,
                _REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name].cls))

    # Append the pluggable to the `registered_classes` dict.
    _REGISTERED_CHEMISTRY_OPERATORS[
        chemistry_operator_name] = RegisteredChemOp(
            chemistry_operator_name, cls, chem_instance.configuration)
    return chemistry_operator_name
    def save_input(self, input_file):
        """Save the input of a run to a file.
        Params:
            input_file (string): file path
        """
        if self._parser is None:
            raise ACQUAChemistryError("Missing input information.")

        self._parser.save_to_file(input_file)
Esempio n. 12
0
def _calculate_integrals(molecule, basis='sto3g', calc_type='rhf'):
    """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in
        the given basis.
    Args:
        molecule : A pyquante2 molecular object.
        basis : The basis set for the electronic structure computation
        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.
        orbs: Molecular orbital coefficients
        orbs_energy: Orbital energies
    """
    bfs = basisset(molecule, basis)
    integrals = onee_integrals(bfs, molecule)
    hij = integrals.T + integrals.V
    hijkl_compressed = twoe_integrals(bfs)

    # convert overlap integrals to molecular basis
    # calculate the Hartree-Fock solution of the molecule

    if calc_type == 'rhf':
        solver = rhf(molecule, bfs)
    elif calc_type == 'rohf':
        solver = rohf(molecule, bfs)
    elif calc_type == 'uhf':
        solver = uhf(molecule, bfs)
    else:
        raise ACQUAChemistryError('Invalid calc_type: {}'.format(calc_type))
    logger.debug('Solver name {}'.format(solver.name))
    ehf = solver.converge()
    if hasattr(solver, 'orbs'):
        orbs = solver.orbs
    else:
        orbs = solver.orbsa
    norbs = len(orbs)
    if hasattr(solver, 'orbe'):
        orbs_energy = solver.orbe
    else:
        orbs_energy = solver.orbea
    enuke = molecule.nuclear_repulsion()
    # Get ints in molecular orbital basis
    mohij = simx(hij, orbs)
    mohijkl_compressed = transformintegrals(hijkl_compressed, orbs)
    mohijkl = np.zeros((norbs, norbs, norbs, norbs))
    for i in range(norbs):
        for j in range(norbs):
            for k in range(norbs):
                for l in range(norbs):
                    mohijkl[i, j, k, l] = mohijkl_compressed[ijkl2intindex(i, j, k, l)]

    return ehf[0], enuke, norbs, mohij, mohijkl, orbs, orbs_energy
    def _run_drive(self, input, save_json_algo_file):
        if input is None:
            raise ACQUAChemistryError("Missing input.")

        self._parser = InputParser(input)
        self._parser.parse()
        driver_return = self._run_driver_from_parser(self._parser,
                                                     save_json_algo_file)
        driver_return[1]['input'] = driver_return[2].to_params()
        driver_return[1]['input']['name'] = driver_return[2].configuration[
            'name']
        return driver_return[1]
Esempio n. 14
0
 def set_section_property(self, section_name, property_name, value):
     if self._parser is None:
         raise ACQUAChemistryError('Input not initialized.')
         
     self._parser.set_section_property(section_name,property_name,value)
     if InputParser.is_pluggable_section(section_name) and property_name == InputParser.NAME:
         properties = self._parser.get_section_default_properties(section_name)
         if isinstance(properties,dict):
             properties[ InputParser.NAME] = value
             self._parser.delete_section_properties(section_name)
             for property_name,property_value in properties.items():  
                 self._parser.set_section_property(section_name,property_name,property_value)
    def _run_g16(cfg):

        # Run Gaussian 16. We capture stdout and if error log the last 10 lines that
        # should include the error description from Gaussian
        process = None
        try:
            process = Popen(GAUSSIAN_16,
                            stdin=PIPE,
                            stdout=PIPE,
                            universal_newlines=True)
            stdout, stderr = process.communicate(cfg)
            process.wait()
        except:
            if process is not None:
                process.kill()

            raise ACQUAChemistryError(
                '{} run has failed'.format(GAUSSIAN_16_DESC))

        if process.returncode != 0:
            errmsg = ""
            if stdout is not None:
                lines = stdout.splitlines()
                start = 0
                if len(lines) > 10:
                    start = len(lines) - 10
                for i in range(start, len(lines)):
                    logger.error(lines[i])
                    errmsg += lines[i] + "\n"
            raise ACQUAChemistryError('{} process return code {}\n{}'.format(
                GAUSSIAN_16_DESC, process.returncode, errmsg))
        else:
            if logger.isEnabledFor(logging.DEBUG):
                alltext = ""
                if stdout is not None:
                    lines = stdout.splitlines()
                    for line in lines:
                        alltext += line + "\n"
                logger.debug("Gaussian output:\n{}".format(alltext))
Esempio n. 16
0
    def _run_psi4(input_file, output_file):
        
        # Run psi4.
        process = None
        try:
            process = subprocess.Popen([PSI4, input_file, output_file],
                                       stdout=subprocess.PIPE, universal_newlines=True)
            stdout, stderr = process.communicate()
            process.wait()
        except:
            if process is not None:
                process.kill()
            
            raise ACQUAChemistryError('{} run has failed'.format(PSI4))

        if process.returncode != 0:
            errmsg = ""
            if stdout is not None:
                lines = stdout.splitlines()
                for i in range(len(lines)):
                    logger.error(lines[i])
                    errmsg += lines[i]+"\n"
            raise ACQUAChemistryError('{} process return code {}\n{}'.format(PSI4, process.returncode, errmsg))
    def run_drive_to_jsonfile(self, input, jsonfile):
        if jsonfile is None:
            raise ACQUAChemistryError("Missing json file")

        data = self._run_drive(input, True)
        if data is None:
            logger.info('No data to save. No further process.')
            return

        logger.debug('Result: {}'.format(
            json.dumps(data, sort_keys=True, indent=4)))
        with open(jsonfile, 'w') as fp:
            json.dump(data, fp, sort_keys=True, indent=4)

        print("Algorithm input file saved: '{}'".format(jsonfile))
Esempio n. 18
0
def deregister_chemistry_operator(chemistry_operator_name):
    """
    Deregisters a chemistry operator class
    Args:
        chemistry_operator_name(str): The chemistry operator name
    Raises:
        ACQUAChemistryError: if the class is not registered
    """
    _discover_on_demand()

    if chemistry_operator_name not in _REGISTERED_CHEMISTRY_OPERATORS:
        raise ACQUAChemistryError(
            'Could not deregister {} not registered'.format(
                chemistry_operator_name))

    _REGISTERED_CHEMISTRY_OPERATORS.pop(chemistry_operator_name)
    def run(self, section):
        properties = section['properties']
        if HDF5Driver.KEY_HDF5_INPUT not in properties:
            raise ACQUAChemistryError('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
Esempio n. 20
0
def get_chemistry_operator_class(chemistry_operator_name):
    """
    Accesses chemistry operator class
    Args:
        chemistry_operator_name (str): The chemistry operator name
    Returns:
        cls: chemistry operator class
    Raises:
        ACQUAChemistryError: if the class is not registered
    """
    _discover_on_demand()

    if chemistry_operator_name not in _REGISTERED_CHEMISTRY_OPERATORS:
        raise ACQUAChemistryError(
            '{} not registered'.format(chemistry_operator_name))

    return _REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name].cls
    def run_algorithm_from_json(self, params, output=None):
        ret = run_algorithm(params, None, True)
        if not isinstance(ret, dict):
            raise ACQUAChemistryError(
                "Algorithm run result should be a dictionary")

        logger.debug('Algorithm returned: {}'.format(json.dumps(ret,
                                                                indent=4)))
        convert_json_to_dict(ret)
        print('Output:')
        if isinstance(ret, dict):
            for k, v in ret.items():
                print("'{}': {}".format(k, v))
        else:
            print(ret)

        return ret
Esempio n. 22
0
def get_chemistry_operator_instance(chemistry_operator_name):
    """
    Instantiates a chemistry operator class
    Args:
        chemistry_operator_name (str): The chemistry operator name 
    Returns:
        instance: chemistry operator instance
    Raises:
        ACQUAChemistryError: if the class is not registered
    """
    _discover_on_demand()

    if chemistry_operator_name not in _REGISTERED_CHEMISTRY_OPERATORS:
        raise ACQUAChemistryError(
            '{} not registered'.format(chemistry_operator_name))

    return _REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name].cls(
        configuration=_REGISTERED_CHEMISTRY_OPERATORS[chemistry_operator_name].
        configuration)
Esempio n. 23
0
    def mapping(self, map_type, threshold=0.00000001, num_workers=4):
        """
        Using multiprocess to speedup the mapping, the improvement can be
        observed when h2 is a non-sparse matrix.

        Args:
            map_type (str): case-insensitive mapping type. "jordan_wigner", "parity", "bravyi_kitaev"
            threshold (float): threshold for Pauli simplification
            num_workers (int): number of processes used to map.

        Returns:
            Operator: create an Operator object in Paulis form.

        Raises:
            ACQUAChemistryError: if the `map_type` can not be recognized.
        """
        """
        ####################################################################
        ############   DEFINING MAPPED FERMIONIC OPERATORS    ##############
        ####################################################################
        """
        n = self._h1.shape[0]  # number of fermionic modes / qubits
        map_type = map_type.lower()
        if map_type == 'jordan_wigner':
            a = self._jordan_wigner_mode(n)
        elif map_type == 'parity':
            a = self._parity_mode(n)
        elif map_type == 'bravyi_kitaev':
            a = self._bravyi_kitaev_mode(n)
        else:
            raise ACQUAChemistryError(
                'Please specify the supported modes: jordan_wigner, parity, bravyi_kitaev'
            )
        """
        ####################################################################
        ############    BUILDING THE MAPPED HAMILTONIAN     ################
        ####################################################################
        """
        max_workers = min(num_workers, multiprocessing.cpu_count())
        pauli_list = Operator(paulis=[])
        with concurrent.futures.ProcessPoolExecutor(
                max_workers=max_workers) as executor:
            #######################    One-body    #############################
            futures = [
                executor.submit(FermionicOperator._one_body_mapping,
                                self._h1[i, j], a[i], a[j], threshold)
                for i, j in itertools.product(range(n), repeat=2)
                if self._h1[i, j] != 0
            ]
            for future in concurrent.futures.as_completed(futures):
                result = future.result()
                pauli_list += result
            pauli_list.chop(threshold=threshold)

            #######################    Two-body    #############################
            futures = [
                executor.submit(FermionicOperator._two_body_mapping,
                                self._h2[i, j, k,
                                         m], a[i], a[j], a[k], a[m], threshold)
                for i, j, k, m in itertools.product(range(n), repeat=4)
                if self._h2[i, j, k, m] != 0
            ]
            for future in concurrent.futures.as_completed(futures):
                result = future.result()
                pauli_list += result
            pauli_list.chop(threshold=threshold)

        if self._ph_trans_shift is not None:
            pauli_list += Operator(paulis=[[
                self._ph_trans_shift,
                label_to_pauli('I' * self._h1.shape[0])
            ]])

        return pauli_list
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 ACQUAChemistryError('Atom is missing')
    val = config['atom']
    if val is None:
        raise ACQUAChemistryError('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 ACQUAChemistryError(
            '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[0]
    _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_
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 ACQUAChemistryError('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
Esempio n. 26
0
 def export_dictionary(self,filename):
     if self.is_empty():
         raise ACQUAChemistryError("Empty input data.")
             
     self._parser.export_dictionary(filename) 
Esempio n. 27
0
 def get_dictionary(self):
     if self.is_empty():
         raise ACQUAChemistryError("Empty input data.")
         
     return self._parser.to_dictionary()
Esempio n. 28
0
 def save_to_file(self,filename):
     if self.is_empty():
         raise ACQUAChemistryError("Empty input data.")
             
     self._parser.save_to_file(filename) 
Esempio n. 29
0
 def delete_section_text(self, section_name):  
     if self._parser is None:
         raise ACQUAChemistryError('Input not initialized.')
         
     self._parser.delete_section_text(section_name)
Esempio n. 30
0
 def set_section_text(self, section_name, value):  
     if self._parser is None:
         raise ACQUAChemistryError('Input not initialized.')
         
     self._parser.set_section_data(section_name, value)