SIRIUS 7.5.0
Electronic structure library and applications
smooth_periodic_function.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2019 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 smooth_periodic_function.hpp
21 *
22 * \brief Contains declaration and implementation of sirius::Smooth_periodic_function and
23 * sirius::Smooth_periodic_function_gradient classes.
24 */
25
26#include "core/typedefs.hpp"
27#include "core/fft/fft.hpp"
28#include "core/fft/gvec.hpp"
29#include "core/profiler.hpp"
30#include "SDDK/memory.hpp"
31
32#ifndef __SMOOTH_PERIODIC_FUNCTION_HPP__
33#define __SMOOTH_PERIODIC_FUNCTION_HPP__
34
35namespace sirius {
36
37template <typename T>
38inline void
39check_smooth_periodic_function_ptr(smooth_periodic_function_ptr_t<T> const& ptr__,
40 fft::spfft_transform_type<T> const& spfft__)
41{
42 if (spfft__.dim_x() != ptr__.size_x) {
43 std::stringstream s;
44 s << "x-dimensions don't match" << std::endl
45 << " spfft__.dim_x() : " << spfft__.dim_x() << std::endl
46 << " ptr__.size_x : " << ptr__.size_x;
47 RTE_THROW(s);
48 }
49 if (spfft__.dim_y() != ptr__.size_y) {
50 std::stringstream s;
51 s << "y-dimensions don't match" << std::endl
52 << " spfft__.dim_y() : " << spfft__.dim_y() << std::endl
53 << " ptr__.size_y : " << ptr__.size_y;
54 RTE_THROW(s);
55 }
56 if (ptr__.offset_z < 0) { /* global FFT buffer */
57 if (spfft__.dim_z() != ptr__.size_z) {
58 std::stringstream s;
59 s << "global z-dimensions don't match" << std::endl
60 << " spfft__.dim_z() : " << spfft__.dim_z() << std::endl
61 << " ptr__.size_z : " << ptr__.size_z;
62 RTE_THROW(s);
63 }
64 } else { /* local FFT buffer */
65 if ((spfft__.local_z_length() != ptr__.size_z) || (spfft__.local_z_offset() != ptr__.offset_z)) {
66 RTE_THROW("local z-dimensions don't match");
67 }
68 }
69}
70
71/// Representation of a smooth (Fourier-transformable) periodic function.
72/** The class is designed to handle periodic functions such as density or potential, defined on a regular FFT grid.
73 * The following functionality is provided:
74 * - access to real-space values
75 * - access to plane-wave coefficients
76 * - distribution of plane-wave coefficients over entire communicator
77 * - Fourier transformation using FFT communicator
78 * - gather PW coefficients into global array
79 */
80template <typename T>
82{
83 protected:
84 /// FFT driver.
85 fft::spfft_transform_type<T>* spfft_{nullptr};
86
87 /// Distribution of G-vectors.
88 std::shared_ptr<fft::Gvec_fft> gvecp_{nullptr};
89
90 /// Function on the regular real-space grid.
92
93 /// Local set of plane-wave expansion coefficients.
95
96 /// Storage of the PW coefficients for the FFT transformation.
98
99 /// Gather plane-wave coefficients for the subsequent FFT call.
100 inline void gather_f_pw_fft()
101 {
102 gvecp_->gather_pw_fft(f_pw_local_.at(sddk::memory_t::host), f_pw_fft_.at(sddk::memory_t::host));
103 }
104
105 template <typename F>
106 friend void
108
109 template <typename F>
110 friend void
111 scale(F alpha__, Smooth_periodic_function<F>& x__);
112
113 template <typename F>
114 friend void
115 axpy(F alpha__, Smooth_periodic_function<F> const& x__, Smooth_periodic_function<F>& y__);
116
118 Smooth_periodic_function<T>& operator=(Smooth_periodic_function<T> const& src__) = delete;
119
120 public:
121 /// Default constructor.
123 {
124 }
125
126 /// Constructor.
127 Smooth_periodic_function(fft::spfft_transform_type<T> const& spfft__, std::shared_ptr<fft::Gvec_fft> gvecp__,
128 smooth_periodic_function_ptr_t<T> const* sptr__ = nullptr)
129 : spfft_{const_cast<fft::spfft_transform_type<T>*>(&spfft__)}
130 , gvecp_{gvecp__}
131 {
132 auto& mp = sddk::get_memory_pool(sddk::memory_t::host);
133 /* wrap external pointer */
134 if (sptr__) {
135 check_smooth_periodic_function_ptr(*sptr__, spfft__);
136
137 if (!sptr__->ptr) {
138 RTE_THROW("Input pointer is null");
139 }
140 /* true if input external buffer points to local part of FFT grid */
141 bool is_local_rg = (sptr__->offset_z >= 0);
142
143 int offs = (is_local_rg) ? 0 : spfft__.dim_x() * spfft__.dim_y() * spfft__.local_z_offset();
144 /* wrap the pointer */
145 f_rg_ = sddk::mdarray<T, 1>(&sptr__->ptr[offs], fft::spfft_grid_size_local(spfft__));
146
147 } else {
148 f_rg_ = sddk::mdarray<T, 1>(fft::spfft_grid_size_local(spfft__), mp, "Smooth_periodic_function.f_rg_");
149 }
150 f_rg_.zero();
151
152 f_pw_local_ = sddk::mdarray<std::complex<T>, 1>(gvecp_->gvec().count(), mp,
153 "Smooth_periodic_function.f_pw_local_");
155 if (gvecp_->comm_ortho_fft().size() != 1) {
156 f_pw_fft_ = sddk::mdarray<std::complex<T>, 1>(gvecp_->count(), mp, "Smooth_periodic_function.f_pw_fft_");
157 f_pw_fft_.zero();
158 } else {
159 /* alias to f_pw_local array */
160 f_pw_fft_ = sddk::mdarray<std::complex<T>, 1>(&f_pw_local_[0], gvecp_->gvec().count());
161 }
162 }
164 Smooth_periodic_function<T>& operator=(Smooth_periodic_function<T>&& src__) = default;
165
166 /// Zero the values on the regular real-space grid and plane-wave coefficients.
167 inline void zero()
168 {
169 f_rg_.zero();
171 }
172
173 inline T const& value(int ir__) const
174 {
175 return f_rg_(ir__);
176 }
177
178 inline T& value(int ir__)
179 {
180 return const_cast<T&>(static_cast<Smooth_periodic_function<T> const&>(*this).value(ir__));
181 }
182
183 inline auto values() -> sddk::mdarray<T, 1>&
184 {
185 return f_rg_;
186 }
187
188 inline auto values() const -> const sddk::mdarray<T,1>&
189 {
190 return f_rg_;
191 }
192
193 inline auto f_pw_local(int ig__) -> std::complex<T>&
194 {
195 return f_pw_local_(ig__);
196 }
197
198 inline auto f_pw_local(int ig__) const -> const std::complex<T>&
199 {
200 return f_pw_local_(ig__);
201 }
202
203 inline auto f_pw_local() -> sddk::mdarray<std::complex<T>, 1>&
204 {
205 return f_pw_local_;
206 }
207
208 inline auto f_pw_local() const -> const sddk::mdarray<std::complex<T>, 1>&
209 {
210 return f_pw_local_;
211 }
212
213 inline auto& f_pw_fft(int ig__)
214 {
215 return f_pw_fft_(ig__);
216 }
217
218 /// Return plane-wave coefficient for G=0 component.
219 inline auto f_0() const
220 {
221 std::complex<T> z;
222 if (gvecp_->gvec().comm().rank() == 0) {
223 z = f_pw_local_(0);
224 }
225 gvecp_->gvec().comm().bcast(&z, 1, 0);
226 return z;
227 }
228
229 auto& spfft()
230 {
231 RTE_ASSERT(spfft_ != nullptr);
232 return *spfft_;
233 }
234
235 auto const& spfft() const
236 {
237 RTE_ASSERT(spfft_ != nullptr);
238 return *spfft_;
239 }
240
241 auto& gvec() const
242 {
243 RTE_ASSERT(gvecp_ != nullptr);
244 return gvecp_->gvec();
245 }
246
247 auto gvec_fft() const
248 {
249 return gvecp_;
250 }
251
252 void fft_transform(int direction__)
253 {
254 PROFILE("sirius::Smooth_periodic_function::fft_transform");
255
256 RTE_ASSERT(gvecp_ != nullptr);
257
258 auto frg_ptr = (spfft_->local_slice_size() == 0) ? nullptr : &f_rg_[0];
259
260 switch (direction__) {
261 case 1: {
262 if (gvecp_->comm_ortho_fft().size() != 1) {
264 }
265 spfft_->backward(reinterpret_cast<real_type<T> const*>(f_pw_fft_.at(sddk::memory_t::host)), SPFFT_PU_HOST);
266 fft::spfft_output(*spfft_, frg_ptr);
267 break;
268 }
269 case -1: {
270 fft::spfft_input(*spfft_, frg_ptr);
271 spfft_->forward(SPFFT_PU_HOST, reinterpret_cast<real_type<T>*>(f_pw_fft_.at(sddk::memory_t::host)),
272 SPFFT_FULL_SCALING);
273 if (gvecp_->comm_ortho_fft().size() != 1) {
274 int count = gvecp_->gvec_slab().counts[gvecp_->comm_ortho_fft().rank()];
275 int offset = gvecp_->gvec_slab().offsets[gvecp_->comm_ortho_fft().rank()];
276 std::memcpy(f_pw_local_.at(sddk::memory_t::host), f_pw_fft_.at(sddk::memory_t::host, offset),
277 count * sizeof(std::complex<T>));
278 }
279 break;
280 }
281 default: {
282 throw std::runtime_error("wrong FFT direction");
283 }
284 }
285 }
286
287 inline auto gather_f_pw() const
288 {
289 PROFILE("sirius::Smooth_periodic_function::gather_f_pw");
290
291 std::vector<std::complex<T>> fpw(gvecp_->gvec().num_gvec());
292 gvec().comm().allgather(&f_pw_local_[0], fpw.data(), gvec().count(), gvec().offset());
293
294 return fpw;
295 }
296
297 inline void scatter_f_pw(std::vector<std::complex<T>> const& f_pw__)
298 {
299 std::copy(&f_pw__[gvecp_->gvec().offset()], &f_pw__[gvecp_->gvec().offset()] + gvecp_->gvec().count(),
300 &f_pw_local_(0));
301 }
302
303 Smooth_periodic_function<T>& operator+=(Smooth_periodic_function<T> const& rhs__)
304 {
305 #pragma omp parallel
306 {
307 #pragma omp for schedule(static) nowait
308 for (int irloc = 0; irloc < this->spfft_->local_slice_size(); irloc++) {
309 this->f_rg_(irloc) += rhs__.value(irloc);
310 }
311 #pragma omp for schedule(static) nowait
312 for (int igloc = 0; igloc < this->gvecp_->gvec().count(); igloc++) {
313 this->f_pw_local_(igloc) += rhs__.f_pw_local(igloc);
314 }
315 }
316 return *this;
317 }
318
319 Smooth_periodic_function<T>& operator*=(T alpha__)
320 {
321 #pragma omp parallel
322 {
323 #pragma omp for schedule(static) nowait
324 for (int irloc = 0; irloc < this->spfft_->local_slice_size(); irloc++) {
325 this->f_rg_(irloc) *= alpha__;
326 }
327 #pragma omp for schedule(static) nowait
328 for (int igloc = 0; igloc < this->gvecp_->gvec().count(); igloc++) {
329 this->f_pw_local_(igloc) *= alpha__;
330 }
331 }
332 return *this;
333 }
334
335 inline T checksum_rg() const
336 {
337 T cs = this->f_rg_.checksum();
338 mpi::Communicator(this->spfft_->communicator()).allreduce(&cs, 1);
339 return cs;
340 }
341
342 inline auto checksum_pw() const
343 {
344 auto cs = this->f_pw_local_.checksum();
345 this->gvecp_->gvec().comm().allreduce(&cs, 1);
346 return cs;
347 }
348
349 inline uint64_t hash_f_pw() const
350 {
351 auto h = f_pw_local_.hash();
352 gvecp_->gvec().comm().bcast(&h, 1, 0);
353
354 for (int r = 1; r < gvecp_->gvec().comm().size(); r++) {
355 h = f_pw_local_.hash(h);
356 gvecp_->gvec().comm().bcast(&h, 1, r);
357 }
358 return h;
359 }
360
361 inline uint64_t hash_f_rg() const
362 {
363 auto comm = mpi::Communicator(spfft_->communicator());
364
365 uint64_t h;
366 for (int r = 0; r < comm.size(); r++) {
367 if (r == 0) {
368 h = f_rg_.hash();
369 } else {
370 h = f_rg_.hash(h);
371 }
372 comm.bcast(&h, 1, r);
373 }
374 return h;
375 }
376};
377
378/// Vector of the smooth periodic functions.
379template <typename T>
380class Smooth_periodic_vector_function : public std::array<Smooth_periodic_function<T>, 3>
381{
382 private:
383 /// FFT driver.
384 fft::spfft_transform_type<T>* spfft_{nullptr};
385
386 /// Distribution of G-vectors.
387 std::shared_ptr<fft::Gvec_fft> gvecp_{nullptr};
388
391
392 public:
393 /// Default constructor does nothing.
395 {
396 }
397
398 Smooth_periodic_vector_function(fft::spfft_transform_type<T>& spfft__, std::shared_ptr<fft::Gvec_fft> gvecp__)
399 : spfft_(&spfft__)
400 , gvecp_(gvecp__)
401 {
402 for (int x : {0, 1, 2}) {
403 (*this)[x] = Smooth_periodic_function<T>(spfft__, gvecp__);
404 }
405 }
406 Smooth_periodic_vector_function(Smooth_periodic_vector_function<T>&& src__) = default;
407 Smooth_periodic_vector_function<T>& operator=(Smooth_periodic_vector_function<T>&& src__) = default;
408
409 spfft::Transform& spfft() const
410 {
411 RTE_ASSERT(spfft_ != nullptr);
412 return *spfft_;
413 }
414
415 auto gvec_fft() const
416 {
417 RTE_ASSERT(gvecp_ != nullptr);
418 return gvecp_;
419 }
420};
421
422
423/// Gradient of the function in the plane-wave domain.
424/** Input functions is expected in the plane wave domain, output function is also in the plane-wave domain */
425template <typename T>
427{
428 PROFILE("sirius::gradient");
429
430 Smooth_periodic_vector_function<T> g(f__.spfft(), f__.gvec_fft());
431
432 #pragma omp parallel for schedule(static)
433 for (int igloc = 0; igloc < f__.gvec().count(); igloc++) {
434 auto G = f__.gvec().template gvec_cart<index_domain_t::local>(igloc);
435 for (int x : {0, 1, 2}) {
436 g[x].f_pw_local(igloc) = f__.f_pw_local(igloc) * std::complex<T>(0, G[x]);
437 }
438 }
439 return g;
440}
441
442/// Divergence of the vecor function.
443/** Input and output functions are in plane-wave domain */
444template <typename T>
446{
447 PROFILE("sirius::divergence");
448
449 /* resulting scalar function */
450 Smooth_periodic_function<T> f(g__.spfft(), g__.gvec_fft());
451 f.zero();
452 for (int x : {0, 1, 2}) {
453 for (int igloc = 0; igloc < f.gvec().count(); igloc++) {
454 auto G = f.gvec().template gvec_cart<index_domain_t::local>(igloc);
455 f.f_pw_local(igloc) += g__[x].f_pw_local(igloc) * std::complex<T>(0, G[x]);
456 }
457 }
458
459 return f;
460}
461
462/// Laplacian of the function in the plane-wave domain.
463template <typename T>
465{
466 PROFILE("sirius::laplacian");
467
468 Smooth_periodic_function<T> g(f__.spfft(), f__.gvec_fft());
469
470 #pragma omp parallel for schedule(static)
471 for (int igloc = 0; igloc < f__.gvec().count(); igloc++) {
472 auto G = f__.gvec().template gvec_cart<index_domain_t::local>(igloc);
473 g.f_pw_local(igloc) = f__.f_pw_local(igloc) * std::complex<T>(-std::pow(G.length(), 2), 0);
474 }
475
476 return g;
477}
478
479template <typename T>
480inline Smooth_periodic_function<T>
481dot(Smooth_periodic_vector_function<T>& vf__, Smooth_periodic_vector_function<T>& vg__)
482
483{
484 PROFILE("sirius::dot");
485
486 Smooth_periodic_function<T> result(vf__.spfft(), vf__.gvec_fft());
487
488 #pragma omp parallel for schedule(static)
489 for (int ir = 0; ir < vf__.spfft().local_slice_size(); ir++) {
490 T d{0};
491 for (int x : {0, 1, 2}) {
492 d += vf__[x].value(ir) * vg__[x].value(ir);
493 }
494 result.value(ir) = d;
495 }
496
497 return result;
498}
499
500/// Compute local contribution to inner product <f|g>
501template <typename T, typename F>
502inline T
504{
505 RTE_ASSERT(&f__.spfft() == &g__.spfft());
506
507 T result_rg{0};
508
509 //#pragma omp parallel for schedule(static) reduction(+:result_rg)
510 for (int irloc = 0; irloc < f__.spfft().local_slice_size(); irloc++) {
511 result_rg += conj(f__.value(irloc)) * g__.value(irloc) * theta__(irloc);
512 }
513
514 result_rg *= (f__.gvec().omega() / fft::spfft_grid_size(f__.spfft()));
515
516 return result_rg;
517}
518
519template <typename T>
520inline T
521inner_local(Smooth_periodic_function<T> const& f__, Smooth_periodic_function<T> const& g__)
522{
523 return inner_local(f__, g__, [](int ir){return 1;});
524}
525
526template <typename T, typename F>
527inline T
528inner(Smooth_periodic_function<T> const& f__, Smooth_periodic_function<T> const& g__, F&& theta__)
529{
530 PROFILE("sirius::inner");
531
532 T result_rg = inner_local(f__, g__, std::forward<F>(theta__));
533 mpi::Communicator(f__.spfft().communicator()).allreduce(&result_rg, 1);
534
535 return result_rg;
536}
537
538/// Compute inner product <f|g>
539template <typename T>
540inline T
542{
543 return inner(f__, g__, [](int ir){return 1;});
544}
545
546/// Copy real-space values from the function to external pointer.
547template <typename T>
548inline void
550{
551 auto& spfft = src__.spfft();
552 check_smooth_periodic_function_ptr(dest__, spfft);
553
554 if (!dest__.ptr) {
555 RTE_THROW("Output pointer is null");
556 }
557 /* true if input external buffer points to local part of FFT grid */
558 bool is_local_rg = (dest__.offset_z >= 0);
559
560 int offs = (is_local_rg) ? 0 : spfft.dim_x() * spfft.dim_y() * spfft.local_z_offset();
561
562 /* copy local fraction of real-space points to local or global array */
563 std::copy(src__.values().at(sddk::memory_t::host),
564 src__.values().at(sddk::memory_t::host) + spfft.local_slice_size(),
565 dest__.ptr + offs);
566
567 /* if output buffer stores the global data array */
568 if (!is_local_rg) {
569 mpi::Communicator(spfft.communicator()).allgather(dest__.ptr, spfft.local_slice_size(), offs);
570 }
571}
572
573/// Copy real-space values from the external pointer to function.
574template <typename T>
575inline void
577{
578 auto& spfft = dest__.spfft();
579 check_smooth_periodic_function_ptr(src__, spfft);
580
581 if (!src__.ptr) {
582 RTE_THROW("Input pointer is null");
583 }
584 /* true if input external buffer points to local part of FFT grid */
585 bool is_local_rg = (src__.offset_z >= 0);
586
587 int offs = (is_local_rg) ? 0 : spfft.dim_x() * spfft.dim_y() * spfft.local_z_offset();
588
589 /* copy local fraction of real-space points to local or global array */
590 std::copy(src__.ptr + offs, src__.ptr + offs + spfft.local_slice_size(),
591 dest__.values().at(sddk::memory_t::host));
592}
593
594template <typename T>
595inline void
596copy(Smooth_periodic_function<T> const& src__, Smooth_periodic_function<T>& dest__)
597{
598 copy(src__.f_rg_, dest__.f_rg_);
599 copy(src__.f_pw_local_, dest__.f_pw_local_);
600}
601
602template <typename T>
603inline void
604scale(T alpha__, Smooth_periodic_function<T>& x__)
605{
606 for (size_t i = 0; i < x__.f_rg_.size(); i++) {
607 x__.f_rg_[i] *= alpha__;
608 }
609 for (size_t i = 0; i < x__.f_pw_local_.size(); i++) {
610 x__.f_pw_local_[i] *= alpha__;
611 }
612}
613
614template <typename T>
615inline void
616axpy(T alpha__, Smooth_periodic_function<T> const& x__, Smooth_periodic_function<T>& y__)
617{
618 for (size_t i = 0; i < x__.f_rg_.size(); i++) {
619 y__.f_rg_[i] += x__.f_rg_[i] * alpha__;
620 }
621 for (size_t i = 0; i < x__.f_pw_local_.size(); i++) {
622 y__.f_pw_local_[i] += x__.f_pw_local_[i] * alpha__;
623 }
624}
625
626} // namespace sirius
627
628#endif // __SMOOTH_PERIODIC_FUNCTION_HPP__
Representation of a smooth (Fourier-transformable) periodic function.
sddk::mdarray< std::complex< T >, 1 > f_pw_local_
Local set of plane-wave expansion coefficients.
fft::spfft_transform_type< T > * spfft_
FFT driver.
void gather_f_pw_fft()
Gather plane-wave coefficients for the subsequent FFT call.
sddk::mdarray< T, 1 > f_rg_
Function on the regular real-space grid.
void zero()
Zero the values on the regular real-space grid and plane-wave coefficients.
Smooth_periodic_function(fft::spfft_transform_type< T > const &spfft__, std::shared_ptr< fft::Gvec_fft > gvecp__, smooth_periodic_function_ptr_t< T > const *sptr__=nullptr)
Constructor.
sddk::mdarray< std::complex< T >, 1 > f_pw_fft_
Storage of the PW coefficients for the FFT transformation.
std::shared_ptr< fft::Gvec_fft > gvecp_
Distribution of G-vectors.
auto f_0() const
Return plane-wave coefficient for G=0 component.
Vector of the smooth periodic functions.
fft::spfft_transform_type< T > * spfft_
FFT driver.
std::shared_ptr< fft::Gvec_fft > gvecp_
Distribution of G-vectors.
Smooth_periodic_vector_function()
Default constructor does nothing.
MPI communicator wrapper.
void allgather(T *buffer__, int const *recvcounts__, int const *displs__) const
In-place MPI_Allgatherv.
uint64_t hash(uint64_t h__=5381) const
Compute hash of the array.
Definition: memory.hpp:1242
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
Definition: memory.hpp:1316
T checksum(size_t idx0__, size_t size__) const
Compute checksum.
Definition: memory.hpp:1262
Contains helper functions for the interface with SpFFT library.
Declaration and implementation of Gvec class.
Memory management functions and classes.
void spfft_output(spfft_transform_type< T > &spfft__, T *data__)
Output CPU data from the CPU buffer of SpFFT.
Definition: fft.hpp:173
enable_return< F, T, int > spfft_input(spfft_transform_type< T > &spfft__, F &&fr__)
Load data from real-valued lambda.
Definition: fft.hpp:91
size_t spfft_grid_size_local(T const &spfft__)
Local size of the SpFFT transformation grid.
Definition: fft.hpp:228
size_t spfft_grid_size(T const &spfft__)
Total size of the SpFFT transformation grid.
Definition: fft.hpp:221
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.
Definition: sirius.f90:5
Smooth_periodic_vector_function< T > gradient(Smooth_periodic_function< T > &f__)
Gradient of the function in the plane-wave domain.
T inner_local(Smooth_periodic_function< T > const &f__, Smooth_periodic_function< T > const &g__, F &&theta__)
Compute local contribution to inner product <f|g>
Smooth_periodic_function< T > laplacian(Smooth_periodic_function< T > &f__)
Laplacian of the function in the plane-wave domain.
Smooth_periodic_function< T > divergence(Smooth_periodic_vector_function< T > &g__)
Divergence of the vecor function.
auto conj(double x__)
Return complex conjugate of a number. For a real value this is the number itself.
Definition: math_tools.hpp:165
A time-based profiler.
Contains typedefs, enums and simple descriptors.