diff --git a/dune/gdt/functionals/vector-based.hh b/dune/gdt/functionals/vector-based.hh index b458243de3e1183aa56a82c5eaa9ceda47b1a577..a0dace412bb5bf70022b7c15e370885ca17a68f7 100644 --- a/dune/gdt/functionals/vector-based.hh +++ b/dune/gdt/functionals/vector-based.hh @@ -270,6 +270,12 @@ public: { this->walk(use_tbb); } + + template <class EntityRange> + void assemble_range(const EntityRange& entity_range) + { + this->walk_range(entity_range); + } }; // class VectorBasedFunctional diff --git a/dune/gdt/operators/advection-fv-entropybased.hh b/dune/gdt/operators/advection-fv-entropybased.hh index 23eb42d961ab2e3a943608b4a01f415d90716e51..34137474bee89cd1e5a356e099afabd6550a8957 100644 --- a/dune/gdt/operators/advection-fv-entropybased.hh +++ b/dune/gdt/operators/advection-fv-entropybased.hh @@ -119,8 +119,6 @@ public: void apply(const VectorType& source, VectorType& range, const XT::Common::Parameter& param) const override final { density_op_.apply(source, range, param); - u_update_ = range; - rhs_update_ = range; advection_op_.apply(range, u_update_, param); u_update_ *= -1.; rhs_op_.apply(range, rhs_update_, param); @@ -129,6 +127,22 @@ public: inverse_hessian_operator_.apply_inverse_hessian(u_update_, reg_indicators_, range, param); } + template <class ElementRange> + void apply_range(const VectorType& source, + VectorType& range, + const XT::Common::Parameter& param, + const ElementRange& output_range, + const ElementRange& input_range) + { + // TODO: replace full-dimensional copies if critical for performance of reduced model + density_op_.apply_range(source, range, param, input_range); + advection_op_.apply_range(range, u_update_, param, output_range, input_range); + u_update_ *= -1.; + rhs_op_.apply_range(range, rhs_update_, param, output_range); + u_update_ += rhs_update_; + inverse_hessian_operator_.apply_inverse_hessian_range(u_update_, reg_indicators_, range, param, output_range); + } + const std::vector<bool>& reg_indicators() const { return reg_indicators_; diff --git a/dune/gdt/operators/localizable-operator.hh b/dune/gdt/operators/localizable-operator.hh index 608d254d1b7e9cf9b5cdda2f4bd00481a8446aa5..a4f9c77293d891ae344bbba7a64d0b6a50feb08e 100644 --- a/dune/gdt/operators/localizable-operator.hh +++ b/dune/gdt/operators/localizable-operator.hh @@ -162,6 +162,12 @@ public: return *this; } + template <class EntityRange> + void assemble_range(const EntityRange& element_range) + { + this->walk_range(element_range); + } + protected: const std::unique_ptr<SourceType> source_; RangeType& range_; @@ -380,6 +386,45 @@ public: apply(source_function, range, param); } // ... apply(...) + template <class ElementRange> + void apply_range(const SourceFunctionInterfaceType& source_function, + VectorType& range, + const XT::Common::Parameter& param, + const ElementRange& element_range) const + { + range.set_all(0); + auto range_function = make_discrete_function(this->range_space_, range); + // set up the actual operator + auto localizable_op = + make_localizable_operator_applicator(this->assembly_grid_view_, source_function, range_function); + // - element contributions + for (const auto& op_and_filter : local_element_operators_) { + const auto local_op = op_and_filter.first->with_source(source_function); + const auto& filter = *op_and_filter.second; + localizable_op.append(*local_op, param, filter); + } + // - intersection contributions + for (const auto& op_and_filter : local_intersection_operators_) { + const auto local_op = op_and_filter.first->with_source(source_function); + const auto& filter = *op_and_filter.second; + localizable_op.append(*local_op, param, filter); + } + // and apply it in a grid walk + localizable_op.assemble_range(element_range); + DEBUG_THROW_IF(!range.valid(), Exceptions::operator_error, "range contains inf or nan!"); + } // ... apply_range(...) + + template <class ElementRange> + void apply_range(const VectorType& source, + VectorType& range, + const XT::Common::Parameter& param, + const ElementRange& element_range) const + { + DUNE_THROW_IF(!source.valid(), Exceptions::operator_error, "source contains inf or nan!"); + const auto source_function = make_discrete_function(this->source_space_, source); + apply_range(source_function, range, param, element_range); + } // ... apply_range(...) + // additional convenience apply methods to match the correct one above void apply(const SourceFunctionInterfaceType& source, RangeFunctionType& range, diff --git a/dune/gdt/operators/matrix-based.hh b/dune/gdt/operators/matrix-based.hh index 0ac89cd82863ea2c1873d2c73f0cfc1d88512940..e726ab346bb1f0ad0aebd46ec8cbe74c63e233ca 100644 --- a/dune/gdt/operators/matrix-based.hh +++ b/dune/gdt/operators/matrix-based.hh @@ -491,6 +491,13 @@ public: this->walk(use_tbb); return *this; } + + template <class EntityRange> + ThisType& assemble_range(const EntityRange& entity_range) + { + this->walk_range(entity_range); + return *this; + } }; // class MatrixOperator diff --git a/dune/gdt/operators/reconstruction/linear_kinetic.hh b/dune/gdt/operators/reconstruction/linear_kinetic.hh index 8a75d2025361221f01deb77179fedc529bdb032a..7443b810d61669039d63ba5165ed45b579eee9f6 100644 --- a/dune/gdt/operators/reconstruction/linear_kinetic.hh +++ b/dune/gdt/operators/reconstruction/linear_kinetic.hh @@ -156,6 +156,23 @@ public: walker.walk(true); } // void apply(...) + template <class ElementRange> + void apply_range(const VectorType& /*source*/, + ReconstructedFunctionType& range, + const XT::Common::Parameter& param, + const ElementRange& element_range) const + { + // do reconstruction + const auto& grid_view = space_.grid_view(); + auto local_reconstruction_operator = + LocalPointwiseLinearKineticReconstructionOperator<GV, AnalyticalFluxType, LocalVectorType>( + range, grid_view, analytical_flux_, param); + auto walker = XT::Grid::Walker<GV>(grid_view); + walker.append(local_reconstruction_operator); + walker.walk_range(element_range); + } // void apply(...) + + private: const SpaceType& space_; const AnalyticalFluxType& analytical_flux_; diff --git a/dune/gdt/test/momentmodels/density_evaluator.hh b/dune/gdt/test/momentmodels/density_evaluator.hh index e319947783e3305644635c84a1b637f42cc931ce..b41ca47e65f4b79b49eab8a15945afe2597a3eb4 100644 --- a/dune/gdt/test/momentmodels/density_evaluator.hh +++ b/dune/gdt/test/momentmodels/density_evaluator.hh @@ -172,6 +172,20 @@ public: walker.walk(true); } // void apply(...) + template <class ElementRange> + void apply_range(const VectorType& alpha, + VectorType& range, + const XT::Common::Parameter& param, + const ElementRange& element_range) const + { + LocalDensityEvaluatorType local_density_evaluator( + space_, alpha, range, analytical_flux_, boundary_distribution_, min_acceptable_density_, param); + auto walker = XT::Grid::Walker<typename SpaceType::GridViewType>(space_.grid_view()); + walker.append(local_density_evaluator); + walker.walk_range(element_range); + } // void apply(...) + + private: EntropyFluxType& analytical_flux_; const SpaceType& space_; diff --git a/dune/gdt/test/momentmodels/hessianinverter.hh b/dune/gdt/test/momentmodels/hessianinverter.hh index bcd6aa67f9981072ea4d83e60d2f1de4c5bb8735..651d1968197ec5827c9fe6c88352f161c352a873 100644 --- a/dune/gdt/test/momentmodels/hessianinverter.hh +++ b/dune/gdt/test/momentmodels/hessianinverter.hh @@ -188,6 +188,21 @@ public: walker.walk(true); } // void apply(...) + template <class ElementRange> + void apply_inverse_hessian_range(const VectorType& u_update, + std::vector<bool>& reg_indicators, + VectorType& alpha_update, + const XT::Common::Parameter& param, + const ElementRange& element_range) const + { + LocalEntropicHessianInverter<SpaceType, VectorType, MomentBasis, slope> local_hessian_inverter( + space_, u_update, reg_indicators, alpha_update, analytical_flux_, param); + auto walker = XT::Grid::Walker<typename SpaceType::GridViewType>(space_.grid_view()); + walker.append(local_hessian_inverter); + walker.walk_range(element_range); + } // void apply(...) + + private: const EntropyFluxType& analytical_flux_; const SpaceType& space_;