In addition, use the standard (orientation, rotation, flip) order in a temporary
translation step.
--- /dev/null
+Changed: GridTools::orthogonal_equality() now returns a
+std::optional<unsigned char> instead of a
+std::optional<std::bitset<3>>. As a consequence,
+PeriodicFacePair now also stores an unsigned char instead of
+a std::bitset<3> to represent the relative orientation of the first face to the
+second face.
+<br>
+(David Wells, 2024/05/25)
* of components of the finite element. This can be used to enforce
* periodicity in only one variable in a system of equations.
*
- * @p face_orientation, @p face_flip and @p face_rotation describe an
- * orientation that should be applied to @p face_1 prior to matching and
- * constraining DoFs. This has nothing to do with the actual orientation of
- * the given faces in their respective cells (which for boundary faces is
- * always the default) but instead how you want to see periodicity to be
- * enforced. For example, by using these flags, you can enforce a condition
- * of the kind $u(0,y)=u(1,1-y)$ (i.e., a Moebius band) or in 3d a twisted
- * torus. More precisely, these flags match local face DoF indices in the
- * following manner:
- *
- * In 2d: <tt>face_orientation</tt> must always be <tt>true</tt>,
- * <tt>face_rotation</tt> is always <tt>false</tt>, and face_flip has the
- * meaning of <tt>line_flip</tt>; this implies e.g. for <tt>Q1</tt>:
- *
- * @code
- *
- * face_orientation = true, face_flip = false, face_rotation = false:
- *
- * face1: face2:
- *
- * 1 1
- * | <--> |
- * 0 0
- *
- * Resulting constraints: 0 <-> 0, 1 <-> 1
- *
- * (Numbers denote local face DoF indices.)
- *
- *
- * face_orientation = true, face_flip = true, face_rotation = false:
- *
- * face1: face2:
- *
- * 0 1
- * | <--> |
- * 1 0
- *
- * Resulting constraints: 1 <-> 0, 0 <-> 1
- * @endcode
- *
- * And similarly for the case of Q1 in 3d:
- *
- * @code
- *
- * face_orientation = true, face_flip = false, face_rotation = false:
- *
- * face1: face2:
- *
- * 2 - 3 2 - 3
- * | | <--> | |
- * 0 - 1 0 - 1
- *
- * Resulting constraints: 0 <-> 0, 1 <-> 1, 2 <-> 2, 3 <-> 3
- *
- * (Numbers denote local face DoF indices.)
- *
- *
- * face_orientation = false, face_flip = false, face_rotation = false:
- *
- * face1: face2:
- *
- * 1 - 3 2 - 3
- * | | <--> | |
- * 0 - 2 0 - 1
- *
- * Resulting constraints: 0 <-> 0, 2 <-> 1, 1 <-> 2, 3 <-> 3
- *
- *
- * face_orientation = true, face_flip = true, face_rotation = false:
- *
- * face1: face2:
- *
- * 1 - 0 2 - 3
- * | | <--> | |
- * 3 - 2 0 - 1
- *
- * Resulting constraints: 3 <-> 0, 2 <-> 1, 1 <-> 2, 0 <-> 3
- *
- *
- * face_orientation = true, face_flip = false, face_rotation = true
- *
- * face1: face2:
- *
- * 0 - 2 2 - 3
- * | | <--> | |
- * 1 - 3 0 - 1
- *
- * Resulting constraints: 1 <-> 0, 3 <-> 1, 0 <-> 2, 2 <-> 3
- *
- * and any combination of that...
- * @endcode
+ * Here, @p combined_orientation is the relative orientation of @p face_1 with
+ * respect to @p face_2. This is typically computed by
+ * GridTools::orthogonal_equality().
*
* Optionally a matrix @p matrix along with a std::vector @p
* first_vector_components can be specified that describes how DoFs on @p
const FaceIterator &face_1,
const std_cxx20::type_identity_t<FaceIterator> &face_2,
AffineConstraints<number> &constraints,
- const ComponentMask &component_mask = {},
- const bool face_orientation = true,
- const bool face_flip = false,
- const bool face_rotation = false,
+ const ComponentMask &component_mask = {},
+ const unsigned char combined_orientation =
+ ReferenceCell::default_combined_face_orientation(),
const FullMatrix<double> &matrix = FullMatrix<double>(),
const std::vector<unsigned int> &first_vector_components =
std::vector<unsigned int>(),
const FullMatrix<double> &transformation,
AffineConstraints<number> &affine_constraints,
const ComponentMask &component_mask,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation,
+ const unsigned char combined_orientation,
const number periodicity_factor,
const unsigned int level = numbers::invalid_unsigned_int);
} // namespace internal
# include <boost/iostreams/stream.hpp>
#endif
-#include <bitset>
#include <optional>
#include <set>
/**
* The relative orientation of the first face with respect to the second
* face as described in orthogonal_equality() and
- * DoFTools::make_periodicity_constraints() (and stored as a bitset).
+ * DoFTools::make_periodicity_constraints().
*/
- std::bitset<3> orientation;
+ unsigned char orientation;
/**
* A @p dim $\times$ @p dim rotation matrix that describes how vector
* identity matrix.
*
* If the matching was successful, the _relative_ orientation of @p face1 with
- * respect to @p face2 is returned a std::optional<std::bitset<3>> object
- * orientation in which
- * @code
- * orientation.value()[0] = face_orientation
- * orientation.value()[1] = face_flip
- * orientation.value()[2] = face_rotation
- * @endcode
- *
- * In 2d <tt>face_orientation</tt> is always <tt>true</tt>,
- * <tt>face_rotation</tt> is always <tt>false</tt>, and face_flip has the
- * meaning of <tt>line_flip</tt>. More precisely in 3d:
- *
- * <tt>face_orientation</tt>: <tt>true</tt> if @p face1 and @p face2 have
- * the same orientation. Otherwise, the vertex indices of @p face1 match the
- * vertex indices of @p face2 in the following manner:
- *
- * @code
- * face1: face2:
- *
- * 1 - 3 2 - 3
- * | | <--> | |
- * 0 - 2 0 - 1
- * @endcode
- *
- * <tt>face_flip</tt>: <tt>true</tt> if the matched vertices are rotated by
- * 180 degrees:
- *
- * @code
- * face1: face2:
- *
- * 1 - 0 2 - 3
- * | | <--> | |
- * 3 - 2 0 - 1
- * @endcode
- *
- * <tt>face_rotation</tt>: <tt>true</tt> if the matched vertices are rotated
- * by 90 degrees counterclockwise:
- *
- * @code
- * face1: face2:
- *
- * 0 - 2 2 - 3
- * | | <--> | |
- * 1 - 3 0 - 1
- * @endcode
- *
- * and any combination of that... More information on the topic can be found
- * in the
+ * respect to @p face2 is returned a std::optional<unsigned char>, in which
+ * the stored value is the same orientation bit format used elsewhere in the
+ * library. More information on that topic can be found in the
* @ref GlossFaceOrientation "glossary"
* article.
*/
template <typename FaceIterator>
- std::optional<std::bitset<3>>
+ std::optional<unsigned char>
orthogonal_equality(
const FaceIterator &face1,
const FaceIterator &face2,
* with faces belonging to the second boundary with the help of
* orthogonal_equality().
*
- * The bitset that is returned inside of PeriodicFacePair encodes the
+ * The unsigned char that is returned inside of PeriodicFacePair encodes the
* _relative_ orientation of the first face with respect to the second face,
* see the documentation of orthogonal_equality() for further details.
*
*/
const std::map<
std::pair<cell_iterator, unsigned int>,
- std::pair<std::pair<cell_iterator, unsigned int>, std::bitset<3>>> &
+ std::pair<std::pair<cell_iterator, unsigned int>, unsigned char>> &
get_periodic_face_map() const;
/**
* face pairs.
*/
std::map<std::pair<cell_iterator, unsigned int>,
- std::pair<std::pair<cell_iterator, unsigned int>, std::bitset<3>>>
+ std::pair<std::pair<cell_iterator, unsigned int>, unsigned char>>
periodic_face_map;
/**
// special treatment of periodic boundaries
if (dim == 3 && cell->has_periodic_neighbor(face_no))
{
- const unsigned int exterior_face_orientation =
- !cell->get_triangulation()
- .get_periodic_face_map()
- .at({cell, face_no})
- .second[0] +
- 2 * cell->get_triangulation()
- .get_periodic_face_map()
- .at({cell, face_no})
- .second[1] +
- 4 * cell->get_triangulation()
- .get_periodic_face_map()
- .at({cell, face_no})
- .second[2];
-
- info.face_orientation = exterior_face_orientation;
+ unsigned char exterior_face_orientation = cell->get_triangulation()
+ .get_periodic_face_map()
+ .at({cell, face_no})
+ .second;
+ const auto [orientation, rotation, flip] =
+ ::dealii::internal::split_face_orientation(
+ exterior_face_orientation);
+
+ info.face_orientation =
+ (orientation ? 0u : 1u) + 2 * flip + 4 * rotation;
return info;
}
typename Triangulation<dim, spacedim>::cell_iterator;
typename std::map<std::pair<cell_iterator, unsigned int>,
std::pair<std::pair<cell_iterator, unsigned int>,
- std::bitset<3>>>::const_iterator it;
+ unsigned char>>::const_iterator it;
for (it = tria.get_periodic_face_map().begin();
it != tria.get_periodic_face_map().end();
++it)
{
- const cell_iterator &cell_1 = it->first.first;
- const unsigned int face_no_1 = it->first.second;
- const cell_iterator &cell_2 = it->second.first.first;
- const unsigned int face_no_2 = it->second.first.second;
- const std::bitset<3> face_orientation = it->second.second;
+ const cell_iterator &cell_1 = it->first.first;
+ const unsigned int face_no_1 = it->first.second;
+ const cell_iterator &cell_2 = it->second.first.first;
+ const unsigned int face_no_2 = it->second.first.second;
+ const unsigned char combined_orientation = it->second.second;
+ const auto [orientation, rotation, flip] =
+ ::dealii::internal::split_face_orientation(combined_orientation);
if (cell_1->level() == cell_2->level())
{
// cell[0] into account
const unsigned int vface0 =
GeometryInfo<dim>::standard_to_real_face_vertex(
- v,
- face_orientation[0],
- face_orientation[1],
- face_orientation[2]);
+ v, orientation, flip, rotation);
const unsigned int vi0 =
topological_vertex_numbering[cell_1->face(face_no_1)
->vertex_index(vface0)];
for (unsigned int repetition = 0; repetition < dim; ++repetition)
for (const auto &it : this->get_periodic_face_map())
{
- const cell_iterator &cell_1 = it.first.first;
- const unsigned int face_no_1 = it.first.second;
- const cell_iterator &cell_2 = it.second.first.first;
- const unsigned int face_no_2 = it.second.first.second;
- const std::bitset<3> &face_orientation = it.second.second;
+ const cell_iterator &cell_1 = it.first.first;
+ const unsigned int face_no_1 = it.first.second;
+ const cell_iterator &cell_2 = it.second.first.first;
+ const unsigned int face_no_2 = it.second.first.second;
+ const unsigned char combined_orientation = it.second.second;
+ const auto [orientation, rotation, flip] =
+ ::dealii::internal::split_face_orientation(combined_orientation);
if (cell_1->level() == level && cell_2->level() == level)
{
// account
const unsigned int vface0 =
GeometryInfo<dim>::standard_to_real_face_vertex(
- v,
- face_orientation[0],
- face_orientation[1],
- face_orientation[2]);
+ v, orientation, flip, rotation);
if (marked_vertices[cell_1->face(face_no_1)->vertex_index(
vface0)] ||
marked_vertices[cell_2->face(face_no_2)->vertex_index(
const unsigned int tree_right =
coarse_cell_to_p4est_tree_permutation[second_cell->index()];
- // p4est wants to know which corner the first corner on
- // the face with the lower id is mapped to on the face with
- // with the higher id. For d==2 there are only two possibilities
- // that are determined by it->orientation[0] (the face_orientation
- // flag). For d==3 we have to use GridTools::OrientationLookupTable.
- // The result is given below.
+ // p4est wants to know which corner the first corner on the face with
+ // the lower id is mapped to on the face with with the higher id. For
+ // d==2 there are only two possibilities: i.e., face_pair.orientation
+ // must be 0 or 1. For d==3 we have to use a lookup table. The result
+ // is given below.
unsigned int p4est_orientation = 0;
if (dim == 2)
- p4est_orientation = face_pair.orientation[0] == true ? 0u : 1u;
+ {
+ AssertIndexRange(face_pair.orientation, 2);
+ p4est_orientation =
+ face_pair.orientation ==
+ ReferenceCell::default_combined_face_orientation() ?
+ 0u :
+ 1u;
+ }
else
{
const unsigned int face_idx_list[] = {face_left, face_right};
Assert(first_dealii_idx_on_face != numbers::invalid_unsigned_int,
ExcInternalError());
// Now map dealii_idx_on_face according to the orientation
+
constexpr unsigned int left_to_right[8][4] = {{0, 2, 1, 3},
{0, 1, 2, 3},
- {3, 1, 2, 0},
- {3, 2, 1, 0},
{2, 3, 0, 1},
{1, 3, 0, 2},
+ {3, 1, 2, 0},
+ {3, 2, 1, 0},
{1, 0, 3, 2},
{2, 0, 3, 1}};
constexpr unsigned int right_to_left[8][4] = {{0, 2, 1, 3},
{0, 1, 2, 3},
- {3, 1, 2, 0},
- {3, 2, 1, 0},
{2, 3, 0, 1},
{2, 0, 3, 1},
+ {3, 1, 2, 0},
+ {3, 2, 1, 0},
{1, 0, 3, 2},
{1, 3, 0, 2}};
const unsigned int second_dealii_idx_on_face =
- lower_idx == 0 ? left_to_right[face_pair.orientation.to_ulong()]
+ lower_idx == 0 ? left_to_right[face_pair.orientation]
[first_dealii_idx_on_face] :
- right_to_left[face_pair.orientation.to_ulong()]
+ right_to_left[face_pair.orientation]
[first_dealii_idx_on_face];
const unsigned int second_dealii_idx_on_cell =
GeometryInfo<dim>::face_to_cell_vertices(
const FullMatrix<double> &transformation,
AffineConstraints<number> &affine_constraints,
const ComponentMask &component_mask,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation,
+ const unsigned char combined_orientation,
const number periodicity_factor,
const unsigned int level)
{
static const int dim = FaceIterator::AccessorType::dimension;
static const int spacedim = FaceIterator::AccessorType::space_dimension;
- const unsigned char combined_face_orientation =
- ::dealii::internal::combined_face_orientation(face_orientation,
- face_rotation,
- face_flip);
-
const bool use_mg = (level != numbers::invalid_unsigned_int);
// If we don't use multigrid, we should be in the case where face_1 is
child_transformation,
affine_constraints,
component_mask,
- face_orientation,
- face_flip,
- face_rotation,
+ combined_orientation,
periodicity_factor);
}
return;
// given orientation:
const unsigned int j =
cell_to_rotated_face_index[fe.face_to_cell_index(
- jj, 0, combined_face_orientation)];
+ jj, 0, combined_orientation)];
if (std::abs(transformation(i, jj)) > eps)
constraint_entries.emplace_back(dofs_1[j],
// orientation:
const unsigned int j =
cell_to_rotated_face_index[fe.face_to_cell_index(
- target, 0, combined_face_orientation)];
+ target, 0, combined_orientation)];
auto dof_left = dofs_1[j];
auto dof_right = dofs_2[i];
const std_cxx20::type_identity_t<FaceIterator> &face_2,
AffineConstraints<number> &affine_constraints,
const ComponentMask &component_mask,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation,
+ const unsigned char combined_orientation,
const FullMatrix<double> &matrix,
const std::vector<unsigned int> &first_vector_components,
const number periodicity_factor)
static const int dim = FaceIterator::AccessorType::dimension;
static const int spacedim = FaceIterator::AccessorType::space_dimension;
- Assert((dim != 1) || (face_orientation == true && face_flip == false &&
- face_rotation == false),
- ExcMessage("The supplied orientation "
- "(face_orientation, face_flip, face_rotation) "
+#ifdef DEBUG
+ const auto [orientation, rotation, flip] =
+ ::dealii::internal::split_face_orientation(combined_orientation);
+
+ Assert((dim != 1) ||
+ (orientation == true && flip == false && rotation == false),
+ ExcMessage("The supplied orientation (orientation, rotation, flip) "
"is invalid for 1d"));
- Assert((dim != 2) || (face_flip == false && face_rotation == false),
- ExcMessage("The supplied orientation "
- "(face_orientation, face_flip, face_rotation) "
+ Assert((dim != 2) || (flip == false && rotation == false),
+ ExcMessage("The supplied orientation (orientation, rotation, flip) "
"is invalid for 2d"));
Assert(face_1 != face_2,
ExcMessage("first_vector_components is nonempty, so matrix must "
"be a rotation matrix exactly of size spacedim"));
- const unsigned char combined_orientation =
- ::dealii::internal::combined_face_orientation(face_orientation,
- face_rotation,
- face_flip);
-
-#ifdef DEBUG
if (!face_1->has_children())
{
// TODO: the implementation makes the assumption that all faces have the
face_2->child(j),
affine_constraints,
component_mask,
- face_orientation,
- face_flip,
- face_rotation,
+ combined_orientation,
matrix,
first_vector_components,
periodicity_factor);
transformation,
affine_constraints,
component_mask,
- face_orientation,
- face_flip,
- face_rotation,
+ combined_orientation,
periodicity_factor);
}
else
inverse,
affine_constraints,
component_mask,
- face_orientation,
- face_flip,
- face_rotation,
+ combined_orientation,
periodicity_factor);
}
}
// the rotation when constraining face_2 to face_1. Therefore
// face_flip has to be toggled if face_rotation is true: In case of
// inverted orientation, nothing has to be done.
- internal::set_periodicity_constraints(face_1,
- face_2,
- transformation,
- affine_constraints,
- component_mask,
- face_orientation,
- face_orientation ?
- face_rotation ^ face_flip :
- face_flip,
- face_rotation,
- periodicity_factor);
+
+ internal::set_periodicity_constraints(
+ face_1,
+ face_2,
+ transformation,
+ affine_constraints,
+ component_mask,
+ ::dealii::internal::combined_face_orientation(
+ orientation, rotation, orientation ? rotation ^ flip : flip),
+ periodicity_factor);
}
}
}
face_2,
constraints,
component_mask,
- pair.orientation[0],
- pair.orientation[1],
- pair.orientation[2],
+ pair.orientation,
pair.matrix,
first_vector_components,
periodicity_factor);
deal_II_space_dimension>::face_iterator &,
AffineConstraints<S> &,
const ComponentMask &,
- bool,
- bool,
- bool,
+ const unsigned char,
const FullMatrix<double> &,
const std::vector<unsigned int> &,
const S);
const FullMatrix<double> &transformation,
AffineConstraints<S> &affine_constraints,
const ComponentMask &component_mask,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation,
+ const unsigned char combined_orientation,
const S periodicity_factor,
const unsigned int level);
const FullMatrix<double> &transformation,
AffineConstraints<S> &affine_constraints,
const ComponentMask &component_mask,
- const bool face_orientation,
- const bool face_flip,
- const bool face_rotation,
+ const unsigned char combined_orientation,
const S periodicity_factor,
const unsigned int level);
#endif
const auto face_a = pair.first.first->face(pair.first.second);
const auto face_b =
pair.second.first.first->face(pair.second.first.second);
- const auto mask = pair.second.second;
+ const unsigned char combined_orientation = pair.second.second;
AssertDimension(face_a->n_vertices(), face_b->n_vertices());
// loop over all vertices on face
for (unsigned int i = 0; i < face_a->n_vertices(); ++i)
{
- const bool face_orientation = mask[0];
- const bool face_flip = mask[1];
- const bool face_rotation = mask[2];
+ const auto [face_orientation, face_rotation, face_flip] =
+ ::dealii::internal::split_face_orientation(
+ combined_orientation);
// find the right local vertex index for the second face
unsigned int j = 0;
const CellIterator cell2 = it2->first;
const unsigned int face_idx1 = it1->second;
const unsigned int face_idx2 = it2->second;
- if (const std::optional<std::bitset<3>> orientation =
+ if (const std::optional<unsigned char> orientation =
GridTools::orthogonal_equality(cell1->face(face_idx1),
cell2->face(face_idx2),
direction,
template <typename FaceIterator>
- std::optional<std::bitset<3>>
+ std::optional<unsigned char>
orthogonal_equality(
const FaceIterator &face1,
const FaceIterator &face2,
face1_vertices.cbegin() + face1->n_vertices()),
make_array_view(face2_vertices.cbegin(),
face2_vertices.cbegin() + face2->n_vertices()));
- std::bitset<3> orientation;
+ unsigned char orientation = std::numeric_limits<unsigned char>::max();
if (dim == 1)
{
// In 1D things are always well-oriented
else
{
Assert(dim == 3, ExcInternalError());
- // There are two differences between the orientation implementation
- // used in the periodicity code and that used in ReferenceCell:
- //
- // 1. The bitset is unpacked as (orientation, flip, rotation)
- // instead of the standard (orientation, rotation, flip).
- //
- // 2. The 90 degree rotations are always clockwise, so the third and
- // seventh (in the combined orientation) are switched.
- //
- // Both translations are encoded in this table. This matches
- // OrientationLookupTable<3> which was present in previous revisions
- // of this file.
+ // Unlike the standard orientation, here the 90 degree rotations are
+ // always clockwise, so the third and seventh (in the combined
+ // orientation) are switched.
constexpr std::array<unsigned int, 8> translation{
- {0, 1, 4, 7, 2, 3, 6, 5}};
+ {0, 1, 2, 7, 4, 5, 6, 3}};
AssertIndexRange(combined_orientation, translation.size());
orientation =
translation[std::min<unsigned int>(combined_orientation, 7u)];
namespace GridTools
\{
- template std::optional<std::bitset<3>>
+ template std::optional<unsigned char>
orthogonal_equality<X::active_face_iterator>(
const X::active_face_iterator &,
const X::active_face_iterator &,
const Tensor<1, deal_II_space_dimension> &,
const FullMatrix<double> &);
- template std::optional<std::bitset<3>>
+ template std::optional<unsigned char>
orthogonal_equality<X::face_iterator>(
const X::face_iterator &,
const X::face_iterator &,
const typename Triangulation<dim, spacedim>::cell_iterator &cell_2,
unsigned int n_face_1,
unsigned int n_face_2,
- const std::bitset<3> &orientation,
+ const unsigned char orientation,
typename std::map<
std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
unsigned int>,
std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
unsigned int>,
- std::bitset<3>>> &periodic_face_map)
+ unsigned char>> &periodic_face_map)
{
using FaceIterator = typename Triangulation<dim, spacedim>::face_iterator;
const FaceIterator face_1 = cell_1->face(n_face_1);
const FaceIterator face_2 = cell_2->face(n_face_2);
- const bool face_orientation = orientation[0];
- const bool face_flip = orientation[1];
- const bool face_rotation = orientation[2];
+ const auto [face_orientation, face_rotation, face_flip] =
+ internal::split_face_orientation(orientation);
Assert((dim != 1) || (face_orientation == true && face_flip == false &&
face_rotation == false),
using CellFace =
std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
unsigned int>;
- const CellFace cell_face_1(cell_1, n_face_1);
- const CellFace cell_face_2(cell_2, n_face_2);
- const std::pair<CellFace, std::bitset<3>> cell_face_orientation_2(
+ const CellFace cell_face_1(cell_1, n_face_1);
+ const CellFace cell_face_2(cell_2, n_face_2);
+ const std::pair<CellFace, unsigned char> cell_face_orientation_2(
cell_face_2, orientation);
- const std::pair<CellFace, std::pair<CellFace, std::bitset<3>>>
+ const std::pair<CellFace, std::pair<CellFace, unsigned char>>
periodic_faces(cell_face_1, cell_face_orientation_2);
// Only one periodic neighbor is allowed
std::pair<typename Triangulation<dim, spacedim>::cell_iterator, unsigned int>,
std::pair<std::pair<typename Triangulation<dim, spacedim>::cell_iterator,
unsigned int>,
- std::bitset<3>>>
+ unsigned char>>
&Triangulation<dim, spacedim>::get_periodic_face_map() const
{
return periodic_face_map;
periodic_face_map);
// for the other way, we need to invert the orientation
- std::bitset<3> inverted_orientation;
+ unsigned char inverted_orientation;
{
- bool orientation, flip, rotation;
- orientation = it->orientation[0];
- rotation = it->orientation[2];
- flip = orientation ? rotation ^ it->orientation[1] : it->orientation[1];
- inverted_orientation[0] = orientation;
- inverted_orientation[1] = flip;
- inverted_orientation[2] = rotation;
+ auto [orientation, rotation, flip] =
+ internal::split_face_orientation(it->orientation);
+ flip = orientation ? rotation ^ flip : flip;
+ inverted_orientation =
+ internal::combined_face_orientation(orientation, rotation, flip);
}
update_periodic_face_map_recursively<dim, spacedim>(it->cell[1],
it->cell[0],
// check consistency
typename std::map<std::pair<cell_iterator, unsigned int>,
std::pair<std::pair<cell_iterator, unsigned int>,
- std::bitset<3>>>::const_iterator it_test;
+ unsigned char>>::const_iterator it_test;
for (it_test = periodic_face_map.begin(); it_test != periodic_face_map.end();
++it_test)
{
* number of children as i_subface.
*/
AssertIndexRange(i_subface, nb_parent_face_it->n_children());
+
+ const auto [orientation, rotation, flip] =
+ internal::split_face_orientation(my_face_pair->second.second);
+
unsigned int sub_neighbor_num =
GeometryInfo<dim>::child_cell_on_face(parent_nb_it->refinement_case(),
nb_face_num,
i_subface,
- my_face_pair->second.second[0],
- my_face_pair->second.second[1],
- my_face_pair->second.second[2],
+ orientation,
+ flip,
+ rotation,
nb_parent_face_it->refinement_case());
return parent_nb_it->child(sub_neighbor_num);
}
transformation,
level_constraints[first_cell.first->level()],
component_mask,
- second_cell.second[0],
- second_cell.second[1],
- second_cell.second[2],
+ second_cell.second,
periodicity_factor,
first_cell.first->level());
}
#include <deal.II/lac/affine_constraints.h>
+#include <bitset>
#include <iostream>
#include <utility>
//
// Test
// DoFTools::
-// make_periodicity_constraints (const FaceIterator &,
-// const FaceIterator &,
-// dealii::AffineConstraints<double> &,
-// const std::vector<bool> &,
-// bool, bool, bool)
+// make_periodicity_constraints(const FaceIterator &,
+// const FaceIterator &,
+// dealii::AffineConstraints<double> &,
+// const std::vector<bool> &,
+// unsigned char)
// for correct behavior on non standard oriented meshes.
//
face_1, face_2, dim == 2 ? 1 : 2, Tensor<1, spacedim>());
AssertThrow(orientation, ExcInternalError());
const auto o = *orientation;
- deallog << "Orientation: " << o[0] << o[1] << o[2] << std::endl;
+ // Preserve old output by printing a bitset and also using the old
+ // (orientation, flip, rotation) format
+ std::bitset<3> bo(o);
+ deallog << "Orientation: " << bo[0] << bo[2] << bo[1] << std::endl;
DoFTools::make_periodicity_constraints(
- face_1, face_2, constraint_matrix, velocity_mask, o[0], o[1], o[2]);
+ face_1, face_2, constraint_matrix, velocity_mask, o);
deallog << "Matching:" << std::endl;
constraint_matrix.print(deallog.get_file_stream());
constraint_matrix.close();
face_2, face_1, dim == 2 ? 1 : 2, Tensor<1, spacedim>());
AssertThrow(reverse_orientation, ExcInternalError());
const auto ro = *reverse_orientation;
- DoFTools::make_periodicity_constraints(face_2,
- face_1,
- constraint_matrix_reverse,
- velocity_mask,
- ro[0],
- ro[1],
- ro[2]);
+ DoFTools::make_periodicity_constraints(
+ face_2, face_1, constraint_matrix_reverse, velocity_mask, ro);
deallog << "Reverse Matching:" << std::endl;
constraint_matrix_reverse.print(deallog.get_file_stream());
constraint_matrix_reverse.close();
deallog << dofs_2[i] << " is located at " << support_points[dofs_2[i]]
<< std::endl;
-
- std::bitset<3> orientation;
- orientation[0] = 0;
- orientation[1] = 0;
- orientation[2] = 0;
-
- DoFTools::make_periodicity_constraints(face_1,
- face_2,
- constraint_matrix,
- ComponentMask(),
- orientation[0],
- orientation[1],
- orientation[2]);
+ DoFTools::make_periodicity_constraints(
+ face_1, face_2, constraint_matrix, ComponentMask(), 0u);
constraint_matrix.print(deallog.get_file_stream());
constraint_matrix.close();
deallog << "Matching:" << std::endl;
deallog << dofs_2[i] << " is located at " << support_points[dofs_2[i]]
<< std::endl;
-
- std::bitset<3> orientation;
- orientation[0] = 0;
- orientation[1] = 0;
- orientation[2] = 0;
-
- DoFTools::make_periodicity_constraints(face_1,
- face_2,
- constraint_matrix,
- ComponentMask(),
- orientation[0],
- orientation[1],
- orientation[2]);
+ DoFTools::make_periodicity_constraints(
+ face_1, face_2, constraint_matrix, ComponentMask(), 0u);
constraint_matrix.print(deallog.get_file_stream());
constraint_matrix.close();
deallog << "Matching:" << std::endl;
deallog << dofs_2[i] << " is located at " << support_points[dofs_2[i]]
<< std::endl;
-
- std::bitset<3> orientation;
- orientation[0] = 0;
- orientation[1] = 0;
- orientation[2] = 0;
-
- DoFTools::make_periodicity_constraints(face_1,
- face_2,
- constraint_matrix,
- ComponentMask(),
- orientation[0],
- orientation[1],
- orientation[2]);
+ DoFTools::make_periodicity_constraints(
+ face_1, face_2, constraint_matrix, ComponentMask(), 0u);
constraint_matrix.print(deallog.get_file_stream());
constraint_matrix.close();
deallog << "Matching:" << std::endl;
#include <deal.II/lac/affine_constraints.h>
+#include <bitset>
#include <iostream>
#include <utility>
//
// Test
// DoFTools::
-// make_periodicity_constraints (const FaceIterator &,
-// const FaceIterator &,
-// dealii::AffineConstraints<double> &,
-// const std::vector<bool> &,
-// bool, bool, bool)
+// make_periodicity_constraints(const FaceIterator &,
+// const FaceIterator &,
+// dealii::AffineConstraints<double> &,
+// const std::vector<bool> &,
+// unsigned char)
//
// for correct behavior with hanging nodes. This is done by additionally
// refining the second cube once. Test that constraining face_1 -> face_2
face_1, face_2, dim == 2 ? 1 : 2, Tensor<1, spacedim>());
AssertThrow(orientation, ExcInternalError());
const auto o = *orientation;
- deallog << "Orientation: " << o[0] << o[1] << o[2] << std::endl;
+ // Preserve old output by printing a bitset and also using the old
+ // (orientation, flip, rotation) format
+ std::bitset<3> bo(o);
+ deallog << "Orientation: " << bo[0] << bo[2] << bo[1] << std::endl;
DoFTools::make_periodicity_constraints(
- face_1, face_2, constraint_matrix, velocity_mask, o[0], o[1], o[2]);
+ face_1, face_2, constraint_matrix, velocity_mask, o);
deallog << "Matching:" << std::endl;
constraint_matrix.print(deallog.get_file_stream());
constraint_matrix.close();
face_2, face_1, dim == 2 ? 1 : 2, Tensor<1, spacedim>());
AssertThrow(reverse_orientation, ExcInternalError());
const auto ro = *reverse_orientation;
- DoFTools::make_periodicity_constraints(face_2,
- face_1,
- constraint_matrix_reverse,
- velocity_mask,
- ro[0],
- ro[1],
- ro[2]);
+ DoFTools::make_periodicity_constraints(
+ face_2, face_1, constraint_matrix_reverse, velocity_mask, ro);
deallog << "Reverse Matching:" << std::endl;
constraint_matrix_reverse.print(deallog.get_file_stream());
constraint_matrix_reverse.close();
*/
template <typename FaceIterator>
void
-print_match(const FaceIterator &face_1,
- const FaceIterator &face_2,
- const std::bitset<3> &orientation)
+print_match(const FaceIterator &face_1,
+ const FaceIterator &face_2,
+ const unsigned char combined_orientation)
{
static const int dim = FaceIterator::AccessorType::dimension;
deallog << " :: " << face_2->vertex(j);
deallog << std::endl;
- deallog << "orientation: " << orientation[0] << " flip: " << orientation[1]
- << " rotation: " << orientation[2] << std::endl
+ const auto [orientation, rotation, flip] =
+ internal::split_face_orientation(combined_orientation);
+ deallog << "orientation: " << orientation << " flip: " << flip
+ << " rotation: " << rotation << std::endl
<< std::endl;
}
*/
template <typename FaceIterator>
void
-print_match(const FaceIterator &face_1,
- const FaceIterator &face_2,
- const std::bitset<3> &orientation)
+print_match(const FaceIterator &face_1,
+ const FaceIterator &face_2,
+ const unsigned char combined_orientation)
{
static const int dim = FaceIterator::AccessorType::dimension;
deallog << " :: " << face_2->vertex(j);
deallog << std::endl;
- deallog << "orientation: " << orientation[0] << " flip: " << orientation[1]
- << " rotation: " << orientation[2] << std::endl
+ const auto [orientation, rotation, flip] =
+ internal::split_face_orientation(combined_orientation);
+ deallog << "orientation: " << orientation << " flip: " << flip
+ << " rotation: " << rotation << std::endl
<< std::endl;
}
#include <deal.II/grid/grid_tools.h>
#include <deal.II/grid/tria.h>
+#include <bitset>
#include <string>
#include "../tests.h"
deallog << periodic_faces[i].cell[0]->index() << ' '
<< periodic_faces[i].cell[1]->index() << ' '
<< periodic_faces[i].face_idx[0] << ' '
- << periodic_faces[i].face_idx[1] << ' '
- << periodic_faces[i].orientation << std::endl;
+ << periodic_faces[i].face_idx[1]
+ << ' '
+ // maintain old output by converting to a a bitset
+ << std::bitset<3>(periodic_faces[i].orientation) << std::endl;
}
}
using CellFace =
std::pair<typename Triangulation<dim>::cell_iterator, unsigned int>;
- const typename std::map<CellFace, std::pair<CellFace, std::bitset<3>>>
+ const typename std::map<CellFace, std::pair<CellFace, unsigned char>>
&face_map = triangulation.get_periodic_face_map();
typename std::map<CellFace,
- std::pair<CellFace, std::bitset<3>>>::const_iterator it;
+ std::pair<CellFace, unsigned char>>::const_iterator it;
int sum_of_pairs_local = face_map.size();
int sum_of_pairs_global;
MPI_Allreduce(&sum_of_pairs_local,
{
std::cout << "face_center_1: " << face_center_1 << std::endl;
std::cout << "face_center_2: " << face_center_2 << std::endl;
- typename std::map<CellFace, std::pair<CellFace, std::bitset<3>>>::
+ typename std::map<CellFace, std::pair<CellFace, unsigned char>>::
const_iterator it;
for (it = triangulation.get_periodic_face_map().begin();
it != triangulation.get_periodic_face_map().end();