const bool face_orientation = true,
const bool face_flip = false,
const bool face_rotation = false,
- const FullMatrix<double> &matrix = IdentityMatrix(FaceIterator::space_dimension),
- const bool rotation_matrix = true);
+ const FullMatrix<double> &matrix = FullMatrix<double>(),
+ const std::vector<unsigned int> &first_vector_components = std::vector<unsigned int>());
/**
* A matrix that describes how vector valued DoFs of the first face
* should be modified prior to constraining to the DoFs of the second
- * face. If rotation_matrix is true the matrix is enterpreted as a
- * rotation matrix applied to all vector valued blocks of an FESystem.
- * For more details see make_periodicity_constraints and the glossary
- * @ref GlossPeriodicConstraints "glossary entry on periodic
+ * face. If the std::vector first_vector_components is non empty the
+ * matrix is interpreted as a rotation matrix that is applied to all
+ * vector valued blocks listed in first_vector_components of the
+ * FESystem. For more details see make_periodicity_constraints and the
+ * glossary @ref GlossPeriodicConstraints "glossary entry on periodic
* boundary conditions".
*/
FullMatrix<double> matrix;
/**
- * A flag indicating whether matrix should be interpreted as rotation
- * matrix or as an interpolation matrix.
+ * A vector of unsigned ints pointing to the first components of all
+ * vector valued blocks that should be rotated by matrix.
*/
- bool rotation_matrix;
+ std::vector<unsigned int> first_vector_components;
};
* them to the corresponding vertices of the 'second' boundary. This can
* be used to implement conditions such as $u(0,y)=u(1,y+1)$.
*
- * Optionally a rotation matrix @p matrix along with a flag @p
- * rotation_matrix can be specified that describes how vector valued DoFs
- * of the first face should be modified prior to constraining to the DoFs
- * of the second face. If rotation_matrix is true the matrix is
- * enterpreted as a rotation matrix applied to all vector valued blocks
- * of an FESystem. For more details see make_periodicity_constraints and
+ * Optionally a rotation matrix @p matrix along with a vector @p
+ * first_vector_components can be specified that describes how vector
+ * valued DoFs of the first face should be modified prior to constraining
+ * to the DoFs of the second face. If @p first_vector_components is non
+ * empty the matrix is interpreted as a rotation matrix that is applied
+ * to all vector valued blocks listet in @p first_vector_components of
+ * the FESystem. For more details see make_periodicity_constraints and
* the glossary @ref GlossPeriodicConstraints "glossary entry on periodic
* boundary conditions".
*
const int direction,
std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> > &matched_pairs,
const Tensor<1,CONTAINER::space_dimension> &offset = dealii::Tensor<1,CONTAINER::space_dimension>(),
- const FullMatrix<double> &matrix = IdentityMatrix(CONTAINER::space_dimension),
- const bool rotation_matrix = true);
+ const FullMatrix<double> &matrix = FullMatrix<double>(),
+ const std::vector<unsigned int> &first_vector_components = std::vector<unsigned int>());
/**
const int direction,
std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> > &matched_pairs,
const dealii::Tensor<1,CONTAINER::space_dimension> &offset = dealii::Tensor<1,CONTAINER::space_dimension>(),
- const FullMatrix<double> &matrix = IdentityMatrix(CONTAINER::space_dimension),
- const bool rotation_matrix = true);
+ const FullMatrix<double> &matrix = FullMatrix<double>(),
+ const std::vector<unsigned int> &first_vector_components = std::vector<unsigned int>());
// Query the correct face_index on face_2 respecting the given
// orientation:
const unsigned int j =
- cell_to_rotated_face_index[fe.face_to_cell_index(jj, 0, /* It doesn't really matter, just assume
- * we're on the first face...
- */
- face_orientation, face_flip, face_rotation)];
+ cell_to_rotated_face_index[fe.face_to_cell_index
+ (jj, 0, face_orientation, face_flip, face_rotation)];
// And finally constrain the two DoFs respecting component_mask:
if (transformation(i,jj) != 0)
const bool face_flip,
const bool face_rotation,
const FullMatrix<double> &matrix,
- const bool rotation_matrix)
+ const std::vector<unsigned int> &first_vector_components)
{
static const int dim = FaceIterator::AccessorType::dimension;
Assert(face_1->at_boundary() && face_2->at_boundary(),
ExcMessage ("Faces for periodicity constraints must be on the boundary"));
+ Assert(first_vector_components.size() == 0 || matrix.size(0) == matrix.size(1) == dim,
+ ExcMessage ("first_vector_components is nonempty, so matrix must be a rotation "
+ "matrix exactly of of size dim"));
+
+#ifdef DEBUG
+ {
+ const unsigned int n_dofs = face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face;
+ Assert(first_vector_components.size() != 0 ||
+ ( (matrix.size(0) == 0 && matrix.size(1) == 0) ||
+ (matrix.size(0) == n_dofs && matrix.size(1) == n_dofs) ),
+ ExcMessage ("first_vector_components is empty, so matrix must have either "
+ "size 0 or the size must be equal to the number of DoFs on the face"));
+ }
+#endif
+
// A lookup table on how to go through the child faces depending on the
// orientation:
face_flip,
face_rotation,
matrix,
- rotation_matrix);
+ first_vector_components);
}
}
else
{
// Build up the transformation matrix:
- if (rotation_matrix)
- AssertThrow(false, ExcNotImplemented());
-// FullMatrix<double>(IdentityMatrix(face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face));
+ if (first_vector_components.size() != 0 && matrix.size(0) == 0)
+ {
+ // We need to create a local transformation matrix...
+ AssertThrow(false, ExcNotImplemented());
- if (face_2->has_children() == false)
+ // FullMatrix<double>(IdentityMatrix(face_1->get_fe(face_1->nth_active_fe_index(0)).dofs_per_face));
+ }
+ else if (face_2->has_children() == false)
{
// TODO: This is horrible...
FullMatrix<double> inverse;
it->orientation[1],
it->orientation[2],
it->matrix,
- it->rotation_matrix);
+ it->first_vector_components);
}
}
const ComponentMask &,
bool, bool, bool,
const FullMatrix<double> &,
- const bool);
+ const std::vector<unsigned int> &);
template
void
std::vector<PeriodicFacePair<CellIterator> > &matched_pairs,
const dealii::Tensor<1,CellIterator::AccessorType::space_dimension> &offset,
const FullMatrix<double> &matrix,
- const bool rotation_matrix)
+ const std::vector<unsigned int> &first_vector_components)
{
static const int space_dim = CellIterator::AccessorType::space_dimension;
Assert (0<=direction && direction<space_dim,
// remove the matched cell in pairs2 to speed up the
// matching:
const PeriodicFacePair<CellIterator> matched_face
- = {{cell1, cell2},{face_idx1, face_idx2}, orientation, matrix, rotation_matrix};
+ = {{cell1, cell2},{face_idx1, face_idx2}, orientation, matrix, first_vector_components};
matched_pairs.push_back(matched_face);
pairs2.erase(it2);
++n_matches;
std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> > &matched_pairs,
const Tensor<1,CONTAINER::space_dimension> &offset,
const FullMatrix<double> &matrix,
- const bool rotation_matrix)
+ const std::vector<unsigned int> &first_vector_components)
{
static const int dim = CONTAINER::dimension;
static const int space_dim = CONTAINER::space_dimension;
// and call match_periodic_face_pairs that does the actual matching:
match_periodic_face_pairs(pairs1, pairs2, direction, matched_pairs,
- offset, matrix, rotation_matrix);
+ offset, matrix, first_vector_components);
}
std::vector<PeriodicFacePair<typename CONTAINER::cell_iterator> > &matched_pairs,
const Tensor<1,CONTAINER::space_dimension> &offset,
const FullMatrix<double> &matrix,
- const bool rotation_matrix)
+ const std::vector<unsigned int> &first_vector_components)
{
static const int dim = CONTAINER::dimension;
static const int space_dim = CONTAINER::space_dimension;
// and call match_periodic_face_pairs that does the actual matching:
match_periodic_face_pairs(pairs1, pairs2, direction, matched_pairs,
- offset, matrix, rotation_matrix);
+ offset, matrix, first_vector_components);
#ifdef DEBUG
//check for standard orientation
std::vector<PeriodicFacePair<X::cell_iterator> > &,
const Tensor<1,X::space_dimension> &,
const FullMatrix<double> &,
- const bool);
+ const std::vector<unsigned int> &);
template
void collect_periodic_faces<X> (const X &,
std::vector<PeriodicFacePair<X::cell_iterator> > &,
const Tensor<1,X::space_dimension> &,
const FullMatrix<double> &,
- const bool);
+ const std::vector<unsigned int> &);
#endif
std::vector<PeriodicFacePair<parallel::distributed::Triangulation<deal_II_dimension, deal_II_space_dimension>::cell_iterator> > &,
const Tensor<1,parallel::distributed::Triangulation<deal_II_dimension, deal_II_space_dimension>::space_dimension> &,
const FullMatrix<double> &,
- const bool);
+ const std::vector<unsigned int> &);
template
void
std::vector<PeriodicFacePair<parallel::distributed::Triangulation<deal_II_dimension, deal_II_space_dimension>::cell_iterator> > &,
const Tensor<1,parallel::distributed::Triangulation<deal_II_dimension, deal_II_space_dimension>::space_dimension> &,
const FullMatrix<double> &,
- const bool);
+ const std::vector<unsigned int> &);
\}
#endif
#endif