ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
CSF.hpp
1 #pragma once
2 #include "LinAlg/LinAlg.hpp"
3 #include "Wavefunction/DiracSpinor.hpp"
4 #include <array>
5 #include <utility>
6 #include <vector>
7 
8 namespace CI {
9 
10 //==============================================================================
12 class CSF2 {
13  int m_parity;
14 
15 public:
16  // nb: array of states is always sorted
17  std::array<DiracSpinor::Index, 2> states;
18 
19  CSF2(const DiracSpinor &a, const DiracSpinor &b);
20 
21  DiracSpinor::Index state(std::size_t i) const;
22 
23  friend bool operator==(const CSF2 &A, const CSF2 &B);
24  friend bool operator!=(const CSF2 &A, const CSF2 &B);
25 
27  static int num_different(const CSF2 &A, const CSF2 &B);
28 
31  static std::array<DiracSpinor::Index, 2> diff_1_na(const CSF2 &V,
32  const CSF2 &X);
34  static DiracSpinor::Index same_1_j(const CSF2 &A, const CSF2 &B);
35 
37  int parity() const;
38 
40  std::string config(bool relativistic = false) const;
41 };
42 
43 //==============================================================================
45 std::vector<CSF2> form_CSFs(int twoJ, int parity,
46  const std::vector<DiracSpinor> &cisp_basis);
47 
48 //==============================================================================
50 struct ConfigInfo {
51  // configuration (typically uses non-rel notation)
52  std::string config{};
53  // square of config coeficient (if non-rel, sum of all)
54  double ci2{0.0};
55  double gJ{0.0};
56  double L{-1.0};
57  double twoS{-1.0};
58 };
59 
60 //==============================================================================
62 class PsiJPi {
63 
64  int m_twoj{-1};
65  int m_pi{0};
66 
67  // Number of solutions stored:
68  std::size_t m_num_solutions{0};
69  // List of CSFs
70  std::vector<CSF2> m_CSFs{};
71  // Energy, and CI expansion coeficients
72  std::pair<LinAlg::Vector<double>, LinAlg::Matrix<double>> m_Solution{};
73  std::vector<ConfigInfo> m_Info{};
74 
75 public:
78  PsiJPi(int twoJ, int pi, const std::vector<DiracSpinor> &cisp_basis)
79  : m_twoj(twoJ), m_pi(pi), m_CSFs(form_CSFs(twoJ, pi, cisp_basis)) {}
80 
81  PsiJPi() {}
82 
87  void solve(const LinAlg::Matrix<double> &Hci, int num_solutions = 0);
88 
90  void update_config_info(std::size_t i, const ConfigInfo &info);
91 
93  const std::vector<CSF2> &CSFs() const;
94 
96  const CSF2 &CSF(std::size_t i) const;
97 
99  double energy(std::size_t i) const;
100 
102  LinAlg::View<const double> coefs(std::size_t i) const;
103 
105  double coef(std::size_t i, std::size_t j) const;
106 
108  int parity() const;
109 
111  int twoJ() const;
112 
114  std::size_t num_solutions() const;
115 
117  const ConfigInfo &info(std::size_t i) const;
118 };
119 
120 } // namespace CI
Very basic two-electron CSF. Only two-electron is implemented.
Definition: CSF.hpp:12
static DiracSpinor::Index same_1_j(const CSF2 &A, const CSF2 &B)
Returns the state in A and B that is the same (assumes A and B differ by 1)
Definition: CSF.cpp:54
std::string config(bool relativistic=false) const
Single-particle configuration as a string, in relativistic or non-rel form.
Definition: CSF.cpp:69
int parity() const
Parity of the CSF, +/-1.
Definition: CSF.cpp:67
static int num_different(const CSF2 &A, const CSF2 &B)
Returns number of different orbitals between two CSFs.
Definition: CSF.cpp:29
static std::array< DiracSpinor::Index, 2 > diff_1_na(const CSF2 &V, const CSF2 &X)
returns different orbitals, for case where CSFs differ by 1. i.e., returns {n,a} where |V> = |X_a^n> ...
Definition: CSF.cpp:40
Stores the CI Solutions for given J and parity (only two-electron).
Definition: CSF.hpp:62
void solve(const LinAlg::Matrix< double > &Hci, int num_solutions=0)
Solves the CI equation for Hamiltonian matrix Hci; finds first num_solutions solutions....
Definition: CSF.cpp:127
double energy(std::size_t i) const
Energy of the ith CI solution.
Definition: CSF.cpp:157
PsiJPi(int twoJ, int pi, const std::vector< DiracSpinor > &cisp_basis)
Construct containter for CI solutions. Constructs the CSFs, but doesn't solve system; have to call so...
Definition: CSF.hpp:78
LinAlg::View< const double > coefs(std::size_t i) const
List of CI expansion coefs for the ith CI solution.
Definition: CSF.cpp:163
const ConfigInfo & info(std::size_t i) const
Configuration info for the ith CI solution, if it has been set.
Definition: CSF.cpp:184
std::size_t num_solutions() const
Number of CI solutions stored.
Definition: CSF.cpp:181
const CSF2 & CSF(std::size_t i) const
The ith CSF.
Definition: CSF.cpp:154
double coef(std::size_t i, std::size_t j) const
The CI coeficient for the ith CI solution, corresponding to the jth CSF.
Definition: CSF.cpp:169
const std::vector< CSF2 > & CSFs() const
Full list of CSFs.
Definition: CSF.cpp:151
int twoJ() const
2J for the CI solutions
Definition: CSF.cpp:178
void update_config_info(std::size_t i, const ConfigInfo &info)
You must manuall update the config. info for each solution (if required)
Definition: CSF.cpp:145
int parity() const
Parity for the CI solutions (+/-1)
Definition: CSF.cpp:175
Stores radial Dirac spinor: F_nk = (f, g)
Definition: DiracSpinor.hpp:41
Proved a "view" onto an array.
Definition: Matrix.ipp:7
Functions and classes for Configuration Interaction calculations.
Definition: CI.hpp:7
std::vector< CSF2 > form_CSFs(int twoJ, int parity, const std::vector< DiracSpinor > &cisp_basis)
Forms list of all possible (2-particle) CSFs with given J and parity.
Definition: CSF.cpp:85
Basic configuration info for each CI level solution.
Definition: CSF.hpp:50