SIRIUS 7.5.0
Electronic structure library and applications
adaptor.hpp
Go to the documentation of this file.
1// Copyright (c) 2023 Simon Pintarelli, 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 adaptor.hpp
21 *
22 * \brief Contains defintion of nlcglib interface.
23 */
24
25#ifndef __NLCGLIB_ADAPTOR_HPP__
26#define __NLCGLIB_ADAPTOR_HPP__
27
28#include <memory>
29#include <nlcglib/interface.hpp>
30#include <cmath>
31#include <map>
32
34#include "density/density.hpp"
37
38namespace sirius {
39
40class Matrix : public nlcglib::MatrixBaseZ
41{
42 public:
43 Matrix(std::vector<buffer_t> const& data, std::vector<kindex_t> const& indices, MPI_Comm mpi_comm = MPI_COMM_SELF)
44 : data(data)
45 , indices(indices)
46 , mpi_comm(mpi_comm)
47 {
48 }
49
50 Matrix(std::vector<buffer_t>&& data, std::vector<kindex_t>&& indices, MPI_Comm mpi_comm = MPI_COMM_SELF)
51 : data{std::forward<std::vector<buffer_t>>(data)}
52 , indices{std::forward<std::vector<kindex_t>>(indices)}
53 , mpi_comm(mpi_comm)
54 { /* empty */
55 }
56
57 buffer_t get(int i) override;
58 const buffer_t get(int i) const override;
59
60 int size() const override
61 {
62 return data.size();
63 };
64
65 MPI_Comm mpicomm(int i) const override
66 {
67 return data[i].mpi_comm;
68 }
69
70 MPI_Comm mpicomm() const override
71 {
72 return mpi_comm;
73 }
74
75 kindex_t kpoint_index(int i) const override
76 {
77 return indices[i];
78 }
79
80 private:
81 std::vector<buffer_t> data;
82 std::vector<kindex_t> indices;
83 MPI_Comm mpi_comm;
84};
85
86/// TODO: Array1d owns data...
87class Array1d : public nlcglib::VectorBaseZ
88{
89 public:
90 Array1d(std::vector<std::vector<double>> const& data, std::vector<kindex_t> const& indices,
91 MPI_Comm mpi_comm = MPI_COMM_SELF)
92 : data(data)
93 , indices(indices)
94 , mpi_comm(mpi_comm)
95 {
96 }
97
98 Array1d(std::vector<std::vector<double>>&& data, std::vector<kindex_t>&& indices, MPI_Comm mpi_comm = MPI_COMM_SELF)
99 : data{std::forward<decltype(data)>(data)}
100 , indices{std::forward<decltype(indices)>(indices)}
101 , mpi_comm(mpi_comm)
102 {
103 }
104
105 buffer_t get(int i) override;
106 const buffer_t get(int i) const override;
107
108 int size() const override
109 {
110 return data.size();
111 };
112
113 MPI_Comm mpicomm(int i) const override
114 {
115 // this object is never distributed
116 return MPI_COMM_SELF;
117 }
118
119 MPI_Comm mpicomm() const override
120 {
121 return mpi_comm;
122 }
123
124 kindex_t kpoint_index(int i) const override
125 {
126 assert(i < static_cast<int>(indices.size()));
127 return indices[i];
128 }
129
130 private:
131 std::vector<std::vector<double>> data;
132 std::vector<kindex_t> indices;
133 MPI_Comm mpi_comm;
134};
135
136class Scalar : public nlcglib::ScalarBaseZ
137{
138 public:
139 Scalar(std::vector<double> const& data__, std::vector<kindex_t> const& indices__, MPI_Comm mpi_comm = MPI_COMM_SELF)
140 : data(data__)
141 , indices(indices__)
142 , mpi_comm(mpi_comm)
143 {
144 }
145
146 Scalar(std::vector<double>&& data__, std::vector<kindex_t>&& indices__, MPI_Comm mpi_comm = MPI_COMM_SELF)
147 : data{std::forward<decltype(data)>(data__)}
148 , indices{std::forward<decltype(indices)>(indices__)}
149 , mpi_comm(mpi_comm)
150 {
151 }
152
153 buffer_t get(int i) override
154 {
155 return data[i];
156 }
157
158 const buffer_t get(int i) const override
159 {
160 return data[i];
161 }
162
163 int size() const override
164 {
165 return data.size();
166 };
167
168 MPI_Comm mpicomm(int i) const override
169 {
170 // this object is never distributed
171 return MPI_COMM_SELF;
172 }
173
174 MPI_Comm mpicomm() const override
175 {
176 return mpi_comm;
177 }
178
179 kindex_t kpoint_index(int i) const override
180 {
181 return indices[i];
182 }
183
184 private:
185 std::vector<double> data;
186 std::vector<kindex_t> indices;
187 MPI_Comm mpi_comm;
188};
189
190/// Kohn-Sham energy
191class Energy : public nlcglib::EnergyBase
192{
193 public:
194 Energy(K_point_set& kset, Density& density, Potential& potential);
195 int nelectrons() override;
196 int occupancy() override;
197 void compute() override;
198 double get_total_energy() override;
199 std::map<std::string, double> get_energy_components() override;
200 std::shared_ptr<nlcglib::MatrixBaseZ> get_hphi(nlcglib::memory_type) override;
201 std::shared_ptr<nlcglib::MatrixBaseZ> get_sphi(nlcglib::memory_type) override;
202 std::shared_ptr<nlcglib::MatrixBaseZ> get_C(nlcglib::memory_type) override;
203 std::shared_ptr<nlcglib::VectorBaseZ> get_fn() override;
204 void set_fn(const std::vector<std::pair<int, int>>& keys, const std::vector<std::vector<double>>& fn) override;
205 std::shared_ptr<nlcglib::VectorBaseZ> get_ek() override;
206 std::shared_ptr<nlcglib::VectorBaseZ> get_gkvec_ekin() override;
207 std::shared_ptr<nlcglib::ScalarBaseZ> get_kpoint_weights() override;
208 void set_chemical_potential(double) override;
209 double get_chemical_potential() override;
210 void print_info() const override;
211
212 private:
213 K_point_set& kset_;
214 Density& density_;
215 Potential& potential_;
216 /// H*psi
217 std::vector<std::shared_ptr<wf::Wave_functions<double>>> hphis_;
218 /// S*spi
219 std::vector<std::shared_ptr<wf::Wave_functions<double>>> sphis_;
220 /// original wfct
221 std::vector<wf::Wave_functions<double>*> cphis_;
222 double etot_{std::nan("1")};
223 std::map<std::string, double> energy_components_;
224};
225
226template <class numeric_t>
227auto
228make_matrix_view(nlcglib::buffer_protocol<numeric_t, 2>& buf)
229{
230 int nrows = buf.size[0];
231 int ncols = buf.size[1];
232
233 if (buf.stride[0] != 1 || buf.stride[1] != nrows) {
234 RTE_THROW("strides not compatible with sddk::mdarray");
235 }
236
237 numeric_t *device_ptr{nullptr}, *host_ptr{nullptr};
238
239 switch (buf.memtype) {
240 case nlcglib::memory_type::device: {
241 device_ptr = buf.data;
242 break;
243 }
244 case nlcglib::memory_type::host: {
245 host_ptr = buf.data;
246 break;
247 }
248 default:
249 RTE_THROW("buffer protocol invalid memory type.");
250 break;
251 }
252
253 return sddk::matrix<numeric_t>(host_ptr, device_ptr, nrows, ncols);
254}
255
256} // namespace sirius
257
258#endif /* __NLCGLIB_ADAPTOR_HPP__ */
TODO: Array1d owns data...
Definition: adaptor.hpp:88
Generate charge density and magnetization from occupied spinor wave-functions.
Definition: density.hpp:214
Kohn-Sham energy.
Definition: adaptor.hpp:192
std::vector< wf::Wave_functions< double > * > cphis_
original wfct
Definition: adaptor.hpp:221
std::vector< std::shared_ptr< wf::Wave_functions< double > > > hphis_
H*psi.
Definition: adaptor.hpp:217
std::vector< std::shared_ptr< wf::Wave_functions< double > > > sphis_
S*spi.
Definition: adaptor.hpp:219
Set of k-points.
Definition: k_point_set.hpp:41
Generate effective potential from charge density and magnetization.
Definition: potential.hpp:46
Contains definition and partial implementation of sirius::Density class.
Contains declaration and partial implementation of sirius::K_point_set class.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
Contains declaration and partial implementation of sirius::Potential class.
Contains declaration and implementation of Wave_functions class.