示例#1
0
def get_basis_dict(bso, x0):
    '''
    Return a dictionary with :py:class:`BasisSet` objects as values and
    element symbols as keys. The dictionary is composed based on the current
    parameters ``x0`` and attributes of the :py:class:`BSOptimizer` including
    the ``staticbs``
    '''

    bsdict = dict()
    for atom, functs in bso.fsopt.items():
        bsdict[atom] = BasisSet.from_optpars(x0, funs=functs, name='opt',
                                             element=atom, explogs=bso.uselogs)

    if bso.staticbs is not None:
        if isinstance(bso.staticbs, dict):
            common_atoms = set(bso.staticbs.keys()) & set(bsdict.keys())
            if common_atoms:
                for atom in common_atoms:
                    bsdict[atom].append(bso.staticbs[atom])
            diff_atoms = set(bso.staticbs.keys()) - set(bsdict.keys())
            if diff_atoms:
                for atom in diff_atoms:
                    bsdict[atom] = bso.staticbs[atom]
        elif isinstance(bso.staticbs, BasisSet):
            if bso.staticbs.element in set(bsdict.keys()):
                bsdict[atom].append(bso.staticbs)
            else:
                bsdict[bso.staticbs.element] = bso.staticbs

    return bsdict
示例#2
0
    def get_basis(self, name=None, element=None):
        '''
        Construct the BasisSet object from the result of the
        optimized exponents and function definition.

        Args:
            name : str
                Name to be assigned to the basis set
            element : str
                Element symbol for the basis set

        Returns:
            basis : chemtools.basisset.BasisSet
                :py:class:`BasisSet <chemtools.basisset.BasisSet>` object with
                the optimized functions
        '''

        bsdict = {}
        # get number of parameters per atom
        npars = [sum(get_num_params(t) for t in funs) for funs in self.fsopt.values()]
        x0peratom = sliceinto(self.result.x, npars)
        for (atom, funs), xpars in zip(self.fsopt.items(), x0peratom):

            bsdict[atom] = BasisSet.from_optpars(xpars, funs, name=name,
                                                 element=element,
                                                 explogs=self.uselogs)

        if self.staticbs is not None:
            if isinstance(self.staticbs, dict):
                common_atoms = set(self.staticbs.keys()) & set(bsdict.keys())
                if common_atoms:
                    for atom in common_atoms:
                        bsdict[atom].append(self.staticbs[atom])
                diff_atoms = set(self.staticbs.keys()) - set(bsdict.keys())
                if diff_atoms:
                    for atom in diff_atoms:
                        bsdict[atom] = self.staticbs[atom]
            elif isinstance(self.staticbs, BasisSet):
                if self.staticbs.element in set(bsdict.keys()):
                    bsdict[atom].append(self.staticbs)
                else:
                    bsdict[self.staticbs.element] = self.staticbs

        return bsdict
示例#3
0
def run_core_energy(x0, *args):
    '''
    Funtion for running two single point calculations and parsing the resulting
    energy (or property) as specified by the objective function, primarily
    designed to extract core energy.

    Args:
        x0: list or numpy.array
            contains a list of parameters to be optimized, may be
            explicit exponents or parametrized exponents in terms
            of some polynomial
        args: tuple of dicts
            bsopt, bsnoopt, code, job, mol, opt, needed for writing
            input and parsing output
    Returns:
        parsed result of the single point calculation as speficied by the
        objective function in the "job" dictionary
    '''

    # unpack the args tuple for code readability
    bso = args[0]

    for atom, functs in bso.fsopt.items():
        ni = 0
        nt = 0
        for shell, seq, nf, params in functs:
            nt += nf
            if seq not in ['le', 'legendre'] and not bso.uselogs:
                x0[ni:nt] = np.abs(x0[ni:nt])
            ni += nf

    bsdict = get_basis_dict(bso, x0)

    # set the penalty value
    if bso.penalize:
        penalty = get_penalty(bsdict, bso.penaltykwargs)
    else:
        penalty = 1.0

    if bso.verbose:
        bso.log.write("Current exponents being optimized:\n")
        for atom, functs in bso.fsopt.items():
            basis = BasisSet.from_optpars(x0, funs=functs, name='opt',
                                          element=atom, explogs=bso.uselogs)
            bso.log.write(atom + "\n" + basis.print_functions())
            bso.log.flush()

    citote = []
    stats = []
    base = os.path.splitext(bso.fname)[0]
    inputs = [base + "_core" + str(sum(x)) + ".inp" for x in bso.core]

    for inpname, core in zip(inputs, bso.core):
        bso.code.write_input(fname=inpname, core=core, basis=bsdict,
                             mol=bso.mol, template=bso.template)

    outputs = bso.code.run_multiple(inputs)
    for output in outputs:
        citote.append(bso.code.parse(output, bso.objective, bso.regexp))
        stats.append(bso.code.accomplished(output))

    if stats[0] and stats[1]:
        if bso.verbose:
            bso.log.write("x0 : " + ", ".join([str(x) for x in x0]) + "\n")
            bso.log.write("{0:<20s} : {1:>30s} {2:>30s}\n".format("Terminated OK",
                                                                str(stats[0]),
                                                                str(stats[1])))
            bso.log.write("{0:<20s} : {1:>30.10f} {2:>30.10f}\n".format(str(bso.objective),
                                                              citote[0],
                                                              citote[1]))
            bso.log.write("-" * 84)
        coreenergy = citote[0] - citote[1]
        if coreenergy > 0.0:
            coreenergy = -1.0 * coreenergy
        if bso.verbose:
            bso.log.write("{0:<20s} : {1:>30.10f}\n".format("Core energy",
                                                            coreenergy))
            bso.log.write("{0:<20s} : {1:>30.10f}\n".format("Objective",
                                                            coreenergy * penalty))
            bso.log.write("=" * 84)
        bso.log.flush()
        return coreenergy * penalty
    else:
        raise ValueError("something went wrong, check outputs {0:s}".format(", ".join(outputs)))
示例#4
0
def run_total_energy(x0, *args):
    '''
    Funtion for running a single point calculation and parsing the resulting
    energy (or property) as specified by the objective function.

    Args:
        x0 : list or numpy.array
            contains a list of parameters to be optimized, may be
            explicit exponents or parametrized exponents in terms
            of some polynomial
        args : tuple of dicts
            bsopt, bsnoopt, code, job, mol, opt, needed for writing
            input and parsing output

    Returns:
        parsed result of the single point calculation as speficied by the
        objective function in the "job" dictionary

    '''

    # unpack the args tuple for code readability
    bso = args[0]

    for atom, functs in bso.fsopt.items():
        ni = 0
        nt = 0
        for shell, seq, nf, params in functs:
            nt += nf
            if seq not in ['le', 'legendre'] and not bso.uselogs:
                x0[ni:nt] = np.abs(x0[ni:nt])
            ni += nf

    bsdict = get_basis_dict(bso, x0)

    # set the penalty value
    if bso.penalize:
        penalty = get_penalty(bsdict, **bso.penaltykwargs)
    else:
        penalty = 1.0

    if bso.verbose:
        bso.log.write("Current exponents being optimized:\n")
        for atom, functs in bso.fsopt.items():
            basis = BasisSet.from_optpars(x0, funs=functs, name='opt',
                                          element=atom, explogs=bso.uselogs)
            bso.log.write(atom + basis.print_functions())
            bso.log.flush()

    bso.code.write_input(fname=bso.fname, template=bso.template, basis=bsdict,
                         mol=bso.mol, core=bso.core)
    output = bso.code.run(bso.fname)
    if bso.code.accomplished(output):

        if callable(bso.objective):
            objective = bso.objective(output)
        else:
            objective = bso.code.parse(output, bso.objective, bso.regexp)

        if objective is None:
            raise ValueError("Unable to parse the objective, check output")
        if bso.verbose:
            bso.log.write("{0:<s}".format("Job Terminated without errors\n"))
            bso.log.write("x0 : " + ", ".join([str(x) for x in x0]) + "\n")
            bso.log.write("\n{0:<20s} : {1:>30s}\n".format("Output", output))
            bso.log.write("{0:<20s} : {1:>30.10f}\n".format(str(bso.objective), objective))
            bso.log.write("{0:<20s} : {1:>30.10f}\n".format("Objective", objective * penalty))
            bso.log.write("=" * 80 + "\n")
            bso.log.flush()
        return objective * penalty
    else:
        raise ValueError("something went wrong, check output {0:s}".format(output))