Skip to content

Commit

Permalink
Non local dofs implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-heltai committed Nov 30, 2023
1 parent c8b51f3 commit bbf855b
Show file tree
Hide file tree
Showing 26 changed files with 1,335 additions and 37 deletions.
8 changes: 8 additions & 0 deletions include/deal.II/dofs/dof_accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2022,6 +2022,14 @@ class DoFCellAccessor : public DoFAccessor<dimension_,
void
set_dof_indices(const std::vector<types::global_dof_index> &dof_indices);

/**
* Set the DoF indices of this cell to the given values. This function
* bypasses the DoF cache, if one exists for the given DoF handler class.
*/
void
set_non_local_dof_indices(
const std::vector<types::global_dof_index> &non_local_dof_indices);

/**
* Set the Level DoF indices of this cell to the given values.
*/
Expand Down
227 changes: 225 additions & 2 deletions include/deal.II/dofs/dof_accessor.templates.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,8 @@ namespace internal
dofs_per_vertex = fe.n_dofs_per_vertex(), //
dofs_per_line = fe.n_dofs_per_line(), //
dofs_per_quad = fe.n_dofs_per_quad(0 /*dummy*/), //
dofs_per_hex = fe.n_dofs_per_hex(); //
dofs_per_hex = fe.n_dofs_per_hex(), //
non_local_dofs = fe.n_non_local_dofs_per_cell(); //

unsigned int index = 0;

Expand All @@ -911,6 +912,10 @@ namespace internal

index += interior_dofs;

// 5) non local dofs
if (dim == structdim)
index += non_local_dofs;

return index;
}
else
Expand All @@ -921,6 +926,11 @@ namespace internal

unsigned int index = 0;

const auto diff = [](const auto &p) { return p.second - p.first; };

const unsigned int non_local_dofs =
accessor.get_fe(fe_index).n_non_local_dofs_per_cell();

// 1) VERTEX dofs
for (const auto vertex : accessor.vertex_indices())
index += process_object_range(accessor.get_dof_handler(),
Expand All @@ -945,6 +955,10 @@ namespace internal
// 4) INNER dofs
index += process_object_range(accessor, fe_index).second;

// 5) non local dofs
if (dim == structdim)
index += non_local_dofs;

return index;
}
}
Expand Down Expand Up @@ -1014,7 +1028,8 @@ namespace internal
// even if level_dof_access==false.
(void)count_level_dofs;

const auto &fe = accessor.get_fe(fe_index);
const auto &fe = accessor.get_fe(fe_index);
const auto non_local_dofs_per_cell = fe.n_non_local_dofs_per_cell();

// we want to pass in rvalue 'std::tuple<>' types as `DoFIndicesType`,
// but we need non-const references for std::vector<> types, so get in
Expand Down Expand Up @@ -1141,6 +1156,11 @@ namespace internal
dof_indices_ptr,
dof_processor);

// 5) non_local dofs
for (unsigned int d = 0; d < non_local_dofs_per_cell; ++d, ++index)
{
// TODO: Check if we need DoFOperation::process_dof also here!
}
AssertDimension(n_dof_indices(accessor, fe_index, count_level_dofs),
dof_indices_ptr - get_array_ptr(const_dof_indices));

Expand All @@ -1153,6 +1173,8 @@ namespace internal
types::global_dof_index invalid_index = numbers::invalid_dof_index;
for (; dof_indices_ptr < end_dof_indices; ++dof_indices_ptr)
dof_processor(invalid_index, dof_indices_ptr);

AssertDimension(dof_indices.size(), index);
}


Expand Down Expand Up @@ -1714,6 +1736,126 @@ DoFAccessor<structdim, dim, spacedim, level_dof_access>::get_fe(
}


// [LH: check where to put the non local part of this]

// template <int structdim, int dim, int spacedim, bool level_dof_access>
// inline void
// DoFAccessor<structdim, dim, spacedim, level_dof_access>::get_dof_indices(
// std::vector<types::global_dof_index> &dof_indices,
// const unsigned int fe_index_) const
// {
// Assert(this->dof_handler != nullptr, ExcInvalidObject());

// const unsigned int fe_index =
// (this->dof_handler->hp_capability_enabled == false &&
// fe_index_ == DoFHandler<dim, spacedim>::invalid_fe_index) ?
// DoFHandler<dim, spacedim>::default_fe_index :
// fe_index_;

// Assert(static_cast<unsigned int>(this->level()) <
// this->dof_handler->object_dof_indices.size(),
// ExcMessage(
// "The DoFHandler to which this accessor points has not "
// "been initialized, i.e., it doesn't appear that DoF indices "
// "have been distributed on it."));

// switch (structdim)
// {
// case 1:
// Assert(
// dof_indices.size() ==
// (this->n_vertices() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_vertex() +
// this->dof_handler->get_fe(fe_index).n_dofs_per_line()) +
// this->dof_handler->get_fe(fe_index).n_non_local_dofs_per_cell(),
// ExcVectorDoesNotMatch());
// break;
// case 2:
// Assert(
// dof_indices.size() ==
// (this->n_vertices() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_vertex() +
// this->n_lines() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_line() +
// this->dof_handler->get_fe(fe_index).n_dofs_per_quad()) +
// this->dof_handler->get_fe(fe_index).n_non_local_dofs_per_cell(),
// ExcVectorDoesNotMatch());
// break;
// case 3:
// Assert(
// dof_indices.size() ==
// (this->n_vertices() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_vertex() +
// this->n_lines() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_line() +
// this->n_faces() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_quad() +
// this->dof_handler->get_fe(fe_index).n_dofs_per_hex()) +
// this->dof_handler->get_fe(fe_index).n_non_local_dofs_per_cell(),
// ExcVectorDoesNotMatch());
// break;
// default:
// Assert(false, ExcNotImplemented());
// }


// // this function really only makes sense if either a) there are degrees of
// // freedom defined on the present object, or b) the object is non-active
// // objects but all degrees of freedom are located on vertices, since
// otherwise
// // there are degrees of freedom on sub-objects which are not allocated for
// // this non-active thing
// Assert(this->fe_index_is_active(fe_index) ||
// (this->dof_handler->get_fe(fe_index).n_dofs_per_cell() ==
// this->n_vertices() *
// this->dof_handler->get_fe(fe_index).n_dofs_per_vertex()),
// ExcInternalError());

// // now do the actual work
// dealii::internal::DoFAccessorImplementation::Implementation::get_dof_indices(
// *this, dof_indices, fe_index);
// }



// template <int structdim, int dim, int spacedim, bool level_dof_access>
// inline void
// DoFAccessor<structdim, dim, spacedim, level_dof_access>::get_mg_dof_indices(
// const int level,
// std::vector<types::global_dof_index> &dof_indices,
// const unsigned int fe_index_) const
// {
// Assert(this->dof_handler != nullptr, ExcInvalidObject());

// const unsigned int fe_index =
// (this->dof_handler->hp_capability_enabled == false &&
// fe_index_ == DoFHandler<dim, spacedim>::invalid_fe_index) ?
// DoFHandler<dim, spacedim>::default_fe_index :
// fe_index_;

// internal::DoFAccessorImplementation::Implementation::get_mg_dof_indices(
// *this, level, dof_indices, fe_index);
// }


// template <int structdim, int dim, int spacedim, bool level_dof_access>
// inline void
// DoFAccessor<structdim, dim, spacedim, level_dof_access>::set_mg_dof_indices(
// const int level,
// const std::vector<types::global_dof_index> &dof_indices,
// const unsigned int fe_index_)
// {
// Assert(this->dof_handler != nullptr, ExcInvalidObject());

// const unsigned int fe_index =
// (this->dof_handler->hp_capability_enabled == false &&
// fe_index_ == DoFHandler<dim, spacedim>::invalid_fe_index) ?
// DoFHandler<dim, spacedim>::default_fe_index :
// fe_index_;

// internal::DoFAccessorImplementation::Implementation::set_mg_dof_indices(
// *this, level, dof_indices, fe_index);
// }

template <int structdim, int dim, int spacedim, bool level_dof_access>
inline typename dealii::internal::DoFHandlerImplementation::
Expand Down Expand Up @@ -2121,6 +2263,87 @@ namespace internal
*/
struct Implementation
{
// [LH: check where to put the non-local part of these functions.]

// /**
// * Implement the updating of the cache.
// */
// template <int dim, int spacedim, bool level_dof_access>
// static void
// update_cell_dof_indices_cache(
// const DoFCellAccessor<dim, spacedim, level_dof_access> &accessor)
// {
// // caches are only for cells with DoFs, i.e., for active ones and not
// // FE_Nothing
// if (accessor.has_children())
// return;
// const unsigned int dofs_per_cell =
// accessor.get_fe().n_dofs_per_cell(); if (dofs_per_cell == 0)
// return;

// // call the get_dof_indices() function of DoFAccessor, which goes
// // through all the parts of the cell to get the indices by hand. the
// // corresponding function of DoFCellAccessor can then later use the
// // cache
// std::vector<types::global_dof_index> dof_indices(dofs_per_cell);
// static_cast<
// const dealii::DoFAccessor<dim, dim, spacedim, level_dof_access> &>(
// accessor)
// .get_dof_indices(dof_indices, accessor.active_fe_index());

// types::global_dof_index *next_dof_index =
// const_cast<types::global_dof_index *>(
// dealii::internal::DoFAccessorImplementation::Implementation::
// get_cache_ptr(accessor.dof_handler,
// accessor.present_level,
// accessor.present_index,
// dofs_per_cell));

// for (unsigned int i = 0; i < dofs_per_cell; ++i, ++next_dof_index)
// *next_dof_index = dof_indices[i];
// }



// /**
// * Implement setting non-local dof indices on a cell.
// */
// template <int dim, int spacedim, bool level_dof_access>
// static void
// set_non_local_dof_indices(
// const DoFCellAccessor<dim, spacedim, level_dof_access> &accessor,
// const std::vector<types::global_dof_index>
// &local_non_local_dof_indices)
// {
// Assert(accessor.has_children() == false, ExcInternalError());

// const unsigned int dofs_per_cell =
// accessor.get_fe().n_dofs_per_cell(); const unsigned int
// n_non_local_dofs =
// accessor.get_fe().n_non_local_dofs_per_cell();
// const unsigned int n_local_dofs = dofs_per_cell - n_non_local_dofs;

// AssertDimension(local_non_local_dof_indices.size(),
// n_non_local_dofs);

// // First the easy case.
// if (n_non_local_dofs == 0)
// return;

// types::global_dof_index *next_dof_index =
// const_cast<types::global_dof_index *>(
// dealii::internal::DoFAccessorImplementation::Implementation::
// get_cache_ptr(accessor.dof_handler,
// accessor.present_level,
// accessor.present_index,
// dofs_per_cell)) +
// n_local_dofs;

// for (unsigned int d = 0; d < n_non_local_dofs; ++d, ++next_dof_index)
// *next_dof_index = local_non_local_dof_indices[d];
// }


/**
* Do what the active_fe_index function in the parent class is supposed to
* do.
Expand Down
7 changes: 7 additions & 0 deletions include/deal.II/dofs/dof_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,13 @@ class DoFHandler : public Subscriptor
bool
has_hp_capabilities() const;

/**
* Distribute non local degrees of freedom. The local DoFs need to be
* distributed using distribute_dofs() before calling this function.
*/
void
distribute_non_local_dofs();

/**
* This function returns whether this DoFHandler has DoFs distributed on
* each multigrid level or in other words if distribute_mg_dofs() has been
Expand Down
6 changes: 6 additions & 0 deletions include/deal.II/dofs/dof_levels.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ namespace internal
*/
DoFObjects<dim> dof_object;

/**
* The offsets for each cell of the cache that holds all DoF indices.
* Only used for hp elements.
*/
std::vector<unsigned int> cell_cache_offsets;

/**
* Return a pointer to the beginning of the DoF indices cache for a
* given cell.
Expand Down
Loading

0 comments on commit bbf855b

Please sign in to comment.