diff --git a/src/common/aka_element_classes_info.hh.in b/src/common/aka_element_classes_info.hh.in index 2b34cddb3..f3c201ba6 100644 --- a/src/common/aka_element_classes_info.hh.in +++ b/src/common/aka_element_classes_info.hh.in @@ -1,209 +1,141 @@ /** * @file aka_element_classes_info.hh.in * * @author Aurelia Isabel Cuba Ramos * @author Nicolas Richart * * @date creation: Sun Jul 19 2015 * @date last modification: Tue Feb 20 2018 * * @brief Declaration of the enums for the element classes * * * Copyright (©) 2015-2018 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_safe_enum.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_AKA_ELEMENT_CLASSES_INFO_HH_ #define AKANTU_AKA_ELEMENT_CLASSES_INFO_HH_ namespace akantu { /* -------------------------------------------------------------------------- */ /* Element Types */ /* -------------------------------------------------------------------------- */ /// @enum ElementType type of elements enum ElementType { _not_defined, @AKANTU_ELEMENT_TYPES_ENUM@ _max_element_type }; @AKANTU_ELEMENT_TYPES_BOOST_SEQ@ @AKANTU_ALL_ELEMENT_BOOST_SEQ@ /* -------------------------------------------------------------------------- */ /* Element Kinds */ /* -------------------------------------------------------------------------- */ @AKANTU_ELEMENT_KINDS_BOOST_SEQ@ @AKANTU_ELEMENT_KIND_BOOST_SEQ@ enum ElementKind { BOOST_PP_SEQ_ENUM(AKANTU_ELEMENT_KIND), _ek_not_defined }; /* -------------------------------------------------------------------------- */ struct ElementKind_def { using type = ElementKind; static const type _begin_ = BOOST_PP_SEQ_HEAD(AKANTU_ELEMENT_KIND); static const type _end_ = _ek_not_defined; }; using element_kind_t = safe_enum ; /* -------------------------------------------------------------------------- */ /// @enum GeometricalType type of element potentially contained in a Mesh enum GeometricalType { @AKANTU_GEOMETRICAL_TYPES_ENUM@ _gt_not_defined }; /* -------------------------------------------------------------------------- */ /* Interpolation Types */ /* -------------------------------------------------------------------------- */ @AKANTU_INTERPOLATION_TYPES_BOOST_SEQ@ /// @enum InterpolationType type of elements enum InterpolationType { BOOST_PP_SEQ_ENUM(AKANTU_INTERPOLATION_TYPES), _itp_not_defined }; /* -------------------------------------------------------------------------- */ /* Some sub types less probable to change */ /* -------------------------------------------------------------------------- */ /// @enum GeometricalShapeType types of shapes to define the contains /// function in the element classes enum GeometricalShapeType { @AKANTU_GEOMETRICAL_SHAPES_ENUM@ _gst_not_defined }; /* -------------------------------------------------------------------------- */ /// @enum GaussIntegrationType classes of types using common /// description of the gauss point position and weights enum GaussIntegrationType { @AKANTU_GAUSS_INTEGRATION_TYPES_ENUM@ _git_not_defined }; /* -------------------------------------------------------------------------- */ /// @enum InterpolationKind the family of interpolation types enum InterpolationKind { @AKANTU_INTERPOLATION_KIND_ENUM@ _itk_not_defined }; -/* -------------------------------------------------------------------------- */ -// BOOST PART: TOUCH ONLY IF YOU KNOW WHAT YOU ARE DOING -#define AKANTU_BOOST_CASE_MACRO(r, macro, _type) \ - case _type: { \ - macro(_type); \ - break; \ - } - -#define AKANTU_BOOST_LIST_SWITCH(macro1, list1, var) \ - do { \ - switch (var) { \ - BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \ - default: { \ - AKANTU_ERROR("Type (" \ - << var /* NOLINT */ << ") not handled by this function"); \ - } \ - } \ - } while (0) - -#define AKANTU_BOOST_LIST_SWITCH_NO_DEFAULT(macro1, list1, var) \ - do { \ - switch (var) { \ - BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \ - case _not_defined: /* FALLTHRU */ \ - case _max_element_type: \ - break; \ - } \ - } while (0) - -#define AKANTU_BOOST_ELEMENT_SWITCH(macro1, list1) \ - AKANTU_BOOST_LIST_SWITCH(macro1, list1, type) - -#define AKANTU_BOOST_ELEMENT_SWITCH_NO_DEFAULT(macro1, list1) \ - AKANTU_BOOST_LIST_SWITCH_NO_DEFAULT(macro1, list1, type) - -#define AKANTU_BOOST_ALL_ELEMENT_SWITCH(macro) \ - AKANTU_BOOST_ELEMENT_SWITCH(macro, AKANTU_ALL_ELEMENT_TYPE) - -#define AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(macro) \ - AKANTU_BOOST_ELEMENT_SWITCH_NO_DEFAULT(macro, AKANTU_ALL_ELEMENT_TYPE) - -#define AKANTU_BOOST_LIST_MACRO(r, macro, type) macro(type) - -#define AKANTU_BOOST_APPLY_ON_LIST(macro, list) \ - BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list) - -#define AKANTU_BOOST_ALL_ELEMENT_LIST(macro) \ - AKANTU_BOOST_APPLY_ON_LIST(macro, AKANTU_ALL_ELEMENT_TYPE) - -#define AKANTU_GET_ELEMENT_LIST(kind) AKANTU##kind##_ELEMENT_TYPE - -#define AKANTU_BOOST_KIND_ELEMENT_SWITCH(macro, kind) \ - AKANTU_BOOST_ELEMENT_SWITCH(macro, AKANTU_GET_ELEMENT_LIST(kind)) - -// BOOST_PP_SEQ_TO_LIST does not exists in Boost < 1.49 -#define AKANTU_GENERATE_KIND_LIST(seq) \ - BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), BOOST_PP_SEQ_TO_TUPLE(seq)) - -#define AKANTU_ELEMENT_KIND_BOOST_LIST \ - AKANTU_GENERATE_KIND_LIST(AKANTU_ELEMENT_KIND) - -#define AKANTU_BOOST_ALL_KIND_LIST(macro, list) \ - BOOST_PP_LIST_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list) - -#define AKANTU_BOOST_ALL_KIND(macro) \ - AKANTU_BOOST_ALL_KIND_LIST(macro, AKANTU_ELEMENT_KIND_BOOST_LIST) - -#define AKANTU_BOOST_ALL_KIND_SWITCH(macro) \ - AKANTU_BOOST_LIST_SWITCH(macro, AKANTU_ELEMENT_KIND, kind) @AKANTU_ELEMENT_KINDS_BOOST_MACROS@ // /// define kept for compatibility reasons (they are most probably not needed // /// anymore) \todo check if they can be removed // #define AKANTU_REGULAR_ELEMENT_TYPE AKANTU_ek_regular_ELEMENT_TYPE // #define AKANTU_COHESIVE_ELEMENT_TYPE AKANTU_ek_cohesive_ELEMENT_TYPE // #define AKANTU_STRUCTURAL_ELEMENT_TYPE AKANTU_ek_structural_ELEMENT_TYPE // #define AKANTU_IGFEM_ELEMENT_TYPE AKANTU_ek_igfem_ELEMENT_TYPE + /* -------------------------------------------------------------------------- */ /* Lists of interests for FEEngineTemplate functions */ /* -------------------------------------------------------------------------- */ @AKANTU_FE_ENGINE_LISTS@ } // akantu #endif /* AKANTU_AKA_ELEMENT_CLASSES_INFO_HH_ */ #include "aka_element_classes_info_inline_impl.hh" diff --git a/src/common/aka_element_classes_info_inline_impl.hh b/src/common/aka_element_classes_info_inline_impl.hh index e5f889756..1407320ff 100644 --- a/src/common/aka_element_classes_info_inline_impl.hh +++ b/src/common/aka_element_classes_info_inline_impl.hh @@ -1,55 +1,226 @@ /** * @file aka_element_classes_info_inline_impl.hh * * @author Aurelia Isabel Cuba Ramos * @author Nicolas Richart * * @date creation: Thu Jun 18 2015 * @date last modification: Tue Sep 29 2020 * * @brief Implementation of the streaming fonction for the element classes * enums * * * @section LICENSE * * Copyright (©) 2015-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_config.hh" +#include "aka_tuple_tools.hh" +/* -------------------------------------------------------------------------- */ +#include #include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_AKA_ELEMENT_CLASSES_INFO_INLINE_IMPL_HH_ #define AKANTU_AKA_ELEMENT_CLASSES_INFO_INLINE_IMPL_HH_ namespace akantu { +/* -------------------------------------------------------------------------- */ +// BOOST PART: TOUCH ONLY IF YOU KNOW WHAT YOU ARE DOING +#define AKANTU_BOOST_CASE_MACRO(r, macro, _type) \ + case _type: { \ + macro(_type); \ + break; \ + } + +#define AKANTU_BOOST_LIST_SWITCH(macro1, list1, var) \ + do { \ + switch (var) { \ + BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \ + default: { \ + AKANTU_ERROR("Type (" << var << ") not handled by this function"); \ + } \ + } \ + } while (0) + +#define AKANTU_BOOST_LIST_SWITCH_NO_DEFAULT(macro1, list1, var) \ + do { \ + switch (var) { \ + BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \ + case _not_defined: \ + break; \ + case _max_element_type: \ + break; \ + } \ + } while (0) + +#define AKANTU_BOOST_LIST_SWITCH_CONSTEXPR(macro1, list1, var) \ + do { \ + switch (var) { \ + BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_CASE_MACRO, macro1, list1) \ + default: { \ + macro1(_not_defined); \ + } \ + } \ + } while (0) + +#define AKANTU_BOOST_ELEMENT_SWITCH(macro1, list1) \ + AKANTU_BOOST_LIST_SWITCH(macro1, list1, type) + +#define AKANTU_BOOST_ELEMENT_SWITCH_NO_DEFAULT(macro1, list1) \ + AKANTU_BOOST_LIST_SWITCH_NO_DEFAULT(macro1, list1, type) + +#define AKANTU_BOOST_ELEMENT_SWITCH_CONSTEXPR(macro1, list1) \ + AKANTU_BOOST_LIST_SWITCH_CONSTEXPR(macro1, list1, type) + +#define AKANTU_BOOST_ALL_ELEMENT_SWITCH(macro) \ + AKANTU_BOOST_ELEMENT_SWITCH(macro, AKANTU_ALL_ELEMENT_TYPE) + +#define AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(macro) \ + AKANTU_BOOST_ELEMENT_SWITCH_NO_DEFAULT(macro, AKANTU_ALL_ELEMENT_TYPE) + +#define AKANTU_BOOST_ALL_ELEMENT_SWITCH_CONSTEXPR(macro) \ + AKANTU_BOOST_ELEMENT_SWITCH_CONSTEXPR(macro, AKANTU_ALL_ELEMENT_TYPE) + +#define AKANTU_BOOST_LIST_MACRO(r, macro, type) macro(type) + +#define AKANTU_BOOST_APPLY_ON_LIST(macro, list) \ + BOOST_PP_SEQ_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list) + +#define AKANTU_BOOST_ALL_ELEMENT_LIST(macro) \ + AKANTU_BOOST_APPLY_ON_LIST(macro, AKANTU_ALL_ELEMENT_TYPE) + +#define AKANTU_GET_ELEMENT_LIST(kind) AKANTU##kind##_ELEMENT_TYPE + +#define AKANTU_BOOST_KIND_ELEMENT_SWITCH(macro, kind) \ + AKANTU_BOOST_ELEMENT_SWITCH(macro, AKANTU_GET_ELEMENT_LIST(kind)) + +// BOOST_PP_SEQ_TO_LIST does not exists in Boost < 1.49 +#define AKANTU_GENERATE_KIND_LIST(seq) \ + BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(seq), BOOST_PP_SEQ_TO_TUPLE(seq)) + +#define AKANTU_ELEMENT_KIND_BOOST_LIST \ + AKANTU_GENERATE_KIND_LIST(AKANTU_ELEMENT_KIND) + +#define AKANTU_BOOST_ALL_KIND_LIST(macro, list) \ + BOOST_PP_LIST_FOR_EACH(AKANTU_BOOST_LIST_MACRO, macro, list) + +#define AKANTU_BOOST_ALL_KIND(macro) \ + AKANTU_BOOST_ALL_KIND_LIST(macro, AKANTU_ELEMENT_KIND_BOOST_LIST) + +#define AKANTU_BOOST_ALL_KIND_SWITCH(macro) \ + AKANTU_BOOST_LIST_SWITCH(macro, AKANTU_ELEMENT_KIND, kind) + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + AKANTU_ENUM_OUTPUT_STREAM( ElementType, AKANTU_ALL_ELEMENT_TYPE(_not_defined)(_max_element_type)) AKANTU_ENUM_INPUT_STREAM(ElementType, AKANTU_ALL_ELEMENT_TYPE) AKANTU_ENUM_OUTPUT_STREAM(InterpolationType, AKANTU_INTERPOLATION_TYPES) AKANTU_ENUM_INPUT_STREAM(InterpolationType, AKANTU_INTERPOLATION_TYPES) AKANTU_ENUM_OUTPUT_STREAM(ElementKind, AKANTU_ELEMENT_KIND) AKANTU_ENUM_INPUT_STREAM(ElementKind, AKANTU_ELEMENT_KIND) +template <::akantu::ElementType t> +using element_type_t = std::integral_constant<::akantu::ElementType, t>; + +#define OP_CAT(s, data, elem) BOOST_PP_CAT(_element_type, elem) + +// creating a type instead of a using helps to debug +#define AKANTU_DECLARE_ELEMENT_TYPE_STRUCT(r, data, elem) \ + struct BOOST_PP_CAT(_element_type, elem) \ + : public element_type_t<::akantu::elem> {}; + +BOOST_PP_SEQ_FOR_EACH(AKANTU_DECLARE_ELEMENT_TYPE_STRUCT, _, + AKANTU_ALL_ELEMENT_TYPE) + +#undef AKANTU_DECLARE_ELEMENT_TYPE_STRUCT + +template struct ElementTypes; + +template <> struct ElementTypes<_ek_regular> { + using type = std::tuple; +}; + +#if defined(AKANTU_COHESIVE_ELEMENT) +template <> struct ElementTypes<_ek_cohesive> { + using type = std::tuple; +}; +#endif + +#if defined(AKANTU_STRUCTURAL_MECHANICS) +template <> struct ElementTypes<_ek_structural> { + using type = std::tuple; +}; +#endif + +#undef OP_CAT + +template +using ElementTypes_t = typename ElementTypes::type; + +#define OP_CAT(s, data, elem) ElementTypes_t +using AllElementTypes = tuple::cat_t; +#undef OP_CAT + +namespace details { + template struct visit_tuple_impl { + template + static constexpr decltype(auto) visit(const Tuple &, Function && function, + const DynamicType & type) { + using integral_type = std::tuple_element_t; + if (integral_type::value == type) { + return function(integral_type{}); + } else { + return visit_tuple_impl::visit( + Tuple{}, std::forward(function), type); + } + } + }; + + template <> struct visit_tuple_impl<0> { + template + static constexpr decltype(auto) visit(const Tuple &, Function && function, + const DynamicType & /*type*/) { + return function(element_type_t<_not_defined>{}); + } + }; +} // namespace details + +template +constexpr decltype(auto) tuple_dispatch(Function && function, + const DynamicType & type) { + return details::visit_tuple_impl::value>::visit( + Tuple{}, std::forward(function), type); +} + + } // namespace akantu #endif /* AKANTU_AKA_ELEMENT_CLASSES_INFO_INLINE_IMPL_HH_ */ diff --git a/src/fe_engine/fe_engine_template.hh b/src/fe_engine/fe_engine_template.hh index 7eaa35dba..b6c8bac0a 100644 --- a/src/fe_engine/fe_engine_template.hh +++ b/src/fe_engine/fe_engine_template.hh @@ -1,432 +1,450 @@ /** * @file fe_engine_template.hh * * @author Guillaume Anciaux * @author Sébastien Hartmann * @author Mohit Pundir * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Fri May 14 2021 * * @brief templated class that calls integration and shape objects * * * @section LICENSE * * Copyright (©) 2010-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 "fe_engine.hh" //#include "integrator.hh" //#include "shape_functions.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #ifndef AKANTU_FE_ENGINE_TEMPLATE_HH_ #define AKANTU_FE_ENGINE_TEMPLATE_HH_ namespace akantu { class Integrator; class ShapeFunctions; } // namespace akantu namespace akantu { class DOFManager; namespace fe_engine { namespace details { template struct AssembleLumpedTemplateHelper; template struct AssembleFieldMatrixHelper; } // namespace details } // namespace fe_engine template struct AssembleFieldMatrixStructHelper; struct DefaultIntegrationOrderFunctor { template static inline constexpr int getOrder() { return ElementClassProperty::polynomial_degree; } }; /* -------------------------------------------------------------------------- */ template