diff --git a/src/fe_engine/gauss_integration_tmpl.hh b/src/fe_engine/gauss_integration_tmpl.hh index 2a2c15a8b..55539a298 100644 --- a/src/fe_engine/gauss_integration_tmpl.hh +++ b/src/fe_engine/gauss_integration_tmpl.hh @@ -1,286 +1,286 @@ /** * @file gauss_integration_tmpl.hh * * @author Nicolas Richart * * @date creation: Tue May 10 2016 * @date last modification: Tue Sep 29 2020 * * @brief implementation of the gauss integration helpers * * * @section LICENSE * * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_math.hh" #ifndef AKANTU_GAUSS_INTEGRATION_TMPL_HH_ #define AKANTU_GAUSS_INTEGRATION_TMPL_HH_ namespace akantu { /* -------------------------------------------------------------------------- */ /* GaussIntegrationElement */ /* -------------------------------------------------------------------------- */ namespace _aka_gauss_helpers { template struct GaussIntegrationNbPoints {}; template struct GaussIntegrationNbPoints<_git_not_defined, n> { static constexpr Int nb_points = 0; }; template struct GaussIntegrationNbPoints<_git_point, n> { static constexpr Int nb_points = 1; }; template struct GaussIntegrationNbPoints<_git_segment, n> { static constexpr Int nb_points = (n + 1) / 2 + (bool((n + 1) % 2) ? 1 : 0); }; #define DECLARE_GAUSS_NB_POINTS(type, order, points) \ template <> struct GaussIntegrationNbPoints { \ static constexpr Int nb_points = points; \ } #define DECLARE_GAUSS_NB_POINTS_PENT(type, order, xo, yo) \ template <> struct GaussIntegrationNbPoints { \ static constexpr Int x_order = xo; \ static constexpr Int yz_order = yo; \ static constexpr Int nb_points = 1; \ } DECLARE_GAUSS_NB_POINTS(_git_triangle, 1, 1); DECLARE_GAUSS_NB_POINTS(_git_triangle, 2, 3); DECLARE_GAUSS_NB_POINTS(_git_triangle, 3, 4); DECLARE_GAUSS_NB_POINTS(_git_triangle, 4, 6); DECLARE_GAUSS_NB_POINTS(_git_triangle, 5, 7); DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 1, 1); DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 2, 4); DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 3, 5); DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 4, 15); DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 5, 15); DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 1, 3, 2); // order 3 in x, order 2 in y and z DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 2, 3, 2); // order 3 in x, order 2 in y and z DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 3, 3, 3); // order 3 in x, order 3 in y and z DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 4, 5, 5); // order 5 in x, order 5 in y and z DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 5, 5, 5); // order 5 in x, order 5 in y and z template struct GaussIntegrationNbPointsHelper { static constexpr Int pnp = GaussIntegrationNbPoints::nb_points; static constexpr Int order = n; static constexpr Int nb_points = pnp; }; template struct GaussIntegrationNbPointsHelper { static constexpr Int nb_points = 0; }; /* ------------------------------------------------------------------------ */ /* Generic helper */ /* ------------------------------------------------------------------------ */ template struct GaussIntegrationTypeDataHelper { using git_np = GaussIntegrationNbPoints; using git_data = GaussIntegrationTypeData; static constexpr Int getNbQuadraturePoints() { return git_np::nb_points; } static constexpr auto getQuadraturePoints() -> Matrix { constexpr auto nb_points = git_np::nb_points; using Matrix = Eigen::Matrix; Matrix quads = Eigen::Map(git_data::quad_positions); return quads; } static constexpr auto getWeights() -> Vector { constexpr auto nb_points = git_np::nb_points; - using Vector = Eigen::Matrix; + using Vector = Eigen::Matrix; Vector weights = Eigen::Map(git_data::quad_weights); return weights; } }; #if !defined(DOXYGEN) /* ------------------------------------------------------------------------ */ /* helper for _segment _quadrangle _hexahedron */ /* ------------------------------------------------------------------------ */ template struct GaussIntegrationTypeDataHelper<_git_segment, dimension, dp> { using git_np = GaussIntegrationNbPoints<_git_segment, dp>; using git_data = GaussIntegrationTypeData<_git_segment, git_np::nb_points>; static constexpr Int getNbQuadraturePoints() { return Math::pow(git_np::nb_points, dimension); } static constexpr auto getQuadraturePoints() -> Matrix { const auto tot_nquad = getNbQuadraturePoints(); const auto nquad = git_np::nb_points; Eigen::Matrix quads; Eigen::Map> pos( git_data::quad_positions); Int offset = 1; for (Int d = 0; d < dimension; ++d) { for (Int n = 0, q = 0; n < tot_nquad; ++n, q += offset) { Int rq = q % tot_nquad + q / tot_nquad; quads(d, rq) = pos(n % nquad); } offset *= nquad; } return quads; } static constexpr Vector< Real, GaussIntegrationTypeDataHelper::getNbQuadraturePoints()> getWeights() { const auto tot_nquad = getNbQuadraturePoints(); const auto nquad = git_np::nb_points; Eigen::Matrix quads_weights; quads_weights.fill(1); Eigen::Map> weights( git_data::quad_weights); Int offset = 1; for (Int d = 0; d < dimension; ++d) { for (Int n = 0, q = 0; n < tot_nquad; ++n, q += offset) { Int rq = q % tot_nquad + q / tot_nquad; quads_weights(rq) *= weights(n % nquad); } offset *= nquad; } return quads_weights; } }; /* ------------------------------------------------------------------------ */ /* helper for _pentahedron */ /* ------------------------------------------------------------------------ */ template struct GaussIntegrationTypeDataHelper<_git_pentahedron, dimension, dp> { using git_info = GaussIntegrationNbPoints<_git_pentahedron, dp>; using git_np_seg = GaussIntegrationNbPoints<_git_segment, git_info::x_order>; using git_np_tri = GaussIntegrationNbPoints<_git_triangle, git_info::yz_order>; using git_data_seg = GaussIntegrationTypeData<_git_segment, git_np_seg::nb_points>; using git_data_tri = GaussIntegrationTypeData<_git_triangle, git_np_tri::nb_points>; static constexpr Int getNbQuadraturePoints() { return git_np_seg::nb_points * git_np_tri::nb_points; } static constexpr auto getQuadraturePoints() -> Matrix { constexpr auto tot_nquad = getNbQuadraturePoints(); constexpr auto nquad_seg = git_np_seg::nb_points; constexpr auto nquad_tri = git_np_tri::nb_points; Matrix quads; Eigen::Map> pos_seg(git_data_seg::quad_positions); Eigen::Map> pos_tri( git_data_tri::quad_positions); for (Int ns = 0, q = 0; ns < nquad_seg; ++ns) { for (Int nt = 0; nt < nquad_tri; ++nt, ++q) { auto && quad = quads(q); quad(_x) = pos_seg(ns); quad(_y) = pos_tri(_x, nt); quad(_z) = pos_tri(_y, nt); } } return quads; } static constexpr auto getWeights() -> Vector { constexpr auto tot_nquad = getNbQuadraturePoints(); constexpr auto nquad_seg = git_np_seg::nb_points; constexpr auto nquad_tri = git_np_tri::nb_points; Vector quads_weights; Eigen::Map> weight_seg( git_data_seg::quad_weights); Eigen::Map> weight_tri( git_data_tri::quad_weights); for (Int ns = 0, q = 0; ns < nquad_seg; ++ns) { for (Int nt = 0; nt < nquad_tri; ++nt, ++q) { quads_weights(q) = weight_seg(ns) * weight_tri(nt); } } return quads_weights; } }; #endif } // namespace _aka_gauss_helpers /* -------------------------------------------------------------------------- */ template constexpr Int GaussIntegrationElement::getNbQuadraturePoints() { using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper< ElementClassProperty::gauss_integration_type, interpolation_property::natural_space_dimension, n>; return data_helper::getNbQuadraturePoints(); } /* -------------------------------------------------------------------------- */ template constexpr auto GaussIntegrationElement::getWeights() { using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper< ElementClassProperty::gauss_integration_type, interpolation_property::natural_space_dimension, n>; return data_helper::getWeights(); } template constexpr auto GaussIntegrationElement::getQuadraturePoints() { using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper< ElementClassProperty::gauss_integration_type, interpolation_property::natural_space_dimension, n>; return data_helper::getQuadraturePoints(); } } // namespace akantu #endif /* AKANTU_GAUSS_INTEGRATION_TMPL_HH_ */