diff --git a/src/common/aka_iterators.hh b/src/common/aka_iterators.hh index 30ae540eb..455b2eae3 100644 --- a/src/common/aka_iterators.hh +++ b/src/common/aka_iterators.hh @@ -1,285 +1,285 @@ /** * @file aka_iterators.hh * * @author Nicolas Richart * * @date creation Wed Jul 19 2017 * * @brief iterator interfaces * * @section LICENSE * * Copyright (©) 2010-2011 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 #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_AKA_ITERATORS_HH__ #define __AKANTU_AKA_ITERATORS_HH__ namespace akantu { namespace tuple { /* ------------------------------------------------------------------------ */ namespace details { template struct Foreach { template static inline bool not_equal(Tuple && a, Tuple && b) { if (std::get(std::forward(a)) == std::get(std::forward(b))) return false; return Foreach::not_equal(std::forward(a), std::forward(b)); } }; /* ---------------------------------------------------------------------- */ template <> struct Foreach<0> { template static inline bool not_equal(Tuple && a, Tuple && b) { return std::get<0>(std::forward(a)) != std::get<0>(std::forward(b)); } }; template decltype(auto) make_tuple_no_decay(Ts &&... args) { return std::tuple(std::forward(args)...); } template void foreach_impl(F && func, Tuple && tuple, std::index_sequence &&) { (void)std::initializer_list{ (std::forward(func)(std::get(std::forward(tuple))), 0)...}; } template decltype(auto) transform_impl(F && func, Tuple && tuple, std::index_sequence &&) { return make_tuple_no_decay( std::forward(func)(std::get(std::forward(tuple)))...); } - }; // namespace details + } // namespace details /* ------------------------------------------------------------------------ */ template bool are_not_equal(Tuple && a, Tuple && b) { return details::Foreach>::value>:: not_equal(std::forward(a), std::forward(b)); } template void foreach (F && func, Tuple && tuple) { return details::foreach_impl( std::forward(func), std::forward(tuple), std::make_index_sequence< std::tuple_size>::value>{}); } template decltype(auto) transform(F && func, Tuple && tuple) { return details::transform_impl( std::forward(func), std::forward(tuple), std::make_index_sequence< std::tuple_size>::value>{}); } } // namespace tuple /* -------------------------------------------------------------------------- */ namespace iterators { template class ZipIterator { private: using tuple_t = std::tuple; public: explicit ZipIterator(tuple_t iterators) : iterators(std::move(iterators)) {} decltype(auto) operator*() { return tuple::transform([] (auto && it) -> decltype(auto) {return *it;}, iterators); } ZipIterator & operator++() { tuple::foreach ([] (auto && it) { ++it; }, iterators); return *this; } bool operator==(const ZipIterator & other) const { return not tuple::are_not_equal(iterators, other.iterators); } bool operator!=(const ZipIterator & other) const { return tuple::are_not_equal(iterators, other.iterators); } private: tuple_t iterators; }; } // namespace iterators /* -------------------------------------------------------------------------- */ template decltype(auto) zip_iterator(std::tuple && iterators_tuple) { auto zip = iterators::ZipIterator( std::forward(iterators_tuple)); return zip; } /* -------------------------------------------------------------------------- */ namespace containers { template class ZipContainer { using containers_t = std::tuple; public: explicit ZipContainer(Containers &&... containers) : containers(std::forward(containers)...) {} decltype(auto) begin() const { return zip_iterator( tuple::transform([] (auto && c) { return c.begin(); }, std::forward(containers))); } decltype(auto) end() const { return zip_iterator( tuple::transform([] (auto && c) { return c.end(); }, std::forward(containers))); } decltype(auto) begin() { return zip_iterator( tuple::transform([] (auto && c) { return c.begin(); }, std::forward(containers))); } decltype(auto) end() { return zip_iterator( tuple::transform([] (auto && c) { return c.end(); }, std::forward(containers))); } private: containers_t containers; }; } // namespace containers /* -------------------------------------------------------------------------- */ template decltype(auto) zip(Containers &&... conts) { return containers::ZipContainer( std::forward(conts)...); } /* -------------------------------------------------------------------------- */ /* Arange */ /* -------------------------------------------------------------------------- */ namespace iterators { template class ArangeIterator { public: using value_type = T; using pointer = T *; using reference = T &; using iterator_category = std::input_iterator_tag; constexpr ArangeIterator(T value, T step) : value(value), step(step) {} constexpr ArangeIterator(const ArangeIterator &) = default; constexpr ArangeIterator & operator++() { value += step; return *this; } constexpr const T & operator*() const { return value; } constexpr bool operator==(const ArangeIterator & other) const { return (value == other.value) and (step == other.step); } constexpr bool operator!=(const ArangeIterator & other) const { return not operator==(other); } private: T value{0}; const T step{1}; }; } // namespace iterators namespace containers { template class ArangeContainer { public: using iterator = iterators::ArangeIterator; constexpr ArangeContainer(T start, T stop, T step = 1) : start(start), stop((stop - start) % step == 0 ? stop : start + (1 + (stop - start) / step) * step), step(step) {} explicit constexpr ArangeContainer(T stop) : ArangeContainer(0, stop, 1) {} constexpr T operator[](size_t i) { T val = start + i * step; assert(val < stop && "i is out of range"); return val; } constexpr T size() { return (stop - start) / step; } constexpr iterator begin() { return iterator(start, step); } constexpr iterator end() { return iterator(stop, step); } private: const T start{0}, stop{0}, step{1}; }; } // namespace containers template >::value>> inline decltype(auto) arange(const T & stop) { return containers::ArangeContainer(stop); } template >::value>> inline constexpr decltype(auto) arange(const T1 & start, const T2 & stop) { return containers::ArangeContainer>(start, stop); } template >::value>> inline constexpr decltype(auto) arange(const T1 & start, const T2 & stop, const T3 & step) { return containers::ArangeContainer>( start, stop, step); } /* -------------------------------------------------------------------------- */ template inline constexpr decltype(auto) enumerate(Container && container, size_t start_ = 0) { auto stop = std::forward(container).size(); decltype(stop) start = start_; return zip(arange(start, stop), std::forward(container)); } } // namespace akantu #endif /* __AKANTU_AKA_ITERATORS_HH__ */ diff --git a/src/common/aka_named_argument.hh b/src/common/aka_named_argument.hh index b64400f38..0f90486bb 100644 --- a/src/common/aka_named_argument.hh +++ b/src/common/aka_named_argument.hh @@ -1,163 +1,164 @@ /** * @file aka_named_argument.hh * * @author Marco Arena * * @date creation Fri Jun 16 2017 * * @brief A Documented file. * * @section LICENSE * * Public Domain ? https://gist.github.com/ilpropheta/7576dce4c3249df89f85 * */ /* -------------------------------------------------------------------------- */ +#include "aka_compatibilty_with_cpp_standard.hh" #include #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_AKA_NAMED_ARGUMENT_HH__ #define __AKANTU_AKA_NAMED_ARGUMENT_HH__ namespace akantu { namespace named_argument { struct param_t_trait {}; /* -- Pack utils (proxy version) ------------------------------------------ */ /// Proxy containing [tag, value] template struct param_t : param_t_trait { using _tag = tag; using _type = type; template explicit param_t(T && value) : _value(std::forward(value)) {} type _value; }; /* * Tagged proxy that allows syntax _name = value * operator=(T&&) returns a param_t instance **/ template struct param_proxy { using _tag = tag; template decltype(auto) operator=(T && value) { return param_t{std::forward(value)}; } }; /* Same as type_at but it's supposed to be used by passing a pack of param_t (_tag is looked for instead of a plain type). This and type_at should be refactored. */ template struct type_at_p { enum { _tmp = (std::is_same::_tag>::value) ? 0 : type_at_p::_pos }; enum { _pos = _tmp == -1 ? -1 : 1 + _tmp }; }; template struct type_at_p { enum { _pos = (std::is_same::type::_tag>::value ? 1 : -1) }; }; template struct type_at { enum { _pos = -1 }; }; template struct type_at { enum { _tmp = type_at_p::_pos }; enum { _pos = _tmp == 1 ? 0 : (_tmp == -1 ? -1 : _tmp - 1) }; }; /* Same as get_at but it's supposed to be used by passing a pack of param_t (_type is retrieved instead) This and get_at should be refactored. */ template struct get_at { static_assert(pos >= 0, "Required parameter"); template static decltype(auto) get(head &&, tail &&... t) { return get_at::get(std::forward(t)...); } }; template struct get_at { static_assert(pos >= 0, "Required parameter"); template static decltype(auto) get(head && h, tail &&...) { return std::forward(h._value); } }; // Optional version template struct get_optional { template static decltype(auto) get(T &&, pack &&... _pack) { return get_at::get(std::forward(_pack)...); } }; template struct get_optional<-1, curr> { template static decltype(auto) get(T && _default, pack &&...) { return std::forward(_default); } }; } // namespace named_argument // CONVENIENCE MACROS FOR CLASS DESIGNERS ========== #define TAG_OF_ARGUMENT(_name) p_##_name #define TAG_OF_ARGUMENT_WNS(_name) TAG_OF_ARGUMENT(_name) #define REQUIRED_NAMED_ARG(_name) \ named_argument::get_at< \ named_argument::type_at::_pos, \ 0>::get(std::forward(_pack)...) #define REQUIRED_NAMED_ARG(_name) \ named_argument::get_at< \ named_argument::type_at::_pos, \ 0>::get(std::forward(_pack)...) #define OPTIONAL_NAMED_ARG(_name, _defaultVal) \ named_argument::get_optional< \ named_argument::type_at::_pos, \ 0>::get(_defaultVal, std::forward(_pack)...) #define DECLARE_NAMED_ARGUMENT(name) \ struct TAG_OF_ARGUMENT(name) {}; \ named_argument::param_proxy _##name \ __attribute__((unused)) namespace { struct use_named_args_t {}; use_named_args_t use_named_args __attribute__((unused)); } // namespace template struct is_named_argument : public std::false_type {}; template struct is_named_argument> : public std::true_type {}; template using are_named_argument = aka::conjunction>...>; } // namespace akantu #endif /* __AKANTU_AKA_NAMED_ARGUMENT_HH__ */ diff --git a/src/model/structural_mechanics/structural_mechanics_model_mass.cc b/src/model/structural_mechanics/structural_mechanics_model_mass.cc index d5d20a54d..82046c06e 100644 --- a/src/model/structural_mechanics/structural_mechanics_model_mass.cc +++ b/src/model/structural_mechanics/structural_mechanics_model_mass.cc @@ -1,77 +1,77 @@ /** * @file structural_mechanics_model_mass.cc * * @author Sébastien Hartmann * * @date creation: Mon Jul 07 2014 * @date last modification: Thu Oct 15 2015 * * @brief function handling mass computation * * @section LICENSE * * Copyright (©) 2014, 2015 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 "structural_mechanics_model.hh" #include "material.hh" #include "integrator_gauss.hh" #include "shape_structural.hh" /* -------------------------------------------------------------------------- */ namespace akantu { class ComputeRhoFunctor { public: explicit ComputeRhoFunctor(const StructuralMechanicsModel & model) : model(model){}; void operator()(Matrix & rho, const Element & element) const { Real mat_rho = model.getMaterial(element).rho; rho.set(mat_rho); } private: const StructuralMechanicsModel & model; }; /* -------------------------------------------------------------------------- */ void StructuralMechanicsModel::assembleMass(){ AKANTU_DEBUG_IN(); assembleMass(_not_ghost); AKANTU_DEBUG_OUT(); } /* -------------------------------------------------------------------------- */ -void StructuralMechanicsModel::assembleMass(GhostType /*ghost_type*/) { +void StructuralMechanicsModel::assembleMass(GhostType ghost_type) { AKANTU_DEBUG_IN(); MyFEEngineType & fem = getFEEngineClass(); ComputeRhoFunctor compute_rho(*this); for (auto type : mesh.elementTypes(spatial_dimension, ghost_type, _ek_structural)) { fem.assembleFieldMatrix(compute_rho, "M", "displacement", this->getDOFManager(), type, ghost_type); } AKANTU_DEBUG_OUT(); } } // akantu