SIRIUS 7.5.0
Electronic structure library and applications
non_local_operator.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 non_local_operator.hpp
21 *
22 * \brief Contains declaration of sirius::Non_local_operator class.
23 */
24
25#ifndef __NON_LOCAL_OPERATOR_HPP__
26#define __NON_LOCAL_OPERATOR_HPP__
27
28#include "core/omp.hpp"
29#include "core/rte/rte.hpp"
30#include "SDDK/memory.hpp"
34
35namespace sirius {
36/* forward declaration */
37template <typename T>
38class Beta_projectors;
39template <typename T>
40class Beta_projectors_base;
41
42template <typename T>
44{
45 private:
46 void initialize();
47
48 public:
49 D_operator(Simulation_context const& ctx_);
50};
51
52template <typename T>
54{
55 private:
56 void initialize();
57
58 public:
59 Q_operator(Simulation_context const& ctx__);
60};
61
62template <typename T>
64{
65 private:
66 Simulation_context const& ctx_;
67 // sddk::mdarray<std::complex<T>, 3> um_;
68 std::array<la::dmatrix<std::complex<T>>, 4> um_;
69 std::vector<int> offset_;
70 std::vector<std::pair<int, int>> atomic_orbitals_;
71 int nhwf_;
73
74 public:
75 U_operator(Simulation_context const& ctx__, Hubbard_matrix const& um1__, std::array<double, 3> vk__);
76 ~U_operator() = default;
77
78 inline auto atomic_orbitals() const
79 {
80 return atomic_orbitals_;
81 }
82
83 inline auto atomic_orbitals(const int idx__) const
84 {
85 return atomic_orbitals_[idx__];
86 }
87 inline auto nhwf() const
88 {
89 return nhwf_;
90 }
91
92 inline auto offset(int ia__) const
93 {
94 return offset_[ia__];
95 }
96
97 std::complex<T> const& operator()(int m1, int m2, int j) const
98 {
99 return um_[j](m1, m2);
100 }
101
102 std::complex<T> const* at(sddk::memory_t mem__, const int idx1, const int idx2, const int idx3) const
103 {
104 return um_[idx3].at(mem__, idx1, idx2);
105 }
106
107 int find_orbital_index(const int ia__, const int n__, const int l__) const;
108};
109
110/** \tparam T Precision of the wave-functions.
111 * \tparam F Type of the subspace.
112 *
113 * \param [in] spins Range of the spin index.
114 * \param [in] N Starting index of the wave-functions.
115 * \param [in] n Number of wave-functions to which D and Q are applied.
116 * \param [in] beta Beta-projector generator
117 * \param [in] beta_coeffs Beta-projector coefficients
118 * \param [in] phi Wave-functions.
119 * \param [in] d_op Pointer to D-operator.
120 * \param [out] hphi Resulting |beta>D<beta|phi>
121 * \param [in] q_op Pointer to Q-operator.
122 * \param [out] sphi Resulting |beta>Q<beta|phi>
123 **/
124template <typename T, typename F>
125void
128 wf::Wave_functions<T> const& phi__, D_operator<T> const* d_op__, wf::Wave_functions<T>* hphi__,
129 Q_operator<T> const* q_op__, wf::Wave_functions<T>* sphi__)
130{
131 if (sddk::is_device_memory(mem__)) {
132 RTE_ASSERT(beta__.device_t() == sddk::device_t::GPU);
133 }
134
135 auto& ctx = beta__.ctx();
136
137 for (int i = 0; i < beta__.num_chunks(); i++) {
138 /* generate beta-projectors for a block of atoms */
139 beta__.generate(beta_coeffs__, i);
140
141 for (auto s = spins__.begin(); s != spins__.end(); s++) {
142 auto sp = phi__.actual_spin_index(s);
143 // auto beta_phi = beta__.template inner<F>(mem__, i, phi__, sp, br__);
144 auto beta_phi = inner_prod_beta<F>(ctx.spla_context(), mem__, ctx.host_memory_t(),
145 sddk::is_device_memory(mem__), /* copy result back to gpu if true */
146 beta_coeffs__, phi__, sp, br__);
147
148 if (hphi__ && d_op__) {
149 /* apply diagonal spin blocks */
150 d_op__->apply(mem__, i, s.get(), *hphi__, br__, beta_coeffs__, beta_phi);
151 if (!d_op__->is_diag() && hphi__->num_md() == wf::num_mag_dims(3)) {
152 /* apply non-diagonal spin blocks */
153 /* xor 3 operator will map 0 to 3 and 1 to 2 */
154 d_op__->apply(mem__, i, s.get() ^ 3, *hphi__, br__, beta_coeffs__, beta_phi);
155 }
156 }
157
158 if (sphi__ && q_op__) {
159 /* apply Q operator (diagonal in spin) */
160 q_op__->apply(mem__, i, s.get(), *sphi__, br__, beta_coeffs__, beta_phi);
161 if (!q_op__->is_diag() && sphi__->num_md() == wf::num_mag_dims(3)) {
162 q_op__->apply(mem__, i, s.get() ^ 3, *sphi__, br__, beta_coeffs__, beta_phi);
163 }
164 }
165 }
166 }
167}
168
169/// Compute |sphi> = (1 + Q)|phi>
170template <typename T, typename F>
171void
173 beta_projectors_coeffs_t<T>& beta_coeffs__, wf::Wave_functions<T> const& phi__,
174 Q_operator<T> const* q_op__, wf::Wave_functions<T>& sphi__)
175{
176 for (auto s = spins__.begin(); s != spins__.end(); s++) {
177 wf::copy(mem__, phi__, s, br__, sphi__, s, br__);
178 }
179
180 if (q_op__) {
181 apply_non_local_D_Q<T, F>(mem__, spins__, br__, beta__, beta_coeffs__, phi__, nullptr, nullptr, q_op__,
182 &sphi__);
183 }
184}
185
186/** Apply Hubbard U correction
187 * \tparam T Precision type of wave-functions (flat or double).
188 * \param [in] hub_wf Hubbard atomic wave-functions.
189 * \param [in] phi Set of wave-functions to which Hubbard correction is applied.
190 * \param [out] hphi Output wave-functions to which the result is added.
191 */
192template <typename T>
193void apply_U_operator(Simulation_context& ctx__, wf::spin_range spins__, wf::band_range br__,
194 wf::Wave_functions<T> const& hub_wf__, wf::Wave_functions<T> const& phi__, U_operator<T> const& um__,
195 wf::Wave_functions<T>& hphi__);
196/// Apply strain derivative of S-operator to all scalar functions.
197void apply_S_operator_strain_deriv(sddk::memory_t mem__, int comp__, Beta_projector_generator<double>& bp__,
198 beta_projectors_coeffs_t<double>& bp_coeffs__,
199 Beta_projector_generator<double>& bp_strain_deriv__,
200 beta_projectors_coeffs_t<double>& bp_strain_deriv_coeffs__,
201 wf::Wave_functions<double>& phi__, Q_operator<double>& q_op__,
202 wf::Wave_functions<double>& ds_phi__);
203} // namespace sirius
204
205#endif
Describes Hubbard orbital occupancy or potential correction matrices.
Non-local part of the Hamiltonian and S-operator in the pseudopotential method.
void apply(sddk::memory_t mem__, int chunk__, int ispn_block__, wf::Wave_functions< T > &op_phi__, wf::band_range br__, beta_projectors_coeffs_t< T > const &beta_coeffs__, sddk::matrix< F > const &beta_phi__) const
Apply chunk of beta-projectors to all wave functions.
Simulation context is a set of parameters and objects describing a single simulation.
auto num_md() const
Return number of magnetic dimensions.
auto actual_spin_index(spin_index s__) const
Return the actual spin index of the wave-functions.
Wave-functions representation.
Describe a range of bands.
Describe a range of spins.
Base class for Hubbard occupancy and potential matrices.
Memory management functions and classes.
memory_t
Memory types where the code can store data.
Definition: memory.hpp:71
void copy(sddk::memory_t mem__, Wave_functions< T > const &in__, wf::spin_index s_in__, wf::band_range br_in__, Wave_functions< F > &out__, wf::spin_index s_out__, wf::band_range br_out__)
Copy wave-functions.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
void apply_S_operator(sddk::memory_t mem__, wf::spin_range spins__, wf::band_range br__, Beta_projector_generator< T > &beta__, beta_projectors_coeffs_t< T > &beta_coeffs__, wf::Wave_functions< T > const &phi__, Q_operator< T > const *q_op__, wf::Wave_functions< T > &sphi__)
Compute |sphi> = (1 + Q)|phi>
void apply_non_local_D_Q(sddk::memory_t mem__, wf::spin_range spins__, wf::band_range br__, Beta_projector_generator< T > &beta__, beta_projectors_coeffs_t< T > &beta_coeffs__, wf::Wave_functions< T > const &phi__, D_operator< T > const *d_op__, wf::Wave_functions< T > *hphi__, Q_operator< T > const *q_op__, wf::Wave_functions< T > *sphi__)
void apply_U_operator(Simulation_context &ctx__, wf::spin_range spins__, wf::band_range br__, wf::Wave_functions< T > const &hub_wf__, wf::Wave_functions< T > const &phi__, U_operator< T > const &um__, wf::Wave_functions< T > &hphi__)
void apply_S_operator_strain_deriv(sddk::memory_t mem__, int comp__, Beta_projector_generator< double > &bp__, beta_projectors_coeffs_t< double > &bp_coeffs__, Beta_projector_generator< double > &bp_strain_deriv__, beta_projectors_coeffs_t< double > &bp_strain_deriv_coeffs__, wf::Wave_functions< double > &phi__, Q_operator< double > &q_op__, wf::Wave_functions< double > &ds_phi__)
Apply strain derivative of S-operator to all scalar functions.
Contains definition of sirius::Non_local_operator class.
Add or substitute OMP functions.
Eror and warning handling during run-time execution.
Contains definition and implementation of Simulation_context class.
Stores a chunk of the beta-projector and metadata.