Skip to content

BoundaryInfo::build_side_list_from_node_list() can add spurious interior sides on thin meshes #4564

Description

@kyriv-lab

Description

BoundaryInfo::build_side_list_from_node_list() adds a side to a sideset whenever every node of that side belongs to the nodeset, with no check for whether the side is actually on the mesh exterior or on a subdomain interface:

// src/mesh/boundary_info.C
for (const auto & elem : _mesh->active_element_ptr_range())
  for (auto side : elem->side_index_range())
    {
      ...
      for (const auto & pr : nodesets_node_count)
        if (pr.second == side_elem->n_nodes())
          add_side(elem, side, pr.first);
    }

On a mesh that is only one element deep in some direction, a nodeset spanning both exterior faces normal to that direction will cause every node of the interior sides between layers to also satisfy this condition, so those interior sides get added to the sideset alongside the intended exterior ones.

Reproduction

  • A 3D mesh one element layer deep in one direction (or a thin shell-like mesh in general)
  • A nodeset containing nodes on both faces normal to that direction
  • Call build_side_list_from_node_list() (or build_side_list_from_node_list(nodeset_list))

Expected behavior

Only sides that are actually exterior (no neighbor) or on a genuine interface between different subdomains should be added. A side whose neighbor is in the same subdomain is interior to a block and shouldn't be pulled into the sideset just because its nodes happen to overlap the nodeset.

Context

This surfaced downstream in idaholab/moose#30917 and was worked around in idaholab/moose#33826 with a MOOSE-side post-processing pass (MooseMeshUtils::removeInteriorSides) that strips sides whose neighbor is in the same subdomain. That fix requires a second full pass over the mesh and an opt-in flag; it would be better handled here, where neighbor/subdomain information is already available during the same traversal (e.g. an optional exterior_only-style parameter, or as new default behavior with a flag to restore the old unconditional behavior for back-compat).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions