https://mooseframework.inl.gov
Loading...
Searching...
No Matches
EFAElement.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 "EFAElement.h"
11
12#include "EFANode.h"
13#include "EFAError.h"
14#include "EFAFuncs.h"
15
16EFAElement::EFAElement(unsigned int eid, unsigned int n_nodes)
17 : _id(eid),
18 _num_nodes(n_nodes),
19 _nodes(_num_nodes, nullptr),
20 _parent(nullptr),
21 _crack_tip_split_element(false)
22{
23}
24
26
27unsigned int
29{
30 return _id;
31}
32
33unsigned int
35{
36 return _num_nodes;
37}
38
39void
40EFAElement::setNode(unsigned int node_id, EFANode * node)
41{
42 _nodes[node_id] = node;
43}
44
45EFANode *
46EFAElement::getNode(unsigned int node_id) const
47{
48 return _nodes[node_id];
49}
50
51bool
53{
54 for (const auto element_node : _nodes)
55 if (element_node == node)
56 return true;
57 return false;
58}
59
60void
61EFAElement::printNodes(std::ostream & ostream) const
62{
63 ostream << "***** nodes for element " << _id << " *****" << std::endl;
64 for (unsigned int i = 0; i < _num_nodes; ++i)
65 ostream << "addr " << _nodes[i] << ", ID " << _nodes[i]->idCatString() << ", category "
66 << _nodes[i]->category() << std::endl;
67}
68
69EFANode *
71{
72 // Given a global node, create a new local node
73 if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
74 global_node->category() != EFANode::N_CATEGORY_TEMP &&
76 EFAError("In createLocalNodeFromGlobalNode node is not global");
77
78 EFANode * new_local_node = nullptr;
79 unsigned int inode = 0;
80 for (; inode < _nodes.size(); ++inode)
81 {
82 if (_nodes[inode] == global_node)
83 {
84 new_local_node = new EFANode(inode, EFANode::N_CATEGORY_LOCAL_INDEX);
85 break;
86 }
87 }
88 if (!new_local_node)
89 EFAError("In createLocalNodeFromGlobalNode could not find global node");
90
91 return new_local_node;
92}
93
94EFANode *
96{
97 // Given a local node, find the global node corresponding to that node
98 if (local_node->category() != EFANode::N_CATEGORY_LOCAL_INDEX)
99 EFAError("In getGlobalNodeFromLocalNode node passed in is not local");
100
101 EFANode * global_node = _nodes[local_node->id()];
102
103 if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
104 global_node->category() != EFANode::N_CATEGORY_TEMP)
105 EFAError("In getGlobalNodeFromLocalNode, the node stored by the element is not global");
106
107 return global_node;
108}
109
110unsigned int
112{
113 for (unsigned int i = 0; i < _num_nodes; ++i)
114 {
115 if (_nodes[i] == node)
116 return i;
117 }
118 EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
119}
120
121void
126
127bool
132
133unsigned int
135{
136 return _crack_tip_neighbors.size();
137}
138
139unsigned int
140EFAElement::getCrackTipNeighbor(unsigned int index) const
141{
142 if (index < _crack_tip_neighbors.size())
143 return _crack_tip_neighbors[index];
144 else
145 EFAError("in getCrackTipNeighbor index out of bounds");
146}
147
148void
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 unsigned int neighbor_index = getNeighborIndex(neighbor_elem);
154 bool crack_tip_neighbor_exist = false;
155 for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
156 {
157 if (_crack_tip_neighbors[i] == neighbor_index)
158 {
159 crack_tip_neighbor_exist = true;
160 break;
161 }
162 }
163 if (!crack_tip_neighbor_exist)
164 _crack_tip_neighbors.push_back(neighbor_index);
165}
166
169{
170 return _parent;
171}
172
174EFAElement::getChild(unsigned int child_id) const
175{
176 if (child_id < _children.size())
177 return _children[child_id];
178 else
179 EFAError("child_id out of bounds");
180}
181
182void
184{
185 _parent = parent;
186}
187
188unsigned int
190{
191 return _children.size();
192}
193
194void
196{
197 _children.push_back(child);
198}
199
200void
202{
203 _parent = nullptr;
204 _children.clear();
205}
206
207void
209 const std::map<EFANode *, std::set<EFAElement *>> & inverse_connectivity)
210{
211 _general_neighbors.clear();
212 std::set<EFAElement *> patch_elements;
213 for (unsigned int inode = 0; inode < _num_nodes; ++inode)
214 {
215 auto it = inverse_connectivity.find(_nodes[inode]);
216 if (it != inverse_connectivity.end())
217 patch_elements.insert(it->second.begin(), it->second.end());
218 }
219
220 std::set<EFAElement *>::iterator eit2;
221 for (eit2 = patch_elements.begin(); eit2 != patch_elements.end(); ++eit2)
222 {
223 EFAElement * neigh_elem = *eit2;
224 if (neigh_elem != this)
225 _general_neighbors.push_back(neigh_elem);
226 }
227}
228
230EFAElement::getGeneralNeighbor(unsigned int index) const
231{
232 return _general_neighbors[index];
233}
234
235unsigned int
237{
238 return _general_neighbors.size();
239}
240
241void
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 if (!_parent)
250 EFAError("no getParent element for child element ", _id, " in mergeNodes");
251
252 EFAElement * childElem = this;
253 if (childNode != childOfNeighborNode)
254 {
255 if (childNode->category() == EFANode::N_CATEGORY_PERMANENT)
256 {
257 if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
258 {
259 if (childOfNeighborNode->parent() == childNode) // merge into childNode
260 {
261 childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
262 if (!Efa::deleteFromMap(PermanentNodes, childOfNeighborNode))
263 {
264 EFAError("Attempted to delete node: ",
265 childOfNeighborNode->id(),
266 " from PermanentNodes, but couldn't find it");
267 }
268 childOfNeighborNode = childNode;
269 }
270 else if (childNode->parent() == childOfNeighborNode) // merge into childOfNeighborNode
271 {
272 childElem->switchNode(childOfNeighborNode, childNode, true);
273 if (!Efa::deleteFromMap(PermanentNodes, childNode))
274 {
275 EFAError("Attempted to delete node: ",
276 childNode->id(),
277 " from PermanentNodes, but couldn't find it");
278 }
279 childNode = childOfNeighborNode;
280 }
281 else if (childNode->parent() != nullptr &&
282 childNode->parent() == childOfNeighborNode->parent())
283 {
284 // merge into childNode if both nodes are child permanent
285 childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
286 if (!Efa::deleteFromMap(PermanentNodes,
287 childOfNeighborNode)) // delete childOfNeighborNode
288 {
289 EFAError("Attempted to delete node: ",
290 childOfNeighborNode->id(),
291 " from PermanentNodes, but couldn't find it");
292 }
293 childOfNeighborNode = childNode;
294 }
295 else
296 {
297 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 if (childOfNeighborNode->parent() != childNode &&
307 childOfNeighborNode->parent() != childNode->parent())
308 {
309 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 childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
316 if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
317 EFAError("Attempted to delete node: ",
318 childOfNeighborNode->id(),
319 " from TempNodes, but couldn't find it");
320 childOfNeighborNode = childNode;
321 }
322 }
323 else if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
324 {
325 if (childNode->parent() != childOfNeighborNode &&
326 childNode->parent() != childOfNeighborNode->parent())
327 {
328 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 childElem->switchNode(childOfNeighborNode, childNode, true);
335 if (!Efa::deleteFromMap(TempNodes, childNode))
336 EFAError(
337 "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
338 childNode = childOfNeighborNode;
339 }
340 else // both nodes are temporary -- create new permanent node and delete temporary nodes
341 {
342 unsigned int new_node_id = Efa::getNewID(PermanentNodes);
343 EFANode * newNode =
344 new EFANode(new_node_id, EFANode::N_CATEGORY_PERMANENT, childNode->parent());
345 PermanentNodes.insert(std::make_pair(new_node_id, newNode));
346
347 childOfNeighborElem->switchNode(newNode, childOfNeighborNode, true);
348 childElem->switchNode(newNode, childNode, true);
349
350 if (childNode->parent() != childOfNeighborNode->parent())
351 {
352 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 if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
360 EFAError("Attempted to delete node: ",
361 childOfNeighborNode->id(),
362 " from TempNodes, but couldn't find it");
363 if (!Efa::deleteFromMap(TempNodes, childNode))
364 EFAError(
365 "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
366 childOfNeighborNode = newNode;
367 childNode = newNode;
368 }
369 }
370}
void addChild(EFAElement *child)
Definition EFAElement.C:195
EFAElement * getGeneralNeighbor(unsigned int index) const
Definition EFAElement.C:230
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const =0
unsigned int numGeneralNeighbors() const
Definition EFAElement.C:236
std::vector< EFANode * > _nodes
Definition EFAElement.h:29
void clearParentAndChildren()
Definition EFAElement.C:201
unsigned int _num_nodes
Definition EFAElement.h:28
unsigned int numNodes() const
Definition EFAElement.C:34
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition EFAElement.C:16
EFAElement * _parent
Definition EFAElement.h:31
void mergeNodes(EFANode *&childNode, EFANode *&childOfNeighborNode, EFAElement *childOfNeighborElem, std::map< unsigned int, EFANode * > &PermanentNodes, std::map< unsigned int, EFANode * > &TempNodes)
Definition EFAElement.C:242
void addCrackTipNeighbor(EFAElement *neighbor_elem)
Definition EFAElement.C:149
std::vector< EFAElement * > _general_neighbors
Definition EFAElement.h:36
EFANode * getNode(unsigned int node_id) const
Definition EFAElement.C:46
void setCrackTipSplit()
Definition EFAElement.C:122
virtual ~EFAElement()
Definition EFAElement.C:25
bool containsNode(EFANode *node) const
Definition EFAElement.C:52
EFAElement * getChild(unsigned int child_id) const
Definition EFAElement.C:174
bool isCrackTipSplit() const
Definition EFAElement.C:128
void setNode(unsigned int node_id, EFANode *node)
Definition EFAElement.C:40
unsigned int numCrackTipNeighbors() const
Definition EFAElement.C:134
unsigned int _id
Definition EFAElement.h:27
bool _crack_tip_split_element
Definition EFAElement.h:33
void setParent(EFAElement *parent)
Definition EFAElement.C:183
std::vector< unsigned int > _crack_tip_neighbors
Definition EFAElement.h:34
unsigned int getLocalNodeIndex(EFANode *node) const
Definition EFAElement.C:111
void findGeneralNeighbors(const std::map< EFANode *, std::set< EFAElement * > > &InverseConnectivity)
Definition EFAElement.C:208
void printNodes(std::ostream &ostream) const
Definition EFAElement.C:61
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
Definition EFAElement.C:70
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
unsigned int getCrackTipNeighbor(unsigned int index) const
Definition EFAElement.C:140
unsigned int numChildren() const
Definition EFAElement.C:189
unsigned int id() const
Definition EFAElement.C:28
std::vector< EFAElement * > _children
Definition EFAElement.h:32
EFAElement * getParent() const
Definition EFAElement.C:168
EFANode * getGlobalNodeFromLocalNode(const EFANode *local_node) const
Definition EFAElement.C:95
EFANode * parent() const
Definition EFANode.C:48
@ N_CATEGORY_EMBEDDED_PERMANENT
Definition EFANode.h:22
@ N_CATEGORY_TEMP
Definition EFANode.h:20
@ N_CATEGORY_PERMANENT
Definition EFANode.h:19
@ N_CATEGORY_LOCAL_INDEX
Definition EFANode.h:23
unsigned int id() const
Definition EFANode.C:36
N_CATEGORY category() const
Definition EFANode.C:42
std::string idCatString()
Definition EFANode.C:20
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition EFAFuncs.h:22
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition EFAFuncs.h:38
const dof_id_type n_nodes