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 57095 : ConstraintWarehouse::ConstraintWarehouse() : MooseObjectWarehouse<Constraint>(/*threaded=*/false) {}
22 :
23 : void
24 1579 : 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 1579 : MooseObjectWarehouse<Constraint>::addObject(object);
30 :
31 : // Cast the the possible Contraint types
32 1579 : std::shared_ptr<NodeFaceConstraint> nfc = std::dynamic_pointer_cast<NodeFaceConstraint>(object);
33 : std::shared_ptr<MortarConstraintBase> mc =
34 1579 : std::dynamic_pointer_cast<MortarConstraintBase>(object);
35 1579 : std::shared_ptr<NodalConstraint> nc = std::dynamic_pointer_cast<NodalConstraint>(object);
36 1579 : std::shared_ptr<ElemElemConstraint> ec = std::dynamic_pointer_cast<ElemElemConstraint>(object);
37 : std::shared_ptr<NodeElemConstraintBase> nec =
38 1579 : std::dynamic_pointer_cast<NodeElemConstraintBase>(object);
39 :
40 : // NodeFaceConstraint
41 1579 : if (nfc)
42 : {
43 93 : MooseMesh & mesh = nfc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
44 93 : unsigned int secondary = mesh.getBoundaryID(nfc->getParam<BoundaryName>("secondary"));
45 186 : bool displaced = nfc->parameters().have_parameter<bool>("use_displaced_mesh") &&
46 186 : nfc->getParam<bool>("use_displaced_mesh");
47 :
48 93 : if (displaced)
49 24 : _displaced_node_face_constraints[secondary].addObject(nfc);
50 : else
51 69 : _node_face_constraints[secondary].addObject(nfc);
52 : }
53 :
54 : // MortarConstraint
55 1486 : else if (mc)
56 : {
57 1228 : MooseMesh & mesh = mc->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
58 1228 : bool displaced = mc->getParam<bool>("use_displaced_mesh");
59 :
60 : auto secondary_boundary_id =
61 1228 : mesh.getBoundaryID(mc->getParam<BoundaryName>("secondary_boundary"));
62 1228 : auto primary_boundary_id = mesh.getBoundaryID(mc->getParam<BoundaryName>("primary_boundary"));
63 1228 : auto key = std::make_pair(primary_boundary_id, secondary_boundary_id);
64 :
65 1228 : if (displaced)
66 92 : _displaced_mortar_constraints[key].addObject(mc);
67 : else
68 1136 : _mortar_constraints[key].addObject(mc);
69 : }
70 :
71 : // ElemElemConstraint
72 258 : 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 258 : else if (nec)
86 : {
87 200 : MooseMesh & mesh = nec->getParam<FEProblemBase *>("_fe_problem_base")->mesh();
88 200 : SubdomainID secondary = mesh.getSubdomainID(nec->getParam<SubdomainName>("secondary"));
89 200 : SubdomainID primary = mesh.getSubdomainID(nec->getParam<SubdomainName>("primary"));
90 400 : bool displaced = nec->parameters().have_parameter<bool>("use_displaced_mesh") &&
91 400 : nec->getParam<bool>("use_displaced_mesh");
92 :
93 200 : if (displaced)
94 0 : _displaced_node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
95 : else
96 200 : _node_elem_constraints[std::make_pair(secondary, primary)].addObject(nec);
97 : }
98 :
99 : // NodalConstraint
100 58 : else if (nc)
101 58 : _nodal_constraints.addObject(nc);
102 :
103 : else
104 0 : mooseError("Unknown type of Constraint object");
105 1579 : }
106 :
107 : const std::vector<std::shared_ptr<NodalConstraint>> &
108 5264 : ConstraintWarehouse::getActiveNodalConstraints() const
109 : {
110 5264 : return _nodal_constraints.getActiveObjects();
111 : }
112 :
113 : const std::vector<std::shared_ptr<NodeFaceConstraint>> &
114 18775 : ConstraintWarehouse::getActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
115 : {
116 18775 : std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
117 :
118 18775 : if (displaced)
119 : {
120 6622 : it = _displaced_node_face_constraints.find(boundary_id);
121 6622 : end_it = _displaced_node_face_constraints.end();
122 : }
123 :
124 : else
125 : {
126 12153 : it = _node_face_constraints.find(boundary_id);
127 12153 : 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 37550 : return it->second.getActiveObjects();
134 : }
135 :
136 : bool
137 933 : ConstraintWarehouse::hasActiveMortarConstraints(
138 : const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
139 : {
140 933 : const auto & constraints = displaced ? _displaced_mortar_constraints : _mortar_constraints;
141 933 : return constraints.find(mortar_interface_key) != constraints.end();
142 : }
143 :
144 : const std::vector<std::shared_ptr<MortarConstraintBase>> &
145 897 : ConstraintWarehouse::getActiveMortarConstraints(
146 : const std::pair<BoundaryID, BoundaryID> & mortar_interface_key, const bool displaced) const
147 : {
148 : std::map<std::pair<BoundaryID, BoundaryID>,
149 897 : MooseObjectWarehouse<MortarConstraintBase>>::const_iterator it,
150 897 : end_it;
151 :
152 897 : if (displaced)
153 : {
154 92 : it = _displaced_mortar_constraints.find(mortar_interface_key);
155 92 : end_it = _displaced_mortar_constraints.end();
156 : }
157 : else
158 : {
159 805 : it = _mortar_constraints.find(mortar_interface_key);
160 805 : 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 1794 : 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 648 : ConstraintWarehouse::getActiveNodeElemConstraints(SubdomainID secondary_id,
197 : SubdomainID primary_id,
198 : bool displaced) const
199 : {
200 : std::map<std::pair<SubdomainID, SubdomainID>,
201 648 : MooseObjectWarehouse<NodeElemConstraintBase>>::const_iterator it,
202 648 : end_it;
203 :
204 648 : 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 648 : it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
212 648 : 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 1296 : return it->second.getActiveObjects();
221 : }
222 :
223 : bool
224 25099 : ConstraintWarehouse::hasActiveNodalConstraints() const
225 : {
226 25099 : 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 81216 : ConstraintWarehouse::hasActiveNodeFaceConstraints(BoundaryID boundary_id, bool displaced) const
252 : {
253 81216 : std::map<BoundaryID, MooseObjectWarehouse<NodeFaceConstraint>>::const_iterator it, end_it;
254 :
255 81216 : if (displaced)
256 : {
257 58376 : it = _displaced_node_face_constraints.find(boundary_id);
258 58376 : end_it = _displaced_node_face_constraints.end();
259 : }
260 :
261 : else
262 : {
263 22840 : it = _node_face_constraints.find(boundary_id);
264 22840 : end_it = _node_face_constraints.end();
265 : }
266 :
267 81216 : return (it != end_it && it->second.hasActiveObjects());
268 : }
269 :
270 : bool
271 932202 : ConstraintWarehouse::hasActiveNodeElemConstraints(SubdomainID secondary_id,
272 : SubdomainID primary_id,
273 : bool displaced) const
274 : {
275 : std::map<std::pair<SubdomainID, SubdomainID>,
276 932202 : MooseObjectWarehouse<NodeElemConstraintBase>>::const_iterator it,
277 932202 : end_it;
278 :
279 932202 : if (displaced)
280 : {
281 184009 : it = _displaced_node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
282 184009 : end_it = _displaced_node_elem_constraints.end();
283 : }
284 :
285 : else
286 : {
287 748193 : it = _node_elem_constraints.find(std::make_pair(secondary_id, primary_id));
288 748193 : end_it = _node_elem_constraints.end();
289 : }
290 :
291 932202 : return (it != end_it && it->second.hasActiveObjects());
292 : }
293 :
294 : void
295 306062 : ConstraintWarehouse::updateActive(THREAD_ID /*tid*/)
296 : {
297 306062 : MooseObjectWarehouse<Constraint>::updateActive();
298 306062 : _nodal_constraints.updateActive();
299 :
300 307005 : for (auto & it : _node_face_constraints)
301 943 : it.second.updateActive();
302 :
303 308273 : for (auto & it : _displaced_node_face_constraints)
304 2211 : it.second.updateActive();
305 :
306 : // FIXME: We call updateActive() on the NodeFaceConstraints again?
307 307005 : for (auto & it : _node_face_constraints)
308 943 : it.second.updateActive();
309 :
310 306062 : for (auto & it : _element_constraints)
311 0 : it.second.updateActive();
312 :
313 306224 : for (auto & it : _node_elem_constraints)
314 162 : it.second.updateActive();
315 306062 : }
316 :
317 : void
318 39593 : 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 40055 : for (const auto & pr : _mortar_constraints)
324 : {
325 462 : const auto & objects = pr.second.getActiveObjects();
326 948 : for (const auto & mc : objects)
327 : {
328 486 : const MooseVariableFEBase * lm_var = mc->variablePtr();
329 486 : if (lm_var)
330 402 : 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 486 : subdomains_covered.insert(mc->primarySubdomain());
335 486 : subdomains_covered.insert(mc->secondarySubdomain());
336 : }
337 : }
338 :
339 : // Loop over displaced
340 39593 : 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 39593 : }
356 :
357 : void
358 10129 : ConstraintWarehouse::residualEnd(THREAD_ID tid /* = 0*/) const
359 : {
360 10129 : checkThreadID(tid);
361 21619 : for (const auto & object : _active_objects[tid])
362 11490 : object->residualEnd();
363 10129 : }
|