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