--- /dev/null
+Fixed: During coarsening, we need to decide which finite element is assigned
+to parent cells. The decision criterion was not consistent, but is now unified:
+The least dominant element of their children will be picked, according to
+hp::FECollection::find_dominated_fe_extended(). This affects the implementations
+of SolutionTransfer, parallel::distributed::SolutionTransfer, parallel::CellWeights,
+and hp::DoFHandler.
+(Marc Fehling, 2019/06/06)
* data will be packed on the parent cell with its `active_fe_index` and
* unpacked later with the same index on its children. If cells get
* coarsened into one, data will be packed on the children with the least
- * dominating finite element of their common subspace, and unpacked on the
- * parent with this particular finite element.
+ * dominant finite element of their common subspace, and unpacked on the
+ * parent with this particular finite element (consult
+ * hp::FECollection::find_dominated_fe_extended() for more information).
*
* Transferring a solution across refinement works exactly like in the
* non-hp case. However, when considering serialization, we also have to
* - When coarsening cells, the (now active) parent cell will be assigned
* an active FE index that is determined from its (no longer active)
* children, following the FiniteElementDomination logic: Out of the set of
- * elements previously assigned to the former children, we choose the
- * dominating one for the parent cell. If none was found, we pick the least
- * dominant element in the whole collection that dominates all former
- * children. See hp::FECollection::find_dominating_fe_extended() for further
- * information on this topic.
+ * elements previously assigned to the former children, we choose the one
+ * dominated by all children for the parent cell. If none was found, we pick
+ * the most dominant element in the whole collection that is dominated by
+ * all former children. See hp::FECollection::find_dominated_fe_extended()
+ * for further information on this topic.
*
- * @note Finite elements need to be assigned to each cell by calling
- * distribute_dofs() first to make this functionality available.
+ * @note Finite elements need to be assigned to each cell by either calling
+ * set_fe() or distribute_dofs() first to make this functionality available.
*
*
* <h3>Active FE indices and parallel meshes</h3>
*
* It is, thus, not entirely natural what should happen if, for example, a few
* cells are coarsened away. This class then implements the following
- * algorithm: - If a cell is refined, then the values of the solution
- * vector(s) are saved before refinement on the to-be-refined cell and in the
- * space associated with this cell. These values are then interpolated to the
- * finite element spaces of the children post-refinement. This may lose
- * information if, for example, the old cell used a Q2 space and the children
- * use Q1 spaces, or the information may be prolonged if the mother cell used
- * a Q1 space and the children are Q2s. - If cells are to be coarsened, then
- * the values from the child cells are interpolated to the mother cell using
- * the largest of the child cell spaces. For example, if the children of a
- * cell use Q1, Q2 and Q3 spaces, then the values from the children are
- * interpolated into a Q3 space on the mother cell. After refinement, this Q3
- * function on the mother cell is then interpolated into the space the user
- * has selected for this cell (which may be different from Q3, in this
- * example, if the user has set the active_fe_index for a different space
- * post-refinement and before calling hp::DoFHandler::distribute_dofs()).
+ * algorithm:
+ * - If a cell is refined, then the values of the solution vector(s) are
+ * saved before refinement on the to-be-refined cell and in the space
+ * associated with this cell. These values are then interpolated to the finite
+ * element spaces of the children post-refinement. This may lose information
+ * if, for example, the old cell used a Q2 space and the children use Q1
+ * spaces, or the information may be prolonged if the mother cell used a Q1
+ * space and the children are Q2s.
+ * - If cells are to be coarsened, then the values from the child cells are
+ * interpolated to the mother cell using the largest of the child cell spaces,
+ * which will be identified as the least dominant element following the
+ * FiniteElementDomination logic (consult
+ * hp::FECollection::find_dominated_fe_extended() for more information). For
+ * example, if the children of a cell use Q1, Q2 and Q3 spaces, then the
+ * values from the children are interpolated into a Q3 space on the mother
+ * cell. After refinement, this Q3 function on the mother cell is then
+ * interpolated into the space the user has selected for this cell (which may
+ * be different from Q3, in this example, if the user has set the
+ * active_fe_index for a different space post-refinement and before calling
+ * hp::DoFHandler::distribute_dofs()).
*
* @note In the context of hp refinement, if cells are coarsened or the
* polynomial degree is lowered on some cells, then the old finite element
case Triangulation<dim, spacedim>::CELL_COARSEN:
{
std::set<unsigned int> fe_indices_children;
- for (unsigned int child_index = 0;
- child_index < GeometryInfo<dim>::max_children_per_cell;
+ for (unsigned int child_index = 0; child_index < cell->n_children();
++child_index)
fe_indices_children.insert(
cell->child(child_index)->future_fe_index());
- Assert(dof_handler->get_fe_collection().find_dominating_fe_extended(
- fe_indices_children, /*codim=*/0) !=
- numbers::invalid_unsigned_int,
+ fe_index =
+ dof_handler->get_fe_collection().find_dominated_fe_extended(
+ fe_indices_children, /*codim=*/0);
+
+ Assert(fe_index != numbers::invalid_unsigned_int,
ExcMessage(
"No FiniteElement has been found in your FECollection "
- "that dominates all children of a cell you are trying "
- "to coarsen!"));
+ "that is dominated by all children of a cell you are "
+ "trying to coarsen!"));
}
break;
DoFHandlerType::space_dimension>::CELL_COARSEN:
{
// In case of coarsening, we need to find a suitable fe index
- // for the parent cell. We choose the 'least dominating fe'
+ // for the parent cell. We choose the 'least dominant fe'
// on all children from the associated FECollection.
std::set<unsigned int> fe_indices_children;
for (unsigned int child_index = 0;
- child_index < GeometryInfo<dim>::max_children_per_cell;
+ child_index < cell->n_children();
++child_index)
fe_indices_children.insert(
cell->child(child_index)->future_fe_index());
- fe_index = dof_handler->get_fe_collection()
- .find_dominating_fe_extended(fe_indices_children,
- /*codim=*/0);
+ fe_index =
+ dof_handler->get_fe_collection().find_dominated_fe_extended(
+ fe_indices_children, /*codim=*/0);
Assert(
fe_index != numbers::invalid_unsigned_int,
ExcMessage(
"No FiniteElement has been found in your FECollection "
- "that dominates all children of a cell you are trying "
- "to coarsen!"));
+ "that is dominated by all children of a cell you are "
+ "trying to coarsen!"));
break;
}
// check if all children have the same fe index.
fe_index = cell->child(0)->active_fe_index();
for (unsigned int child_index = 1;
- child_index < GeometryInfo<dim>::max_children_per_cell;
+ child_index < cell->n_children();
++child_index)
Assert(cell->child(child_index)->active_fe_index() ==
fe_index,
// Note that the last solution covers the first two
// scenarios, thus we stick with it assuming that we
// won't lose much time/efficiency.
- unsigned int dominating_fe_index =
+ const unsigned int dominating_fe_index =
fe_collection.find_dominating_fe_extended(
- fe_ind_face_subface,
- /*codim=*/1);
+ fe_ind_face_subface, /*codim=*/1);
AssertThrow(
dominating_fe_index != numbers::invalid_unsigned_int,
const dealii::hp::FECollection<dim, spacedim>
&fe_collection = dof_handler.get_fe_collection();
- unsigned int dominating_fe_index =
+ const unsigned int dominating_fe_index =
fe_collection.find_dominating_fe_extended(
- fes,
- /*codim=*/1);
+ fes, /*codim=*/1);
AssertThrow(
dominating_fe_index !=
* their children and thus will be stored as such.
*
* On cells to be coarsened, we choose the finite element on the parent
- * cell from those assigned to their children to be the one dominating
- * all children. If none was found, we pick the least dominant element
- * in the whole collection that dominates all children. See
- * documentation of hp::FECollection::find_dominating_fe_extended() for
- * further information.
+ * cell from those assigned to their children to be the one that is
+ * dominated by all children. If none was found, we pick the most
+ * dominant element in the whole collection that is dominated by all
+ * children. See documentation of
+ * hp::FECollection::find_dominated_fe_extended() for further
+ * information.
*
* On cells intended for p-refinement or p-coarsening, those
* active_fe_indices will be determined by the corresponding flags that
fe_transfer->coarsened_cells_fe_index.end())
{
// Find a suitable active_fe_index for the parent cell
- // based on the least dominating finite element of its
+ // based on the 'least dominant finite element' of its
// children. Consider the childrens' hypothetical future
// index when they have been flagged for p-refinement.
std::set<unsigned int> fe_indices_children;
ExcInternalError());
const unsigned int fe_index =
- dof_handler.fe_collection.find_dominating_fe_extended(
- fe_indices_children,
- /*codim=*/0);
+ dof_handler.fe_collection.find_dominated_fe_extended(
+ fe_indices_children, /*codim=*/0);
Assert(
fe_index != numbers::invalid_unsigned_int,
ExcMessage(
"No FiniteElement has been found in your FECollection "
- "that dominates all children of a cell you are trying "
- "to coarsen!"));
+ "that is dominated by all children of a cell you are "
+ "trying to coarsen!"));
fe_transfer->coarsened_cells_fe_index.insert(
{parent, fe_index});
DEAL:2d:: cellid=3_1:2 fe_index=4 feq_degree=1 coarsening
DEAL:2d:: cellid=3_1:3 fe_index=0 feq_degree=5 coarsening
DEAL:2d::cells after: 16
-DEAL:2d:: cellid=3_0: fe_index=4 feq_degree=1
+DEAL:2d:: cellid=3_0: fe_index=0 feq_degree=5
DEAL:2d:: cellid=0_1:1 fe_index=1 feq_degree=4
DEAL:2d:: cellid=0_1:2 fe_index=2 feq_degree=3
DEAL:2d:: cellid=0_1:3 fe_index=3 feq_degree=2
DEAL:3d:: cellid=7_1:6 fe_index=8 feq_degree=1 coarsening
DEAL:3d:: cellid=7_1:7 fe_index=0 feq_degree=9 coarsening
DEAL:3d::cells after: 64
-DEAL:3d:: cellid=7_0: fe_index=8 feq_degree=1
+DEAL:3d:: cellid=7_0: fe_index=0 feq_degree=9
DEAL:3d:: cellid=0_1:1 fe_index=1 feq_degree=8
DEAL:3d:: cellid=0_1:2 fe_index=2 feq_degree=7
DEAL:3d:: cellid=0_1:3 fe_index=3 feq_degree=6
DEAL:0:3d::myid=0 cellid=0_2:05 fe_index=0 feq_degree=9
DEAL:0:3d::myid=0 cellid=0_2:06 fe_index=0 feq_degree=9
DEAL:0:3d::myid=0 cellid=0_2:07 fe_index=0 feq_degree=9
-DEAL:0:3d::OK
+DEAL:0:3d::OK
DEAL:1:2d::cells before: 16
DEAL:1:2d::myid=1 cellid=2_1:0 fe_index=0 feq_degree=5
DEAL:1:2d::myid=1 cellid=3_1:2 fe_index=1 feq_degree=4 coarsening
DEAL:1:2d::myid=1 cellid=3_1:3 fe_index=2 feq_degree=3 coarsening
DEAL:1:2d::cells after: 16
-DEAL:1:2d::myid=1 cellid=3_0: fe_index=4 feq_degree=1
+DEAL:1:2d::myid=1 cellid=3_0: fe_index=0 feq_degree=5
DEAL:1:2d::myid=1 cellid=1_1:0 fe_index=4 feq_degree=1
DEAL:1:2d::myid=1 cellid=1_1:1 fe_index=0 feq_degree=5
DEAL:1:2d::myid=1 cellid=1_1:2 fe_index=1 feq_degree=4
DEAL:1:3d::myid=1 cellid=7_1:6 fe_index=3 feq_degree=6 coarsening
DEAL:1:3d::myid=1 cellid=7_1:7 fe_index=4 feq_degree=5 coarsening
DEAL:1:3d::cells after: 64
-DEAL:1:3d::myid=1 cellid=7_0: fe_index=8 feq_degree=1
+DEAL:1:3d::myid=1 cellid=7_0: fe_index=0 feq_degree=9
DEAL:1:3d::myid=1 cellid=3_1:0 fe_index=6 feq_degree=3
DEAL:1:3d::myid=1 cellid=3_1:1 fe_index=7 feq_degree=2
DEAL:1:3d::myid=1 cellid=3_1:2 fe_index=8 feq_degree=1
DEAL:0:3d::myid=0 cellid=0_1:5 fe_index=5 feq_degree=4
DEAL:0:3d::myid=0 cellid=0_1:6 fe_index=6 feq_degree=3
DEAL:0:3d::myid=0 cellid=0_1:7 fe_index=7 feq_degree=2
-DEAL:0:3d::cells after: 64
+DEAL:0:3d::cells after: 64
DEAL:0:3d::myid=0 cellid=0_2:00 fe_index=0 feq_degree=9
DEAL:0:3d::myid=0 cellid=0_2:01 fe_index=0 feq_degree=9
DEAL:0:3d::myid=0 cellid=0_2:02 fe_index=0 feq_degree=9
DEAL:7:2d::cells before: 16
DEAL:7:2d::cells after: 16
-DEAL:7:2d::myid=7 cellid=3_0: fe_index=3 feq_degree=2
+DEAL:7:2d::myid=7 cellid=3_0: fe_index=0 feq_degree=5
DEAL:7:2d::OK
DEAL:7:3d::cells before: 64
DEAL:7:3d::myid=7 cellid=7_1:0 fe_index=0 feq_degree=9 coarsening
DEAL:7:3d::myid=7 cellid=7_1:6 fe_index=6 feq_degree=3 coarsening
DEAL:7:3d::myid=7 cellid=7_1:7 fe_index=7 feq_degree=2 coarsening
DEAL:7:3d::cells after: 64
-DEAL:7:3d::myid=7 cellid=7_0: fe_index=7 feq_degree=2
+DEAL:7:3d::myid=7 cellid=7_0: fe_index=0 feq_degree=9
DEAL:7:3d::myid=7 cellid=6_1:0 fe_index=0 feq_degree=9
DEAL:7:3d::myid=7 cellid=6_1:1 fe_index=1 feq_degree=8
DEAL:7:3d::myid=7 cellid=6_1:2 fe_index=2 feq_degree=7
DEAL:1:2d:: cellid=1_1:2 fe_index=1 feq_degree=4
DEAL:1:2d:: cellid=1_1:3 fe_index=2 feq_degree=3
DEAL:1:2d::cells after: 16
-DEAL:1:2d:: cellid=3_0: fe_index=4 feq_degree=1
+DEAL:1:2d:: cellid=3_0: fe_index=0 feq_degree=5
DEAL:1:2d:: cellid=1_1:1 fe_index=0 feq_degree=5
DEAL:1:2d:: cellid=1_1:2 fe_index=1 feq_degree=4
DEAL:1:2d:: cellid=1_1:3 fe_index=2 feq_degree=3
DEAL:1:3d:: cellid=5_1:6 fe_index=3 feq_degree=6
DEAL:1:3d:: cellid=5_1:7 fe_index=4 feq_degree=5
DEAL:1:3d::cells after: 64
-DEAL:1:3d:: cellid=7_0: fe_index=8 feq_degree=1
+DEAL:1:3d:: cellid=7_0: fe_index=0 feq_degree=9
DEAL:1:3d:: cellid=3_1:4 fe_index=3 feq_degree=6
DEAL:1:3d:: cellid=3_1:5 fe_index=4 feq_degree=5
DEAL:1:3d:: cellid=3_1:6 fe_index=5 feq_degree=4
DEAL:1:2d:: cellid=1_1:2 fe_index=1 feq_degree=4
DEAL:1:2d:: cellid=1_1:3 fe_index=2 feq_degree=3
DEAL:1:2d::cells after: 16
-DEAL:1:2d:: cellid=3_0: fe_index=4 feq_degree=1
+DEAL:1:2d:: cellid=3_0: fe_index=0 feq_degree=5
DEAL:1:2d:: cellid=1_1:1 fe_index=0 feq_degree=5
DEAL:1:2d:: cellid=1_1:2 fe_index=1 feq_degree=4
DEAL:1:2d:: cellid=1_1:3 fe_index=2 feq_degree=3
DEAL:1:3d:: cellid=5_1:6 fe_index=3 feq_degree=6
DEAL:1:3d:: cellid=5_1:7 fe_index=4 feq_degree=5
DEAL:1:3d::cells after: 64
-DEAL:1:3d:: cellid=7_0: fe_index=8 feq_degree=1
+DEAL:1:3d:: cellid=7_0: fe_index=0 feq_degree=9
DEAL:1:3d:: cellid=3_1:4 fe_index=3 feq_degree=6
DEAL:1:3d:: cellid=3_1:5 fe_index=4 feq_degree=5
DEAL:1:3d:: cellid=3_1:6 fe_index=5 feq_degree=4