32 , atom_type_(atom_type__)
35 RTE_THROW(
"atom type is not initialized");
55 if (
atom_type_.parameters().valence_relativity() == relativity_t::iora) {
61 for (
int i = 0; i <
atom_type_.num_aw_descriptors(); i++) {
65 for (
int i = 0; i <
atom_type_.num_lo_descriptors(); i++) {
80 #pragma omp parallel default(shared)
84 std::vector<double> p;
85 std::vector<double> rdudr;
86 std::array<double, 2> uderiv;
88 #pragma omp for schedule(dynamic, 1)
89 for (
int l = 0; l < num_aw_descriptors(); l++) {
90 for (
int order = 0; order < (int)aw_descriptor(l).size(); order++) {
91 auto rsd = aw_descriptor(l)[order];
95 solver.solve(rel__, rsd.dme, rsd.l, rsd.enu, p, rdudr, uderiv);
98 for (
int ir = 0; ir < nmtp; ir++) {
99 s(ir) = std::pow(p[ir], 2);
101 double norm = 1.0 / std::sqrt(s.
interpolate().integrate(0));
103 for (
int ir = 0; ir < nmtp; ir++) {
108 for (
int i : {0, 1}) {
113 for (
int order1 = 0; order1 < order; order1++) {
116 for (
int ir = 0; ir < nmtp; ir++) {
123 for (
int ir = 0; ir < nmtp; ir++) {
127 for (
int i : {0, 1, 2}) {
133 for (
int ir = 0; ir < nmtp; ir++) {
138 if (std::abs(norm) < 1e-10) {
140 s <<
"AW radial function for atom " <<
atom_type_.label() <<
" is linearly dependent" << std::endl
141 <<
" order: " << order << std::endl
142 <<
" l: " << l << std::endl
143 <<
" dme: " << rsd.dme << std::endl
144 <<
" enu: " << rsd.enu;
148 norm = 1.0 / std::sqrt(norm);
150 for (
int ir = 0; ir < nmtp; ir++) {
154 for (
int i : {0, 1, 2}) {
159 for (
int order = 0; order < (int)aw_descriptor(l).size(); order++) {
161 for (
int ir = 0; ir < nmtp; ir++) {
176 #pragma omp parallel for schedule(dynamic, 1)
177 for (
int idxlo = 0; idxlo < num_lo_descriptors(); idxlo++) {
183 int num_rs =
static_cast<int>(lo_descriptor(idxlo).
rsd_set.size());
184 RTE_ASSERT(num_rs <= 3);
186 std::vector<std::vector<double>> p(num_rs);
187 std::vector<std::vector<double>> rdudr(num_rs);
188 std::array<double, 2> uderiv;
190 for (
int order = 0; order < num_rs; order++) {
191 auto rsd = lo_descriptor(idxlo).
rsd_set[order];
193 solver.solve(rel__, rsd.dme, rsd.l, rsd.enu, p[order], rdudr[order], uderiv);
196 for (
int ir = 0; ir < nmtp; ir++) {
197 s(ir) = std::pow(p[order][ir], 2);
199 double norm = 1.0 / std::sqrt(s.
interpolate().integrate(0));
202 for (
int ir = 0; ir < nmtp; ir++) {
206 rdudr[order][ir] *= norm;
212 a[order][0] = p[order].back();
213 a[order][1] = uderiv[0];
214 a[order][2] = uderiv[1];
216 for (
int i: {0, 1, 2}) {
217 rderiv[order][i] = a[order][i];
221 double b[] = {0, 0, 0};
229 for (
int i = 0; i < num_rs; i++) {
230 for (
int j = 0; j < num_rs; j++) {
231 s << rderiv[i][j] <<
" ";
235 s <<
"atom: " <<
atom_type_.label() << std::endl
237 <<
"l: " << lo_descriptor(idxlo).
am.
l() << std::endl;
238 s <<
"gesv returned " << info;
245 for (
int i : {0, 1, 2}) {
249 for (
int order = 0; order < num_rs; order++) {
250 for (
int ir = 0; ir < nmtp; ir++) {
256 for (
int i : {0, 1, 2}) {
262 for (
int ir = 0; ir < nmtp; ir++) {
265 double norm = 1.0 / std::sqrt(s.
interpolate().integrate(2));
268 for (
int ir = 0; ir < nmtp; ir++) {
272 for (
int i : {0, 1, 2}) {
278 s <<
"local orbital " << idxlo <<
" is not zero at MT boundary" << std::endl
279 <<
" atom symmetry class id : " <<
id() <<
" (" << atom_type().symbol() <<
")" << std::endl
281 <<
" number of MT points: " << nmtp << std::endl
284 for (
int j = 0; j < num_rs; j++) {
293 if (
atom_type_.parameters().cfg().control().verification() > 0 && num_lo_descriptors() > 0) {
304 for (
int l = 0; l <= atom_type().
indexr().lmax_lo(); l++) {
305 for (
int j = 0; j < atom_type().
indexr().num_lo(l); j++) {
307 for (
int j1 = 0; j1 < j; j1++) {
310 for (
int ir = 0; ir < nmtp; ir++) {
316 for (
int ir = 0; ir < nmtp; ir++) {
320 for (
int i : {0, 1, 2}) {
325 for (
int ir = 0; ir < nmtp; ir++) {
330 if (std::abs(norm) < 1e-10) {
332 s <<
"LO radial function for atom " <<
atom_type_.label() <<
" is linearly dependent" << std::endl
333 <<
" l : " << l << std::endl
334 <<
" index for a given l : " << j;
337 norm = 1.0 / std::sqrt(norm);
339 for (
int ir = 0; ir < nmtp; ir++) {
343 for (
int i : {0, 1, 2}) {
358 for (
int idxlo1 = 0; idxlo1 < num_lo_descriptors(); idxlo1++) {
362 for (
int idxlo2 = 0; idxlo2 < num_lo_descriptors(); idxlo2++) {
366 if (lo_descriptor(idxlo1).
am == lo_descriptor(idxlo2).
am) {
368 for (
int ir = 0; ir < nmtp; ir++) {
371 loprod(idxlo1, idxlo2) = s.
interpolate().integrate(2);
379 auto stdevp = la::Eigensolver_factory(
"lapack");
381 std::vector<double> loprod_eval(num_lo_descriptors());
384 stdevp->solve(num_lo_descriptors(), loprod, &loprod_eval[0], loprod_evec);
386 if (std::abs(loprod_eval[0]) < tol__) {
388 std::printf(
"local orbitals for atom symmetry class %i are almost linearly dependent\n",
id_);
389 std::printf(
"local orbitals overlap matrix:\n");
390 for (
int i = 0; i < num_lo_descriptors(); i++) {
391 for (
int j = 0; j < num_lo_descriptors(); j++) {
392 std::printf(
"%12.6f", ovlp(i, j));
396 std::printf(
"overlap matrix eigen-values:\n");
397 for (
int i = 0; i < num_lo_descriptors(); i++) {
398 std::printf(
"%12.6f", loprod_eval[i]);
401 std::printf(
"smallest eigenvalue: %20.16f\n", loprod_eval[0]);
404 std::vector<int> inc(num_lo_descriptors(), 0);
407 for (
int i = 0; i < num_lo_descriptors(); i++) {
410 std::vector<int> ilo;
411 for (
int j = 0; j < num_lo_descriptors(); j++) {
417 std::vector<double> eval(ilo.size());
420 for (
int j1 = 0; j1 < (int)ilo.size(); j1++) {
421 for (
int j2 = 0; j2 < (int)ilo.size(); j2++) {
422 tmp(j1, j2) = ovlp(ilo[j1], ilo[j2]);
426 stdevp->solve(
static_cast<int>(ilo.size()), tmp, &eval[0], evec);
428 if (eval[0] < tol__) {
429 std::printf(
"local orbital %i can be removed\n", i);
440 s <<
"local_orbitals_" <<
id_ <<
".dat";
441 FILE* fout = fopen(s.str().c_str(),
"w");
444 fprintf(fout,
"%f ",
atom_type_.radial_grid(ir));
445 for (
int idxlo = 0; idxlo < num_lo_descriptors(); idxlo++) {
454 s <<
"local_orbitals_deriv_" <<
id_ <<
".dat";
455 fout = fopen(s.str().c_str(),
"w");
458 fprintf(fout,
"%f ",
atom_type_.radial_grid(ir));
459 for (
int idxlo = 0; idxlo < num_lo_descriptors(); idxlo++) {
472 RTE_THROW(
"wrong size of effective potential array");
495 PROFILE(
"sirius::Atom_symmetry_class::find_enu");
497 std::vector<radial_solution_descriptor*> rs_with_auto_enu;
500 for (
int l = 0; l < num_aw_descriptors(); l++) {
501 for (
size_t order = 0; order < aw_descriptor(l).size(); order++) {
502 auto& rsd = aw_descriptor(l)[order];
504 rs_with_auto_enu.push_back(&rsd);
510 for (
int idxlo = 0; idxlo < num_lo_descriptors(); idxlo++) {
512 size_t num_rs = lo_descriptor(idxlo).
rsd_set.size();
514 for (
size_t order = 0; order < num_rs; order++) {
515 auto& rsd = lo_descriptor(idxlo).
rsd_set[order];
517 rs_with_auto_enu.push_back(&rsd);
522 #pragma omp parallel for
523 for (
size_t i = 0; i < rs_with_auto_enu.size(); i++) {
524 auto rsd = rs_with_auto_enu[i];
527 if (std::abs(new_enu - rsd->enu) >
atom_type_.parameters().cfg().settings().auto_enu_tol()) {
529 rsd->new_enu_found =
true;
531 rsd->new_enu_found =
false;
539 PROFILE(
"sirius::Atom_symmetry_class::generate_radial_functions");
549 if (atom_type().parameters().cfg().control().ortho_rf()) {
574Atom_symmetry_class::sync_radial_functions(
mpi::Communicator const& comm__,
int const rank__)
584Atom_symmetry_class::sync_radial_integrals(mpi::Communicator
const& comm__,
int const rank__)
589 if (
atom_type_.parameters().valence_relativity() == relativity_t::iora) {
595Atom_symmetry_class::sync_core_charge_density(mpi::Communicator
const& comm__,
int const rank__)
607 PROFILE(
"sirius::Atom_symmetry_class::generate_radial_integrals");
612 if (rel__ == relativity_t::none) {
617 #pragma omp parallel default(shared)
626 for (
int ir = 0; ir < nmtp; ir++) {
642 #pragma omp parallel default(shared)
649 for (
int order1 = 0; order1 < nrf; order1++) {
651 for (
int order2 = 0; order2 < nrf; order2++) {
653 if (order1 == order2) {
656 for (
int ir = 0; ir < nmtp; ir++) {
665 if (
atom_type_.parameters().valence_relativity() == relativity_t::iora) {
667 #pragma omp parallel for
674 for (
int ir = 0; ir < nmtp; ir++) {
680 s(ir) = sq_alpha_half * 0.5 * Minv * (t1 + t0 * 0.5 * ll);
688 if (
atom_type_.parameters().so_correction()) {
695 for (
int i = 0; i < nmtp; i++) {
704 for (
int order1 = 0; order1 < nrf; order1++) {
706 for (
int order2 = 0; order2 < nrf; order2++) {
709 for (
int ir = 0; ir < nmtp; ir++) {
713 soc * ve.deriv(1, ir) / pow(M, 2);
732 pout <<
"Atom : " <<
atom_type_.symbol() <<
", class id : " <<
id_ << std::endl;
733 pout <<
"augmented waves" << std::endl;
734 for (
int l = 0; l < num_aw_descriptors(); l++) {
735 for (
size_t order = 0; order < aw_descriptor(l).size(); order++) {
736 auto& rsd = aw_descriptor(l)[order];
739 if (rsd.new_enu_found) {
747 pout <<
"local orbitals" << std::endl;
748 for (
int idxlo = 0; idxlo < num_lo_descriptors(); idxlo++) {
749 for (
size_t order = 0; order < lo_descriptor(idxlo).
rsd_set.size(); order++) {
750 auto& rsd = lo_descriptor(idxlo).
rsd_set[order];
754 if (rsd.new_enu_found) {
767 PROFILE(
"sirius::Atom_symmetry_class::generate_core_charge_density");
776 std::vector<double> free_atom_grid(nmtp);
777 for (
int i = 0; i < nmtp; i++) {
778 free_atom_grid[i] =
atom_type_.radial_grid(i);
786 free_atom_grid.push_back(x);
794 for (
int ir = 0; ir < nmtp; ir++) {
804 for (
int ir = 0; ir < nmtp; ir++) {
808 for (
int ir = nmtp; ir < rgrid.
num_points(); ir++) {
809 veff[ir] = alpha * rgrid.
x_inv(ir) + beta;
828 std::vector<double> level_energy(
atom_type_.num_atomic_levels());
830 for (
int ist = 0; ist <
atom_type_.num_atomic_levels(); ist++) {
836 #pragma omp parallel for
837 for (
int ist = 0; ist <
atom_type_.num_atomic_levels(); ist++) {
841 atom_type_.atomic_level(ist).
k, rgrid, veff, level_energy[ist]);
843 auto& rho = bs.
rho();
844 for (
int i = 0; i < rgrid.
num_points(); i++) {
848 level_energy[ist] = bs.enu();
851 for (
int ist = 0; ist <
atom_type_.num_atomic_levels(); ist++) {
853 for (
int i = 0; i < rgrid.
num_points(); i++) {
854 rho(i) += rho_t(i, ist);
897 for (
int ist = 0; ist <
atom_type_.num_atomic_levels(); ist++) {
Contains declaration and partial implementation of sirius::Atom_symmetry_class class.
void generate_aw_radial_functions(relativity_t rel__)
Generate radial functions for augmented waves.
void generate_radial_functions(relativity_t rel__)
Generate APW and LO radial functions.
Atom_symmetry_class(int id_, Atom_type const &atom_type_)
Constructor.
void set_spherical_potential(std::vector< double > const &vs__)
Set the spherical component of the potential.
double core_eval_sum_
Core eigen-value sum.
void generate_lo_radial_functions(relativity_t rel__)
Generate local orbital raidal functions.
void dump_lo()
Dump local orbitals to the file for debug purposes.
Atom_type const & atom_type_
Pointer to atom type.
std::vector< double > ae_core_charge_density_
Core charge density.
std::vector< local_orbital_descriptor > lo_descriptors_
list of radial descriptor sets used to construct local orbitals
void generate_core_charge_density(relativity_t core_rel__)
Find core states and generate core density.
sddk::mdarray< double, 2 > o1_radial_integrals_
Overlap integrals for IORA relativistic treatment.
int id() const
Return symmetry class id.
std::vector< double > spherical_potential_
Spherical part of the effective potential.
double core_leakage_
Core leakage.
sddk::mdarray< double, 3 > so_radial_integrals_
Spin-orbit interaction integrals.
void find_enu(relativity_t rel__)
Find linearization energy.
sddk::mdarray< double, 2 > h_spherical_integrals_
Spherical part of radial integral.
sddk::mdarray< double, 3 > o_radial_integrals_
Overlap integrals.
int id_
Symmetry class id in the range [0, N_class).
sddk::mdarray< double, 3 > radial_functions_
List of radial functions for the LAPW basis.
std::vector< radial_solution_descriptor_set > aw_descriptors_
list of radial descriptor sets used to construct augmented waves
sddk::mdarray< double, 2 > surface_derivatives_
Surface derivatives of AW radial functions.
void generate_radial_integrals(relativity_t rel__)
Generate radial overlap and SO integrals.
void orthogonalize_radial_functions()
Orthogonalize the radial functions.
std::vector< int > check_lo_linear_independence(double etol__)
Check if local orbitals are linearly independent.
Defines the properties of atom type.
int num_mt_points() const
Return number of muffin-tin radial grid points.
auto const & indexr() const
Return const reference to the index of radial functions.
int zn() const
Return ionic charge (as positive integer).
double mt_radius() const
Return muffin-tin radius.
int mt_radial_basis_size() const
Total number of radial basis functions.
int aw_order(int l__) const
Order of augmented wave radial functions for a given l.
Spline< double > const & rho() const
Return charge density, corresponding to a radial solution.
External radial grid provided as a list of points.
T last() const
Last point of the grid.
T dx(const int i) const
Return .
T x_inv(const int i) const
Return .
int num_points() const
Number of grid points.
Finds a solution to radial Schrodinger, Koelling-Harmon or Dirac equation.
T integrate(std::vector< T > &g__, int m__) const
Integrate spline with r^m prefactor.
Spline< T, U > & interpolate()
Angular momentum quantum number.
auto l() const
Get orbital quantum number l.
int gesv(ftn_int n, ftn_int nrhs, T *A, ftn_int lda, T *B, ftn_int ldb) const
Compute the solution to system of linear equations A * X = B for general matrix.
MPI communicator wrapper.
void bcast(T *buffer__, int count__, int root__) const
Perform buffer broadcast.
Parallel standard output.
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
size_t size() const
Return total size (number of elements) of the array.
Contains definition of eigensolver factory.
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
int lmax(int lmmax__)
Get maximum orbital quantum number by the maximum lm index.
Namespace of the SIRIUS library.
relativity_t
Type of relativity treatment in the case of LAPW.
strong_type< int, struct __rf_lo_index_tag > rf_lo_index
Local orbital radial function index.
const double y00
First spherical harmonic .
const double speed_of_light
NIST value for the inverse fine structure (http://physics.nist.gov/cuu/Constants/index....
bool core
True if this is a core level.
int n
Principal quantum number.
double occupancy
Level occupancy.
int l
Angular momentum quantum number.
radial_solution_descriptor_set rsd_set
Set of radial solution descriptors.
angular_momentum am
Orbital quantum number .