ampsci
High-precision calculations for one- and two-valence atomic systems
BSplineBasis.hpp
1#pragma once
2#include "IO/InputBlock.hpp"
3#include "LinAlg/include.hpp"
4#include <memory>
5#include <string>
6#include <utility>
7class DiracSpinor;
8class Wavefunction;
9class Grid;
10namespace MBPT {
11class CorrelationPotential;
12}
13namespace IO {
14class InputBlock;
15}
16
17/*!
18@brief Constucts of spinor/orbital basis using B-splines
19(DKB/Reno/Derevianko-Beloy method)
20
21@details
22Uses Maths/Bsplines to forma set of B-spline orbitals (using method from [1]
23"Derevianko", or [2] "Johnson"). Diagonalises B-splines over Hamiltonian to
24produce a set of basis orbitals.
25 * [1] K. Beloy, A. Derevianko, Comput. Phys. Commun. 179, 310 (2008).
26 * [2] W. Johnson, S. Blundell, J. Sapirstein, Phys. Rev. A 37, 307 (1988).
27 * See also: Bachau et al., Reports Prog. Phys. 64, 1815 (2001).
28
29If \f$\{|i\rangle\}\f$ are the set of \f$2N\f$ DKB spline orbitals (of a given
30angular symmetry), and
31\f[ H_{ij} = \langle{S_i}|\hat H_{\rm HF}|{S_j}\rangle \,
32, \qquad S_{ij} = \langle{S_i|S_j}\rangle. \f]
33The eigenvalue problem:
34\f[
35H_{ij}p_i = \epsilon S_{ij}p_i,
36\f]
37is solved, yielding \f$2N\f$ eigenvalues \f$\epsilon\f$ with corresponding
38eigenvectors \f$p\f$ (half of these are positive energy solutions, half are
39negative energy solutions).
40
41Note: form_basis() does not store the eigenvectors, instead, it expands the
42basis orbitals and stores them on the regular grid (coordinate space).
43i.e., for each eigenvalue, n, the corresponding basis orbital is:
44\f[
45|{n}\rangle = \sum_i^{2N} p_i |i\rangle\,
46\f]
47*/
48namespace SplineBasis {
49
50enum class SplineType { Derevianko, Johnson };
51inline auto parseSplineType(std::string_view type) {
52 return (type == "Johnson" || type == "johnson") ? SplineType::Johnson :
53 SplineType::Derevianko;
54}
55
56struct Parameters {
57 Parameters() {}
58 Parameters(const std::string &states, std::size_t n, std::size_t k, double r0,
59 double reps, double rmax, const std::string &positron = "",
60 SplineType itype = SplineType::Derevianko,
61 bool in_orthogonalise = false, bool in_verbose = true);
62 Parameters(IO::InputBlock input);
63
64 std::string states{};
65 std::size_t n{}, k{};
66 double r0{}, reps{}, rmax{};
67 std::string positron{};
68 SplineType type{SplineType::Derevianko};
69 bool orthogonalise{false};
70 bool verbose{true};
71};
72
73//! @brief Forms + returns the basis orbitals (expanded in terms of splines)
74/*! @details
75 - states_str = which states to keep e.g., "25spd10f" (up to n=25 for
76 s,p,d-states, and up to n=10 for f states)
77 - n_spl: Number of splines (nb: underlying spline set is larger, see [1])
78 - k_spl: k order of the B-splines. NB: must have \f$k\geq l_{\rm max}+3\f$ [1]
79 - r0_spl: first internal knot
80 - r0_eps: sets r0_spl as r where relative core density larger than
81 r0_eps (updates r0 for each l). Typically ~1.0e-8. Set to zero to use r0_spl.
82 - rmax_spl: last internal knot (basis orbitals only non-zero before this
83 point)
84 - wf: Wavefunction object: needed to form Hartree-Fock Hamiltonian
85 - positronQ: =true will keep negative energy states (have -ve principal
86 quantum number, are appended to end of the basis std::vector). If false,
87 discards them.
88
89Note: This function calls the below functions, they rarely need to be called
90explicitely, unless you are trying to do something different to usual.
91*/
92std::vector<DiracSpinor> form_basis(const Parameters &params,
93 const Wavefunction &wf,
94 const bool correlationsQ = false);
95
96double check(const std::vector<DiracSpinor> &basis,
97 const std::vector<DiracSpinor> &orbs, bool print_warning = true);
98
99//! Forms the underlying spline basis (which is not kept)
100std::pair<std::vector<DiracSpinor>, std::vector<DiracSpinor>> form_spline_basis(
101 const int kappa, const std::size_t n_states, const std::size_t k_spl,
102 const double r0_spl, const double rmax_spl, std::shared_ptr<const Grid> rgrid,
103 const double alpha, SplineType itype = SplineType::Derevianko);
104
105//! Calculates + reyurns the Hamiltonian \f$H_{ij}\f$ (and \f$S_{ij}\f$)
106//! matrices
107std::pair<LinAlg::Matrix<double>, LinAlg::Matrix<double>>
108fill_Hamiltonian_matrix(const std::vector<DiracSpinor> &spl_basis,
109 const std::vector<DiracSpinor> &d_basis,
110 const Wavefunction &wf,
111 const bool correlationsQ = false,
112 SplineType itype = SplineType::Derevianko);
113
114void add_NotreDameBoundary(LinAlg::Matrix<double> *Aij, const int kappa,
115 const double alpha);
116
117//! @brief Expands basis orbitals in terms of spline orbitals, by
118//! diagonalising Hamiltonian
119void expand_basis_orbitals(std::vector<DiracSpinor> *basis,
120 std::vector<DiracSpinor> *basis_positron,
121 const std::vector<DiracSpinor> &spl_basis,
122 const int kappa, const int max_n, int max_n_positron,
123 const LinAlg::Vector<double> &e_values,
124 const LinAlg::Matrix<double> &e_vectors,
125 const Wavefunction &wf);
126
127//! TKR sum rule (basis test); should =0 (must include -ve energy states)
128std::vector<double> sumrule_TKR(const std::vector<DiracSpinor> &basis,
129 const std::vector<double> &r,
130 bool print = false);
131
132//! Drake-Gordon sum rule (basis test); should =0 (must incl -ve energy states)
133std::vector<double> sumrule_DG(int nDG, const std::vector<DiracSpinor> &basis,
134 const Grid &gr, double alpha, bool print);
135
136std::pair<double, double> r_completeness(const DiracSpinor &Fv,
137 const std::vector<DiracSpinor> &basis,
138 const Grid &gr, bool print = false);
139} // namespace SplineBasis
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:41
Holds grid, including type + Jacobian (dr/du)
Definition Grid.hpp:31
Holds list of Options, and a list of other InputBlocks. Can be initialised with a list of options,...
Definition InputBlock.hpp:142
Matrix class; row-major.
Definition Matrix.hpp:35
Vector class (inherits from Matrix)
Definition Vector.hpp:9
Stores Wavefunction (set of valence orbitals, grid, HF etc.)
Definition Wavefunction.hpp:37
In-out (timers, profilers, and read/write data)
Definition ChronoTimer.hpp:9
Many-body perturbation theory.
Definition CI_Integrals.hpp:9
Constucts of spinor/orbital basis using B-splines (DKB/Reno/Derevianko-Beloy method)
Definition BSplineBasis.cpp:20
std::vector< double > sumrule_DG(int nDG, const std::vector< DiracSpinor > &basis, const Grid &gr, double alpha, bool print)
Drake-Gordon sum rule (basis test); should =0 (must incl -ve energy states)
Definition BSplineBasis.cpp:450
std::pair< std::vector< DiracSpinor >, std::vector< DiracSpinor > > form_spline_basis(const int kappa, const std::size_t n_states, const std::size_t k_spl, const double r0_spl, const double rmax_spl, std::shared_ptr< const Grid > rgrid, const double alpha, SplineType type)
Forms the underlying spline basis (which is not kept)
Definition BSplineBasis.cpp:194
std::pair< LinAlg::Matrix< double >, LinAlg::Matrix< double > > fill_Hamiltonian_matrix(const std::vector< DiracSpinor > &spl_basis, const std::vector< DiracSpinor > &d_basis, const Wavefunction &wf, const bool correlationsQ, SplineType type)
Calculates + reyurns the Hamiltonian (and ) matrices.
Definition BSplineBasis.cpp:266
std::vector< double > sumrule_TKR(const std::vector< DiracSpinor > &basis, const std::vector< double > &r, bool print)
TKR sum rule (basis test); should =0 (must include -ve energy states)
Definition BSplineBasis.cpp:414
std::vector< DiracSpinor > form_basis(const Parameters &params, const Wavefunction &wf, const bool correlationsQ)
Forms + returns the basis orbitals (expanded in terms of splines)
Definition BSplineBasis.cpp:51
void expand_basis_orbitals(std::vector< DiracSpinor > *basis, std::vector< DiracSpinor > *basis_positron, const std::vector< DiracSpinor > &spl_basis, const int kappa, const int max_n, int max_n_positron, const LinAlg::Vector< double > &e_values, const LinAlg::Matrix< double > &e_vectors, const Wavefunction &wf)
Expands basis orbitals in terms of spline orbitals, by diagonalising Hamiltonian.
Definition BSplineBasis.cpp:340