Base classes for ebcc.cc.

ebcc.cc.base.T = float64 module-attribute

Defines the type for the eris argument in functions.

ebcc.cc.base.ERIsInputType = Any module-attribute

Defines the type for arrays, including spin labels.

ebcc.cc.base.SpinArrayType = Any module-attribute

Defines the type for the spaces, including spin labels.

ebcc.cc.base.BaseOptions(e_tol=1e-08, t_tol=1e-08, max_iter=200, diis_space=9, diis_min_space=1, damping=0.0, shift=True) dataclass

Bases: _BaseOptions

Options for EBCC calculations.

Parameters:
  • e_tol (float, default: 1e-08 ) –

    Threshold for convergence in the correlation energy.

  • t_tol (float, default: 1e-08 ) –

    Threshold for convergence in the amplitude norm.

  • max_iter (int, default: 200 ) –

    Maximum number of iterations.

  • diis_space (int, default: 9 ) –

    Number of amplitudes to use in DIIS extrapolation.

  • diis_min_space (int, default: 1 ) –

    Minimum number of amplitudes to use in DIIS extrapolation.

  • damping (float, default: 0.0 ) –

    Damping factor for DIIS extrapolation.

  • shift (bool, default: True ) –

    Shift the boson operators such that the Hamiltonian is normal-ordered with respect to a coherent state. This removes the bosonic coupling to the static mean-field density, introducing a constant energy shift.

ebcc.cc.base.BaseEBCC(mf, log=None, ansatz='CCSD', options=None, space=None, omega=None, g=None, G=None, mo_coeff=None, mo_occ=None, fock=None, **kwargs)

Bases: ABC

Base class for electron-boson coupled cluster.

Initialise the EBCC object.

Parameters:
  • mf (SCF) –

    PySCF mean-field object.

  • log (Optional[Logger], default: None ) –

    Log to write output to. Default is the global logger, outputting to stderr.

  • ansatz (Optional[Union[Ansatz, str]], default: 'CCSD' ) –

    Overall ansatz.

  • options (Optional[BaseOptions], default: None ) –

    Options for the EBCC calculation.

  • space (Optional[SpaceType], default: None ) –

    Space containing the frozen, correlated, and active fermionic spaces. Default assumes all electrons are correlated.

  • omega (Optional[NDArray[T]], default: None ) –

    Bosonic frequencies.

  • g (Optional[NDArray[T]], default: None ) –

    Electron-boson coupling matrix corresponding to the bosonic annihilation operator :math:g_{bpq} p^\dagger q b. The creation part is assumed to be the fermionic conjugate transpose to retain Hermiticity in the Hamiltonian.

  • G (Optional[NDArray[T]], default: None ) –

    Boson non-conserving term :math:G_{b} (b^\dagger + b).

  • mo_coeff (Optional[NDArray[T]], default: None ) –

    Molecular orbital coefficients. Default is the mean-field coefficients.

  • mo_occ (Optional[NDArray[T]], default: None ) –

    Molecular orbital occupation numbers. Default is the mean-field occupation.

  • fock (Optional[BaseFock], default: None ) –

    Fock matrix. Default is the mean-field Fock matrix.

  • **kwargs (Any, default: {} ) –

    Additional keyword arguments used to update options.

Source code in ebcc/cc/base.py
def __init__(
    self,
    mf: SCF,
    log: Optional[Logger] = None,
    ansatz: Optional[Union[Ansatz, str]] = "CCSD",
    options: Optional[BaseOptions] = None,
    space: Optional[SpaceType] = None,
    omega: Optional[NDArray[T]] = None,
    g: Optional[NDArray[T]] = None,
    G: Optional[NDArray[T]] = None,
    mo_coeff: Optional[NDArray[T]] = None,
    mo_occ: Optional[NDArray[T]] = None,
    fock: Optional[BaseFock] = None,
    **kwargs: Any,
) -> None:
    r"""Initialise the EBCC object.

    Args:
        mf: PySCF mean-field object.
        log: Log to write output to. Default is the global logger, outputting to `stderr`.
        ansatz: Overall ansatz.
        options: Options for the EBCC calculation.
        space: Space containing the frozen, correlated, and active fermionic spaces. Default
            assumes all electrons are correlated.
        omega: Bosonic frequencies.
        g: Electron-boson coupling matrix corresponding to the bosonic annihilation operator
            :math:`g_{bpq} p^\dagger q b`. The creation part is assumed to be the fermionic
            conjugate transpose to retain Hermiticity in the Hamiltonian.
        G: Boson non-conserving term :math:`G_{b} (b^\dagger + b)`.
        mo_coeff: Molecular orbital coefficients. Default is the mean-field coefficients.
        mo_occ: Molecular orbital occupation numbers. Default is the mean-field occupation.
        fock: Fock matrix. Default is the mean-field Fock matrix.
        **kwargs: Additional keyword arguments used to update `options`.
    """
    # Options:
    if options is None:
        options = self.Options()
    self.options = options
    for key, val in kwargs.items():
        setattr(self.options, key, val)

    # Parameters:
    self.log = default_log if log is None else log
    self.mf = self._convert_mf(mf)
    self._mo_coeff: Optional[NDArray[T]] = (
        np.asarray(mo_coeff, dtype=types[float]) if mo_coeff is not None else None
    )
    self._mo_occ: Optional[NDArray[T]] = (
        np.asarray(mo_occ, dtype=types[float]) if mo_occ is not None else None
    )

    # Ansatz:
    if isinstance(ansatz, Ansatz):
        self.ansatz = ansatz
    elif isinstance(ansatz, str):
        self.ansatz = Ansatz.from_string(
            ansatz, density_fitting=getattr(self.mf, "with_df", None) is not None
        )
    else:
        raise TypeError("ansatz must be an Ansatz object or a string.")
    self._eqns = self.ansatz._get_eqns(self.spin_type)

    # Space:
    if space is not None:
        self.space = space
    else:
        self.space = self.init_space()

    # Boson parameters:
    if bool(self.fermion_coupling_rank) != bool(self.boson_coupling_rank):
        raise ValueError(
            "Fermionic and bosonic coupling ranks must both be zero, or both non-zero."
        )
    self.omega = np.asarray(omega, dtype=types[float]) if omega is not None else None
    self.bare_g = np.asarray(g, dtype=types[float]) if g is not None else None
    self.bare_G = np.asarray(G, dtype=types[float]) if G is not None else None
    if self.boson_ansatz != "":
        self.g = self.get_g()
        self.G = self.get_mean_field_G()
    else:
        assert self.nbos == 0
        self.options.shift = False
        self.g = None
        self.G = None

    # Fock matrix:
    if fock is None:
        self.fock = self.get_fock()
    else:
        self.fock = fock

    # Attributes:
    self.e_corr = 0.0
    self.amplitudes = util.Namespace()
    self.converged = False
    self.lambdas = util.Namespace()
    self.converged_lambda = False

    # Logging:
    init_logging(self.log)
    self.log.info(f"\n{ANSI.B}{ANSI.U}{self.name}{ANSI.R}")
    self.log.debug(f"{ANSI.B}{'*' * len(self.name)}{ANSI.R}")
    self.log.debug("")
    self.log.info(f"{ANSI.B}Options{ANSI.R}:")
    self.log.info(f" > e_tol:  {ANSI.y}{self.options.e_tol}{ANSI.R}")
    self.log.info(f" > t_tol:  {ANSI.y}{self.options.t_tol}{ANSI.R}")
    self.log.info(f" > max_iter:  {ANSI.y}{self.options.max_iter}{ANSI.R}")
    self.log.info(f" > diis_space:  {ANSI.y}{self.options.diis_space}{ANSI.R}")
    self.log.info(f" > diis_min_space:  {ANSI.y}{self.options.diis_min_space}{ANSI.R}")
    self.log.info(f" > damping:  {ANSI.y}{self.options.damping}{ANSI.R}")
    self.log.debug("")
    self.log.info(f"{ANSI.B}Ansatz{ANSI.R}: {ANSI.m}{self.ansatz}{ANSI.R}")
    self.log.debug("")
    self.log.info(f"{ANSI.B}Space{ANSI.R}: {ANSI.m}{self.space}{ANSI.R}")
    self.log.debug("")
    if self.boson_ansatz != "":
        self.log.info(f"{ANSI.B}Bosons{ANSI.R}: {ANSI.m}{self.nbos}{ANSI.R}")
        self.log.info(" > Energy shift due to polaritonic basis:  %.10f", self.const)
        self.log.debug("")

ebcc.cc.base.BaseEBCC.spin_type: str abstractmethod property

Get a string representation of the spin type.

ebcc.cc.base.BaseEBCC.name: str property

Get the name of the method.

ebcc.cc.base.BaseEBCC.fermion_ansatz: str property

Get a string representation of the fermion ansatz.

ebcc.cc.base.BaseEBCC.boson_ansatz: str property

Get a string representation of the boson ansatz.

ebcc.cc.base.BaseEBCC.fermion_coupling_rank: int property

Get an integer representation of the fermion coupling rank.

ebcc.cc.base.BaseEBCC.boson_coupling_rank: int property

Get an integer representation of the boson coupling rank.

ebcc.cc.base.BaseEBCC.xi: NDArray[T] abstractmethod property

Get the shift in the bosonic operators to diagonalise the photon Hamiltonian.

Returns:
  • NDArray[T]

    Shift in the bosonic operators.

ebcc.cc.base.BaseEBCC.const: float property

Get the shift in energy from moving to the polaritonic basis.

Returns:
  • float

    Constant energy shift due to the polaritonic basis.

ebcc.cc.base.BaseEBCC.mo_coeff: NDArray[T] property

Get the molecular orbital coefficients.

Returns:
  • NDArray[T]

    Molecular orbital coefficients.

ebcc.cc.base.BaseEBCC.mo_occ: NDArray[T] property

Get the molecular orbital occupation numbers.

Returns:
  • NDArray[T]

    Molecular orbital occupation numbers.

ebcc.cc.base.BaseEBCC.nmo: Any abstractmethod property

Get the number of molecular orbitals.

Returns:
  • Any

    Number of molecular orbitals.

ebcc.cc.base.BaseEBCC.nocc: Any abstractmethod property

Get the number of occupied molecular orbitals.

Returns:
  • Any

    Number of occupied molecular orbitals.

ebcc.cc.base.BaseEBCC.nvir: Any abstractmethod property

Get the number of virtual molecular orbitals.

Returns:
  • Any

    Number of virtual molecular orbitals.

ebcc.cc.base.BaseEBCC.nbos: int property

Get the number of bosonic modes.

Returns:
  • int

    Number of bosonic modes.

ebcc.cc.base.BaseEBCC.e_tot: float property

Get the total energy (mean-field plus correlation).

Returns:
  • float

    Total energy.

ebcc.cc.base.BaseEBCC.t1: Any property

Get the T1 amplitudes.

ebcc.cc.base.BaseEBCC.t2: Any property

Get the T2 amplitudes.

ebcc.cc.base.BaseEBCC.t3: Any property

Get the T3 amplitudes.

ebcc.cc.base.BaseEBCC.l1: Any property

Get the L1 amplitudes.

ebcc.cc.base.BaseEBCC.l2: Any property

Get the L2 amplitudes.

ebcc.cc.base.BaseEBCC.l3: Any property

Get the L3 amplitudes.

ebcc.cc.base.BaseEBCC.kernel(eris=None)

Run the coupled cluster calculation.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def kernel(self, eris: Optional[ERIsInputType] = None) -> float:
    """Run the coupled cluster calculation.

    Args:
        eris: Electron repulsion integrals.

    Returns:
        Correlation energy.
    """
    timer = util.Timer()

    # Get the ERIs:
    eris = self.get_eris(eris)

    # Get the amplitude guesses:
    amplitudes = self.amplitudes
    if not amplitudes:
        amplitudes = self.init_amps(eris=eris)

    # Get the initial energy:
    e_cc = self.energy(amplitudes=amplitudes, eris=eris)

    self.log.output("Solving for excitation amplitudes.")
    self.log.debug("")
    self.log.info(
        f"{ANSI.B}{'Iter':>4s} {'Energy (corr.)':>16s} {'Energy (tot.)':>18s} "
        f"{'Δ(Energy)':>13s} {'Δ(Ampl.)':>13s}{ANSI.R}"
    )
    self.log.info("%4d %16.10f %18.10f", 0, e_cc, e_cc + self.mf.e_tot)

    if not self.ansatz.is_one_shot:
        # Set up damping:
        damping = self.Damping(options=self.options)

        converged = False
        for niter in range(1, self.options.max_iter + 1):
            # Update the amplitudes, extrapolate with DIIS and calculate change:
            amplitudes_prev = amplitudes
            amplitudes = self.update_amps(amplitudes=amplitudes, eris=eris)
            vector = self.amplitudes_to_vector(amplitudes)
            vector = damping(vector)
            amplitudes = self.vector_to_amplitudes(vector)
            dt = np.linalg.norm(
                np.abs(vector - self.amplitudes_to_vector(amplitudes_prev)), ord=np.inf
            )

            # Update the energy and calculate change:
            e_prev = e_cc
            e_cc = self.energy(amplitudes=amplitudes, eris=eris)
            de = abs(e_prev - e_cc)

            # Log the iteration:
            converged_e = bool(de < self.options.e_tol)
            converged_t = bool(dt < self.options.t_tol)
            self.log.info(
                f"%4d %16.10f %18.10f {[ANSI.r, ANSI.g][int(converged_e)]}%13.3e{ANSI.R}"
                f" {[ANSI.r, ANSI.g][int(converged_t)]}%13.3e{ANSI.R}",
                niter,
                e_cc,
                e_cc + self.mf.e_tot,
                de,
                dt,
            )

            # Check for convergence:
            converged = converged_e and converged_t
            if converged:
                self.log.debug("")
                self.log.output(f"{ANSI.g}Converged.{ANSI.R}")
                break
        else:
            self.log.debug("")
            self.log.warning(f"{ANSI.r}Failed to converge.{ANSI.R}")

        # Include perturbative correction if required:
        if self.ansatz.has_perturbative_correction:
            self.log.debug("")
            self.log.info("Computing perturbative energy correction.")
            e_pert = self.energy_perturbative(amplitudes=amplitudes, eris=eris)
            e_cc += e_pert
            self.log.info("E(pert) = %.10f", e_pert)

    else:
        converged = True

    # Update attributes:
    self.e_corr = e_cc
    self.amplitudes = amplitudes
    self.converged = converged

    self.log.debug("")
    self.log.output("E(corr) = %.10f", self.e_corr)
    self.log.output("E(tot)  = %.10f", self.e_corr + self.mf.e_tot)
    self.log.debug("")
    self.log.debug("Time elapsed: %s", timer.format_time(timer()))
    self.log.debug("")

    return e_cc

ebcc.cc.base.BaseEBCC.solve_lambda(amplitudes=None, eris=None)

Solve for the lambda amplitudes.

Parameters:
Source code in ebcc/cc/base.py
def solve_lambda(
    self,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    eris: Optional[ERIsInputType] = None,
) -> None:
    """Solve for the lambda amplitudes.

    Args:
        amplitudes: Cluster amplitudes.
        eris: Electron repulsion integrals.
    """
    timer = util.Timer()

    # Get the ERIs:
    eris = self.get_eris(eris)

    # Get the amplitudes:
    amplitudes = self.amplitudes
    if not amplitudes:
        amplitudes = self.init_amps(eris=eris)

    # If needed, get the perturbative part of the lambda amplitudes:
    lambdas_pert = None
    if self.ansatz.has_perturbative_correction:
        lambdas_pert = self.update_lams(eris=eris, amplitudes=amplitudes, perturbative=True)

    # Get the initial lambda amplitudes:
    lambdas = self.lambdas
    if not lambdas:
        lambdas = self.init_lams(amplitudes=amplitudes)

    self.log.output("Solving for de-excitation (lambda) amplitudes.")
    self.log.debug("")
    self.log.info(f"{ANSI.B}{'Iter':>4s} {'Δ(Ampl.)':>13s}{ANSI.R}")

    # Set up damping:
    damping = self.Damping(options=self.options)

    converged = False
    for niter in range(1, self.options.max_iter + 1):
        # Update the lambda amplitudes, extrapolate with DIIS and calculate change:
        lambdas_prev = lambdas
        lambdas = self.update_lams(
            amplitudes=amplitudes,
            lambdas=lambdas,
            lambdas_pert=lambdas_pert,
            eris=eris,
        )
        vector = self.lambdas_to_vector(lambdas)
        vector = damping(vector)
        lambdas = self.vector_to_lambdas(vector)
        dl = np.linalg.norm(np.abs(vector - self.lambdas_to_vector(lambdas_prev)), ord=np.inf)

        # Log the iteration:
        converged = bool(dl < self.options.t_tol)
        self.log.info(f"%4d {[ANSI.r, ANSI.g][int(converged)]}%13.3e{ANSI.R}", niter, dl)

        # Check for convergence:
        if converged:
            self.log.debug("")
            self.log.output(f"{ANSI.g}Converged.{ANSI.R}")
            break
    else:
        self.log.debug("")
        self.log.warning(f"{ANSI.r}Failed to converge.{ANSI.R}")

    self.log.debug("")
    self.log.debug("Time elapsed: %s", timer.format_time(timer()))
    self.log.debug("")
    self.log.debug("")

    # Update attributes:
    self.lambdas = lambdas
    self.converged_lambda = converged

ebcc.cc.base.BaseEBCC.ip_eom(**kwargs) abstractmethod

Get the IP-EOM object.

Parameters:
  • **kwargs (Any, default: {} ) –

    Additional keyword arguments.

Returns:
  • Any

    IP-EOM object.

Source code in ebcc/cc/base.py
@abstractmethod
def ip_eom(self, **kwargs: Any) -> Any:
    """Get the IP-EOM object.

    Args:
        **kwargs: Additional keyword arguments.

    Returns:
        IP-EOM object.
    """
    pass

ebcc.cc.base.BaseEBCC.ea_eom(**kwargs) abstractmethod

Get the EA-EOM object.

Parameters:
  • **kwargs (Any, default: {} ) –

    Additional keyword arguments.

Returns:
  • Any

    EA-EOM object.

Source code in ebcc/cc/base.py
@abstractmethod
def ea_eom(self, **kwargs: Any) -> Any:
    """Get the EA-EOM object.

    Args:
        **kwargs: Additional keyword arguments.

    Returns:
        EA-EOM object.
    """
    pass

ebcc.cc.base.BaseEBCC.ee_eom(**kwargs) abstractmethod

Get the EE-EOM object.

Parameters:
  • **kwargs (Any, default: {} ) –

    Additional keyword arguments.

Returns:
  • Any

    EE-EOM object.

Source code in ebcc/cc/base.py
@abstractmethod
def ee_eom(self, **kwargs: Any) -> Any:
    """Get the EE-EOM object.

    Args:
        **kwargs: Additional keyword arguments.

    Returns:
        EE-EOM object.
    """
    pass

ebcc.cc.base.BaseEBCC.brueckner(*args, **kwargs)

Run a Brueckner orbital coupled cluster calculation.

The coupled cluster object will be update in-place.

Parameters:
  • *args (Any, default: () ) –

    Arguments to pass to the Brueckner object.

  • **kwargs (Any, default: {} ) –

    Keyword arguments to pass to the Brueckner object.

Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def brueckner(self, *args: Any, **kwargs: Any) -> float:
    """Run a Brueckner orbital coupled cluster calculation.

    The coupled cluster object will be update in-place.

    Args:
        *args: Arguments to pass to the Brueckner object.
        **kwargs: Keyword arguments to pass to the Brueckner object.

    Returns:
        Correlation energy.
    """
    bcc = self.Brueckner(self, *args, **kwargs)
    return bcc.kernel()

ebcc.cc.base.BaseEBCC.write(file)

Write the EBCC object to a file.

Parameters:
  • file (str) –

    File to write the object to.

Source code in ebcc/cc/base.py
def write(self, file: str) -> None:
    """Write the EBCC object to a file.

    Args:
        file: File to write the object to.
    """
    writer = Dump(file)
    writer.write(self)

ebcc.cc.base.BaseEBCC.read(file, log=None) classmethod

Read the EBCC object from a file.

Parameters:
  • file (str) –

    File to read the object from.

  • log (Optional[Logger], default: None ) –

    Logger to use for new object.

Returns:
Source code in ebcc/cc/base.py
@classmethod
def read(cls, file: str, log: Optional[Logger] = None) -> BaseEBCC:
    """Read the EBCC object from a file.

    Args:
        file: File to read the object from.
        log: Logger to use for new object.

    Returns:
        EBCC object.
    """
    reader = Dump(file)
    return reader.read(cls=cls, log=log)

ebcc.cc.base.BaseEBCC.init_amps(eris=None) abstractmethod

Initialise the cluster amplitudes.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def init_amps(self, eris: Optional[ERIsInputType] = None) -> Namespace[SpinArrayType]:
    """Initialise the cluster amplitudes.

    Args:
        eris: Electron repulsion integrals.

    Returns:
        Initial cluster amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.init_lams(amplitudes=None) abstractmethod

Initialise the cluster lambda amplitudes.

Parameters:
Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def init_lams(
    self, amplitudes: Optional[Namespace[SpinArrayType]] = None
) -> Namespace[SpinArrayType]:
    """Initialise the cluster lambda amplitudes.

    Args:
        amplitudes: Cluster amplitudes.

    Returns:
        Initial cluster lambda amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.energy(eris=None, amplitudes=None)

Calculate the correlation energy.

Parameters:
Returns:
  • float

    Correlation energy.

Source code in ebcc/cc/base.py
def energy(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
) -> float:
    """Calculate the correlation energy.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.

    Returns:
        Correlation energy.
    """
    func, kwargs = self._load_function(
        "energy",
        eris=eris,
        amplitudes=amplitudes,
    )
    res: float = ensure_scalar(func(**kwargs)).real
    return astype(res, float)

ebcc.cc.base.BaseEBCC.energy_perturbative(eris=None, amplitudes=None, lambdas=None)

Calculate the perturbative correction to the correlation energy.

Parameters:
Returns:
  • float

    Perturbative energy correction.

Source code in ebcc/cc/base.py
def energy_perturbative(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
) -> float:
    """Calculate the perturbative correction to the correlation energy.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.

    Returns:
        Perturbative energy correction.
    """
    func, kwargs = self._load_function(
        "energy_perturbative",
        eris=eris,
        amplitudes=amplitudes,
        lambdas=lambdas,
    )
    res: float = ensure_scalar(func(**kwargs)).real
    return res

ebcc.cc.base.BaseEBCC.update_amps(eris=None, amplitudes=None) abstractmethod

Update the cluster amplitudes.

Parameters:
Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def update_amps(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
) -> Namespace[SpinArrayType]:
    """Update the cluster amplitudes.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.

    Returns:
        Updated cluster amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.update_lams(eris=None, amplitudes=None, lambdas=None, lambdas_pert=None, perturbative=False) abstractmethod

Update the cluster lambda amplitudes.

Parameters:
  • eris (ERIsInputType, default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • lambdas_pert (Optional[Namespace[SpinArrayType]], default: None ) –

    Perturbative cluster lambda amplitudes.

  • perturbative (bool, default: False ) –

    Flag to include perturbative correction.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def update_lams(
    self,
    eris: ERIsInputType = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    lambdas_pert: Optional[Namespace[SpinArrayType]] = None,
    perturbative: bool = False,
) -> Namespace[SpinArrayType]:
    """Update the cluster lambda amplitudes.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        lambdas_pert: Perturbative cluster lambda amplitudes.
        perturbative: Flag to include perturbative correction.

    Returns:
        Updated cluster lambda amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.make_sing_b_dm(eris=None, amplitudes=None, lambdas=None)

Make the single boson density matrix :math:\langle b \rangle.

Parameters:
Returns:
  • NDArray[T]

    Single boson density matrix.

Source code in ebcc/cc/base.py
def make_sing_b_dm(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
) -> NDArray[T]:
    r"""Make the single boson density matrix :math:`\langle b \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.

    Returns:
        Single boson density matrix.
    """
    func, kwargs = self._load_function(
        "make_sing_b_dm",
        eris=eris,
        amplitudes=amplitudes,
        lambdas=lambdas,
    )
    res: NDArray[T] = func(**kwargs)
    return res

ebcc.cc.base.BaseEBCC.make_rdm1_b(eris=None, amplitudes=None, lambdas=None, unshifted=True, hermitise=True)

Make the one-particle boson reduced density matrix :math:\langle b^+ c \rangle.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • unshifted (bool, default: True ) –

    If self.options.shift is True, return the unshifted density matrix. Has no effect if self.options.shift is False.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • NDArray[T]

    One-particle boson reduced density matrix.

Source code in ebcc/cc/base.py
def make_rdm1_b(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    unshifted: bool = True,
    hermitise: bool = True,
) -> NDArray[T]:
    r"""Make the one-particle boson reduced density matrix :math:`\langle b^+ c \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        unshifted: If `self.options.shift` is `True`, return the unshifted density matrix. Has
            no effect if `self.options.shift` is `False`.
        hermitise: Hermitise the density matrix.

    Returns:
        One-particle boson reduced density matrix.
    """
    func, kwargs = self._load_function(
        "make_rdm1_b",
        eris=eris,
        amplitudes=amplitudes,
        lambdas=lambdas,
    )
    dm: NDArray[T] = func(**kwargs)

    if hermitise:
        dm = (dm + np.transpose(dm)) * 0.5

    if unshifted and self.options.shift:
        xi = self.xi
        dm_b = util.einsum("ni->i", self.make_sing_b_dm())
        dm -= util.einsum("ij,i->ij", np.eye(dm.shape[0]), xi * dm_b - xi**2.0)

    return dm

ebcc.cc.base.BaseEBCC.make_rdm1_f(eris=None, amplitudes=None, lambdas=None, hermitise=True) abstractmethod

Make the one-particle fermionic reduced density matrix :math:\langle i^+ j \rangle.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • Any

    One-particle fermion reduced density matrix.

Source code in ebcc/cc/base.py
@abstractmethod
def make_rdm1_f(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    hermitise: bool = True,
) -> Any:
    r"""Make the one-particle fermionic reduced density matrix :math:`\langle i^+ j \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        hermitise: Hermitise the density matrix.

    Returns:
        One-particle fermion reduced density matrix.
    """
    pass

ebcc.cc.base.BaseEBCC.make_rdm2_f(eris=None, amplitudes=None, lambdas=None, hermitise=True) abstractmethod

Make the two-particle fermionic reduced density matrix :math:\langle i^+j^+lk \rangle.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • Any

    Two-particle fermion reduced density matrix.

Source code in ebcc/cc/base.py
@abstractmethod
def make_rdm2_f(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    hermitise: bool = True,
) -> Any:
    r"""Make the two-particle fermionic reduced density matrix :math:`\langle i^+j^+lk \rangle`.

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        hermitise: Hermitise the density matrix.

    Returns:
        Two-particle fermion reduced density matrix.
    """
    pass

ebcc.cc.base.BaseEBCC.make_eb_coup_rdm(eris=None, amplitudes=None, lambdas=None, unshifted=True, hermitise=True) abstractmethod

Make the electron-boson coupling reduced density matrix.

.. math:: \langle b^+ i^+ j \rangle

and

.. math:: \langle b i^+ j \rangle

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Electron repulsion integrals.

  • amplitudes (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster amplitudes.

  • lambdas (Optional[Namespace[SpinArrayType]], default: None ) –

    Cluster lambda amplitudes.

  • unshifted (bool, default: True ) –

    If self.options.shift is True, return the unshifted density matrix. Has no effect if self.options.shift is False.

  • hermitise (bool, default: True ) –

    Hermitise the density matrix.

Returns:
  • Any

    Electron-boson coupling reduced density matrix.

Source code in ebcc/cc/base.py
@abstractmethod
def make_eb_coup_rdm(
    self,
    eris: Optional[ERIsInputType] = None,
    amplitudes: Optional[Namespace[SpinArrayType]] = None,
    lambdas: Optional[Namespace[SpinArrayType]] = None,
    unshifted: bool = True,
    hermitise: bool = True,
) -> Any:
    r"""Make the electron-boson coupling reduced density matrix.

    .. math::
        \langle b^+ i^+ j \rangle

    and

    .. math::
        \langle b i^+ j \rangle

    Args:
        eris: Electron repulsion integrals.
        amplitudes: Cluster amplitudes.
        lambdas: Cluster lambda amplitudes.
        unshifted: If `self.options.shift` is `True`, return the unshifted density matrix. Has
            no effect if `self.options.shift` is `False`.
        hermitise: Hermitise the density matrix.

    Returns:
        Electron-boson coupling reduced density matrix.
    """
    pass

ebcc.cc.base.BaseEBCC.energy_sum(*args, signs_dict=None) abstractmethod

Get a direct sum of energies.

Parameters:
  • *args (str, default: () ) –

    Energies to sum. Subclass should specify a subscript, and optionally spins.

  • signs_dict (Optional[dict[str, str]], default: None ) –

    Signs of the energies in the sum. Default sets ("o", "O", "i") to be positive, and ("v", "V", "a", "b") to be negative.

Returns:
  • NDArray[T]

    Sum of energies.

Source code in ebcc/cc/base.py
@abstractmethod
def energy_sum(self, *args: str, signs_dict: Optional[dict[str, str]] = None) -> NDArray[T]:
    """Get a direct sum of energies.

    Args:
        *args: Energies to sum. Subclass should specify a subscript, and optionally spins.
        signs_dict: Signs of the energies in the sum. Default sets `("o", "O", "i")` to be
            positive, and `("v", "V", "a", "b")` to be negative.

    Returns:
        Sum of energies.
    """
    pass

ebcc.cc.base.BaseEBCC.amplitudes_to_vector(amplitudes) abstractmethod

Construct a vector containing all of the amplitudes used in the given ansatz.

Parameters:
Returns:
  • NDArray[T]

    Cluster amplitudes as a vector.

Source code in ebcc/cc/base.py
@abstractmethod
def amplitudes_to_vector(self, amplitudes: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the amplitudes used in the given ansatz.

    Args:
        amplitudes: Cluster amplitudes.

    Returns:
        Cluster amplitudes as a vector.
    """
    pass

ebcc.cc.base.BaseEBCC.vector_to_amplitudes(vector) abstractmethod

Construct a namespace of amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    Cluster amplitudes as a vector.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def vector_to_amplitudes(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of amplitudes from a vector.

    Args:
        vector: Cluster amplitudes as a vector.

    Returns:
        Cluster amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.lambdas_to_vector(lambdas) abstractmethod

Construct a vector containing all of the lambda amplitudes used in the given ansatz.

Parameters:
Returns:
  • NDArray[T]

    Cluster lambda amplitudes as a vector.

Source code in ebcc/cc/base.py
@abstractmethod
def lambdas_to_vector(self, lambdas: Namespace[SpinArrayType]) -> NDArray[T]:
    """Construct a vector containing all of the lambda amplitudes used in the given ansatz.

    Args:
        lambdas: Cluster lambda amplitudes.

    Returns:
        Cluster lambda amplitudes as a vector.
    """
    pass

ebcc.cc.base.BaseEBCC.vector_to_lambdas(vector) abstractmethod

Construct a namespace of lambda amplitudes from a vector.

Parameters:
  • vector (NDArray[T]) –

    Cluster lambda amplitudes as a vector.

Returns:
Source code in ebcc/cc/base.py
@abstractmethod
def vector_to_lambdas(self, vector: NDArray[T]) -> Namespace[SpinArrayType]:
    """Construct a namespace of lambda amplitudes from a vector.

    Args:
        vector: Cluster lambda amplitudes as a vector.

    Returns:
        Cluster lambda amplitudes.
    """
    pass

ebcc.cc.base.BaseEBCC.init_space() abstractmethod

Initialise the fermionic space.

Returns:
  • SpaceType

    Fermionic space. All fermionic degrees of freedom are assumed to be correlated.

Source code in ebcc/cc/base.py
@abstractmethod
def init_space(self) -> SpaceType:
    """Initialise the fermionic space.

    Returns:
        Fermionic space. All fermionic degrees of freedom are assumed to be correlated.
    """
    pass

ebcc.cc.base.BaseEBCC.get_fock()

Get the Fock matrix.

Returns:
Source code in ebcc/cc/base.py
def get_fock(self) -> BaseFock:
    """Get the Fock matrix.

    Returns:
        Fock matrix.
    """
    return self.Fock(
        self.mf,
        space=(self.space, self.space),
        mo_coeff=(self.mo_coeff, self.mo_coeff),
        g=self.g,
        shift=self.options.shift,
        xi=self.xi if self.boson_ansatz else None,
    )

ebcc.cc.base.BaseEBCC.get_eris(eris=None)

Get the electron repulsion integrals.

Parameters:
  • eris (Optional[ERIsInputType], default: None ) –

    Input electron repulsion integrals.

Returns:
  • BaseERIs

    Electron repulsion integrals.

Source code in ebcc/cc/base.py
def get_eris(self, eris: Optional[ERIsInputType] = None) -> BaseERIs:
    """Get the electron repulsion integrals.

    Args:
        eris: Input electron repulsion integrals.

    Returns:
        Electron repulsion integrals.
    """
    use_df = getattr(self.mf, "with_df", None) is not None
    if isinstance(eris, BaseERIs):
        return eris
    elif eris is not None:
        raise TypeError(f"`eris` must be an `BaseERIs` object, got {eris.__class__.__name__}.")
    elif use_df:
        return self.CDERIs(
            self.mf,
            space=(self.space, self.space, self.space, self.space),
            mo_coeff=(self.mo_coeff, self.mo_coeff, self.mo_coeff, self.mo_coeff),
        )
    else:
        return self.ERIs(
            self.mf,
            space=(self.space, self.space, self.space, self.space),
            mo_coeff=(self.mo_coeff, self.mo_coeff, self.mo_coeff, self.mo_coeff),
        )

ebcc.cc.base.BaseEBCC.get_g()

Get the blocks of the electron-boson coupling matrix.

This matrix corresponds to the bosonic annihilation operator.

Returns:
Source code in ebcc/cc/base.py
def get_g(self) -> BaseElectronBoson:
    """Get the blocks of the electron-boson coupling matrix.

    This matrix corresponds to the bosonic annihilation operator.

    Returns:
        Electron-boson coupling matrix.
    """
    if self.bare_g is None:
        raise ValueError("Bare electron-boson coupling matrix not provided.")
    return self.ElectronBoson(
        self.mf,
        self.bare_g,
        (self.space, self.space),
        (self.mo_coeff, self.mo_coeff),
    )

ebcc.cc.base.BaseEBCC.get_mean_field_G() abstractmethod

Get the mean-field boson non-conserving term.

Returns:
  • Any

    Mean-field boson non-conserving term.

Source code in ebcc/cc/base.py
@abstractmethod
def get_mean_field_G(self) -> Any:
    """Get the mean-field boson non-conserving term.

    Returns:
        Mean-field boson non-conserving term.
    """
    pass