.. _program_listing_file_src_array_lqvec.tpp: Program Listing for File array_lqvec.tpp ======================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/array_lqvec.tpp``) .. |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 . */ template template LQVec LQVec::view(A... args) const { return LQVec(this->get_lattice(), this->bArray::view(args...)); } template template LQVec LQVec::extract(A... args) const { return LQVec(this->get_lattice(), this->bArray::extract(args...)); } template bArray LQVec::get_hkl() const { return bArray(*this); // strip off the Lattice information } template bArray LQVec::get_xyz() const { assert(this->is_row_ordered() && this->is_contiguous() && this->size(this->ndim()-1) == 3); bArray xyz(this->shape(), this->stride()); std::vector toxyz = this->get_lattice().get_xyz_transform(); auto tshape = this->shape(); tshape.back() = 0u; for (auto x: this->subItr(tshape)) brille::utils::multiply_matrix_vector(xyz.ptr(x), toxyz.data(), this->ptr(x)); return xyz; } template LDVec LQVec::star() const { assert(this->is_row_ordered() && this->is_contiguous() && this->size(this->ndim()-1) == 3); std::vector cvmt = this->get_lattice().get_covariant_metric_tensor(); LDVec slv(this->get_lattice().star(), this->shape(), this->stride()); auto fx = this->shape(); fx.back() = 0; for (auto x: this->subItr(fx)) brille::utils::multiply_matrix_vector(slv.ptr(x), cvmt.data(), this->ptr(x)); slv /= 2.0*brille::pi; // ai= gij/2/pi * ai_star return slv; } template LQVec LQVec::cross(const size_t i, const size_t j) const { assert(this->is_row_ordered() && this->is_contiguous() && this->ndim()==2 && this->size(this->ndim()-1) == 3); bool bothok = (isize(0) && jsize(0)); LQVec out(this->get_lattice(), bothok? 1u : 0u, 3u); if (bothok){ auto lat = this->get_lattice(); LDVec ldv(lat.star(), 1u); brille::utils::vector_cross(ldv.ptr(0), this->ptr(i), this->ptr(j)); ldv *= lat.get_volume()/2.0/brille::pi; out = ldv.star(); } return out; } template double LQVec::dot(const size_t i, const size_t j) const { assert(this->is_row_ordered() && this->is_contiguous() && this->ndim()==2 && this->size(this->ndim()-1) == 3); if (i>=this->size(0) || j>=this->size(0)) throw std::out_of_range("attempted out of bounds access by dot"); auto lat = this->get_lattice(); std::vector len{lat.get_a(), lat.get_b(), lat.get_c()}; std::vector ang{lat.get_alpha(), lat.get_beta(), lat.get_gamma()}; return same_lattice_dot(this->view(i),this->view(j),len,ang); } template void LQVec::check_array(){ auto last = this->ndim()-1; // the last dimension must cover 3-vectors if(this->size(last) != 3) throw std::runtime_error("LQVec objects must have a last dimension of size 3"); // which must be contiguous in memory for most operations auto st = this->stride(); if(st[last] != 1) throw std::runtime_error("LQVec objects must have a contiguous last dimension"); }