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 "EFAFace.h"
11 :
12 : #include "EFAFaceNode.h"
13 : #include "EFANode.h"
14 : #include "EFAEdge.h"
15 : #include "EFAFragment2D.h"
16 : #include "EFAFuncs.h"
17 : #include "EFAError.h"
18 :
19 220532 : EFAFace::EFAFace(unsigned int n_nodes, unsigned int num_interior_face_nodes)
20 220532 : : _num_nodes(n_nodes),
21 220532 : _nodes(_num_nodes, nullptr),
22 220532 : _num_edges(_num_nodes),
23 220532 : _edges(_num_edges, nullptr),
24 220532 : _face_interior_nodes(num_interior_face_nodes, nullptr)
25 : {
26 220532 : }
27 :
28 191894 : EFAFace::EFAFace(const EFAFace & other_face)
29 191894 : : _num_nodes(other_face._num_nodes),
30 191894 : _nodes(_num_nodes, nullptr),
31 191894 : _num_edges(_num_nodes),
32 191894 : _edges(_num_edges, nullptr)
33 : {
34 891580 : for (unsigned int k = 0; k < other_face._num_nodes; ++k)
35 : {
36 699686 : _nodes[k] = other_face._nodes[k];
37 699686 : _edges[k] = new EFAEdge(*other_face._edges[k]);
38 : }
39 191894 : for (unsigned int k = 0; k < other_face._interior_nodes.size(); ++k)
40 0 : _interior_nodes.push_back(new EFAFaceNode(*other_face._interior_nodes[k]));
41 191894 : }
42 :
43 10840 : EFAFace::EFAFace(const EFAFragment2D * frag)
44 10840 : : _num_nodes(frag->numEdges()),
45 10840 : _nodes(_num_nodes, nullptr),
46 10840 : _num_edges(_num_nodes),
47 10840 : _edges(_num_edges, nullptr)
48 : {
49 52610 : for (unsigned int k = 0; k < frag->numEdges(); ++k)
50 : {
51 41770 : EFANode * node = frag->getEdge(k)->getNode(0);
52 41770 : unsigned int kprev(k > 0 ? (k - 1) : (frag->numEdges() - 1));
53 41770 : if (!frag->getEdge(kprev)->containsNode(node))
54 0 : node = getEdge(k)->getNode(1);
55 41770 : _nodes[k] = node;
56 41770 : _edges[k] = new EFAEdge(*frag->getEdge(k));
57 : }
58 10840 : }
59 :
60 423266 : EFAFace::~EFAFace()
61 : {
62 1959926 : for (unsigned int i = 0; i < _edges.size(); ++i)
63 : {
64 1536660 : if (_edges[i])
65 : {
66 1536660 : delete _edges[i];
67 1536660 : _edges[i] = nullptr;
68 : }
69 : }
70 423266 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
71 : {
72 0 : if (_interior_nodes[i])
73 : {
74 0 : delete _interior_nodes[i];
75 0 : _interior_nodes[i] = nullptr;
76 : }
77 : }
78 423266 : }
79 :
80 : void
81 320104 : EFAFace::setInteriorFaceNode(unsigned int i, EFANode * node)
82 : {
83 320104 : _face_interior_nodes[i] = node;
84 320104 : }
85 :
86 : unsigned int
87 7568787 : EFAFace::numNodes() const
88 : {
89 7568787 : return _nodes.size();
90 : }
91 :
92 : void
93 786960 : EFAFace::setNode(unsigned int node_id, EFANode * node)
94 : {
95 786960 : _nodes[node_id] = node;
96 786960 : }
97 :
98 : EFANode *
99 5501172 : EFAFace::getNode(unsigned int node_id) const
100 : {
101 5501172 : return _nodes[node_id];
102 : }
103 :
104 : void
105 6412455 : EFAFace::switchNode(EFANode * new_node, EFANode * old_node)
106 : {
107 : bool is_face_node = true;
108 27881741 : for (unsigned int i = 0; i < _num_nodes; ++i)
109 : {
110 21469286 : if (_nodes[i] == old_node)
111 : {
112 153543 : _nodes[i] = new_node;
113 : is_face_node = false;
114 : }
115 : }
116 6412455 : if (is_face_node)
117 : {
118 16994216 : for (unsigned int i = 0; i < _face_interior_nodes.size(); ++i)
119 10735304 : if (_face_interior_nodes[i] == old_node)
120 9664 : _face_interior_nodes[i] = new_node;
121 : }
122 : else
123 : {
124 737171 : for (unsigned int i = 0; i < _edges.size(); ++i)
125 583628 : _edges[i]->switchNode(new_node, old_node);
126 153543 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
127 0 : _interior_nodes[i]->switchNode(new_node, old_node);
128 : }
129 6412455 : }
130 :
131 : bool
132 2611614 : EFAFace::getMasterInfo(EFANode * node,
133 : std::vector<EFANode *> & master_nodes,
134 : std::vector<double> & master_weights) const
135 : {
136 : // Given a EFAnode, find the element edge or fragment edge that contains it
137 : // Return its master nodes and weights
138 2611614 : master_nodes.clear();
139 2611614 : master_weights.clear();
140 : bool masters_found = false;
141 6329864 : for (unsigned int i = 0; i < _num_edges; ++i) // check element exterior edges
142 : {
143 6329864 : if (_edges[i]->containsNode(node))
144 : {
145 2611614 : masters_found = _edges[i]->getNodeMasters(node, master_nodes, master_weights);
146 2611614 : if (masters_found)
147 : break;
148 : else
149 0 : EFAError("In getMasterInfo: cannot find master nodes in element edges");
150 : }
151 : }
152 :
153 : if (!masters_found) // check element interior embedded nodes
154 : {
155 0 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
156 : {
157 0 : if (_interior_nodes[i]->getNode() == node)
158 : {
159 0 : std::vector<double> emb_xi(2, 0.0);
160 0 : emb_xi[0] = _interior_nodes[i]->getParametricCoordinates(0);
161 0 : emb_xi[1] = _interior_nodes[i]->getParametricCoordinates(1);
162 0 : for (unsigned int j = 0; j < _num_nodes; ++j)
163 : {
164 0 : master_nodes.push_back(_nodes[j]);
165 0 : double weight = 0.0;
166 0 : if (_num_nodes == 4)
167 0 : weight = Efa::linearQuadShape2D(j, emb_xi);
168 0 : else if (_num_nodes == 3)
169 0 : weight = Efa::linearTriShape2D(j, emb_xi);
170 : else
171 0 : EFAError("EFAface::getMasterInfo() only works for quad and tri EFAface");
172 0 : master_weights.push_back(weight);
173 : }
174 : masters_found = true;
175 : break;
176 0 : }
177 : }
178 : }
179 2611614 : return masters_found;
180 : }
181 :
182 : bool
183 3108 : EFAFace::getEdgeNodeParametricCoords(EFANode * node, std::vector<double> & xi_2d) const
184 : {
185 : // get the parametric coords of a node in an edge
186 : bool edge_found = false;
187 : unsigned int edge_id;
188 3108 : if (!isTriOrQuad())
189 0 : EFAError("EFAface::getEdgeNodeParaCoor can only work for quad or tri faces");
190 :
191 5586 : for (unsigned int i = 0; i < _num_edges; ++i)
192 : {
193 5586 : if (_edges[i]->containsNode(node))
194 : {
195 : edge_id = i;
196 : edge_found = true;
197 : break;
198 : }
199 : }
200 3108 : if (edge_found)
201 : {
202 3108 : double rel_dist = _edges[edge_id]->distanceFromNode1(node);
203 3108 : double xi_1d = 2.0 * rel_dist - 1.0; // translate to [-1,1] parent coord syst
204 3108 : mapParametricCoordsFrom1DTo2D(edge_id, xi_1d, xi_2d);
205 : }
206 3108 : return edge_found;
207 : }
208 :
209 : bool
210 3108 : EFAFace::getFaceNodeParametricCoords(EFANode * node, std::vector<double> & xi_2d) const
211 : {
212 : bool node_in_face = false;
213 3108 : if (!isTriOrQuad())
214 0 : EFAError("EFAface::getFaceNodeParaCoor can only work for quad or tri faces");
215 :
216 3108 : if (getEdgeNodeParametricCoords(node, xi_2d))
217 : node_in_face = true;
218 : else
219 : {
220 0 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
221 : {
222 0 : if (_interior_nodes[i]->getNode() == node)
223 : {
224 0 : xi_2d.resize(2, 0.0);
225 0 : xi_2d[0] = _interior_nodes[i]->getParametricCoordinates(0);
226 0 : xi_2d[1] = _interior_nodes[i]->getParametricCoordinates(1);
227 : node_in_face = true;
228 0 : break;
229 : }
230 : } // i
231 : }
232 3108 : return node_in_face;
233 : }
234 :
235 : unsigned int
236 57532 : EFAFace::numInteriorNodes() const
237 : {
238 57532 : return _interior_nodes.size();
239 : }
240 :
241 : void
242 2424 : EFAFace::createNodes()
243 : {
244 11176 : for (unsigned int i = 0; i < _edges.size(); ++i)
245 : {
246 8752 : if (_edges[i] != nullptr)
247 8752 : _nodes[i] = _edges[i]->getNode(0);
248 : else
249 0 : EFAError("in EFAface::createNodes() _edges[i] does not exist");
250 : }
251 2424 : }
252 :
253 : void
254 8752 : EFAFace::setEdge(unsigned int edge_id, EFAEdge * new_edge)
255 : {
256 8752 : _edges[edge_id] = new_edge;
257 8752 : }
258 :
259 : void
260 218108 : EFAFace::createEdges()
261 : {
262 1005068 : for (unsigned int i = 0; i < _num_nodes; ++i)
263 : {
264 786960 : unsigned int i_plus1(i < (_num_nodes - 1) ? i + 1 : 0);
265 786960 : if (_nodes[i] != nullptr && _nodes[i_plus1] != nullptr)
266 : {
267 786960 : EFAEdge * new_edge = new EFAEdge(_nodes[i], _nodes[i_plus1]);
268 786960 : _edges[i] = new_edge;
269 : }
270 : else
271 0 : EFAError("EFAface::createEdges requires exsiting _nodes");
272 : }
273 218108 : }
274 :
275 : void
276 508 : EFAFace::combineTwoEdges(unsigned int edge_id1, unsigned int edge_id2)
277 : {
278 762 : if (_edges[edge_id1]->containsNode(_edges[edge_id2]->getNode(0)) ||
279 254 : _edges[edge_id1]->containsNode(_edges[edge_id2]->getNode(1)))
280 : {
281 : // edge_id1 must precede edge_id2
282 508 : unsigned int edge1_next(edge_id1 < (_num_edges - 1) ? edge_id1 + 1 : 0);
283 508 : if (edge1_next != edge_id2) // if not, swap
284 : {
285 : unsigned int itmp = edge_id1;
286 : edge_id1 = edge_id2;
287 : edge_id2 = itmp;
288 : }
289 :
290 : // build new edge and delete old ones
291 508 : EFANode * new_node1 = _edges[edge_id1]->getNode(0);
292 508 : EFANode * emb_node = _edges[edge_id1]->getNode(1);
293 508 : EFANode * new_node2 = _edges[edge_id2]->getNode(1);
294 508 : if (emb_node != _edges[edge_id2]->getNode(0))
295 0 : EFAError("in combine_two_edges face edges are not correctly set up");
296 :
297 508 : EFAEdge * full_edge = new EFAEdge(new_node1, new_node2);
298 508 : full_edge->addIntersection(-1.0, emb_node, new_node1); // dummy intersection_x
299 :
300 508 : delete _edges[edge_id1];
301 508 : delete _edges[edge_id2];
302 508 : _edges[edge_id1] = full_edge;
303 508 : _edges.erase(_edges.begin() + edge_id2);
304 :
305 : // update face memeber variables
306 508 : _num_edges -= 1;
307 508 : _num_nodes -= 1;
308 508 : _nodes.resize(_num_nodes, nullptr);
309 2380 : for (unsigned int k = 0; k < _num_edges; ++k)
310 1872 : _nodes[k] = _edges[k]->getNode(0);
311 : }
312 : else
313 0 : EFAError("two edges to be combined are not ajacent to each other");
314 508 : }
315 :
316 : void
317 2424 : EFAFace::sortEdges()
318 : {
319 2424 : std::vector<EFAEdge *> ordered_edges(_num_edges, nullptr);
320 2424 : ordered_edges[0] = _edges[0];
321 8752 : for (unsigned int i = 1; i < _num_edges; ++i)
322 : {
323 6328 : EFAEdge * last_edge = ordered_edges[i - 1];
324 18082 : for (unsigned int j = 0; j < _num_edges; ++j)
325 : {
326 18082 : if (!_edges[j]->equivalent(*last_edge) && _edges[j]->containsNode(last_edge->getNode(1)))
327 : {
328 6328 : ordered_edges[i] = _edges[j];
329 6328 : break;
330 : }
331 : } // j
332 : } // i
333 2424 : _edges = ordered_edges;
334 2424 : }
335 :
336 : void
337 2424 : EFAFace::reverseEdges()
338 : {
339 : // reverse the orientation of the face
340 11176 : for (unsigned int i = 0; i < _edges.size(); ++i)
341 8752 : _edges[i]->reverseNodes();
342 2424 : std::reverse(_edges.begin(), _edges.end());
343 2424 : }
344 :
345 : bool
346 6216 : EFAFace::isTriOrQuad() const
347 : {
348 6216 : if (_num_edges == 3 || _num_edges == 4)
349 : return true;
350 : else
351 0 : return false;
352 : }
353 :
354 : bool
355 41757617 : EFAFace::equivalent(const EFAFace * other_face) const
356 : {
357 41757617 : return std::is_permutation(
358 41757617 : _nodes.begin(), _nodes.end(), other_face->_nodes.begin(), other_face->_nodes.end());
359 : }
360 :
361 : bool
362 76265468 : EFAFace::containsNode(const EFANode * node) const
363 : {
364 259608770 : for (unsigned int i = 0; i < _num_edges; ++i)
365 220520462 : if (_edges[i]->containsNode(node))
366 : return true;
367 :
368 39088308 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
369 0 : if (_interior_nodes[i]->getNode() == node)
370 : return true;
371 :
372 : return false;
373 : }
374 :
375 : bool
376 17051396 : EFAFace::containsFace(const EFAFace * other_face) const
377 : {
378 : unsigned int counter = 0;
379 81695276 : for (unsigned int i = 0; i < other_face->_num_nodes; ++i)
380 : {
381 64643880 : if (containsNode(other_face->_nodes[i]))
382 33306232 : counter += 1;
383 : }
384 17051396 : if (counter == other_face->_num_nodes)
385 : return true;
386 : else
387 13094775 : return false;
388 : }
389 :
390 : bool
391 17089834 : EFAFace::ownsEdge(const EFAEdge * other_edge) const
392 : {
393 69756453 : for (unsigned int i = 0; i < _edges.size(); ++i)
394 57593161 : if (_edges[i]->equivalent(*other_edge))
395 : return true;
396 : return false;
397 : }
398 :
399 : void
400 0 : EFAFace::removeEmbeddedNode(EFANode * emb_node)
401 : {
402 0 : for (unsigned int i = 0; i < _num_edges; ++i)
403 0 : _edges[i]->removeEmbeddedNode(emb_node);
404 :
405 : unsigned int index = 0;
406 : bool node_found = false;
407 0 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
408 : {
409 0 : if (_interior_nodes[i]->getNode() == emb_node)
410 : {
411 : node_found = true;
412 : index = i;
413 : break;
414 : }
415 : }
416 0 : if (node_found)
417 : {
418 0 : delete _interior_nodes[index];
419 0 : _interior_nodes.erase(_interior_nodes.begin() + index);
420 : }
421 0 : }
422 :
423 : std::vector<EFAFace *>
424 8438 : EFAFace::split() const
425 : {
426 : std::vector<EFAFace *> new_faces;
427 8438 : if (getNumCuts() > 0)
428 : {
429 : // construct a fragment from this face
430 5733 : EFAFragment2D * frag_tmp = new EFAFragment2D(nullptr, this);
431 5733 : std::vector<EFAFragment2D *> new_frags_tmp = frag_tmp->split();
432 :
433 : // copy new_frags to new_faces
434 16309 : for (unsigned int i = 0; i < new_frags_tmp.size(); ++i)
435 10576 : new_faces.push_back(new EFAFace(new_frags_tmp[i]));
436 :
437 : // delete frag_tmp and new_frags
438 5733 : delete frag_tmp;
439 16309 : for (unsigned int i = 0; i < new_frags_tmp.size(); ++i)
440 10576 : delete new_frags_tmp[i];
441 5733 : }
442 : else
443 2705 : new_faces.push_back(new EFAFace(*this));
444 :
445 8438 : return new_faces;
446 0 : }
447 :
448 : EFAFace *
449 264 : EFAFace::combineWithFace(const EFAFace * other_face) const
450 : {
451 : // combine this face with another adjacent face
452 : EFAFace * new_face = nullptr;
453 264 : if (isAdjacent(other_face))
454 : {
455 264 : unsigned int this_common_edge_id = adjacentCommonEdge(other_face);
456 : std::vector<EFANode *> common_nodes;
457 264 : common_nodes.push_back(_edges[this_common_edge_id]->getNode(0));
458 264 : common_nodes.push_back(_edges[this_common_edge_id]->getNode(1));
459 :
460 264 : unsigned int other_common_edge_id = other_face->adjacentCommonEdge(this);
461 264 : unsigned int new_n_nodes = _num_edges + other_face->_num_edges - 4;
462 264 : EFAFragment2D * new_frag = new EFAFragment2D(nullptr, false, nullptr); // temp fragment
463 :
464 264 : unsigned int this_edge_id0(this_common_edge_id > 0 ? this_common_edge_id - 1
465 0 : : _num_edges - 1); // common_nodes[0]
466 264 : unsigned int this_edge_id1(this_common_edge_id < (_num_edges - 1) ? this_common_edge_id + 1
467 : : 0); // common_nodes[1]
468 : unsigned int other_edge_id0(
469 264 : other_common_edge_id < (other_face->_num_edges - 1) ? other_common_edge_id + 1 : 0);
470 264 : unsigned int other_edge_id1(other_common_edge_id > 0 ? other_common_edge_id - 1
471 : : other_face->_num_edges - 1);
472 :
473 264 : EFAEdge * new_edge0 = new EFAEdge(_edges[this_edge_id0]->getNode(0),
474 264 : other_face->_edges[other_edge_id0]->getNode(1));
475 264 : new_edge0->addIntersection(
476 : -1.0, common_nodes[0], new_edge0->getNode(0)); // dummy intersection_x
477 264 : new_frag->addEdge(new_edge0); // common_nodes[0]'s edge
478 :
479 264 : unsigned int other_iedge(other_edge_id0 < (other_face->_num_edges - 1) ? other_edge_id0 + 1
480 : : 0);
481 468 : while (!other_face->_edges[other_iedge]->equivalent(*other_face->_edges[other_edge_id1]))
482 : {
483 204 : new_frag->addEdge(new EFAEdge(*other_face->_edges[other_iedge]));
484 204 : other_iedge += 1;
485 204 : if (other_iedge == other_face->_num_edges)
486 : other_iedge = 0;
487 : } // loop over other_face's edges
488 :
489 : EFAEdge * new_edge1 = new EFAEdge(other_face->_edges[other_edge_id1]->getNode(0),
490 264 : _edges[this_edge_id1]->getNode(1));
491 264 : new_edge1->addIntersection(
492 : -1.0, common_nodes[1], new_edge1->getNode(0)); // dummy intersection_x
493 264 : new_frag->addEdge(new_edge1);
494 :
495 264 : unsigned int this_iedge(this_edge_id1 < (_num_edges - 1) ? this_edge_id1 + 1 : 0);
496 508 : while (!_edges[this_iedge]->equivalent(*_edges[this_edge_id0])) // common_nodes[1]'s edge
497 : {
498 244 : new_frag->addEdge(new EFAEdge(*_edges[this_iedge]));
499 244 : this_iedge += 1;
500 244 : if (this_iedge == _num_edges)
501 : this_iedge = 0;
502 : } // loop over this_face's edges
503 :
504 264 : new_face = new EFAFace(new_frag);
505 264 : delete new_frag;
506 264 : if (new_face->numNodes() != new_n_nodes)
507 0 : EFAError("combine_with() sanity check fails");
508 264 : }
509 264 : return new_face;
510 : }
511 :
512 : void
513 772 : EFAFace::resetEdgeIntersection(const EFAFace * ref_face)
514 : {
515 : // set up correct edge intersections based on the reference face
516 : // the reference face must contain the edge of this face that is to be set up
517 : // the reference face must be an element face
518 3620 : for (unsigned int j = 0; j < _num_edges; ++j)
519 : {
520 2848 : if (_edges[j]->hasIntersection())
521 : {
522 1100 : if (_edges[j]->numEmbeddedNodes() > 1)
523 0 : EFAError("frag face edge can only have 1 emb node at this point");
524 :
525 1100 : EFANode * edge_node1 = _edges[j]->getNode(0);
526 1100 : EFANode * edge_node2 = _edges[j]->getNode(1);
527 1100 : EFANode * emb_node = _edges[j]->getEmbeddedNode(0);
528 1100 : double inters_x = _edges[j]->getIntersection(0, edge_node1);
529 1100 : if (std::abs(inters_x + 1.0) < 1.0e-4) // invalid intersection found
530 : {
531 1036 : std::vector<double> node1_xi2d(2, 0.0);
532 1036 : std::vector<double> node2_xi2d(2, 0.0);
533 1036 : std::vector<double> emb_xi2d(2, 0.0);
534 2072 : if (ref_face->getFaceNodeParametricCoords(edge_node1, node1_xi2d) &&
535 2072 : ref_face->getFaceNodeParametricCoords(edge_node2, node2_xi2d) &&
536 1036 : ref_face->getFaceNodeParametricCoords(emb_node, emb_xi2d))
537 : {
538 : // TODO: this is not correct for unstructured elements. Need a fix
539 : double dist2node1 =
540 1036 : std::sqrt((emb_xi2d[0] - node1_xi2d[0]) * (emb_xi2d[0] - node1_xi2d[0]) +
541 1036 : (emb_xi2d[1] - node1_xi2d[1]) * (emb_xi2d[1] - node1_xi2d[1]));
542 : double full_dist =
543 1036 : std::sqrt((node2_xi2d[0] - node1_xi2d[0]) * (node2_xi2d[0] - node1_xi2d[0]) +
544 1036 : (node2_xi2d[1] - node1_xi2d[1]) * (node2_xi2d[1] - node1_xi2d[1]));
545 1036 : inters_x = dist2node1 / full_dist;
546 : }
547 : else
548 0 : EFAError("reference face does not contain the edge with invalid inters");
549 1036 : _edges[j]->resetIntersection(inters_x, emb_node, edge_node1);
550 1036 : }
551 : }
552 : }
553 772 : }
554 :
555 : unsigned int
556 283721 : EFAFace::getNumCuts() const
557 : {
558 : unsigned int num_cuts = 0;
559 1312917 : for (unsigned int i = 0; i < _edges.size(); ++i)
560 : {
561 1029196 : if (_edges[i]->hasIntersection())
562 144157 : num_cuts += _edges[i]->numEmbeddedNodes();
563 : }
564 283721 : return num_cuts;
565 : }
566 :
567 : bool
568 251467 : EFAFace::hasIntersection() const
569 : {
570 251467 : if (getNumCuts() > 1)
571 : return true;
572 : else
573 192185 : return false;
574 : }
575 :
576 : void
577 43826 : EFAFace::copyIntersection(const EFAFace & from_face)
578 : {
579 202490 : for (unsigned int i = 0; i < _edges.size(); ++i)
580 158664 : if (from_face._edges[i]->hasIntersection())
581 60840 : _edges[i]->copyIntersection(*from_face._edges[i], 0);
582 :
583 43826 : if (from_face.numInteriorNodes() > 0)
584 0 : _interior_nodes = from_face._interior_nodes;
585 43826 : }
586 :
587 : bool
588 3546708 : EFAFace::isAdjacent(const EFAFace * other_face) const
589 : {
590 : // two faces are adjacent if they only share one common edge
591 : unsigned int counter = 0;
592 16729274 : for (unsigned int i = 0; i < _num_edges; ++i)
593 13182566 : if (other_face->ownsEdge(_edges[i]))
594 3253473 : counter += 1;
595 :
596 3546708 : if (counter == 1)
597 : return true;
598 : else
599 293235 : return false;
600 : }
601 :
602 : unsigned int
603 1673069 : EFAFace::adjacentCommonEdge(const EFAFace * other_face) const
604 : {
605 1673069 : if (isAdjacent(other_face))
606 : {
607 3907268 : for (unsigned int i = 0; i < _num_edges; ++i)
608 3907268 : if (other_face->ownsEdge(_edges[i]))
609 1673069 : return i;
610 : }
611 0 : EFAError("this face is not adjacent with other_face");
612 : }
613 :
614 : bool
615 158940 : EFAFace::hasSameOrientation(const EFAFace * other_face) const
616 : {
617 : bool same_order = false;
618 158940 : if (equivalent(other_face))
619 : {
620 718480 : for (unsigned int i = 0; i < other_face->numNodes(); ++i)
621 : {
622 560308 : if (other_face->_nodes[i] == _nodes[0])
623 : {
624 158940 : unsigned int iplus1(i < (other_face->_num_nodes - 1) ? i + 1 : 0);
625 158940 : if (other_face->_nodes[iplus1] == _nodes[1])
626 : {
627 : same_order = true;
628 : break;
629 : }
630 158172 : else if (other_face->_nodes[iplus1] != _nodes[_num_nodes - 1])
631 0 : EFAError("two faces overlap but can't find correct common nodes");
632 : }
633 : }
634 : }
635 : else
636 : EFAWarning("in hasSameOrientation two faces does not overlap");
637 158940 : return same_order;
638 : }
639 :
640 : EFAFaceNode *
641 0 : EFAFace::getInteriorNode(unsigned int index) const
642 : {
643 0 : return _interior_nodes[index];
644 : }
645 :
646 : void
647 3108 : EFAFace::mapParametricCoordsFrom1DTo2D(unsigned int edge_id,
648 : double xi_1d,
649 : std::vector<double> & xi_2d) const
650 : {
651 : // given the 1D parent coord of a point in an 2D element edge, translate it to 2D para coords
652 3108 : xi_2d.resize(2, 0.0);
653 3108 : if (_num_edges == 4)
654 : {
655 2148 : if (edge_id == 0)
656 : {
657 1020 : xi_2d[0] = xi_1d;
658 1020 : xi_2d[1] = -1.0;
659 : }
660 1128 : else if (edge_id == 1)
661 : {
662 412 : xi_2d[0] = 1.0;
663 412 : xi_2d[1] = xi_1d;
664 : }
665 716 : else if (edge_id == 2)
666 : {
667 682 : xi_2d[0] = -xi_1d;
668 682 : xi_2d[1] = 1.0;
669 : }
670 34 : else if (edge_id == 3)
671 : {
672 34 : xi_2d[0] = -1.0;
673 34 : xi_2d[1] = -xi_1d;
674 : }
675 : else
676 0 : EFAError("edge_id out of bounds");
677 : }
678 960 : else if (_num_edges == 3)
679 : {
680 960 : if (edge_id == 0)
681 : {
682 480 : xi_2d[0] = 0.5 * (1.0 - xi_1d);
683 480 : xi_2d[1] = 0.5 * (1.0 + xi_1d);
684 : }
685 480 : else if (edge_id == 1)
686 : {
687 360 : xi_2d[0] = 0.0;
688 360 : xi_2d[1] = 0.5 * (1.0 - xi_1d);
689 : }
690 120 : else if (edge_id == 2)
691 : {
692 120 : xi_2d[0] = 0.5 * (1.0 + xi_1d);
693 120 : xi_2d[1] = 0.0;
694 : }
695 : else
696 0 : EFAError("edge_id out of bounds");
697 : }
698 : else
699 0 : EFAError("the EFAface::mapParametricCoordsFrom1DTo2D only works for quad and tri faces");
700 3108 : }
|