SIRIUS 7.5.0
Electronic structure library and applications
radial_grid.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 radial_grid.hpp
21 *
22 * \brief Contains declaraion and partial implementation of sirius::Radial_grid class.
23 */
24
25#ifndef __RADIAL_GRID_HPP__
26#define __RADIAL_GRID_HPP__
27
28#include "SDDK/memory.hpp"
29#include "core/typedefs.hpp"
30
31namespace sirius {
32
33/// Types of radial grid.
34enum class radial_grid_t : int
35{
36 linear = 0,
37
38 exponential = 1,
39
40 power = 2,
41
42 lin_exp = 3
43};
44
45/// Base class for radial grids.
46template <typename T>
48{
49 protected:
50 /// Radial grid points.
52
53 /// Inverse values of radial grid points.
55
56 /// Radial grid points difference.
57 /** \f$ dx_{i} = x_{i+1} - x_{i} \f$ */
59
60 /// Name of the grid type.
61 std::string name_;
62
63 /// Initialize the grid.
64 void init()
65 {
66 x_inv_ = sddk::mdarray<T, 1>(num_points(), sddk::memory_t::host, "Radial_grid::x_inv");
67 dx_ = sddk::mdarray<T, 1>(num_points() - 1, sddk::memory_t::host, "Radial_grid::dx");
68
69 /* set x^{-1} */
70 for (int i = 0; i < num_points(); i++) {
71 x_inv_(i) = (x_(i) == 0) ? 0 : 1.0 / x_(i);
72 }
73
74 /* set dx */
75 for (int i = 0; i < num_points() - 1; i++) {
76 dx_(i) = x_(i + 1) - x_(i);
77 }
78 }
79
80 /* forbid copy constructor */
81 Radial_grid(Radial_grid<T> const& src__) = delete;
82 /* forbid assignment operator */
83 Radial_grid& operator=(Radial_grid<T> const& src__) = delete;
84
85 public:
86 /// Constructor of the empty object.
88 {
89 }
90
91 /// Constructor.
92 Radial_grid(int num_points__)
93 {
94 x_ = sddk::mdarray<T, 1>(num_points__, sddk::memory_t::host, "Radial_grid::x");
95 }
96
97 Radial_grid(Radial_grid<T>&& src__) = default;
98
99 Radial_grid<T>& operator=(Radial_grid<T>&& src__) = default;
100
101 int index_of(T x__) const
102 {
103 if (x__ < first() || x__ > last()) {
104 return -1;
105 }
106 int i0 = 0;
107 int i1 = num_points() - 1;
108
109 while (i1 - i0 > 1) {
110 int i = (i1 + i0) >> 1;
111 if (x__ >= x_[i0] && x__ < x_[i]) {
112 i1 = i;
113 } else {
114 i0 = i;
115 }
116 }
117 return i0;
118 }
119
120 /// Number of grid points.
121 inline int num_points() const
122 {
123 return static_cast<int>(x_.size());
124 }
125
126 /// First point of the grid.
127 inline T first() const
128 {
129 return x_(0);
130 }
131
132 /// Last point of the grid.
133 inline T last() const
134 {
135 return x_(num_points() - 1);
136 }
137
138 /// Return \f$ x_{i} \f$.
139 inline T operator[](const int i) const
140 {
141 assert(i < (int)x_.size());
142 return x_(i);
143 }
144
145 /// Return \f$ x_{i} \f$.
146 inline T x(const int i) const
147 {
148 return x_(i);
149 }
150
151 /// Return \f$ dx_{i} \f$.
152 inline T dx(const int i) const
153 {
154 return dx_(i);
155 }
156
157 /// Return \f$ x_{i}^{-1} \f$.
158 inline T x_inv(const int i) const
159 {
160 return x_inv_(i);
161 }
162
163 inline std::string const& name() const
164 {
165 return name_;
166 }
167
168 void copy_to_device()
169 {
170 x_.allocate(sddk::memory_t::device).copy_to(sddk::memory_t::device);
171 dx_.allocate(sddk::memory_t::device).copy_to(sddk::memory_t::device);
172 }
173
174 sddk::mdarray<T, 1> const& x() const
175 {
176 return x_;
177 }
178
179 sddk::mdarray<T, 1> const& dx() const
180 {
181 return dx_;
182 }
183
184 Radial_grid<T> segment(int num_points__) const
185 {
186 assert(num_points__ >= 0 && num_points__ <= (int)x_.size());
187 Radial_grid<T> r;
188 r.name_ = name_ + " (segment)";
189 r.x_ = sddk::mdarray<T, 1>(num_points__);
190 r.dx_ = sddk::mdarray<T, 1>(num_points__ - 1);
191 r.x_inv_ = sddk::mdarray<T, 1>(num_points__);
192
193 std::memcpy(&r.x_(0), &x_(0), num_points__ * sizeof(T));
194 std::memcpy(&r.dx_(0), &dx_(0), (num_points__ - 1) * sizeof(T));
195 std::memcpy(&r.x_inv_(0), &x_inv_(0), num_points__ * sizeof(T));
196
197 return r;
198 }
199
200 std::vector<real_type<T>> values() const
201 {
202 std::vector<real_type<T>> v(num_points());
203 for (int i = 0; i < num_points(); i++) {
204 v[i] = x_[i];
205 }
206 return v;
207 }
208
209 uint64_t hash() const
210 {
211 return 0;
212 }
213
214 // uint64_t hash() const
215 //{
216 // uint64_t h = Utils::hash(&x_(0), x_.size() * sizeof(double));
217 // h += Utils::hash(&dx_(0), dx_.size() * sizeof(double), h);
218 // h += Utils::hash(&x_inv_(0), x_inv_.size() * sizeof(double), h);
219 // return h;
220 //}
221};
222
223template <typename T>
225{
226 public:
227 Radial_grid_pow(int num_points__, T rmin__, T rmax__, double p__)
228 : Radial_grid<T>(num_points__)
229 {
230 for (int i = 0; i < this->num_points(); i++) {
231 T t = static_cast<T>(i) / (this->num_points() - 1);
232 this->x_[i] = rmin__ + (rmax__ - rmin__) * std::pow(t, p__);
233 }
234 this->x_[0] = rmin__;
235 this->x_[num_points__ - 1] = rmax__;
236 this->init();
237 std::stringstream s;
238 s << p__;
239 this->name_ = "power" + s.str();
240 }
241};
242
243template <typename T>
245{
246 public:
247 Radial_grid_lin(int num_points__, T rmin__, T rmax__)
248 : Radial_grid_pow<T>(num_points__, rmin__, rmax__, 1.0)
249 {
250 this->name_ = "linear";
251 }
252};
253
254template <typename T>
256{
257 public:
258 Radial_grid_exp(int num_points__, T rmin__, T rmax__, T p__ = 1.0)
259 : Radial_grid<T>(num_points__)
260 {
261 /* x_i = x_min * (x_max/x_min) ^ (i / (N - 1)) */
262 for (int i = 0; i < this->num_points(); i++) {
263 T t = static_cast<T>(i) / (this->num_points() - 1);
264 this->x_[i] = rmin__ * std::pow(rmax__ / rmin__, std::pow(t, p__));
265 }
266 this->x_[0] = rmin__;
267 this->x_[num_points__ - 1] = rmax__;
268 this->init();
269 this->name_ = "exponential";
270 }
271};
272
273template <typename T>
275{
276 public:
277 Radial_grid_lin_exp(int num_points__, T rmin__, T rmax__, T p__ = 6.0)
278 : Radial_grid<T>(num_points__)
279 {
280 /* x_i = x_min + (x_max - x_min) * A(t)
281 A(0) = 0; A(1) = 1
282 A(t) ~ b * t + Exp[t^a] - 1 */
283 T alpha = p__;
284 T beta = 1e-6 * this->num_points() / (rmax__ - rmin__);
285 T A = 1.0 / (std::exp(static_cast<T>(1)) + beta - static_cast<T>(1));
286 for (int i = 0; i < this->num_points(); i++) {
287 T t = static_cast<T>(i) / (this->num_points() - 1);
288 this->x_[i] =
289 rmin__ + (rmax__ - rmin__) * (beta * t + std::exp(std::pow(t, alpha)) - static_cast<T>(1)) * A;
290 }
291 // T beta = std::log((rmax__ - rmin__ * (num_points__ - 1)) / rmin__);
292 // for (int i = 0; i < this->num_points(); i++) {
293 // T t = static_cast<T>(i) / (this->num_points() - 1);
294 // this->x_[i] = rmin__ * (i + std::exp(beta * std::pow(t, 1)));
295 //}
296
297 this->x_[0] = rmin__;
298 this->x_[num_points__ - 1] = rmax__;
299 this->init();
300 this->name_ = "linear_exponential";
301 }
302};
303
304/// External radial grid provided as a list of points.
305template <typename T>
307{
308 public:
309 Radial_grid_ext(int num_points__, T const* data__)
310 : Radial_grid<T>(num_points__)
311 {
312 for (int i = 0; i < this->num_points(); i++) {
313 this->x_[i] = data__[i];
314 }
315 this->init();
316 this->name_ = "external";
317 }
318};
319
320template <typename T>
321Radial_grid<T> Radial_grid_factory(radial_grid_t grid_type__, int num_points__, T rmin__, T rmax__, double p__)
322{
323 Radial_grid<T> rgrid;
324
325 switch (grid_type__) {
326 case radial_grid_t::linear: {
327 rgrid = Radial_grid_lin<T>(num_points__, rmin__, rmax__);
328 break;
329 }
330 case radial_grid_t::exponential: {
331 rgrid = Radial_grid_exp<T>(num_points__, rmin__, rmax__, p__);
332 break;
333 }
334 case radial_grid_t::power: {
335 rgrid = Radial_grid_pow<T>(num_points__, rmin__, rmax__, p__);
336 break;
337 }
338 case radial_grid_t::lin_exp: {
339 rgrid = Radial_grid_lin_exp<T>(num_points__, rmin__, rmax__, p__);
340 break;
341 }
342 default: {
343 throw std::runtime_error("wrong radial grid type");
344 }
345 }
346 return rgrid;
347};
348
349inline std::pair<radial_grid_t, double> get_radial_grid_t(std::string str__)
350{
351 auto pos = str__.find(",");
352 if (pos == std::string::npos) {
353 std::stringstream s;
354 s << "wrong string for the radial grid type: " << str__;
355 throw std::runtime_error(s.str());
356 }
357
358 std::string name = str__.substr(0, pos);
359 double p = std::stod(str__.substr(pos + 1));
360
361 const std::map<std::string, radial_grid_t> map_to_type = {{"linear", radial_grid_t::linear},
362 {"exponential", radial_grid_t::exponential},
363 {"power", radial_grid_t::power},
364 {"lin_exp", radial_grid_t::lin_exp}};
365
366 return std::make_pair(map_to_type.at(name), p);
367}
368
369} // namespace sirius
370
371#endif // __RADIAL_GRID_HPP__
External radial grid provided as a list of points.
Base class for radial grids.
Definition: radial_grid.hpp:48
T last() const
Last point of the grid.
sddk::mdarray< T, 1 > x_
Radial grid points.
Definition: radial_grid.hpp:51
T dx(const int i) const
Return .
sddk::mdarray< T, 1 > x_inv_
Inverse values of radial grid points.
Definition: radial_grid.hpp:54
T first() const
First point of the grid.
void init()
Initialize the grid.
Definition: radial_grid.hpp:64
std::string name_
Name of the grid type.
Definition: radial_grid.hpp:61
sddk::mdarray< T, 1 > dx_
Radial grid points difference.
Definition: radial_grid.hpp:58
T operator[](const int i) const
Return .
T x(const int i) const
Return .
T x_inv(const int i) const
Return .
int num_points() const
Number of grid points.
Radial_grid(int num_points__)
Constructor.
Definition: radial_grid.hpp:92
Radial_grid()
Constructor of the empty object.
Definition: radial_grid.hpp:87
mdarray< T, N > & allocate(memory_t memory__)
Allocate memory for array.
Definition: memory.hpp:1057
size_t size() const
Return total size (number of elements) of the array.
Definition: memory.hpp:1207
Memory management functions and classes.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
radial_grid_t
Types of radial grid.
Definition: radial_grid.hpp:35
Contains typedefs, enums and simple descriptors.