102 if (
type().parameters().full_potential()) {
119 if (!
type().parameters().full_potential()) {
143 PROFILE(
"sirius::Atom::generate_radial_integrals");
150 if (comm__.
size() != 1) {
151 RTE_THROW(
"not yet mpi parallel");
164 std::vector<Spline<double>> rf_spline(nrf);
165 #pragma omp parallel for
166 for (
int i = 0; i < nrf; i++) {
168 for (
int ir = 0; ir < nmtp; ir++) {
175 #pragma omp parallel for
178 for (
int ir = 0; ir < nmtp; ir++) {
184 for (
int ir = 0; ir < nmtp; ir++) {
193 auto& idx_ri =
type().idx_radial_integrals();
197 if (pu__ == sddk::device_t::GPU) {
199 auto& rgrid =
type().radial_grid();
200 auto& rf_coef =
type().rf_coef();
201 auto& vrf_coef =
type().vrf_coef();
203 PROFILE_START(
"sirius::Atom::generate_radial_integrals|interp");
207 for (
int i = 0; i < nrf; i++) {
208 rf_spline[i].interpolate();
209 std::copy(rf_spline[i].coeffs().at(sddk::memory_t::host),
210 rf_spline[i].coeffs().at(sddk::memory_t::host) + nmtp * 4,
211 rf_coef.at(sddk::memory_t::host, 0, 0, i));
217 v_spline[i].interpolate();
222 #pragma omp parallel for
224 for (
int i = 0; i < nrf; i++) {
227 vrf_spline[idx] = rf_spline[i] * v_spline[
lm + j *
lmmax];
228 std::memcpy(vrf_coef.at(sddk::memory_t::host, 0, 0, idx), vrf_spline[idx].coeffs().at(sddk::memory_t::host),
229 nmtp * 4 *
sizeof(
double));
235 vrf_coef.copy_to(sddk::memory_t::device);
236 PROFILE_STOP(
"sirius::Atom::generate_radial_integrals|interp");
238 result.
allocate(sddk::memory_t::device);
239 spline_inner_product_gpu_v3(idx_ri.at(sddk::memory_t::device), (
int)idx_ri.size(1), nmtp,
240 rgrid.x().at(sddk::memory_t::device), rgrid.dx().at(sddk::memory_t::device),
241 rf_coef.at(sddk::memory_t::device), vrf_coef.at(sddk::memory_t::device),
242 result.at(sddk::memory_t::device));
249 result.
copy_to(sddk::memory_t::host);
253 if (pu__ == sddk::device_t::CPU) {
254 PROFILE_START(
"sirius::Atom::generate_radial_integrals|interp");
258 for (
int i = 0; i < nrf; i++) {
259 rf_spline[i].interpolate();
263 v_spline[i].interpolate();
268 for (
int i = 0; i < nrf; i++) {
275 PROFILE_STOP(
"sirius::Atom::generate_radial_integrals|interp");
277 PROFILE(
"sirius::Atom::generate_radial_integrals|inner");
278 #pragma omp parallel for
279 for (
int j = 0; j < (int)idx_ri.size(1); j++) {
280 result(j) =
inner(rf_spline[idx_ri(0, j)], vrf_spline[idx_ri(1, j)], 2);
293 for (
int i2 = 0; i2 <
type().
indexr().size(); i2++) {
295 for (
int i1 = 0; i1 <= i2; i1++) {
297 if ((l + l1 + l2) % 2 == 0) {
378 for (
int j = 0; j < 3; j++) {
383 inline void sync_radial_integrals(
mpi::Communicator const& comm__,
int const rank__)
391 inline void sync_occupation_matrix(mpi::Communicator
const& comm__,
int const rank__)
396 inline double const* h_radial_integrals(
int idxrf1,
int idxrf2)
const
401 inline double* h_radial_integrals(
int idxrf1,
int idxrf2)
406 inline double const* b_radial_integrals(
int idxrf1,
int idxrf2,
int x)
const
418 template <spin_block_t sblock>
419 inline std::complex<double>
422 std::complex<double> zsum(0, 0);
424 for (
size_t i = 0; i < gnt__.size(); i++) {
445 zsum += gnt__[i].coef * std::complex<double>(
b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 1),
451 zsum += gnt__[i].coef * std::complex<double>(
b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 1),
460 inline int num_mt_points()
const
465 inline Radial_grid<double>
const& radial_grid()
const
467 return type_.radial_grid();
470 inline double radial_grid(
int idx)
const
472 return type_.radial_grid(idx);
475 inline double mt_radius()
const
480 inline int zn()
const
485 inline int mt_basis_size()
const
490 inline int mt_aw_basis_size()
const
492 return type_.mt_aw_basis_size();
495 inline int mt_lo_basis_size()
const
497 return type_.mt_lo_basis_size();
500 inline void set_occupation_matrix(
const std::complex<double>* source)
502 std::memcpy(
occupation_matrix_.at(sddk::memory_t::host), source, 16 * 16 * 2 * 2 *
sizeof(std::complex<double>));
506 inline void get_occupation_matrix(std::complex<double>* destination)
508 std::memcpy(destination,
occupation_matrix_.at(sddk::memory_t::host), 16 * 16 * 2 * 2 *
sizeof(std::complex<double>));
511 inline void set_uj_correction_matrix(
const int l,
const std::complex<double>* source)
514 std::memcpy(
uj_correction_matrix_.at(sddk::memory_t::host), source, 16 * 16 * 2 * 2 *
sizeof(std::complex<double>));
518 inline bool apply_uj_correction()
523 inline int uj_correction_l()
528 inline auto uj_correction_matrix(
int lm1,
int lm2,
int ispn1,
int ispn2)
533 inline double& d_mtrx(
int xi1,
int xi2,
int iv)
538 inline double const& d_mtrx(
int xi1,
int xi2,
int iv)
const
543 inline auto const& d_mtrx()
const
548 inline auto& d_mtrx()
Contains declaration and partial implementation of sirius::Atom_symmetry_class class.
Data and methods specific to the symmetry class of the atom.
double radial_function(int ir, int idx) const
Get a value of the radial functions.
Defines the properties of atom type.
int mt_basis_size() const
Total number of muffin-tin basis functions (APW + LO).
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 id() const
Return atom type id.
Data and methods specific to the actual atom in the unit cell.
int type_id() const
Return atom type id.
std::shared_ptr< Atom_symmetry_class > symmetry_class_
Symmetry class of the given atom.
void set_position(r3::vector< double > position__)
Set atom position in fractional coordinates.
sddk::mdarray< double, 2 > beff_[3]
Muffin-tin magnetic field.
Atom_type const & type_
Type of the given atom.
bool apply_uj_correction_
True if UJ correction is applied for the current atom.
Atom_symmetry_class & symmetry_class()
Return reference to corresponding atom symmetry class.
std::complex< double > radial_integrals_sum_L3(int idxrf1__, int idxrf2__, std::vector< gaunt_L3< std::complex< double > > > const &gnt__) const
Atom_symmetry_class const & symmetry_class() const
Return const referenced to atom symmetry class.
sddk::mdarray< double, 2 > veff_
Muffin-tin potential.
sddk::mdarray< double, 3 > d_mtrx_
Auxiliary form of the D_{ij} operator matrix of the pseudo-potential method.
Atom(Atom_type const &type__, r3::vector< double > position__, r3::vector< double > vector_field__)
Constructor.
void set_symmetry_class(std::shared_ptr< Atom_symmetry_class > symmetry_class__)
Set symmetry class of the atom.
int lmax_pot_
Maximum l for potential and magnetic field.
void generate_radial_integrals(sddk::device_t pu__, mpi::Communicator const &comm__)
Generate radial Hamiltonian and effective magnetic field integrals.
void init()
Initialize atom.
sddk::mdarray< std::complex< double >, 4 > occupation_matrix_
Unsymmetrized (sampled over IBZ) occupation matrix of the L(S)DA+U method.
void set_nonspherical_potential(double *veff__, double *beff__[3])
Set muffin-tin potential and magnetic field.
sddk::mdarray< double, 3 > h_radial_integrals_
Radial integrals of the Hamiltonian.
r3::vector< double > position_
Position in fractional coordinates.
sddk::mdarray< std::complex< double >, 4 > uj_correction_matrix_
U,J correction matrix of the L(S)DA+U method.
sddk::mdarray< double, 4 > b_radial_integrals_
Radial integrals of the effective magnetic field.
Atom_type const & type() const
Return const reference to corresponding atom type object.
auto vector_field() const
Return vector field.
r3::vector< double > const & position() const
Return atom position in fractional coordinates.
int uj_correction_l_
Orbital quantum number for UJ correction.
int symmetry_class_id() const
Return id of the symmetry class.
r3::vector< double > vector_field_
Vector field associated with the current site.
Helper class to wrap stream id (integer number).
MPI communicator wrapper.
void bcast(T *buffer__, int count__, int root__) const
Perform buffer broadcast.
int size() const
Size of the communicator (number of ranks).
int rank() const
Rank of MPI process inside communicator.
void copy_to(memory_t mem__, size_t idx0__, size_t n__, acc::stream_id sid=acc::stream_id(-1))
Copy n elements starting from idx0 from one memory type to another.
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
void deallocate(memory_t memory__)
Deallocate host or device memory.
mdarray< T, N > & allocate(memory_t memory__)
Allocate memory for array.
size_t size() const
Return total size (number of elements) of the array.
Contains definition and implementation of sirius::Gaunt class.
device_t
Type of the main processing unit.
void sync()
Synchronize device.
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
int lmmax(int lmax)
Maximum number of combinations for a given .
int lm(int l, int m)
Get composite lm index by angular index l and azimuthal index m.
std::vector< int > l_by_lm(int lmax__)
Get array of orbital quantum numbers for each lm component.
std::enable_if_t< std::is_same< T, real_type< F > >::value, void > inner(::spla::Context &spla_ctx__, sddk::memory_t mem__, spin_range spins__, W const &wf_i__, band_range br_i__, Wave_functions< T > const &wf_j__, band_range br_j__, la::dmatrix< F > &result__, int irow0__, int jcol0__)
Compute inner product between the two sets of wave-functions.
Namespace of the SIRIUS library.
strong_type< int, struct __n_blocks_tag > n_blocks
Number of blocks to which the global index is split.
Contains declaration and implementation of sirius::Spheric_function and sirius::Spheric_function_grad...
Used in the {lm1, lm2} : {lm3, coefficient} way of grouping non-zero Gaunt coefficients.