www.mooseframework.org
EFAElement.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 EFAElement::EFAElement(unsigned int eid, unsigned int n_nodes)
17  : _id(eid),
18  _num_nodes(n_nodes),
19  _nodes(_num_nodes, NULL),
20  _parent(NULL),
21  _crack_tip_split_element(false)
22 {
23 }
24 
26 
27 unsigned int
29 {
30  return _id;
31 }
32 
33 unsigned int
35 {
36  return _num_nodes;
37 }
38 
39 void
40 EFAElement::setNode(unsigned int node_id, EFANode * node)
41 {
42  _nodes[node_id] = node;
43 }
44 
45 EFANode *
46 EFAElement::getNode(unsigned int node_id) const
47 {
48  return _nodes[node_id];
49 }
50 
51 bool
53 {
54  for (unsigned int i = 0; i < _nodes.size(); ++i)
55  if (_nodes[i] == node)
56  return true;
57  return false;
58 }
59 
60 void
61 EFAElement::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 
69 EFANode *
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 = NULL;
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 
94 EFANode *
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 
110 unsigned int
112 {
113  unsigned int local_node_id = 99999;
114  bool found_local_node = false;
115  for (unsigned int i = 0; i < _num_nodes; ++i)
116  {
117  if (_nodes[i] == node)
118  {
119  found_local_node = true;
120  local_node_id = i;
121  break;
122  }
123  }
124  if (!found_local_node)
125  EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
126  return local_node_id;
127 }
128 
129 void
131 {
133 }
134 
135 bool
137 {
139 }
140 
141 unsigned int
143 {
144  return _crack_tip_neighbors.size();
145 }
146 
147 unsigned int
148 EFAElement::getCrackTipNeighbor(unsigned int index) const
149 {
150  if (index < _crack_tip_neighbors.size())
151  return _crack_tip_neighbors[index];
152  else
153  EFAError("in getCrackTipNeighbor index out of bounds");
154 }
155 
156 void
158 {
159  // Find out what side the specified element is on, and add it as a crack tip neighbor
160  // element for that side.
161  unsigned int neighbor_index = getNeighborIndex(neighbor_elem);
162  bool crack_tip_neighbor_exist = false;
163  for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
164  {
165  if (_crack_tip_neighbors[i] == neighbor_index)
166  {
167  crack_tip_neighbor_exist = true;
168  break;
169  }
170  }
171  if (!crack_tip_neighbor_exist)
172  _crack_tip_neighbors.push_back(neighbor_index);
173 }
174 
175 EFAElement *
177 {
178  return _parent;
179 }
180 
181 EFAElement *
182 EFAElement::getChild(unsigned int child_id) const
183 {
184  if (child_id < _children.size())
185  return _children[child_id];
186  else
187  EFAError("child_id out of bounds");
188 }
189 
190 void
192 {
193  _parent = parent;
194 }
195 
196 unsigned int
198 {
199  return _children.size();
200 }
201 
202 void
204 {
205  _children.push_back(child);
206 }
207 
208 void
210 {
211  _parent = NULL;
212  _children.clear();
213 }
214 
215 void
216 EFAElement::findGeneralNeighbors(std::map<EFANode *, std::set<EFAElement *>> & InverseConnectivity)
217 {
218  _general_neighbors.clear();
219  std::set<EFAElement *> patch_elements;
220  for (unsigned int inode = 0; inode < _num_nodes; ++inode)
221  {
222  std::set<EFAElement *> this_node_connected_elems = InverseConnectivity[_nodes[inode]];
223  patch_elements.insert(this_node_connected_elems.begin(), this_node_connected_elems.end());
224  }
225 
226  std::set<EFAElement *>::iterator eit2;
227  for (eit2 = patch_elements.begin(); eit2 != patch_elements.end(); ++eit2)
228  {
229  EFAElement * neigh_elem = *eit2;
230  if (neigh_elem != this)
231  _general_neighbors.push_back(neigh_elem);
232  }
233 }
234 
235 EFAElement *
236 EFAElement::getGeneralNeighbor(unsigned int index) const
237 {
238  return _general_neighbors[index];
239 }
240 
241 unsigned int
243 {
244  return _general_neighbors.size();
245 }
246 
247 void
249  EFANode *& childOfNeighborNode,
250  EFAElement * childOfNeighborElem,
251  std::map<unsigned int, EFANode *> & PermanentNodes,
252  std::map<unsigned int, EFANode *> & TempNodes)
253 {
254  // Important: this must be run only on child elements that were just created
255  if (!_parent)
256  EFAError("no getParent element for child element ", _id, " in mergeNodes");
257 
258  EFAElement * childElem = this;
259  if (childNode != childOfNeighborNode)
260  {
261  if (childNode->category() == EFANode::N_CATEGORY_PERMANENT)
262  {
263  if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
264  {
265  if (childOfNeighborNode->parent() == childNode) // merge into childNode
266  {
267  childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
268  if (!Efa::deleteFromMap(PermanentNodes, childOfNeighborNode))
269  {
270  EFAError("Attempted to delete node: ",
271  childOfNeighborNode->id(),
272  " from PermanentNodes, but couldn't find it");
273  }
274  childOfNeighborNode = childNode;
275  }
276  else if (childNode->parent() == childOfNeighborNode) // merge into childOfNeighborNode
277  {
278  childElem->switchNode(childOfNeighborNode, childNode, true);
279  if (!Efa::deleteFromMap(PermanentNodes, childNode))
280  {
281  EFAError("Attempted to delete node: ",
282  childNode->id(),
283  " from PermanentNodes, but couldn't find it");
284  }
285  childNode = childOfNeighborNode;
286  }
287  else if (childNode->parent() != NULL &&
288  childNode->parent() == childOfNeighborNode->parent())
289  {
290  // merge into childNode if both nodes are child permanent
291  childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
292  if (!Efa::deleteFromMap(PermanentNodes,
293  childOfNeighborNode)) // delete childOfNeighborNode
294  {
295  EFAError("Attempted to delete node: ",
296  childOfNeighborNode->id(),
297  " from PermanentNodes, but couldn't find it");
298  }
299  childOfNeighborNode = childNode;
300  }
301  else
302  {
303  EFAError("Attempting to merge nodes: ",
304  childNode->id(),
305  " and ",
306  childOfNeighborNode->id(),
307  " but both are permanent themselves");
308  }
309  }
310  else
311  {
312  if (childOfNeighborNode->parent() != childNode &&
313  childOfNeighborNode->parent() != childNode->parent())
314  {
315  EFAError("Attempting to merge nodes ",
316  childOfNeighborNode->idCatString(),
317  " and ",
318  childNode->idCatString(),
319  " but neither the 2nd node nor its parent is parent of the 1st");
320  }
321  childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
322  if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
323  EFAError("Attempted to delete node: ",
324  childOfNeighborNode->id(),
325  " from TempNodes, but couldn't find it");
326  childOfNeighborNode = childNode;
327  }
328  }
329  else if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
330  {
331  if (childNode->parent() != childOfNeighborNode &&
332  childNode->parent() != childOfNeighborNode->parent())
333  {
334  EFAError("Attempting to merge nodes ",
335  childNode->id(),
336  " and ",
337  childOfNeighborNode->id(),
338  " but neither the 2nd node nor its parent is parent of the 1st");
339  }
340  childElem->switchNode(childOfNeighborNode, childNode, true);
341  if (!Efa::deleteFromMap(TempNodes, childNode))
342  EFAError(
343  "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
344  childNode = childOfNeighborNode;
345  }
346  else // both nodes are temporary -- create new permanent node and delete temporary nodes
347  {
348  unsigned int new_node_id = Efa::getNewID(PermanentNodes);
349  EFANode * newNode =
350  new EFANode(new_node_id, EFANode::N_CATEGORY_PERMANENT, childNode->parent());
351  PermanentNodes.insert(std::make_pair(new_node_id, newNode));
352 
353  childOfNeighborElem->switchNode(newNode, childOfNeighborNode, true);
354  childElem->switchNode(newNode, childNode, true);
355 
356  if (childNode->parent() != childOfNeighborNode->parent())
357  {
358  EFAError("Attempting to merge nodes ",
359  childNode->id(),
360  " and ",
361  childOfNeighborNode->id(),
362  " but they don't share a common parent");
363  }
364 
365  if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
366  EFAError("Attempted to delete node: ",
367  childOfNeighborNode->id(),
368  " from TempNodes, but couldn't find it");
369  if (!Efa::deleteFromMap(TempNodes, childNode))
370  EFAError(
371  "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
372  childOfNeighborNode = newNode;
373  childNode = newNode;
374  }
375  }
376 }
EFAElement::switchNode
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
EFAElement::getCrackTipNeighbor
unsigned int getCrackTipNeighbor(unsigned int index) const
Definition: EFAElement.C:148
EFAElement::_parent
EFAElement * _parent
Definition: EFAElement.h:31
EFAElement::getNode
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
EFANode::category
N_CATEGORY category() const
Definition: EFANode.C:42
EFANode::id
unsigned int id() const
Definition: EFANode.C:36
EFAElement
Definition: EFAElement.h:19
EFAElement::getGeneralNeighbor
EFAElement * getGeneralNeighbor(unsigned int index) const
Definition: EFAElement.C:236
EFAElement::~EFAElement
virtual ~EFAElement()
Definition: EFAElement.C:25
EFANode.h
EFAElement.h
EFAFuncs.h
EFANode::N_CATEGORY_LOCAL_INDEX
Definition: EFANode.h:23
EFANode::N_CATEGORY_TEMP
Definition: EFANode.h:20
EFAElement::setCrackTipSplit
void setCrackTipSplit()
Definition: EFAElement.C:130
EFAElement::mergeNodes
void mergeNodes(EFANode *&childNode, EFANode *&childOfNeighborNode, EFAElement *childOfNeighborElem, std::map< unsigned int, EFANode * > &PermanentNodes, std::map< unsigned int, EFANode * > &TempNodes)
Definition: EFAElement.C:248
EFAElement::numNodes
unsigned int numNodes() const
Definition: EFAElement.C:34
EFAElement::findGeneralNeighbors
void findGeneralNeighbors(std::map< EFANode *, std::set< EFAElement * >> &InverseConnectivity)
Definition: EFAElement.C:216
EFAElement::getLocalNodeIndex
unsigned int getLocalNodeIndex(EFANode *node) const
Definition: EFAElement.C:111
EFAElement::getParent
EFAElement * getParent() const
Definition: EFAElement.C:176
EFAElement::createLocalNodeFromGlobalNode
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
Definition: EFAElement.C:70
EFAElement::_crack_tip_neighbors
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:34
EFAElement::setNode
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:40
EFAElement::addCrackTipNeighbor
void addCrackTipNeighbor(EFAElement *neighbor_elem)
Definition: EFAElement.C:157
EFAElement::_general_neighbors
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36
EFAElement::_children
std::vector< EFAElement * > _children
Definition: EFAElement.h:32
EFAElement::clearParentAndChildren
void clearParentAndChildren()
Definition: EFAElement.C:209
EFAElement::_crack_tip_split_element
bool _crack_tip_split_element
Definition: EFAElement.h:33
EFANode::idCatString
std::string idCatString()
Definition: EFANode.C:20
EFAElement::numCrackTipNeighbors
unsigned int numCrackTipNeighbors() const
Definition: EFAElement.C:142
EFAElement::id
unsigned int id() const
Definition: EFAElement.C:28
EFAElement::isCrackTipSplit
bool isCrackTipSplit() const
Definition: EFAElement.C:136
EFAError.h
EFAElement::numChildren
unsigned int numChildren() const
Definition: EFAElement.C:197
EFAElement::_id
unsigned int _id
Definition: EFAElement.h:27
EFANode::N_CATEGORY_PERMANENT
Definition: EFANode.h:19
EFAElement::EFAElement
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:16
EFANode::N_CATEGORY_EMBEDDED_PERMANENT
Definition: EFANode.h:22
EFANode
Definition: EFANode.h:14
EFAElement::getNeighborIndex
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const =0
EFANode::parent
EFANode * parent() const
Definition: EFANode.C:48
EFAElement::addChild
void addChild(EFAElement *child)
Definition: EFAElement.C:203
EFAElement::getGlobalNodeFromLocalNode
EFANode * getGlobalNodeFromLocalNode(const EFANode *local_node) const
Definition: EFAElement.C:95
EFAElement::getChild
EFAElement * getChild(unsigned int child_id) const
Definition: EFAElement.C:182
Efa::deleteFromMap
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:22
EFAElement::_nodes
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
EFAElement::numGeneralNeighbors
unsigned int numGeneralNeighbors() const
Definition: EFAElement.C:242
EFAElement::containsNode
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
Efa::getNewID
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:38
EFAElement::printNodes
void printNodes(std::ostream &ostream) const
Definition: EFAElement.C:61
EFAElement::setParent
void setParent(EFAElement *parent)
Definition: EFAElement.C:191
EFAElement::_num_nodes
unsigned int _num_nodes
Definition: EFAElement.h:28