Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use std::variant instead of a hand-rolled version. #16355

Merged
merged 1 commit into from Dec 17, 2023

Conversation

bangerth
Copy link
Member

Follow-up to #16350.

Comment on lines -1631 to +1647
std::optional<typename Triangulation<dim, spacedim>::cell_iterator> cell;
const DoFHandler<dim, spacedim> *dof_handler;
bool level_dof_access;
/**
* The cell in question, if one has been assigned to this object. The
* concrete data type can either be a Triangulation cell iterator, a
* DoFHandler cell iterator, or a DoFHandler level cell iterator.
*/
std::optional<
std::variant<typename Triangulation<dim, spacedim>::cell_iterator,
typename DoFHandler<dim, spacedim>::cell_iterator,
typename DoFHandler<dim, spacedim>::level_cell_iterator>>
cell;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the key part of the patch. We really do store a variant already, we just break the data stored into the base object plus potentially the members of a derived class. Using the std::variant is, in my view, a clear win.

case 1:
return std::get<1>(cell.value())->get_dof_handler().n_dofs();
case 2:
return std::get<2>(cell.value())->get_dof_handler().n_dofs();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this patch, but shouldn't we return

Suggested change
return std::get<2>(cell.value())->get_dof_handler().n_dofs();
return std::get<2>(cell.value())->get_dof_handler().n_dofs(std::get<2>(cell.value())->level());

i.e., the number of level dofs rather than the number of dofs globally?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what the code originally did, nor what is apparently necessary to pass the test suite. This function is used in contexts such as this:

template <int dim, int spacedim>
template <typename Number>
void
FEValuesBase<dim, spacedim>::get_function_values(
  const ReadVector<Number> &fe_function,
  std::vector<Number>      &values) const
{
  Assert(this->update_flags & update_values,
         ExcAccessToUninitializedField("update_values"));
  AssertDimension(fe->n_components(), 1);
  Assert(present_cell.is_initialized(), ExcNotReinited());
  AssertDimension(fe_function.size(), present_cell.n_dofs_for_dof_handler());

  // get function values of dofs on this cell
  Vector<Number> dof_values(dofs_per_cell);
  present_cell.get_interpolated_dof_values(fe_function, dof_values);

We pass in a global vector and interpolate it onto the current cell (active or not).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words, I believe that the change I made is correct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for checking, this is not what I expected to happen, but I do see it now.

@kronbichler kronbichler merged commit 671a53c into dealii:master Dec 17, 2023
15 checks passed
@bangerth bangerth deleted the variant branch December 17, 2023 23:37
@bangerth
Copy link
Member Author

In reference to #16346.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants