AlmaBTE  1.3
A solver of the space- and time-dependent Boltzmann transport equation for phonons
qpoint_grid.hpp
Go to the documentation of this file.
1 // Copyright 2015-2018 The ALMA Project Developers
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 // implied. See the License for the specific language governing
13 // permissions and limitations under the License.
14 
15 #pragma once
16 
19 
20 #include <boost/mpi.hpp>
21 #include <structures.hpp>
22 #include <dynamical_matrix.hpp>
23 
24 namespace alma {
26 using Tetrahedron = std::array<std::size_t, 4>;
28 using Triangle = std::array<std::size_t, 3>;
29 
32 class Gamma_grid {
33 public:
35  const int na;
37  const int nb;
39  const int nc;
41  const std::size_t nqpoints;
43  const Eigen::MatrixXd rlattvec;
45  const Eigen::MatrixXd dq;
49  Gamma_grid(const Crystal_structure& poscar,
50  const Symmetry_operations& symms,
51  const Harmonic_ifcs& force_constants,
52  int _na,
53  int _nb,
54  int _nc);
55 
56 
60  Gamma_grid(const Crystal_structure& poscar,
61  const Symmetry_operations& symms,
62  const Harmonic_ifcs& force_constants,
63  const Dielectric_parameters& born,
64  int _na,
65  int _nb,
66  int _nc);
67 
68 
70  void enforce_asr() {
71  this->spectrum[0].omega.head(3).fill(0.);
72  }
73 
74 
83  std::size_t three_to_one(const std::array<int, 3>& indices) const {
84  auto ia = python_mod(indices[0], this->na);
85  auto ib = python_mod(indices[1], this->nb);
86  auto ic = python_mod(indices[2], this->nc);
87 
88  return ic + nc * (ib + nb * ia);
89  }
90 
91 
98  std::array<int, 3> one_to_three(std::size_t iq) const {
99  std::array<int, 3> nruter;
100  nruter[2] = iq % nc;
101  iq /= nc;
102  nruter[1] = iq % nb;
103  nruter[0] = iq / nb;
104  return nruter;
105  }
106 
107 
109  std::size_t get_nequivalences() const {
110  return this->equivalences.size();
111  }
112 
113 
120  const Spectrum_at_point& get_spectrum_at_q(int iq) const {
121  std::size_t index = python_mod(iq, this->nqpoints);
122 
123  return this->spectrum[index];
124  }
125 
126 
131  std::size_t get_cardinal(std::size_t ic) const {
132  if (ic > this->equivalences.size())
133  throw value_error("wrong equivalence class index");
134  return this->equivalences[ic].size();
135  }
136 
137 
143  std::size_t get_representative(std::size_t ic) const {
144  if (ic > this->equivalences.size())
145  throw value_error("wrong equivalence class index");
146  return this->equivalences[ic][0];
147  }
148 
149 
155  std::vector<std::size_t> get_equivalence(std::size_t ic) const {
156  if (ic > this->equivalences.size())
157  throw value_error("wrong equivalence class index");
158  return this->equivalences[ic];
159  }
160 
161 
166  Eigen::VectorXd get_q(std::size_t iq) const {
167  std::size_t index = python_mod(iq, this->nqpoints);
168 
169  return this->cpos.col(index);
170  }
171 
172 
179  double base_sigma(const Eigen::VectorXd& v) const {
180  return (v.transpose() * this->dq).norm() / std::sqrt(12.);
181  }
182 
183 
187  Gamma_grid(const Crystal_structure& poscar,
188  const Symmetry_operations& symms,
189  int _na,
190  int _nb,
191  int _nc);
192 
193 
198  std::size_t polar_opposite(std::size_t q) {
199  auto indices = this->one_to_three(q);
200 
201  return this->three_to_one({{-indices[0], -indices[1], -indices[2]}});
202  }
203 
204 
213  std::vector<size_t> equivalent_qpoints(std::size_t original) const {
214  std::size_t index = python_mod(original, this->nqpoints);
215  return this->symmetry_map[index];
216  }
217 
218 
225  std::vector<std::array<std::size_t, 2>> equivalent_qpairs(
226  const std::array<std::size_t, 2>& original) const;
227 
228 
235  std::vector<std::array<std::size_t, 3>> equivalent_qtriplets(
236  const std::array<std::size_t, 3>& original) const;
237 
238 
243  std::vector<Tetrahedron> get_tetrahedra(std::size_t q) const {
244  // Find out the indices of the eight corners of the
245  // microcell.
246  std::size_t i000 = q;
247  auto indices = this->one_to_three(i000);
248  std::size_t i001 =
249  this->three_to_one({{indices[0], indices[1], indices[2] + 1}});
250  std::size_t i010 =
251  this->three_to_one({{indices[0], indices[1] + 1, indices[2]}});
252  std::size_t i011 =
253  this->three_to_one({{indices[0], indices[1] + 1, indices[2] + 1}});
254  std::size_t i100 =
255  this->three_to_one({{indices[0] + 1, indices[1], indices[2]}});
256  std::size_t i101 =
257  this->three_to_one({{indices[0] + 1, indices[1], indices[2] + 1}});
258  std::size_t i110 =
259  this->three_to_one({{indices[0] + 1, indices[1] + 1, indices[2]}});
260  std::size_t i111 = this->three_to_one(
261  {{indices[0] + 1, indices[1] + 1, indices[2] + 1}});
262 
263  // Build the four equivalent tetrahedra.
264  std::vector<Tetrahedron> nruter;
265  nruter.reserve(5);
266  nruter.emplace_back(Tetrahedron({{i000, i001, i010, i100}}));
267  nruter.emplace_back(Tetrahedron({{i110, i111, i100, i010}}));
268  nruter.emplace_back(Tetrahedron({{i101, i100, i111, i001}}));
269  nruter.emplace_back(Tetrahedron({{i011, i010, i001, i111}}));
270  // And the central, inequivalent one.
271  nruter.emplace_back(Tetrahedron({{i010, i100, i111, i001}}));
272  return nruter;
273  }
274 
275 
278  std::vector<Triangle> get_triangles(std::size_t ia) const;
279 
280 
284  std::size_t getParentIdx(std::size_t iq) const;
285 
286 
291  std::size_t getSymIdxToParent(std::size_t iq) const;
292 
293 
295  std::vector<std::vector<std::size_t>> getSymmetryMap() {
296  return this->symmetry_map;
297  }
298 
299 
308  template <typename T>
309  auto copy_symmetry(std::size_t iq,
310  const Symmetry_operations& symms,
311  const Eigen::MatrixBase<T>& x) const
312  -> Eigen::Matrix<typename T::Scalar, Eigen::Dynamic, Eigen::Dynamic> {
313  std::size_t index = python_mod(iq, this->nqpoints);
314  std::size_t nops = symms.get_nsym();
315 
316  typename T::PlainObject nruter(x);
317  nruter.fill(0.);
318  std::size_t nfound = 0;
319 
320  for (std::size_t iop = 0; iop < nops; ++iop) {
321  if (this->symmetry_map[index][2 * iop] == index) {
322  nruter += symms.rotate_v(x, iop, true);
323  ++nfound;
324  }
325  }
326  nruter /= nfound;
327  return nruter;
328  }
329 
330 private:
331  friend void save_bulk_hdf5(const char* filename,
332  const std::string& description,
333  const Crystal_structure& cell,
334  const Symmetry_operations& symmetries,
335  const Gamma_grid& grid,
336  const std::vector<Threeph_process>& processes,
337  const boost::mpi::communicator& comm);
338 
339  friend std::tuple<std::string,
340  std::unique_ptr<Crystal_structure>,
341  std::unique_ptr<Symmetry_operations>,
342  std::unique_ptr<Gamma_grid>,
343  std::unique_ptr<std::vector<Threeph_process>>>
344  load_bulk_hdf5(const char* filename, const boost::mpi::communicator& comm);
345 
347  Eigen::MatrixXd cpos;
349  std::vector<Spectrum_at_point> spectrum;
354  std::vector<std::vector<std::size_t>> equivalences;
357  std::vector<std::vector<std::size_t>> symmetry_map;
360  void initialize_cpos();
361 
370  std::vector<Spectrum_at_point> compute_my_spectrum(
371  const Dynamical_matrix_builder& factory,
372  const Symmetry_operations& symms,
373  const boost::mpi::communicator& communicator);
374 
378  void fill_equivalences(const Symmetry_operations& symms);
379 
383  std::vector<std::size_t> parentlookup;
384 
386  void fill_parentlookup();
387 
391  void fill_map(const Symmetry_operations& symms);
392 };
393 } // namespace alma
std::vector< Tetrahedron > get_tetrahedra(std::size_t q) const
Decompose the q-th microcell in five tetrahedra.
Definition: qpoint_grid.hpp:243
Definition: analytic1d.hpp:26
U python_mod(const T &n, const U &d)
Alternative modulus operation with a behavior similar to the % operator in Python.
Definition: utilities.hpp:292
friend void save_bulk_hdf5(const char *filename, const std::string &description, const Crystal_structure &cell, const Symmetry_operations &symmetries, const Gamma_grid &grid, const std::vector< Threeph_process > &processes, const boost::mpi::communicator &comm)
Save all relevant information about a bulk material to an HDF5 file.
Definition: bulk_hdf5.cpp:125
std::size_t get_cardinal(std::size_t ic) const
Return the cardinal of an equivalence class.
Definition: qpoint_grid.hpp:131
void enforce_asr()
Set the three lowest frequencies at Gamma to zero.
Definition: qpoint_grid.hpp:70
auto rotate_v(const Eigen::MatrixBase< T > &vector, std::size_t index, bool cartesian=false) const -> Eigen::Matrix< typename T::Scalar, Eigen::Dynamic, Eigen::Dynamic >
Rotate (but do not translate) a vector according to one of the symmetry operations.
Definition: symmetry.hpp:115
const int nb
Size of the grid along the second reciprocal axis.
Definition: qpoint_grid.hpp:37
std::size_t get_representative(std::size_t ic) const
Return a representative of an equivalence class.
Definition: qpoint_grid.hpp:143
const Eigen::MatrixXd dq
Side vectors of each element in reciprocal space.
Definition: qpoint_grid.hpp:45
std::size_t polar_opposite(std::size_t q)
Find the index of the polar opposite q point.
Definition: qpoint_grid.hpp:198
Exception related to the parameters passed to a function.
Definition: exceptions.hpp:33
friend std::tuple< std::string, std::unique_ptr< Crystal_structure >, std::unique_ptr< Symmetry_operations >, std::unique_ptr< Gamma_grid >, std::unique_ptr< std::vector< Threeph_process > > > load_bulk_hdf5(const char *filename, const boost::mpi::communicator &comm)
Reconstruct all data structures from a file saved with save_bulk_hdf5().
Definition: bulk_hdf5.cpp:442
Hold information about the harmonic interactions between atoms.
Definition: structures.hpp:233
std::size_t getSymIdxToParent(std::size_t iq) const
Definition: qpoint_grid.cpp:276
Code related to the dynamical matrix.
Hold information about the polarization properties of the structure.
Definition: structures.hpp:272
std::vector< std::array< std::size_t, 2 > > equivalent_qpairs(const std::array< std::size_t, 2 > &original) const
Find all q-point pairs equivalent to the input.
Definition: qpoint_grid.cpp:312
Eigen::VectorXd get_q(std::size_t iq) const
Return the Cartesian coordinates of a q point.
Definition: qpoint_grid.hpp:166
std::size_t getParentIdx(std::size_t iq) const
Definition: qpoint_grid.cpp:268
const int na
Size of the grid along the first reciprocal axis.
Definition: qpoint_grid.hpp:35
auto copy_symmetry(std::size_t iq, const Symmetry_operations &symms, const Eigen::MatrixBase< T > &x) const -> Eigen::Matrix< typename T::Scalar, Eigen::Dynamic, Eigen::Dynamic >
Remove the component of a Cartesian vector which does transform as a q-point in the grid...
Definition: qpoint_grid.hpp:309
Factory of Dynamical_matrix objects.
Definition: dynamical_matrix.hpp:108
std::array< std::size_t, 3 > Triangle
Convenient shorthand for an array of three indices.
Definition: qpoint_grid.hpp:28
Gamma_grid(const Crystal_structure &poscar, const Symmetry_operations &symms, const Harmonic_ifcs &force_constants, int _na, int _nb, int _nc)
Constructor: initialize all internal variables and compute the spectrum at each q point...
Definition: qpoint_grid.cpp:41
std::vector< size_t > equivalent_qpoints(std::size_t original) const
Return the images of a q point through all the symmetry operations, including inversions.
Definition: qpoint_grid.hpp:213
std::size_t get_nsym() const
Definition: symmetry.hpp:59
std::vector< std::vector< std::size_t > > getSymmetryMap()
Definition: qpoint_grid.hpp:295
const Spectrum_at_point & get_spectrum_at_q(int iq) const
Access the harmonic properties at a point in the grid.
Definition: qpoint_grid.hpp:120
Definitions of the basic data-handling classes in ALMA.
Objects of this class hold a subset of the information provided by spg_get_dataset().
Definition: symmetry.hpp:47
std::size_t three_to_one(const std::array< int, 3 > &indices) const
Return the index of a q point identified by its position along the three axes.
Definition: qpoint_grid.hpp:83
std::array< int, 3 > one_to_three(std::size_t iq) const
Return the coordinates of a q point identified by its index.
Definition: qpoint_grid.hpp:98
Objects of this class represent a regular grid with the Gamma point in one corner.
Definition: qpoint_grid.hpp:32
Hold information about a crystal structure.
Definition: structures.hpp:51
POD class that holds all the information about the harmonic properties of the system at a particular ...
Definition: dynamical_matrix.hpp:30
std::vector< std::size_t > get_equivalence(std::size_t ic) const
Return the elements in an equivalence class.
Definition: qpoint_grid.hpp:155
const Eigen::MatrixXd rlattvec
Reciprocal lattice basis vectors.
Definition: qpoint_grid.hpp:43
std::array< std::size_t, 4 > Tetrahedron
Convenient shorthand for an array of four indices.
Definition: qpoint_grid.hpp:26
const std::size_t nqpoints
Total number of q points in the grid.
Definition: qpoint_grid.hpp:41
double base_sigma(const Eigen::VectorXd &v) const
Return the base broadening (without any prefactor) for a mode.
Definition: qpoint_grid.hpp:179
std::size_t get_nequivalences() const
Definition: qpoint_grid.hpp:109
const int nc
Size of the grid along the third reciprocal axis.
Definition: qpoint_grid.hpp:39
std::vector< Triangle > get_triangles(std::size_t ia) const
Definition: qpoint_grid.cpp:366
std::vector< std::array< std::size_t, 3 > > equivalent_qtriplets(const std::array< std::size_t, 3 > &original) const
Find all q-point triplets equivalent to the input.
Definition: qpoint_grid.cpp:336