示例#1
0
    def initial_greens_function_uhf(self, A, B, trial, nup, weights):
        r"""Compute initial green's function at timestep n for UHF wavefunction.

        Here we actually compute the equal-time green's function:

        .. math::

            G_{ij} = \langle c_i c_j^{\dagger} \rangle

        Parameters
        ----------
        A : :class:`numpy.ndarray`
            Left hand wavefunction for green's function.
        B : :class:`numpy.ndarray`
            Left hand wavefunction for green's function.
        trial : :class:`pauxy.trial_wavefunction.X' object
            Trial wavefunction class.
        nup : int
            Number of up electrons.
        weight : :class:`numpy.ndarray`
            Any GS orthogonalisation factors which need to be included.

        Returns
        -------
        G_nn : :class:`numpy.ndarray`
            Green's function.
        """
        Ggr_up = self.I - gab(A[:, :nup], B[:, :nup])
        Ggr_down = self.I - gab(A[:, nup:], B[:, nup:])
        Gls_up = self.I - Ggr_up
        Gls_down = self.I - Ggr_down
        return (numpy.array([Ggr_up,
                             Ggr_down]), numpy.array([Gls_up, Gls_down]))
示例#2
0
def freeze_core(h1e, chol, ecore, nc, ncas, verbose=True):
    # 1. Construct one-body hamiltonian
    print(ecore, type(h1e), type(chol))
    nbasis = h1e.shape[-1]
    chol = chol.reshape((-1, nbasis, nbasis))
    system = dotdict({
        'H1': numpy.array([h1e, h1e]),
        'chol_vecs': chol,
        'ecore': ecore,
        'nbasis': nbasis
    })
    psi = numpy.identity(nbasis)[:, :nc]
    Gcore = gab(psi, psi)
    ecore = local_energy_generic_cholesky(system, [Gcore, Gcore])[0]
    (hc_a, hc_b) = core_contribution_cholesky(system.chol_vecs, [Gcore, Gcore])
    h1e = numpy.array([h1e, h1e])
    h1e[0] = h1e[0] + 2 * hc_a
    h1e[1] = h1e[1] + 2 * hc_b
    h1e = h1e[:, nc:nc + ncas, nc:nc + ncas]
    nchol = chol.shape[0]
    chol = chol[:, nc:nc + ncas, nc:nc + ncas].reshape((nchol, -1))
    # 4. Subtract one-body term from writing H2 as sum of squares.
    if verbose:
        print(" # Number of active orbitals: %d" % ncas)
        print(" # Freezing %d core electrons and %d virtuals." %
              (2 * nc, nbasis - nc - ncas))
        print(" # Frozen core energy : %13.8e" % ecore.real)
    return h1e, chol, ecore
示例#3
0
文件: ueg.py 项目: hungpham2017/pauxy
def unit_test():
    from pauxy.systems.ueg import UEG
    import numpy as np
    inputs = {'nup': 7, 'ndown': 7, 'rs': 1.0, 'ecut': 2.0}
    system = UEG(inputs, True)
    nbsf = system.nbasis
    Pa = np.zeros([nbsf, nbsf], dtype=np.complex128)
    Pb = np.zeros([nbsf, nbsf], dtype=np.complex128)
    na = system.nup
    nb = system.ndown
    for i in range(na):
        Pa[i, i] = 1.0
    for i in range(nb):
        Pb[i, i] = 1.0
    P = np.array([Pa, Pb])
    etot, ekin, epot = local_energy_ueg(system, G=P)
    print("ERHF = {}, {}, {}".format(etot, ekin, epot))

    from pauxy.utils.linalg import exponentiate_matrix, reortho
    from pauxy.estimators.greens_function import gab
    # numpy.random.seed()
    rCa = numpy.random.randn(nbsf, na)
    zCa = numpy.random.randn(nbsf, na)
    rCb = numpy.random.randn(nbsf, nb)
    zCb = numpy.random.randn(nbsf, nb)

    Ca = rCa + 1j * zCa
    Cb = rCb + 1j * zCb

    Ca, detR = reortho(Ca)
    Cb, detR = reortho(Cb)
    # S = print(Ca.dot(Cb.T))
    # print(S)
    # exit()
    Ca = numpy.array(Ca, dtype=numpy.complex128)
    Cb = numpy.array(Cb, dtype=numpy.complex128)
    P = [gab(Ca, Ca), gab(Cb, Cb)]
示例#4
0
 def __init__(self, system, cplx, trial, parallel=False, verbose=0):
     if verbose:
         print("# Constructing UHF trial wavefunction")
     self.verbose = verbose
     init_time = time.time()
     self.name = "UHF"
     self.type = "UHF"
     self.initial_wavefunction = trial.get('initial_wavefunction', 'trial')
     if cplx:
         self.trial_type = complex
     else:
         self.trial_type = float
     # Unpack input options.
     self.ninitial = trial.get('ninitial', 10)
     self.nconv = trial.get('nconv', 5000)
     self.ueff = trial.get('ueff', 0.4)
     self.deps = trial.get('deps', 1e-8)
     self.alpha = trial.get('alpha', 0.5)
     # For interface compatability
     self.coeffs = 1.0
     self.type = 'UHF'
     self.ndets = 1
     (self.psi, self.eigs, self.emin, self.error,
      self.nav) = (self.find_uhf_wfn(system, cplx, self.ueff, self.ninitial,
                                     self.nconv, self.alpha, self.deps,
                                     verbose))
     if self.error and not parallel:
         warnings.warn('Error in constructing trial wavefunction. Exiting')
         sys.exit()
     Gup = gab(self.psi[:, :system.nup], self.psi[:, :system.nup]).T
     Gdown = gab(self.psi[:, system.nup:], self.psi[:, system.nup:]).T
     self.G = numpy.array([Gup, Gdown])
     self.etrial = local_energy(system, self.G)[0].real
     self.bp_wfn = trial.get('bp_wfn', None)
     self.initialisation_time = time.time() - init_time
     self.init = self.psi
示例#5
0
    def find_uhf_wfn(self,
                     system,
                     cplx,
                     ueff,
                     ninit,
                     nit_max,
                     alpha,
                     deps=1e-8,
                     verbose=0):
        emin = 0
        uold = system.U
        system.U = ueff
        minima = []  # Local minima
        nup = system.nup
        # Search over different random starting points.
        for attempt in range(0, ninit):
            # Set up initial (random) guess for the density.
            (self.trial, eold) = self.initialise(system.nbasis, system.nup,
                                                 system.ndown, cplx)
            niup = self.density(self.trial[:, :nup])
            nidown = self.density(self.trial[:, nup:])
            niup_old = self.density(self.trial[:, :nup])
            nidown_old = self.density(self.trial[:, nup:])
            for it in range(0, nit_max):
                (niup, nidown, e_up, e_down) = (self.diagonalise_mean_field(
                    system, ueff, niup, nidown))
                # Construct Green's function to compute the energy.
                Gup = gab(self.trial[:, :nup], self.trial[:, :nup]).T
                Gdown = gab(self.trial[:, nup:], self.trial[:, nup:]).T
                enew = local_energy(system, numpy.array([Gup, Gdown]))[0].real
                if verbose > 1:
                    print("# %d %f %f" % (it, enew, eold))
                sc = self.self_consistant(enew, eold, niup, niup_old, nidown,
                                          nidown_old, it, deps, verbose)
                if sc:
                    # Global minimum search.
                    if attempt == 0:
                        minima.append(enew)
                        psi_accept = copy.deepcopy(self.trial)
                        e_accept = numpy.append(e_up, e_down)
                    elif all(numpy.array(minima) - enew > deps):
                        minima.append(enew)
                        psi_accept = copy.deepcopy(self.trial)
                        e_accept = numpy.append(e_up, e_down)
                    break
                else:
                    mixup = self.mix_density(niup, niup_old, alpha)
                    mixdown = self.mix_density(nidown, nidown_old, alpha)
                    niup_old = niup
                    nidown_old = nidown
                    niup = mixup
                    nidown = mixdown
                    eold = enew
            if verbose > 1:
                print("# SCF cycle: {:3d}. After {:4d} steps the minimum UHF"
                      " energy found is: {: 8f}".format(attempt, it, eold))

        system.U = uold
        print("# Minimum energy found: {: 8f}".format(min(minima)))
        try:
            return (psi_accept, e_accept, min(minima), False, [niup, nidown])
        except UnboundLocalError:
            warnings.warn("Warning: No UHF wavefunction found."
                          "Delta E: %f" % (enew - emin))
            return (trial, numpy.append(e_up, e_down), None, True, None)
示例#6
0
 def __init__(self, system, cplx, trial, parallel=False, verbose=False):
     self.verbose = verbose
     if verbose:
         print("# Parsing multi-determinant trial wavefunction input"
               " options.")
     init_time = time.time()
     self.name = "multi_determinant"
     self.expansion = "multi_determinant"
     self.type = "Not GHF"
     self.eigs = numpy.array([0.0])
     if cplx:
         self.trial_type = numpy.complex128
     else:
         self.trial_type = numpy.float64
     # For debugging purposes.
     self.error = False
     self.orbital_file = trial.get('orbitals', None)
     self.coeffs_file = trial.get('coefficients', None)
     self.write = trial.get('write', False)
     if self.orbital_file is not None:
         self.ndets = trial.get('ndets', None)
         self.psi = numpy.zeros((ndets, nbasis, system.ne),
                                dtype=self.trial_type)
         self.from_ascii(system)
     elif system.orbs is not None:
         orbs = system.orbs.copy()
         self.ndets = orbs.shape[0]
         if system.frozen_core:
             nc = system.ncore
             nfv = system.nfv
             nb = system.nbasis
             orbs_core = orbs[0, :, :nc]
             orbs = orbs[:, nc:nb - nfv, :]
             Gcore, half = gab_mod(orbs_core, orbs_core)
             self.Gcore = numpy.array([Gcore, Gcore])
         self.psi = numpy.zeros(shape=(self.ndets, system.nactive,
                                       system.ne),
                                dtype=self.trial_type)
         self.psi[:, :, :system.nup] = orbs[:, :, nc:nc + system.nup].copy()
         self.psi[:, :,
                  system.nup:] = orbs[:, :, 2 * nc + system.nup:2 * nc +
                                      system.ne].copy()
         self.coeffs = system.coeffs
         self.nup = system.nup
     else:
         print("Could not construct trial wavefunction.")
         self.error = True
     nbasis = system.nbasis
     self.GAB = numpy.zeros(shape=(2, self.ndets, self.ndets,
                                   system.nactive, system.nactive),
                            dtype=self.trial_type)
     self.weights = numpy.zeros(shape=(2, self.ndets, self.ndets),
                                dtype=self.trial_type)
     # Store the complex conjugate of the multi-determinant trial
     # wavefunction expansion coefficients for ease later.
     Gup = gab(self.psi[0, :, :system.nup], self.psi[0, :, :system.nup])
     Gdn = gab(self.psi[0, :, system.nup:], self.psi[0, :, system.nup:])
     self.G = numpy.array([Gup, Gdn])
     self.initialisation_time = time.time() - init_time
     if self.write:
         self.to_qmcpack_ascii()
     if verbose:
         print("# Number of determinants in expansion: %d" % self.ndets)
         print("# Finished setting up trial wavefunction.")
示例#7
0
    def update_uhf(self, system, qmc, trial, psi, step, free_projection=False):
        """Calculate back-propagated estimates for RHF/UHF walkers.

        Parameters
        ----------
        system : system object in general.
            Container for model input options.
        qmc : :class:`pauxy.state.QMCOpts` object.
            Container for qmc input options.
        trial : :class:`pauxy.trial_wavefunction.X' object
            Trial wavefunction class.
        psi : :class:`pauxy.walkers.Walkers` object
            CPMC wavefunction.
        step : int
            Current simulation step
        free_projection : bool
            True if doing free projection.
        """
        buff_ix = psi.walkers[0].field_configs.step
        if buff_ix not in self.splits:
            return
        nup = system.nup
        for i, wnm in enumerate(psi.walkers):
            if self.init_walker:
                phi_bp = trial.init.copy()
            else:
                phi_bp = trial.psi.copy()
            # TODO: Fix for ITCF.
            self.back_propagate(phi_bp, wnm.field_configs, system, self.nstblz,
                                self.BT2, self.dt)
            self.G[0] = gab(phi_bp[:, :nup], wnm.phi_old[:, :nup]).T
            self.G[1] = gab(phi_bp[:, nup:], wnm.phi_old[:, nup:]).T

            if self.eval_energy:
                eloc = local_energy(system,
                                    self.G,
                                    opt=False,
                                    two_rdm=self.two_rdm)
                energies = numpy.array(list(eloc))
            else:
                energies = numpy.zeros(3)

            if self.calc_two_rdm is not None and self.calc_two_rdm is not "structure_factor":
                # <p^+ q^+ s r> = G(p, r, q, s) also spin-summed
                self.two_rdm =  numpy.einsum("pr,qs->prqs",self.G[0], self.G[0], optimize=True)\
                              - numpy.einsum("ps,qr->prqs",self.G[0], self.G[0], optimize=True)
                self.two_rdm += numpy.einsum("pr,qs->prqs",self.G[1], self.G[1], optimize=True)\
                              - numpy.einsum("ps,qr->prqs",self.G[1], self.G[1], optimize=True)
                self.two_rdm += numpy.einsum("pr,qs->prqs",self.G[0], self.G[1], optimize=True)\
                              + numpy.einsum("pr,qs->prqs",self.G[1], self.G[0], optimize=True)

            if self.eval_ekt:
                if (system.name == 'UEG'):
                    # there needs to be a factor of 2.0 here to account for the convention of cholesky vectors in the system class
                    chol_vecs = 2.0 * system.chol_vecs.toarray().T.reshape(
                        (system.nchol, system.nbasis, system.nbasis))
                    self.ekt_fock_1p = ekt_1p_fock_opt(system.H1[0], chol_vecs,
                                                       self.G[0], self.G[1])
                    self.ekt_fock_1h = ekt_1h_fock_opt(system.H1[0], chol_vecs,
                                                       self.G[0], self.G[1])
                else:
                    self.ekt_fock_1p = ekt_1p_fock_opt(system.H1[0],
                                                       system.chol_vecs,
                                                       self.G[0], self.G[1])
                    self.ekt_fock_1h = ekt_1h_fock_opt(system.H1[0],
                                                       system.chol_vecs,
                                                       self.G[0], self.G[1])

            if self.restore_weights is not None:
                cosine_fac, ph_fac = wnm.field_configs.get_wfac()
                if self.restore_weights == "full":
                    # BP-Pres
                    wfac = ph_fac / cosine_fac
                else:
                    # BP-PRes (partial)
                    wfac = ph_fac
                weight = wnm.weight * wfac
            else:
                # BP-PhL
                weight = wnm.weight

            self.estimates[:self.nreg] += weight * energies
            self.estimates[self.nreg] += weight

            start = self.nreg + 1
            end = start + self.G.size
            self.estimates[start:end] += weight * self.G.flatten()

            if self.calc_two_rdm is not None:
                start = end
                end = end + self.two_rdm.size
                self.estimates[start:end] += weight * self.two_rdm.flatten()

            if self.eval_ekt:
                start = end
                end = end + self.ekt_fock_1p.size
                self.estimates[start:end] += weight * self.ekt_fock_1p.flatten(
                )
                start = end
                end = end + self.ekt_fock_1h.size
                self.estimates[start:end] += weight * self.ekt_fock_1h.flatten(
                )

            if buff_ix == self.splits[-1]:
                wnm.field_configs.reset()
        if buff_ix == self.splits[-1]:
            psi.copy_historic_wfn()
        self.accumulated = True
        self.buff_ix = buff_ix