www.mooseframework.org
SideSetsBetweenSubdomains.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
16 #include "InputParameters.h"
17 #include "MooseTypes.h"
18 #include "MooseMesh.h"
19 
20 #include "libmesh/remote_elem.h"
21 
22 template <>
25 {
27  params.addRequiredParam<std::vector<SubdomainName>>(
28  "master_block", "The master set of blocks for which to draw a sideset between");
29  params.addRequiredParam<std::vector<SubdomainName>>(
30  "paired_block", "The paired set of blocks for which to draw a sideset between");
31  params.addRequiredParam<std::vector<BoundaryName>>("new_boundary",
32  "The name of the boundary to create");
33  return params;
34 }
35 
37  : MeshModifier(parameters)
38 {
39 }
40 
41 void
43 {
44  MeshBase & mesh = _mesh_ptr->getMesh();
45 
46  std::vector<SubdomainID> vec_master_ids =
47  _mesh_ptr->getSubdomainIDs(getParam<std::vector<SubdomainName>>("master_block"));
48  std::set<SubdomainID> master_ids(vec_master_ids.begin(), vec_master_ids.end());
49 
50  std::vector<SubdomainID> vec_paired_ids =
51  _mesh_ptr->getSubdomainIDs(getParam<std::vector<SubdomainName>>("paired_block"));
52  std::set<SubdomainID> paired_ids(vec_paired_ids.begin(), vec_paired_ids.end());
53 
54  std::vector<BoundaryName> boundary_names = getParam<std::vector<BoundaryName>>("new_boundary");
55  std::vector<BoundaryID> boundary_ids = _mesh_ptr->getBoundaryIDs(boundary_names, true);
56 
57  // Get a reference to our BoundaryInfo object for later use
58  BoundaryInfo & boundary_info = mesh.get_boundary_info();
59 
60  // Prepare to query about sides adjacent to remote elements if we're
61  // on a distributed mesh
62  const processor_id_type my_n_proc = mesh.n_processors();
63  const processor_id_type my_proc_id = mesh.processor_id();
64  typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
65  std::vector<vec_type> queries(my_n_proc);
66 
67  for (const auto & elem : mesh.active_element_ptr_range())
68  {
69  SubdomainID curr_subdomain = elem->subdomain_id();
70 
71  // We only need to loop over elements in the master subdomain
72  if (master_ids.count(curr_subdomain) == 0)
73  continue;
74 
75  for (unsigned int side = 0; side < elem->n_sides(); side++)
76  {
77  const Elem * neighbor = elem->neighbor_ptr(side);
78 
79  // On a replicated mesh, we add all subdomain sides ourselves.
80  // On a distributed mesh, we may have missed sides which
81  // neighbor remote elements. We should query any such cases.
82  if (neighbor == remote_elem)
83  {
84  queries[elem->processor_id()].push_back(std::make_pair(elem->id(), side));
85  }
86  else if (neighbor != NULL && paired_ids.count(neighbor->subdomain_id()) > 0)
87 
88  // Add the boundaries
89  for (const auto & boundary_id : boundary_ids)
90  boundary_info.add_side(elem, side, boundary_id);
91  }
92  }
93 
94  if (!mesh.is_serial())
95  {
96  Parallel::MessageTag queries_tag = mesh.comm().get_unique_tag(867),
97  replies_tag = mesh.comm().get_unique_tag(5309);
98 
99  std::vector<Parallel::Request> side_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
100 
101  // Make all requests
102  for (processor_id_type p = 0; p != my_n_proc; ++p)
103  {
104  if (p == my_proc_id)
105  continue;
106 
107  Parallel::Request & request = side_requests[p - (p > my_proc_id)];
108 
109  mesh.comm().send(p, queries[p], request, queries_tag);
110  }
111 
112  // Reply to all requests
113  std::vector<vec_type> responses(my_n_proc - 1);
114 
115  for (processor_id_type p = 1; p != my_n_proc; ++p)
116  {
117  vec_type query;
118 
119  Parallel::Status status(mesh.comm().probe(Parallel::any_source, queries_tag));
120  const processor_id_type source_pid = cast_int<processor_id_type>(status.source());
121 
122  mesh.comm().receive(source_pid, query, queries_tag);
123 
124  Parallel::Request & request = reply_requests[p - 1];
125 
126  for (const auto & q : query)
127  {
128  const Elem * elem = mesh.elem_ptr(q.first);
129  const unsigned int side = q.second;
130  const Elem * neighbor = elem->neighbor_ptr(side);
131 
132  if (neighbor != NULL && paired_ids.count(neighbor->subdomain_id()) > 0)
133  {
134  responses[p - 1].push_back(std::make_pair(elem->id(), side));
135  }
136  }
137 
138  mesh.comm().send(source_pid, responses[p - 1], request, replies_tag);
139  }
140 
141  // Process all incoming replies
142  for (processor_id_type p = 1; p != my_n_proc; ++p)
143  {
144  Parallel::Status status(this->comm().probe(Parallel::any_source, replies_tag));
145  const processor_id_type source_pid = cast_int<processor_id_type>(status.source());
146 
147  vec_type response;
148 
149  this->comm().receive(source_pid, response, replies_tag);
150 
151  for (const auto & r : response)
152  {
153  const Elem * elem = mesh.elem_ptr(r.first);
154  const unsigned int side = r.second;
155 
156  for (const auto & boundary_id : boundary_ids)
157  boundary_info.add_side(elem, side, boundary_id);
158  }
159  }
160 
161  Parallel::wait(side_requests);
162  Parallel::wait(reply_requests);
163  }
164 
165  for (unsigned int i = 0; i < boundary_ids.size(); ++i)
166  boundary_info.sideset_name(boundary_ids[i]) = boundary_names[i];
167 }
subdomain_id_type SubdomainID
Definition: MooseTypes.h:77
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side. ...
Definition: MooseMesh.C:1990
MeshModifiers are objects that can modify or add to an existing mesh.
Definition: MeshModifier.h:31
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
MooseMesh * _mesh_ptr
Pointer to the mesh.
Definition: MeshModifier.h:74
virtual void modify() override
Pure virtual modify function MUST be overridden by children classes.
SideSetsBetweenSubdomains(const InputParameters &parameters)
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:2408
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseObject.h:122
InputParameters validParams< SideSetsBetweenSubdomains >()
MPI_Comm comm
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_name) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1051
InputParameters validParams< MeshModifier >()
Definition: MeshModifier.C:20