From f27c726a9de2882fd011a830fce2f7a9e32ea387 Mon Sep 17 00:00:00 2001 From: Jean-Paul Pelteret Date: Thu, 5 Aug 2021 19:57:34 +0200 Subject: [PATCH] Add dof_indices() to FEInterfaceValues --- .../changes/minor/20210805Jean-PaulPelteret | 5 +++ examples/step-74/step-74.cc | 9 ++-- include/deal.II/fe/fe_interface_values.h | 41 +++++++++++++++++++ tests/simplex/step-74.cc | 9 ++-- 4 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 doc/news/changes/minor/20210805Jean-PaulPelteret diff --git a/doc/news/changes/minor/20210805Jean-PaulPelteret b/doc/news/changes/minor/20210805Jean-PaulPelteret new file mode 100644 index 0000000000..d98b09501b --- /dev/null +++ b/doc/news/changes/minor/20210805Jean-PaulPelteret @@ -0,0 +1,5 @@ +New: The function FEInterfaceValues::dof_indices() has been added to make +writing range-based for loops over all local interface degrees of freedom much +simpler. +
+(Jean-Paul Pelteret, 2021/08/05) diff --git a/examples/step-74/step-74.cc b/examples/step-74/step-74.cc index 8a0ee148af..01623b5128 100644 --- a/examples/step-74/step-74.cc +++ b/examples/step-74/step-74.cc @@ -488,9 +488,6 @@ namespace Step74 const FEInterfaceValues &fe_iv = scratch_data.reinit(cell, f, sf, ncell, nf, nsf); - const auto & q_points = fe_iv.get_quadrature_points(); - const unsigned int n_q_points = q_points.size(); - copy_data.face_data.emplace_back(); CopyDataFace & copy_data_face = copy_data.face_data.back(); const unsigned int n_dofs_face = fe_iv.n_current_interface_dofs(); @@ -504,10 +501,10 @@ namespace Step74 const double extent2 = ncell->measure() / ncell->face(nf)->measure(); const double penalty = get_penalty_factor(degree, extent1, extent2); - for (unsigned int point = 0; point < n_q_points; ++point) + for (const unsigned int point : fe_iv.quadrature_point_indices()) { - for (unsigned int i = 0; i < n_dofs_face; ++i) - for (unsigned int j = 0; j < n_dofs_face; ++j) + for (const unsigned int i : fe_iv.dof_indices()) + for (const unsigned int j : fe_iv.dof_indices()) copy_data_face.cell_matrix(i, j) += (-diffusion_coefficient * // - nu fe_iv.jump_in_shape_values(i, point) * // [v_h] diff --git a/include/deal.II/fe/fe_interface_values.h b/include/deal.II/fe/fe_interface_values.h index f285cce413..93a74a1db1 100644 --- a/include/deal.II/fe/fe_interface_values.h +++ b/include/deal.II/fe/fe_interface_values.h @@ -18,6 +18,8 @@ #include +#include + #include #include @@ -721,6 +723,36 @@ public: unsigned n_current_interface_dofs() const; + /** + * Return an object that can be thought of as an array containing all + * indices from zero (inclusive) to `n_current_interface_dofs()` (exclusive). + * This allows one to write code using range-based `for` loops of the + * following kind: + * @code + * FEInterfaceValues fe_iv (...); + * FullMatrix cell_matrix (...); + * + * for (auto &cell : dof_handler.active_cell_iterators()) + * { + * cell_matrix = 0; + * for (const auto &face : cell->face_iterators()) + * { + * fe_iv.values.reinit(cell, face, ...); + * for (const auto q : fe_iv.quadrature_point_indices()) + * for (const auto i : fe_iv.dof_indices()) + * for (const auto j : fe_iv.dof_indices()) + * cell_matrix(i,j) += ...; // Do something for DoF indices + * // (i,j) at quadrature point q + * } + * } + * @endcode + * Here, we are looping over all degrees of freedom on all cell interfaces, + * with `i` and `j` taking on all valid indices for interface degrees of + * freedom, as defined by the finite element passed to `fe_iv`. + */ + std_cxx20::ranges::iota_view + dof_indices() const; + /** * Return the set of joint DoF indices. This includes indices from both cells. * If reinit was called with an active cell iterator, the indices are based @@ -1341,6 +1373,15 @@ FEInterfaceValues::n_current_interface_dofs() const +template +inline std_cxx20::ranges::iota_view +FEInterfaceValues::dof_indices() const +{ + return {0U, n_current_interface_dofs()}; +} + + + template bool FEInterfaceValues::at_boundary() const diff --git a/tests/simplex/step-74.cc b/tests/simplex/step-74.cc index 13d9bde589..815c18aa38 100644 --- a/tests/simplex/step-74.cc +++ b/tests/simplex/step-74.cc @@ -458,9 +458,6 @@ namespace Step74 const FEInterfaceValues &fe_iv = scratch_data.reinit(cell, f, sf, ncell, nf, nsf); - const auto & q_points = fe_iv.get_quadrature_points(); - const unsigned int n_q_points = q_points.size(); - copy_data.face_data.emplace_back(); CopyDataFace & copy_data_face = copy_data.face_data.back(); const unsigned int n_dofs_face = fe_iv.n_current_interface_dofs(); @@ -474,10 +471,10 @@ namespace Step74 const double extent2 = ncell->measure() / ncell->face(nf)->measure(); const double penalty = compute_penalty(degree, extent1, extent2); - for (unsigned int point = 0; point < n_q_points; ++point) + for (const unsigned int point : fe_iv.quadrature_point_indices()) { - for (unsigned int i = 0; i < n_dofs_face; ++i) - for (unsigned int j = 0; j < n_dofs_face; ++j) + for (const unsigned int i : fe_iv.dof_indices()) + for (const unsigned int j : fe_iv.dof_indices()) copy_data_face.cell_matrix(i, j) += (-diffusion_coefficient * // - nu fe_iv.jump_in_shape_values(i, point) * // [v_h] -- 2.39.5