Line data Source code
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 :
21 61453 : ConstraintWarehouse::ConstraintWarehouse() : MooseObjectWarehouse<Constraint>(/*threaded=*/false) {}
22 :
23 : void
24 1693 : 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
29 1693 : MooseObjectWarehouse<Constraint>::addObject(object);
30 :
31 : // Cast the the possible Contraint types
32 1693 : std::shared_ptr<NodeFaceConstraint> nfc = std::dynamic_pointer_cast<NodeFaceConstraint>(object);
33 : std::shared_ptr<MortarConstraintBase> mc =
34 1693 : std::dynamic_pointer_cast<MortarConstraintBase>(object);
35 1693 : std::shared_ptr<NodalConstraint> nc = std::dynamic_pointer_cast<NodalConstraint>(object);
36 1693 : std::shared_ptr<ElemElemConstraint> ec = std::dynamic_pointer_cast<ElemElemConstraint>(object);
37 : std::shared_ptr<NodeElemConstraintBase> nec =
38 1693 : std::dynamic_pointer_cast<NodeElemConstraintBase>(object);
39 :
40 : // NodeFaceConstraint
41 1693 : if (nfc)
42 : {
43 101 : MooseMesh & mesh = nfc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
44 101 : unsigned int secondary = mesh.getBoundaryID(nfc->getParam<BoundaryName>("secondary"));
45 202 : bool displaced = nfc->parameters().have_parameter<bool>("use_displaced_mesh") &&
46 202 : nfc->getParam<bool>("use_displaced_mesh");
47 :
48 101 : if (displaced)
49 26 : _displaced_node_face_constraints[secondary].addObject(nfc);
50 : else
51 75 : _node_face_constraints[secondary].addObject(nfc);
52 : }
53 :
54 : // MortarConstraint
55 1592 : else if (mc)
56 : {
57 1308 : MooseMesh & mesh = mc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
58 1308 : bool displaced = mc->getParam<bool>("use_displaced_mesh");
59 :
60 : auto secondary_boundary_id =
61 1308 : mesh.getBoundaryID(mc->getParam<BoundaryName>("secondary_boundary"));
62 1308 : auto primary_boundary_id = mesh.getBoundaryID(mc->getParam<BoundaryName>("primary_boundary"));
63 1308 : auto key = std::make_pair(primary_boundary_id, secondary_boundary_id);
64 :
65 1308 : if (displaced)
66 98 : _displaced_mortar_constraints[key].addObject(mc);
67 : else
68 1210 : _mortar_constraints[key].addObject(mc);
69 : }
70 :
71 : // ElemElemConstraint
72 284 : else if (ec)
73 : {
74 0 : bool displaced = ec->parameters().have_parameter<bool>("use_displaced_mesh") &&
75 0 : ec->getParam<bool>("use_displaced_mesh");
76 0 : const InterfaceID interface_id = ec->getInterfaceID();
77 :
78 0 : if (displaced)
79 0 : _displaced_element_constraints[interface_id].addObject(ec);
80 : else
81 0 : _element_constraints[interface_id].addObject(ec);
82 : }
83 :
84 : // NodeElemConstraintBase
85 284 : else if (nec)
86 : {
87 220 : MooseMesh & mesh = nec->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
88 220 : SubdomainID secondary = mesh.getSubdomainID(nec->getParam<SubdomainName>("secondary"));
89 220 : SubdomainID primary = mesh.getSubdomainID(nec->getParam<SubdomainName>("primary"));
90 440 : bool displaced = nec->parameters().have_parameter<bool>("use_displaced_mesh") &&
91 440 : nec->getParam<bool>("use_displaced_mesh");
92 :
93 220 : if (displaced)
94 0 : _displaced_node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
95 : else
96 220 : _node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
97 : }
98 :
99 : // NodalConstraint
100 64 : else if (nc)
101 64 : _nodal_constraints.addObject(nc);
102 :
103 : else
104 0 : mooseError("Unknown type of Constraint object");
105 1693 : }
106 :
107 : const std::vector<std::shared_ptr<NodalConstraint>> &
108 5756 : ConstraintWarehouse::getActiveNodalConstraints() const
109 : {
110 5756 : return _nodal_constraints.getActiveObjects();
111 : }
112 :
113 : const std::vector<std::shared_ptr<NodeFaceConstraint>> &
114 20510 : ConstraintWarehouse::getActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
115 : {
116 20510 : std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
117 :
118 20510 : if (displaced)
119 : {
120 7227 : it = _displaced_node_face_constraints.find(boundary_id);
121 7227 : end_it = _displaced_node_face_constraints.end();
122 : }
123 :
124 : else
125 : {
126 13283 : it = _node_face_constraints.find(boundary_id);
127 13283 : 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 41020 : return it->second.getActiveObjects();
134 : }
135 :
136 : bool
137 994 : ConstraintWarehouse::hasActiveMortarConstraints(
138 : const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
139 : {
140 994 : const auto & constraints = displaced ? _displaced_mortar_constraints : _mortar_constraints;
141 994 : return constraints.find(mortar_interface_key) != constraints.end();
142 : }
143 :
144 : const std::vector<std::shared_ptr<MortarConstraintBase>> &
145 955 : ConstraintWarehouse::getActiveMortarConstraints(
146 : const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
147 : {
148 : std::map<std::pair<BoundaryID, BoundaryID>,
149 955 : MooseObjectWarehouse<MortarConstraintBase>>::const_iterator it,
150 955 : end_it;
151 :
152 955 : if (displaced)
153 : {
154 98 : it = _displaced_mortar_constraints.find(mortar_interface_key);
155 98 : end_it = _displaced_mortar_constraints.end();
156 : }
157 : else
158 : {
159 857 : it = _mortar_constraints.find(mortar_interface_key);
160 857 : 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 1910 : return it->second.getActiveObjects();
169 : }
170 :
171 : const std::vector<std::shared_ptr<ElemElemConstraint>> &
172 0 : ConstraintWarehouse::getActiveElemElemConstraints(const InterfaceID interface_id,
173 : bool displaced) const
174 : {
175 0 : std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
176 :
177 0 : if (displaced)
178 : {
179 0 : it = _displaced_element_constraints.find(interface_id);
180 0 : end_it = _displaced_element_constraints.end();
181 : }
182 :
183 : else
184 : {
185 0 : it = _element_constraints.find(interface_id);
186 0 : 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 0 : return it->second.getActiveObjects();
193 : }
194 :
195 : const std::vector<std::shared_ptr<NodeElemConstraintBase>> &
196 720 : ConstraintWarehouse::getActiveNodeElemConstraints(SubdomainID secondary_id,
197 : SubdomainID primary_id,
198 : bool displaced) const
199 : {
200 : std::map<std::pair<SubdomainID, SubdomainID>,
201 720 : MooseObjectWarehouse<NodeElemConstraintBase>>::const_iterator it,
202 720 : end_it;
203 :
204 720 : if (displaced)
205 : {
206 0 : it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
207 0 : end_it = _displaced_node_elem_constraints.end();
208 : }
209 : else
210 : {
211 720 : it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
212 720 : 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 1440 : return it->second.getActiveObjects();
221 : }
222 :
223 : bool
224 26902 : ConstraintWarehouse::hasActiveNodalConstraints() const
225 : {
226 26902 : return _nodal_constraints.hasActiveObjects();
227 : }
228 :
229 : bool
230 0 : ConstraintWarehouse::hasActiveElemElemConstraints(const InterfaceID interface_id,
231 : bool displaced) const
232 : {
233 0 : std::map<unsigned int, MooseObjectWarehouse<ElemElemConstraint>>::const_iterator it, end_it;
234 :
235 0 : if (displaced)
236 : {
237 0 : it = _displaced_element_constraints.find(interface_id);
238 0 : end_it = _displaced_element_constraints.end();
239 : }
240 :
241 : else
242 : {
243 0 : it = _element_constraints.find(interface_id);
244 0 : end_it = _element_constraints.end();
245 : }
246 :
247 0 : return (it != end_it && it->second.hasActiveObjects());
248 : }
249 :
250 : bool
251 88754 : ConstraintWarehouse::hasActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
252 : {
253 88754 : std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
254 :
255 88754 : if (displaced)
256 : {
257 63819 : it = _displaced_node_face_constraints.find(boundary_id);
258 63819 : end_it = _displaced_node_face_constraints.end();
259 : }
260 :
261 : else
262 : {
263 24935 : it = _node_face_constraints.find(boundary_id);
264 24935 : end_it = _node_face_constraints.end();
265 : }
266 :
267 88754 : return (it != end_it && it->second.hasActiveObjects());
268 : }
269 :
270 : bool
271 1001699 : ConstraintWarehouse::hasActiveNodeElemConstraints(SubdomainID secondary_id,
272 : SubdomainID primary_id,
273 : bool displaced) const
274 : {
275 : std::map<std::pair<SubdomainID, SubdomainID>,
276 1001699 : MooseObjectWarehouse<NodeElemConstraintBase>>::const_iterator it,
277 1001699 : end_it;
278 :
279 1001699 : if (displaced)
280 : {
281 200035 : it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
282 200035 : end_it = _displaced_node_elem_constraints.end();
283 : }
284 :
285 : else
286 : {
287 801664 : it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
288 801664 : end_it = _node_elem_constraints.end();
289 : }
290 :
291 1001699 : return (it != end_it && it->second.hasActiveObjects());
292 : }
293 :
294 : void
295 333846 : ConstraintWarehouse::updateActive(THREAD_ID /*tid*/)
296 : {
297 333846 : MooseObjectWarehouse<Constraint>::updateActive();
298 333846 : _nodal_constraints.updateActive();
299 :
300 334879 : for (auto & it : _node_face_constraints)
301 1033 : it.second.updateActive();
302 :
303 336259 : for (auto & it : _displaced_node_face_constraints)
304 2413 : it.second.updateActive();
305 :
306 : // FIXME: We call updateActive() on the NodeFaceConstraints again?
307 334879 : for (auto & it : _node_face_constraints)
308 1033 : it.second.updateActive();
309 :
310 333846 : for (auto & it : _element_constraints)
311 0 : it.second.updateActive();
312 :
313 334026 : for (auto & it : _node_elem_constraints)
314 180 : it.second.updateActive();
315 333846 : }
316 :
317 : void
318 42526 : 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 43018 : for (const auto & pr : _mortar_constraints)
324 : {
325 492 : const auto & objects = pr.second.getActiveObjects();
326 1010 : for (const auto & mc : objects)
327 : {
328 518 : const MooseVariableFEBase * lm_var = mc->variablePtr();
329 518 : if (lm_var)
330 426 : 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 518 : subdomains_covered.insert(mc->primarySubdomain());
335 518 : subdomains_covered.insert(mc->secondarySubdomain());
336 : }
337 : }
338 :
339 : // Loop over displaced
340 42526 : for (const auto & pr : _displaced_mortar_constraints)
341 : {
342 0 : const auto & objects = pr.second.getActiveObjects();
343 0 : for (const auto & mc : objects)
344 : {
345 0 : const MooseVariableFEBase * lm_var = mc->variablePtr();
346 0 : if (lm_var)
347 0 : 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 0 : subdomains_covered.insert(mc->primarySubdomain());
352 0 : subdomains_covered.insert(mc->secondarySubdomain());
353 : }
354 : }
355 42526 : }
356 :
357 : void
358 10581 : ConstraintWarehouse::residualEnd(THREAD_ID tid /* = 0*/) const
359 : {
360 10581 : checkThreadID(tid);
361 22622 : for (const auto & object : _active_objects[tid])
362 12041 : object->residualEnd();
363 10581 : }
|