Пример #1
0
 def __init__(self, system, cplx, trial, parallel=False, verbose=False):
     if verbose:
         print("# Parsing Hartree--Fock trial wavefunction input options.")
     init_time = time.time()
     self.name = "hartree_fock"
     self.type = "hartree_fock"
     self.initial_wavefunction = trial.get('initial_wavefunction',
                                           'hartree_fock')
     self.trial_type = complex
     self.psi = numpy.zeros(shape=(system.nbasis,
                                   system.nup + system.ndown),
                            dtype=self.trial_type)
     occup = numpy.identity(system.nup)
     occdown = numpy.identity(system.ndown)
     self.psi[:system.nup, :system.nup] = occup
     self.psi[:system.ndown, system.nup:] = occdown
     gup = gab(self.psi[:, :system.nup], self.psi[:, :system.nup])
     gdown = gab(self.psi[:, system.nup:], self.psi[:, system.nup:])
     self.G = numpy.array([gup, gdown])
     (self.energy, self.e1b, self.e2b) = local_energy(system, self.G)
     self.coeffs = 1.0
     self.bp_wfn = trial.get('bp_wfn', None)
     self.error = False
     self.initialisation_time = time.time() - init_time
     if verbose:
         print("# Finished setting up trial wavefunction.")
Пример #2
0
 def __init__(self, system, cplx, trial, parallel=False, verbose=False):
     if verbose:
         print("# Constructing UHF trial wavefunction")
     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.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
Пример #3
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]))
Пример #4
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.
        """
        if step % self.nmax != 0:
            return
        psi_bp = self.back_propagate(system, psi.walkers, trial, self.nstblz,
                                     self.BT2, qmc.dt)
        nup = system.nup
        denominator = 0
        for i, (wnm, wb) in enumerate(zip(psi.walkers, psi_bp)):
            self.G[0] = gab(wb.phi[:, :nup], wnm.phi_old[:, :nup]).T
            self.G[1] = gab(wb.phi[:, nup:], wnm.phi_old[:, nup:]).T
            energies = numpy.array(list(local_energy(system, self.G)))
            if self.restore_weights is not None:
                weight = wnm.weight * self.calculate_weight_factor(wnm)
            else:
                weight = wnm.weight
            denominator += weight
            self.estimates[1:] = (
                self.estimates[1:] +
                weight * numpy.append(energies, self.G.flatten()))
        self.estimates[0] += denominator
        psi.copy_historic_wfn()
        psi.copy_bp_wfn(psi_bp)
Пример #5
0
 def __init__(self, system, cplx, trial, parallel=False, verbose=False):
     if verbose:
         print ("# Parsing free electron input options.")
     init_time = time.time()
     self.name = "free_electron"
     self.type = "free_electron"
     self.initial_wavefunction = trial.get('initial_wavefunction',
                                           'free_electron')
     if verbose:
         print ("# Diagonalising one-body Hamiltonian.")
     (self.eigs_up, self.eigv_up) = diagonalise_sorted(system.T[0])
     (self.eigs_dn, self.eigv_dn) = diagonalise_sorted(system.T[1])
     self.reference = trial.get('reference', None)
     if cplx:
         self.trial_type = complex
     else:
         self.trial_type = float
     self.read_in = trial.get('read_in', None)
     self.psi = numpy.zeros(shape=(system.nbasis, system.nup+system.ndown),
                            dtype=self.trial_type)
     if self.read_in is not None:
         if verbose:
             print ("# Reading trial wavefunction from %s"%(self.read_in))
         try:
             self.psi = numpy.load(self.read_in)
             self.psi = self.psi.astype(self.trial_type)
         except OSError:
             if verbose:
                 print("# Trial wavefunction is not in native numpy form.")
                 print("# Assuming Fortran GHF format.")
             orbitals = read_fortran_complex_numbers(self.read_in)
             tmp = orbitals.reshape((2*system.nbasis, system.ne),
                                    order='F')
             ups = []
             downs = []
             # deal with potential inconsistency in ghf format...
             for (i, c) in enumerate(tmp.T):
                 if all(abs(c[:system.nbasis]) > 1e-10):
                     ups.append(i)
                 else:
                     downs.append(i)
             self.psi[:, :system.nup] = tmp[:system.nbasis, ups]
             self.psi[:, system.nup:] = tmp[system.nbasis:, downs]
     else:
         # I think this is slightly cleaner than using two separate
         # matrices.
         if self.reference is not None:
             self.psi[:, :system.nup] = self.eigv_up[:, self.reference]
             self.psi[:, system.nup:] = self.eigv_dn[:, self.reference]
         else:
             self.psi[:, :system.nup] = self.eigv_up[:, :system.nup]
             self.psi[:, system.nup:] = self.eigv_dn[:, :system.ndown]
     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
     # For interface compatability
     self.coeffs = 1.0
     self.ndets = 1
     self.bp_wfn = trial.get('bp_wfn', None)
     self.error = False
     self.eigs = numpy.append(self.eigs_up, self.eigs_dn)
     self.eigs.sort()
     self.initialisation_time = time.time() - init_time
     if verbose:
         print ("# Finished initialising free electron trial wavefunction.")
Пример #6
0
    def find_uhf_wfn(self,
                     system,
                     cplx,
                     ueff,
                     ninit,
                     nit_max,
                     alpha,
                     deps=1e-8,
                     verbose=False):
        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:
                    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
            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)