When I noticed that the preparatory steps took much longer than actually solving the system, I profiled by hand: commenting and uncommeting the code, and measuring elapsed times.
The first point where there is significant slow down comes at that method set to next positive. I attach a simplified code where I use three methods. The second is the one I use. The third is a naive implementation, slower, and the first is the faster, but works for a special case where the descendants are direct children. Probably, the problem is not the filtered iterator, but maybe I should re-think the algorithm, to avoid a costly search for active descendants. On Sat, May 25, 2024, 12:17 AM Wolfgang Bangerth <bange...@colostate.edu> wrote: > On 5/24/24 15:24, Felipe Ponce wrote: > > * > > * > > Is there a better alternative to iterate active descendants? Why is > > /set_to_next_positive/ so slow here?// > > Is it? I would also expect it to be fast, but have also learned that you > can't > judge where a code is slow without benchmarking it. So: Have you run your > code > through a profiler to see where it's actually slow? > > Best > W. > > -- > ------------------------------------------------------------------------ > Wolfgang Bangerth email: bange...@colostate.edu > www: http://www.math.colostate.edu/~bangerth/ > > > -- > The deal.II project is located at http://www.dealii.org/ > For mailing list/forum options, see > https://groups.google.com/d/forum/dealii?hl=en > --- > You received this message because you are subscribed to the Google Groups > "deal.II User Group" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to dealii+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/dealii/6cea45c8-6774-4cf6-909a-da8bd11a87f9%40colostate.edu > . > -- The deal.II project is located at http://www.dealii.org/ For mailing list/forum options, see https://groups.google.com/d/forum/dealii?hl=en --- You received this message because you are subscribed to the Google Groups "deal.II User Group" group. To unsubscribe from this group and stop receiving emails from it, send an email to dealii+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/dealii/CAEjcB7VWURXXnqzc9%2Bt3oEYzgW3F%3DwPU2OqLrY4XzxcyOwiJHw%40mail.gmail.com.
#include <deal.II/grid/tria.h> #include <deal.II/grid/tria_accessor.h> #include <deal.II/grid/grid_generator.h> #include <deal.II/grid/grid_tools.h> #include <deal.II/fe/fe_q.h> #include <deal.II/fe/fe_values.h> #include <deal.II/dofs/dof_handler.h> #include <deal.II/dofs/dof_tools.h> #include <deal.II/numerics/data_out.h> #include <cmath> #include <fstream> #include <iostream> #include <typeinfo> #include <chrono> namespace Static { using namespace dealii; using index_t = unsigned int; using clock_t = std::chrono::steady_clock; using ChildIt = FilteredIterator<typename DoFHandler<2, 3>::active_cell_iterator>; class ActiveChild { public: CellId parent; ActiveChild(const CellId &parent) : parent(parent) {} template <typename Iterator> bool operator()(const Iterator &cell) const { return parent.is_ancestor_of(cell->id()); } }; class Child_Test { public: Child_Test( const index_t n_levels, const index_t fe_degree = 1); void run(); private: void make_grid(); void test_method(); const index_t n_levels; Triangulation<2, 3> tria; FE_Q<2, 3> fe; DoFHandler<2, 3> dof_handler; }; Child_Test::Child_Test( const index_t n_levels, const index_t fe_degree) : n_levels(n_levels), fe(fe_degree), dof_handler(tria) { } void Child_Test::make_grid() { { // Create a 3D meash with the target surface. Triangulation<3> cube_mesh; GridGenerator::hyper_cube(cube_mesh, -1, 1); const std::set<types::boundary_id> boundary_ids = {}; // Extract the surface. GridGenerator::extract_boundary_mesh( cube_mesh, tria, boundary_ids); } tria.refine_global(n_levels); dof_handler.distribute_dofs(fe); } void Child_Test::test_method() { std::vector<index_t> global_dofs(fe.dofs_per_cell); // Iterate through coarse cells. for (index_t idx = 0; idx < tria.n_quads(n_levels - 1); ++idx) { // Define iterators over active cells in coarse cell. const CellAccessor<2, 3> coarse_cell(&tria, n_levels - 1, idx); // Method I: Iterate using indices. for (index_t i = 0; i < coarse_cell.n_children(); ++i) { const index_t id_child = coarse_cell.child(i)->index(); } // Method II: Iterate using filter. // ChildIt cell(ActiveChild(coarse_cell.id())); // ChildIt endc(ActiveChild(coarse_cell.id()), dof_handler.end()); // cell.set_to_next_positive(dof_handler.begin_active()); // for (; cell != endc; ++cell) // { // cell->get_dof_indices(global_dofs); // } // Method II: Iterate without using filter. // for (const auto &cell : dof_handler.active_cell_iterators()) // { // if (coarse_cell.id().is_ancestor_of(cell->id())) // { // cell->get_dof_indices(global_dofs); // } // } } } void Child_Test::run() { clock_t::time_point start; clock_t::time_point end; make_grid(); start = clock_t::now(); test_method(); end = clock_t::now(); std::cout << "Time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << " ms\n"; } } // namespace Static int main() { using namespace Static; Child_Test basic(4); basic.run(); return 0; }