Self-consistent reaction-field engine — owns the cavity, the COSMO/CPCM pre-factored response, and (optionally) the SMD CDS cavity.
More...
|
| | ReactionFieldEngine (Options opts={}) |
| void | initialize (const Mat3N &atom_positions_bohr, const IVec &atomic_numbers) |
| | Build the cavity, pre-factor the COSMO A matrix, and (if include_cds) pre-evaluate the CDS branch.
|
| void | solve_asc (const Vec &phi_at_cavity, std::optional< double > total_solute_charge=std::nullopt) |
| | Eulerian: solve A σ = −f(ε)·φ_cavity.
|
| void | update_from_atom_charges (const Vec &atom_charges) |
| | Atom-resolved: from input atomic charges, compute φ = B·q, σ = G·q, V_atom = J_solv·q, E_es = ½ q·V_atom.
|
| void | update_from_atom_multipoles (const Vec &atom_charges, const Mat3N &dipoles, const Mat &quadrupoles) |
| | Atom-resolved including the anisotropic part of the solute density.
|
| void | set_multipole_damping (const Vec &rco_bohr, double kdmp3, double kdmp5) |
| | Short-range damping for the atom→cavity dipole and quadrupole kernels (see detail::MultipoleDamping).
|
| double | energy () const |
| | Total cached solvation energy: E_es + E_cds.
|
| double | energy_es () const |
| double | energy_cds () const |
| const Vec & | atom_potential () const |
| | Cached per-atom screening potential V_atom (Hartree, length = natom).
|
| const Mat3N & | dipole_potential () const |
| | Conjugates of the atomic dipoles (3 × natom) and quadrupoles (6 × natom, in the input layout) at the last update.
|
| const Mat & | quadrupole_potential () const |
| const Vec & | damping_radius_gradient () const |
| | ∂E_es/∂R_co per atom at the last update (empty when the kernels are undamped).
|
| const Vec & | surface_charges () const |
| | Cached apparent surface charges σ on the ES cavity.
|
| SolvationSurfaces | surfaces () const |
| | Per-element decomposition of the latest update.
|
| Mat3N | gradient () const |
| | Frozen-cavity analytical gradient (Hartree/Bohr, 3 × natom).
|
| Mat | solve_cavity (const Mat &b) const |
| | A⁻¹ b with the pre-factored COSMO matrix (b is ncav x ncol).
|
| Mat3N | es_gradient (const Vec &sigma, const Vec &atom_charges) const |
| | Explicit nuclear derivative (3 x N) of E_es = ½ σ·φ = −(f/2) φᵀA⁻¹φ for the given σ, when φ is the potential of the atom-centred charges atom_charges (the nuclei, say): σᵀ ∂φ/∂x + (1/2f) σᵀ (∂A/∂x) σ, cavity points moving with their atoms.
|
| EsDerivatives | es_derivatives (const Vec &sigma, const Vec &atom_charges) const |
| Mat3N | cds_gradient () const |
| | Analytic nuclear gradient of the CDS energy (3 x N; zero without CDS).
|
| Mat | cds_hessian () const |
| | CDS Hessian (3N x 3N), central differences of the analytic gradient: the term depends on the geometry alone, so this costs 6N cavity builds and no electronic structure.
|
| const occ::solvent::surface::Surface & | es_cavity () const |
| const occ::solvent::surface::Surface & | cds_cavity () const |
| size_t | num_es_surface_points () const |
| size_t | num_cds_surface_points () const |
| const Mat & | B () const |
| const Mat & | G () const |
| const Mat & | J_solv () const |
| double | dielectric () const |
| double | f_epsilon () const |
| const Options & | options () const |
| const occ::solvent::SMDSolventParameters & | smd_parameters () const |
| const Vec & | es_atom_radii () const |
| | ES cavity radii (Bohr) used at initialize(). Empty before initialize().
|
| const Vec & | cds_energy_elements () const |
| | Per-element CDS energy (Hartree).
|
Self-consistent reaction-field engine — owns the cavity, the COSMO/CPCM pre-factored response, and (optionally) the SMD CDS cavity.
Provides both an atom-resolved API (q → V_atom, used by xTB) and an Eulerian API (φ at cavity → σ, used by HF/DFT).
Lifecycle:
- construct with Options,
- initialize(atoms, Z) to build the cavity and factor A,
- per-iteration: update_from_atom_charges(q) OR solve_asc(phi),
- energy(), surfaces(), gradient() reflect the latest update.
gradient() is the frozen-cavity analytical gradient (plus CDS when include_cds). It requires an atom-resolved update (it goes through the SCC's Mulliken charges); calling it after a pure Eulerian solve returns an empty matrix.
| Mat3N occ::scrf::ReactionFieldEngine::es_gradient |
( |
const Vec & | sigma, |
|
|
const Vec & | atom_charges ) const |
Explicit nuclear derivative (3 x N) of E_es = ½ σ·φ = −(f/2) φᵀA⁻¹φ for the given σ, when φ is the potential of the atom-centred charges atom_charges (the nuclei, say): σᵀ ∂φ/∂x + (1/2f) σᵀ (∂A/∂x) σ, cavity points moving with their atoms.
A caller whose φ has another source as well (an electron density) adds σᵀ ∂φ_source/∂x itself. Stationary in σ, so σ need only be the self-consistent one.
| Mat3N occ::scrf::ReactionFieldEngine::gradient |
( |
| ) |
const |
Frozen-cavity analytical gradient (Hartree/Bohr, 3 × natom).
Requires a prior atom-resolved update — returns a zero matrix otherwise. When include_cds, adds the CDS gradient on top.
This is the explicit derivative at frozen moments. After update_from_atom_multipoles the dipoles and quadrupoles are included in the source field, but their own response to the geometry (∂μ/∂R, ∂Θ/∂R) belongs to the caller's density-Pulay chain, exactly as it does for the charges.
| void occ::scrf::ReactionFieldEngine::solve_asc |
( |
const Vec & | phi_at_cavity, |
|
|
std::optional< double > | total_solute_charge = std::nullopt ) |
Eulerian: solve A σ = −f(ε)·φ_cavity.
Caches σ and φ so energy_es() / surfaces() reflect the result. Does NOT compute V_atom — use the atom-resolved path for that.
With total_solute_charge set, the solve is constrained to Σσ = −f(ε)·q, which for a conductor is exact by Gauss's law. The unconstrained solve falls short by the charge lying outside the cavity. Enforced with a Lagrange multiplier on the existing factorisation:
σ = σ_free − λ A⁻¹1, λ = (1ᵀσ_free − σ_target) / (1ᵀA⁻¹1)
This restores the sum rule but does not redistribute σ; the shape error needs the Klamt–Jonas double-cavity correction, which is not implemented.
| void occ::scrf::ReactionFieldEngine::update_from_atom_multipoles |
( |
const Vec & | atom_charges, |
|
|
const Mat3N & | dipoles, |
|
|
const Mat & | quadrupoles ) |
Atom-resolved including the anisotropic part of the solute density.
The cavity potential comes from the atom-centred multipole expansion
φ_i = Σ_A [ q_A/d + μ_A·d/d³ + Σ_αβ Θ^A_αβ d_α d_β/d⁵ ], d = r_i − R_A
so that a solute with no net atomic charges — benzene, say — still polarises the continuum through its quadrupoles. Caches the conjugate of every moment, each being that moment's own kernel contracted with σ:
V_atom = ∂E_es/∂q, V_dipole = ∂E_es/∂μ, V_quad = ∂E_es/∂Θ
dipoles is 3 × natom. quadrupoles is 6 × natom, traceless, ordered (xx, xy, yy, xz, yz, zz) with the off-diagonal components entering φ twice — the layout and normalisation of occ::xtb::CammMoments::qp, so the potentials come back conjugate to the stored components directly.
Costs one LU solve per call: the pre-solved response G only covers the charge column, and widening it to the dipoles and quadrupoles would make it nine times larger for no saving on the systems this is used for.