.. _program_listing_file_src_bz_mesh.hpp: Program Listing for File bz_mesh.hpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/bz_mesh.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* This file is part of brille. Copyright © 2019,2020 Greg Tucker brille is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. brille is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with brille. If not, see . */ #ifndef BRILLE_BZ_MESH_ #define BRILLE_BZ_MESH_ #include "bz.hpp" #include "mesh.hpp" namespace brille { template class BrillouinZoneMesh3: public Mesh3{ using SuperClass = Mesh3; protected: BrillouinZone brillouinzone; public: // BrillouinZoneMesh3(const BrillouinZone& bz, const double max_size_invA=-1., const double min_angle=20.0, const double max_angle=-1.0, const double max_ratio=-1., const int max_points=-1): // Mesh3(bz.get_ir_vertices().get_xyz(), bz.get_ir_vertices_per_face(), max_size_invA, min_angle, max_angle, max_ratio, max_points), // brillouinzone(bz) {} // BrillouinZoneMesh3(const BrillouinZone& bz) Mesh3(bz.get_ir_vertices().get_xyz(), bz.get_ir_vertices_per_face()); template BrillouinZoneMesh3(const BrillouinZone& bz, A... args): SuperClass(bz.get_ir_vertices().get_xyz(), bz.get_ir_vertices_per_face(), args...), brillouinzone(bz) {} // get the BrillouinZone object BrillouinZone get_brillouinzone(void) const {return this->brillouinzone;} // get the mesh vertices in relative lattice units bArray get_mesh_hkl(void) const { auto xyz = this->get_mesh_xyz(); double toxyz[9], fromxyz[9]; const BrillouinZone bz = this->get_brillouinzone(); bz.get_lattice().get_xyz_transform(toxyz); if (!brille::utils::matrix_inverse(fromxyz,toxyz)) throw std::runtime_error("transform matrix toxyz has zero determinant"); auto shape = xyz.shape(); bArray hkl(shape); std::vector tmp(3); for (size_t i=0; i(tmp.data(), fromxyz, vxyz.data()); hkl.set(i, tmp); } return hkl; } template std::tuple,brille::Array> ir_interpolate_at(const LQVec& x, const int nthreads, const bool no_move=false) const { LQVec ir_q(x.get_lattice(), x.size(0)); LQVec tau(x.get_lattice(), x.size(0)); std::vector rot(x.size(0),0u), invrot(x.size(0),0u); if (no_move){ ir_q = x; } else if (!brillouinzone.ir_moveinto(x, ir_q, tau, rot, invrot, nthreads)){ std::string msg; msg = "Moving all points into the irreducible Brillouin zone failed."; throw std::runtime_error(msg); } // perform the interpolation within the irreducible Brillouin zone auto [vals, vecs] = (nthreads > 1) ? this->SuperClass::parallel_interpolate_at(ir_q.get_xyz(), nthreads) : this->SuperClass::interpolate_at(ir_q.get_xyz()); // we always need the pointgroup operations to 'rotate' PointSymmetry psym = brillouinzone.get_pointgroup_symmetry(); // and might need the Phonon Gamma table GammaTable pgt{GammaTable()}; if (RotatesLike::Gamma == this->data().vectors().rotateslike()){ pgt.construct(brillouinzone.get_lattice().star(), brillouinzone.add_time_reversal()); } brille::Array2 vals2(vals); brille::Array2 vecs2(vecs); // actually perform the rotation to Q this->data().values() .rotate_in_place(vals2, ir_q, pgt, psym, rot, invrot, nthreads); this->data().vectors().rotate_in_place(vecs2, ir_q, pgt, psym, rot, invrot, nthreads); // we're done so bundle the output return std::make_tuple(vals, vecs); } }; } // end namespace brille #endif // _BZ_MESH_