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::optional in fe_values_base.h/cc. #16346

Closed
bangerth opened this issue Dec 12, 2023 · 0 comments · Fixed by #16361
Closed

Use std::optional in fe_values_base.h/cc. #16346

bangerth opened this issue Dec 12, 2023 · 0 comments · Fixed by #16361
Assignees
Milestone

Comments

@bangerth
Copy link
Member

This file has an (internal) data structure CellIteratorContainer that can either store a tria iterator, or a tria iterator plus dof handler with level access information:

  class CellIteratorContainer
  {
  public:
    DeclExceptionMsg(
      ExcNeedsDoFHandler,
      "You have previously called the FEValues::reinit() function with a "
      "cell iterator of type Triangulation<dim,spacedim>::cell_iterator. However, "
      "when you do this, you cannot call some functions in the FEValues "
      "class, such as the get_function_values/gradients/hessians/third_derivatives "
      "functions. If you need these functions, then you need to call "
      "FEValues::reinit() with an iterator type that allows to extract "
      "degrees of freedom, such as DoFHandler<dim,spacedim>::cell_iterator.");

    /**
     * Constructor.
     */
    CellIteratorContainer();

    /**
     * Constructor.
     */
    template <bool lda>
    CellIteratorContainer(
      const TriaIterator<DoFCellAccessor<dim, spacedim, lda>> &cell);

    /**
     * Constructor.
     */
    CellIteratorContainer(
      const typename Triangulation<dim, spacedim>::cell_iterator &cell);

    /**
     * Indicate whether FEValues::reinit() was called.
     */
    bool
    is_initialized() const;

    /**
     * Conversion operator to an iterator for triangulations. This
     * conversion is implicit for the original iterators, since they are derived
     * classes. However, since here we have kind of a parallel class hierarchy,
     * we have to have a conversion operator.
     */
    operator typename Triangulation<dim, spacedim>::cell_iterator() const;

    /**
     * Return the number of degrees of freedom the DoF
     * handler object has to which the iterator belongs to.
     */
    types::global_dof_index
    n_dofs_for_dof_handler() const;

    /**
     * Call @p get_interpolated_dof_values of the iterator with the
     * given arguments.
     */
    template <typename Number>
    void
    get_interpolated_dof_values(const ReadVector<Number> &in,
                                Vector<Number>           &out) const;

    /**
     * Call @p get_interpolated_dof_values of the iterator with the
     * given arguments.
     */
    void
    get_interpolated_dof_values(const IndexSet               &in,
                                Vector<IndexSet::value_type> &out) const;

  private:
    bool                                                 initialized;
    typename Triangulation<dim, spacedim>::cell_iterator cell;
    const DoFHandler<dim, spacedim>                     *dof_handler;
    bool                                                 level_dof_access;
  };

We can combine the cell and initialized variables into a std::optional. Or one could combine all possibilities via a std::variant, though the latter is awkward because a std::variant always needs to store something.

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

Successfully merging a pull request may close this issue.

2 participants