Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
ConstraintWarehouse.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
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 "NodeElemConstraintBase.h"
19 #include "FEProblemBase.h"
20 
22 
23 void
24 ConstraintWarehouse::addObject(std::shared_ptr<Constraint> object,
25  THREAD_ID /*tid = 0*/,
26  bool /*recurse = true*/)
27 {
28  // Adds to the storage of _all_objects
30 
31  // Cast the the possible Contraint types
32  std::shared_ptr<NodeFaceConstraint> nfc = std::dynamic_pointer_cast<NodeFaceConstraint>(object);
33  std::shared_ptr<MortarConstraintBase> mc =
35  std::shared_ptr<NodalConstraint> nc = std::dynamic_pointer_cast<NodalConstraint>(object);
36  std::shared_ptr<ElemElemConstraint> ec = std::dynamic_pointer_cast<ElemElemConstraint>(object);
37  std::shared_ptr<NodeElemConstraintBase> nec =
39 
40  // NodeFaceConstraint
41  if (nfc)
42  {
43  MooseMesh & mesh = nfc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
44  unsigned int secondary = mesh.getBoundaryID(nfc->getParam<BoundaryName>("secondary"));
45  bool displaced = nfc->parameters().have_parameter<bool>("use_displaced_mesh") &&
46  nfc->getParam<bool>("use_displaced_mesh");
47 
48  if (displaced)
49  _displaced_node_face_constraints[secondary].addObject(nfc);
50  else
51  _node_face_constraints[secondary].addObject(nfc);
52  }
53 
54  // MortarConstraint
55  else if (mc)
56  {
57  MooseMesh & mesh = mc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
58  bool displaced = mc->getParam<bool>("use_displaced_mesh");
59 
60  auto secondary_boundary_id =
61  mesh.getBoundaryID(mc->getParam<BoundaryName>("secondary_boundary"));
62  auto primary_boundary_id = mesh.getBoundaryID(mc->getParam<BoundaryName>("primary_boundary"));
63  auto key = std::make_pair(primary_boundary_id, secondary_boundary_id);
64 
65  if (displaced)
66  _displaced_mortar_constraints[key].addObject(mc);
67  else
68  _mortar_constraints[key].addObject(mc);
69  }
70 
71  // ElemElemConstraint
72  else if (ec)
73  {
74  bool displaced = ec->parameters().have_parameter<bool>("use_displaced_mesh") &&
75  ec->getParam<bool>("use_displaced_mesh");
76  const InterfaceID interface_id = ec->getInterfaceID();
77 
78  if (displaced)
79  _displaced_element_constraints[interface_id].addObject(ec);
80  else
81  _element_constraints[interface_id].addObject(ec);
82  }
83 
84  // NodeElemConstraintBase
85  else if (nec)
86  {
87  MooseMesh & mesh = nec->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
88  SubdomainID secondary = mesh.getSubdomainID(nec->getParam<SubdomainName>("secondary"));
89  SubdomainID primary = mesh.getSubdomainID(nec->getParam<SubdomainName>("primary"));
90  bool displaced = nec->parameters().have_parameter<bool>("use_displaced_mesh") &&
91  nec->getParam<bool>("use_displaced_mesh");
92 
93  if (displaced)
94  _displaced_node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
95  else
96  _node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
97  }
98 
99  // NodalConstraint
100  else if (nc)
102 
103  else
104  mooseError("Unknown type of Constraint object");
105 }
106 
107 const std::vector<std::shared_ptr<NodalConstraint>> &
109 {
111 }
112 
113 const std::vector<std::shared_ptr<NodeFaceConstraint>> &
115 {
116  std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
117 
118  if (displaced)
119  {
120  it = _displaced_node_face_constraints.find(boundary_id);
121  end_it = _displaced_node_face_constraints.end();
122  }
123 
124  else
125  {
126  it = _node_face_constraints.find(boundary_id);
127  end_it = _node_face_constraints.end();
128  }
129 
130  mooseAssert(it != end_it,
131  "Unable to locate storage for NodeFaceConstraint objects for the given boundary id: "
132  << boundary_id);
133  return it->second.getActiveObjects();
134 }
135 
136 bool
138  const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
139 {
140  const auto & constraints = displaced ? _displaced_mortar_constraints : _mortar_constraints;
141  return constraints.find(mortar_interface_key) != constraints.end();
142 }
143 
144 const std::vector<std::shared_ptr<MortarConstraintBase>> &
146  const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
147 {
148  std::map<std::pair<BoundaryID, BoundaryID>,
149  MooseObjectWarehouse<MortarConstraintBase>>::const_iterator it,
150  end_it;
151 
152  if (displaced)
153  {
154  it = _displaced_mortar_constraints.find(mortar_interface_key);
155  end_it = _displaced_mortar_constraints.end();
156  }
157  else
158  {
159  it = _mortar_constraints.find(mortar_interface_key);
160  end_it = _mortar_constraints.end();
161  }
162 
163  mooseAssert(
164  it != end_it,
165  "No MortarConstraints exist for the specified primary-secondary boundary pair, primary "
166  << mortar_interface_key.first << " and secondary " << mortar_interface_key.second);
167 
168  return it->second.getActiveObjects();
169 }
170 
171 const std::vector<std::shared_ptr<ElemElemConstraint>> &
173  bool displaced) const
174 {
175  std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
176 
177  if (displaced)
178  {
179  it = _displaced_element_constraints.find(interface_id);
180  end_it = _displaced_element_constraints.end();
181  }
182 
183  else
184  {
185  it = _element_constraints.find(interface_id);
186  end_it = _element_constraints.end();
187  }
188 
189  mooseAssert(it != end_it,
190  "Unable to locate storage for ElemElemConstraint objects for the given interface id: "
191  << interface_id);
192  return it->second.getActiveObjects();
193 }
194 
195 const std::vector<std::shared_ptr<NodeElemConstraintBase>> &
197  SubdomainID primary_id,
198  bool displaced) const
199 {
200  std::map<std::pair<SubdomainID, SubdomainID>,
202  end_it;
203 
204  if (displaced)
205  {
206  it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
207  end_it = _displaced_node_elem_constraints.end();
208  }
209  else
210  {
211  it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
212  end_it = _node_elem_constraints.end();
213  }
214 
215  mooseAssert(
216  it != end_it,
217  "Unable to locate storage for NodeElemConstraintBase objects for the given secondary and "
218  "primary id pair: ["
219  << secondary_id << ", " << primary_id << "]");
220  return it->second.getActiveObjects();
221 }
222 
223 bool
225 {
227 }
228 
229 bool
231  bool displaced) const
232 {
233  std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
234 
235  if (displaced)
236  {
237  it = _displaced_element_constraints.find(interface_id);
238  end_it = _displaced_element_constraints.end();
239  }
240 
241  else
242  {
243  it = _element_constraints.find(interface_id);
244  end_it = _element_constraints.end();
245  }
246 
247  return (it != end_it && it->second.hasActiveObjects());
248 }
249 
250 bool
252 {
253  std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
254 
255  if (displaced)
256  {
257  it = _displaced_node_face_constraints.find(boundary_id);
258  end_it = _displaced_node_face_constraints.end();
259  }
260 
261  else
262  {
263  it = _node_face_constraints.find(boundary_id);
264  end_it = _node_face_constraints.end();
265  }
266 
267  return (it != end_it && it->second.hasActiveObjects());
268 }
269 
270 bool
272  SubdomainID primary_id,
273  bool displaced) const
274 {
275  std::map<std::pair<SubdomainID, SubdomainID>,
277  end_it;
278 
279  if (displaced)
280  {
281  it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
282  end_it = _displaced_node_elem_constraints.end();
283  }
284 
285  else
286  {
287  it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
288  end_it = _node_elem_constraints.end();
289  }
290 
291  return (it != end_it && it->second.hasActiveObjects());
292 }
293 
294 void
296 {
299 
300  for (auto & it : _node_face_constraints)
301  it.second.updateActive();
302 
303  for (auto & it : _displaced_node_face_constraints)
304  it.second.updateActive();
305 
306  // FIXME: We call updateActive() on the NodeFaceConstraints again?
307  for (auto & it : _node_face_constraints)
308  it.second.updateActive();
309 
310  for (auto & it : _element_constraints)
311  it.second.updateActive();
312 
313  for (auto & it : _node_elem_constraints)
314  it.second.updateActive();
315 }
316 
317 void
318 ConstraintWarehouse::subdomainsCovered(std::set<SubdomainID> & subdomains_covered,
319  std::set<std::string> & unique_variables,
320  THREAD_ID /*tid=0*/) const
321 {
322  // Loop over undisplaced
323  for (const auto & pr : _mortar_constraints)
324  {
325  const auto & objects = pr.second.getActiveObjects();
326  for (const auto & mc : objects)
327  {
328  const MooseVariableFEBase * lm_var = mc->variablePtr();
329  if (lm_var)
330  unique_variables.insert(lm_var->name());
331 
332  // Mortar constraints will cover primary and secondary subdomains regardless of whether we
333  // have a Lagrange multiplier associated.
334  subdomains_covered.insert(mc->primarySubdomain());
335  subdomains_covered.insert(mc->secondarySubdomain());
336  }
337  }
338 
339  // Loop over displaced
340  for (const auto & pr : _displaced_mortar_constraints)
341  {
342  const auto & objects = pr.second.getActiveObjects();
343  for (const auto & mc : objects)
344  {
345  const MooseVariableFEBase * lm_var = mc->variablePtr();
346  if (lm_var)
347  unique_variables.insert(lm_var->name());
348 
349  // Mortar constraints will cover primary and secondary subdomains regardless of whether we
350  // have a Lagrange multiplier associated.
351  subdomains_covered.insert(mc->primarySubdomain());
352  subdomains_covered.insert(mc->secondarySubdomain());
353  }
354  }
355 }
356 
357 void
359 {
360  checkThreadID(tid);
361  for (const auto & object : _active_objects[tid])
362  object->residualEnd();
363 }
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:302
const std::vector< std::shared_ptr< NodalConstraint > > & getActiveNodalConstraints() const
Access methods for active objects.
std::map< std::pair< SubdomainID, SubdomainID >, MooseObjectWarehouse< NodeElemConstraintBase > > _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::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
const std::vector< std::shared_ptr< NodeElemConstraintBase > > & getActiveNodeElemConstraints(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:206
virtual void insert(libMesh::NumericVector< libMesh::Number > &vector)=0
Insert the currently cached degree of freedom values into the provided vector.
std::map< unsigned int, MooseObjectWarehouse< ElemElemConstraint > > _element_constraints
ElemElemConstraints (non-displaced)
std::map< std::pair< SubdomainID, SubdomainID >, MooseObjectWarehouse< NodeElemConstraintBase > > _node_elem_constraints
NodeElemConstraint objects.
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
std::vector< std::vector< std::shared_ptr< Constraint > > > _active_objects
All active objects (THREAD_ID on outer vector)
A NodeElemConstraintBase is used when you need to create constraints between a secondary node and a p...
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
unsigned int THREAD_ID
Definition: MooseTypes.h:209