www.mooseframework.org
ConstraintWarehouse.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 
10 #include "ConstraintWarehouse.h"
11 
12 // MOOSE includes
13 #include "ElemElemConstraint.h"
14 #include "MortarConstraintBase.h"
15 #include "MooseVariable.h"
16 #include "NodalConstraint.h"
17 #include "NodeFaceConstraint.h"
18 #include "NodeElemConstraint.h"
19 
21 
22 void
23 ConstraintWarehouse::addObject(std::shared_ptr<Constraint> object,
24  THREAD_ID /*tid = 0*/,
25  bool /*recurse = true*/)
26 {
27  // Adds to the storage of _all_objects
29 
30  // Cast the the possible Contraint types
31  std::shared_ptr<NodeFaceConstraint> nfc = std::dynamic_pointer_cast<NodeFaceConstraint>(object);
32  std::shared_ptr<MortarConstraintBase> mc =
34  std::shared_ptr<NodalConstraint> nc = std::dynamic_pointer_cast<NodalConstraint>(object);
35  std::shared_ptr<ElemElemConstraint> ec = std::dynamic_pointer_cast<ElemElemConstraint>(object);
36  std::shared_ptr<NodeElemConstraint> nec = std::dynamic_pointer_cast<NodeElemConstraint>(object);
37 
38  // NodeFaceConstraint
39  if (nfc)
40  {
41  MooseMesh & mesh = nfc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
42  unsigned int slave = mesh.getBoundaryID(nfc->getParam<BoundaryName>("slave"));
43  bool displaced = nfc->parameters().have_parameter<bool>("use_displaced_mesh") &&
44  nfc->getParam<bool>("use_displaced_mesh");
45 
46  if (displaced)
47  _displaced_node_face_constraints[slave].addObject(nfc);
48  else
49  _node_face_constraints[slave].addObject(nfc);
50  }
51 
52  // MortarConstraint
53  else if (mc)
54  {
55  MooseMesh & mesh = mc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
56  bool displaced = mc->getParam<bool>("use_displaced_mesh");
57 
58  auto slave_boundary_id = mesh.getBoundaryID(mc->getParam<BoundaryName>("slave_boundary"));
59  auto master_boundary_id = mesh.getBoundaryID(mc->getParam<BoundaryName>("master_boundary"));
60  auto key = std::make_pair(master_boundary_id, slave_boundary_id);
61 
62  if (displaced)
63  _displaced_mortar_constraints[key].addObject(mc);
64  else
65  _mortar_constraints[key].addObject(mc);
66  }
67 
68  // ElemElemConstraint
69  else if (ec)
70  {
71  bool displaced = ec->parameters().have_parameter<bool>("use_displaced_mesh") &&
72  ec->getParam<bool>("use_displaced_mesh");
73  const InterfaceID interface_id = ec->getInterfaceID();
74 
75  if (displaced)
76  _displaced_element_constraints[interface_id].addObject(ec);
77  else
78  _element_constraints[interface_id].addObject(ec);
79  }
80 
81  // NodeElemConstraint
82  else if (nec)
83  {
84  MooseMesh & mesh = nec->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
85  SubdomainID slave = mesh.getSubdomainID(nec->getParam<SubdomainName>("slave"));
86  SubdomainID master = mesh.getSubdomainID(nec->getParam<SubdomainName>("master"));
87  bool displaced = nec->parameters().have_parameter<bool>("use_displaced_mesh") &&
88  nec->getParam<bool>("use_displaced_mesh");
89 
90  if (displaced)
91  _displaced_node_elem_constraints[std::make_pair(slave, master)].addObject(nec);
92  else
93  _node_elem_constraints[std::make_pair(slave, master)].addObject(nec);
94  }
95 
96  // NodalConstraint
97  else if (nc)
99 
100  else
101  mooseError("Unknown type of Constraint object");
102 }
103 
104 const std::vector<std::shared_ptr<NodalConstraint>> &
106 {
108 }
109 
110 const std::vector<std::shared_ptr<NodeFaceConstraint>> &
112 {
113  std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
114 
115  if (displaced)
116  {
117  it = _displaced_node_face_constraints.find(boundary_id);
118  end_it = _displaced_node_face_constraints.end();
119  }
120 
121  else
122  {
123  it = _node_face_constraints.find(boundary_id);
124  end_it = _node_face_constraints.end();
125  }
126 
127  mooseAssert(it != end_it,
128  "Unable to locate storage for NodeFaceConstraint objects for the given boundary id: "
129  << boundary_id);
130  return it->second.getActiveObjects();
131 }
132 
133 const std::vector<std::shared_ptr<MortarConstraintBase>> &
135  const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, bool displaced) const
136 {
137  std::map<std::pair<BoundaryID, BoundaryID>,
138  MooseObjectWarehouse<MortarConstraintBase>>::const_iterator it,
139  end_it;
140 
141  if (displaced)
142  {
143  it = _displaced_mortar_constraints.find(mortar_interface_key);
144  end_it = _displaced_mortar_constraints.end();
145  }
146  else
147  {
148  it = _mortar_constraints.find(mortar_interface_key);
149  end_it = _mortar_constraints.end();
150  }
151 
152  mooseAssert(it != end_it,
153  "No MortarConstraints exist for the specified master-slave boundary pair, master "
154  << mortar_interface_key.first << " and slave " << mortar_interface_key.second);
155 
156  return it->second.getActiveObjects();
157 }
158 
159 const std::vector<std::shared_ptr<ElemElemConstraint>> &
161  bool displaced) const
162 {
163  std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
164 
165  if (displaced)
166  {
167  it = _displaced_element_constraints.find(interface_id);
168  end_it = _displaced_element_constraints.end();
169  }
170 
171  else
172  {
173  it = _element_constraints.find(interface_id);
174  end_it = _element_constraints.end();
175  }
176 
177  mooseAssert(it != end_it,
178  "Unable to locate storage for ElemElemConstraint objects for the given interface id: "
179  << interface_id);
180  return it->second.getActiveObjects();
181 }
182 
183 const std::vector<std::shared_ptr<NodeElemConstraint>> &
185  SubdomainID master_id,
186  bool displaced) const
187 {
188  std::map<std::pair<SubdomainID, SubdomainID>,
189  MooseObjectWarehouse<NodeElemConstraint>>::const_iterator it,
190  end_it;
191 
192  if (displaced)
193  {
194  it = _displaced_node_elem_constraints.find(std::make_pair(slave_id, master_id));
195  end_it = _displaced_node_elem_constraints.end();
196  }
197  else
198  {
199  it = _node_elem_constraints.find(std::make_pair(slave_id, master_id));
200  end_it = _node_elem_constraints.end();
201  }
202 
203  mooseAssert(it != end_it,
204  "Unable to locate storage for NodeElemConstraint objects for the given slave and "
205  "master id pair: ["
206  << slave_id << ", " << master_id << "]");
207  return it->second.getActiveObjects();
208 }
209 
210 bool
212 {
214 }
215 
216 bool
218  bool displaced) const
219 {
220  std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
221 
222  if (displaced)
223  {
224  it = _displaced_element_constraints.find(interface_id);
225  end_it = _displaced_element_constraints.end();
226  }
227 
228  else
229  {
230  it = _element_constraints.find(interface_id);
231  end_it = _element_constraints.end();
232  }
233 
234  return (it != end_it && it->second.hasActiveObjects());
235 }
236 
237 bool
239 {
240  std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
241 
242  if (displaced)
243  {
244  it = _displaced_node_face_constraints.find(boundary_id);
245  end_it = _displaced_node_face_constraints.end();
246  }
247 
248  else
249  {
250  it = _node_face_constraints.find(boundary_id);
251  end_it = _node_face_constraints.end();
252  }
253 
254  return (it != end_it && it->second.hasActiveObjects());
255 }
256 
257 bool
259  SubdomainID master_id,
260  bool displaced) const
261 {
262  std::map<std::pair<SubdomainID, SubdomainID>,
263  MooseObjectWarehouse<NodeElemConstraint>>::const_iterator it,
264  end_it;
265 
266  if (displaced)
267  {
268  it = _displaced_node_elem_constraints.find(std::make_pair(slave_id, master_id));
269  end_it = _displaced_node_elem_constraints.end();
270  }
271 
272  else
273  {
274  it = _node_elem_constraints.find(std::make_pair(slave_id, master_id));
275  end_it = _node_elem_constraints.end();
276  }
277 
278  return (it != end_it && it->second.hasActiveObjects());
279 }
280 
282 {
285 
286  for (auto & it : _node_face_constraints)
287  it.second.updateActive();
288 
289  for (auto & it : _displaced_node_face_constraints)
290  it.second.updateActive();
291 
292  // FIXME: We call updateActive() on the NodeFaceConstraints again?
293  for (auto & it : _node_face_constraints)
294  it.second.updateActive();
295 
296  for (auto & it : _element_constraints)
297  it.second.updateActive();
298 
299  for (auto & it : _node_elem_constraints)
300  it.second.updateActive();
301 }
302 
303 void
304 ConstraintWarehouse::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
305  std::set<std::string> & unique_variables,
306  THREAD_ID /*tid=0*/) const
307 {
308  // Loop over undisplaced
309  for (const auto & pr : _mortar_constraints)
310  {
311  const auto & objects = pr.second.getActiveObjects();
312  for (const auto & mc : objects)
313  {
314  const MooseVariableFEBase * lm_var = mc->variable();
315  if (lm_var)
316  {
317  unique_variables.insert(lm_var->name());
318  const std::set<SubdomainID> & lm_subdomains = lm_var->activeSubdomains();
319  subdomains_covered.insert(lm_subdomains.begin(), lm_subdomains.end());
320  }
321 
322  // Mortar constraints require the creation of a master lower dimensional subdomain in order to
323  // create the mortar segment mesh. We don't need any computing objects on it
324  subdomains_covered.insert(mc->masterSubdomain());
325  }
326  }
327 
328  // Loop over displaced
329  for (const auto & pr : _displaced_mortar_constraints)
330  {
331  const auto & objects = pr.second.getActiveObjects();
332  for (const auto & mc : objects)
333  {
334  const MooseVariableFEBase * lm_var = mc->variable();
335  if (lm_var)
336  {
337  unique_variables.insert(lm_var->name());
338  const std::set<SubdomainID> & lm_subdomains = lm_var->activeSubdomains();
339  subdomains_covered.insert(lm_subdomains.begin(), lm_subdomains.end());
340  }
341 
342  // Mortar constraints require the creation of a master lower dimensional subdomain in order to
343  // create the mortar segment mesh. We don't need any computing objects on it
344  subdomains_covered.insert(mc->masterSubdomain());
345  }
346  }
347 }
348 
349 void
351 {
352  checkThreadID(tid);
353  for (const auto & object : _active_objects[tid])
354  object->residualEnd();
355 }
std::map< std::pair< BoundaryID, BoundaryID >, MooseObjectWarehouse< MortarConstraintBase > > _displaced_mortar_constraints
Displaced MortarConstraints.
User for mortar methods.
MooseObjectWarehouse< NodalConstraint > _nodal_constraints
NodalConstraint objects.
std::map< BoundaryID, MooseObjectWarehouse< NodeFaceConstraint > > _displaced_node_face_constraints
NodeFaceConstraint objects (displaced)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
const std::vector< std::shared_ptr< NodalConstraint > > & getActiveNodalConstraints() const
Access methods for active objects.
std::map< std::pair< SubdomainID, SubdomainID >, MooseObjectWarehouse< NodeElemConstraint > > _displaced_node_elem_constraints
NodeElemConstraint objects.
A storage container for MooseObjects that inherit from SetupInterface.
Base class for all Constraint types.
Definition: Constraint.h:39
const std::vector< std::shared_ptr< NodeFaceConstraint > > & getActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
void checkThreadID(THREAD_ID tid) const
Calls assert on thread id.
bool hasActiveNodalConstraints() const
Deterimine if active objects exist.
std::map< std::pair< SubdomainID, SubdomainID >, MooseObjectWarehouse< NodeElemConstraint > > _node_elem_constraints
NodeElemConstraint objects.
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
void updateActive(THREAD_ID tid=0) override
Update the various active lists.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseObject.h:191
bool hasActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
virtual const std::set< SubdomainID > & activeSubdomains() const =0
The subdomains the variable is active on.
virtual void insert(NumericVector< Number > &residual)=0
const std::vector< std::shared_ptr< T > > & getActiveObjects(THREAD_ID tid=0) const
Retrieve complete vector to the active all/block/boundary restricted objects for a given thread...
boundary_id_type BoundaryID
A NodeFaceConstraint is used when you need to create constraints between two surfaces in a mesh...
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
unsigned int InterfaceID
Definition: MooseTypes.h:158
subdomain_id_type SubdomainID
std::map< unsigned int, MooseObjectWarehouse< ElemElemConstraint > > _element_constraints
ElemElemConstraints (non-displaced)
const std::vector< std::shared_ptr< NodeElemConstraint > > & getActiveNodeElemConstraints(SubdomainID slave_id, SubdomainID master_id, bool displaced) const
std::map< unsigned int, MooseObjectWarehouse< ElemElemConstraint > > _displaced_element_constraints
ElemElemConstraints (displaced)
bool hasActiveObjects(THREAD_ID tid=0) const
void addObject(std::shared_ptr< Constraint > object, THREAD_ID tid=0, bool recurse=true) override
Add Constraint object to the warehouse.
const std::string & name() const
Get the variable name.
const std::vector< std::shared_ptr< MortarConstraintBase > > & getActiveMortarConstraints(const std::pair< BoundaryID, BoundaryID > &mortar_interface_key, bool displaced) const
std::map< std::pair< BoundaryID, BoundaryID >, MooseObjectWarehouse< MortarConstraintBase > > _mortar_constraints
Undisplaced MortarConstraints.
virtual void updateActive(THREAD_ID tid=0) override
Update the active status of Kernels.
bool hasActiveElemElemConstraints(const InterfaceID interface_id, bool displaced) const
bool hasActiveNodeElemConstraints(SubdomainID slave_id, SubdomainID master_id, bool displaced) const
std::vector< std::vector< std::shared_ptr< Constraint > > > _active_objects
All active objects (THREAD_ID on outer vector)
A NodeElemConstraint is used when you need to create constraints between a slave node and a master el...
void subdomainsCovered(std::set< SubdomainID > &subdomains_covered, std::set< std::string > &unique_variables, THREAD_ID tid=0) const
Update supplied subdomain and variable coverate containters.
const std::vector< std::shared_ptr< ElemElemConstraint > > & getActiveElemElemConstraints(InterfaceID interface_id, bool displaced) const
virtual void addObject(std::shared_ptr< T > object, THREAD_ID tid=0, bool recurse=true) override
Adds an object to the storage structure.
std::map< BoundaryID, MooseObjectWarehouse< NodeFaceConstraint > > _node_face_constraints
NodeFaceConstraint objects (non-displaced)
virtual void residualEnd(THREAD_ID tid=0) const
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
Definition: MooseMesh.C:1007
unsigned int THREAD_ID
Definition: MooseTypes.h:161
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.
Definition: MooseMesh.C:1075