46 namespace MeshClassifierImplementation
50 "The Triangulation has not been classified. You need to call the "
51 "reclassify()-function before using this function.");
55 "The incoming cell does not belong to the triangulation passed to "
66 template <
typename VectorType>
70 const auto [min_element, max_element] =
71 std::minmax_element(local_levelset_values.begin(),
72 local_levelset_values.end());
77 if (*min_element == 0.0 && *max_element == 0.0)
79 if (*max_element <= 0)
81 if (0 <= *min_element)
94 template <
typename VectorType>
98 template <
typename Number>
100 LinearAlgebra::distributed::Vector<Number, MemorySpace::Host>>
116 template <
int dim,
typename VectorType>
120 [[maybe_unused]]
const VectorType &level_set)
127 level_set.locally_owned_elements());
131 level_set.get_partitioner()->ghost_indices()),
133 "The level set vector does not contain all locally relevant "
134 "DoFs of the DoFHandler as locally owned or ghost entries. "
135 "However, the MeshClassifier needs to access the level set "
136 "values on the faces of all ghost cells. This typically "
137 "happens if the vector was initialized via "
138 "MatrixFree::initialize_dof_vector(), whose ghost entries only "
139 "cover the DoFs of the locally owned cells. Copy the level set "
140 "field into a vector whose ghost entries are given by "
141 "DoFTools::extract_locally_relevant_dofs()."));
151 template <
int dim,
typename VectorType>
173 &cell)
const override;
182 const unsigned int face_index,
223 template <
int dim,
typename VectorType>
226 const VectorType &level_set)
227 : dof_handler(&dof_handler)
228 , level_set(&level_set)
233 template <
int dim,
typename VectorType>
237 return dof_handler->get_fe_collection();
242 template <
int dim,
typename VectorType>
246 const unsigned int face_index,
249 const auto cell_with_dofs = cell->as_dof_handler_iterator(*dof_handler);
251 const unsigned int n_dofs_per_face =
252 dof_handler->get_fe().n_dofs_per_face();
253 std::vector<types::global_dof_index> dof_indices(n_dofs_per_face);
254 cell_with_dofs->face(face_index)->get_dof_indices(dof_indices);
256 local_levelset_values.
reinit(dof_indices.size());
258 for (
unsigned int i = 0; i < dof_indices.size(); i++)
259 local_levelset_values[i] =
266 template <
int dim,
typename VectorType>
275 template <
int dim,
typename VectorType>
280 const auto cell_with_dofs = cell->as_dof_handler_iterator(*dof_handler);
282 return cell_with_dofs->active_fe_index();
314 &cell)
const override;
323 const unsigned int face_index,
351 : level_set(&level_set)
352 , fe_collection(element)
353 , fe_face_values(element,
355 element.get_unit_face_support_points()),
365 const unsigned int face_index,
369 fe_face_values.n_quadrature_points);
371 fe_face_values.reinit(cell, face_index);
372 const std::vector<Point<dim>> &points =
373 fe_face_values.get_quadrature_points();
375 for (
unsigned int i = 0; i < points.size(); i++)
376 local_levelset_values[i] = level_set->value(points[i]);
385 return fe_collection;
403 template <
typename VectorType>
405 const VectorType &level_set)
406 : triangulation(&dof_handler.get_triangulation())
407 , level_set_description(
408 std::make_unique<
internal::MeshClassifierImplementation::
409 DiscreteLevelSetDescription<dim, VectorType>>(
413#ifdef DEAL_II_WITH_LAPACK
416 for (
unsigned int i = 0; i < fe_collection.
size(); i++)
421 Assert(fe_collection[i].has_face_support_points(),
423 "The elements in the FECollection of the incoming DoFHandler "
424 "must have face support points."));
437 : triangulation(&triangulation)
438 , level_set_description(
439 std::make_unique<
internal::MeshClassifierImplementation::
440 AnalyticLevelSetDescription<dim>>(level_set,
454 level_set_description->check_consistency();
456 cell_locations.assign(triangulation->n_active_cells(),
458 face_locations.assign(triangulation->n_raw_faces(),
464 const auto contains =
465 [](
const std::set<LocationToLevelSet> &local_face_locations,
467 return local_face_locations.count(location) > 0;
472 for (
const auto &cell : triangulation->active_cell_iterators())
473 if (!cell->is_artificial())
475 std::set<LocationToLevelSet> local_face_locations;
477 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
480 determine_face_location_to_levelset(cell, f);
482 face_locations[cell->face(f)->index()] = face_location;
483 local_face_locations.insert(face_location);
488 const bool all_faces_have_same_location =
489 local_face_locations.size() == 1;
491 if (all_faces_have_same_location)
493 cell_location = *local_face_locations.cbegin();
495 else if (contains(local_face_locations,
520 cell_locations[cell->active_cell_index()] = cell_location;
530 const unsigned int face_index)
535 face_locations.at(cell->face(face_index)->index());
541 const unsigned int fe_index = level_set_description->active_fe_index(cell);
542 const unsigned int n_local_dofs =
543 lagrange_to_bernstein_face[fe_index][face_index].m();
546 level_set_description->get_local_level_set_values(cell,
548 local_levelset_values);
551 level_set_description->get_fe_collection()[fe_index];
558 const bool is_linear = fe_q_iso_q1 !=
nullptr ||
559 (fe_poly !=
nullptr && fe_poly->
get_degree() == 1);
565 local_levelset_values);
568 lagrange_to_bernstein_face[fe_index][face_index].solve(
569 local_levelset_values);
572 local_levelset_values);
582 Assert(cell_locations.size() == triangulation->n_active_cells(),
584 Assert(&cell->get_triangulation() == triangulation,
587 return cell_locations.at(cell->active_cell_index());
596 const unsigned int face_index)
const
599 Assert(face_locations.size() == triangulation->n_raw_faces(),
601 Assert(&cell->get_triangulation() == triangulation,
604 return face_locations.at(cell->face(face_index)->index());
614 level_set_description->get_fe_collection();
619 lagrange_to_bernstein_face.resize(fe_collection.
size());
621 for (
unsigned int i = 0; i < fe_collection.
size(); i++)
631 for (
unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; f++)
637 *fe_q, face_interpolation_matrix, f);
638 lagrange_to_bernstein_face[i][f].reinit(dofs_per_face);
639 lagrange_to_bernstein_face[i][f] = face_interpolation_matrix;
640 lagrange_to_bernstein_face[i][f].compute_lu_factorization();
647#include "non_matching/mesh_classifier.inst"
const hp::FECollection< dim, spacedim > & get_fe_collection() const
virtual void get_face_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix, const unsigned int face_no=0) const override
unsigned int get_degree() const
const unsigned int dofs_per_face
unsigned int n_components() const
const unsigned int n_components
bool is_subset_of(const IndexSet &other) const
void subtract_set(const IndexSet &other)
LocationToLevelSet location_to_level_set(const typename Triangulation< dim >::cell_iterator &cell) const
LocationToLevelSet determine_face_location_to_levelset(const typename Triangulation< dim >::active_cell_iterator &cell, const unsigned int face_index)
MeshClassifier(const DoFHandler< dim > &level_set_dof_handler, const VectorType &level_set)
AnalyticLevelSetDescription(const Function< dim > &level_set, const FiniteElement< dim > &element)
unsigned int active_fe_index(const typename Triangulation< dim >::active_cell_iterator &cell) const override
FEFaceValues< dim > fe_face_values
const hp::FECollection< dim > & get_fe_collection() const override
const ObserverPointer< const Function< dim > > level_set
const hp::FECollection< dim > fe_collection
void get_local_level_set_values(const typename Triangulation< dim >::active_cell_iterator &cell, const unsigned int face_index, Vector< double > &local_levelset_values) override
void get_local_level_set_values(const typename Triangulation< dim >::active_cell_iterator &cell, const unsigned int face_index, Vector< double > &local_levelset_values) override
const ObserverPointer< const DoFHandler< dim > > dof_handler
void check_consistency() const override
unsigned int active_fe_index(const typename Triangulation< dim >::active_cell_iterator &cell) const override
const hp::FECollection< dim > & get_fe_collection() const override
const ObserverPointer< const VectorType > level_set
DiscreteLevelSetDescription(const DoFHandler< dim > &dof_handler, const VectorType &level_set)
virtual size_type size() const override
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
unsigned int size() const
unsigned int n_components() const
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcNeedsLAPACK()
static ::ExceptionBase & ExcReclassifyNotCalled()
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcTriangulationMismatch()
#define AssertThrow(cond, exc)
@ update_quadrature_points
Transformed quadrature points.
LocationToLevelSet location_from_dof_signs(const VectorType &local_levelset_values)
void assert_locally_relevant_dofs_are_accessible(const DoFHandler< dim > &dof_handler, const VectorType &level_set)