www.mooseframework.org
AssignElementSubdomainID.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 "MooseMesh.h"
17 
18 template <>
21 {
23  params.addRequiredParam<std::vector<SubdomainID>>("subdomain_ids",
24  "New subdomain IDs of all elements");
25  params.addParam<std::vector<dof_id_type>>("element_ids", "New subdomain IDs of all elements");
26  return params;
27 }
28 
30  : MeshModifier(parameters)
31 {
32 }
33 
34 void
36 {
37  // Check that we have access to the mesh
38  if (!_mesh_ptr)
39  mooseError("_mesh_ptr must be initialized before calling SubdomainBoundingBox::modify()");
40 
41  // Reference the the libMesh::MeshBase
42  MeshBase & mesh = _mesh_ptr->getMesh();
43 
44  std::vector<SubdomainID> bids = getParam<std::vector<SubdomainID>>("subdomain_ids");
45 
46  // Generate a list of elements to which new subdomain IDs are to be assigned
47  std::vector<Elem *> elements;
48  if (isParamValid("element_ids"))
49  {
50  std::vector<dof_id_type> elemids = getParam<std::vector<dof_id_type>>("element_ids");
51  for (const auto & dof : elemids)
52  {
53  Elem * elem = mesh.query_elem_ptr(dof);
54  bool has_elem = elem;
55 
56  // If no processor sees this element, something must be wrong
57  // with the specified ID. If another processor sees this
58  // element but we don't, we'll insert NULL into our elements
59  // vector anyway so as to keep the indexing matching our bids
60  // vector.
61  this->comm().max(has_elem);
62  if (!has_elem)
63  mooseError("invalid element ID is in element_ids");
64  else
65  elements.push_back(elem);
66  }
67  }
68  else
69  {
70  bool has_warned_remapping = false;
71 
72  // On a distributed mesh, iterating over all elements in
73  // increasing order is tricky. We have to consider element ids
74  // which aren't on a particular processor because they're remote,
75  // *and* elements which aren't on a particular processor because
76  // there's a hole in the current numbering.
77  //
78  // I don't see how to do this without a ton of communication,
79  // which is hopefully okay because it only happens at mesh setup,
80  // and because nobody who is here trying to use
81  // AssignElementSubdomainID to hand write every single element's
82  // subdomain ID will have a huge number of elements on their
83  // initial mesh.
84 
85  // Using plain max_elem_id() currently gives the same result on
86  // every processor, but that isn't guaranteed by the libMesh
87  // documentation, so let's be paranoid.
88  dof_id_type end_id = mesh.max_elem_id();
89  this->comm().max(end_id);
90 
91  for (dof_id_type e = 0; e != end_id; ++e)
92  {
93  // This is O(1) on ReplicatedMesh but O(log(N_elem)) on
94  // DistributedMesh. We can switch to more complicated but
95  // asymptotically faster code if my "nobody who is here ... will
96  // have a huge number of elements" claim turns out to be false.
97  Elem * elem = mesh.query_elem_ptr(e);
98  bool someone_has_elem = elem;
99  if (!mesh.is_replicated())
100  this->comm().max(someone_has_elem);
101 
102  if (elem && elem->id() != e && (!has_warned_remapping))
103  {
104  mooseWarning("AssignElementSubdomainID will ignore the element remapping");
105  has_warned_remapping = true;
106  }
107 
108  if (someone_has_elem)
109  elements.push_back(elem);
110  }
111  }
112 
113  if (bids.size() != elements.size())
114  mooseError(" Size of subdomain_ids is not consistent with the number of elements");
115 
116  // Assign new subdomain IDs and make sure elements in different types are not assigned with the
117  // same subdomain ID
118  std::map<ElemType, std::set<SubdomainID>> type2blocks;
119  for (dof_id_type e = 0; e < elements.size(); ++e)
120  {
121  // Get the element we need to assign, or skip it if we just have a
122  // nullptr placeholder indicating a remote element.
123  Elem * elem = elements[e];
124  if (!elem)
125  continue;
126 
127  ElemType type = elem->type();
128  SubdomainID newid = bids[e];
129 
130  bool has_type = false;
131  for (auto & it : type2blocks)
132  {
133  if (it.first == type)
134  {
135  has_type = true;
136  it.second.insert(newid);
137  }
138  else if (it.second.count(newid) > 0)
139  mooseError("trying to assign elements with different types with the same subdomain ID");
140  }
141 
142  if (!has_type)
143  {
144  std::set<SubdomainID> blocks;
145  blocks.insert(newid);
146  type2blocks.insert(std::make_pair(type, blocks));
147  }
148 
149  elem->subdomain_id() = newid;
150  }
151 }
void mooseWarning(Args &&...args) const
Definition: MooseObject.h:89
subdomain_id_type SubdomainID
Definition: MooseTypes.h:77
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.
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:2355
AssignElementSubdomainID(const InputParameters &parameters)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:67
MatType type
MPI_Comm comm
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
void mooseError(Args &&...args) const
Definition: MooseObject.h:80
InputParameters validParams< AssignElementSubdomainID >()
InputParameters validParams< MeshModifier >()
Definition: MeshModifier.C:20