-
Bastian Telgen authoredBastian Telgen authored
construct_periodic_point_cloud.cc 2.94 KiB
// © 2021 ETH Zurich, Mechanics and Materials Lab
//
// ae108 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or any
// later version.
//
// ae108 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ae108. If not, see <https://www.gnu.org/licenses/>.
#include "ae108/meshing/construct_periodic_point_cloud.h"
#include <Eigen/Dense>
#include <range/v3/view/cartesian_product.hpp>
#include <range/v3/view/zip.hpp>
namespace ae108 {
namespace meshing {
constexpr auto get_array = [](auto &&...x) {
return std::array{std::forward<decltype(x)>(x)...};
};
template <std::size_t Dimension>
const auto construct_point_cloud =
[](const std::array<std::array<double, Dimension>, Dimension> &translations,
const std::array<double, Dimension> &origin, const auto &permutations) {
std::vector<std::array<double, Dimension>> pointCloud(
permutations.size());
for (auto &&[point, tuple] :
ranges::views::zip(pointCloud, permutations)) {
const auto permutation = std::apply(get_array, tuple);
Eigen::Map<Eigen::Matrix<double, Dimension, 1>>(point.data()) =
Eigen::Map<const Eigen::Matrix<double, Dimension, 1>>(
origin.data()) +
(Eigen::Map<const Eigen::Matrix<double, Dimension, Dimension,
Eigen::ColMajor>>(
translations.front().data()) *
Eigen::Map<const Eigen::Matrix<double, Dimension, 1>>(
permutation.data()));
}
return pointCloud;
};
template <>
std::vector<std::array<double, 3>> construct_periodic_point_cloud(
const std::array<std::array<double, 3>, 3> &translations,
std::array<double, 3> origin, std::vector<double> set) noexcept {
return construct_point_cloud<3>(
translations, origin, ranges::views::cartesian_product(set, set, set));
}
template <>
std::vector<std::array<double, 2>> construct_periodic_point_cloud(
const std::array<std::array<double, 2>, 2> &translations,
std::array<double, 2> origin, std::vector<double> set) noexcept {
return construct_point_cloud<2>(translations, origin,
ranges::views::cartesian_product(set, set));
}
template <>
std::vector<std::array<double, 1>> construct_periodic_point_cloud(
const std::array<std::array<double, 1>, 1> &translations,
std::array<double, 1> origin, std::vector<double> set) noexcept {
return construct_point_cloud<1>(translations, origin,
ranges::views::cartesian_product(set));
}
} // namespace meshing
} // namespace ae108