https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
EFAFragment2D Class Reference

#include <EFAFragment2D.h>

Inheritance diagram for EFAFragment2D:
[legend]

Public Member Functions

 EFAFragment2D (EFAElement2D *host, bool create_boundary_edges, const EFAElement2D *from_host, unsigned int frag_id=std::numeric_limits< unsigned int >::max())
 
 EFAFragment2D (EFAElement2D *host, const EFAFace *from_face)
 
 ~EFAFragment2D ()
 
virtual void switchNode (EFANode *new_node, EFANode *old_node)
 
virtual bool containsNode (EFANode *node) const
 
virtual unsigned int getNumCuts () const
 
virtual unsigned int getNumCutNodes () const
 
virtual std::set< EFANode * > getAllNodes () const
 
virtual bool isConnected (EFAFragment *other_fragment) const
 
virtual void removeInvalidEmbeddedNodes (std::map< unsigned int, EFANode * > &EmbeddedNodes)
 
void combineTipEdges ()
 
bool isEdgeInterior (unsigned int edge_id) const
 
std::vector< unsigned intgetInteriorEdgeID () const
 
bool isSecondaryInteriorEdge (unsigned int edge_id) const
 
unsigned int numEdges () const
 
EFAEdgegetEdge (unsigned int edge_id) const
 
void addEdge (EFAEdge *new_edge)
 
std::set< EFANode * > getEdgeNodes (unsigned int edge_id) const
 
EFAElement2DgetHostElement () const
 
std::vector< EFAFragment2D * > split ()
 
std::vector< EFANode * > getCommonNodes (EFAFragment *other) const
 

Private Attributes

EFAElement2D_host_elem
 
std::vector< EFAEdge * > _boundary_edges
 

Detailed Description

Definition at line 20 of file EFAFragment2D.h.

Constructor & Destructor Documentation

◆ EFAFragment2D() [1/2]

EFAFragment2D::EFAFragment2D ( EFAElement2D host,
bool  create_boundary_edges,
const EFAElement2D from_host,
unsigned int  frag_id = std::numeric_limits<unsigned int>::max() 
)

Definition at line 21 of file EFAFragment2D.C.

25 : EFAFragment(), _host_elem(host)
26{
27 if (create_boundary_edges)
28 {
29 if (!from_host)
30 EFAError("EFAfragment2D constructor must have a from_host to copy from");
31 if (frag_id == std::numeric_limits<unsigned int>::max()) // copy the from_host itself
32 {
33 for (unsigned int i = 0; i < from_host->numEdges(); ++i)
34 _boundary_edges.push_back(new EFAEdge(*from_host->getEdge(i)));
35 }
36 else
37 {
38 if (frag_id > from_host->numFragments() - 1)
39 EFAError("In EFAfragment2D constructor fragment_copy_index out of bounds");
40 for (unsigned int i = 0; i < from_host->getFragment(frag_id)->numEdges(); ++i)
41 _boundary_edges.push_back(new EFAEdge(*from_host->getFragmentEdge(frag_id, i)));
42 }
43 }
44}
virtual unsigned int numFragments() const
EFAFragment2D * getFragment(unsigned int frag_id) const
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int numEdges() const
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
EFAElement2D * _host_elem
unsigned int numEdges() const
std::vector< EFAEdge * > _boundary_edges

◆ EFAFragment2D() [2/2]

EFAFragment2D::EFAFragment2D ( EFAElement2D host,
const EFAFace from_face 
)

Definition at line 46 of file EFAFragment2D.C.

47 : EFAFragment(), _host_elem(host)
48{
49 for (unsigned int i = 0; i < from_face->numEdges(); ++i)
50 _boundary_edges.push_back(new EFAEdge(*from_face->getEdge(i)));
51}
unsigned int numEdges() const
Definition EFAFace.h:49
EFAEdge * getEdge(unsigned int edge_id) const
Definition EFAFace.h:50

◆ ~EFAFragment2D()

EFAFragment2D::~EFAFragment2D ( )

Definition at line 53 of file EFAFragment2D.C.

54{
55 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
56 {
57 if (_boundary_edges[i])
58 {
59 delete _boundary_edges[i];
60 _boundary_edges[i] = nullptr;
61 }
62 }
63}

Member Function Documentation

◆ addEdge()

void EFAFragment2D::addEdge ( EFAEdge new_edge)

Definition at line 310 of file EFAFragment2D.C.

311{
312 _boundary_edges.push_back(new_edge);
313}

Referenced by EFAElement2D::branchingSplit(), EFAFace::combineWithFace(), and split().

◆ combineTipEdges()

void EFAFragment2D::combineTipEdges ( )

Definition at line 168 of file EFAFragment2D.C.

169{
170 // combine the tip edges in a crack tip fragment
171 // N.B. the host elem can only have one elem_tip_edge, otherwise it should have already been
172 // completely split
173 if (!_host_elem)
174 EFAError("In combine_tip_edges() the frag must have host_elem");
175
176 bool has_tip_edges = false;
177 unsigned int elem_tip_edge_id = std::numeric_limits<unsigned int>::max();
178 std::vector<unsigned int> frag_tip_edge_id;
179 for (unsigned int i = 0; i < _host_elem->numEdges(); ++i)
180 {
181 frag_tip_edge_id.clear();
183 {
184 for (unsigned int j = 0; j < _boundary_edges.size(); ++j)
185 {
187 frag_tip_edge_id.push_back(j);
188 } // j
189 if (frag_tip_edge_id.size() == 2) // combine the two frag edges on this elem edge
190 {
191 has_tip_edges = true;
192 elem_tip_edge_id = i;
193 break;
194 }
195 }
196 } // i
197 if (has_tip_edges)
198 {
199 // frag_tip_edge_id[0] must precede frag_tip_edge_id[1]
200 unsigned int edge0_next(frag_tip_edge_id[0] < (numEdges() - 1) ? frag_tip_edge_id[0] + 1 : 0);
201 if (edge0_next != frag_tip_edge_id[1])
202 EFAError("frag_tip_edge_id[1] must be the next edge of frag_tip_edge_id[0]");
203
204 // get the two end nodes of the new edge
205 EFANode * node1 = _boundary_edges[frag_tip_edge_id[0]]->getNode(0);
206 EFANode * emb_node = _boundary_edges[frag_tip_edge_id[0]]->getNode(1);
207 EFANode * node2 = _boundary_edges[frag_tip_edge_id[1]]->getNode(1);
208 if (emb_node != _boundary_edges[frag_tip_edge_id[1]]->getNode(0))
209 EFAError("fragment edges are not correctly set up");
210
211 // get the new edge with one intersection
212 EFAEdge * elem_edge = _host_elem->getEdge(elem_tip_edge_id);
213 double xi_node1 = elem_edge->distanceFromNode1(node1);
214 double xi_node2 = elem_edge->distanceFromNode1(node2);
215 double xi_emb = elem_edge->distanceFromNode1(emb_node);
216 double position = (xi_emb - xi_node1) / (xi_node2 - xi_node1);
217 EFAEdge * full_edge = new EFAEdge(node1, node2);
218 full_edge->addIntersection(position, emb_node, node1);
219
220 // combine the two original fragment edges
221 delete _boundary_edges[frag_tip_edge_id[0]];
222 delete _boundary_edges[frag_tip_edge_id[1]];
223 _boundary_edges[frag_tip_edge_id[0]] = full_edge;
224 _boundary_edges.erase(_boundary_edges.begin() + frag_tip_edge_id[1]);
225 }
226}
double distanceFromNode1(EFANode *node) const
Definition EFAEdge.C:250
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition EFAEdge.C:132
bool containsEdge(const EFAEdge &other) const
Definition EFAEdge.C:65
bool hasIntersection() const
Definition EFAEdge.C:200

◆ containsNode()

bool EFAFragment2D::containsNode ( EFANode node) const
virtual

Implements EFAFragment.

Definition at line 73 of file EFAFragment2D.C.

74{
75 bool contains = false;
76 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
77 {
78 if (_boundary_edges[i]->containsNode(node))
79 {
80 contains = true;
81 break;
82 }
83 }
84 return contains;
85}
virtual bool containsNode(EFANode *node) const
bool contains(std::string_view superstring, std::string_view substring)

Referenced by containsNode(), and isSecondaryInteriorEdge().

◆ getAllNodes()

std::set< EFANode * > EFAFragment2D::getAllNodes ( ) const
virtual

Implements EFAFragment.

Definition at line 110 of file EFAFragment2D.C.

111{
112 std::set<EFANode *> nodes;
113 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
114 {
115 nodes.insert(_boundary_edges[i]->getNode(0));
116 nodes.insert(_boundary_edges[i]->getNode(1));
117 }
118 return nodes;
119}

◆ getCommonNodes()

std::vector< EFANode * > EFAFragment::getCommonNodes ( EFAFragment other) const
inherited

Definition at line 20 of file EFAFragment.C.

21{
22 std::set<EFANode *> frag1_nodes = getAllNodes();
23 std::set<EFANode *> frag2_nodes = other->getAllNodes();
24 std::vector<EFANode *> common_nodes = Efa::getCommonElems(frag1_nodes, frag2_nodes);
25 return common_nodes;
26}
virtual std::set< EFANode * > getAllNodes() const =0
std::vector< T > getCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition EFAFuncs.h:69

Referenced by EFAElement2D::willCrackTipExtend(), and EFAElement3D::willCrackTipExtend().

◆ getEdge()

EFAEdge * EFAFragment2D::getEdge ( unsigned int  edge_id) const

Definition at line 302 of file EFAFragment2D.C.

303{
304 if (edge_id > _boundary_edges.size() - 1)
305 EFAError("in EFAfragment2D::get_edge, index out of bounds");
306 return _boundary_edges[edge_id];
307}

Referenced by EFAFace::EFAFace(), XFEMCutElem2D::getPhysicalQuadraturePoints(), and isConnected().

◆ getEdgeNodes()

std::set< EFANode * > EFAFragment2D::getEdgeNodes ( unsigned int  edge_id) const

Definition at line 316 of file EFAFragment2D.C.

317{
318 std::set<EFANode *> edge_nodes;
319 edge_nodes.insert(_boundary_edges[edge_id]->getNode(0));
320 edge_nodes.insert(_boundary_edges[edge_id]->getNode(1));
321 return edge_nodes;
322}

◆ getHostElement()

EFAElement2D * EFAFragment2D::getHostElement ( ) const

Definition at line 325 of file EFAFragment2D.C.

326{
327 return _host_elem;
328}

◆ getInteriorEdgeID()

std::vector< unsigned int > EFAFragment2D::getInteriorEdgeID ( ) const

Definition at line 266 of file EFAFragment2D.C.

267{
268 std::vector<unsigned int> interior_edge_id;
269 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
270 {
271 if (isEdgeInterior(i))
272 interior_edge_id.push_back(i);
273 }
274 return interior_edge_id;
275}
bool isEdgeInterior(unsigned int edge_id) const

Referenced by XFEM::markCutEdgesByState().

◆ getNumCutNodes()

unsigned int EFAFragment2D::getNumCutNodes ( ) const
virtual

Implements EFAFragment.

Definition at line 100 of file EFAFragment2D.C.

101{
102 unsigned int num_cut_nodes = 0;
103 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
104 if (_boundary_edges[i]->getNode(0)->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
105 num_cut_nodes++;
106 return num_cut_nodes;
107}
@ N_CATEGORY_EMBEDDED_PERMANENT
Definition EFANode.h:22

◆ getNumCuts()

unsigned int EFAFragment2D::getNumCuts ( ) const
virtual

Implements EFAFragment.

Definition at line 88 of file EFAFragment2D.C.

89{
90 unsigned int num_cut_edges = 0;
91 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
92 {
93 if (_boundary_edges[i]->hasIntersection())
94 num_cut_edges += _boundary_edges[i]->numEmbeddedNodes();
95 }
96 return num_cut_edges;
97}

Referenced by removeInvalidEmbeddedNodes().

◆ isConnected()

bool EFAFragment2D::isConnected ( EFAFragment other_fragment) const
virtual

Implements EFAFragment.

Definition at line 122 of file EFAFragment2D.C.

123{
124 bool is_connected = false;
125 EFAFragment2D * other_frag2d = dynamic_cast<EFAFragment2D *>(other_fragment);
126 if (!other_frag2d)
127 EFAError("in isConnected other_fragment is not of type EFAfragement2D");
128
129 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
130 {
131 for (unsigned int j = 0; j < other_frag2d->numEdges(); ++j)
132 {
133 if (_boundary_edges[i]->equivalent(*other_frag2d->getEdge(j)))
134 {
135 is_connected = true;
136 break;
137 }
138 }
139 if (is_connected)
140 break;
141 } // i
142 return is_connected;
143}
EFAEdge * getEdge(unsigned int edge_id) const

◆ isEdgeInterior()

bool EFAFragment2D::isEdgeInterior ( unsigned int  edge_id) const

Definition at line 244 of file EFAFragment2D.C.

245{
246 if (!_host_elem)
247 EFAError("in isEdgeInterior fragment must have host elem");
248
249 bool edge_in_elem_edge = false;
250
251 for (unsigned int i = 0; i < _host_elem->numEdges(); ++i)
252 {
254 {
255 edge_in_elem_edge = true;
256 break;
257 }
258 }
259 if (!edge_in_elem_edge)
260 return true; // yes, is interior
261 else
262 return false;
263}

Referenced by EFAElement2D::createChild(), XFEMCutElem2D::getCrackTipOriginAndDirection(), XFEMCutElem2D::getCutPlaneNormal(), XFEMCutElem2D::getCutPlaneOrigin(), getInteriorEdgeID(), XFEMCutElem2D::getIntersectionInfo(), XFEMCutElem2D::numCutPlanes(), and removeInvalidEmbeddedNodes().

◆ isSecondaryInteriorEdge()

bool EFAFragment2D::isSecondaryInteriorEdge ( unsigned int  edge_id) const

Definition at line 278 of file EFAFragment2D.C.

279{
280 bool is_second_cut = false;
281 if (!_host_elem)
282 EFAError("in isSecondaryInteriorEdge fragment must have host elem");
283
284 for (unsigned int i = 0; i < _host_elem->numInteriorNodes(); ++i)
285 {
287 {
288 is_second_cut = true;
289 break;
290 }
291 }
292 return is_second_cut;
293}
virtual unsigned int numInteriorNodes() const
EFAFaceNode * getInteriorNode(unsigned int interior_node_id) const
EFANode * getNode()
Definition EFAFaceNode.C:25

Referenced by XFEM::markCutEdgesByGeometry(), and XFEM::markCutEdgesByState().

◆ numEdges()

unsigned int EFAFragment2D::numEdges ( ) const

◆ removeInvalidEmbeddedNodes()

void EFAFragment2D::removeInvalidEmbeddedNodes ( std::map< unsigned int, EFANode * > &  EmbeddedNodes)
virtual

Implements EFAFragment.

Definition at line 146 of file EFAFragment2D.C.

147{
148 // if a fragment only has 1 intersection which is in an interior edge
149 // remove this embedded node (MUST DO THIS AFTER combine_tip_edges())
150 if (getNumCuts() == 1)
151 {
152 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
153 {
154 if (isEdgeInterior(i) && _boundary_edges[i]->hasIntersection())
155 {
156 if (_host_elem->numInteriorNodes() != 1)
157 EFAError("host element must have 1 interior node at this point");
158 Efa::deleteFromMap(EmbeddedNodes, _boundary_edges[i]->getEmbeddedNode(0));
159 _boundary_edges[i]->removeEmbeddedNodes();
161 break;
162 }
163 } // i
164 }
165}
void deleteInteriorNodes()
virtual unsigned int getNumCuts() const
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition EFAFuncs.h:22

◆ split()

std::vector< EFAFragment2D * > EFAFragment2D::split ( )

Definition at line 331 of file EFAFragment2D.C.

332{
333 // This method will split one existing fragment into one or two
334 // new fragments and return them.
335 // N.B. each boundary each can only have 1 cut at most
336 std::vector<EFAFragment2D *> new_fragments;
337 std::vector<std::vector<EFANode *>> fragment_nodes(
338 2); // vectors of EFA nodes in the two fragments
339 unsigned int frag_number = 0; // Index of the current fragment that we are assmbling nodes into
340 unsigned int edge_cut_count = 0;
341 unsigned int node_cut_count = 0;
342 for (unsigned int iedge = 0; iedge < _boundary_edges.size(); ++iedge)
343 {
344 fragment_nodes[frag_number].push_back(_boundary_edges[iedge]->getNode(0));
345
346 if (_boundary_edges[iedge]->getNode(0)->category() ==
347 EFANode::N_CATEGORY_EMBEDDED_PERMANENT) // if current node has been cut change fragment
348 {
349 ++node_cut_count;
350 frag_number = 1 - frag_number; // Toggle between 0 and 1
351 fragment_nodes[frag_number].push_back(_boundary_edges[iedge]->getNode(0));
352 }
353
354 if (_boundary_edges[iedge]->numEmbeddedNodes() > 1)
355 EFAError("A fragment boundary edge can't have more than 1 cuts");
356 if (_boundary_edges[iedge]->hasIntersection()) // if current edge is cut add cut intersection //
357 // node to both fragments and and change fragment
358 {
359 fragment_nodes[frag_number].push_back(_boundary_edges[iedge]->getEmbeddedNode(0));
360 ++edge_cut_count;
361 frag_number = 1 - frag_number; // Toggle between 0 and 1
362 fragment_nodes[frag_number].push_back(_boundary_edges[iedge]->getEmbeddedNode(0));
363 }
364 }
365
366 if ((edge_cut_count + node_cut_count) > 1) // any two cuts case
367 {
368 for (unsigned int frag_idx = 0; frag_idx < 2; ++frag_idx) // Create 2 fragments
369 {
370 auto & this_frag_nodes = fragment_nodes[frag_idx];
371 // check to make sure an edge wasn't cut
372 if (this_frag_nodes.size() >= 3)
373 {
374 EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, nullptr);
375 for (unsigned int inode = 0; inode < this_frag_nodes.size() - 1; inode++)
376 new_frag->addEdge(new EFAEdge(this_frag_nodes[inode], this_frag_nodes[inode + 1]));
377
378 new_frag->addEdge(
379 new EFAEdge(this_frag_nodes[this_frag_nodes.size() - 1], this_frag_nodes[0]));
380
381 new_fragments.push_back(new_frag);
382 }
383 }
384 }
385 else if (edge_cut_count == 1) // single edge cut case
386 {
387 EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, nullptr);
388 for (unsigned int inode = 0; inode < fragment_nodes[0].size() - 1;
389 inode++) // assemble fragment part 1
390 new_frag->addEdge(new EFAEdge(fragment_nodes[0][inode], fragment_nodes[0][inode + 1]));
391
392 for (unsigned int inode = 0; inode < fragment_nodes[1].size() - 1;
393 inode++) // assemble fragment part 2
394 new_frag->addEdge(new EFAEdge(fragment_nodes[1][inode], fragment_nodes[1][inode + 1]));
395
396 new_frag->addEdge(
397 new EFAEdge(fragment_nodes[1][fragment_nodes[1].size() - 1], fragment_nodes[0][0]));
398
399 new_fragments.push_back(new_frag);
400 }
401 else if (node_cut_count == 1) // single node cut case
402 {
403 EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, nullptr);
404 for (unsigned int iedge = 0; iedge < _boundary_edges.size(); ++iedge)
405 {
406 EFANode * first_node_on_edge = _boundary_edges[iedge]->getNode(0);
407 EFANode * second_node_on_edge = _boundary_edges[iedge]->getNode(1);
408 new_frag->addEdge(new EFAEdge(first_node_on_edge, second_node_on_edge));
409 }
410
411 new_fragments.push_back(new_frag);
412 }
413
414 return new_fragments;
415}
void addEdge(EFAEdge *new_edge)

Referenced by EFAFace::split().

◆ switchNode()

void EFAFragment2D::switchNode ( EFANode new_node,
EFANode old_node 
)
virtual

Implements EFAFragment.

Definition at line 66 of file EFAFragment2D.C.

67{
68 for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
69 _boundary_edges[i]->switchNode(new_node, old_node);
70}
virtual void switchNode(EFANode *new_node, EFANode *old_node)

Referenced by switchNode().

Member Data Documentation

◆ _boundary_edges

std::vector<EFAEdge *> EFAFragment2D::_boundary_edges
private

◆ _host_elem

EFAElement2D* EFAFragment2D::_host_elem
private

The documentation for this class was generated from the following files: