Skip to content

Commit

Permalink
FEValuesViews::Scalar takes two new optional renumbering vecs.
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-heltai committed Jul 25, 2023
1 parent 9ee53ef commit 419d701
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 7 deletions.
3 changes: 3 additions & 0 deletions doc/news/changes/minor/20230725LucaHeltai
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
New: FEValuesViews::Scalar() now takes two optional renumbering vectors.
<br>
(Luca Heltai, 2023/07/25)
28 changes: 24 additions & 4 deletions include/deal.II/fe/fe_values.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ namespace FEValuesViews
* FEValuesBase).
*/
Scalar(const FEValuesBase<dim, spacedim> &fe_values_base,
const unsigned int component);
const unsigned int component,
const std::vector<unsigned int> & dof_renumbering = {},
const std::vector<unsigned int> & quadrature_renumbering = {});

/**
* Copy constructor. This is not a lightweight object so we don't allow
Expand Down Expand Up @@ -584,6 +586,16 @@ namespace FEValuesViews
* Store the data about shape functions.
*/
std::vector<ShapeFunctionData> shape_function_data;

/**
* Possibly renumber degrees of freedom.
*/
const std::vector<unsigned int> dof_renumbering;

/**
* Possibly renumber quadrature points.
*/
const std::vector<unsigned int> quadrature_renumbering;
};


Expand Down Expand Up @@ -4427,14 +4439,22 @@ namespace FEValuesViews
{
template <int dim, int spacedim>
inline typename Scalar<dim, spacedim>::value_type
Scalar<dim, spacedim>::value(const unsigned int shape_function,
const unsigned int q_point) const
Scalar<dim, spacedim>::value(const unsigned int in_shape_function,
const unsigned int in_q_point) const
{
AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());
Assert(
fe_values->update_flags & update_values,
((typename FEValuesBase<dim, spacedim>::ExcAccessToUninitializedField(
"update_values"))));
AssertIndexRange(in_shape_function, dof_renumbering.size());
AssertIndexRange(in_q_point, quadrature_renumbering.size());
const auto shape_function = dof_renumbering[in_shape_function];
const auto q_point = quadrature_renumbering[in_q_point];
// First the special case
if (shape_function == numbers::invalid_unsigned_int)
return 0;

AssertIndexRange(shape_function, fe_values->fe->n_dofs_per_cell());

// an adaptation of the FEValuesBase::shape_value_component function
// except that here we know the component as fixed and we have
Expand Down
26 changes: 23 additions & 3 deletions source/fe/fe_values.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,36 @@ namespace internal
} // namespace
} // namespace internal


namespace {
// helper function to construct default id renumbering
std::vector<unsigned int>
make_default_renumbering(const unsigned int size)
{
const auto iota =
std_cxx20::ranges::iota_view<unsigned int, unsigned int>(0, size);
return {iota.begin(), iota.end()};
}
}

namespace FEValuesViews
{
template <int dim, int spacedim>
Scalar<dim, spacedim>::Scalar(const FEValuesBase<dim, spacedim> &fe_values,
const unsigned int component)
Scalar<dim, spacedim>::Scalar(
const FEValuesBase<dim, spacedim> &fe_values,
const unsigned int component,
const std::vector<unsigned int> & dof_renumbering,
const std::vector<unsigned int> & quadrature_renumbering)
: fe_values(&fe_values)
, component(component)
, shape_function_data(this->fe_values->fe->n_dofs_per_cell())
, dof_renumbering(dof_renumbering.empty() ?
make_default_renumbering(
this->fe_values->fe->n_dofs_per_cell()) :
dof_renumbering)
, quadrature_renumbering(quadrature_renumbering.empty() ?
make_default_renumbering(
this->fe_values->n_quadrature_points) :
quadrature_renumbering)
{
const FiniteElement<dim, spacedim> &fe = *this->fe_values->fe;
AssertIndexRange(component, fe.n_components());
Expand Down
129 changes: 129 additions & 0 deletions tests/fe/fe_values_views_scalar_01.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// ---------------------------------------------------------------------
//
// Copyright (C) 2023 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE.md at
// the top level directory of deal.II.
//
// ---------------------------------------------------------------------


// Test renumbering of FEValuesViews

#include <deal.II/base/quadrature_lib.h>

#include <deal.II/fe/fe_q.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/fe/mapping_q.h>

#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_refinement.h>
#include <deal.II/grid/tria.h>

#include <fstream>
#include <iostream>

#include "../test_grids.h"
#include "../tests.h"

template <int dim>
void
test()
{
Triangulation<dim> tria;
TestGrids::hyper_line(tria, 2);

DoFHandler<dim> dofh(tria);
FE_Q<dim> fe(1);
dofh.distribute_dofs(fe);

MappingQ<dim> mapping(1);
UpdateFlags update_flags =
update_values | update_quadrature_points | update_JxW_values;

FEValues<dim> fv1(mapping, fe, QGauss<dim>(fe.degree + 1), update_flags);
fv1.reinit(dofh.begin_active());

using iota = std_cxx20::ranges::iota_view<unsigned int, unsigned int>;

{
// No renumbering
FEValuesViews::Scalar<dim> fv1_scalar(fv1, 0);
for (const auto &i : fv1.dof_indices())
{
deallog << "i = " << i << ", fv1_scalar = " << fv1_scalar.value(i, 0)
<< std::endl;
}
}
{
// Trivial renumbering
auto id = iota(0, fv1.dofs_per_cell);
std::vector<unsigned int> renumber(id.begin(), id.end());
FEValuesViews::Scalar<dim> fv1_scalar(fv1, 0, renumber);
for (const auto &i : fv1.dof_indices())
{
deallog << "i = " << i
<< ", fv1_scalar_trivial_renumber = " << fv1_scalar.value(i, 0)
<< std::endl;
}
}
{
// Inverse renumbering
auto id = iota(0, fv1.dofs_per_cell);
std::vector<unsigned int> renumber(id.begin(), id.end());
std::reverse(renumber.begin(), renumber.end());
FEValuesViews::Scalar<dim> fv1_scalar(fv1, 0, renumber);
for (const auto &i : fv1.dof_indices())
{
deallog << "i = " << i
<< ", fv1_scalar_inverse_renumber = " << fv1_scalar.value(i, 0)
<< std::endl;
}
}
// Now test quadrature renumbering
{
// No renumbering
FEValuesViews::Scalar<dim> fv1_scalar(fv1, 0);
for (const auto &q : fv1.quadrature_point_indices())
{
deallog << "q = " << q
<< ", fv1_scalar_0_q = " << fv1_scalar.value(0, q) << std::endl;
}
}
{
// Trivial renumbering
auto id = iota(0, fv1.n_quadrature_points);
std::vector<unsigned int> renumber(id.begin(), id.end());
FEValuesViews::Scalar<dim> fv1_scalar(fv1, 0, {}, renumber);
for (const auto &q : fv1.quadrature_point_indices())
{
deallog << "q = " << q << ", fv1_scalar_0_q_trivial_renumbering = "
<< fv1_scalar.value(0, q) << std::endl;
}
}
{
// Inverse renumbering
auto id = iota(0, fv1.n_quadrature_points);
std::vector<unsigned int> renumber(id.begin(), id.end());
std::reverse(renumber.begin(), renumber.end());
FEValuesViews::Scalar<dim> fv1_scalar(fv1, 0, {}, renumber);
for (const auto &q : fv1.quadrature_point_indices())
{
deallog << "q = " << q << ", fv1_scalar_0_q_inverse_renumbering = "
<< fv1_scalar.value(0, q) << std::endl;
}
}
}

int
main()
{
initlog(1);
test<2>();
}
Empty file.

0 comments on commit 419d701

Please sign in to comment.