.. _program_listing_file_src_mesh.tpp: Program Listing for File mesh.tpp ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/mesh.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 . */ // Perform sanity checks before attempting to interpolate template template unsigned int Mesh3::check_before_interpolating(const bArray& x) const{ unsigned int mask = 0u; if (data_.size()==0) throw std::runtime_error("The interpolation data must be filled before interpolating."); if (x.ndim()!=2 || x.size(1)!=3u) throw std::runtime_error("Only (n,3) two-dimensional Q vectors supported in interpolating."); if (x.stride().back()!=1) throw std::runtime_error("Contiguous vectors required for interpolation."); return mask; } //! Perform linear interpolating at the specified points in the mesh's orthonormal frame template template std::tuple,brille::Array> Mesh3::interpolate_at(const bArray& x) const { this->check_before_interpolating(x); auto valsh = data_.values().shape(); auto vecsh = data_.vectors().shape(); valsh[0] = x.size(0); vecsh[0] = x.size(0); brille::Array vals(valsh); brille::Array vecs(vecsh); // vals and vecs are row-ordered contiguous by default, so we can create // mutable data-sharing Array2 objects for use with // Interpolator2::interpolate_at through the constructor: brille::Array2 vals2(vals); brille::Array2 vecs2(vecs); for (ind_t i=0; imesh.locate(x.view(i)); if (verts_weights.size()<1){ debug_update("Point ",x.to_string(i)," not found in tetrahedra!"); throw std::runtime_error("Point not found in tetrahedral mesh"); } data_.interpolate_at(verts_weights, vals2, vecs2, i); } return std::make_tuple(vals, vecs); } template template std::tuple,brille::Array> Mesh3::parallel_interpolate_at(const bArray& x, const int threads) const { omp_set_num_threads( (threads > 0) ? threads : omp_get_max_threads() ); this->check_before_interpolating(x); // not used in parallel region auto valsh = data_.values().shape(); auto vecsh = data_.vectors().shape(); valsh[0] = x.size(0); vecsh[0] = x.size(0); // shared between threads brille::Array vals(valsh); brille::Array vecs(vecsh); // vals and vecs are row-ordered contiguous by default, so we can create // mutable data-sharing Array2 objects for use with // Interpolator2::interpolate_at through the constructor: brille::Array2 vals2(vals); brille::Array2 vecs2(vecs); // OpenMP < v3.0 (VS uses v2.0) requires signed indexes for omp parallel long xsize = brille::utils::u2s(x.size(0)); #pragma omp parallel for default(none) shared(x, vals2, vecs2, xsize) schedule(dynamic) for (long si=0; si(si); auto verts_weights = this->mesh.locate(x.view(i)); data_.interpolate_at(verts_weights, vals2, vecs2, i); } return std::make_tuple(vals, vecs); } // template template // std::vector // Mesh3::which_neighbours(const std::vector& t, const R value, const ind_t v) const{ // std::vector out; // for (ind_t n: this->mesh.neighbours(v)) if (t[n] == value) out.push_back(n); // return out; // }