break;
}
}
+ }
+
- // there is another thing here:
- // if any of the lines will be
- // refined, then we may not
- // coarsen the present cell
- if (cell->line(line)->user_flag_set()
- &&
- cell->coarsen_flag_set())
+ // there is another thing here:
+ // if any of the lines will be
+ // refined, then we may not
+ // coarsen the present cell
+ for (active_cell_iterator cell=last_active(); cell!=end(); --cell)
+ {
+ if (cell->coarsen_flag_set())
+ for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++line)
{
- cell->clear_coarsen_flag ();
- mesh_changed = true;
+ if (cell->line(line)->user_flag_set())
+ {
+ cell->clear_coarsen_flag ();
+ mesh_changed = true;
- break;
- }
+ goto next_cell;
+ }
- // similarly, if any of the lines
- // *is* already refined, we may
- // not coarsen the current
- // cell. however, there's a
- // catch: if the line is refined,
- // but the cell behind it is
- // going to be coarsened, then
- // the situation changes. if we
- // forget this second condition,
- // the refine_and_coarsen_3d test
- // will start to fail. note that
- // to know which cells are going
- // to be coarsened, the call for
- // fix_coarsen_flags above is
- // necessary
- //
- // the problem is that finding
- // all cells that are behind an
- // edge in 3d is somewhat of a
- // pain and worst of all
- // introduces a quadratic
- // behavior in this algorithm. on
- // the other hand, not many cells
- // have their coarsen flag set
- // usually, and fixing
- // refine_and_coarsen_3d is a
- // somewhat important case
- if (cell->line(line)->has_children() &&
- cell->coarsen_flag_set())
- {
- bool cant_be_coarsened = false;
-
- // loop over all cells of this
- // level to find neighbors of
- // this cell and edge
- for (cell_iterator edge_neighbor=begin(cell->level());
- ((edge_neighbor != end(cell->level()))
- &&
- (cant_be_coarsened == false));
- ++edge_neighbor)
- if (edge_neighbor != cell)
- for (unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++e)
- if (edge_neighbor->line(e) == cell->line(line))
- {
- // this is a cell
- // that is adjacent
- // to the present
- // cell across this
- // edge. so treat
- // it, but only if
- // it is actually
- // refined or will
- // be refined
- if (! (cell->has_children()
- ||
- (!cell->has_children() &&
- cell->refine_flag_set())))
- break;
-
- // figure out if
- // the neighbor is
- // going to be
- // coarsened. as a
- // post-condition
- // of the call to
- // fix_coarsen_flags(),
- // either all
- // children of a
- // cell must be
- // flagged for
- // coarsening, or
- // none may. above
- // we delete some
- // coarsen flags,
- // and in the next
- // call to
- // fix_coarsen_flags()
- // the flags to all
- // siblings will be
- // removed. we will
- // check here if
- // still all
- // children have
- // that flag set
- unsigned int n_children_flagged = 0;
- for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
- if ((edge_neighbor->child(c)->has_children() == false)
- &&
- edge_neighbor->child(c)->coarsen_flag_set())
- ++n_children_flagged;
+ // similarly, if any of the lines
+ // *is* already refined, we may
+ // not coarsen the current
+ // cell. however, there's a
+ // catch: if the line is refined,
+ // but the cell behind it is
+ // going to be coarsened, then
+ // the situation changes. if we
+ // forget this second condition,
+ // the refine_and_coarsen_3d test
+ // will start to fail. note that
+ // to know which cells are going
+ // to be coarsened, the call for
+ // fix_coarsen_flags above is
+ // necessary
+ //
+ // the problem is that finding
+ // all cells that are behind an
+ // edge in 3d is somewhat of a
+ // pain and worst of all
+ // introduces a quadratic
+ // behavior in this algorithm. on
+ // the other hand, not many cells
+ // have their coarsen flag set
+ // usually, and fixing
+ // refine_and_coarsen_3d is a
+ // somewhat important case
+ if (cell->line(line)->has_children())
+ {
+ bool cant_be_coarsened = false;
+
+ // loop over all cells of this
+ // level to find neighbors of
+ // this cell and edge
+ for (cell_iterator edge_neighbor=begin(cell->level());
+ ((edge_neighbor != end(cell->level()))
+ &&
+ (cant_be_coarsened == false));
+ ++edge_neighbor)
+ if (edge_neighbor != cell)
+ for (unsigned int e=0; e<GeometryInfo<dim>::lines_per_cell; ++e)
+ if (edge_neighbor->line(e) == cell->line(line))
+ {
+ // this is a cell
+ // that is adjacent
+ // to the present
+ // cell across this
+ // edge. so treat
+ // it, but only if
+ // it is actually
+ // refined or will
+ // be refined
+ if (! (edge_neighbor->has_children()
+ ||
+ (!edge_neighbor->has_children() &&
+ edge_neighbor->refine_flag_set())))
+ break;
+
+ // figure out if
+ // the neighbor is
+ // going to be
+ // coarsened. as a
+ // post-condition
+ // of the call to
+ // fix_coarsen_flags(),
+ // either all
+ // children of a
+ // cell must be
+ // flagged for
+ // coarsening, or
+ // none may. above
+ // we delete some
+ // coarsen flags,
+ // and in the next
+ // call to
+ // fix_coarsen_flags()
+ // the flags to all
+ // siblings will be
+ // removed. we will
+ // check here if
+ // still all
+ // children have
+ // that flag set
+ unsigned int n_children_flagged = 0;
+ for (unsigned int c=0; c<GeometryInfo<dim>::children_per_cell; ++c)
+ if ((edge_neighbor->child(c)->has_children() == false)
+ &&
+ edge_neighbor->child(c)->coarsen_flag_set())
+ ++n_children_flagged;
- // now, if not all
- // children are
- // flagged, then
- // the neighboring
- // cell isn't going
- // to be
- // coarsened. that
- // means that the
- // common edge
- // isn't going to
- // be coarsened and
- // that we can't
- // coarsen the
- // present cell
- if (n_children_flagged !=
- GeometryInfo<dim>::children_per_cell)
- cant_be_coarsened = true;
-
-
- // neighbor was
- // found. no reason
- // to keep looping
- // over edges of
- // the possible
- // edge_neighbor
- break;
- }
+ // now, if not all
+ // children are
+ // flagged, then
+ // the neighboring
+ // cell isn't going
+ // to be
+ // coarsened. that
+ // means that the
+ // common edge
+ // isn't going to
+ // be coarsened and
+ // that we can't
+ // coarsen the
+ // present cell
+ if (n_children_flagged !=
+ GeometryInfo<dim>::children_per_cell)
+ cant_be_coarsened = true;
+
+
+ // neighbor was
+ // found. no reason
+ // to keep looping
+ // over edges of
+ // the possible
+ // edge_neighbor
+ break;
+ }
- if (cant_be_coarsened == true)
- {
- cell->clear_coarsen_flag ();
- mesh_changed = true;
+ if (cant_be_coarsened == true)
+ {
+ cell->clear_coarsen_flag ();
+ mesh_changed = true;
+
+ goto next_cell;
+ }
}
}
- }
+ next_cell:
+ ;
+ }
}
while (mesh_changed == true);
}
// i.e. on the coarsest level are
// deleted explicitly.
clear_user_flags ();
- // number of active children of
- // @p{cell}. number of children of
- // @p{cell} which are flagged for
- // coarsening
- unsigned int flagged_children;
cell_iterator cell = begin(),
endc = end();
continue;
}
- flagged_children = 0;
+ unsigned int flagged_children = 0;
for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell; ++child)
if (cell->child(child)->active() &&
cell->child(child)->coarsen_flag_set())
}
+
template <int dim>
bool Triangulation<dim>::prepare_coarsening_and_refinement ()
{
}
while (mesh_changed_in_this_loop);
+
// find out whether something was really
// changed in this function. Note that
// @p{flags_before_loop} represents the
Assert (cell->line(line)->has_children(),
ExcInternalError());
for (unsigned int c=0; c<2; ++c)
- Assert (!cell->line(line)->child(c)->has_children(),
- ExcInternalError());
+ Assert (!cell->line(line)->child(c)->has_children(),
+ ExcInternalError());
}