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 "EFAElement.h"
11 :
12 : #include "EFANode.h"
13 : #include "EFAError.h"
14 : #include "EFAFuncs.h"
15 :
16 450039 : EFAElement::EFAElement(unsigned int eid, unsigned int n_nodes)
17 450039 : : _id(eid),
18 450039 : _num_nodes(n_nodes),
19 900078 : _nodes(_num_nodes, nullptr),
20 450039 : _parent(nullptr),
21 450039 : _crack_tip_split_element(false)
22 : {
23 450039 : }
24 :
25 449839 : EFAElement::~EFAElement() {}
26 :
27 : unsigned int
28 44236 : EFAElement::id() const
29 : {
30 44236 : return _id;
31 : }
32 :
33 : unsigned int
34 3126058 : EFAElement::numNodes() const
35 : {
36 3126058 : return _num_nodes;
37 : }
38 :
39 : void
40 2096564 : EFAElement::setNode(unsigned int node_id, EFANode * node)
41 : {
42 2096564 : _nodes[node_id] = node;
43 2096564 : }
44 :
45 : EFANode *
46 9707632 : EFAElement::getNode(unsigned int node_id) const
47 : {
48 9707632 : return _nodes[node_id];
49 : }
50 :
51 : bool
52 2352 : EFAElement::containsNode(EFANode * node) const
53 : {
54 14884 : for (const auto element_node : _nodes)
55 12648 : if (element_node == node)
56 : return true;
57 : return false;
58 : }
59 :
60 : void
61 0 : EFAElement::printNodes(std::ostream & ostream) const
62 : {
63 0 : ostream << "***** nodes for element " << _id << " *****" << std::endl;
64 0 : for (unsigned int i = 0; i < _num_nodes; ++i)
65 0 : ostream << "addr " << _nodes[i] << ", ID " << _nodes[i]->idCatString() << ", category "
66 0 : << _nodes[i]->category() << std::endl;
67 0 : }
68 :
69 : EFANode *
70 120616 : EFAElement::createLocalNodeFromGlobalNode(const EFANode * global_node) const
71 : {
72 : // Given a global node, create a new local node
73 120828 : if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
74 120828 : global_node->category() != EFANode::N_CATEGORY_TEMP &&
75 212 : global_node->category() != EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
76 0 : EFAError("In createLocalNodeFromGlobalNode node is not global");
77 :
78 : EFANode * new_local_node = nullptr;
79 : unsigned int inode = 0;
80 435764 : for (; inode < _nodes.size(); ++inode)
81 : {
82 435764 : if (_nodes[inode] == global_node)
83 : {
84 120616 : new_local_node = new EFANode(inode, EFANode::N_CATEGORY_LOCAL_INDEX);
85 : break;
86 : }
87 : }
88 : if (!new_local_node)
89 0 : EFAError("In createLocalNodeFromGlobalNode could not find global node");
90 :
91 120616 : return new_local_node;
92 : }
93 :
94 : EFANode *
95 0 : EFAElement::getGlobalNodeFromLocalNode(const EFANode * local_node) const
96 : {
97 : // Given a local node, find the global node corresponding to that node
98 0 : if (local_node->category() != EFANode::N_CATEGORY_LOCAL_INDEX)
99 0 : EFAError("In getGlobalNodeFromLocalNode node passed in is not local");
100 :
101 0 : EFANode * global_node = _nodes[local_node->id()];
102 :
103 0 : if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
104 0 : global_node->category() != EFANode::N_CATEGORY_TEMP)
105 0 : EFAError("In getGlobalNodeFromLocalNode, the node stored by the element is not global");
106 :
107 0 : return global_node;
108 : }
109 :
110 : unsigned int
111 275744 : EFAElement::getLocalNodeIndex(EFANode * node) const
112 : {
113 768426 : for (unsigned int i = 0; i < _num_nodes; ++i)
114 : {
115 768426 : if (_nodes[i] == node)
116 275744 : return i;
117 : }
118 0 : EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
119 : }
120 :
121 : void
122 5072 : EFAElement::setCrackTipSplit()
123 : {
124 5072 : _crack_tip_split_element = true;
125 5072 : }
126 :
127 : bool
128 2011 : EFAElement::isCrackTipSplit() const
129 : {
130 2011 : return _crack_tip_split_element;
131 : }
132 :
133 : unsigned int
134 0 : EFAElement::numCrackTipNeighbors() const
135 : {
136 0 : return _crack_tip_neighbors.size();
137 : }
138 :
139 : unsigned int
140 0 : EFAElement::getCrackTipNeighbor(unsigned int index) const
141 : {
142 0 : if (index < _crack_tip_neighbors.size())
143 0 : return _crack_tip_neighbors[index];
144 : else
145 0 : EFAError("in getCrackTipNeighbor index out of bounds");
146 : }
147 :
148 : void
149 5072 : EFAElement::addCrackTipNeighbor(EFAElement * neighbor_elem)
150 : {
151 : // Find out what side the specified element is on, and add it as a crack tip neighbor
152 : // element for that side.
153 5072 : unsigned int neighbor_index = getNeighborIndex(neighbor_elem);
154 : bool crack_tip_neighbor_exist = false;
155 5488 : for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
156 : {
157 420 : if (_crack_tip_neighbors[i] == neighbor_index)
158 : {
159 : crack_tip_neighbor_exist = true;
160 : break;
161 : }
162 : }
163 5072 : if (!crack_tip_neighbor_exist)
164 5068 : _crack_tip_neighbors.push_back(neighbor_index);
165 5072 : }
166 :
167 : EFAElement *
168 24900 : EFAElement::getParent() const
169 : {
170 24900 : return _parent;
171 : }
172 :
173 : EFAElement *
174 980624 : EFAElement::getChild(unsigned int child_id) const
175 : {
176 980624 : if (child_id < _children.size())
177 980624 : return _children[child_id];
178 : else
179 0 : EFAError("child_id out of bounds");
180 : }
181 :
182 : void
183 12084 : EFAElement::setParent(EFAElement * parent)
184 : {
185 12084 : _parent = parent;
186 12084 : }
187 :
188 : unsigned int
189 1722082 : EFAElement::numChildren() const
190 : {
191 1722082 : return _children.size();
192 : }
193 :
194 : void
195 0 : EFAElement::addChild(EFAElement * child)
196 : {
197 0 : _children.push_back(child);
198 0 : }
199 :
200 : void
201 347 : EFAElement::clearParentAndChildren()
202 : {
203 347 : _parent = nullptr;
204 347 : _children.clear();
205 347 : }
206 :
207 : void
208 426444 : EFAElement::findGeneralNeighbors(
209 : const std::map<EFANode *, std::set<EFAElement *>> & inverse_connectivity)
210 : {
211 426444 : _general_neighbors.clear();
212 : std::set<EFAElement *> patch_elements;
213 2456244 : for (unsigned int inode = 0; inode < _num_nodes; ++inode)
214 : {
215 2029800 : auto it = inverse_connectivity.find(_nodes[inode]);
216 2029800 : if (it != inverse_connectivity.end())
217 2029800 : patch_elements.insert(it->second.begin(), it->second.end());
218 : }
219 :
220 : std::set<EFAElement *>::iterator eit2;
221 5107908 : for (eit2 = patch_elements.begin(); eit2 != patch_elements.end(); ++eit2)
222 : {
223 4681464 : EFAElement * neigh_elem = *eit2;
224 4681464 : if (neigh_elem != this)
225 4255020 : _general_neighbors.push_back(neigh_elem);
226 : }
227 426444 : }
228 :
229 : EFAElement *
230 685416 : EFAElement::getGeneralNeighbor(unsigned int index) const
231 : {
232 685416 : return _general_neighbors[index];
233 : }
234 :
235 : unsigned int
236 712325 : EFAElement::numGeneralNeighbors() const
237 : {
238 712325 : return _general_neighbors.size();
239 : }
240 :
241 : void
242 42851 : EFAElement::mergeNodes(EFANode *& childNode,
243 : EFANode *& childOfNeighborNode,
244 : EFAElement * childOfNeighborElem,
245 : std::map<unsigned int, EFANode *> & PermanentNodes,
246 : std::map<unsigned int, EFANode *> & TempNodes)
247 : {
248 : // Important: this must be run only on child elements that were just created
249 42851 : if (!_parent)
250 0 : EFAError("no getParent element for child element ", _id, " in mergeNodes");
251 :
252 : EFAElement * childElem = this;
253 42851 : if (childNode != childOfNeighborNode)
254 : {
255 17255 : if (childNode->category() == EFANode::N_CATEGORY_PERMANENT)
256 : {
257 5764 : if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
258 : {
259 258 : if (childOfNeighborNode->parent() == childNode) // merge into childNode
260 : {
261 17 : childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
262 17 : if (!Efa::deleteFromMap(PermanentNodes, childOfNeighborNode))
263 : {
264 0 : EFAError("Attempted to delete node: ",
265 : childOfNeighborNode->id(),
266 : " from PermanentNodes, but couldn't find it");
267 : }
268 17 : childOfNeighborNode = childNode;
269 : }
270 241 : else if (childNode->parent() == childOfNeighborNode) // merge into childOfNeighborNode
271 : {
272 125 : childElem->switchNode(childOfNeighborNode, childNode, true);
273 125 : if (!Efa::deleteFromMap(PermanentNodes, childNode))
274 : {
275 0 : EFAError("Attempted to delete node: ",
276 : childNode->id(),
277 : " from PermanentNodes, but couldn't find it");
278 : }
279 125 : childNode = childOfNeighborNode;
280 : }
281 232 : else if (childNode->parent() != nullptr &&
282 116 : childNode->parent() == childOfNeighborNode->parent())
283 : {
284 : // merge into childNode if both nodes are child permanent
285 116 : childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
286 116 : if (!Efa::deleteFromMap(PermanentNodes,
287 : childOfNeighborNode)) // delete childOfNeighborNode
288 : {
289 0 : EFAError("Attempted to delete node: ",
290 : childOfNeighborNode->id(),
291 : " from PermanentNodes, but couldn't find it");
292 : }
293 116 : childOfNeighborNode = childNode;
294 : }
295 : else
296 : {
297 0 : EFAError("Attempting to merge nodes: ",
298 : childNode->id(),
299 : " and ",
300 : childOfNeighborNode->id(),
301 : " but both are permanent themselves");
302 : }
303 : }
304 : else
305 : {
306 9203 : if (childOfNeighborNode->parent() != childNode &&
307 3697 : childOfNeighborNode->parent() != childNode->parent())
308 : {
309 0 : EFAError("Attempting to merge nodes ",
310 : childOfNeighborNode->idCatString(),
311 : " and ",
312 : childNode->idCatString(),
313 : " but neither the 2nd node nor its parent is parent of the 1st");
314 : }
315 5506 : childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
316 5506 : if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
317 0 : EFAError("Attempted to delete node: ",
318 : childOfNeighborNode->id(),
319 : " from TempNodes, but couldn't find it");
320 5506 : childOfNeighborNode = childNode;
321 : }
322 : }
323 11491 : else if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
324 : {
325 2451 : if (childNode->parent() != childOfNeighborNode &&
326 498 : childNode->parent() != childOfNeighborNode->parent())
327 : {
328 0 : EFAError("Attempting to merge nodes ",
329 : childNode->id(),
330 : " and ",
331 : childOfNeighborNode->id(),
332 : " but neither the 2nd node nor its parent is parent of the 1st");
333 : }
334 1953 : childElem->switchNode(childOfNeighborNode, childNode, true);
335 1953 : if (!Efa::deleteFromMap(TempNodes, childNode))
336 0 : EFAError(
337 : "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
338 1953 : childNode = childOfNeighborNode;
339 : }
340 : else // both nodes are temporary -- create new permanent node and delete temporary nodes
341 : {
342 9538 : unsigned int new_node_id = Efa::getNewID(PermanentNodes);
343 : EFANode * newNode =
344 9538 : new EFANode(new_node_id, EFANode::N_CATEGORY_PERMANENT, childNode->parent());
345 9538 : PermanentNodes.insert(std::make_pair(new_node_id, newNode));
346 :
347 9538 : childOfNeighborElem->switchNode(newNode, childOfNeighborNode, true);
348 9538 : childElem->switchNode(newNode, childNode, true);
349 :
350 9538 : if (childNode->parent() != childOfNeighborNode->parent())
351 : {
352 0 : EFAError("Attempting to merge nodes ",
353 : childNode->id(),
354 : " and ",
355 : childOfNeighborNode->id(),
356 : " but they don't share a common parent");
357 : }
358 :
359 9538 : if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
360 0 : EFAError("Attempted to delete node: ",
361 : childOfNeighborNode->id(),
362 : " from TempNodes, but couldn't find it");
363 9538 : if (!Efa::deleteFromMap(TempNodes, childNode))
364 0 : EFAError(
365 : "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
366 9538 : childOfNeighborNode = newNode;
367 9538 : childNode = newNode;
368 : }
369 : }
370 42851 : }
|