ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Wavefunction.hpp
1 #pragma once
2 #include "CI/CSF.hpp"
3 #include "HF/HartreeFock.hpp"
4 #include "MBPT/CorrelationPotential.hpp"
5 #include "Maths/Grid.hpp"
6 #include "Physics/AtomData.hpp"
7 #include "Physics/NuclearPotentials.hpp"
8 #include "Physics/PhysConst_constants.hpp"
9 #include "Physics/RadPot.hpp"
10 #include "Wavefunction/BSplineBasis.hpp"
11 #include "Wavefunction/DiracSpinor.hpp"
12 #include <iostream>
13 #include <memory>
14 #include <numeric>
15 #include <optional>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 namespace SplineBasis {
21 struct Parameters;
22 }
23 
24 //==============================================================================
36 class Wavefunction {
37 
38 public:
42  Wavefunction(std::shared_ptr<const Grid> grid,
43  const Nuclear::Nucleus &nucleus, double var_alpha = 1.0,
44  const std::string &run_label = "");
46  Wavefunction(const GridParameters &gridparams,
47  const Nuclear::Nucleus &nucleus, double var_alpha = 1.0,
48  const std::string &run_label = "");
49 
51 
52 private:
53  // Radial grid
54  std::shared_ptr<const Grid> rgrid;
55  // Internal value for alpha (alpha = var_alpha * alpha_0, alpha_0=~1/137)
56  double m_alpha;
57  std::string m_run_label;
58  // Holds nuclear parameters (isotope, charge distro etc.)
59  Nuclear::Nucleus m_nucleus;
60  // Valence (single-particle) orbitals
61  std::vector<DiracSpinor> m_valence{};
62  std::vector<DiracSpinor> m_hf_valence{};
63  // Basis, daigonalised over HF core. Used for MBPT
64  std::vector<DiracSpinor> m_basis{};
65  // Sprectrum: like basis, but includes Sigma (correlations).
66  std::vector<DiracSpinor> m_spectrum{};
67  // Nuclear potential // here AND hf?
68  std::vector<double> m_vnuc{};
69  // Hartree-Fock potential
70  std::optional<HF::HartreeFock> m_HF{std::nullopt};
71  // Correlation potential; for now unique_ptr; prefer std::optional
72  std::optional<MBPT::CorrelationPotential> m_Sigma{};
73  // Core configuration (non-rel terms)
74  std::string m_core_string = "";
75  std::string m_aboveFermi_core_string = "";
76 
77  std::vector<CI::PsiJPi> m_CIwfs{};
78 
79 public:
81  const Grid &grid() const { return *rgrid; };
84  std::shared_ptr<const Grid> grid_sptr() const { return rgrid; };
85 
87  double alpha() const { return m_alpha; }
88 
90  double dalpha2() const {
91  // (alpha/alpha_0)^2 -1
92  return (m_alpha * m_alpha / PhysConst::alpha2) - 1.0;
93  }
94 
96  const Nuclear::Nucleus &nucleus() const { return m_nucleus; }
98  int Znuc() const { return m_nucleus.z(); }
100  int Anuc() const { return m_nucleus.a(); }
102  double get_rrms() const { return m_nucleus.r_rms(); }
103 
105  const std::vector<DiracSpinor> &core() const {
106  static const auto empty = std::vector<DiracSpinor>{}; //?
107  return m_HF ? m_HF->core() : empty;
108  }
109 
111  const std::vector<DiracSpinor> &valence() const { return m_valence; }
112  std::vector<DiracSpinor> &valence() { return m_valence; }
113 
114  const std::vector<DiracSpinor> &hf_valence() const { return m_hf_valence; }
115 
118  const std::vector<DiracSpinor> &basis() const { return m_basis; }
119  std::vector<DiracSpinor> &basis() { return m_basis; }
120 
122  const std::vector<DiracSpinor> &spectrum() const { return m_spectrum; }
123  std::vector<DiracSpinor> &spectrum() { return m_spectrum; }
124 
125  const std::vector<CI::PsiJPi> &CIwfs() const { return m_CIwfs; }
126 
127  const CI::PsiJPi *CIwf(int J, int parity) const {
128  for (const auto &ci_wf : m_CIwfs) {
129  if (ci_wf.twoJ() == 2 * J && ci_wf.parity() == parity)
130  return &ci_wf;
131  }
132  return nullptr;
133  }
134 
137  const std::vector<double> &vnuc() const { return m_vnuc; }
138 
140  const HF::HartreeFock *vHF() const { return m_HF ? &*m_HF : nullptr; }
141  HF::HartreeFock *vHF() { return m_HF ? &*m_HF : nullptr; }
142 
145  std::vector<double> vlocal(int l = 0) const;
146 
149  std::vector<double> Hmag(int l = 0) const;
150 
152  const QED::RadPot *vrad() const { return m_HF ? m_HF->Vrad() : nullptr; }
153  QED::RadPot *vrad() { return m_HF ? m_HF->Vrad() : nullptr; }
154 
156  const MBPT::CorrelationPotential *Sigma() const {
157  return m_Sigma ? &*m_Sigma : nullptr;
158  }
159  MBPT::CorrelationPotential *Sigma() { return m_Sigma ? &*m_Sigma : nullptr; }
160 
161  //----------------------------------
162 
164  int Ncore() const;
165 
169  const DiracSpinor *getState(int n, int k) const;
171  const DiracSpinor *getState(std::string_view state) const;
172 
174  double FermiLevel() const;
175 
178  double energy_gap() const;
179 
181  std::string coreConfiguration() const { return m_core_string; }
182 
184  std::string coreConfiguration_nice() const {
185  return AtomData::niceCoreOutput(m_core_string);
186  }
187 
189  std::string atom() const {
190  return AtomData::atomicSymbol(m_nucleus.z()) +
191  ", Z=" + std::to_string(m_nucleus.z()) +
192  " A=" + std::to_string(m_nucleus.a());
193  }
194 
196  std::string atomicSymbol() const {
197  return AtomData::atomicSymbol(m_nucleus.z());
198  }
199 
201  std::string identity() const;
202 
204  int ion_degree(int num_val) const { return Zion() - num_val; }
205 
207  std::string ion_symbol(int num_val) const {
208  return qip::int_to_roman(Zion() - num_val + 1);
209  }
210 
212  int Zion() const { return Znuc() - Ncore(); }
213 
215  void printCore() const;
218  void printValence(const std::vector<DiracSpinor> &tmp_orbitals = {}) const;
219 
221  void printBasis(const std::vector<DiracSpinor> &the_basis) const;
222 
224  bool isInCore(int n, int k) const;
225  bool isInValence(int n, int k) const;
226 
228  std::vector<double> coreDensity() const;
229 
231  double coreEnergyHF() const;
232 
233  //------------------------------------------------------------------
234 
237  void set_HF(const std::string &method = "HartreeFock",
238  const double x_Breit = 0.0, const std::string &in_core = "",
239  double eps_HF = 1.0e-13, bool print = true);
240 
242  void solve_core(bool print = true);
243 
245  void solve_core(const std::string &method, const double x_Breit = 0.0,
246  const std::string &in_core = "", double eps_HF = 1.0e-13,
247  bool print = true);
248 
250  void solve_valence(const std::string &in_valence_str = "",
251  const bool print = true);
252 
255  void hartreeFockBrueckner(const bool print = true);
256 
258  void fitSigma_hfBrueckner(const std::string &valence_list,
259  const std::vector<double> &fit_energies);
260 
262  void radiativePotential(QED::RadPot::Scale s, double rcut, double scale_rN,
263  const std::vector<double> &x_spd,
264  bool do_readwrite = true, bool print = true);
265 
267  void radiativePotential(const IO::InputBlock &qed_input, bool do_readwrite,
268  bool print);
269 
271  void formBasis(const SplineBasis::Parameters &params);
272 
274  void formSpectrum(const SplineBasis::Parameters &params);
275 
277  void formSigma(int nmin_core = 1, int nmin_core_F = 1, double r0 = 1.0e-4,
278  double rmax = 30.0, int stride = 4, bool each_valence = false,
279  bool include_G = false, bool include_Breit = false,
280  int n_max_breit = 0, const std::vector<double> &lambdas = {},
281  const std::vector<double> &fk = {},
282  const std::vector<double> &etak = {},
283  const std::string &in_fname = "",
284  const std::string &out_fname = "", bool FeynmanQ = false,
285  bool ScreeningQ = false, bool holeParticleQ = false,
286  int lmax = 6, double omre = -0.2, double w0 = 0.01,
287  double wratio = 1.5,
288  const std::optional<IO::InputBlock> &ek = std::nullopt);
289 
290  // void correlations(const IO::InputBlock &input);
291 
292  void copySigma(const MBPT::CorrelationPotential *const Sigma) {
293  if (Sigma != nullptr)
294  m_Sigma = *Sigma;
295  }
296 
298  // _and_ HartreeFock)
299  void update_Vnuc(const std::vector<double> &v_new) {
301  m_vnuc = v_new;
302  if (m_HF) {
303  m_HF->vnuc() = v_new;
304  }
305  }
306 
313  std::tuple<double, double> lminmax_core_range(int l, double eps = 0.0) const;
314 
316  double H0ab(const DiracSpinor &Fa, const DiracSpinor &Fb) const;
318  double H0ab(const DiracSpinor &Fa, const DiracSpinor &dFa,
319  const DiracSpinor &Fb, const DiracSpinor &dFb) const;
320 
321  double Hab(const DiracSpinor &Fa, const DiracSpinor &Fb) const;
322 
323  void ConfigurationInteraction(const IO::InputBlock &input);
324 
325 private:
326  double H0ab_impl(const DiracSpinor &Fa, std::vector<double> dga,
327  const DiracSpinor &Fb, std::vector<double> dgb) const;
328 
329  // Creates set of blank core orbitals
330  std::vector<DiracSpinor> determineCore(const std::string &str_core_in);
331  bool isInAboveFermiCore(int n, int k) const;
332 };
Stores the CI Solutions for given J and parity (only two-electron).
Definition: CSF.hpp:62
Stores radial Dirac spinor: F_nk = (f, g)
Definition: DiracSpinor.hpp:41
Holds grid, including type + Jacobian (dr/du)
Definition: Grid.hpp:31
Solves relativistic Hartree-Fock equations for core and valence. Optionally includes Breit and QED ef...
Definition: HartreeFock.hpp:70
Holds list of Options, and a list of other InputBlocks. Can be initialised with a list of options,...
Definition: InputBlock.hpp:142
Stores set of nuclear parameters (all radii in fm)
Definition: NuclearPotentials.hpp:20
Class holds Flambaum-Ginges QED Radiative Potential.
Definition: RadPot.hpp:15
Stores Wavefunction (set of valence orbitals, grid, HF etc.)
Definition: Wavefunction.hpp:36
void fitSigma_hfBrueckner(const std::string &valence_list, const std::vector< double > &fit_energies)
First, fits Sigma to energies, then forms fitted Brueckner orbitals.
Definition: Wavefunction.cpp:615
void solve_valence(const std::string &in_valence_str="", const bool print=true)
Performs hartree-Fock procedure for valence: note: poplulates valnece.
Definition: Wavefunction.cpp:185
void formBasis(const SplineBasis::Parameters &params)
Calculates + populates basis [see BSplineBasis].
Definition: Wavefunction.cpp:468
void solve_core(bool print=true)
Performs hartree-Fock procedure for core.
Definition: Wavefunction.cpp:164
void printValence(const std::vector< DiracSpinor > &tmp_orbitals={}) const
Prints table of valence orbitals + energies etc.
Definition: Wavefunction.cpp:407
const std::vector< double > & vnuc() const
Nuclear potential. Only provide const version, since HF and WF version of vnuc must be kept in sync.
Definition: Wavefunction.hpp:137
std::shared_ptr< const Grid > grid_sptr() const
Copy of shared_ptr to grid [shared resource] - used when we want to construct a new object that share...
Definition: Wavefunction.hpp:84
double coreEnergyHF() const
Calculates HF core energy (doesn't include magnetic QED?)
Definition: Wavefunction.cpp:177
std::tuple< double, double > lminmax_core_range(int l, double eps=0.0) const
Returns [min,max] r values for which the core density (given l) is larger than cutoff (= eps*max_valu...
Definition: Wavefunction.cpp:349
const DiracSpinor * getState(int n, int k) const
Finds requested state; returns nullptr if not found.
Definition: Wavefunction.cpp:290
int Znuc() const
Nuclear charge, Z.
Definition: Wavefunction.hpp:98
double energy_gap() const
Energy gap between lowest valence + highest core state: e(v) - e(c) [should be positive].
Definition: Wavefunction.cpp:336
const std::vector< DiracSpinor > & spectrum() const
Sprectrum: like basis, but includes correlations.
Definition: Wavefunction.hpp:122
const std::vector< DiracSpinor > & valence() const
Valence orbitals (HF or Brueckner orbitals)
Definition: Wavefunction.hpp:111
std::string identity() const
Atomic symbol, including core ionisation degree and run_label.
Definition: Wavefunction.cpp:687
std::string coreConfiguration() const
Returns full core configuration.
Definition: Wavefunction.hpp:181
int Zion() const
Effective charge (for core) = Z-N_core.
Definition: Wavefunction.hpp:212
std::vector< double > vlocal(int l=0) const
Local part of potential, e.g., Vl = Vnuc + Vdir + Vrad_el(l) - can be l-dependent....
Definition: Wavefunction.cpp:668
std::vector< double > Hmag(int l=0) const
QED Magnetic form factor. May return empty vector. Not typically l-dependent, but may be in future....
Definition: Wavefunction.cpp:673
std::vector< double > coreDensity() const
Calculates rho(r) = sum_c psi^2(r) for core states, c={n,k,m}.
Definition: Wavefunction.cpp:456
int ion_degree(int num_val) const
0 for neutral, 1 for singly-ionised etc.
Definition: Wavefunction.hpp:204
int Anuc() const
Nuclear mass number, A.
Definition: Wavefunction.hpp:100
const Grid & grid() const
Returns a const reference to the radial grid.
Definition: Wavefunction.hpp:81
std::string atomicSymbol() const
e.g., "Cs"
Definition: Wavefunction.hpp:196
void radiativePotential(QED::RadPot::Scale s, double rcut, double scale_rN, const std::vector< double > &x_spd, bool do_readwrite=true, bool print=true)
OLD: deprecated.
Definition: Wavefunction.cpp:220
std::string ion_symbol(int num_val) const
I for neutral, II for singly-ionised etc.
Definition: Wavefunction.hpp:207
double get_rrms() const
Nuclear rms charge radii, in fm (femptometres)
Definition: Wavefunction.hpp:102
const std::vector< DiracSpinor > & basis() const
Basis, eigenstates of HF potential. Used for MBPT. Includes Breit and QED (if they are included),...
Definition: Wavefunction.hpp:118
std::string coreConfiguration_nice() const
Returns core configuration, in nice output notation.
Definition: Wavefunction.hpp:184
void formSpectrum(const SplineBasis::Parameters &params)
Calculates + populates Spectrum [see BSplineBasis].
Definition: Wavefunction.cpp:487
void formSigma(int nmin_core=1, int nmin_core_F=1, double r0=1.0e-4, double rmax=30.0, int stride=4, bool each_valence=false, bool include_G=false, bool include_Breit=false, int n_max_breit=0, const std::vector< double > &lambdas={}, const std::vector< double > &fk={}, const std::vector< double > &etak={}, const std::string &in_fname="", const std::string &out_fname="", bool FeynmanQ=false, bool ScreeningQ=false, bool holeParticleQ=false, int lmax=6, double omre=-0.2, double w0=0.01, double wratio=1.5, const std::optional< IO::InputBlock > &ek=std::nullopt)
Forms + stores correlation potential Sigma.
Definition: Wavefunction.cpp:507
const QED::RadPot * vrad() const
Pointer to QED radiative potnential. May be nullptr.
Definition: Wavefunction.hpp:152
void printCore() const
Prints table of core orbitals + energies etc.
Definition: Wavefunction.cpp:375
bool isInCore(int n, int k) const
Check if a state is in the core (or valence) list.
Definition: Wavefunction.cpp:261
std::string atom() const
String of atom info (e.g., "Cs, Z=55, A=133")
Definition: Wavefunction.hpp:189
const std::vector< DiracSpinor > & core() const
Core orbitals (frozen HF core)
Definition: Wavefunction.hpp:105
double alpha() const
Local value of fine-structure constant.
Definition: Wavefunction.hpp:87
double H0ab(const DiracSpinor &Fa, const DiracSpinor &Fb) const
Returns <a|H|b> for Hamiltonian H (inludes Rad.pot, NOT sigma, Breit, or exchange!...
Definition: Wavefunction.cpp:718
const Nuclear::Nucleus & nucleus() const
Returns Nuclear::nucleus object (contains nuc. parameters)
Definition: Wavefunction.hpp:96
void update_Vnuc(const std::vector< double > &v_new)
Allows extra potential to be added to Vnuc (updates both in Wavefunction.
Definition: Wavefunction.hpp:299
void set_HF(const std::string &method="HartreeFock", const double x_Breit=0.0, const std::string &in_core="", double eps_HF=1.0e-13, bool print=true)
Initialises HF object and populates core orbitals (does not solve HF equations)
Definition: Wavefunction.cpp:122
const MBPT::CorrelationPotential * Sigma() const
Returns ptr to (const) Correlation Potential, Sigma.
Definition: Wavefunction.hpp:156
void hartreeFockBrueckner(const bool print=true)
Forms Bruckner valence orbitals: (H_hf + Sigma)|nk> = e|nk>. Replaces existing valence states.
Definition: Wavefunction.cpp:605
int Ncore() const
Number of electrons in the core.
Definition: Wavefunction.cpp:679
double FermiLevel() const
Returns energy location of the "Fermi Level", - energy half way between core/valence....
Definition: Wavefunction.cpp:317
void printBasis(const std::vector< DiracSpinor > &the_basis) const
Prints table of Basis/Spectrum orbitals, compares to HF orbitals.
Definition: Wavefunction.cpp:433
const HF::HartreeFock * vHF() const
Returns ptr to Hartree Fock (class)
Definition: Wavefunction.hpp:140
double dalpha2() const
Variation in alpha^2 : x = (alpha/alpha_0)^2 - 1.
Definition: Wavefunction.hpp:90
std::string niceCoreOutput(const std::string &full_core)
Given a full electron config., returns nicer format by recognising nobel gas.
Definition: AtomData.cpp:198
std::string atomicSymbol(int Z)
e.g., 55 -> "Cs"
Definition: AtomData.cpp:64
Constucts of spinor/orbital basis using B-splines (DKB/Reno/Derevianko-Beloy method)
Definition: BSplineBasis.cpp:20
std::string int_to_roman(int a)
Converts integer, a, to Roman Numerals. Assumed that |a|<=4000.
Definition: String.hpp:282
Parmaters used to create Grid.
Definition: Grid.hpp:9
Scale factors for Uehling, high, low, magnetic, Wickman-Kroll.
Definition: RadPot.hpp:20