Exemple #1
0
import numpy as np
from pyscf import gto, scf, tools
from c2h6n4_struct import structure as struct
from mrh.my_pyscf.mcscf.lasscf_testing import LASSCF

rnn0 = 1.23681571
mol = struct(3.0, 3.0, '6-31g', symmetry=False)
mf = scf.RHF(mol).run()
las = LASSCF(mf, (4, 4), (4, 4), spin_sub=(1, 1))
frag_atom_list = (list(range(3)), list(range(9, 12)))
mo0 = las.localize_init_guess(frag_atom_list)
las.kernel(mo0)
las_scanner = las.as_scanner()

pes = np.loadtxt('c2h6n4_pes_old.dat')[:34, :]
pes = np.hstack((pes, np.zeros((34, 1))))
pes[33, 3] = las.e_tot

# ISN'T THIS SO MUCH BETTER RIDDHISH?????
for ix, dr_nn in enumerate(np.arange(2.9, -0.301, -0.1)):
    mol1 = struct(dr_nn, dr_nn, '6-31g', symmetry=False)
    pes[32 - ix, 3] = las_scanner(mol1)

print("  r_NN  {:>11s}  {:>13s}  {:>13s}".format("CASSCF", "vLASSCF(v1)",
                                                 "vLASSCF(test)"))
for row in pes:
    print(" {:5.3f}  {:11.6f}  {:13.8f}  {:13.8f}".format(*row))
Exemple #2
0
            self.savedPath = os.getcwd()
            os.chdir(self.newPath)

        def __exit__(self, etype, value, traceback):
            os.chdir(self.savedPath)

    from mrh.examples.lasscf.c2h6n4.c2h6n4_struct import structure as struct
    with cd("/home/herme068/gits/mrh/examples/lasscf/c2h6n4"):
        mol = struct(2.0, 2.0, '6-31g', symmetry=False)
    mol.verbose = lib.logger.DEBUG
    mol.output = 'sa_lasscf_slow_ham.log'
    mol.build()
    mf = scf.RHF(mol).run()
    tol = 1e-6 if len(sys.argv) < 2 else float(sys.argv[1])
    las = LASSCF(mf, (4, 4), (4, 4)).set(conv_tol_grad=tol)
    mo = las.localize_init_guess((list(range(3)), list(range(9, 12))),
                                 mo_coeff=mf.mo_coeff)
    las.state_average_(weights=[0.5, 0.5], spins=[[0, 0], [2, -2]])
    h2eff_sub, veff = las.kernel(mo)[-2:]
    e_states = las.e_states

    ncore, ncas, nocc = las.ncore, las.ncas, las.ncore + las.ncas
    mo_coeff = las.mo_coeff
    mo_core = mo_coeff[:, :ncore]
    mo_cas = mo_coeff[:, ncore:nocc]
    e0 = las._scf.energy_nuc() + 2 * ((
        (las._scf.get_hcore() + veff.c / 2) @ mo_core) * mo_core).sum()
    h1 = mo_cas.conj().T @ (las._scf.get_hcore() + veff.c) @ mo_cas
    h2 = h2eff_sub[ncore:nocc].reshape(ncas * ncas, ncas * (ncas + 1) // 2)
    h2 = lib.numpy_helper.unpack_tril(h2).reshape(ncas, ncas, ncas, ncas)
    nelec_fr = []
    for fcibox, nelec in zip(las.fciboxes, las.nelecas_sub):
Exemple #3
0
    3) List or tuple of nelec for each fragment
    A list or tuple of total-spin multiplicity is supplied
    in "spin_sub".'''
las = LASSCF(mf, (4, 4), (4, 4), spin_sub=(1, 1))
''' The class doesn't know anything about "fragments" at all.
    The active space is only "localized" provided one offers an
    initial guess for the active orbitals that is localized.
    That is the purpose of the localize_init_guess function.
    It requires a sequence of sequence of atom numbers, and it
    projects the orbitals in the ncore:nocc columns into the
    space of those atoms' AOs. The orbitals in the range
    ncore:ncore+ncas_sub[0] are the first active subspace,
    those in the range ncore+ncas_sub[0]:ncore+sum(ncas_sub[:2])
    are the second active subspace, and so on.'''
frag_atom_list = (list(range(3)), list(range(7, 10)))
mo_coeff = las.localize_init_guess(frag_atom_list, mf.mo_coeff)
''' Right now, this function can only (roughly) reproduce the
    "force_imp=False, confine_guess=True" behavior of the old 
    orbital guess builder. I might add the complement later,
    but if you are doing potential energy scans or geometry
    optimizations I think the current implementation of
    pyscf.mcscf.addons.project_init_guess might actually be better.'''
las.kernel(mo_coeff)
print("E(dia singlet) =", las.e_tot)

# 2. Antiferromagnetic quasi-singlet
''' To change the spin projection quantum numbers of the
    subspaces, instead of providing a list of nelec, provide
    a list of tuples of (neleca,nelecb).'''
las = LASSCF(mf, (4, 4), ((4, 0), (0, 4)), spin_sub=(5, 5))
las.kernel(mo_coeff)
Exemple #4
0
] + [
    0.0,
] * 56
nroots = 57
# End building crazy state list

dr_nn = 2.0
mol = struct(dr_nn, dr_nn, '6-31g', symmetry='Cs')
mol.verbose = lib.logger.INFO
mol.output = 'test_lassi_op.log'
mol.spin = 0
mol.build()
mf = scf.RHF(mol).run()
las = LASSCF(mf, (4, 2, 4), (4, 2, 4))
las.state_average_(weights=weights, **states)
las.mo_coeff = las.localize_init_guess(
    (list(range(3)), list(range(3, 7)), list(range(7, 10))), mf.mo_coeff)
las.ci = get_init_guess_ci(las, las.mo_coeff, las.get_h2eff(las.mo_coeff))
np.random.seed(1)
for c in las.ci:
    for iroot in range(len(c)):
        c[iroot] = np.random.rand(*c[iroot].shape)
        c[iroot] /= linalg.norm(c[iroot])
orbsym = getattr(las.mo_coeff, 'orbsym', None)
if orbsym is None and callable(getattr(las, 'label_symmetry_', None)):
    orbsym = las.label_symmetry_(las.mo_coeff).orbsym
if orbsym is not None:
    orbsym = orbsym[las.ncore:las.ncore + las.ncas]
wfnsym = 0
idx_all = np.ones(nroots, dtype=np.bool_)
rand_mat = np.random.rand(57, 57)
rand_mat += rand_mat.T
Exemple #5
0
 def test_symm_df (self):
     las = LASSCF (mf_df, (4,4), (4,4), spin_sub=(1,1))
     mo_coeff = las.localize_init_guess (frags)
     las.kernel (mo_coeff)
     self.assertAlmostEqual (las.e_tot, -295.44716017803967, 7)
Exemple #6
0
 def test_symm (self):
     las = LASSCF (mf, (4,4), (4,4), spin_sub=(1,1))
     mo_coeff = las.localize_init_guess (frags)
     las.kernel (mo_coeff)
     self.assertAlmostEqual (las.e_tot, -295.44779578419946, 7)
Exemple #7
0
# SA-LASSCF object
# The first positional argument of "state_average" is the orbital weighting function
# Note that there are four states and two fragments and the weights sum to 1
# "Spins" is neleca - nelecb (= 2m for the sake of being an integer)
# "Smults" is the desired local spin quantum *MULTIPLICITY* (2s+1)
# "Wfnsyms" can also be the names of the irreps but I got lazy
# "Charges" should be self-explanatory
# If your molecule doesn't have point-group symmetry turned on then don't pass "wfnsyms"
las = LASSCF(mf, (5, 5), ((3, 2), (2, 3)))
las = las.state_average([0.5, 0.5, 0.0, 0.0],
                        spins=[[1, -1], [-1, 1], [0, 0], [0, 0]],
                        smults=[[2, 2], [2, 2], [1, 1], [1, 1]],
                        charges=[[0, 0], [0, 0], [-1, 1], [1, -1]],
                        wfnsyms=[[1, 1], [1, 1], [0, 0], [0, 0]])
mo_loc = las.localize_init_guess((list(range(5)), list(range(5, 10))),
                                 mf.mo_coeff)
las.kernel(mo_loc)
print("\n---SA-LASSCF---")
print("Energy:", las.e_states)

# For now, the LASSI diagonalizer is just a post-hoc function call
# It returns eigenvalues (energies) in the first position and
# eigenvectors (here, a 4-by-4 vector)
e_roots, si = las.lassi()

# Symmetry information about the LASSI solutions is "tagged" on the si array
# Additionally, since spin contamination sometimes happens, the S**2 operator
# in the LAS-state "diabatic" basis is also available
print("S**2 operator:\n", si.s2_mat)
print("\n---LASSI solutions---")
print("Energy:", e_roots)
Exemple #8
0
 def test_af_df (self):
     las = LASSCF (mf_hs_df, (4,4), ((4,0),(0,4)), spin_sub=(5,5))
     mo_coeff = las.localize_init_guess (frags)
     las.kernel (mo_coeff)
     self.assertAlmostEqual (las.e_tot, -295.4466638852035, 7)
Exemple #9
0
 def test_ferro_df (self):
     las = LASSCF (mf_hs_df, (4,4), ((4,0),(4,0)), spin_sub=(5,5))
     mo_coeff = las.localize_init_guess (frags)
     las.kernel (mo_coeff)
     self.assertAlmostEqual (las.e_tot, mf_hs_df.e_tot, 7)