#pragma once #include #include #include #include #include #include namespace AMDiS { namespace Impl { /// Traverse all interior boundary DOFs and apply the functor f. /// The Functor must have the signature `void(int, typename Basis::LocalView, typename Basis::GridView::Intersection)` template void forEachInteriorBoundaryDOF(Basis const& basis, F&& f) { auto localView = basis.localView(); auto seDOFs = Dune::Functions::subEntityDOFs(basis); auto const& gridView = basis.gridView(); for (auto const& element : elements(gridView, typename BackendTraits::PartitionSet{})) { if (element.hasBoundaryIntersections()) { localView.bind(element); for(auto const& intersection: intersections(gridView, element)) if (intersection.boundary()) for(auto localIndex: seDOFs.bind(localView,intersection)) f(localIndex, localView, intersection); } } } } // end namespace Impl template template void DirichletBC:: init(RB const& rowBasis, CB const& colBasis) { using LV = typename CB::LocalView; using IS = typename CB::GridView::Intersection; dirichletNodes_.resize(colBasis.dimension()); dirichletNodes_.assign(dirichletNodes_.size(), false); Impl::forEachInteriorBoundaryDOF(colBasis, [&](int localIndex, LV const& localView, IS const& intersection) { dirichletNodes_[localView.index(localIndex)] = dirichletNodes_[localView.index(localIndex)] || onBoundary(intersection); }); } template template void DirichletBC:: fillBoundaryCondition(Mat& matrix, Sol& solution, Rhs& rhs, RN const& rowNode, RTP rowTreePath, CN const& colNode, CTP colTreePath) { Dune::Hybrid::ifElse(std::is_same, R>{}, [&](auto id) { auto&& gf = makeGridFunction(values_, solution.basis()->gridView()); AMDiS::interpolate(*solution.basis(), id(solution), gf, rowTreePath, tag::defaulted{}, dirichletNodes_); }); dirichletBC(matrix, solution, rhs, dirichletNodes_); } } // end namespace AMDiS