#ifndef DUNE_TNNMG_SUMFUNCTIONALCONSTRAINEDLINEARIZATION_HH #define DUNE_TNNMG_SUMFUNCTIONALCONSTRAINEDLINEARIZATION_HH #include #include #include namespace Dune::TNNMG { /** * \brief A constrained linearization for a sum of functionals * * \tparam F The SumFunctional to be linearized * \tparam BV Bit vector types for the degrees of freedom to be ignored * \tparam Addends A list of ConstrainedLinearization implementations, * corresponding to the sum functional F */ template class SumFunctionalConstrainedLinearization { public: using Matrix = typename std::tuple_element_t<0,typename F::Functions>::Matrix; using Vector = typename F::Vector; using BitVector = BV; using ConstrainedVector = Vector; using ConstrainedMatrix = Matrix; using ConstrainedBitVector = BitVector; /** \brief Constructor */ SumFunctionalConstrainedLinearization(const F& f, const BitVector& ignore) : addends_(std::apply([&](auto&&... fi) { return std::make_tuple(Addends(fi, ignore)...); }, f.functions())), ignore_(ignore) {} /** \brief Pre-compute derivative information at the configuration x */ void bind(const Vector& x) { Hybrid::forEach(addends_, [&](auto&& addend) { addend.bind(x); }); // Compute first derivatives of the functionals Solvers::resizeInitializeZero(negativeGradient_, x); Hybrid::forEach(addends_, [&](auto&& addend) { negativeGradient_ += addend.negativeGradient(); }); // Compute second derivatives of the functionals hessian_ = std::get<0>(addends_).hessian(); Hybrid::forEach(Hybrid::integralRange(std::integral_constant(),Hybrid::size(addends_)), [&](auto i) { hessian_ += std::get(addends_).hessian(); }); //////////////////////////////////////////////////// // Determine which dofs to truncate //////////////////////////////////////////////////// // Truncate all degrees of freedom explicitly requested in the constructor truncationFlags_ = ignore_; // Also truncate a degree of freedom if one of the addends wants it truncated for (std::size_t i=0; i addends_; // Mark degrees of freedom that should be truncated const BitVector& ignore_; Vector negativeGradient_; Matrix hessian_; BitVector truncationFlags_; }; } // namespace Dune::TNNMG #endif // DUNE_TNNMG_SUMFUNCTIONALCONSTRAINEDLINEARIZATION_HH