14#include "libmesh/parallel_algebra.h"
15#include "libmesh/parallel_sync.h"
23 params.
addClassDescription(
"Sets up a boundary between inner_subdomains and outer_subdomains");
24 params.
addParam<std::vector<SubdomainName>>(
"inner_subdomains",
25 "Subdomains that own the boundary");
26 params.
addParam<std::vector<SubdomainName>>(
"outer_subdomains",
27 "Subdomains on the outside of the boundary");
28 params.
addParam<BoundaryName>(
"mask_side",
29 "If specified, only add sides where this sideset exists.");
30 params.
addParam<
bool>(
"assign_outer_surface_sides",
32 "Assign sides of elements im `inner_subdomains` that have no neighbor.");
34 "The name of the sideset to be updated. If the boundary "
35 "does not exist it will be added to the system.");
37 "update_sideset_name",
"update_boundary_name",
"The boundary name which is updated.");
40 "The ID of the sideset to be updated. If the boundary "
41 "does not exist it will be added to the system.");
43 "update_sideset_id",
"update_boundary_id",
"The boundary id which is updated.");
45 params.
addParam<
bool>(
"verbose",
false,
"Whether to output some information during execution");
51 _pid(_communicator.rank()),
52 _displaced_problem(_fe_problem.getDisplacedProblem().get()),
53 _neighbor_side(_assembly.neighborSide()),
54 _assign_outer_surface_sides(getParam<bool>(
"assign_outer_surface_sides")),
55 _boundary_name(getParam<BoundaryName>(
"update_boundary_name")),
56 _boundary_id(_mesh.getBoundaryID(_boundary_name)),
57 _mask_side(isParamValid(
"mask_side") ? _mesh.getBoundaryID(getParam<BoundaryName>(
"mask_side"))
58 :
Moose::INVALID_BOUNDARY_ID),
59 _boundary_info(_mesh.getMesh().get_boundary_info()),
60 _displaced_boundary_info(
61 _displaced_problem ? &_displaced_problem->
mesh().getMesh().get_boundary_info() : nullptr)
64 const auto & inner_subdomains = getParam<std::vector<SubdomainName>>(
"inner_subdomains");
65 const auto & outer_subdomains = getParam<std::vector<SubdomainName>>(
"outer_subdomains");
73 if (mesh_subdomains.find(
id) == mesh_subdomains.end())
74 paramError(
"inner_subdomains",
"The block '",
id,
"' was not found in the mesh");
76 if (mesh_subdomains.find(
id) == mesh_subdomains.end())
77 paramError(
"outer_subdomains",
"The block '",
id,
"' was not found in the mesh");
89 mooseWarning(
"The user has selected 'construct_node_list_from_side_list' as false, but "
90 "SidesetAroundSubdomainUpdate is building node lists from the side lists."));
103 _add[
_pid].emplace_back(elem->id(), side);
121 unsigned short int primary_side,
122 const Elem * secondary_elem)
125 if (
_inner_ids.count(primary_elem->subdomain_id()) &&
126 _outer_ids.count(secondary_elem->subdomain_id()))
133 _add[primary_elem->processor_id()].emplace_back(primary_elem->id(), primary_side);
140 _remove[primary_elem->processor_id()].emplace_back(primary_elem->id(), primary_side);
156 for (
const auto & [pid, list] : sas._add)
157 _add[pid].insert(
_add[pid].end(), list.begin(), list.end());
159 for (
const auto & [pid, list] : sas._remove)
160 _remove[pid].insert(
_remove[pid].end(), list.begin(), list.end());
167 const auto * displaced_mesh =
169 if (getParam<bool>(
"verbose"))
171 unsigned int total_remove = 0, total_add = 0;
172 for (
const auto & [pid, list] :
_remove)
173 total_remove +=
_remove[pid].size();
174 for (
const auto & [pid, list] :
_add)
175 total_add +=
_add[pid].size();
186 auto add_functor = [
this, &
mesh, &displaced_mesh](
const processor_id_type,
const auto & sent_data)
188 for (
auto & [elem_id, side] : sent_data)
196 auto remove_functor =
197 [
this, &
mesh, &displaced_mesh](
const processor_id_type,
const SideList & sent_data)
199 for (
const auto & [elem_id, side] : sent_data)
201 const auto elem =
mesh.elem_ptr(elem_id);
203 for (
const auto local_node_id : elem->nodes_on_side(side))
207 const auto displaced_elem = displaced_mesh->elem_ptr(elem_id);
209 for (
const auto local_node_id : displaced_elem->nodes_on_side(side))
220 auto sync = [](
auto &
mesh)
222 mesh.getMesh().get_boundary_info().parallel_sync_side_ids();
223 mesh.getMesh().get_boundary_info().parallel_sync_node_ids();
224 mesh.getMesh().get_boundary_info().build_node_list_from_side_list();
233 false,
false,
false);
boundary_id_type BoundaryID
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
registerMooseObject("MooseApp", SidesetAroundSubdomainUpdater)
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
virtual MooseMesh & mesh() override
This user object allows related evaluations on elements, boundaries, internal sides,...
const Elem *const & _current_elem
The current element pointer (available during all execute functions)
MooseMesh & _mesh
the Moose mesh
const Elem *const & _neighbor_elem
The neighboring element (available during executeOnInternalSide() and executeOnInterface())
static InputParameters validParams()
const unsigned int & _current_side
Current side of the current element (available during executeOnInternalSide() and executeOnBoundary()...
virtual void meshChanged(bool intermediate_change, bool contract_mesh, bool clean_refinement_flags)
Update data after a mesh change.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
bool getConstructNodeListFromSideList()
Return construct node list from side list boolean.
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
Update side sets around subdomains during a run, as subdomain IDs are changing.
const processor_id_type _pid
The MPI rank of this processor.
DisplacedProblem * _displaced_problem
Pointer to the displaced problem.
const bool _assign_outer_surface_sides
assign sideset to sides that have no neighbor elements
virtual void finalize() override
Finalize.
const BoundaryID _mask_side
If specified, only sides also on this boundary will be updated.
virtual void executeOnExternalSide(const Elem *, unsigned int) override
execute method that is called during ComputeUserObjects::onExternalSide
std::map< processor_id_type, SideList > _add
virtual void executeOnInternalSide() override
execute method that is called during ComputeUserObjects::onInternalSide
const unsigned int & _neighbor_side
Current side on the neighboring element.
BoundaryName _boundary_name
Boundary / sideset to update.
std::set< SubdomainID > _inner_ids
Subdomains on the two sides of the boundary.
std::vector< std::tuple< dof_id_type, unsigned short int > > SideList
virtual void threadJoin(const UserObject &) override
Must override.
std::set< SubdomainID > _outer_ids
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
SidesetAroundSubdomainUpdater(const InputParameters ¶meters)
BoundaryInfo & _boundary_info
static InputParameters validParams()
void processSide(const Elem *primary_elem, unsigned short int primary_side, const Elem *secondary_elem)
std::map< processor_id_type, SideList > _remove
BoundaryInfo * _displaced_boundary_info
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
Base class for user-specific data.
const Parallel::Communicator & _communicator
const Parallel::Communicator & comm() const
std::vector< subdomain_id_type > getSubdomainIDs(const libMesh::MeshBase &mesh, const std::vector< SubdomainName > &subdomain_name)
Get the associated subdomainIDs for the subdomain names that are passed in.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const BoundaryID INVALID_BOUNDARY_ID
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)