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 secondary = mesh.getBoundaryID(nfc->getParam<BoundaryName>("secondary"));
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[secondary].addObject(nfc);
48  else
49  _node_face_constraints[secondary].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 secondary_boundary_id =
59  mesh.getBoundaryID(mc->getParam<BoundaryName>("secondary_boundary"));
60  auto primary_boundary_id = mesh.getBoundaryID(mc->getParam<BoundaryName>("primary_boundary"));
61  auto key = std::make_pair(primary_boundary_id, secondary_boundary_id);
62 
63  if (displaced)
64  _displaced_mortar_constraints[key].addObject(mc);
65  else
66  _mortar_constraints[key].addObject(mc);
67  }
68 
69  // ElemElemConstraint
70  else if (ec)
71  {
72  bool displaced = ec->parameters().have_parameter<bool>("use_displaced_mesh") &&
73  ec->getParam<bool>("use_displaced_mesh");
74  const InterfaceID interface_id = ec->getInterfaceID();
75 
76  if (displaced)
77  _displaced_element_constraints[interface_id].addObject(ec);
78  else
79  _element_constraints[interface_id].addObject(ec);
80  }
81 
82  // NodeElemConstraint
83  else if (nec)
84  {
85  MooseMesh & mesh = nec->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
86  SubdomainID secondary = mesh.getSubdomainID(nec->getParam<SubdomainName>("secondary"));
87  SubdomainID primary = mesh.getSubdomainID(nec->getParam<SubdomainName>("primary"));
88  bool displaced = nec->parameters().have_parameter<bool>("use_displaced_mesh") &&
89  nec->getParam<bool>("use_displaced_mesh");
90 
91  if (displaced)
92  _displaced_node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
93  else
94  _node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
95  }
96 
97  // NodalConstraint
98  else if (nc)
100 
101  else
102  mooseError("Unknown type of Constraint object");
103 }
104 
105 const std::vector<std::shared_ptr<NodalConstraint>> &
107 {
109 }
110 
111 const std::vector<std::shared_ptr<NodeFaceConstraint>> &
113 {
114  std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
115 
116  if (displaced)
117  {
118  it = _displaced_node_face_constraints.find(boundary_id);
119  end_it = _displaced_node_face_constraints.end();
120  }
121 
122  else
123  {
124  it = _node_face_constraints.find(boundary_id);
125  end_it = _node_face_constraints.end();
126  }
127 
128  mooseAssert(it != end_it,
129  "Unable to locate storage for NodeFaceConstraint objects for the given boundary id: "
130  << boundary_id);
131  return it->second.getActiveObjects();
132 }
133 
134 bool
136  const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
137 {
138  const auto & constraints = displaced ? _displaced_mortar_constraints : _mortar_constraints;
139  return constraints.find(mortar_interface_key) != constraints.end();
140 }
141 
142 const std::vector<std::shared_ptr<MortarConstraintBase>> &
144  const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
145 {
146  std::map<std::pair<BoundaryID, BoundaryID>,
147  MooseObjectWarehouse<MortarConstraintBase>>::const_iterator it,
148  end_it;
149 
150  if (displaced)
151  {
152  it = _displaced_mortar_constraints.find(mortar_interface_key);
153  end_it = _displaced_mortar_constraints.end();
154  }
155  else
156  {
157  it = _mortar_constraints.find(mortar_interface_key);
158  end_it = _mortar_constraints.end();
159  }
160 
161  mooseAssert(
162  it != end_it,
163  "No MortarConstraints exist for the specified primary-secondary boundary pair, primary "
164  << mortar_interface_key.first << " and secondary " << mortar_interface_key.second);
165 
166  return it->second.getActiveObjects();
167 }
168 
169 const std::vector<std::shared_ptr<ElemElemConstraint>> &
171  bool displaced) const
172 {
173  std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
174 
175  if (displaced)
176  {
177  it = _displaced_element_constraints.find(interface_id);
178  end_it = _displaced_element_constraints.end();
179  }
180 
181  else
182  {
183  it = _element_constraints.find(interface_id);
184  end_it = _element_constraints.end();
185  }
186 
187  mooseAssert(it != end_it,
188  "Unable to locate storage for ElemElemConstraint objects for the given interface id: "
189  << interface_id);
190  return it->second.getActiveObjects();
191 }
192 
193 const std::vector<std::shared_ptr<NodeElemConstraint>> &
195  SubdomainID primary_id,
196  bool displaced) const
197 {
198  std::map<std::pair<SubdomainID, SubdomainID>,
199  MooseObjectWarehouse<NodeElemConstraint>>::const_iterator it,
200  end_it;
201 
202  if (displaced)
203  {
204  it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
205  end_it = _displaced_node_elem_constraints.end();
206  }
207  else
208  {
209  it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
210  end_it = _node_elem_constraints.end();
211  }
212 
213  mooseAssert(it != end_it,
214  "Unable to locate storage for NodeElemConstraint objects for the given secondary and "
215  "primary id pair: ["
216  << secondary_id << ", " << primary_id << "]");
217  return it->second.getActiveObjects();
218 }
219 
220 bool
222 {
224 }
225 
226 bool
228  bool displaced) const
229 {
230  std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
231 
232  if (displaced)
233  {
234  it = _displaced_element_constraints.find(interface_id);
235  end_it = _displaced_element_constraints.end();
236  }
237 
238  else
239  {
240  it = _element_constraints.find(interface_id);
241  end_it = _element_constraints.end();
242  }
243 
244  return (it != end_it && it->second.hasActiveObjects());
245 }
246 
247 bool
249 {
250  std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
251 
252  if (displaced)
253  {
254  it = _displaced_node_face_constraints.find(boundary_id);
255  end_it = _displaced_node_face_constraints.end();
256  }
257 
258  else
259  {
260  it = _node_face_constraints.find(boundary_id);
261  end_it = _node_face_constraints.end();
262  }
263 
264  return (it != end_it && it->second.hasActiveObjects());
265 }
266 
267 bool
269  SubdomainID primary_id,
270  bool displaced) const
271 {
272  std::map<std::pair<SubdomainID, SubdomainID>,
273  MooseObjectWarehouse<NodeElemConstraint>>::const_iterator it,
274  end_it;
275 
276  if (displaced)
277  {
278  it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
279  end_it = _displaced_node_elem_constraints.end();
280  }
281 
282  else
283  {
284  it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
285  end_it = _node_elem_constraints.end();
286  }
287 
288  return (it != end_it && it->second.hasActiveObjects());
289 }
290 
292 {
295 
296  for (auto & it : _node_face_constraints)
297  it.second.updateActive();
298 
299  for (auto & it : _displaced_node_face_constraints)
300  it.second.updateActive();
301 
302  // FIXME: We call updateActive() on the NodeFaceConstraints again?
303  for (auto & it : _node_face_constraints)
304  it.second.updateActive();
305 
306  for (auto & it : _element_constraints)
307  it.second.updateActive();
308 
309  for (auto & it : _node_elem_constraints)
310  it.second.updateActive();
311 }
312 
313 void
314 ConstraintWarehouse::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
315  std::set<std::string> & unique_variables,
316  THREAD_ID /*tid=0*/) const
317 {
318  // Loop over undisplaced
319  for (const auto & pr : _mortar_constraints)
320  {
321  const auto & objects = pr.second.getActiveObjects();
322  for (const auto & mc : objects)
323  {
324  const MooseVariableFEBase * lm_var = mc->variablePtr();
325  if (lm_var)
326  unique_variables.insert(lm_var->name());
327 
328  // Mortar constraints will cover primary and secondary subdomains regardless of whether we
329  // have a Lagrange multiplier associated.
330  subdomains_covered.insert(mc->primarySubdomain());
331  subdomains_covered.insert(mc->secondarySubdomain());
332  }
333  }
334 
335  // Loop over displaced
336  for (const auto & pr : _displaced_mortar_constraints)
337  {
338  const auto & objects = pr.second.getActiveObjects();
339  for (const auto & mc : objects)
340  {
341  const MooseVariableFEBase * lm_var = mc->variablePtr();
342  if (lm_var)
343  unique_variables.insert(lm_var->name());
344 
345  // Mortar constraints will cover primary and secondary subdomains regardless of whether we
346  // have a Lagrange multiplier associated.
347  subdomains_covered.insert(mc->primarySubdomain());
348  subdomains_covered.insert(mc->secondarySubdomain());
349  }
350  }
351 }
352 
353 void
355 {
356  checkThreadID(tid);
357  for (const auto & object : _active_objects[tid])
358  object->residualEnd();
359 }
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:284
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:19
const std::vector< std::shared_ptr< NodeFaceConstraint > > & getActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
MeshBase & mesh
void checkThreadID(THREAD_ID tid) const
Calls assert on thread id.
const std::string & name() const override
Get the variable name.
bool hasActiveMortarConstraints(const std::pair< BoundaryID, BoundaryID > &mortar_interface_key, bool displaced) const
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.
This class provides an interface for common operations on field variables of both FE and FV types wit...
void updateActive(THREAD_ID tid=0) override
Update the various active lists.
bool hasActiveNodeElemConstraints(SubdomainID secondary_id, SubdomainID primary_id, bool displaced) const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
bool hasActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
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:88
unsigned int InterfaceID
Definition: MooseTypes.h:195
std::map< unsigned int, MooseObjectWarehouse< ElemElemConstraint > > _element_constraints
ElemElemConstraints (non-displaced)
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::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
const std::vector< std::shared_ptr< NodeElemConstraint > > & getActiveNodeElemConstraints(SubdomainID secondary_id, SubdomainID primary_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 secondary node and a prima...
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 insert(NumericVector< Number > &vector)=0
Insert the currently cached degree of freedom values into the provided vector.
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
unsigned int THREAD_ID
Definition: MooseTypes.h:198