25#ifndef __FREE_ATOM_HPP__
26#define __FREE_ATOM_HPP__
59 void find_new_rho(std::vector<double>
const& veff__,
bool rel__)
64 #pragma omp parallel for
66 relativity_t rt = (rel__) ? relativity_t::dirac : relativity_t::none;
67 Bound_state bound_state(rt,
zn(), atomic_level(ist).n, atomic_level(ist).l, atomic_level(ist).k,
69 enu_[ist] = bound_state.enu();
70 auto& bs_rho = bound_state.
rho();
71 auto& bs_u = bound_state.
u();
72 auto& bs_p = bound_state.
p();
73 auto& bs_dpdr = bound_state.dpdr();
76 for (
int i = 0; i < np; i++) {
83 for (
int i = 0; i < np; i++) {
99 Free_atom(Free_atom&& src) =
default;
117 PROFILE(
"sirius::Free_atom::ground_state");
130 RTE_THROW(
"Fixme : the libxc staring with version 4 changed the way to set relativitic LDA exchange");
136 std::vector<double> veff(np);
137 std::vector<double> vrho(np);
138 std::vector<double> vnuc(np);
139 for (
int i = 0; i < np; i++) {
145 auto mixer = std::make_shared<sirius::mixer::Anderson<std::vector<double>>>(12,
153 [](
const std::vector<double>& x) -> std::size_t {
return x.size(); },
154 [](
const std::vector<double>& x,
const std::vector<double>& y) ->
double {
156 for (std::size_t i = 0; i < x.size(); ++i)
157 result += x[i] * y[i];
160 [](
double alpha, std::vector<double>& x) ->
void {
164 [](
const std::vector<double>& x, std::vector<double>& y) ->
void {
165 std::copy(x.begin(), x.end(), y.begin());
167 [](
double alpha,
const std::vector<double>& x, std::vector<double>& y) ->
void {
168 for (std::size_t i = 0; i < x.size(); ++i)
169 y[i] += alpha * x[i];
171 [](
double c,
double s, std::vector<double>& x, std::vector<double>& y) ->
void {
172 for (std::size_t i = 0; i < x.size(); ++i) {
175 x[i] = xi * c + yi * s;
176 y[i] = xi * -s + yi * c;
181 mixer->initialize_function<0>(mixer_function_prop, vrho, vrho.size());
187 std::vector<double> vh(np);
188 std::vector<double> vxc(np);
189 std::vector<double> exc(np);
190 std::vector<double> vx(np);
191 std::vector<double> vc(np);
192 std::vector<double> ex(np);
193 std::vector<double> ec(np);
194 std::vector<double> g1;
195 std::vector<double> g2;
196 std::vector<double> rho_old;
200 double energy_tot = 0.0;
201 double energy_tot_old;
205 double energy_xc = 0;
207 double energy_coul = 0;
211 enu_[ist] = -1.0 *
zn() / 2 / std::pow(
double(atomic_level(ist).n), 2);
216 for (
int iter = 0; iter < 200; iter++) {
219 find_new_rho(veff, rel);
223 for (
int i = 0; i < np; i++) {
226 charge_rms = std::sqrt(charge_rms / np);
232 for (
int i = 0; i < np; i++) {
239 for (
int ir = 0; ir < np; ir++) {
240 vxc[ir] = (vx[ir] + vc[ir]);
241 exc[ir] = (ex[ir] + ec[ir]);
245 for (
int i = 0; i < np; i++) {
246 vrho[i] = vh[i] + vxc[i];
248 mixer->set_input<0>(vrho);
250 mixer->get_output<0>(vrho);
251 for (
int i = 0; i < np; i++) {
252 veff[i] = vrho[i] + vnuc[i];
261 for (
int i = 0; i < np; i++) {
268 for (
int i = 0; i < np; i++) {
277 for (
int i = 0; i < np; i++) {
282 energy_tot_old = energy_tot;
286 energy_diff = std::abs(energy_tot - energy_tot_old);
288 if (energy_diff < energy_tol && charge_rms < charge_tol) {
296 dict[
"converged"] =
true;
297 dict[
"num_scf_iterations"] = num_iter;
299 dict[
"converged"] =
false;
301 dict[
"energy_diff"] = energy_diff;
302 dict[
"charge_rms"] = charge_rms;
303 dict[
"energy_tot"] = energy_tot;
335 inline void generate_local_orbitals(std::string
const& recipe__)
364 inline double free_atom_orbital_density(
int ir,
int ist)
const
369 inline double free_atom_wave_function(
int ir,
int ist)
const
374 inline double free_atom_electronic_potential(
double x)
const
379 std::vector<double> radial_grid_points()
const
385 std::vector<double> free_atom_wave_function(
int ist__)
const
388 std::vector<double> v(np);
389 for (
int i = 0; i< np; i++) {
390 v[i] = free_atom_wave_function(i, ist__);
395 std::vector<double> free_atom_wave_function_x(
int ist__)
const
398 std::vector<double> v(np);
399 for (
int i = 0; i< np; i++) {
405 std::vector<double> free_atom_wave_function_x_deriv(
int ist__)
const
408 std::vector<double> v(np);
409 for (
int i = 0; i< np; i++) {
415 std::vector<double> free_atom_electronic_potential()
const
421 double atomic_level_energy(
int ist__)
const
431 for (
int i = 0; i < np; i++) {
435 std::vector<double> v(np);
436 int l = atomic_level(ist__).
l;
437 for (
int i = 0; i < np; i++) {
440 l * (l + 1) / x / x / 2) * p(i) -
enu_[ist__] * p(i);
Contains definition and implementation sirius::Anderson.
Contains declaration and implementation of sirius::Atom_type_base class.
Base class for sirius::Atom_type and sirius::Free_atom classes.
int zn_
Nucleus charge or pseudocharge, treated as positive(!) integer.
int num_atomic_levels() const
Return number of the atomic levels.
int zn() const
Get atomic charge.
Spline< double > free_atom_density_spline_
Density of a free atom.
Radial_grid< double > free_atom_radial_grid_
Radial grid of a free atom.
Radial_grid< double > const & free_atom_radial_grid() const
Get the whole radial grid.
Spline< double > const & u() const
Return radial function.
Spline< double > const & p() const
Return radial function multiplied by x.
Spline< double > const & rho() const
Return charge density, corresponding to a radial solution.
Full potential free atom solver.
Free_atom(int zn__)
Constructor.
mdarray< double, 2 > free_atom_orbital_density_
Densities of individual orbitals.
Free_atom(std::string symbol__)
Constructor.
mdarray< double, 2 > free_atom_wave_functions_x_
Radial wave-functions multiplied by r.
Spline< double > free_atom_electronic_potential_
Potential generated by the electronic ensity.
double NIST_LDA_Etot_
NIST total energy for LDA calculation.
json ground_state(double energy_tol, double charge_tol, bool rel)
std::vector< double > enu_
Energies of atomic levels.
mdarray< double, 2 > free_atom_wave_functions_x_deriv_
Derivatieve of radial wave-functions multiplied by r.
std::vector< double > free_atom_wave_function_residual(int ist__) const
Get residual.
mdarray< double, 2 > free_atom_wave_functions_
Radial wave-functions.
double NIST_ScRLDA_Etot_
NIST total energy for scalar-relativistic LDA calculation.
T x_inv(const int i) const
Return .
int num_points() const
Number of grid points.
T integrate(std::vector< T > &g__, int m__) const
Integrate spline with r^m prefactor.
Spline< T, U > & interpolate()
T at_point(U x) const
Compute value at any point.
Interface class to Libxc.
void get_lda(const int size, const double *rho, double *v, double *e) const
Get LDA contribution.
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
Namespace of the SIRIUS library.
relativity_t
Type of relativity treatment in the case of LAPW.
double eval_sum(Unit_cell const &unit_cell, K_point_set const &kset)
TODO doc.
double energy_kin(Simulation_context const &ctx, K_point_set const &kset, Density const &density, Potential const &potential)
Return kinetic energy.
double energy_enuc(Simulation_context const &ctx, Potential const &potential)
Return nucleus energy in the electrostatic field.
Contains declaration and partial implementation of sirius::Radial_solver class.
double occupancy
Level occupancy.
int l
Angular momentum quantum number.
Describes operations on a function type used for mixing.
Contains implementation of sirius::XC_functional class.