High-precision calculations for one- and two-valence atomic systems
Wavefunction.hpp
1#pragma once
2#include "CI/CI_Integrals.hpp"
3#include "CI/CSF.hpp"
4#include "HF/HartreeFock.hpp"
5#include "MBPT/CorrelationPotential.hpp"
6#include "Maths/Grid.hpp"
7#include "Physics/AtomData.hpp"
8#include "Physics/PhysConst_constants.hpp"
9#include "Potentials/NuclearPotentials.hpp"
10#include "Potentials/RadPot.hpp"
11#include "Wavefunction/BSplineBasis.hpp"
12#include "Wavefunction/DiracSpinor.hpp"
13#include "json/json.hpp"
14#include <iostream>
15#include <memory>
16#include <numeric>
17#include <optional>
18#include <string>
19#include <utility>
20#include <vector>
21
22namespace SplineBasis {
23struct Parameters;
24}
25
26//==============================================================================
27/*!
28 @brief Stores Wavefunction (set of valence orbitals, grid, HF etc.)
29
30 @details
31 Also holds the Hartree-Fock potential (and core), basis, spectrum,
32 correlation potential (Sigma), and CI solutions.
33
34 \par Construction:
35 - Set of GridParameters [see Maths/Grid]
36 - Nuclear::Nucleus [see Potentials/NuclearPotentials]
37 - var_alpha = \f$\lambda\f$, \f$\alpha = \lambda\alpha_0\f$
38 - run_label: Optional label for output identity - for distinguishing
39 outputs with different parameters
40
41 \par Copying:
42 A copy has its own HF object (and core), but its Sigma (if formed) still
43 refers to the HF object of the original (see copySigma). Applying Sigma
44 does not use the HF object, but forming or writing Sigma does: these then
45 use the original core (e.g., without any changes to the copy's HF), and the
46 original must outlive the copy.
47*/
49
50public:
51 /*!
52 @brief Construct with a Grid [shared resource] and a nucleus.
53
54 @details
55 Nucleus: isotope data etc. Optional fractional variation in alpha:
56 alpha = var_alpha * alpha_0, alpha_0 =~ 1/137. Forms the nuclear
57 potential; orbitals are formed later (see set_HF, solve_core).
58
59 @param grid Radial grid (shared resource)
60 @param nucleus Nuclear parameters (isotope, charge distribution)
61 @param var_alpha Ratio alpha/alpha_0
62 @param run_label Optional label for output identity (see identity)
63 */
64 Wavefunction(std::shared_ptr<const Grid> grid,
65 const Nuclear::Nucleus &nucleus, double var_alpha = 1.0,
66 const std::string &run_label = "");
67 //! As above, but Grid is constructed here using given parameters
68 Wavefunction(const GridParameters &gridparams,
69 const Nuclear::Nucleus &nucleus, double var_alpha = 1.0,
70 const std::string &run_label = "");
71
72 //! Default grid and nucleus (see GridParameters, Nuclear::Nucleus)
74
75private:
76 // Radial grid
77 std::shared_ptr<const Grid> rgrid;
78 // Internal value for alpha (alpha = var_alpha * alpha_0, alpha_0=~1/137)
79 double m_alpha;
80 std::string m_run_label;
81 // Holds nuclear parameters (isotope, charge distro etc.)
82 Nuclear::Nucleus m_nucleus;
83 // Valence (single-particle) orbitals
84 std::vector<DiracSpinor> m_valence{};
85 std::vector<DiracSpinor> m_hf_valence{};
86 // Basis, daigonalised over HF core. Used for MBPT
87 std::vector<DiracSpinor> m_basis{};
88 // Sprectrum: like basis, but includes Sigma (correlations).
89 std::vector<DiracSpinor> m_spectrum{};
90 // Nuclear potential // here AND hf?
91 std::vector<double> m_vnuc{};
92 // Hartree-Fock potential
93 std::optional<HF::HartreeFock> m_HF{std::nullopt};
94 // Correlation potential; for now unique_ptr; prefer std::optional
95 std::optional<MBPT::CorrelationPotential> m_Sigma{};
96 // Core configuration (non-rel terms)
97 std::string m_core_string = "";
98 std::string m_aboveFermi_core_string = "";
99
100 // CI solutions, and the integrals used to construct the CI Hamiltonians
101 CI::Solutions m_CI{};
102
103public:
104 //! Returns a const reference to the radial grid
105 const Grid &grid() const { return *rgrid; };
106 /*!
107 @brief Copy of shared_ptr to grid [shared resource].
108
109 @details
110 Used when we want to construct a new object that shares this grid.
111 */
112 std::shared_ptr<const Grid> grid_sptr() const { return rgrid; };
113
114 //! Local value of fine-structure constant.
115 double alpha() const { return m_alpha; }
116
117 //! Variation in alpha^2 : x = (alpha/alpha_0)^2 - 1
118 double dalpha2() const {
119 // (alpha/alpha_0)^2 -1
120 return (m_alpha * m_alpha / PhysConst::alpha2) - 1.0;
121 }
122
123 //! Returns Nuclear::nucleus object (contains nuc. parameters)
124 const Nuclear::Nucleus &nucleus() const { return m_nucleus; }
125 //! Nuclear charge, Z
126 int Znuc() const { return m_nucleus.z(); }
127 //! Nuclear mass number, A
128 int Anuc() const { return m_nucleus.a(); }
129 //! Nuclear rms charge radius, in fm (femtometres)
130 double get_rrms() const { return m_nucleus.r_rms(); }
131
132 //! Core orbitals (frozen HF core); empty if HF not set
133 const std::vector<DiracSpinor> &core() const {
134 static const auto empty = std::vector<DiracSpinor>{}; //?
135 return m_HF ? m_HF->core() : empty;
136 }
137
138 //! Valence orbitals (HF or Brueckner orbitals)
139 const std::vector<DiracSpinor> &valence() const { return m_valence; }
140 std::vector<DiracSpinor> &valence() { return m_valence; }
141
142 //! HF valence orbitals: copy of valence, as last solved by solve_valence
143 const std::vector<DiracSpinor> &hf_valence() const { return m_hf_valence; }
144
145 /*!
146 @brief Basis, eigenstates of HF potential. Used for MBPT.
147
148 @details
149 Includes Breit and QED (if they are included), but not correlations.
150 */
151 const std::vector<DiracSpinor> &basis() const { return m_basis; }
152 std::vector<DiracSpinor> &basis() { return m_basis; }
153
154 //! Spectrum: like basis, but includes correlations
155 const std::vector<DiracSpinor> &spectrum() const { return m_spectrum; }
156 std::vector<DiracSpinor> &spectrum() { return m_spectrum; }
157
158 //! CI solutions, one for each {J, parity}; empty unless CI was run
159 const std::vector<CI::PsiJPi> &CIwfs() const { return m_CI.levels; }
160
161 /*!
162 @brief CI solutions for given J and parity; nullptr if not found.
163
164 @details
165 @p J is integer (CI is for two-electron systems); @p parity is +1 or -1.
166 */
167 const CI::PsiJPi *CIwf(int J, int parity) const {
168 for (const auto &ci_wf : m_CI.levels) {
169 if (ci_wf.twoJ() == 2 * J && ci_wf.parity() == parity)
170 return &ci_wf;
171 }
172 return nullptr;
173 }
174
175 /*!
176 @brief Integral tables used to construct the CI Hamiltonians.
177
178 @details
179 Empty unless CI was run; see CI::Integrals.
180 */
181 const CI::Integrals &CI_integrals() const { return m_CI.integrals; }
182
183 /*!
184 @brief Nuclear potential.
185
186 @details
187 Only provide const version, since HF and WF version of vnuc must be kept
188 in sync (see update_Vnuc).
189 */
190 const std::vector<double> &vnuc() const { return m_vnuc; }
191
192 //! Returns ptr to Hartree Fock (class); nullptr if not set
193 const HF::HartreeFock *vHF() const { return m_HF ? &*m_HF : nullptr; }
194 HF::HartreeFock *vHF() { return m_HF ? &*m_HF : nullptr; }
195
196 /*!
197 @brief Local part of potential, e.g., Vl = Vnuc + Vdir + Vrad_el(l).
198
199 @details
200 Can be l-dependent. Returns a copy. Just Vnuc if HF is not set.
201 */
202 std::vector<double> vlocal(int l = 0) const;
203
204 /*!
205 @brief QED Magnetic form factor.
206
207 @details
208 May return empty vector (no QED, or HF not set). Not typically
209 l-dependent, but may be in future. Returns a copy.
210 */
211 std::vector<double> Hmag(int l = 0) const;
212
213 //! Pointer to QED radiative potential. May be nullptr
214 const QED::RadPot *vrad() const { return m_HF ? m_HF->Vrad() : nullptr; }
215 QED::RadPot *vrad() { return m_HF ? m_HF->Vrad() : nullptr; }
216
217 //! Returns ptr to (const) Correlation Potential, Sigma; nullptr if none
219 return m_Sigma ? &*m_Sigma : nullptr;
220 }
221 MBPT::CorrelationPotential *Sigma() { return m_Sigma ? &*m_Sigma : nullptr; }
222
223 //----------------------------------
224
225 //! Number of electrons in the core
226 int Ncore() const;
227
228 /*!
229 @brief Finds requested state (n, kappa); returns nullptr if not found.
230
231 @details
232 Searches valence first, then core.
233 */
234 const DiracSpinor *getState(int n, int k) const;
235 //! As above, but takes 'short symbol' (e.g., 6s+, 6p-)
236 const DiracSpinor *getState(std::string_view state) const;
237
238 /*!
239 @brief Returns energy location of the "Fermi Level".
240
241 @details
242 Energy half way between core/valence. Defined:
243 0.5*( max(e_core) + min(e_valence)), plus a small offset (1e-5; or 1e-3
244 if there are no valence states, in which case min(e_valence) is taken as
245 zero). If there is no core: 1.1*min(e_valence). Should be -ve.
246 */
247 double FermiLevel() const;
248
249 /*!
250 @brief Energy gap between lowest valence + highest core state.
251
252 @details
253 e(v) - e(c) [should be positive]. Zero if there are no core or no valence
254 states.
255 */
256 double energy_gap() const;
257
258 //! Returns full core configuration
259 std::string coreConfiguration() const { return m_core_string; }
260
261 //! Returns core configuration, in nice output notation
262 std::string coreConfiguration_nice() const {
263 return AtomData::niceCoreOutput(m_core_string);
264 }
265
266 //! String of atom info (e.g., "Cs, Z=55 A=133")
267 std::string atom() const {
268 return AtomData::atomicSymbol(m_nucleus.z()) +
269 ", Z=" + std::to_string(m_nucleus.z()) +
270 " A=" + std::to_string(m_nucleus.a());
271 }
272
273 //! e.g., "Cs"
274 std::string atomicSymbol() const {
275 return AtomData::atomicSymbol(m_nucleus.z());
276 }
277
278 /*!
279 @brief Atomic symbol, including core ionisation degree and run_label.
280
281 @details
282 Used as the base name for output and cache files (Sigma, Qk, CI, etc.).
283 Form: symbol + Zion + Breit/QED flag ("b", "q", or "bq") + alpha
284 variation ("_x", with x = (alpha/alpha_0)^2 to 6 significant figures, if
285 |dalpha2()| > 1e-5) + "_run_label" (if not empty). E.g., "Cs1",
286 "Cs1bq_label", "Cs1_1.01".
287 */
288 std::string identity() const;
289
290 //! Optional label for output identity (see identity)
291 const std::string &run_label() const { return m_run_label; };
292
293 //! 0 for neutral, 1 for singly-ionised etc. (num_val: valence electrons)
294 int ion_degree(int num_val) const { return Zion() - num_val; }
295
296 //! I for neutral, II for singly-ionised etc. (num_val: valence electrons)
297 std::string ion_symbol(int num_val) const {
298 return qip::int_to_roman(Zion() - num_val + 1);
299 }
300
301 //! Effective charge (for core) = Z-N_core
302 int Zion() const { return Znuc() - Ncore(); }
303
304 //! Prints table of core orbitals + energies etc.
305 void printCore() const;
306 /*!
307 @brief Prints table of valence orbitals + energies etc.
308
309 @details
310 Can optionally give it any list of orbitals to print (default: valence).
311 */
312 void printValence(const std::vector<DiracSpinor> &tmp_orbitals = {}) const;
313
314 //! Prints table of Basis/Spectrum orbitals, compares to HF orbitals
315 void printBasis(const std::vector<DiracSpinor> &the_basis) const;
316
317 //! Check if a state (n, kappa) is in the core list
318 bool isInCore(int n, int k) const;
319 //! Check if a state (n, kappa) is in the valence list
320 bool isInValence(int n, int k) const;
321
322 //! Calculates rho(r) = sum_c psi^2(r) for core states, c={n,k,m}
323 std::vector<double> coreDensity() const;
324
325 /*!
326 @brief Calculates HF core energy.
327
328 @details
329 Sum of core orbital energies (weighted by occupation), minus the
330 double-counted Coulomb (direct + exchange) and Breit (if included)
331 interactions. QED (if included in the core) enters through the orbital
332 energies. Zero if HF is not set.
333 */
334 double coreEnergyHF() const;
335
336 //------------------------------------------------------------------
337
338 /*!
339 @brief Initialises HF object and populates core orbitals.
340
341 @details
342 Does not solve HF equations (see solve_core). Replaces any existing HF
343 object, including any radiative potential (QED is added later; see
344 radiativePotential).
345
346 @param method Mean-field method (HartreeFock, Hartree, KohnSham..)
347 @param in_core Core configuration, "[X],nLm,nLm,...", e.g., "[Xe]"
348 or "[Xe],6s1". A ':' may replace one of the commas:
349 shells after it are in the core, but may also be
350 valence states (see solve_valence)
351 @param breit_params Breit parameters (nullopt: no Breit). HartreeFock
352 method only: ignored (with a warning) otherwise
353 @param eps_HF HF convergence goal (if >= 1, taken as the exponent:
354 10^-eps_HF)
355 @param print Print method details
356
357 @warning Aborts if the core configuration is invalid, or has more than Z
358 electrons.
359 */
360 void set_HF(HF::Method method = HF::Method::HartreeFock,
361 const std::string &in_core = "",
362 std::optional<HF::Breit::Params> breit_params = std::nullopt,
363 double eps_HF = 1.0e-14, bool print = true);
364
365 //! Performs Hartree-Fock procedure for core (nothing if HF not set)
366 void solve_core(bool print = true);
367
368 //! This version will first set_HF(), then solve_core()
369 void solve_core(HF::Method method, const std::string &in_core = "",
370 std::optional<HF::Breit::Params> breit_params = std::nullopt,
371 double eps_HF = 1.0e-14, bool print = true);
372 //! @overload
373 void solve_core(const std::string &method, const std::string &in_core = "",
374 std::optional<HF::Breit::Params> breit_params = std::nullopt,
375 double eps_HF = 1.0e-14, bool print = true);
376
377 /*!
378 @brief Performs Hartree-Fock procedure for valence; populates valence.
379
380 @details
381 Adds the states in @p in_valence_str (basis-string format, e.g., "7sp5d":
382 up to n=7 for s and p, n=5 for d) that are not already in valence, and
383 not in the core (except those after the ':' in the core string; see
384 set_HF). Then solves for all valence states (existing ones are re-solved)
385 in the HF potential, without Sigma, and copies them to hf_valence. If HF
386 is not set, solves in the nuclear potential (H-like).
387 */
388 void solve_valence(const std::string &in_valence_str = "",
389 const bool print = true);
390
391 /*!
392 @brief Solves for exotic atoms (e.g., muonic), including screening.
393
394 @details
395 Resulting states are included in valence (flagged as exotic); the
396 screening also updates core.
397
398 Each state is first solved in the nuclear (+QED) potential. With
399 @p screening (and a non-empty core), the core HF equations are iterated
400 including the direct potential of the first exotic state; the HF object
401 (core) is then replaced by the screened one (Vnuc itself unchanged), and
402 the exotic states are re-solved in the screened potential.
403
404 Note: The exotic states are just added to the valence list, so they can
405 be used more simply with all the modules. However, be careful; for
406 example, RPA will now be meaningless for these states!
407
408 @param in_exotic_str States, in basis-string format (e.g., "1s2p")
409 @param mass Mass of the exotic particle, in units of m_e
410 @param screening Include screening (core and exotic states)
411 @param print Print energies and screening iterations
412
413 @note With @p screening, any (electron) valence states already present
414 are not re-solved, so are no longer consistent with the screened
415 core.
416 */
417 void solve_exotic(const std::string &in_exotic_str,
418 double mass = PhysConst::m_muon, bool screening = true,
419 bool print = true);
420
421 /*!
422 @brief Forms Brueckner valence orbitals; replaces existing valence states.
423
424 @details
425 \f$ (H_{\rm HF} + \Sigma)\ket{nk} = \varepsilon\ket{nk} \f$.
426 Does nothing if Sigma has not been formed; prints a warning and does
427 nothing if HF is not set.
428
429 @note Sigma is only formed for the HartreeFock method (see formSigma).
430 */
431 void hartreeFockBrueckner(const bool print = true);
432
433 /*!
434 @brief First, fits Sigma to energies, then forms fitted Brueckner orbitals.
435
436 @details
437 For each of the first fit_energies.size() valence states (in order),
438 finds the scaling factor lambda such that the Brueckner energy, with
439 lambda*Sigma, matches the given energy (damped iteration; lambda kept
440 within [0.25, 2.5]). By default, fitted lambdas are averaged over each
441 fine-structure pair (same n and l); separate_lambda = true keeps them
442 separate. Then calls hartreeFockBrueckner.
443
444 @param valence_list Unused
445 @param fit_energies Energies to fit to (au), in the same order as
446 valence; sign ignored (binding energies)
447 @param separate_lambda Keep lambdas of fine-structure pairs separate
448
449 @note Each fitted state needs its own Sigma (same kappa and n; see
450 each_valence in formSigma). Otherwise it is not fitted (lambda = 1
451 is printed): its energy is that with the lower-n Sigma.
452 @note Prints a warning and does nothing if Sigma has not been formed.
453 */
454 void fitSigma_hfBrueckner(const std::string &valence_list,
455 const std::vector<double> &fit_energies,
456 bool separate_lambda = false);
457
458 //! OLD: deprecated
459 void radiativePotential(QED::RadPot::Scale s, double rcut, double scale_rN,
460 const std::vector<double> &x_spd,
461 bool do_readwrite = true, bool print = true);
462
463 /*!
464 @brief Calculates radiative potential, adds to HF potential.
465
466 @details
467 Replaces any existing radiative potential in HF. Included in subsequent
468 HF solutions: call before solve_core to include QED in the core, after
469 it for valence only. Prints a warning and does nothing if HF is not set.
470
471 @param qed_input QED options (see QED::ConstructRadPot)
472 @param do_readwrite Read/write the potential from/to file
473 @param print Print details
474 */
475 void radiativePotential(const IO::InputBlock &qed_input, bool do_readwrite,
476 bool print);
477
478 //! Calculates + populates basis [see BSplineBasis]
479 void formBasis(const SplineBasis::Parameters &params);
480
481 //! Calculates + populates Spectrum [see BSplineBasis]
482 void formSpectrum(const SplineBasis::Parameters &params);
483
484 /*!
485 @brief Forms + stores correlation potential Sigma.
486
487 @details
488 Constructs Sigma (see MBPT::CorrelationPotential), reading it from file if
489 it exists, and forms it for the valence states (see @p each_valence,
490 @p ek). Then applies @p lambdas, optionally prints the energy shifts, and
491 writes Sigma to file. Requires the basis (formBasis) for the Goldstone
492 sums. Does nothing if the core is empty or HF is not set. Requires the
493 HartreeFock method: prints a warning and does nothing otherwise.
494
495 @param nmin_core Minimum n of core states included in
496 polarisation
497 @param r0 Sub-grid first point (aB)
498 @param rmax Sub-grid last point (aB)
499 @param stride Sub-grid stride: every stride-th point of the
500 full grid
501 @param each_valence Form Sigma for each valence state; else for the
502 first valence state of each kappa. Ignored if
503 @p ek is given
504 @param include_G Include small-component (g) parts of Sigma
505 @param include_Breit Include two-body Breit correction, B2 (only if
506 HF includes Breit)
507 @param n_max_breit Maximum n of excited states in B2 (0: all)
508 @param lambdas Scaling factors, lambda, for each Sigma, in the
509 order formed
510 @param fk Effective screening factors for exchange, for
511 each k (empty: calculated for Feynman with
512 screening)
513 @param etak Effective hole-particle factors, for each k
514 (Goldstone only)
515 @param read_write Read Sigma from file (if it exists) and write
516 it; false: no file
517 @param fname Sigma file name (empty: identity() plus an
518 extension encoding the method)
519 @param FeynmanQ Feynman method for direct diagrams; else
520 Goldstone
521 @param ScreeningQ Include all-order screening (Feynman only)
522 @param hole_particleQ Include hole-particle interaction (Feynman
523 only)
524 @param lmax Maximum l of internal lines (Feynman)
525 @param omre Real part of frequency for the Im(w)
526 integration (Feynman)
527 @param w0 First non-zero point of the Im(w) grid
528 (Feynman)
529 @param wratio Ratio of the logarithmic Im(w) grid (Feynman)
530 @param complex_green Solve Green's function directly at complex
531 energy (see MBPT::FeynmanOptions)
532 @param ek State/energy pairs (energies in au): form Sigma
533 for each at the given energy, instead of the
534 valence energies
535 @param ladder_file File with ladder correction, Sigma_L (empty:
536 none)
537 @param derivative Also form dSigma/dE
538 @param print_de Print MBPT(2) energy corrections for valence
539 @param fk_both_lines Apply fk to both Coulomb lines of the exchange
540 diagrams (else outer only)
541 @param tail_extrapolation Extrapolate Sigma beyond the sub-grid as
542 a_eff/r^4 (experimental)
543
544 @note If read from file, the sub-grid and @p include_G are taken from the
545 file (see MBPT::CorrelationPotential).
546 */
547 void formSigma(int nmin_core = 1, double r0 = 1.0e-4, double rmax = 30.0,
548 int stride = 4, bool each_valence = false,
549 bool include_G = false, bool include_Breit = false,
550 int n_max_breit = 0, const std::vector<double> &lambdas = {},
551 const std::vector<double> &fk = {},
552 const std::vector<double> &etak = {}, bool read_write = true,
553 const std::string &fname = "", bool FeynmanQ = false,
554 bool ScreeningQ = false, bool hole_particleQ = false,
555 int lmax = 6, double omre = -0.2, double w0 = 0.01,
556 double wratio = 1.5, bool complex_green = false,
557 const std::optional<IO::InputBlock> &ek = std::nullopt,
558 const std::string &ladder_file = "", bool derivative = false,
559 bool print_de = false, bool fk_both_lines = false,
560 bool tail_extrapolation = false);
561
562 // void correlations(const IO::InputBlock &input);
563
564 /*!
565 @brief Copies correlation potential Sigma (nothing if @p Sigma is null).
566
567 @details
568 E.g., to re-use Sigma from another Wavefunction (different isotope).
569
570 @note The copy still refers to the Hartree-Fock object it was formed with,
571 which must outlive it if it is used to form or write Sigma.
572 */
574 if (Sigma != nullptr)
575 m_Sigma = *Sigma;
576 }
577
578 /*!
579 @brief Replaces nuclear potential, in both Wavefunction and HartreeFock.
580
581 @details
582 Allows extra potential to be added to Vnuc: pass vnuc() + extra. Updates
583 both in Wavefunction _and_ HartreeFock, which must be kept in sync.
584 Orbitals are not re-solved, and nucleus() is not updated.
585 */
586 void update_Vnuc(const std::vector<double> &v_new) {
587 /// nb: two versions of Vnuc...
588 m_vnuc = v_new;
589 if (m_HF) {
590 m_HF->vnuc() = v_new;
591 }
592 }
593
594 /*!
595 @brief Returns [min,max] r values for which the core density is > cutoff.
596
597 @details
598 Core density for given l; cutoff = eps*max_value.
599 Returns the r values (au) for which the value of
600 \f$ \rho(r) = \sum|\psi|^2 \f$ drops below cutoff. Sum goes over all m for
601 given l. Cut-off defined as eps*max, where max is maximum value for
602 rho(r). Set l<0 to get for all l (entire core). Returns the full grid
603 range if there are no core states with given l (or if eps = 0).
604 */
605 std::tuple<double, double> lminmax_core_range(int l, double eps = 0.0) const;
606
607 /*!
608 @brief Returns <a|H|b> for Hamiltonian H (NOT Sigma, Breit, or exchange).
609
610 @details
611 Includes the local potential, vlocal (incl. Rad.pot), and the QED
612 magnetic form factor, Hmag. Uses the symmetric form of the derivative
613 term (integrated by parts). Zero if @p Fa and @p Fb have different kappa.
614 */
615 double H0ab(const DiracSpinor &Fa, const DiracSpinor &Fb) const;
616 /*!
617 @brief As above, but with the radial derivatives given.
618
619 @details
620 @p dFa and @p dFb are the derivatives (d/dr) of @p Fa and @p Fb; only
621 their g components are used.
622 */
623 double H0ab(const DiracSpinor &Fa, const DiracSpinor &dFa,
624 const DiracSpinor &Fb, const DiracSpinor &dFb) const;
625
626 /*!
627 @brief Returns <a|H|b>, including exchange, Sigma, and Breit.
628
629 @details
630 H0ab, plus HF exchange (if HF is non-local), Sigma (if formed, including
631 lambda), and Breit (if included in HF). Zero if kappa differs.
632 */
633 double Hab(const DiracSpinor &Fa, const DiracSpinor &Fb) const;
634
635 //! Runs the CI+MBPT routines; stores wavefunctions
636 void ConfigurationInteraction(const IO::InputBlock &input);
637
638 /*!
639 @brief Writes wavefunction information to json file.
640
641 @details
642 Grid, nuclear parameters, and core, valence, and exotic (muon) orbitals,
643 with a description of each field ("metadata").
644
645 @param out_name If given (not empty), will print to that file
646 @return The json object.
647 */
648 nlohmann::json
649 output_to_json(const std::string &out_name = "ampsci_output.json");
650
651private:
652 double H0ab_impl(const DiracSpinor &Fa, std::vector<double> dga,
653 const DiracSpinor &Fb, std::vector<double> dgb) const;
654
655 // Creates set of blank core orbitals
656 std::vector<DiracSpinor> determineCore(const std::string &str_core_in);
657 bool isInAboveFermiCore(int n, int k) const;
658};
Container for CI solutions in a single J/Pi.
Definition CSF.hpp:248
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:55
Non-uniform radial grid with Jacobian, suitable for atomic structure calculations.
Definition Grid.hpp:85
Solves relativistic Hartree-Fock equations for core and valence. Optionally includes Breit and QED ef...
Definition HartreeFock.hpp:114
Holds a named list of key=value options and nested InputBlocks.
Definition InputBlock.hpp:154
Correlation potential, Sigma, for valence states.
Definition CorrelationPotential.hpp:108
Stores set of nuclear parameters (all radii in fm)
Definition NuclearPotentials.hpp:41
int & z()
Nuclear charge, Z.
Definition NuclearPotentials.hpp:93
double r_rms() const
Root-mean-square charge radius (fm); 0 if not set.
Definition NuclearPotentials.hpp:106
int & a()
Mass number, A.
Definition NuclearPotentials.hpp:96
Constructs and stores the Flambaum-Ginges QED Radiative Potential.
Definition RadPot.hpp:16
Scale factors for Uehling, high, low, magnetic, Wickman-Kroll.
Definition RadPot.hpp:21
Stores Wavefunction (set of valence orbitals, grid, HF etc.)
Definition Wavefunction.hpp:48
void solve_valence(const std::string &in_valence_str="", const bool print=true)
Performs Hartree-Fock procedure for valence; populates valence.
Definition Wavefunction.cpp:192
void formBasis(const SplineBasis::Parameters &params)
Calculates + populates basis [see BSplineBasis].
Definition Wavefunction.cpp:481
void solve_core(bool print=true)
Performs Hartree-Fock procedure for core (nothing if HF not set)
Definition Wavefunction.cpp:164
const std::vector< DiracSpinor > & core() const
Core orbitals (frozen HF core); empty if HF not set.
Definition Wavefunction.hpp:133
void printValence(const std::vector< DiracSpinor > &tmp_orbitals={}) const
Prints table of valence orbitals + energies etc.
Definition Wavefunction.cpp:414
const Grid & grid() const
Returns a const reference to the radial grid.
Definition Wavefunction.hpp:105
double coreEnergyHF() const
Calculates HF core energy.
Definition Wavefunction.cpp:184
std::tuple< double, double > lminmax_core_range(int l, double eps=0.0) const
Returns [min,max] r values for which the core density is > cutoff.
Definition Wavefunction.cpp:356
const DiracSpinor * getState(int n, int k) const
Finds requested state (n, kappa); returns nullptr if not found.
Definition Wavefunction.cpp:297
int Znuc() const
Nuclear charge, Z.
Definition Wavefunction.hpp:126
double energy_gap() const
Energy gap between lowest valence + highest core state.
Definition Wavefunction.cpp:343
std::string identity() const
Atomic symbol, including core ionisation degree and run_label.
Definition Wavefunction.cpp:771
const CI::PsiJPi * CIwf(int J, int parity) const
CI solutions for given J and parity; nullptr if not found.
Definition Wavefunction.hpp:167
void copySigma(const MBPT::CorrelationPotential *const Sigma)
Copies correlation potential Sigma (nothing if Sigma is null).
Definition Wavefunction.hpp:573
std::string coreConfiguration() const
Returns full core configuration.
Definition Wavefunction.hpp:259
nlohmann::json output_to_json(const std::string &out_name="ampsci_output.json")
Writes wavefunction information to json file.
Definition Wavefunction.cpp:1004
int Zion() const
Effective charge (for core) = Z-N_core.
Definition Wavefunction.hpp:302
const CI::Integrals & CI_integrals() const
Integral tables used to construct the CI Hamiltonians.
Definition Wavefunction.hpp:181
std::vector< double > vlocal(int l=0) const
Local part of potential, e.g., Vl = Vnuc + Vdir + Vrad_el(l).
Definition Wavefunction.cpp:752
const std::string & run_label() const
Optional label for output identity (see identity)
Definition Wavefunction.hpp:291
std::vector< double > Hmag(int l=0) const
QED Magnetic form factor.
Definition Wavefunction.cpp:757
std::vector< double > coreDensity() const
Calculates rho(r) = sum_c psi^2(r) for core states, c={n,k,m}.
Definition Wavefunction.cpp:469
int ion_degree(int num_val) const
0 for neutral, 1 for singly-ionised etc. (num_val: valence electrons)
Definition Wavefunction.hpp:294
void formSigma(int nmin_core=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={}, bool read_write=true, const std::string &fname="", bool FeynmanQ=false, bool ScreeningQ=false, bool hole_particleQ=false, int lmax=6, double omre=-0.2, double w0=0.01, double wratio=1.5, bool complex_green=false, const std::optional< IO::InputBlock > &ek=std::nullopt, const std::string &ladder_file="", bool derivative=false, bool print_de=false, bool fk_both_lines=false, bool tail_extrapolation=false)
Forms + stores correlation potential Sigma.
Definition Wavefunction.cpp:524
int Anuc() const
Nuclear mass number, A.
Definition Wavefunction.hpp:128
std::string atomicSymbol() const
e.g., "Cs"
Definition Wavefunction.hpp:274
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:227
std::string ion_symbol(int num_val) const
I for neutral, II for singly-ionised etc. (num_val: valence electrons)
Definition Wavefunction.hpp:297
double get_rrms() const
Nuclear rms charge radius, in fm (femtometres)
Definition Wavefunction.hpp:130
void solve_exotic(const std::string &in_exotic_str, double mass=PhysConst::m_muon, bool screening=true, bool print=true)
Solves for exotic atoms (e.g., muonic), including screening.
Definition Wavefunction.cpp:874
const std::vector< DiracSpinor > & spectrum() const
Spectrum: like basis, but includes correlations.
Definition Wavefunction.hpp:155
const MBPT::CorrelationPotential * Sigma() const
Returns ptr to (const) Correlation Potential, Sigma; nullptr if none.
Definition Wavefunction.hpp:218
std::string coreConfiguration_nice() const
Returns core configuration, in nice output notation.
Definition Wavefunction.hpp:262
void formSpectrum(const SplineBasis::Parameters &params)
Calculates + populates Spectrum [see BSplineBasis].
Definition Wavefunction.cpp:502
const std::vector< CI::PsiJPi > & CIwfs() const
CI solutions, one for each {J, parity}; empty unless CI was run.
Definition Wavefunction.hpp:159
void set_HF(HF::Method method=HF::Method::HartreeFock, const std::string &in_core="", std::optional< HF::Breit::Params > breit_params=std::nullopt, double eps_HF=1.0e-14, bool print=true)
Initialises HF object and populates core orbitals.
Definition Wavefunction.cpp:122
const std::vector< DiracSpinor > & valence() const
Valence orbitals (HF or Brueckner orbitals)
Definition Wavefunction.hpp:139
std::shared_ptr< const Grid > grid_sptr() const
Copy of shared_ptr to grid [shared resource].
Definition Wavefunction.hpp:112
void printCore() const
Prints table of core orbitals + energies etc.
Definition Wavefunction.cpp:382
bool isInCore(int n, int k) const
Check if a state (n, kappa) is in the core list.
Definition Wavefunction.cpp:268
std::string atom() const
String of atom info (e.g., "Cs, Z=55 A=133")
Definition Wavefunction.hpp:267
double alpha() const
Local value of fine-structure constant.
Definition Wavefunction.hpp:115
double H0ab(const DiracSpinor &Fa, const DiracSpinor &Fb) const
Returns <a|H|b> for Hamiltonian H (NOT Sigma, Breit, or exchange).
Definition Wavefunction.cpp:806
const HF::HartreeFock * vHF() const
Returns ptr to Hartree Fock (class); nullptr if not set.
Definition Wavefunction.hpp:193
void ConfigurationInteraction(const IO::InputBlock &input)
Runs the CI+MBPT routines; stores wavefunctions.
Definition Wavefunction.cpp:865
void update_Vnuc(const std::vector< double > &v_new)
Replaces nuclear potential, in both Wavefunction and HartreeFock.
Definition Wavefunction.hpp:586
void fitSigma_hfBrueckner(const std::string &valence_list, const std::vector< double > &fit_energies, bool separate_lambda=false)
First, fits Sigma to energies, then forms fitted Brueckner orbitals.
Definition Wavefunction.cpp:655
const std::vector< double > & vnuc() const
Nuclear potential.
Definition Wavefunction.hpp:190
void hartreeFockBrueckner(const bool print=true)
Forms Brueckner valence orbitals; replaces existing valence states.
Definition Wavefunction.cpp:644
int Ncore() const
Number of electrons in the core.
Definition Wavefunction.cpp:763
const Nuclear::Nucleus & nucleus() const
Returns Nuclear::nucleus object (contains nuc. parameters)
Definition Wavefunction.hpp:124
const std::vector< DiracSpinor > & basis() const
Basis, eigenstates of HF potential. Used for MBPT.
Definition Wavefunction.hpp:151
const QED::RadPot * vrad() const
Pointer to QED radiative potential. May be nullptr.
Definition Wavefunction.hpp:214
double FermiLevel() const
Returns energy location of the "Fermi Level".
Definition Wavefunction.cpp:324
void printBasis(const std::vector< DiracSpinor > &the_basis) const
Prints table of Basis/Spectrum orbitals, compares to HF orbitals.
Definition Wavefunction.cpp:446
double Hab(const DiracSpinor &Fa, const DiracSpinor &Fb) const
Returns <a|H|b>, including exchange, Sigma, and Breit.
Definition Wavefunction.cpp:785
Wavefunction()
Default grid and nucleus (see GridParameters, Nuclear::Nucleus)
Definition Wavefunction.hpp:73
double dalpha2() const
Variation in alpha^2 : x = (alpha/alpha_0)^2 - 1.
Definition Wavefunction.hpp:118
const std::vector< DiracSpinor > & hf_valence() const
HF valence orbitals: copy of valence, as last solved by solve_valence.
Definition Wavefunction.hpp:143
bool isInValence(int n, int k) const
Check if a state (n, kappa) is in the valence list.
Definition Wavefunction.cpp:276
std::string niceCoreOutput(const std::string &full_core)
Given a full electron config., returns nicer format by recognising nobel gas.
Definition AtomData.cpp:199
std::string atomicSymbol(int Z)
e.g., 55 -> "Cs"
Definition AtomData.cpp:65
std::vector< PsiJPi > levels
One entry per {J, parity} requested.
Definition CI_Integrals.hpp:295
Integrals integrals
Integral tables used to construct the CI Hamiltonians.
Definition CI_Integrals.hpp:297
The result of a CI calculation: the solutions, and the integrals used to construct the CI Hamiltonian...
Definition CI_Integrals.hpp:293
Method
Methods available for self-consistant field model.
Definition HartreeFock.hpp:55
Data and useful functions for nuclear properties and potentials. Radii all in Fermi (fm,...
Definition nuclear_data_table.hpp:5
std::vector< T > derivative(const std::vector< T > &f, const std::vector< T > &drdt, const T dt, const int order=1)
Computes the derivative df/dr on a non-uniform grid.
Definition NumCalc_quadIntegrate.hpp:97
constexpr double m_muon
muon mass in atomic units (m_mu/m_e). Codata 2022: 206.768 2827(46)
Definition PhysConst_constants.hpp:39
Constructs spinor/orbital basis using B-splines.
Definition BSplineBasis.cpp:21
std::string int_to_roman(int a)
Converts an integer to a Roman numeral string. Assumes |a| <= 3999.
Definition String.hpp:349
The integral tables required to construct the CI Hamiltonian matrix.
Definition CI_Integrals.hpp:250
Parameters used to construct a Grid.
Definition Grid.hpp:26
Input parameters for B-spline basis construction (see form_basis).
Definition BSplineBasis.hpp:170