High-precision calculations for one- and two-valence atomic systems
NuclearPotentials.hpp
1#pragma once
2#include "IO/InputBlock.hpp"
3#include "Physics/NuclearData.hpp" //for Isotope
4#include <optional>
5#include <string>
6#include <vector>
7class Grid;
8
9namespace Nuclear {
10
11/*!
12 @brief Nuclear charge distribution options.
13
14 @details
15 - Fermi : two-parameter Fermi distribution (c and t)
16 - spherical : uniformly charged sphere (ball)
17 - point : point-like nucleus
18 - Gaussian : Gaussian distribution
19 - custom : potential read from file (see formPotential)
20 - Error : unrecognised type (see parseType)
21*/
22enum class ChargeDistro { Fermi, spherical, point, Gaussian, custom, Error };
23
24/*!
25 @brief Converts string to ChargeDistro (case-insensitive).
26
27 @details
28 Also accepts: "spher*", "ball", "uniform" (spherical); "point*", "zero*"
29 (point); "gaus*" (Gaussian). If unknown, prints a warning with the closest
30 match.
31
32 @return ChargeDistro; ChargeDistro::Error if unknown.
33*/
34ChargeDistro parseType(const std::string &str_type);
35//! Converts ChargeDistro to string
36std::string parseType(ChargeDistro type);
37
38//------------------------------------------------------------------------------
39
40//! Stores set of nuclear parameters (all radii in fm)
41class Nucleus {
42 // Isotope data
43 Isotope m_iso;
44 // Charge distribution type
46 // skin thickness parameter (in fm). Usually 2.3
47 double m_t;
48 // Deformation parameter beta. Usually 0.
49 double m_beta;
50 // Name of input file used to read in custom nuclear potential
51 std::string m_custom_pot_file_name;
52 // Other parameters: not used for now
53 std::vector<double> m_params;
54
55public:
56 /*!
57 @brief Constructs nucleus from Z and A, with optional parameters.
58
59 @details
60 r_rms is taken from isotope data if not given; if not in the isotope
61 data, an approximate formula is used. A = 0 gives r_rms = 0 (point-like),
62 regardless of @p in_rrms. For non-Fermi types, t is set to zero.
63
64 @param in_z Nuclear charge, Z
65 @param in_a Mass number, A. Negative: default A for Z;
66 0: point-like
67 @param str_type Charge distribution type (see parseType)
68 @param in_rrms Root-mean-square charge radius (fm).
69 Negative: from isotope data
70 @param in_t Skin thickness (fm), Fermi only. Negative:
71 default_t
72 @param in_beta Quadrupole deformation parameter (Fermi only)
73 @param in_params Extra parameters (not currently used)
74 @param custom_pot_file_name File for custom nuclear potential
75 */
76 Nucleus(int in_z = 1, int in_a = 0, const std::string &str_type = "Fermi",
77 double in_rrms = -1.0, double in_t = -1.0, double in_beta = 0.0,
78 const std::vector<double> &in_params = {},
79 const std::string &custom_pot_file_name = "");
80
81 //! As above, with Z given as atomic symbol or name (e.g., "Cs")
82 Nucleus(const std::string &z_str, int in_a,
83 const std::string &str_type = "Fermi", double in_rrms = -1.0,
84 double in_t = Nuclear::default_t, double in_beta = 0.0,
85 const std::vector<double> &in_params = {},
86 const std::string &custom_pot_file_name = "");
87
88public:
89 //! Charge distribution type
90 ChargeDistro &type() { return m_type; }
91 ChargeDistro type() const { return m_type; }
92 //! Nuclear charge, Z
93 int &z() { return m_iso.Z; };
94 int z() const { return m_iso.Z; };
95 //! Mass number, A
96 int &a() { return m_iso.A; };
97 int a() const { return m_iso.A; };
98
99 //! Extra parameters (not currently used)
100 const std::vector<double> &params() const { return m_params; };
101 std::vector<double> &params() { return m_params; };
102
103 //! Sets root-mean-square charge radius (fm)
104 void set_rrms(double rrms) { m_iso.r_rms = rrms; }
105 //! Root-mean-square charge radius (fm); 0 if not set
106 double r_rms() const { return m_iso.r_rms ? *m_iso.r_rms : 0.0; };
107
108 //! Skin thickness, t (fm); Fermi only
109 double &t() { return m_t; };
110 double t() const { return m_t; };
111
112 //! Quadrupole deformation parameter, beta; Fermi only
113 double &beta() { return m_beta; };
114 double beta() const { return m_beta; };
115
116 //! File name for custom nuclear potential
117 std::string &custom_pot_file() { return m_custom_pot_file_name; };
118 std::string custom_pot_file() const { return m_custom_pot_file_name; };
119
120 //! Half-density radius, c (fm), from r_rms and t
121 double c() const { return c_hdr_formula_rrms_t(r_rms(), m_t); }
122
123 //! Prints summary of nuclear parameters
124 friend std::ostream &operator<<(std::ostream &ostr, const Nucleus &n);
125};
126
127//------------------------------------------------------------------------------
128/*!
129 @brief Forms nucleus from Z, A, and the nuclear options in @p input.
130
131 @details
132 Starts from the default nucleus for given Z and A (see Nucleus), then
133 over-rides with any options given in @p input: type, rrms, c, t, beta,
134 input_file, parameters. If c is given, it over-rides rrms. If A or r_rms
135 is zero, the nucleus is set to point-like (except for custom).
136
137 @param Z Nuclear charge
138 @param A Mass number; default A for Z if not given
139 @param input Input block with nuclear options (see input.check() in .cpp)
140
141 @note input_file only sets the file name: type must also be custom.
142*/
143Nucleus form_nucleus(int Z, std::optional<int> A = std::nullopt,
144 IO::InputBlock input = {});
145
146//------------------------------------------------------------------------------
147
148/*!
149 @brief Nuclear potential: uniformly charged sphere (ball) of radius rnuc.
150
151 @details
152 \f[
153 V(r) = \begin{cases}
154 -\frac{Z}{2 r_N}\left(3 - r^2/r_N^2\right) & r < r_N, \\
155 -Z/r & r \geq r_N.
156 \end{cases}
157 \f]
158 rnuc = 0 gives a point-like nucleus.
159
160 @param Z Nuclear charge
161 @param rnuc Nuclear charge radius, in fm (not r_rms: for a uniform
162 sphere, r_N = sqrt(5/3) r_rms)
163 @param rgrid Radial points (atomic units)
164
165 @return V(r) at each point of @p rgrid (atomic units).
166*/
167[[nodiscard]] std::vector<double>
168sphericalNuclearPotential(double Z, double rnuc,
169 const std::vector<double> &rgrid);
170
171/*!
172 @brief Nuclear potential: Gaussian charge distribution.
173
174 @details
175 \f[
176 V(r) = -\frac{Z}{r}\,{\rm erf}\left(\sqrt{3/2}\;r/r_{\rm rms}\right).
177 \f]
178
179 @param Z Nuclear charge
180 @param r_rms Root-mean-square charge radius, in fm
181 @param rgrid Radial points (atomic units)
182
183 @return V(r) at each point of @p rgrid (atomic units).
184*/
185[[nodiscard]] std::vector<double>
186GaussianNuclearPotential(double Z, double r_rms,
187 const std::vector<double> &rgrid);
188
189/*!
190 @brief Nuclear potential: Fermi charge distribution.
191
192 @details
193 For charge density
194 \f[
195 \rho(r) = \rho_0 \left[ 1 + e^{(r - c)/a} \right]^{-1},
196 \qquad a = t/(4\ln 3),
197 \f]
198 normalised to Z. Expressed in terms of complete Fermi-Dirac integrals
199 (GSL). V = -Z/r beyond r = 10c.
200
201 @param Z Nuclear charge
202 @param t Skin thickness (90% to 10% fall-off), in fm
203 @param c Half-density radius, in fm (not r_rms)
204 @param rgrid Radial points (atomic units)
205
206 @return V(r) at each point of @p rgrid (atomic units).
207*/
208[[nodiscard]] std::vector<double>
209fermiNuclearPotential(double Z, double t, double c,
210 const std::vector<double> &rgrid);
211
212/*!
213 @brief Fermi charge distribution, rho(r), normalised to Z_norm.
214
215 @details
216 \f$ \int \rho\, d^3r = 4\pi \int \rho(r)\, r^2 dr = Z_{\rm norm} \f$:
217 Z_norm = Z for nuclear charge density; Z_norm = 1 for nuclear density.
218 rho = 0 beyond r = 10c.
219
220 @param t Skin thickness, in fm
221 @param c Half-density radius, in fm
222 @param Z_norm Normalisation
223 @param grid Radial grid
224
225 @return rho(r) on @p grid (atomic units).
226*/
227[[nodiscard]] std::vector<double>
228fermiNuclearDensity_tcN(double t, double c, double Z_norm, const Grid &grid);
229
230/*!
231 @brief Nuclear potential V(r) for given nucleus, at radial points @p r.
232
233 @details
234 Calls one of the above, depending on nucleus type. If r_rms = 0, point-like
235 (-Z/r) for all types except custom.
236 - Fermi: c from r_rms and t; if beta is non-zero, uses the effective skin
237 thickness for the deformed nucleus (deformation_effective_t)
238 - spherical: radius r_N = sqrt(5/3) r_rms
239 - custom: reads {r, V(r)} (atomic units) from custom_pot_file(), and
240 interpolates onto @p r. Beyond the last point, V = -Z_eff/r, with Z_eff
241 from the last point. Not extrapolated to smaller r.
242
243 @return V(r) at each point of @p r (atomic units).
244
245 @warning Aborts if the custom file is invalid (fewer than 3 points), or the
246 type is invalid.
247*/
248[[nodiscard]] std::vector<double> formPotential(const Nucleus &nucleus,
249 const std::vector<double> &r);
250
251} // namespace Nuclear
Non-uniform radial grid with Jacobian, suitable for atomic structure calculations.
Definition Grid.hpp:85
Holds a named list of key=value options and nested InputBlocks.
Definition InputBlock.hpp:154
Stores set of nuclear parameters (all radii in fm)
Definition NuclearPotentials.hpp:41
int & z()
Nuclear charge, Z.
Definition NuclearPotentials.hpp:93
void set_rrms(double rrms)
Sets root-mean-square charge radius (fm)
Definition NuclearPotentials.hpp:104
double r_rms() const
Root-mean-square charge radius (fm); 0 if not set.
Definition NuclearPotentials.hpp:106
friend std::ostream & operator<<(std::ostream &ostr, const Nucleus &n)
Prints summary of nuclear parameters.
Definition NuclearPotentials.cpp:105
ChargeDistro & type()
Charge distribution type.
Definition NuclearPotentials.hpp:90
double & t()
Skin thickness, t (fm); Fermi only.
Definition NuclearPotentials.hpp:109
const std::vector< double > & params() const
Extra parameters (not currently used)
Definition NuclearPotentials.hpp:100
std::string & custom_pot_file()
File name for custom nuclear potential.
Definition NuclearPotentials.hpp:117
double c() const
Half-density radius, c (fm), from r_rms and t.
Definition NuclearPotentials.hpp:121
double & beta()
Quadrupole deformation parameter, beta; Fermi only.
Definition NuclearPotentials.hpp:113
int & a()
Mass number, A.
Definition NuclearPotentials.hpp:96
Data and useful functions for nuclear properties and potentials. Radii all in Fermi (fm,...
Definition nuclear_data_table.hpp:5
double c_hdr_formula_rrms_t(double rrms, double t)
Calculates c from rrms and t.
Definition NuclearData.cpp:73
std::optional< double > r_rms
root-mean-square charge radius, in Fermi (fm, e-15m)
Definition NuclearData.hpp:24
std::vector< double > sphericalNuclearPotential(double Z, double rnuc, const std::vector< double > &rgrid)
Nuclear potential: uniformly charged sphere (ball) of radius rnuc.
Definition NuclearPotentials.cpp:231
int A
Atomic mass number (A = Z + N)
Definition NuclearData.hpp:22
int Z
Atomic charge.
Definition NuclearData.hpp:20
ChargeDistro parseType(const std::string &str_type)
Converts string to ChargeDistro (case-insensitive).
Definition NuclearPotentials.cpp:20
std::vector< double > formPotential(const Nucleus &nuc, const std::vector< double > &r)
Nuclear potential V(r) for given nucleus, at radial points r.
Definition NuclearPotentials.cpp:356
std::vector< double > fermiNuclearDensity_tcN(double t, double c, double Z_norm, const Grid &grid)
Fermi charge distribution, rho(r), normalised to Z_norm.
Definition NuclearPotentials.cpp:321
Nucleus form_nucleus(int Z, std::optional< int > tA, IO::InputBlock input)
Forms nucleus from Z, A, and the nuclear options in input.
Definition NuclearPotentials.cpp:151
std::vector< double > fermiNuclearPotential(double z, double t, double c, const std::vector< double > &rgrid)
Nuclear potential: Fermi charge distribution.
Definition NuclearPotentials.cpp:272
std::vector< double > GaussianNuclearPotential(double Z, double r_rms, const std::vector< double > &rgrid)
Nuclear potential: Gaussian charge distribution.
Definition NuclearPotentials.cpp:254
ChargeDistro
Nuclear charge distribution options.
Definition NuclearPotentials.hpp:22
Isotope data: Z, A, r_rms/fm, I, pi, mu, Q.
Definition NuclearData.hpp:18