Example #1
0
class TestFromPrevious(HartreeFockTestCase):
    def __run_test_same(self, name):
        case = testdata.test_cases_by_name(name)[0]

        inp = case["input_parameters"]
        scfparams = molsturm.ScfParameters.from_dict(inp)
        scfparams_lowtol = molsturm.ScfParameters.from_dict(inp)
        scfparams_lowtol["scf/con_tol"] = 1e-5

        try:
            scfparams.normalise()
            scfparams_lowtol.normalise()
        except (ValueError, KeyError, TypeError) as e:
            raise unittest.SkipTest("Skipped subtest " + case["testing"]["name"] +
                                    ", since construction of ScfParameters "
                                    "failed: " + str(e))

        res = molsturm.self_consistent_field(scfparams_lowtol)

        # Construct extrapolated guess and run again
        guess = extrapolate_from_previous(res, scfparams)
        scfparams.set_guess_external(*guess)
        hfres = molsturm.self_consistent_field(scfparams)

        self.assertLessEqual(hfres["final_error_norm"], res["final_error_norm"])
        self.assertLessEqual(hfres["n_iter"], 3)
        self.compare_hf_results_small(case, hfres)
Example #2
0
    def test_0_hf(self):
        for case in self.cases:

            testing = case["testing"]
            name = testing["name"]
            with self.subTest(label=name):
                scfparams = molsturm.ScfParameters.from_dict(case["input_parameters"])

                # Update parameters if posthf is done
                hf = molsturm.self_consistent_field(scfparams)

                self.compare_hf_results(case, hf)
                self.hf_results[testing["name"]] = hf
Example #3
0
def run_matrix_free(system, basis, extra={}):
    params = molsturm.ScfParameters()
    params.system = system
    params.basis = basis
    params["guess/method"] = "random"
    params["guess/eigensolver/method"] = "arpack"
    params["scf/eigensolver/method"] = "arpack"
    params["scf/n_eigenpairs"] = 2 * (basis.size // 2)
    params.update(extra)

    res = molsturm.self_consistent_field(params)
    molsturm.print_convergence_summary(res)
    molsturm.print_energies(res)
    molsturm.print_mo_occupation(res)
    molsturm.print_quote(res)
    return res
Example #4
0
    def test_hf(self):
        for case in self.cases:
            testing = case["testing"]

            with self.subTest(label=testing["name"]):
                try:
                    scfparams = molsturm.ScfParameters.from_dict(
                        case["input_parameters"])
                    scfparams.normalise()
                except (ValueError, KeyError, TypeError) as e:
                    raise unittest.SkipTest(
                        "Skipped subtest " + testing["name"] +
                        ", since construction of ScfParameters "
                        "failed: " + str(e))

                hfres = molsturm.self_consistent_field(scfparams)
                self.compare_hf_results(case, hfres)
Example #5
0
def main():
    carbon = molsturm.System("c")
    carbon.multiplicity = 3

    params = molsturm.ScfParameters()
    params.system = carbon
    params.basis = molsturm.construct_basis("sturmian/atomic/cs_reference_pc",
                                            params.system, k_exp=3.3, n_max=4,
                                            l_max=3)
    params["scf/eigensolver/method"] = "lapack"
    params["scf/print_iterations"] = True
    params["guess/eigensolver/method"] = "lapack"

    res = molsturm.self_consistent_field(params)
    molsturm.print_convergence_summary(res)
    molsturm.print_energies(res)
    molsturm.print_mo_occupation(res)
    molsturm.print_quote(res)
    return res
Example #6
0
def run_scf_calculation(name, scfparams):
    if name not in calculation_scf_cache:
        print_status("run_hf", "Running HF calculation")
        calculation_scf_cache[name] = molsturm.self_consistent_field(scfparams)
    return calculation_scf_cache[name]
Example #7
0
        try:
            scfparams.normalise()
        except (ValueError, KeyError, TypeError) as e:
            raise unittest.SkipTest("Skipped subtest " + case["testing"]["name"] +
                                    ", since construction of ScfParameters "
                                    "failed: " + str(e))

        smallparams = scfparams.copy()
        origbasis = scfparams.basis

        smallparams.basis = molsturm.construct_basis(
            "sturmian/atomic", scfparams.system, n_max=n_max, l_max=l_max,
            m_max=m_max, k_exp=origbasis.k_exp, backend=origbasis.backend
        )
        smallres = molsturm.self_consistent_field(smallparams)

        res_no_guess = molsturm.self_consistent_field(scfparams)

        guess = molsturm.scf_guess.extrapolate_from_previous(smallres, scfparams)
        scfparams.set_guess_external(*guess)
        res_guess = molsturm.self_consistent_field(scfparams)

        self.assertAlmostEqual(res_no_guess["energy_ground_state"],
                               res_guess["energy_ground_state"],
                               tol=case["testing"]["numeric_tolerance"],
                               prefix="Energy of ground state without and with guess: ")

        self.assertLess(res_guess["n_iter"], res_no_guess["n_iter"],
                        msg="Number of iterations with guess not smaller than without.")
Example #8
0
def extrapolate_cbs_limit(scfparams, n_points=3, quantity="hfenergy"):
    """
    Perform an automatic CBS extrapolation for a particular quantity using
    the basis set family specified in the ScfParameters object as well
    as n_points points on the CBS surface, where the first point of the
    extrapolation is exactly the basis set specified in the scfparams
    object.

    Example: scfparams.basis is a cc-pVDZ basis. n_points=3.
    The quantity will be computed for cc-pVDZ, cc-pVTZ and cc-pVQZ
    and then extrapolated to the CBS.

    quantity may either be a string describing the quantity to compute
    or a function to take a state and return the quantity to extrapolate.

    If the extrapolation fails the function returns a CBSExtrapolationResult
    where the success flag is set to False. One may then retrieve
    the states of the performed calculations and the derived quantities
    for the fit, but the values of the CBS limit and the extrapolation_function
    are not reliable.
    """
    scfparams = scfparams.copy()
    origbasis = scfparams.basis
    if not isinstance(origbasis, gint.gaussian.Basis):
        raise ValueError(
            "The basis of the scfparams needs to be a gaussian basis set.")

    if isinstance(quantity, str):
        if quantity == "hfenergy":

            def quantity(x):
                return x["energy_ground_state"]
        else:
            raise NotImplementedError("The quantity '" + quantity +
                                      "' is not supported at the moment. "
                                      "Currently we only support 'hfenergy'")

    #
    # Translate between zetaness as number and as letter
    #
    # Translation map for letter to zetaness of the basis set
    letter_to_zeta = {
        "D": 2,
        "T": 3,
        "Q": 4,
        "P": 5,
        "H": 6,
    }

    # And function to translate back in the conventional way:
    def zeta_to_string(zeta):
        if zeta <= 4:
            return [k for k, v in letter_to_zeta.items() if v == zeta][0]
        else:
            return str(zeta)

    #
    # Match for Dunning basis sets
    #
    dunning_re = re.compile(r"""
        ^(?P<pre>cc-pV)           # Prefix of the basis set
        (?P<zeta>[0-9]+|[DTQPH])  # Zetaness either as string or as letter
        (?P<post>Z)$              # Postfix
    """,
                            flags=re.IGNORECASE | re.VERBOSE)

    is_dunning = dunning_re.match(origbasis.basis_set_name)
    if is_dunning:
        pre = is_dunning.group("pre")
        zetaness = letter_to_zeta[is_dunning.group("zeta").upper()]
        post = is_dunning.group("post")
    else:
        raise NotImplementedError(
            "Currently automatic CBS limit extrapolation is only "
            "implemented for plain Dunning basis sets.")

    # Construct containers and basis sets
    orders = np.arange(zetaness, zetaness + n_points)

    basis_sets = []
    for i, zeta in enumerate(orders):
        basis_set_name = pre + zeta_to_string(zeta) + post

        try:
            basis = gint.gaussian.Basis(scfparams.system,
                                        basis_set_name=basis_set_name,
                                        backend=origbasis.backend)
        except RuntimeError as e:
            raise ValueError(
                "Could not construct the basis set '" + basis_set_name +
                "'. Check your input parameters, especially n_points. "
                "Further info: " + str(e))
        basis_sets.append(basis)

    states = []
    quantities = []
    for i, basis in enumerate(basis_sets):
        # TODO One could very likely improve convergence if one took the
        #      just computed hf result of the previous step as a guess for
        #      the next. Right now we cannot do this, since the interpolation
        #      for this has not yet been implemented, but for the future ...

        scfparams.basis = basis
        res = molsturm.self_consistent_field(scfparams)
        states.append(res)
        quantities.append(quantity(res))
    quantities = np.array(quantities)

    try:
        popt, pcov = fit_cbs_curve(orders, quantities)
    except RuntimeError as e:
        return CBSExtrapolationResult(orders,
                                      quantities,
                                      None,
                                      None,
                                      states,
                                      success=False)

    return CBSExtrapolationResult(orders,
                                  quantities,
                                  popt,
                                  pcov,
                                  states,
                                  success=True)
    )
    params = molsturm.ScfParameters()
    params.system = system

    basis_type = str(h5f["discretisation/basis_type"].value)
    if basis_type == "gaussian":
        bas = str(h5f["discretisation/basis_set_name"].value)
        params.basis = molsturm.construct_basis("gaussian",
                                                params.system,
                                                basis_set_name=bas)
    elif basis_type == "sturmian/atomic":
        k_exp = float(h5f["discretisation/k_exp"].value)
        n_max = int(h5f["discretisation/n_max"].value)
        l_max = int(h5f["discretisation/l_max"].value)
        m_max = int(h5f["discretisation/m_max"].value)
        params.basis = molsturm.construct_basis("sturmian/atomic",
                                                params.system,
                                                k_exp=k_exp,
                                                n_max=n_max,
                                                l_max=l_max,
                                                m_max=m_max)
    else:
        raise NotImplementedError("Basis type {} is not "
                                  "implemented".format(basis_type))
    params["scf/print_iterations"] = True

res = molsturm.self_consistent_field(params)
molsturm.print_convergence_summary(res)
molsturm.print_energies(res)
molsturm.print_mo_occupation(res)
Example #10
0
 def setUpClass(cls):
     scfparams = molsturm.ScfParameters.from_dict(data.input_parameters)
     cls._hf_result = molsturm.self_consistent_field(scfparams)