On 5/27/24 00:28, Felipe Ponce wrote:
>
> Probably, the problem is not the filtered iterator, but maybe I should
> re-think the algorithm, to avoid a costly search for active descendants.
Yes. The three methods you show in your code are doing very different things:
// 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();
}
Here, for each of the 384 coarse mesh cells in the outer loop (not shown) you
are only looping over the 4 children. So you are touching 384*4 = 1536 cells.
// Method II: Iterate using filter.
cell.set_to_next_positive(dof_handler.begin_active());
for (; cell != endc; ++cell)
{
cell->get_dof_indices(global_dofs);
}
Here, for each of the 384 coarse mesh cells, you are looping over *all* 1536
fine mesh cells. So you are touching 384*1536 = 589,824 cells in either the
set_to_next_positive() call or in the ++cell calls where you need to test
whether a cell is a descendant of the current coarse cell.
// 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);
}
}
And here you do the same, just by hand.
So you are doing fundamentally different things. I'm not surprised you get
fundamentally different run times :-)