diff --git a/framework/doc/content/source/mesh/MooseMesh.md b/framework/doc/content/source/mesh/MooseMesh.md index 8e187367ed78..b858fc397a20 100644 --- a/framework/doc/content/source/mesh/MooseMesh.md +++ b/framework/doc/content/source/mesh/MooseMesh.md @@ -40,6 +40,8 @@ To declare subdomains which are not found on the mesh right after the mesh is se specified using the [!param](/Mesh/MeshGeneratorMesh/add_subdomain_ids) parameter and/or a list of names can be specified using the [!param](/Mesh/MeshGeneratorMesh/add_subdomain_names) parameter. This permits setting up block restricted objects that will only act on subdomains created during the simulation (e.g. using the [CoupledVarThresholdElementSubdomainModifier.md]). +Likewise, sidesets which are not found on the mesh right after the mesh is setup, can be added with the parameters +[!param](/Mesh/MeshGeneratorMesh/add_sideset_ids) and [!param](/Mesh/MeshGeneratorMesh/add_sideset_names). ## Minimal interface diff --git a/framework/src/mesh/MooseMesh.C b/framework/src/mesh/MooseMesh.C index 6394ddb193ae..bc0ebdff5404 100644 --- a/framework/src/mesh/MooseMesh.C +++ b/framework/src/mesh/MooseMesh.C @@ -179,11 +179,15 @@ MooseMesh::validParams() params.addParam>( "add_sideset_ids", "The listed sideset ids will be assumed valid for the mesh. This permits setting up boundary " - "restrictions for sidesets initially containing no sides."); + "restrictions for sidesets initially containing no sides. Names for this sidesets may be " + "provided using add_sideset_names. In this case this list and add_sideset_names must contain " + "the same number of items."); params.addParam>( "add_sideset_names", "The listed sideset names will be assumed valid for the mesh. This permits setting up " - "boundary restrictions for sidesets initially containing no sides."); + "boundary restrictions for sidesets initially containing no sides. Ids for this sidesets may " + "be provided using add_sideset_ids. In this case this list and add_sideset_ids must contain " + "the same number of items."); params += MooseAppCoordTransform::validParams(); @@ -460,7 +464,23 @@ MooseMesh::prepare(const MeshBase * const mesh_to_clone) } } + // Make sure nodesets have been generated + buildNodeListFromSideList(); + + // Collect (local) boundary IDs + const std::set & local_bids = getMesh().get_boundary_info().get_boundary_ids(); + _mesh_boundary_ids.insert(local_bids.begin(), local_bids.end()); + + const std::set & local_node_bids = + getMesh().get_boundary_info().get_node_boundary_ids(); + _mesh_nodeset_ids.insert(local_node_bids.begin(), local_node_bids.end()); + + const std::set & local_side_bids = + getMesh().get_boundary_info().get_side_boundary_ids(); + _mesh_sideset_ids.insert(local_side_bids.begin(), local_side_bids.end()); + // Add explicitly requested sidesets + // This is done *after* the side boundaries (e.g. "right", ...) have been generated. if (isParamValid("add_sideset_ids") && !isParamValid("add_sideset_names")) { const auto & add_sideset_ids = getParam>("add_sideset_ids"); @@ -481,24 +501,31 @@ MooseMesh::prepare(const MeshBase * const mesh_to_clone) } } else if (isParamValid("add_sideset_names")) + { // the user has defined add_sideset_names, but not add_sideset_ids - paramError("add_sideset_names", - "In combination with add_sideset_names, add_sideset_ids must be defined."); - - // Make sure nodesets have been generated - buildNodeListFromSideList(); - - // Collect (local) boundary IDs - const std::set & local_bids = getMesh().get_boundary_info().get_boundary_ids(); - _mesh_boundary_ids.insert(local_bids.begin(), local_bids.end()); + const auto & add_sideset_names = getParam>("add_sideset_names"); - const std::set & local_node_bids = - getMesh().get_boundary_info().get_node_boundary_ids(); - _mesh_nodeset_ids.insert(local_node_bids.begin(), local_node_bids.end()); + // to define sideset ids, we need the largest sideset id defined yet. + boundary_id_type offset = 0; + if (!_mesh_sideset_ids.empty()) + offset = *_mesh_sideset_ids.rbegin(); + if (!_mesh_boundary_ids.empty()) + offset = std::max(offset, *_mesh_boundary_ids.rbegin()); - const std::set & local_side_bids = - getMesh().get_boundary_info().get_side_boundary_ids(); - _mesh_sideset_ids.insert(local_side_bids.begin(), local_side_bids.end()); + // add all sidesets (and auto-assign ids) + for (const BoundaryName & sideset_name : add_sideset_names) + { + // to avoid two sidesets with the same ID (notably on recover) + if (getBoundaryID(sideset_name) != Moose::INVALID_BOUNDARY_ID) + continue; + const auto sideset_id = ++offset; + // add sideset id + _mesh_boundary_ids.insert(sideset_id); + _mesh_sideset_ids.insert(sideset_id); + // set name of the sideset just added + setBoundaryName(sideset_id, sideset_name); + } + } // Communicate subdomain and boundary IDs if this is a parallel mesh if (!getMesh().is_serial()) diff --git a/test/tests/mesh/add_sideset_ids/add_sideset_names.i b/test/tests/mesh/add_sideset_ids/add_sideset_names.i new file mode 100644 index 000000000000..9305036d5f2d --- /dev/null +++ b/test/tests/mesh/add_sideset_ids/add_sideset_names.i @@ -0,0 +1,71 @@ +[Mesh] + [generate] + type = GeneratedMeshGenerator + dim = 2 + nx = 10 + ny = 10 + [] + add_sideset_names = 'AdditionalSidesetA' +[] + +[Variables] + [u] + [] +[] + +[Kernels] + [diff] + type = Diffusion + variable = u + [] + [diff2] + type = MatDiffusion + diffusivity = 1e-4 + variable = u + [] +[] + +[BCs] + [left] + type = DirichletBC + variable = u + boundary = left + value = 0 + [] + [right] + type = DirichletBC + variable = u + boundary = right + value = 1 + [] +[] + +[Postprocessors] + [flux] + type = SideIntegralVariablePostprocessor + variable = 'u' + boundary = 'AdditionalSidesetA' + execute_on = 'INITIAL TIMESTEP_END' + [] +[] + +[UserObjects] + [side_updater] + type = SidesetAroundSubdomainUpdater + inner_subdomains = 0 + outer_subdomains = 0 + update_sideset_name = 'AdditionalSidesetA' + execute_on = TIMESTEP_END + execution_order_group = -1 + [] +[] + +[Executioner] + type = Steady + petsc_options_iname = '-pc_type -pc_hypre_type' + petsc_options_value = 'hypre boomeramg' +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/mesh/add_sideset_ids/gold/add_sideset_names_out.csv b/test/tests/mesh/add_sideset_ids/gold/add_sideset_names_out.csv new file mode 100644 index 000000000000..d7fb7b505747 --- /dev/null +++ b/test/tests/mesh/add_sideset_ids/gold/add_sideset_names_out.csv @@ -0,0 +1,3 @@ +time,flux +0,0 +1,20.000000000006 diff --git a/test/tests/mesh/add_sideset_ids/tests b/test/tests/mesh/add_sideset_ids/tests index 6d52a9d5cbd5..ae629556d417 100644 --- a/test/tests/mesh/add_sideset_ids/tests +++ b/test/tests/mesh/add_sideset_ids/tests @@ -17,4 +17,11 @@ "UserObjects/side_updater/update_sideset_name=future" requirement = 'The system shall allow specifying valid sideset IDs and names that do not exist on the initial mesh.' [] + [add_sideset_names] + type = CSVDiff + input = add_sideset_names.i + csvdiff = add_sideset_names_out.csv + design = MooseMesh.md + requirement = 'The system shall allow specifying valid sideset names that do not exist on the initial mesh, and assign IDs automatically.' + [] []