From d22cae4888463ba63a6f1e12aec2c1b94419bfaa Mon Sep 17 00:00:00 2001 From: Tobias Leibner <tobias.leibner@googlemail.com> Date: Fri, 2 Oct 2020 17:46:07 +0200 Subject: [PATCH] [spaces.basis.default] cache evaluations --- dune/gdt/spaces/basis/default.hh | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/dune/gdt/spaces/basis/default.hh b/dune/gdt/spaces/basis/default.hh index a9e4d5085..8f6bd5af9 100644 --- a/dune/gdt/spaces/basis/default.hh +++ b/dune/gdt/spaces/basis/default.hh @@ -114,21 +114,28 @@ private: protected: void post_bind(const ElementType& elemnt) override final { - current_local_fe_ = XT::Common::ConstStorageProvider<LocalFiniteElementInterface<D, d, R, r, rC>>( - self_.local_finite_elements_.get(elemnt.type(), self_.fe_order_)); + auto&& new_geometry_type = elemnt.type(); + if (geometry_type_ != new_geometry_type) { + geometry_type_ = new_geometry_type; + current_local_fe_ = XT::Common::ConstStorageProvider<LocalFiniteElementInterface<D, d, R, r, rC>>( + self_.local_finite_elements_.get(geometry_type_, self_.fe_order_)); + size_ = current_local_fe_.access().size(); + order_ = current_local_fe_.access().basis().order(); + eval_cache_.clear(); + } } public: size_t size(const XT::Common::Parameter& /*param*/ = {}) const override final { DUNE_THROW_IF(!current_local_fe_.valid(), Exceptions::not_bound_to_an_element_yet, ""); - return current_local_fe_.access().size(); + return size_; } int order(const XT::Common::Parameter& /*param*/ = {}) const override final { DUNE_THROW_IF(!current_local_fe_.valid(), Exceptions::not_bound_to_an_element_yet, ""); - return current_local_fe_.access().basis().order(); + return order_; } using BaseType::evaluate; @@ -140,7 +147,13 @@ private: { DUNE_THROW_IF(!current_local_fe_.valid(), Exceptions::not_bound_to_an_element_yet, ""); this->assert_inside_reference_element(point_in_reference_element); - current_local_fe_.access().basis().evaluate(point_in_reference_element, result); + const auto it = eval_cache_.find(point_in_reference_element); + if (it != eval_cache_.end()) + result = it->second; + else { + current_local_fe_.access().basis().evaluate(point_in_reference_element, result); + eval_cache_[point_in_reference_element] = result; + } } void jacobians(const DomainType& point_in_reference_element, @@ -160,7 +173,8 @@ private: // function gradients) to get the transposed jacobian of the basis function (basis function gradient). const auto J_inv_T = this->element().geometry().jacobianInverseTransposed(point_in_reference_element); auto tmp_value = result[0][0]; - for (size_t ii = 0; ii < current_local_fe_.access().basis().size(); ++ii) + const size_t basis_size = current_local_fe_.access().basis().size(); + for (size_t ii = 0; ii < basis_size; ++ii) for (size_t rr = 0; rr < r; ++rr) { J_inv_T.mv(result[ii][rr], tmp_value); result[ii][rr] = tmp_value; @@ -202,6 +216,10 @@ private: private: const DefaultGlobalBasis<GV, r, rC, R>& self_; XT::Common::ConstStorageProvider<LocalFiniteElementInterface<D, d, R, r, rC>> current_local_fe_; + size_t size_; + int order_; + Dune::GeometryType geometry_type_; + mutable std::map<DomainType, std::vector<RangeType>, XT::Common::FieldVectorLess> eval_cache_; }; // class LocalizedDefaultGlobalBasis const GridViewType& grid_view_; -- GitLab