-
Notifications
You must be signed in to change notification settings - Fork 708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NonMatching::MeshClassifier: adequate treatment of face-conforming interface #16888
Comments
FYI @vyushut |
I think this is a good solution. Even if it is kind of weird. As it is right now, using In your workaround, what convention did you choose for which cell is intersected? |
Currently, we use the following procedure:
For now, we have not modified the // definition of lambda function for setting either the active or the future FE index
// for the current cell
const auto set_fe_index_lambda = [&](const auto &cell, const auto active_fe_index) {
if (is_future)
cell->set_future_fe_index(active_fe_index);
else
cell->set_active_fe_index(active_fe_index);
};
// 2) modify intersected cells that contain a face-conforming interface
MappingQ1<dim> mapping;
dealii::FEFaceValues<dim> ls_eval(mapping,
ls_dof_handler.get_fe(),
Quadrature<dim - 1>(
ls_dof_handler.get_fe().get_unit_face_support_points()),
update_values);
for (const auto &cell : dof_handler.get_triangulation().active_cell_iterators())
{
if (cell->is_locally_owned() && mesh_classifier.location_to_level_set(cell) ==
NonMatching::LocationToLevelSet::intersected)
{
bool cell_has_conforming_face = false;
TriaIterator<DoFCellAccessor<dim, dim, false>> dof_cell(
&dof_handler.get_triangulation(), cell->level(), cell->index(), &dof_handler);
TriaIterator<DoFCellAccessor<dim, dim, false>> ls_dof_cell(
&dof_handler.get_triangulation(), cell->level(), cell->index(), &ls_dof_handler);
for (unsigned int face_index = 0; face_index < GeometryInfo<dim>::faces_per_cell;
++face_index)
{
std::vector<double> ls_values(ls_dof_handler.get_fe().n_dofs_per_face());
ls_eval.reinit(ls_dof_cell, face_index);
ls_eval.get_function_values(level_set, ls_values);
if (cell_has_conforming_face =
std::all_of(ls_values.begin(), ls_values.end(), [&tolerance](double v) {
return std::abs(v) <= tolerance;
}))
break;
}
// shortcut if no face-conforming interface has been detected
if (not cell_has_conforming_face)
continue;
// If a face with a conforming interface is detected and there is at least one inside
// face attached to the cell, mark this cell as "inside".
bool all_faces_are_intersected = false;
for (unsigned int face_index = 0; face_index < GeometryInfo<dim>::faces_per_cell;
++face_index)
{
all_faces_are_intersected =
std::min(all_faces_are_intersected,
mesh_classifier.location_to_level_set(cell, face_index) ==
NonMatching::LocationToLevelSet::intersected);
if (mesh_classifier.location_to_level_set(cell, face_index) ==
NonMatching::LocationToLevelSet::inside)
{
set_fe_index_lambda(dof_cell, ActiveFEIndex::inside);
break;
}
}
AssertThrow(!all_faces_are_intersected, ExcNotImplemented());
}
} However, if you think this is useful, then I can see how we could put this into the |
Change logic in MeshClassifier to handle the situation described in issue dealii#16888. Add a new type to the enum LocationToLevelSet that describes that the zero contour is exactly aligned with a face. Change the logic in MeshClassifier to set the "inside" cell sharing an aligned face to intersected and the other cell to outside.
When the interface (given by a zero-level-set isosurface) is located at an element face, the current implementation of the
NonMatching::MeshClassifier
class detects both cells adjacent to the face-conforming interface as intersected. This can be seen here (white line refers to zero-level-set isosurface; gray cells are marked as intersected):In our application, we (1) check if a cell is cut by the interface and (2) perform an integral over the interface.
However, when dealing with face-conforming interfaces, our current method results in incorrect outcomes due to inadvertently looping over the interface twice for adjacent cells. To address this issue, we've applied a workaround where we mark one of the adjacent cells as "intersected" and the other as "inside". I am wondering how the
MeshClassifier
should handle this corner case in a user-friendly way and would be happy to hear your opinion about it. Does it generally make sense to let the interface belong to only one cell in the face-conforming case?FYI @nmuch @bergbauer
The text was updated successfully, but these errors were encountered: