Ejemplo n.º 1
0
    def _run_psi4(self, options: dict, method=None, return_wfn=True, point_group=None, filename: str = None,
                  guess_wfn=None, ref_wfn=None, *args, **kwargs):
        psi4.core.clean()

        if self.active_space and not self.active_space.psi4_representable:
            print("Warning: Active space is not Psi4 representable")

        if "threads" in kwargs:
            psi4.set_num_threads(nthread=kwargs["threads"])

        if filename is None:
            filename = "{}_{}.out".format(self.parameters.filename, method)

        psi4.core.set_output_file(filename)

        # easier guess read in
        if guess_wfn is not None:
            if isinstance(guess_wfn, QuantumChemistryPsi4):
                guess_wfn = guess_wfn.logs["hf"].wfn
            if isinstance(guess_wfn, str):
                guess_wfn = psi4.core.Wavefunction.from_file(guess_wfn)
            guess_wfn.to_file(guess_wfn.get_scratch_filename(180))  # this is necessary
            options["guess"] = "read"

        # prevent known flaws
        if "guess" in options and options["guess"].lower() == "read":
            options["basis_guess"] = False
            # additionally the outputfile needs to be the same
            # as in the previous guess
            # this can not be determined here
            # better pass down a guess_wfn

        mol = psi4.geometry(self.parameters.get_geometry_string())
        mol.set_multiplicity(self.parameters.multiplicity)
        if self.parameters.multiplicity != 1:
            raise TequilaPsi4Exception("Multiplicity != 1 no yet supported")
        mol.set_molecular_charge(self.parameters.charge)

        if point_group is not None:
            mol.reset_point_group(point_group.lower())

        if ref_wfn is None and hasattr(self, "ref_wfn"):
            ref_wfn = self.ref_wfn

        if point_group is not None and point_group.lower() == "c1":
            ref_wfn = None  # ref_wfn.c1_deep_copy(ref_wfn.basisset())  # CC will not converge otherwise
            guess_wfn = None

        psi4.activate(mol)

        psi4.set_options(options)
        if ref_wfn is None or method.lower() == "hf":
            energy, wfn = psi4.energy(name=method.lower(), return_wfn=return_wfn, molecule=mol)
        else:
            energy, wfn = psi4.energy(name=method.lower(), ref_wfn=ref_wfn, return_wfn=return_wfn, molecule=mol,
                                      guess_wfn=guess_wfn)
        self.energies[method.lower()] = energy
        self.logs[method.lower()] = Psi4Results(filename=filename, variables=copy.deepcopy(psi4.core.variables()),
                                                wfn=wfn, mol=mol)
        return energy, wfn
Ejemplo n.º 2
0
def v2rdm_psi4():

    mol = psi4.geometry("""
    0 1
    b
    h 1 1.1
    """)

    psi4.set_options({
      'basis':           'sto-3g',
      'scf_type':        'out_of_core',
      'd_convergence':   1e-10,
      'maxiter':         500,
    })
    psi4.set_module_options('hilbert', {
      #'sdp_solver':      'rrsdp',
      'positivity':      'dqg',
      'r_convergence':   1e-5,
      'e_convergence':   1e-4,
      'maxiter':         20000,
    })

    psi4.activate(mol)

    # get scf wfn
    scf_energy,ref_wfn = psi4.energy('scf',return_wfn=True)

    # grab options object
    options = psi4.core.get_options()
    options.set_current_module('HILBERT')

    v2rdm_psi4 = hilbert.v2RDMHelper(ref_wfn,options)
    current_energy = v2rdm_psi4.compute_energy()

    return current_energy, mol.nuclear_repulsion_energy()
Ejemplo n.º 3
0
    def __init__(self, parameters: ParametersQC,
                 transformation: typing.Union[str, typing.Callable] = None,
                 active_orbitals=None,
                 reference=None,
                 *args,
                 **kwargs):
        """

        Parameters
        ----------
        parameters
        transformation
        active_orbitals: dictionary :
            dictionary with irreps as keys and a list of integers as values
            i.e. occ = {"A1":[0,1], "A2":[0]}
            means the occupied active space is made up of spatial orbitals
            0A1, 1A1 and 0A2
            as list: Give a list of spatial orbital indices
            i.e. occ = [0,1,3] means that spatial orbital 0, 1 and 3 are used
        reference: (Default value=None)
            List of orbitals which form the reference
            Can be given in the same format as active_orbitals
            If given as None then the first N_electron/2 orbitals are taken
            and the corresponding active orbitals are removed
        args
        kwargs
        """

        self.psi4_mol = psi4.geometry(parameters.get_geometry_string())
        psi4.activate(self.psi4_mol)

        self.energies = {}  # history to avoid recomputation
        self.logs = {}  # store full psi4 output

        self.active_space = None # will be assigned in super
        # active space will be formed later
        super().__init__(parameters=parameters, transformation=transformation, active_orbitals=None, reference=None, *args, **kwargs)
        self.ref_energy = self.molecule.hf_energy
        self.ref_wfn = self.logs['hf'].wfn
        self.irreps = [self.psi4_mol.point_group().char_table().gamma(i).symbol().upper() for i in range(self.nirrep)]

        oenergies = []
        for i in self.irreps:
            oenergies += [(i, j, x) for j, x in enumerate(self.orbital_energies(irrep=i))]

        oenergies = sorted(oenergies, key=lambda x: x[2])
        self.orbitals = [self.OrbitalData(irrep=data[0], idx_irrep=data[1], idx_total=i, energy=data[2]) for i, data in
                         enumerate(oenergies)]
        orbitals_by_irrep = {o.irrep: [] for o in self.orbitals}
        for o in self.orbitals:
            orbitals_by_irrep[o.irrep] += [o]

        self.orbitals_by_irrep = orbitals_by_irrep

        if active_orbitals is not None:
            self.active_space = self._make_psi4_active_space_data(active_orbitals=active_orbitals, reference=reference)
            # need to recompute
            # (psi4 won't take over active space information otherwise)
            self.compute_energy(method="hf", recompute=True)
            self.ref_wfn = self.logs["hf"].wfn
Ejemplo n.º 4
0
def test_v2rdm_casscf():
    """v2rdm_casscf/tests/v2rdm1"""
    #! cc-pvdz N2 (6,6) active space Test DQG

    print(
        '        N2 / cc-pVDZ / DQG(6,6), scf_type = CD / 1e-12, rNN = 0.5 A')

    import v2rdm_casscf

    n2 = psi4.geometry("""
    0 1
    n
    n 1 r
    """)

    interloper = psi4.geometry("""
    0 1
    O
    H 1 1.0
    H 1 1.0 2 90.0
    """)

    psi4.set_options({
        'basis': 'cc-pvdz',
        'scf_type': 'cd',
        'cholesky_tolerance': 1e-12,
        'd_convergence': 1e-10,
        'maxiter': 500,
        'restricted_docc': [2, 0, 0, 0, 0, 2, 0, 0],
        'active': [1, 0, 1, 1, 0, 1, 1, 1],
    })
    psi4.set_module_options(
        'v2rdm_casscf',
        {
            'positivity': 'dqg',
            'r_convergence': 1e-5,
            'e_convergence': 1e-6,
            'maxiter': 20000,
            #'orbopt_frequency': 1000,
            #'mu_update_frequency': 1000,
        })

    psi4.activate(n2)

    n2.r = 0.5 * 0.52917721067 / 0.52917720859
    refscf = -103.04337420425350
    refv2rdm = -103.086205379481

    psi4.energy('v2rdm-casscf', molecule=n2)

    assert psi4.compare_values(refscf, psi4.variable("SCF TOTAL ENERGY"), 8,
                               "SCF total energy")
    assert psi4.compare_values(refv2rdm, psi4.variable("CURRENT ENERGY"), 5,
                               "v2RDM-CASSCF total energy")
Ejemplo n.º 5
0
def test_v2rdm_casscf():
    """v2rdm_casscf/tests/v2rdm1"""
    #! cc-pvdz N2 (6,6) active space Test DQG

    print('        N2 / cc-pVDZ / DQG(6,6), scf_type = CD / 1e-12, rNN = 0.5 A')

    import v2rdm_casscf

    n2 = psi4.geometry("""
    0 1
    n
    n 1 r
    """)

    interloper = psi4.geometry("""
    0 1
    O
    H 1 1.0
    H 1 1.0 2 90.0
    """)

    psi4.set_options({
      'basis': 'cc-pvdz',
      'scf_type': 'cd',
      'cholesky_tolerance': 1e-12,
      'd_convergence': 1e-10,
      'maxiter': 500,
      'restricted_docc': [ 2, 0, 0, 0, 0, 2, 0, 0 ],
      'active': [ 1, 0, 1, 1, 0, 1, 1, 1 ],
    })
    ##psi4.set_module_options('v2rdm_casscf', {
    psi4.set_options({
    #  'positivity': 'dqg',
      'r_convergence': 1e-5,
      'e_convergence': 1e-6,
      'maxiter': 20000,
    #  #'orbopt_frequency': 1000,
    #  #'mu_update_frequency': 1000,
    })

    psi4.activate(n2)

    n2.r     = 0.5
    refscf   = -103.04337420425350
    refv2rdm = -103.086205379481

    psi4.energy('v2rdm-casscf', molecule=n2)

    assert psi4.compare_values(refscf, psi4.get_variable("SCF TOTAL ENERGY"), 8, "SCF total energy")
    assert psi4.compare_values(refv2rdm, psi4.get_variable("CURRENT ENERGY"), 5, "v2RDM-CASSCF total energy")
Ejemplo n.º 6
0
def test_v2rdm6():
    #! cc-pvdz N2 (6,6) active space Test DQG

    print('        N2 / cc-pVDZ / DQG(6,6), geometry optimization')

    import psi4

    n2 = psi4.geometry("""
    0 1
    n
    n 1 1.1
    """)

    psi4.set_options({
        'basis': 'cc-pvdz',
        'scf_type': 'pk',
        'd_convergence': 1e-10,
        'maxiter': 500,
        'restricted_docc': [2, 0, 0, 0, 0, 2, 0, 0],
        'active': [1, 0, 1, 1, 0, 1, 1, 1],
    })
    psi4.set_module_options(
        'v2rdm_casscf',
        {
            'positivity': 'dqg',
            #'r_convergence': 1e-7,
            'r_convergence': 1e-6,
            'e_convergence': 1e-5,
            'orbopt_gradient_convergence': 1e-8,
            'maxiter': 20000,
        })

    psi4.activate(n2)

    psi4.optimize('v2rdm-casscf')

    refnuc = 23.1968666562054260
    refscf = -108.95016246035139
    refv2rdm = -109.095505119442

    assert psi4.compare_values(refnuc, n2.nuclear_repulsion_energy(), 4,
                               "Nuclear repulsion energy")
    assert psi4.compare_values(refscf, psi4.variable("SCF TOTAL ENERGY"), 5,
                               "SCF total energy")
    assert psi4.compare_values(refv2rdm, psi4.variable("CURRENT ENERGY"), 4,
                               "v2RDM-CASSCF total energy")
Ejemplo n.º 7
0
def test_v2rdm():
    #! cc-pvdz N2 (6,6) active space Test DQG

    print('        N2 / cc-pVDZ / DQG(6,6), scf_type = DF, rNN = 1.1 A')

    import psi4

    import sys
    sys.path.insert(0, '../..')
    import hilbert

    n2 = psi4.geometry("""
    0 1
    n
    n 1 r
    """)

    psi4.set_options({
        'basis': 'cc-pvdz',
        'scf_type': 'df',
        'd_convergence': 1e-10,
        'maxiter': 500,
        'restricted_docc': [2, 0, 0, 0, 0, 2, 0, 0],
        'active': [1, 0, 1, 1, 0, 1, 1, 1],
    })
    psi4.set_module_options(
        'hilbert', {
            'positivity': 'dqg',
            'r_convergence': 1e-5,
            'e_convergence': 1e-6,
            'maxiter': 20000,
        })

    psi4.activate(n2)

    n2.r = 1.1
    refscf = -108.95348837831371
    refv2rdm = -109.094404909477

    psi4.energy('v2rdm-casscf')

    assert psi4.compare_values(refscf, psi4.variable("SCF TOTAL ENERGY"), 8,
                               "SCF total energy")
    assert psi4.compare_values(refv2rdm, psi4.variable("CURRENT ENERGY"), 5,
                               "v2RDM-CASSCF total energy")
Ejemplo n.º 8
0
def test_v2rdm8():
    # H2 / cc-pVDZ / D(2,2), scf_type = DF, rHH = 1.0 A

    print('        H2 / cc-pVDZ / D(2,2), scf_type = DF, rHH = 1.0 A')

    import v2rdm_casscf
    import psi4

    h2 = psi4.geometry("""
    0 1
    h
    h 1 r
    symmetry c1
    """)

    psi4.set_options({
        "basis": "cc-pvdz",
        "mcscf_type": "df",
        "scf_type": "df",
        "d_convergence": 1e-10,
        "maxiter": 500,
        "restricted_docc": [0],
        "restricted_uocc": [8],
        "active": [2],
    })
    psi4.set_module_options(
        'v2rdm_casscf', {
            "positivity": "d",
            "r_convergence": 1e-6,
            "e_convergence": 1e-8,
            "maxiter": 20000,
        })

    psi4.activate(h2)

    h2.r = 1.0

    psi4.set_options({"df_ints_io": "save"})
    en, wfn = psi4.energy('scf', return_wfn=True)

    en1 = v2rdm_casscf.v2rdm_scf_solver(wfn)
    en2 = psi4.energy('casscf')

    assert psi4.compare_values(en1, en2, 6, "v2RDM-CASSCF total energy")
Ejemplo n.º 9
0
def test_v2rdm5():
    #! cc-pvdz N2 (6,6) active space Test DQG

    print('        N2 / cc-pVDZ / DQG+T2(6,6), scf_type = PK, rNN = 1.1 A')

    import psi4

    n2 = psi4.geometry("""
    0 1
    n
    n 1 r
    """)

    psi4.set_options({
        'basis': 'cc-pvdz',
        'scf_type': 'pk',
        'd_convergence': 1e-10,
        'maxiter': 500,
        'restricted_docc': [2, 0, 0, 0, 0, 2, 0, 0],
        'active': [1, 0, 1, 1, 0, 1, 1, 1],
    })
    psi4.set_module_options(
        'v2rdm_casscf', {
            'positivity': 'dqgt2',
            'r_convergence': 1e-4,
            'e_convergence': 5e-4,
            'maxiter': 20000,
        })

    psi4.activate(n2)

    n2.r = 1.1
    refscf = -108.95379624015767
    refv2rdm = -109.091487394061

    psi4.energy('v2rdm-casscf')

    assert psi4.compare_values(refscf, psi4.variable("SCF TOTAL ENERGY"), 8,
                               "SCF total energy")
    assert psi4.compare_values(refv2rdm, psi4.variable("CURRENT ENERGY"), 4,
                               "v2RDM-CASSCF total energy")
Ejemplo n.º 10
0
def energy(geom, confId, method='HF-3C', **kwargs):
    """
    Finds the energy of a given molecule

    :param geom: an RDKit.Mol or a string
    :param confId: the ID of the conformer to optimize
    :param method: the PSI4 method to calculate the H**O and LUMO
    :return: wavefunction (energy is available under wavefunction.energy)
    """
    try:
        geom = make_psi4_geometry(geom, confId)
        psi4.activate(geom)
        psi4.core.IO.set_default_namespace(str(id(geom)))

        psi4.core.set_global_option("MAXITER", 1000)

        return psi4.energy(method, return_wfn=True, **kwargs)[1]
    except Exception as e:
        print(e)

    return np.nan
Ejemplo n.º 11
0
def optimize(geom, confId=None, method='HF-3C', **kwargs):
    """
    Optimizes the given conformation.

    :param mol: an RDKit.Mol or a string
    :param confId: the ID of the conformer to optimize, if needed
    :param method: the PSI4 method to use
    :return: wavefunction (energy is available under wavefunction.energy)
    """
    try:
        geom = make_psi4_geometry(geom, confId)
        psi4.activate(geom)
        psi4.core.IO.set_default_namespace(str(id(geom)))

        psi4.core.set_global_option("MAXITER", 1000)

        return psi4.optimize(method, return_wfn=True, **kwargs)[1]
    except Exception as e:
        pass

    return np.nan
Ejemplo n.º 12
0
def test_v2rdm3():
    #! H3 / cc-pvdz / D+D3 vs full CI, scf_type = PK

    print('        H3 / cc-pvdz / D+D3 vs full CI, scf_type = PK')

    import psi4

    h3 = psi4.geometry("""
    0 2
    H
    H 1 1.0
    H 1 2.0 2 90.0
    """)

    psi4.set_options({
        'basis': 'sto-3g',
        'scf_type': 'pk',
        'reference': 'rohf',
        'guess': 'sad',
        'd_convergence': 1e-10,
        'maxiter': 500,
    })

    psi4.set_module_options(
        'v2rdm_casscf', {
            'positivity': 'd',
            'constrain_d3': True,
            'r_convergence': 1e-5,
            'e_convergence': 1e-6,
            'maxiter': 20000,
            'optimize_orbitals': False,
            'semicanonicalize_orbitals': False,
        })

    psi4.activate(h3)
    v2rdm = psi4.energy('v2rdm-casscf')
    fci = psi4.energy('fci')

    assert psi4.compare_values(v2rdm, fci, 5, "v2RDM vs full CI")
Ejemplo n.º 13
0
Archivo: _psi4.py Proyecto: zhenglz/qm3
        def __init__(self, mol, opts, sele, nbnd=[], link=[]):
            """
        opts = { "reference": "rks", "basis": "6-31g*", "d_convergence": 6, "scf_type": "direct", "guess": "read",
                "output": False, "charge": 0, "method": "b3lyp", "ncpus": 1, "memory": "1024 MB" }
            """
            self._ce = qm3.constants.H2J
            self._cg = self._ce / qm3.constants.A0
            self.sel = sele[:]
            self.lnk = link[:]
            t = [j for i, j in self.lnk]
            self.nbn = [i for i in nbnd if not i in t]

            self.smb = mol.guess_symbols(sele)
            buf = "\n%d 1\n" % (opts.pop("charge"))
            j = 0
            for i in sele:
                i3 = i * 3
                buf += "%-2s%20.10lf%20.10lf%20.10lf\n" % (
                    self.smb[j], mol.coor[i3] - mol.boxl[0] *
                    round(mol.coor[i3] / mol.boxl[0], 0), mol.coor[i3 + 1] -
                    mol.boxl[1] * round(mol.coor[i3 + 1] / mol.boxl[1], 0),
                    mol.coor[i3 + 2] -
                    mol.boxl[2] * round(mol.coor[i3 + 2] / mol.boxl[2], 0))
                j += 1
            self.vla = []
            if (len(self.lnk) > 0):
                k = len(self.sel)
                for i, j in self.lnk:
                    c, v = qm3.engines.LA_coordinates(i, j, mol)
                    buf += "%-2s%20.10lf%20.10lf%20.10lf\n" % ("H", c[0], c[1],
                                                               c[2])
                    self.vla.append((self.sel.index(i), k, v[:]))
                    k += 1

            # -- psi4 --
            if (opts.pop("output")):
                psi4.core.set_output_file("psi4.out", False)
            else:
                psi4.core.be_quiet()
            psi4.set_memory(opts.pop("memory"))
            psi4.set_num_threads(opts.pop("ncpus"))
            buf += "symmetry c1\nno_reorient\nno_com\n"
            self.QMatm = psi4.geometry(buf)
            psi4.activate(self.QMatm)
            if (len(self.nbn) > 0):
                self.MMatm = psi4.QMMM()
                self.MMatm.charges = []
                for i in self.nbn:
                    i3 = i * 3
                    self.MMatm.charges.append([
                        mol.chrg[i], mol.coor[i3] -
                        mol.boxl[0] * round(mol.coor[i3] / mol.boxl[0], 0),
                        mol.coor[i3 + 1] -
                        mol.boxl[1] * round(mol.coor[i3 + 1] / mol.boxl[1], 0),
                        mol.coor[i3 + 2] -
                        mol.boxl[2] * round(mol.coor[i3 + 2] / mol.boxl[2], 0)
                    ])
                self.MMatm.populateExtern()
                psi4.core.set_global_option_python("EXTERN", self.MMatm.extern)
            self.met = opts.pop("method")
            psi4.set_options(opts)
Ejemplo n.º 14
0
def test_dftd3():
    """dftd3/energy"""
    #! Exercises the various DFT-D corrections, both through python directly and through c++

    ref_d2 = [-0.00390110, -0.00165271, -0.00058118]
    ref_d3zero = [-0.00285088, -0.00084340, -0.00031923]
    ref_d3bj = [-0.00784595, -0.00394347, -0.00226683]

    ref_pbe_d2 = [-0.00278650, -0.00118051, -0.00041513]
    ref_pbe_d3zero = [-0.00175474, -0.00045421, -0.00016839]
    ref_pbe_d3bj = [-0.00475937, -0.00235265, -0.00131239]

    eneyne = psi4.geometry("""
    C   0.000000  -0.667578  -2.124659
    C   0.000000   0.667578  -2.124659
    H   0.923621  -1.232253  -2.126185
    H  -0.923621  -1.232253  -2.126185
    H  -0.923621   1.232253  -2.126185
    H   0.923621   1.232253  -2.126185
    --
    C   0.000000   0.000000   2.900503
    C   0.000000   0.000000   1.693240
    H   0.000000   0.000000   0.627352
    H   0.000000   0.000000   3.963929
    """)

    print('  -D correction from Py-side')
    eneyne.update_geometry()
    E, G = eneyne.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[0], E, 7, 'Ethene-Ethyne -D2')
    mA = eneyne.extract_subsets(1)
    E, G = mA.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[1], E, 7, 'Ethene -D2')
    mB = eneyne.extract_subsets(2)
    E, G = mB.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[2], E, 7, 'Ethyne -D2')
    #mBcp = eneyne.extract_subsets(2,1)
    #E, G = mBcp.run_dftd3('b3lyp', 'd2')
    #compare_values(ref_d2[2], E, 7, 'Ethyne(CP) -D2')

    E, G = eneyne.run_dftd3('b3lyp', 'd3zero')
    assert psi4.compare_values(ref_d3zero[0], E, 7, 'Ethene-Ethyne -D3 (zero)')
    mA = eneyne.extract_subsets(1)
    E, G = mA.run_dftd3('b3lyp', 'd3zero')
    assert psi4.compare_values(ref_d3zero[1], E, 7, 'Ethene -D3 (zero)')
    mB = eneyne.extract_subsets(2)
    E, G = mB.run_dftd3('b3lyp', 'd3zero')
    assert psi4.compare_values(ref_d3zero[2], E, 7, 'Ethyne -D3 (zero)')

    E, G = eneyne.run_dftd3('b3lyp', 'd3bj')
    assert psi4.compare_values(ref_d3bj[0], E, 7, 'Ethene-Ethyne -D3 (bj)')
    mA = eneyne.extract_subsets(1)
    E, G = mA.run_dftd3('b3lyp', 'd3bj')
    assert psi4.compare_values(ref_d3bj[1], E, 7, 'Ethene -D3 (bj)')
    mB = eneyne.extract_subsets(2)
    E, G = mB.run_dftd3('b3lyp', 'd3bj')
    assert psi4.compare_values(ref_d3bj[2], E, 7, 'Ethyne -D3 (bj)')

    E, G = eneyne.run_dftd3('b3lyp', 'd3')
    assert psi4.compare_values(ref_d3zero[0], E, 7,
                               'Ethene-Ethyne -D3 (alias)')
    E, G = eneyne.run_dftd3('b3lyp', 'd')
    assert psi4.compare_values(ref_d2[0], E, 7, 'Ethene-Ethyne -D (alias)')
    E, G = eneyne.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[0], E, 7, 'Ethene-Ethyne -D2 (alias)')

    psi4.set_options({
        'basis': 'sto-3g',
        'scf_type': 'df',
        'dft_radial_points':
        50,  # use really bad grid for speed since all we want is the -D value
        'dft_spherical_points': 110,
        #'scf print': 3,  # will print dftd3 program output to psi4 output file
    })

    print('  -D correction from C-side')
    psi4.activate(mA)
    #psi4.energy('b3lyp-d2', engine='libdisp')
    #assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling psi4 Disp class)')
    #psi4.energy('b3lyp-d2')
    #assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling dftd3 -old)')
    #psi4.energy('b3lyp-d3zero')
    #assert psi4.compare_values(ref_d3zero[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (calling dftd3 -zero)')
    psi4.energy('b3lyp-d3bj')
    assert psi4.compare_values(ref_d3bj[1],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D3 (calling dftd3 -bj)')

    psi4.energy('b3lyp-d2', engine='libdisp')
    assert psi4.compare_values(ref_d2[1],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D2 (alias)')
    #psi4.energy('b3lyp-d3')
    #assert psi4.compare_values(ref_d3zero[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (alias)')
    #psi4.energy('b3lyp-d')
    #assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D (alias)')
    psi4.energy('wb97x-d')
    assert psi4.compare_values(-0.000834247063,
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene wb97x-d (chg)')

    print('  non-default -D correction from C-side')
    psi4.activate(mB)
    #psi4.set_options({'dft_dispersion_parameters': [0.75]})
    #psi4.energy('b3lyp-d2', engine='libdisp')
    #assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling psi4 Disp class)')
    #psi4.set_options({'dft_dispersion_parameters': [0.75, 20.0]})
    #psi4.energy('b3lyp-d2')
    #assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling dftd3 -old)')
    #psi4.set_options({'dft_dispersion_parameters': [1.0,  0.722, 1.217, 14.0]})
    #psi4.energy('b3lyp-d3zero')
    #assert psi4.compare_values(ref_pbe_d3zero[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (calling dftd3 -zero)')
    psi4.set_options(
        {'dft_dispersion_parameters': [1.000, 0.7875, 0.4289, 4.4407]})
    psi4.energy('b3lyp-d3bj')
    assert psi4.compare_values(ref_pbe_d3bj[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D3 (calling dftd3 -bj)')

    psi4.set_options({'dft_dispersion_parameters': [0.75]})
    psi4.energy('b3lyp-d2', engine='dftd3')
    assert psi4.compare_values(ref_pbe_d2[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D2 (alias)')
    psi4.set_options({'dft_dispersion_parameters': [1.0, 0.722, 1.217, 14.0]})
    psi4.energy('b3lyp-d3')
    assert psi4.compare_values(ref_pbe_d3zero[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D3 (alias)')
    psi4.set_options({'dft_dispersion_parameters': [0.75]})
    psi4.energy('b3lyp-d')
    assert psi4.compare_values(ref_pbe_d2[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D (alias)')
    psi4.activate(mA)
    psi4.set_options({'dft_dispersion_parameters': [1.0]})
    psi4.energy('wb97x-d')
    assert psi4.compare_values(-0.000834247063,
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene wb97x-d (chg)')

    print('  non-default -D correction from Py-side')
    eneyne.update_geometry()
    eneyne.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[0],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene-Ethyne -D2')
    mA = eneyne.extract_subsets(1)
    mA.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[1],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D2')
    mB = eneyne.extract_subsets(2)
    mB.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethyne -D2')

    eneyne.run_dftd3('b3lyp', 'd3zero', {
        's6': 1.0,
        's8': 0.722,
        'sr6': 1.217,
        'alpha6': 14.0
    })
    assert psi4.compare_values(ref_pbe_d3zero[0],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene-Ethyne -D3 (zero)')
    mA = eneyne.extract_subsets(1)
    mA.run_dftd3('b3lyp', 'd3zero', {
        's6': 1.0,
        's8': 0.722,
        'sr6': 1.217,
        'alpha6': 14.0
    })
    assert psi4.compare_values(ref_pbe_d3zero[1],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D3 (zero)')
    mB = eneyne.extract_subsets(2)
    mB.run_dftd3('b3lyp', 'd3zero', {
        's6': 1.0,
        's8': 0.722,
        'sr6': 1.217,
        'alpha6': 14.0
    })
    assert psi4.compare_values(ref_pbe_d3zero[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethyne -D3 (zero)')

    eneyne.run_dftd3('b3lyp', 'd3bj', {
        's6': 1.000,
        's8': 0.7875,
        'a1': 0.4289,
        'a2': 4.4407
    })
    assert psi4.compare_values(ref_pbe_d3bj[0],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene-Ethyne -D3 (bj)')
    mA = eneyne.extract_subsets(1)
    mA.run_dftd3('b3lyp', 'd3bj', {
        's6': 1.000,
        's8': 0.7875,
        'a1': 0.4289,
        'a2': 4.4407
    })
    assert psi4.compare_values(ref_pbe_d3bj[1],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene -D3 (bj)')
    mB = eneyne.extract_subsets(2)
    mB.run_dftd3('b3lyp', 'd3bj', {
        's6': 1.000,
        's8': 0.7875,
        'a1': 0.4289,
        'a2': 4.4407
    })
    assert psi4.compare_values(ref_pbe_d3bj[2],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethyne -D3 (bj)')
    eneyne.run_dftd3('b3lyp', 'd3', {
        's6': 1.0,
        's8': 0.722,
        'sr6': 1.217,
        'alpha6': 14.0
    })

    assert psi4.compare_values(ref_pbe_d3zero[0],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene-Ethyne -D3 (alias)')
    eneyne.run_dftd3('b3lyp', 'd', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[0],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene-Ethyne -D (alias)')
    eneyne.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[0],
                               psi4.variable('DISPERSION CORRECTION ENERGY'),
                               7, 'Ethene-Ethyne -D2 (alias)')
Ejemplo n.º 15
0
def test_pp2rdm():
    """hilbert/tests/pp2rdm"""
    #! 6-31g H2O pp2RDM Test

    import psi4

    import sys
    sys.path.insert(0, '../..')
    import hilbert

    h2o = psi4.geometry("""
    0 1
    o
    h 1 1.0
    h 1 1.0 2 104.5
    symmetry c1
    """)

    interloper = psi4.geometry("""
    0 1
    O
    H 1 1.0
    H 1 1.0 2 90.0
    """)

    psi4.set_options({
        'basis': '6-31g',
        'scf_type': 'df',
        'e_convergence': 1e-10,
        'r_convergence': 1e-8,
        'orbopt_gradient_convergence': 1e-6,
        'orbopt_energy_convergence': 1e-8,
        'maxiter': 500,
    })
    psi4.set_module_options(
        'hilbert', {
            'orbopt_maxiter': 1,
            'localize_orbitals': True,
            'noisy_orbitals': True,
            'optimize_orbitals': True,
            'p2rdm_type': 'k',
        })

    psi4.activate(h2o)

    ref_scf = -75.98014193580194
    ref_pp2rdm = -76.052804542359

    # be sure to save three-index integrals after scf
    psi4.core.set_local_option('SCF', 'DF_INTS_IO', 'SAVE')

    # get scf wfn
    scf_energy, ref_wfn = psi4.energy('scf', return_wfn=True)

    # grab options object
    options = psi4.core.get_options()
    options.set_current_module('HILBERT')

    # evaluate pp2RDM energy
    pp2rdm = hilbert.pp2RDMHelper(ref_wfn, options)
    current_energy = pp2rdm.compute_energy()

    assert psi4.compare_values(ref_scf, scf_energy, 8, "SCF total energy")
    assert psi4.compare_values(ref_pp2rdm, current_energy, 5,
                               "pp2RDM total energy")
Ejemplo n.º 16
0
def test_v2rdm7():
    # STO-3g benzene (6,6) guess orbital rotation test DQG

    print('        benzene (6,6), scf_type = PK')

    import psi4

    # orbital rotation needed before MCSCF calculation
    benzene_c1 = psi4.geometry("""
    0 1
    symmetry c1
     C                  0.00000000    1.38980400    0.00000000
     C                  1.20360500    0.69490200    0.00000000
     C                  1.20360500   -0.69490200    0.00000000
     C                  0.00000000   -1.38980400    0.00000000
     C                 -1.20360500   -0.69490200    0.00000000
     C                 -1.20360500    0.69490200    0.00000000
     H                  0.00000000    2.47523400    0.00000000
     H                  2.14361600    1.23761700    0.00000000
     H                  2.14361600   -1.23761700    0.00000000
     H                  0.00000000   -2.47523400    0.00000000
     H                 -2.14361600   -1.23761700    0.00000000
     H                 -2.14361600    1.23761700    0.00000000
    """)

    psi4.set_options({
        'basis': 'sto-3g',
        'scf_type': 'pk',
        'd_convergence': 1e-10,
        'maxiter': 500,
        'restricted_docc': [18],
        'active': [6],
    })

    psi4.energy('hf')

    psi4.set_module_options(
        'v2rdm_casscf',
        {
            # Switch the 17th (index 16) and the 19th (index 18) orbitals of the 1st irrep (index 0)
            # If more than one set of orbitals need to be rotated, use the following syntex
            # mcscf_rotate [[irrep_1, orb1_1, orb2_1, theta_1], [irrep_2, orb1_2, orb2_2, theta2],...]
            # Setting theta to 90 would switch the orbitals, setting it to 0 does nothing.
            'mcscf_rotate': [[0, 16, 18, 90]],
            'positivity': 'dq',
            'r_convergence': 1e-5,
            'e_convergence': 1e-6,
            'maxiter': 20000,
            'guess_orbitals_write': False,
            'molden_write': False,
        })

    psi4.activate(benzene_c1)

    E_c1 = psi4.energy('v2rdm-casscf')

    psi4.core.clean()

    # reference calculation, no need to rotate orbitals for MCSCF
    benzene_d2h = psi4.geometry("""
    0 1
    symmetry d2h
     C                  0.00000000    1.38980400    0.00000000
     C                  1.20360500    0.69490200    0.00000000
     C                  1.20360500   -0.69490200    0.00000000
     C                  0.00000000   -1.38980400    0.00000000
     C                 -1.20360500   -0.69490200    0.00000000
     C                 -1.20360500    0.69490200    0.00000000
     H                  0.00000000    2.47523400    0.00000000
     H                  2.14361600    1.23761700    0.00000000
     H                  2.14361600   -1.23761700    0.00000000
     H                  0.00000000   -2.47523400    0.00000000
     H                 -2.14361600   -1.23761700    0.00000000
     H                 -2.14361600    1.23761700    0.00000000
    """)

    psi4.set_options({
        'basis': 'sto-3g',
        'scf_type': 'pk',
        'd_convergence': 1e-10,
        'maxiter': 500,
        'restricted_docc': [6, 3, 0, 0, 0, 0, 5, 4],
        'active': [0, 0, 1, 2, 1, 2, 0, 0],
    })

    psi4.energy('hf')

    psi4.set_module_options(
        'v2rdm_casscf',
        {
            # Note that when mcscf_rotate is set for the previous molecule, the calculations afterwards
            #   also use this input, unless you overwrite it. A safe way to unset it is to overwrite it
            #   with mcscf_rotate [[0, 0, 0, 0]], which should work as long as your molecule has at
            #   least 1 orbital in the 1st irrep. This problem can also be simply avoided by calculating
            #   the molecules that do not require orbital rotations first.
            'mcscf_rotate': [[0, 0, 0, 0]],
            'positivity': 'dq',
            'r_convergence': 1e-5,
            'e_convergence': 1e-6,
            'maxiter': 20000,
            'guess_orbitals_write': False,
            'molden_write': False,
        })

    psi4.activate(benzene_d2h)

    E_d2h = psi4.energy('v2rdm-casscf')

    assert psi4.compare_values(E_c1, E_d2h, 4, "v2RDM-CASSCF total energy")
Ejemplo n.º 17
0
def run_n_body(name, **kwargs):
    r"""Function encoding sequence of PSI module and plugin calls so that
    n_body can be called via :py:func:`~driver.energy`. For post-scf plugins.

    >>> energy('n_body')

    """
    lowername = name.lower()
    kwargs = p4util.kwargs_lower(kwargs)

    #    print("START run_n_body()")

    # Your plugin's psi4 run sequence goes here
    psi4.core.set_local_option('MYPLUGIN', 'PRINT', 1)

    ##### BEGIN TAYLOR'S run_n_body() FUNCTION #####

    # Only energy and properties are implemented for now, not sure others even
    # make sense anyways.

    db = shelve.open('database', writeback=True)
    #    print(db)
    # Initialize database
    if not 'initialized' in db:
        n_body.initialize_database(db, kwargs)
        db['initialized'] = True
    elif not db['initialized']:
        n_body.initialize_database(db, kwargs)
        db['initialized'] = True

    # Remove n_body_func, it's being tracked in the database and we don't want to propagate it
    if 'n_body_func' in kwargs:
        kwargs.pop('n_body_func')

    # Process user requested options
    n_body_options = n_body.process_options(name, db, kwargs.pop('n_body'))

    # Compare database options to n_body_options
    if 'distributed' in n_body_options:
        db['distributed'] = n_body_options['distributed']
        if not db['distributed']:
            raise Exception(
                "Currently n_body jobs must be run in distributed mode"
                " use the n_body wrapper instead.\n")
    if 'cutoff' in n_body_options:
        db['cutoff'] = n_body_options['cutoff']
    if 'num_threads' in n_body_options:
        db['num_threads'] = n_body_options['num_threads']
    if 'bsse' in n_body_options:
        db['bsse'] = n_body_options['bsse']
    if 'pcm' in n_body_options:
        db['pcm'] = n_body_options['pcm']
    if 'solute' in n_body_options:
        db['solute'] = n_body_options['solute']
    if 'timing' in n_body_options:
        db['timing'] = n_body_options['timing']
    if 'harvest' in n_body_options:
        db['harvest'] = n_body_options['harvest']
    if 'cook' in n_body_options:
        db['cook'] = n_body_options['cook']

    # methods consistency check
    if 'methods' in n_body_options:
        for key, val in n_body_options['methods'].items():
            if key in db['methods'].keys():
                # requested n_body_max smaller than previously requested
                if val < db['methods'][key]:
                    raise Exception('n_body_max for {} has '
                                    'decreased.'.format(key))
                # requested n_body_max has increased
                elif val > db['methods'][key]:
                    # save requested n_body_max
                    db['methods'][key] = val
                    # update database entries
                    n_body.extend_database(db, kwargs)
                    # set flag to regenerate inputs
                    db['inputs_generated'] = False
            else:  # method not already in database
                # add method and n_body_max to database
                db['methods'][key] = val
                # update database entries
                n_body.extend_database(db, kwargs)
                # set flag to regenerate inputs
                db['inputs_generated'] = False

    # Get complete system
    molecule = psi4.core.get_active_molecule()

    # Determine interacting fragments
    if db['cutoff']:
        i_pairs = n_body.interacting_pairs(db['cutoff'])
        i_clusters = []

    if not db['inputs_generated']:
        # Create method directories
        for method, n_body_max in db['methods'].items():
            try:
                os.makedirs(method)
            except:
                if os.path.isdir(method):
                    print(method)
                    pass
                else:
                    raise Exception('Attempt to create {} directory '
                                    'failed.'.format(method))
            # Create n_body_level directories
            for n in range(1, n_body_max + 1):
                directory = '{}/{}'.format(method, n_body.n_body_dir(n))
                try:
                    os.makedirs(directory)
                except:
                    if os.path.isdir(directory):
                        print(directory)
                        pass
                    else:
                        raise Exception('Attempt to create {} directory '
                                        'failed.'.format(directory))
                # Create job input files

                # Grab all ghost functions if SSFC
                # Else, get all possible clusters without ghost atoms
                if db['bsse'] == 'ssfc':
                    clusters = psi4.extract_clusters(molecule, True, n)
                else:
                    clusters = psi4.extract_clusters(molecule, False, n)

                # Flip distance-dropoff off for now
                #if db['bsse'] == 'radius'
                #clusters = extract_clusters(molecule, False, n)
                #clusters = n_body.expand_basis(clusters, db['basis_cutoff'])

                # Get list of fragments involved in clusters
                indexes = psi4.extract_cluster_indexing(molecule, n)
                print('Length of index array = {}'.format(len(indexes)))

                # Testing for extension to inclusion of nearby atoms (ghosted)
                #cluster_string = clusters[0].save_string_xyz_g09()
                #print(cluster_string)
                #cluster_string += molecule.extract_subsets(2).save_string_xyz_g09()
                #print(molecule.extract_subsets(2).save_string_xyz_g09())
                #print(clusters[0].save_string_xyz_g09())
                #print(cluster_string)
                #cluster_string = ''

                # Get interacting clusters
                if db['cutoff']:
                    if n == 1:
                        # Generate all inputs
                        pass
                    elif n == 2:
                        # generate inputs for i_pairs only
                        for k in range(len(clusters) - 1, -1, -1):
                            clus = indexes[k]
                            if clus in i_pairs:
                                i_clusters.append(clus)
                            else:
                                # Remove non-interacting clusters from lists
                                clusters.pop(k)
                                indexes.pop(k)

                    elif n > 2:
                        prev_clusters = copy.deepcopy(i_clusters)
                        i_clusters = []

                        for k in range(len(clusters) - 1, -1, -1):
                            # Check if interacting cluster
                            clus = indexes[k]
                            for p_clus in prev_clusters:
                                # previous cluster is contained within current cluster
                                if set(p_clus).issubset(set(clus)):
                                    # Get remaining frag number
                                    if len(set(clus).difference(
                                            set(p_clus))) == 1:
                                        l = set(clus).difference(
                                            set(p_clus)).pop()
                                    else:
                                        raise Exception(
                                            'Length of difference '
                                            'set is greater than 1')
                                    for m in p_clus:
                                        # Is this an interacting pair?
                                        if sorted([l, m],
                                                  reverse=True) in i_pairs:
                                            i_clusters.append(clus)
                                            # Don't check anymore pairs
                                            break
                                    if clus in i_clusters:
                                        break
                            else:
                                # Remove non-interacting clusters from lists
                                clusters.pop(k)
                                indexes.pop(k)

                # Create input files
                db[method][n]['total_num_jobs'] = len(clusters)
                print('n = {}'.format(n))
                print('Number of jobs created = {}'.format(len(clusters)))
                for k in range(len(clusters)):
                    psi4.activate(clusters[k])
                    cluster = psi4.core.get_active_molecule()
                    #                    db[method][n]['MW'][job] = value
                    ### Set-up things for input generation
                    # Get list of combinations to ghost
                    # MBCP
                    if db['bsse'] == 'mbcp' and n > 1:
                        mbcp = list(itertools.combinations(indexes[k], n - 1))
                        for ghost in mbcp:
                            directory = '{}/{}/{}'.format(
                                method, n_body.n_body_dir(n),
                                n_body.ghost_dir(indexes[k], ghost))
                            cluster.set_ghost_fragments(list(ghost))
                            cluster.update_geometry()
                            cluster.set_name('{}_{}'.format(
                                molecule.name(),
                                n_body.ghost_dir(indexes[k], ghost)))
                            n_body.plant(cluster, db, kwargs, method,
                                         directory)
                            # Update job_status dict
                            n_basis = n
                            n_real = n - len(ghost)
                            ghost_jobs = '{}-{}r'.format(n_basis, n_real)
                            #                            db[method][ghost_jobs]['total_num_jobs'] = len(mbcp) * len(clusters)
                            #                            db[method][ghost_jobs]['job_status'].update({n_body.ghost_dir(indexes[k],ghost):
                            #                                                                        'not_started'})
                            db[method][n]['total_num_jobs'] = len(mbcp) * len(
                                clusters)
                            db[method][n]['job_status'].update({
                                n_body.ghost_dir(indexes[k], ghost):
                                'not_started'
                            })
                            # Calculate molecular weight
                            totalmass = sum(
                                mol2.mass(i) for i in range(mol2.natom())
                                if mol2.Z(i))
                            totmass = sum(
                                cluster.mass(i) for i in range(cluster.natom())
                                if cluster.Z(i))
                            db[method][n]['MW'].update(
                                {n_body.ghost_dir(indexes[k], ghost): totmass})
                            # Reactivate fragments for next round
                            cluster.set_active_fragments(list(ghost))
                            cluster.update_geometry()
                    # VMFC
                    elif db['bsse'] == 'vmfc':
                        vmfc = []
                        for n_ghost in range(n - 1, 0, -1):
                            vmfc.extend(
                                list(
                                    itertools.combinations(
                                        indexes[k], n_ghost)))
                        for ghost in vmfc:
                            directory = '{}/{}/{}'.format(
                                method, n_body.n_body_dir(n),
                                n_body.ghost_dir(indexes[k], ghost))
                            cluster.set_ghost_fragments(list(ghost))
                            cluster.update_geometry()
                            cluster.set_name('{}_{}'.format(
                                molecule.name(),
                                n_body.ghost_dir(indexes[k], ghost)))
                            n_body.plant(cluster, db, kwargs, method,
                                         directory)
                            # Update job_status dict
                            n_basis = n
                            n_real = n - len(ghost)
                            ghost_jobs = '{}-{}r'.format(n_basis, n_real)
                            #db[method][ghost_jobs]['total_num_jobs'] = len(vmfc) * len(clusters)
                            #                            db[method][ghost_jobs]['total_num_jobs'] = len(list(itertools.combinations(range(0,n),n_real))) * len(clusters)
                            #                            db[method][ghost_jobs]['job_status'].update({n_body.ghost_dir(indexes[k],ghost):
                            #                                                                        'not_started'})
                            db[method][n]['total_num_jobs'] = len(
                                list(
                                    itertools.combinations(
                                        range(0, n), n_real))) * len(clusters)
                            db[method][n]['job_status'].update({
                                n_body.ghost_dir(indexes[k], ghost):
                                'not_started'
                            })
                            # Calculate molecular weight
                            totmass = sum(
                                cluster.mass(i) for i in range(cluster.natom())
                                if cluster.Z(i))
                            db[method][n]['MW'].update(
                                {n_body.ghost_dir(indexes[k], ghost): totmass})
                            # Reactivate fragments for next round
                            cluster.set_active_fragments(list(ghost))
                            cluster.update_geometry()

                    # SSFC or no BSSE
                    else:
                        cluster.set_name('{}_{}'.format(
                            molecule.name(), n_body.cluster_dir(indexes[k])))
                        #molecule.set_name('{}_{}'.format(molecule.name(),cluster_dir(indexes[k])))
                        directory = '{}/{}/{}'.format(
                            method, n_body.n_body_dir(n),
                            n_body.cluster_dir(indexes[k]))
                        n_body.plant(cluster, db, kwargs, method, directory)

                        # Update database job_status dict
                        db[method][n]['job_status'].update(
                            {n_body.cluster_dir(indexes[k]): 'not_started'})
                        # Calculate molecular weight
                        totmass = sum(
                            cluster.mass(i) for i in range(cluster.natom())
                            if cluster.Z(i))
                        db[method][n]['MW'].update(
                            {n_body.cluster_dir(indexes[k]): totmass})
        # Check for zero jobs (happens occasionally due to cutoff)
        for method in db['methods']:
            for n in range(1, db[method]['n_body_max'] + 1):
                if db[method][n]['total_num_jobs'] == 0:
                    db[method]['n_body_max'] = n - 1
                    break
        # Inputs successfully generated
        db['inputs_generated'] = True

    # For now open and close database frequently, until I figure out atexit
    db.close()
    db = shelve.open('database', writeback=True)

    # Check status of jobs
    if not db['jobs_complete']:
        n_incomplete = 0
        # Check all methods
        for method in db['methods'].keys():
            #### NOTE: dft_methods is defunct #####
            #            if method in n_body.dft_methods:
            #                outname = 'input.log'
            #                complete_message = 'Normal termination of Gaussian'
            #            if (method == 'b3lyp'):
            if method in n_body.dft_methods:
                outname = 'input.log'
                complete_message = 'Normal termination of Gaussian'
                error_message = 'Error termination'
            else:
                outname = 'output.dat'
                complete_message = 'Psi4 exiting successfully'
                error_message = 'Psi4 encountered an error'
            # Check all n_body_levels
            print('Before job checking:')
            for field in db[method]['farm']:
                num_fin = db[method][field]['num_jobs_complete']
                tot_num = db[method][field]['total_num_jobs']
                print('{}/{} {}-body jobs finished'.format(
                    num_fin, tot_num, field))
                n_complete = num_fin
                if num_fin != tot_num:
                    db_stat = db[method][field]['job_status']
                    n_complete = 0
                    for job, status in db_stat.items():
                        if status == 'complete':
                            n_complete += 1
                        elif status in ('not_started', 'running', 'error'):
                            try:
                                outfile = open('{}/{}/{}/{}'.format(
                                    method, n_body.n_body_dir(field), job,
                                    outname))
                                for line in outfile:
                                    if complete_message in line:
                                        # This actually marks the job complete as soon as
                                        # the first route section is complete in the case
                                        # of g09, not when the job is totally finished.
                                        db_stat[job] = 'complete'
                                        n_complete += 1
                                        break
                                    elif error_message in line:
                                        db_stat[job] = 'error'
                                        break
                                else:
                                    db_stat[job] = 'running'
                                    n_incomplete += 1
                            except:
                                # this print statement is super annoying, muting it for now
                                #                                print('Exception: probably could not open file for {}'.format(job))
                                n_incomplete += 1
                db[method][field]['num_jobs_complete'] = n_complete
        if n_incomplete == 0:
            db['jobs_complete'] = True

    db.close()
    db = shelve.open('database', writeback=True)

    # Gather results
    if not db['results_computed']:
        for method in db['methods'].keys():
            print('\nAfter job checking:')
            for field in db[method]['farm']:
                num_fin = db[method][field]['num_jobs_complete']
                tot_num = db[method][field]['total_num_jobs']
                print('{}/{} {}-body jobs finished'.format(
                    num_fin, tot_num, field))
                if (db[method][field]['num_jobs_complete'] == db[method][field]
                    ['total_num_jobs']):
                    if db['harvest']:
                        if method in n_body.dft_methods:
                            n_body.harvest_g09(db, method, field)
                        else:
                            n_body.harvest_data(db, method, field)
            if not db['harvest']:
                print("Data harvesting has been disabled.")
            elif not db['cook']:
                print("Data cooking has been disabled.")
            else:
                for field in db[method]['farm']:
                    if (db[method][field]['num_jobs_complete'] == db[method]
                        [field]['total_num_jobs']):
                        n_body.cook_data(db, method, field)
#                       #if db['bsse'] == 'vmfc' and field > 1:
#                       #    n_body.vmfc_cook(db, method, field)
#                       #    n_body.mbcp_cook(db, method, field)
#                       if db['bsse'] == 'vmfc':
#                           n_body.vmfc_cook(db, method, field)
#                           if field > 1:
#                               n_body.mbcp_cook(db, method, field)
#                       elif db['bsse'] == 'mbcp' and field > 1:
#                           n_body.mbcp_cook(db,method,field)
#                       # Future location of an if check for mass adjust or not
#                       if 'rotation' in db[method]['results']:
#                           n_body.mass_adjust_rotations(db,method,field)

    db.close()
    db = shelve.open('database', writeback=True)

    # Print banner to output file including user options
    n_body.banner(db)

    db.close()

    pass
Ejemplo n.º 18
0
def test_v2rdm_doci():
    """hilbert/tests/v2rdm_doci"""
    #! 6-31g H2O v2RDM-DOCI Test

    import psi4

    import sys
    sys.path.insert(0, '../..')
    import hilbert

    h2o = psi4.geometry("""
    0 1
    o
    h 1 1.0
    h 1 1.0 2 104.5
    symmetry c1
    """)

    interloper = psi4.geometry("""
    0 1
    O
    H 1 1.0
    H 1 1.0 2 90.0
    """)

    psi4.set_options({
        'basis': '6-31g',
        'scf_type': 'df',
        'e_convergence': 1e-4,
        'r_convergence': 1e-6,
        'maxiter': 100000,
    })
    psi4.set_module_options(
        'hilbert', {
            'orbopt_maxiter': 20,
            'localize_orbitals': True,
            'noisy_orbitals': True,
            'optimize_orbitals': True,
            'orbopt_gradient_convergence': 1e-6,
            'orbopt_energy_convergence': 1e-8,
            'orbopt_frequency': 1000,
        })

    psi4.activate(h2o)

    ref_scf = -75.98014193580194
    ref_v2rdm_doci = -76.053681341564

    # be sure to save three-index integrals after scf
    psi4.core.set_local_option('SCF', 'DF_INTS_IO', 'SAVE')

    # get scf wfn
    scf_energy, ref_wfn = psi4.energy('scf', return_wfn=True)

    # grab options object
    options = psi4.core.get_options()
    options.set_current_module('HILBERT')

    # evaluate v2RDM-DOCI energy
    v2rdm_doci = hilbert.v2RDM_DOCIHelper(ref_wfn, options)
    current_energy = v2rdm_doci.compute_energy()

    assert psi4.compare_values(ref_scf, scf_energy, 8, "SCF total energy")
    assert psi4.compare_values(ref_v2rdm_doci, current_energy, 4,
                               "v2RDM-DOCI total energy")
Ejemplo n.º 19
0
def test_v2rdm4():

    print('        1,4-phenylenedinitrene/(10,10)/cc-pVDZ')

    import psi4

    singlet = psi4.geometry("""
    0 1
    C      0.00000000    -1.43825841     0.00000000
    C      1.26321637    -0.67149862     0.00000000
    C      1.26321637     0.67149862     0.00000000
    C      0.00000000     1.43825841     0.00000000
    C     -1.26321637     0.67149862     0.00000000
    C     -1.26321637    -0.67149862     0.00000000
    H      2.18678709    -1.24095300     0.00000000
    H      2.18678709     1.24095300     0.00000000
    H     -2.18678709     1.24095300     0.00000000
    H     -2.18678709    -1.24095300     0.00000000
    N      0.00000000     2.71003942     0.00000000
    N      0.00000000    -2.71003942     0.00000000
    """)
    triplet = psi4.geometry("""
    0 3
    C      0.00000000    -1.43825841     0.00000000
    C      1.26321637    -0.67149862     0.00000000
    C      1.26321637     0.67149862     0.00000000
    C      0.00000000     1.43825841     0.00000000
    C     -1.26321637     0.67149862     0.00000000
    C     -1.26321637    -0.67149862     0.00000000
    H      2.18678709    -1.24095300     0.00000000
    H      2.18678709     1.24095300     0.00000000
    H     -2.18678709     1.24095300     0.00000000
    H     -2.18678709    -1.24095300     0.00000000
    N      0.00000000     2.71003942     0.00000000
    N      0.00000000    -2.71003942     0.00000000
    """)

    psi4.set_options({
        'basis': 'cc-pvdz',
        'scf_type': 'df',
        'd_convergence': 1e-8,
        'maxiter': 500,
        'reference': 'rohf',
        'restricted_docc': [8, 3, 0, 0, 0, 0, 7, 4],
        'active': [0, 1, 1, 3, 1, 3, 0, 1],
    })
    psi4.set_module_options(
        'v2rdm_casscf', {
            'positivity': 'dqg',
            'constrain_spin': True,
            'r_convergence': 1e-4,
            'e_convergence': 1e-4,
            'cg_convergence': 1e-8,
            'mu_update_frequency': 250,
            'orbopt_frequency': 500,
            'maxiter': 100000,
        })

    # singlet
    # from JCTC, with r_convergence = e_convergence = 1e-5
    #    * v2RDM total energy:           -338.502362198038

    psi4.activate(singlet)
    ref_singlet = -338.502342367694
    e_singlet = psi4.energy('v2rdm-casscf')

    assert psi4.compare_values(e_singlet, ref_singlet, 4, "singlet")

    # triplet
    # from JCTC, with r_convergence = e_convergence = 1e-5
    #    * v2RDM total energy:           -338.495146818081

    psi4.activate(triplet)
    ref_triplet = -338.495170913420
    e_triplet = psi4.energy('v2rdm-casscf')

    assert psi4.compare_values(e_triplet, ref_triplet, 4, "triplet")
Ejemplo n.º 20
0
def test_dftd3():
    """dftd3/energy"""
    #! Exercises the various DFT-D corrections, both through python directly and through c++

    ref_d2         = [-0.00390110, -0.00165271, -0.00058118]
    ref_d3zero     = [-0.00285088, -0.00084340, -0.00031923]
    ref_d3bj       = [-0.00784595, -0.00394347, -0.00226683]

    ref_pbe_d2     = [-0.00278650, -0.00118051, -0.00041513]
    ref_pbe_d3zero = [-0.00175474, -0.00045421, -0.00016839]
    ref_pbe_d3bj   = [-0.00475937, -0.00235265, -0.00131239]

    eneyne = psi4.geometry("""
    C   0.000000  -0.667578  -2.124659
    C   0.000000   0.667578  -2.124659
    H   0.923621  -1.232253  -2.126185
    H  -0.923621  -1.232253  -2.126185
    H  -0.923621   1.232253  -2.126185
    H   0.923621   1.232253  -2.126185
    --
    C   0.000000   0.000000   2.900503
    C   0.000000   0.000000   1.693240
    H   0.000000   0.000000   0.627352
    H   0.000000   0.000000   3.963929
    """)

    print('  -D correction from Py-side')
    eneyne.update_geometry()
    E, G = eneyne.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[0], E, 7, 'Ethene-Ethyne -D2')
    mA = eneyne.extract_subsets(1)
    E, G = mA.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[1], E, 7, 'Ethene -D2')
    mB = eneyne.extract_subsets(2)
    E, G = mB.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[2], E, 7, 'Ethyne -D2')
    #mBcp = eneyne.extract_subsets(2,1)
    #E, G = mBcp.run_dftd3('b3lyp', 'd2')
    #compare_values(ref_d2[2], E, 7, 'Ethyne(CP) -D2')

    E, G = eneyne.run_dftd3('b3lyp', 'd3zero')
    assert psi4.compare_values(ref_d3zero[0], E, 7, 'Ethene-Ethyne -D3 (zero)')
    mA = eneyne.extract_subsets(1)
    E, G = mA.run_dftd3('b3lyp', 'd3zero')
    assert psi4.compare_values(ref_d3zero[1], E, 7, 'Ethene -D3 (zero)')
    mB = eneyne.extract_subsets(2)
    E, G = mB.run_dftd3('b3lyp', 'd3zero')
    assert psi4.compare_values(ref_d3zero[2], E, 7, 'Ethyne -D3 (zero)')

    E, G = eneyne.run_dftd3('b3lyp', 'd3bj')
    assert psi4.compare_values(ref_d3bj[0], E, 7, 'Ethene-Ethyne -D3 (bj)')
    mA = eneyne.extract_subsets(1)
    E, G = mA.run_dftd3('b3lyp', 'd3bj')
    assert psi4.compare_values(ref_d3bj[1], E, 7, 'Ethene -D3 (bj)')
    mB = eneyne.extract_subsets(2)
    E, G = mB.run_dftd3('b3lyp', 'd3bj')
    assert psi4.compare_values(ref_d3bj[2], E, 7, 'Ethyne -D3 (bj)')

    E, G = eneyne.run_dftd3('b3lyp', 'd3')
    assert psi4.compare_values(ref_d3zero[0], E, 7, 'Ethene-Ethyne -D3 (alias)')
    E, G = eneyne.run_dftd3('b3lyp', 'd')
    assert psi4.compare_values(ref_d2[0], E, 7, 'Ethene-Ethyne -D (alias)')
    E, G = eneyne.run_dftd3('b3lyp', 'd2')
    assert psi4.compare_values(ref_d2[0], E, 7, 'Ethene-Ethyne -D2 (alias)')

    psi4.set_options({'basis': 'sto-3g',
                      'scf_type': 'df',
                      'dft_radial_points': 50,  # use really bad grid for speed since all we want is the -D value
                      'dft_spherical_points': 110,
                      #'scf print': 3,  # will print dftd3 program output to psi4 output file
                    })

    print('  -D correction from C-side')
    psi4.activate(mA)
    #psi4.energy('b3lyp-d2', engine='libdisp')
    #assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling psi4 Disp class)')
    #psi4.energy('b3lyp-d2')
    #assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling dftd3 -old)')
    #psi4.energy('b3lyp-d3zero')
    #assert psi4.compare_values(ref_d3zero[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (calling dftd3 -zero)')
    psi4.energy('b3lyp-d3bj')
    assert psi4.compare_values(ref_d3bj[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (calling dftd3 -bj)')

    psi4.energy('b3lyp-d2', engine='libdisp')
    assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (alias)')
    #psi4.energy('b3lyp-d3')
    #assert psi4.compare_values(ref_d3zero[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (alias)')
    #psi4.energy('b3lyp-d')
    #assert psi4.compare_values(ref_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D (alias)')
    psi4.energy('wb97x-d')
    assert psi4.compare_values(-0.000834247063, psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene wb97x-d (chg)')

    print('  non-default -D correction from C-side')
    psi4.activate(mB)
    #psi4.set_options({'dft_dispersion_parameters': [0.75]})
    #psi4.energy('b3lyp-d2', engine='libdisp')
    #assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling psi4 Disp class)')
    #psi4.set_options({'dft_dispersion_parameters': [0.75, 20.0]})
    #psi4.energy('b3lyp-d2')
    #assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (calling dftd3 -old)')
    #psi4.set_options({'dft_dispersion_parameters': [1.0,  0.722, 1.217, 14.0]})
    #psi4.energy('b3lyp-d3zero')
    #assert psi4.compare_values(ref_pbe_d3zero[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (calling dftd3 -zero)')
    psi4.set_options({'dft_dispersion_parameters': [1.000, 0.7875, 0.4289, 4.4407]})
    psi4.energy('b3lyp-d3bj')
    assert psi4.compare_values(ref_pbe_d3bj[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (calling dftd3 -bj)')

    psi4.set_options({'dft_dispersion_parameters': [0.75]})
    psi4.energy('b3lyp-d2', engine='dftd3')
    assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2 (alias)')
    psi4.set_options({'dft_dispersion_parameters': [1.0,  0.722, 1.217, 14.0]})
    psi4.energy('b3lyp-d3')
    assert psi4.compare_values(ref_pbe_d3zero[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (alias)')
    psi4.set_options({'dft_dispersion_parameters': [0.75]})
    psi4.energy('b3lyp-d')
    assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D (alias)')
    psi4.activate(mA)
    psi4.set_options({'dft_dispersion_parameters': [1.0]})
    psi4.energy('wb97x-d')
    assert psi4.compare_values(-0.000834247063, psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene wb97x-d (chg)')

    print('  non-default -D correction from Py-side')
    eneyne.update_geometry()
    eneyne.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[0], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene-Ethyne -D2')
    mA = eneyne.extract_subsets(1)
    mA.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D2')
    mB = eneyne.extract_subsets(2)
    mB.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethyne -D2')

    eneyne.run_dftd3('b3lyp', 'd3zero', {'s6': 1.0,  's8': 0.722, 'sr6': 1.217, 'alpha6': 14.0})
    assert psi4.compare_values(ref_pbe_d3zero[0], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene-Ethyne -D3 (zero)')
    mA = eneyne.extract_subsets(1)
    mA.run_dftd3('b3lyp', 'd3zero', {'s6': 1.0,  's8': 0.722, 'sr6': 1.217, 'alpha6': 14.0})
    assert psi4.compare_values(ref_pbe_d3zero[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (zero)')
    mB = eneyne.extract_subsets(2)
    mB.run_dftd3('b3lyp', 'd3zero', {'s6': 1.0,  's8': 0.722, 'sr6': 1.217, 'alpha6': 14.0})
    assert psi4.compare_values(ref_pbe_d3zero[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethyne -D3 (zero)')

    eneyne.run_dftd3('b3lyp', 'd3bj', {'s6': 1.000, 's8':  0.7875, 'a1':  0.4289, 'a2': 4.4407})
    assert psi4.compare_values(ref_pbe_d3bj[0], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene-Ethyne -D3 (bj)')
    mA = eneyne.extract_subsets(1)
    mA.run_dftd3('b3lyp', 'd3bj', {'s6': 1.000, 's8':  0.7875, 'a1':  0.4289, 'a2': 4.4407})
    assert psi4.compare_values(ref_pbe_d3bj[1], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene -D3 (bj)')
    mB = eneyne.extract_subsets(2)
    mB.run_dftd3('b3lyp', 'd3bj', {'s6': 1.000, 's8':  0.7875, 'a1':  0.4289, 'a2': 4.4407})
    assert psi4.compare_values(ref_pbe_d3bj[2], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethyne -D3 (bj)')
    eneyne.run_dftd3('b3lyp', 'd3', {'s6': 1.0,  's8': 0.722, 'sr6': 1.217, 'alpha6': 14.0})

    assert psi4.compare_values(ref_pbe_d3zero[0], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene-Ethyne -D3 (alias)')
    eneyne.run_dftd3('b3lyp', 'd', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[0], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene-Ethyne -D (alias)')
    eneyne.run_dftd3('b3lyp', 'd2', {'s6': 0.75})
    assert psi4.compare_values(ref_pbe_d2[0], psi4.variable('DISPERSION CORRECTION ENERGY'), 7, 'Ethene-Ethyne -D2 (alias)')