SIRIUS 7.5.0
Electronic structure library and applications
gvec.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2017 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file gvec.hpp
21 *
22 * \brief Declaration and implementation of Gvec class.
23 */
24
25#ifndef __GVEC_HPP__
26#define __GVEC_HPP__
27
28#include <numeric>
29#include <map>
30#include <iostream>
31#include <limits>
32#include <type_traits>
34#include "core/r3/r3.hpp"
35#include "core/splindex.hpp"
36#include "core/serializer.hpp"
37#include "core/mpi/pstdout.hpp"
38#include "core/rte/rte.hpp"
39#include "core/profiler.hpp"
40#include "SDDK/memory.hpp"
41
42namespace sirius {
43
44namespace fft {
45
46/// Descriptor of the z-column (x,y fixed, z varying) of the G-vectors.
47/** Sphere of G-vectors within a given plane-wave cutoff is represented as a set of z-columns with different lengths. */
49{
50 /// X-coordinate (can be negative and positive).
51 int x;
52 /// Y-coordinate (can be negative and positive).
53 int y;
54 /// Minimum z-coordinate.
55 int z_min;
56 /// Maximum z-coordinate.
57 int z_max;
58 /// List of the Z-coordinates of the column.
59 std::vector<int> z;
60 /// Constructor.
61 z_column_descriptor(int x__, int y__, std::vector<int> z__)
62 : x(x__)
63 , y(y__)
64 , z(z__)
65 {
66 z_min = std::numeric_limits<int>::max();
67 z_max = std::numeric_limits<int>::min();
68 for (auto e : z__) {
69 z_min = std::min(z_min, e);
70 z_max = std::max(z_max, e);
71 }
72 }
73 /// Default constructor.
75 {
76 }
77};
78
79/// Serialize a single z-column descriptor.
80inline void serialize(serializer& s__, z_column_descriptor const& zcol__)
81{
82 serialize(s__, zcol__.x);
83 serialize(s__, zcol__.y);
84 serialize(s__, zcol__.z_min);
85 serialize(s__, zcol__.z_max);
86 serialize(s__, zcol__.z);
87}
88
89/// Deserialize a single z-column descriptor.
90inline void deserialize(serializer& s__, z_column_descriptor& zcol__)
91{
92 deserialize(s__, zcol__.x);
93 deserialize(s__, zcol__.y);
94 deserialize(s__, zcol__.z_min);
95 deserialize(s__, zcol__.z_max);
96 deserialize(s__, zcol__.z);
97}
98
99/// Serialize a vector of z-column descriptors.
100inline void serialize(serializer& s__, std::vector<z_column_descriptor> const& zcol__)
101{
102 serialize(s__, zcol__.size());
103 for (auto& e: zcol__) {
104 serialize(s__, e);
105 }
106}
107
108/// Deserialize a vector of z-column descriptors.
109inline void deserialize(serializer& s__, std::vector<z_column_descriptor>& zcol__)
110{
111 size_t sz;
112 deserialize(s__, sz);
113 zcol__.resize(sz);
114 for (size_t i = 0; i < sz; i++) {
115 deserialize(s__, zcol__[i]);
116 }
117}
118
119/* forward declarations */
120class Gvec;
121void serialize(serializer& s__, Gvec const& gv__);
122void deserialize(serializer& s__, Gvec& gv__);
123Gvec send_recv(mpi::Communicator const& comm__, Gvec const& gv_src__, int source__, int dest__);
124
125/// A set of G-vectors for FFTs and G+k basis functions.
126/** Current implemntation supports up to 2^12 (4096) z-dimension of the FFT grid and 2^20 (1048576) number of
127 * z-columns. The order of z-sticks and G-vectors is not fixed and depends on the number of MPI ranks used
128 * for the parallelization. */
129class Gvec
130{
131 private:
132 /// k-vector of G+k.
134
135 /// Cutoff for |G+k| vectors.
136 double Gmax_{0};
137
138 /// Reciprocal lattice vectors.
140
141 /// Total communicator which is used to distribute G or G+k vectors.
143
144 /// Indicates that G-vectors are reduced by inversion symmetry.
145 bool reduce_gvec_{false};
146
147 /// True if this a list of G-vectors without k-point shift.
148 bool bare_gvec_{true};
149
150 /// Total number of G-vectors.
151 int num_gvec_{0};
152
153 /// Mapping between G-vector index [0:num_gvec_) and a full index.
154 /** Full index is used to store x,y,z coordinates in a packed form in a single integer number.
155 * The index is equal to ((i << 12) + j) where i is the global index of z_column and j is the
156 * index of G-vector z-coordinate in the column i. This is a global array: each MPI rank stores exactly the
157 * same copy of the gvec_full_index_.
158 *
159 * Limitations: size of z-dimension of FFT grid: 4096, number of z-columns: 1048576
160 */
162
163 /// Index of the shell to which the given G-vector belongs.
165
166 /// Number of G-vector shells (groups of G-vectors with the same length).
168
169 /// Radii (or lengths) of G-vector shells in a.u.^-1.
171
172 /// Local number of G-vector shells for the local number of G-vectors.
173 /** G-vectors are distributed by sticks, not by G-shells. This means that each rank stores local fraction of
174 G-vectors with a non-consecutive G-shell index and not all G-shells are present at a given rank. This
175 variable stores the number of G-shells which this rank holds. */
177
178 /// Radii of G-vector shells in the local index counting [0, num_gvec_shells_local)
179 std::vector<double> gvec_shell_len_local_;
180
181 /// Mapping between local index of G-vector and local G-shell index.
182 std::vector<int> gvec_shell_idx_local_;
183
184 sddk::mdarray<int, 3> gvec_index_by_xy_;
185
186 /// Global list of non-zero z-columns.
187 std::vector<z_column_descriptor> z_columns_;
188
189 /// Fine-grained distribution of G-vectors.
191
192 /// Fine-grained distribution of z-columns.
194
195 /// Set of G-vectors on which the current G-vector distribution can be based.
196 /** This can be used to establish a local mapping between coarse and fine G-vector sets
197 * without MPI communication. */
198 Gvec const* gvec_base_{nullptr};
199
200 /// Mapping between current and base G-vector sets.
201 /** This mapping allows for a local-to-local copy of PW coefficients without any MPI communication.
202
203 Example:
204 \code{.cpp}
205 // Copy from a coarse G-vector set.
206 for (int igloc = 0; igloc < ctx_.gvec_coarse().count(); igloc++) {
207 rho_vec_[j]->f_pw_local(ctx_.gvec().gvec_base_mapping(igloc)) = rho_mag_coarse_[j]->f_pw_local(igloc);
208 }
209 \endcode
210 */
212
213 /// Lattice coordinates of a local set of G-vectors.
214 /** This are also known as Miller indices */
216
217 /// Lattice coordinates of a local set of G+k-vectors.
219
220 /// Cartiesian coordinaes of a local set of G-vectors.
222
223 /// Cartesian coordinaes of a local set of G+k-vectors.
225
226 /// Length of the local fraction of G-vectors.
228
229 // Theta- and phi- angles of G-vectors.
231
232 // Theta- and phi- angles of G+k-vectors.
233 sddk::mdarray<double, 2> gkvec_tp_;
234
235 /// Offset in the global index for the local part of G-vectors.
236 int offset_{-1};
237
238 /// Local number of G-vectors.
239 int count_{-1};
240
241 /// Local number of z-columns.
243
244 /// Symmetry tolerance of the real-space lattice.
245 double sym_tol_{1e-6};
246
247 /// Return corresponding G-vector for an index in the range [0, num_gvec).
248 r3::vector<int> gvec_by_full_index(uint32_t idx__) const;
249
250 /// Find z-columns of G-vectors inside a sphere with Gmax radius.
251 /** This function also computes the total number of G-vectors. */
252 void find_z_columns(double Gmax__, fft::Grid const& fft_box__);
253
254 /// Distribute z-columns between MPI ranks.
256
257 /// Find a list of G-vector shells.
258 /** G-vectors belonging to the same shell have the same length and transform to each other
259 under a lattice symmetry operation. */
260 void find_gvec_shells();
261
262 /// Initialize lattice coordinates of the local fraction of G-vectors.
263 void init_gvec_local();
264
265 /// Initialize Cartesian coordinates of the local fraction of G-vectors.
267
268 /// Initialize everything.
269 void init(fft::Grid const& fft_grid);
270
271 friend void serialize(serializer& s__, Gvec const& gv__);
272
273 friend void deserialize(serializer& s__, Gvec& gv__);
274
275 /* copy constructor is forbidden */
276 Gvec(Gvec const& src__) = delete;
277
278 /* copy assignment operator is forbidden */
279 Gvec& operator=(Gvec const& src__) = delete;
280
281 public:
282 /// Constructor for G+k vectors.
283 /** \param [in] vk K-point vector of G+k
284 * \param [in] M Reciprocal lattice vectors in column order
285 * \param [in] Gmax Cutoff for G+k vectors
286 * \param [in] comm Total communicator which is used to distribute G-vectors
287 * \param [in] reduce_gvec True if G-vectors need to be reduced by inversion symmetry.
288 * \param [in] sym_tol Unit cell lattice symmetry tolerance.
289 */
290 Gvec(r3::vector<double> vk__, r3::matrix<double> M__, double Gmax__, mpi::Communicator const& comm__,
291 bool reduce_gvec__, double sym_tol__ = 1e-6)
292 : vk_{vk__}
293 , Gmax_{Gmax__}
294 , lattice_vectors_{M__}
295 , comm_{comm__}
296 , reduce_gvec_{reduce_gvec__}
297 , bare_gvec_{false}
298 , sym_tol_{sym_tol__}
299 {
300 init(fft::get_min_grid(Gmax__, M__));
301 }
302
303 /// Constructor for G-vectors.
304 /** \param [in] M Reciprocal lattice vectors in column order
305 * \param [in] Gmax Cutoff for G+k vectors
306 * \param [in] comm Total communicator which is used to distribute G-vectors
307 * \param [in] reduce_gvec True if G-vectors need to be reduced by inversion symmetry.
308 * \param [in] sym_tol Unit cell lattice symmetry tolerance.
309 */
310 Gvec(r3::matrix<double> M__, double Gmax__, mpi::Communicator const& comm__, bool reduce_gvec__,
311 double sym_tol__ = 1e-6)
312 : Gmax_{Gmax__}
313 , lattice_vectors_{M__}
314 , comm_{comm__}
315 , reduce_gvec_{reduce_gvec__}
316 , sym_tol_{sym_tol__}
317 {
318 init(fft::get_min_grid(Gmax__, M__));
319 }
320
321 /// Constructor for G-vectors.
322 /** \param [in] M Reciprocal lattice vectors in column order
323 * \param [in] Gmax Cutoff for G+k vectors
324 * \param [in] fft_grid Provide explicit boundaries for the G-vector min and max frequencies.
325 * \param [in] comm Total communicator which is used to distribute G-vectors
326 * \param [in] reduce_gvec True if G-vectors need to be reduced by inversion symmetry.
327 * \param [in] sym_tol Unit cell lattice symmetry tolerance.
328 */
329 Gvec(r3::matrix<double> M__, double Gmax__, fft::Grid const& fft_grid__, mpi::Communicator const& comm__,
330 bool reduce_gvec__, double sym_tol__ = 1e-6)
331 : Gmax_{Gmax__}
332 , lattice_vectors_{M__}
333 , comm_{comm__}
334 , reduce_gvec_{reduce_gvec__}
335 , sym_tol_{sym_tol__}
336 {
337 init(fft_grid__);
338 }
339
340 /// Constructor for G-vector distribution based on a previous set.
341 /** Previous set of G-vectors must be a subset of the current set. */
342 Gvec(double Gmax__, Gvec const& gvec_base__)
343 : Gmax_{Gmax__}
345 , comm_{gvec_base__.comm()}
346 , reduce_gvec_{gvec_base__.reduced()}
347 , gvec_base_{&gvec_base__}
348 , sym_tol_{gvec_base__.sym_tol_}
349 {
351 }
352
353 /// Constructor for G-vectors with mpi_comm_self()
354 Gvec(r3::matrix<double> M__, double Gmax__, bool reduce_gvec__, double sym_tol__ = 1e-6)
355 : Gmax_{Gmax__}
356 , lattice_vectors_{M__}
357 , comm_{mpi::Communicator::self()}
358 , reduce_gvec_{reduce_gvec__}
359 , sym_tol_{sym_tol__}
360 {
361 init(fft::get_min_grid(Gmax__, M__));
362 }
363
364 /// Construct with the defined order of G-vectors.
365 Gvec(r3::vector<double> vk__, r3::matrix<double> M__, int ngv_loc__, int const* gv__,
366 mpi::Communicator const& comm__, bool reduce_gvec__)
367 : vk_(vk__)
368 , lattice_vectors_(M__)
369 , comm_(comm__)
370 , reduce_gvec_(reduce_gvec__)
371 , bare_gvec_(false)
372 , count_(ngv_loc__)
373 {
374 sddk::mdarray<int, 2> G(const_cast<int*>(gv__), 3, ngv_loc__);
375
376 gvec_ = sddk::mdarray<int, 2>(3, count(), sddk::memory_t::host, "gvec_");
377 gkvec_ = sddk::mdarray<double, 2>(3, count(), sddk::memory_t::host, "gkvec_");
378
379 /* do a first pass: determine boundaries of the grid */
380 int xmin{0}, xmax{0};
381 int ymin{0}, ymax{0};
382 for (int i = 0; i < ngv_loc__; i++) {
383 xmin = std::min(xmin, G(0, i));
384 xmax = std::max(xmax, G(0, i));
385 ymin = std::min(ymin, G(1, i));
386 ymax = std::max(ymax, G(1, i));
387 }
388 comm_.allreduce<int, mpi::op_t::min>(&xmin, 1);
389 comm_.allreduce<int, mpi::op_t::min>(&ymin, 1);
390 comm_.allreduce<int, mpi::op_t::max>(&xmax, 1);
391 comm_.allreduce<int, mpi::op_t::max>(&ymax, 1);
392
394 zcol.zero();
395 for (int ig = 0; ig < ngv_loc__; ig++) {
396 zcol(G(0, ig), G(1, ig))++;
397 for (int x : {0, 1, 2}) {
398 gvec_(x, ig) = G(x, ig);
399 gkvec_(x, ig) = G(x, ig) + vk_[x];
400 }
401 }
402 num_zcol_local_ = 0;
403 for (size_t i = 0; i < zcol.size(); i++) {
404 if (zcol[i]) {
406 }
407 }
408
410
412 comm().allgather(&count_, gvec_distr_.counts.data(), 1, comm_.rank());
413 gvec_distr_.calc_offsets();
414 offset_ = gvec_distr_.offsets[comm().rank()];
415
417 comm().allgather(&num_zcol_local_, zcol_distr_.counts.data(), 1, comm_.rank());
418 zcol_distr_.calc_offsets();
419
421 comm().allreduce(&num_gvec_, 1);
422 }
423
424 /// Constructor for empty set of G-vectors.
425 Gvec(mpi::Communicator const& comm__)
426 : comm_(comm__)
427 {
428 }
429
430 /// Move assignment operator.
431 Gvec& operator=(Gvec&& src__) = default;
432
433 /// Move constructor.
434 Gvec(Gvec&& src__) = default;
435
436 inline auto const& vk() const
437 {
438 return vk_;
439 }
440
441 inline mpi::Communicator const& comm() const
442 {
443 return comm_;
444 }
445
446 /// Set the new reciprocal lattice vectors.
447 /** For the varibale-cell relaxation runs we need an option to preserve the number of G- and G+k vectors.
448 * Here we can set the new lattice vectors and update the relevant members of the Gvec class. */
449 inline auto const& lattice_vectors(r3::matrix<double> lattice_vectors__)
450 {
451 lattice_vectors_ = lattice_vectors__;
454 return lattice_vectors_;
455 }
456
457 /// Retrn a const reference to the reciprocal lattice vectors.
458 inline auto const& lattice_vectors() const
459 {
460 return lattice_vectors_;
461 }
462
463 inline auto const unit_cell_lattice_vectors() const
464 {
465 double const twopi = 6.2831853071795864769;
467 return r;
468 }
469
470 /// Return the volume of the real space unit cell that corresponds to the reciprocal lattice of G-vectors.
471 inline double omega() const
472 {
473 double const twopi_pow3 = 248.050213442398561403810520537;
474 return twopi_pow3 / std::abs(lattice_vectors().det());
475 }
476
477 /// Return the total number of G-vectors within the cutoff.
478 inline int num_gvec() const
479 {
480 return num_gvec_;
481 }
482
483 /// Number of z-columns for a fine-grained distribution.
484 inline int zcol_count(int rank__) const
485 {
486 RTE_ASSERT(rank__ < comm().size());
487 return zcol_distr_.counts[rank__];
488 }
489
490 /// Offset in the global index of z-columns for a given rank.
491 inline int zcol_offset(int rank__) const
492 {
493 RTE_ASSERT(rank__ < comm().size());
494 return zcol_distr_.offsets[rank__];
495 }
496
497 /// Number of G-vectors for a fine-grained distribution.
498 inline int gvec_count(int rank__) const
499 {
500 RTE_ASSERT(rank__ < comm().size());
501 return gvec_distr_.counts[rank__];
502 }
503
504 /// Number of G-vectors for a fine-grained distribution for the current MPI rank.
505 /** The \em count and \em offset are borrowed from the MPI terminology for data distribution. */
506 inline int count() const
507 {
508 return count_;
509 }
510
511 /// Offset (in the global index) of G-vectors for a fine-grained distribution.
512 inline int gvec_offset(int rank__) const
513 {
514 RTE_ASSERT(rank__ < comm().size());
515 return gvec_distr_.offsets[rank__];
516 }
517
518 /// Offset (in the global index) of G-vectors for a fine-grained distribution for a current MPI rank.
519 /** The \em count and \em offset are borrowed from the MPI terminology for data distribution. */
520 inline int offset() const
521 {
522 return offset_;
523 }
524
525 /// Local starting index of G-vectors if G=0 is not counted.
526 inline int skip_g0() const
527 {
528 return (comm().rank() == 0) ? 1 : 0;
529 }
530
531 /// Return number of G-vector shells.
532 inline int num_shells() const
533 {
534 return num_gvec_shells_;
535 }
536
537 /// Return G vector in fractional coordinates.
538 template <index_domain_t idx_t>
539 inline r3::vector<int>
540 gvec(int ig__) const
541 {
542 switch (idx_t) {
544 return r3::vector<int>(gvec_(0, ig__), gvec_(1, ig__), gvec_(2, ig__));
545 break;
546 }
549 break;
550 }
551 }
552 }
553
554 /// Return G+k vector in fractional coordinates.
555 template <index_domain_t idx_t>
556 inline r3::vector<double>
557 gkvec(int ig__) const
558 {
559 switch (idx_t) {
561 return r3::vector<double>(gkvec_(0, ig__), gkvec_(1, ig__), gkvec_(2, ig__));
562 break;
563 }
565 return this->gvec<idx_t>(ig__) + vk_;
566 break;
567 }
568 }
569 }
570
571 /// Return G vector in Cartesian coordinates.
572 template <index_domain_t idx_t>
573 inline r3::vector<double>
574 gvec_cart(int ig__) const
575 {
576 switch (idx_t) {
578 return r3::vector<double>(gvec_cart_(0, ig__), gvec_cart_(1, ig__), gvec_cart_(2, ig__));
579 break;
580 }
582 auto G = this->gvec<idx_t>(ig__);
583 return dot(lattice_vectors_, G);
584 break;
585 }
586 }
587 }
588
589 /// Return G+k vector in fractional coordinates.
590 template <index_domain_t idx_t>
591 inline r3::vector<double>
592 gkvec_cart(int ig__) const
593 {
594 switch (idx_t) {
596 return r3::vector<double>(gkvec_cart_(0, ig__), gkvec_cart_(1, ig__), gkvec_cart_(2, ig__));
597 break;
598 }
600 auto Gk = this->gvec<idx_t>(ig__) + vk_;
601 return dot(lattice_vectors_, Gk);
602 break;
603 }
604 }
605 }
606
607 /// Return index of the G-vector shell by the G-vector index.
608 inline int shell(int ig__) const
609 {
610 return gvec_shell_(ig__);
611 }
612
613 inline int shell(r3::vector<int> const& G__) const
614 {
615 return this->shell(index_by_gvec(G__));
616 }
617
618 /// Return length of the G-vector shell.
619 inline double shell_len(int igs__) const
620 {
621 return gvec_shell_len_(igs__);
622 }
623
624 /// Get lengths of all G-vector shells.
625 std::vector<double> shells_len() const
626 {
627 std::vector<double> q(this->num_shells());
628 for (int i = 0; i < this->num_shells(); i++) {
629 q[i] = this->shell_len(i);
630 }
631 return q;
632 }
633
634 /// Return length of the G-vector.
635 template <index_domain_t idx_t>
636 inline double
637 gvec_len(int ig__) const
638 {
639 switch (idx_t) {
641 return gvec_len_(ig__);
642 break;
643 }
645 return gvec_shell_len_(gvec_shell_(ig__));
646 break;
647 }
648 }
649 }
650
651 inline int index_g12(r3::vector<int> const& g1__, r3::vector<int> const& g2__) const
652 {
653 auto v = g1__ - g2__;
654 int idx = index_by_gvec(v);
655 RTE_ASSERT(idx >= 0);
656 RTE_ASSERT(idx < num_gvec());
657 return idx;
658 }
659
660 std::pair<int, bool> index_g12_safe(r3::vector<int> const& g1__, r3::vector<int> const& g2__) const;
661
662 //inline int index_g12_safe(int ig1__, int ig2__) const
663 //{
664 // STOP();
665 // return 0;
666 //}
667
668 /// Return a global G-vector index in the range [0, num_gvec) by the G-vector.
669 /** The information about a G-vector index is encoded by two numbers: a starting index for the
670 * column of G-vectors and column's size. Depending on the geometry of the reciprocal lattice,
671 * z-columns may have only negative, only positive or both negative and positive frequencies for
672 * a given x and y. This information is used to compute the offset which is added to the starting index
673 * in order to get a full G-vector index. Check find_z_columns() to see how the z-columns are found and
674 * added to the list of columns. */
675 int index_by_gvec(r3::vector<int> const& G__) const;
676
677 inline bool reduced() const
678 {
679 return reduce_gvec_;
680 }
681
682 inline bool bare() const
683 {
684 return bare_gvec_;
685 }
686
687 /// Return global number of z-columns.
688 inline int num_zcol() const
689 {
690 return static_cast<int>(z_columns_.size());
691 }
692
693 /// Return local number of z-columns.
694 inline int num_zcol_local() const
695 {
696 return num_zcol_local_;
697 }
698
699 inline z_column_descriptor const& zcol(size_t idx__) const
700 {
701 return z_columns_[idx__];
702 }
703
704 inline int gvec_base_mapping(int igloc_base__) const
705 {
706 RTE_ASSERT(gvec_base_ != nullptr);
707 return gvec_base_mapping_(igloc_base__);
708 }
709
710 inline int num_gvec_shells_local() const
711 {
713 }
714
715 inline double gvec_shell_len_local(int idx__) const
716 {
717 return gvec_shell_len_local_[idx__];
718 }
719
720 inline int gvec_shell_idx_local(int igloc__) const
721 {
722 return gvec_shell_idx_local_[igloc__];
723 }
724
725 /// Return local list of G-vectors.
726 inline auto const& gvec_local() const
727 {
728 return gvec_;
729 }
730
731 /// Return local list of G-vectors for a given rank.
732 /** This function must be called by all MPI ranks of the G-vector communicator. */
733 inline auto gvec_local(int rank__) const
734 {
735 int ngv = this->count();
736 this->comm().bcast(&ngv, 1, rank__);
737 sddk::mdarray<int, 2> result(3, ngv);
738 if (this->comm().rank() == rank__) {
739 RTE_ASSERT(ngv == this->count());
740 copy(this->gvec_, result);
741 }
742 this->comm().bcast(&result(0, 0), 3 * ngv, rank__);
743 return result;
744 }
745
746 inline auto& gvec_tp()
747 {
748 return gvec_tp_;
749 }
750
751 inline auto const& gvec_tp() const
752 {
753 return gvec_tp_;
754 }
755
756 inline auto& gkvec_tp()
757 {
758 return gkvec_tp_;
759 }
760
761 inline auto const& gkvec_tp() const
762 {
763 return gkvec_tp_;
764 }
765};
766
767/// Stores information about G-vector partitioning between MPI ranks for the FFT transformation.
768/** FFT driver works with a small communicator. G-vectors are distributed over the entire communicator which is
769 larger than the FFT communicator. In order to transform the functions, G-vectors must be redistributed to the
770 FFT-friendly "fat" slabs based on the FFT communicator size. */
772{
773 private:
774 /// Reference to the G-vector instance.
775 Gvec const& gvec_;
776
777 /// Communicator for the FFT.
779
780 /// Communicator which is orthogonal to FFT communicator.
782
783 /// Distribution of G-vectors for FFT.
785
786 /// Local number of z-columns.
788
789 /// Distribution of G-vectors inside FFT-friendly "fat" slab.
791
792 /// Mapping of MPI ranks used to split G-vectors to a 2D grid.
794
795 /// Lattice coordinates of a local set of G-vectors.
796 /** These are also known as Miller indices */
798
799 /// Cartesian coordinaes of a local set of G+k-vectors.
801
802 void build_fft_distr();
803
804 /// Stack together the G-vector slabs to make a larger ("fat") slab for a FFT driver.
805 void pile_gvec();
806
807 public:
808 Gvec_fft(Gvec const& gvec__, mpi::Communicator const& fft_comm__, mpi::Communicator const& comm_ortho_fft__);
809
810 /// Return FFT communicator
811 inline mpi::Communicator const& comm_fft() const
812 {
813 return comm_fft_;
814 }
815
816 /// Return a communicator that is orthogonal to the FFT communicator.
817 inline mpi::Communicator const& comm_ortho_fft() const
818 {
819 return comm_ortho_fft_;
820 }
821
822 /// Local number of G-vectors in the FFT distribution for a given rank.
823 inline int count(int rank__) const
824 {
825 return gvec_distr_fft_.counts[rank__];
826 }
827
828 /// Local number of G-vectors for FFT-friendly distribution for this rank.
829 inline int count() const
830 {
831 return this->count(comm_fft().rank());
832 }
833
834 /// Return local number of z-columns.
835 inline int zcol_count() const
836 {
837 return num_zcol_local_;
838 }
839
840 /// Represents a "fat" slab of G-vectors in the FFT-friendly distribution.
841 inline auto const& gvec_slab() const
842 {
843 return gvec_fft_slab_;
844 }
845
846 /// Return the original (not reshuffled) G-vector class.
847 inline Gvec const& gvec() const
848 {
849 return gvec_;
850 }
851
852 /// Return the Cartesian coordinates of the local G-vector.
853 inline auto gkvec_cart(int igloc__) const
854 {
855 return r3::vector<double>(&gkvec_cart_array_(0, igloc__));
856 }
857
858 /// Return the full array of the local G-vector Cartesian coodinates.
859 inline auto const& gvec_array() const
860 {
861 return gvec_array_;
862 }
863
864 template <typename T> // TODO: document
865 void gather_pw_fft(std::complex<T> const* f_pw_local__, std::complex<T>* f_pw_fft__) const
866 {
867 int rank = gvec().comm().rank();
868 /* collect scattered PW coefficients */
869 comm_ortho_fft().allgather(f_pw_local__, gvec().gvec_count(rank), f_pw_fft__, gvec_slab().counts.data(),
870 gvec_slab().offsets.data());
871
872 }
873
874 template <typename T> // TODO: document
875 void gather_pw_global(std::complex<T> const* f_pw_fft__, std::complex<T>* f_pw_global__) const
876 {
877 for (int ig = 0; ig < gvec().count(); ig++) {
878 /* position inside fft buffer */
879 int ig1 = gvec_slab().offsets[comm_ortho_fft().rank()] + ig;
880 f_pw_global__[gvec().offset() + ig] = f_pw_fft__[ig1];
881 }
882 gvec().comm().allgather(&f_pw_global__[0], gvec().count(), gvec().offset());
883 }
884
885 template<typename T>
886 void scatter_pw_global(std::complex<T> const* f_pw_global__, std::complex<T>* f_pw_fft__) const
887 {
888 for (int i = 0; i < comm_ortho_fft_.size(); i++) {
889 /* offset in global index */
890 int offset = this->gvec_.gvec_offset(rank_map_(comm_fft_.rank(), i));
891 for (int ig = 0; ig < gvec_fft_slab_.counts[i]; ig++) {
892 f_pw_fft__[gvec_fft_slab_.offsets[i] + ig] = f_pw_global__[offset + ig];
893 }
894 }
895 }
896
897 /// Update Cartesian coordinates after a change in lattice vectors.
899 {
900 for (int ig = 0; ig < this->count(); ig++) {
901 auto G = r3::vector<int>(&gvec_array_(0, ig));
902 auto Gkc = dot(this->gvec_.lattice_vectors(), G + this->gvec_.vk());
903 for (int x : {0, 1, 2}) {
904 gkvec_cart_array_(x, ig) = Gkc[x];
905 }
906 }
907 }
908};
909
910/// Helper class to manage G-vector shells and redistribute G-vectors for symmetrization.
911/** G-vectors are remapped from default distribution which balances both the local number
912 of z-columns and G-vectors to the distribution of G-vector shells in which each MPI rank stores
913 local set of complete G-vector shells such that the "rotated" G-vector remains on the same MPI rank.
914 */
916{
917 private:
918 /// Sending counts and offsets.
920
921 /// Receiving counts and offsets.
923
924 /// Split global index of G-shells between MPI ranks.
926
927 /// List of G-vectors in the remapped storage.
929
930 /// Mapping between index of local G-vector and global index of G-vector shell.
932
933 /// Alias for the G-vector communicator.
935
936 Gvec const& gvec_;
937
938 /// A mapping between G-vector and it's local index in the new distribution.
939 std::map<r3::vector<int>, int> idx_gvec_;
940
941 public:
942
943 Gvec_shells(Gvec const& gvec__);
944
945 inline void print_gvec(std::ostream& out__) const
946 {
947 mpi::pstdout pout(gvec_.comm());
948 pout << "rank: " << gvec_.comm().rank() << std::endl;
949 pout << "-- list of G-vectors in the remapped distribution --" << std::endl;
950 for (int igloc = 0; igloc < gvec_count_remapped(); igloc++) {
951 auto G = gvec_remapped(igloc);
952
953 int igsh = gvec_shell_remapped(igloc);
954 pout << "igloc=" << igloc << " igsh=" << igsh << " G=" << G[0] << " " << G[1] << " " << G[2] << std::endl;
955 }
956 pout << "-- reverse list --" << std::endl;
957 for (auto const& e: idx_gvec_) {
958 pout << "G=" << e.first[0] << " " << e.first[1] << " " << e.first[2] << ", igloc=" << e.second << std::endl;
959 }
960 out__ << pout.flush(0);
961 }
962
963 /// Local number of G-vectors in the remapped distribution with complete shells on each rank.
965 {
966 return a2a_recv_.size();
967 }
968
969 /// G-vector by local index (in the remapped set).
971 {
972 return r3::vector<int>(gvec_remapped_(0, igloc__), gvec_remapped_(1, igloc__), gvec_remapped_(2, igloc__));
973 }
974
975 /// Return local index of the G-vector in the remapped set.
977 {
978 if (idx_gvec_.count(G__)) {
979 return idx_gvec_.at(G__);
980 } else {
981 return -1;
982 }
983 }
984
985 /// Index of the G-vector shell by the local G-vector index (in the remapped set).
986 int gvec_shell_remapped(int igloc__) const
987 {
988 return gvec_shell_remapped_(igloc__);
989 }
990
991 template <typename T>
992 auto remap_forward(T* data__) const
993 {
994 PROFILE("fft::Gvec_shells::remap_forward");
995
996 std::vector<T> send_buf(gvec_.count());
997 std::vector<int> counts(comm_.size(), 0);
998 for (int igloc = 0; igloc < gvec_.count(); igloc++) {
999 int ig = gvec_.offset() + igloc;
1000 int igsh = gvec_.shell(ig);
1001 int r = spl_num_gsh_.location(igsh).ib;
1002 send_buf[a2a_send_.offsets[r] + counts[r]] = data__[igloc];
1003 counts[r]++;
1004 }
1005
1006 std::vector<T> recv_buf(gvec_count_remapped());
1007
1008 comm_.alltoall(send_buf.data(), a2a_send_.counts.data(), a2a_send_.offsets.data(), recv_buf.data(),
1009 a2a_recv_.counts.data(), a2a_recv_.offsets.data());
1010
1011 return recv_buf;
1012 }
1013
1014 template <typename T>
1015 void remap_backward(std::vector<T> buf__, T* data__) const
1016 {
1017 PROFILE("fft::Gvec_shells::remap_backward");
1018
1019 std::vector<T> recv_buf(gvec_.count());
1020
1021 comm_.alltoall(buf__.data(), a2a_recv_.counts.data(), a2a_recv_.offsets.data(), recv_buf.data(),
1022 a2a_send_.counts.data(), a2a_send_.offsets.data());
1023
1024 std::vector<int> counts(comm_.size(), 0);
1025 for (int igloc = 0; igloc < gvec_.count(); igloc++) {
1026 int ig = gvec_.offset() + igloc;
1027 int igsh = gvec_.shell(ig);
1028 int r = spl_num_gsh_.location(igsh).ib;
1029 data__[igloc] = recv_buf[a2a_send_.offsets[r] + counts[r]];
1030 counts[r]++;
1031 }
1032 }
1033
1034 inline Gvec const& gvec() const
1035 {
1036 return gvec_;
1037 }
1038};
1039
1040/// This is only for debug purpose.
1041inline std::shared_ptr<Gvec>
1042gkvec_factory(double gk_cutoff__, mpi::Communicator const& comm__)
1043{
1044 auto M = r3::matrix<double>({{1, 0, 0}, {0, 1, 0}, {0, 0, 1}});
1045 return std::make_shared<Gvec>(r3::vector<double>({0, 0, 0}), M, gk_cutoff__, comm__, false);
1046}
1047
1048inline std::shared_ptr<Gvec>
1049gkvec_factory(r3::vector<double> vk__, r3::matrix<double> reciprocal_lattice_vectors__, double gk_cutoff__,
1050 mpi::Communicator const& comm__ = mpi::Communicator::self(), bool gamma__ = false)
1051{
1052 return std::make_shared<Gvec>(vk__, reciprocal_lattice_vectors__, gk_cutoff__, comm__, gamma__);
1053}
1054
1055inline void print(std::ostream& out__, Gvec const& gvec__)
1056{
1057 std::map<int, std::vector<int>> gsh_map;
1058 for (int i = 0; i < gvec__.num_gvec(); i++) {
1059 int igsh = gvec__.shell(i);
1060 if (gsh_map.count(igsh) == 0) {
1061 gsh_map[igsh] = std::vector<int>();
1062 }
1063 gsh_map[igsh].push_back(i);
1064 }
1065
1066 out__ << "num_gvec : " << gvec__.num_gvec() << std::endl;
1067 out__ << "num_gvec_shells : " << gvec__.num_shells() << std::endl;
1068
1069 for (int igsh = 0; igsh < gvec__.num_shells(); igsh++) {
1070 auto len = gvec__.shell_len(igsh);
1071 out__ << "shell : " << igsh << ", length : " << len << std::endl;
1072 for (auto ig : gsh_map[igsh]) {
1073 auto G = gvec__.gvec<index_domain_t::global>(ig);
1074 auto Gc = gvec__.gvec_cart<index_domain_t::global>(ig);
1075 out__ << " ig : " << ig << ", G = " << G << ", length diff : " << std::abs(Gc.length() - len) << std::endl;
1076 }
1077 }
1078 //mpi::pstdout pout(gvec__.comm());
1079 //pout << "rank: " << gvec_.comm().rank() << std::endl;
1080 //pout << "-- list of G-vectors in the remapped distribution --" << std::endl;
1081 //for (int igloc = 0; igloc < gvec_count_remapped(); igloc++) {
1082 // auto G = gvec_remapped(igloc);
1083
1084 // int igsh = gvec_shell_remapped(igloc);
1085 // pout << "igloc=" << igloc << " igsh=" << igsh << " G=" << G[0] << " " << G[1] << " " << G[2] << std::endl;
1086 //}
1087 //pout << "-- reverse list --" << std::endl;
1088 //for (auto const& e: idx_gvec_) {
1089 // pout << "G=" << e.first[0] << " " << e.first[1] << " " << e.first[2] << ", igloc=" << e.second << std::endl;
1090 //}
1091 //out__ << pout.flush(0);
1092}
1093
1094} // namespace
1095
1096} // namespace sirius
1097
1098#endif //__GVEC_HPP__
Helper class to create FFT grids of given sizes and compute indices in space- and frequency domains.
Definition: fft3d_grid.hpp:38
Stores information about G-vector partitioning between MPI ranks for the FFT transformation.
Definition: gvec.hpp:772
mpi::Communicator const & comm_fft() const
Return FFT communicator.
Definition: gvec.hpp:811
int count() const
Local number of G-vectors for FFT-friendly distribution for this rank.
Definition: gvec.hpp:829
int zcol_count() const
Return local number of z-columns.
Definition: gvec.hpp:835
auto const & gvec_slab() const
Represents a "fat" slab of G-vectors in the FFT-friendly distribution.
Definition: gvec.hpp:841
mpi::block_data_descriptor gvec_fft_slab_
Distribution of G-vectors inside FFT-friendly "fat" slab.
Definition: gvec.hpp:790
int count(int rank__) const
Local number of G-vectors in the FFT distribution for a given rank.
Definition: gvec.hpp:823
mpi::Communicator const & comm_ortho_fft() const
Return a communicator that is orthogonal to the FFT communicator.
Definition: gvec.hpp:817
mpi::Communicator const & comm_ortho_fft_
Communicator which is orthogonal to FFT communicator.
Definition: gvec.hpp:781
sddk::mdarray< int, 2 > rank_map_
Mapping of MPI ranks used to split G-vectors to a 2D grid.
Definition: gvec.hpp:793
sddk::mdarray< double, 2 > gkvec_cart_array_
Cartesian coordinaes of a local set of G+k-vectors.
Definition: gvec.hpp:800
mpi::Communicator const & comm_fft_
Communicator for the FFT.
Definition: gvec.hpp:778
void update_gkvec_cart()
Update Cartesian coordinates after a change in lattice vectors.
Definition: gvec.hpp:898
sddk::mdarray< int, 2 > gvec_array_
Lattice coordinates of a local set of G-vectors.
Definition: gvec.hpp:797
auto const & gvec_array() const
Return the full array of the local G-vector Cartesian coodinates.
Definition: gvec.hpp:859
auto gkvec_cart(int igloc__) const
Return the Cartesian coordinates of the local G-vector.
Definition: gvec.hpp:853
mpi::block_data_descriptor gvec_distr_fft_
Distribution of G-vectors for FFT.
Definition: gvec.hpp:784
Gvec const & gvec_
Reference to the G-vector instance.
Definition: gvec.hpp:775
Gvec const & gvec() const
Return the original (not reshuffled) G-vector class.
Definition: gvec.hpp:847
void pile_gvec()
Stack together the G-vector slabs to make a larger ("fat") slab for a FFT driver.
Definition: gvec.cpp:599
int num_zcol_local_
Local number of z-columns.
Definition: gvec.hpp:787
Helper class to manage G-vector shells and redistribute G-vectors for symmetrization.
Definition: gvec.hpp:916
sddk::mdarray< int, 1 > gvec_shell_remapped_
Mapping between index of local G-vector and global index of G-vector shell.
Definition: gvec.hpp:931
int gvec_count_remapped() const
Local number of G-vectors in the remapped distribution with complete shells on each rank.
Definition: gvec.hpp:964
std::map< r3::vector< int >, int > idx_gvec_
A mapping between G-vector and it's local index in the new distribution.
Definition: gvec.hpp:939
mpi::Communicator const & comm_
Alias for the G-vector communicator.
Definition: gvec.hpp:934
r3::vector< int > gvec_remapped(int igloc__) const
G-vector by local index (in the remapped set).
Definition: gvec.hpp:970
mpi::block_data_descriptor a2a_recv_
Receiving counts and offsets.
Definition: gvec.hpp:922
int gvec_shell_remapped(int igloc__) const
Index of the G-vector shell by the local G-vector index (in the remapped set).
Definition: gvec.hpp:986
splindex_block_cyclic spl_num_gsh_
Split global index of G-shells between MPI ranks.
Definition: gvec.hpp:925
mpi::block_data_descriptor a2a_send_
Sending counts and offsets.
Definition: gvec.hpp:919
sddk::mdarray< int, 2 > gvec_remapped_
List of G-vectors in the remapped storage.
Definition: gvec.hpp:928
int index_by_gvec(r3::vector< int > G__) const
Return local index of the G-vector in the remapped set.
Definition: gvec.hpp:976
A set of G-vectors for FFTs and G+k basis functions.
Definition: gvec.hpp:130
int offset_
Offset in the global index for the local part of G-vectors.
Definition: gvec.hpp:236
int gvec_count(int rank__) const
Number of G-vectors for a fine-grained distribution.
Definition: gvec.hpp:498
int num_zcol() const
Return global number of z-columns.
Definition: gvec.hpp:688
sddk::mdarray< double, 1 > gvec_shell_len_
Radii (or lengths) of G-vector shells in a.u.^-1.
Definition: gvec.hpp:170
mpi::block_data_descriptor zcol_distr_
Fine-grained distribution of z-columns.
Definition: gvec.hpp:193
sddk::mdarray< uint32_t, 1 > gvec_full_index_
Mapping between G-vector index [0:num_gvec_) and a full index.
Definition: gvec.hpp:161
double gvec_len(int ig__) const
Return length of the G-vector.
Definition: gvec.hpp:637
sddk::mdarray< double, 2 > gvec_cart_
Cartiesian coordinaes of a local set of G-vectors.
Definition: gvec.hpp:221
Gvec(r3::matrix< double > M__, double Gmax__, bool reduce_gvec__, double sym_tol__=1e-6)
Constructor for G-vectors with mpi_comm_self()
Definition: gvec.hpp:354
int num_gvec() const
Return the total number of G-vectors within the cutoff.
Definition: gvec.hpp:478
auto gvec_local(int rank__) const
Return local list of G-vectors for a given rank.
Definition: gvec.hpp:733
int num_zcol_local() const
Return local number of z-columns.
Definition: gvec.hpp:694
Gvec(double Gmax__, Gvec const &gvec_base__)
Constructor for G-vector distribution based on a previous set.
Definition: gvec.hpp:342
std::vector< double > gvec_shell_len_local_
Radii of G-vector shells in the local index counting [0, num_gvec_shells_local)
Definition: gvec.hpp:179
int offset() const
Offset (in the global index) of G-vectors for a fine-grained distribution for a current MPI rank.
Definition: gvec.hpp:520
sddk::mdarray< int, 2 > gvec_
Lattice coordinates of a local set of G-vectors.
Definition: gvec.hpp:215
std::vector< z_column_descriptor > z_columns_
Global list of non-zero z-columns.
Definition: gvec.hpp:187
sddk::mdarray< int, 1 > gvec_shell_
Index of the shell to which the given G-vector belongs.
Definition: gvec.hpp:164
int skip_g0() const
Local starting index of G-vectors if G=0 is not counted.
Definition: gvec.hpp:526
Gvec(r3::vector< double > vk__, r3::matrix< double > M__, double Gmax__, mpi::Communicator const &comm__, bool reduce_gvec__, double sym_tol__=1e-6)
Constructor for G+k vectors.
Definition: gvec.hpp:290
sddk::mdarray< int, 1 > gvec_base_mapping_
Mapping between current and base G-vector sets.
Definition: gvec.hpp:211
void distribute_z_columns()
Distribute z-columns between MPI ranks.
Definition: gvec.cpp:208
sddk::mdarray< double, 1 > gvec_len_
Length of the local fraction of G-vectors.
Definition: gvec.hpp:227
r3::vector< double > vk_
k-vector of G+k.
Definition: gvec.hpp:133
int zcol_offset(int rank__) const
Offset in the global index of z-columns for a given rank.
Definition: gvec.hpp:491
int count() const
Number of G-vectors for a fine-grained distribution for the current MPI rank.
Definition: gvec.hpp:506
void find_gvec_shells()
Find a list of G-vector shells.
Definition: gvec.cpp:275
int gvec_offset(int rank__) const
Offset (in the global index) of G-vectors for a fine-grained distribution.
Definition: gvec.hpp:512
Gvec(r3::matrix< double > M__, double Gmax__, fft::Grid const &fft_grid__, mpi::Communicator const &comm__, bool reduce_gvec__, double sym_tol__=1e-6)
Constructor for G-vectors.
Definition: gvec.hpp:329
bool bare_gvec_
True if this a list of G-vectors without k-point shift.
Definition: gvec.hpp:148
int count_
Local number of G-vectors.
Definition: gvec.hpp:239
int num_shells() const
Return number of G-vector shells.
Definition: gvec.hpp:532
double sym_tol_
Symmetry tolerance of the real-space lattice.
Definition: gvec.hpp:245
void init_gvec_cart_local()
Initialize Cartesian coordinates of the local fraction of G-vectors.
Definition: gvec.cpp:388
int num_gvec_shells_local_
Local number of G-vector shells for the local number of G-vectors.
Definition: gvec.hpp:176
auto const & lattice_vectors(r3::matrix< double > lattice_vectors__)
Set the new reciprocal lattice vectors.
Definition: gvec.hpp:449
Gvec(r3::matrix< double > M__, double Gmax__, mpi::Communicator const &comm__, bool reduce_gvec__, double sym_tol__=1e-6)
Constructor for G-vectors.
Definition: gvec.hpp:310
int zcol_count(int rank__) const
Number of z-columns for a fine-grained distribution.
Definition: gvec.hpp:484
mpi::block_data_descriptor gvec_distr_
Fine-grained distribution of G-vectors.
Definition: gvec.hpp:190
r3::vector< int > gvec(int ig__) const
Return G vector in fractional coordinates.
Definition: gvec.hpp:540
sddk::mdarray< double, 2 > gkvec_cart_
Cartesian coordinaes of a local set of G+k-vectors.
Definition: gvec.hpp:224
std::vector< double > shells_len() const
Get lengths of all G-vector shells.
Definition: gvec.hpp:625
bool reduce_gvec_
Indicates that G-vectors are reduced by inversion symmetry.
Definition: gvec.hpp:145
int shell(int ig__) const
Return index of the G-vector shell by the G-vector index.
Definition: gvec.hpp:608
int index_by_gvec(r3::vector< int > const &G__) const
Return a global G-vector index in the range [0, num_gvec) by the G-vector.
Definition: gvec.cpp:518
int num_zcol_local_
Local number of z-columns.
Definition: gvec.hpp:242
int num_gvec_shells_
Number of G-vector shells (groups of G-vectors with the same length).
Definition: gvec.hpp:167
Gvec const * gvec_base_
Set of G-vectors on which the current G-vector distribution can be based.
Definition: gvec.hpp:198
mpi::Communicator comm_
Total communicator which is used to distribute G or G+k vectors.
Definition: gvec.hpp:142
Gvec & operator=(Gvec &&src__)=default
Move assignment operator.
double Gmax_
Cutoff for |G+k| vectors.
Definition: gvec.hpp:136
double omega() const
Return the volume of the real space unit cell that corresponds to the reciprocal lattice of G-vectors...
Definition: gvec.hpp:471
Gvec(r3::vector< double > vk__, r3::matrix< double > M__, int ngv_loc__, int const *gv__, mpi::Communicator const &comm__, bool reduce_gvec__)
Construct with the defined order of G-vectors.
Definition: gvec.hpp:365
r3::vector< double > gvec_cart(int ig__) const
Return G vector in Cartesian coordinates.
Definition: gvec.hpp:574
double shell_len(int igs__) const
Return length of the G-vector shell.
Definition: gvec.hpp:619
sddk::mdarray< double, 2 > gkvec_
Lattice coordinates of a local set of G+k-vectors.
Definition: gvec.hpp:218
Gvec(Gvec &&src__)=default
Move constructor.
auto const & gvec_local() const
Return local list of G-vectors.
Definition: gvec.hpp:726
r3::vector< int > gvec_by_full_index(uint32_t idx__) const
Return corresponding G-vector for an index in the range [0, num_gvec).
Definition: gvec.cpp:34
std::vector< int > gvec_shell_idx_local_
Mapping between local index of G-vector and local G-shell index.
Definition: gvec.hpp:182
void init(fft::Grid const &fft_grid)
Initialize everything.
Definition: gvec.cpp:420
auto const & lattice_vectors() const
Retrn a const reference to the reciprocal lattice vectors.
Definition: gvec.hpp:458
r3::vector< double > gkvec_cart(int ig__) const
Return G+k vector in fractional coordinates.
Definition: gvec.hpp:592
r3::matrix< double > lattice_vectors_
Reciprocal lattice vectors.
Definition: gvec.hpp:139
r3::vector< double > gkvec(int ig__) const
Return G+k vector in fractional coordinates.
Definition: gvec.hpp:557
Gvec(mpi::Communicator const &comm__)
Constructor for empty set of G-vectors.
Definition: gvec.hpp:425
int num_gvec_
Total number of G-vectors.
Definition: gvec.hpp:151
void init_gvec_local()
Initialize lattice coordinates of the local fraction of G-vectors.
Definition: gvec.cpp:372
void find_z_columns(double Gmax__, fft::Grid const &fft_box__)
Find z-columns of G-vectors inside a sphere with Gmax radius.
Definition: gvec.cpp:48
MPI communicator wrapper.
void bcast(T *buffer__, int count__, int root__) const
Perform buffer broadcast.
void allgather(T *buffer__, int const *recvcounts__, int const *displs__) const
In-place MPI_Allgatherv.
int size() const
Size of the communicator (number of ranks).
void allreduce(T *buffer__, int count__) const
Perform the in-place (the output buffer is used as the input buffer) all-to-all reduction.
int rank() const
Rank of MPI process inside communicator.
Parallel standard output.
Definition: pstdout.hpp:42
Index descriptor of mdarray.
Definition: memory.hpp:554
Serialize and deserialize objects.
Definition: serializer.hpp:36
splindex< Index_t >::location_t location(typename Index_t::global idx__) const
Return "local index, rank" pair for a global index.
Definition: splindex.hpp:409
Contains declaration and implementation of sddk::FFT3D_grid class.
Memory management functions and classes.
std::shared_ptr< Gvec > gkvec_factory(double gk_cutoff__, mpi::Communicator const &comm__)
This is only for debug purpose.
Definition: gvec.hpp:1042
void serialize(serializer &s__, std::vector< z_column_descriptor > const &zcol__)
Serialize a vector of z-column descriptors.
Definition: gvec.hpp:100
auto get_min_grid(double cutoff__, r3::matrix< double > M__)
Get the minimum grid that circumscribes the cutoff sphere.
Definition: fft3d_grid.hpp:161
void deserialize(serializer &s__, std::vector< z_column_descriptor > &zcol__)
Deserialize a vector of z-column descriptors.
Definition: gvec.hpp:109
auto transpose(matrix< T > src)
Return transpose of the matrix.
Definition: r3.hpp:445
auto inverse(matrix< int > src)
Return inverse of the integer matrix.
Definition: r3.hpp:475
Namespace of the SIRIUS library.
Definition: sirius.f90:5
@ global
Global index.
const double twopi
Definition: constants.hpp:45
A time-based profiler.
Contains implementation of the parallel standard output.
Simple classes and functions to work with vectors and matrices of the R^3 space.
Eror and warning handling during run-time execution.
Serializer for simple data structures.
Contains definition of sddk::splindex_base and specializations of sddk::splindex class.
Descriptor of the z-column (x,y fixed, z varying) of the G-vectors.
Definition: gvec.hpp:49
z_column_descriptor(int x__, int y__, std::vector< int > z__)
Constructor.
Definition: gvec.hpp:61
std::vector< int > z
List of the Z-coordinates of the column.
Definition: gvec.hpp:59
z_column_descriptor()
Default constructor.
Definition: gvec.hpp:74
int z_min
Minimum z-coordinate.
Definition: gvec.hpp:55
int z_max
Maximum z-coordinate.
Definition: gvec.hpp:57
int y
Y-coordinate (can be negative and positive).
Definition: gvec.hpp:53
int x
X-coordinate (can be negative and positive).
Definition: gvec.hpp:51