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 246556 : EFAFace::EFAFace(unsigned int n_nodes, unsigned int num_interior_face_nodes)
20 246556 : : _num_nodes(n_nodes),
21 246556 : _nodes(_num_nodes, nullptr),
22 246556 : _num_edges(_num_nodes),
23 246556 : _edges(_num_edges, nullptr),
24 246556 : _face_interior_nodes(num_interior_face_nodes, nullptr)
25 : {
26 246556 : }
27 :
28 216870 : EFAFace::EFAFace(const EFAFace & other_face)
29 216870 : : _num_nodes(other_face._num_nodes),
30 216870 : _nodes(_num_nodes, nullptr),
31 216870 : _num_edges(_num_nodes),
32 216870 : _edges(_num_edges, nullptr)
33 : {
34 1016836 : for (unsigned int k = 0; k < other_face._num_nodes; ++k)
35 : {
36 799966 : _nodes[k] = other_face._nodes[k];
37 799966 : _edges[k] = new EFAEdge(*other_face._edges[k]);
38 : }
39 216870 : 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 216870 : }
42 :
43 11804 : EFAFace::EFAFace(const EFAFragment2D * frag)
44 11804 : : _num_nodes(frag->numEdges()),
45 11804 : _nodes(_num_nodes, nullptr),
46 11804 : _num_edges(_num_nodes),
47 11804 : _edges(_num_edges, nullptr)
48 : {
49 57694 : for (unsigned int k = 0; k < frag->numEdges(); ++k)
50 : {
51 45890 : EFANode * node = frag->getEdge(k)->getNode(0);
52 45890 : unsigned int kprev(k > 0 ? (k - 1) : (frag->numEdges() - 1));
53 45890 : if (!frag->getEdge(kprev)->containsNode(node))
54 0 : node = getEdge(k)->getNode(1);
55 45890 : _nodes[k] = node;
56 45890 : _edges[k] = new EFAEdge(*frag->getEdge(k));
57 : }
58 11804 : }
59 :
60 475230 : EFAFace::~EFAFace()
61 : {
62 2220154 : for (unsigned int i = 0; i < _edges.size(); ++i)
63 : {
64 1744924 : if (_edges[i])
65 : {
66 1744924 : delete _edges[i];
67 1744924 : _edges[i] = nullptr;
68 : }
69 : }
70 475230 : 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 475230 : }
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 8646119 : EFAFace::numNodes() const
88 : {
89 8646119 : return _nodes.size();
90 : }
91 :
92 : void
93 890736 : EFAFace::setNode(unsigned int node_id, EFANode * node)
94 : {
95 890736 : _nodes[node_id] = node;
96 890736 : }
97 :
98 : EFANode *
99 6308404 : EFAFace::getNode(unsigned int node_id) const
100 : {
101 6308404 : return _nodes[node_id];
102 : }
103 :
104 : void
105 6562567 : EFAFace::switchNode(EFANode * new_node, EFANode * old_node)
106 : {
107 : bool is_face_node = true;
108 28635693 : for (unsigned int i = 0; i < _num_nodes; ++i)
109 : {
110 22073126 : if (_nodes[i] == old_node)
111 : {
112 169959 : _nodes[i] = new_node;
113 : is_face_node = false;
114 : }
115 : }
116 6562567 : if (is_face_node)
117 : {
118 17127912 : 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 820563 : for (unsigned int i = 0; i < _edges.size(); ++i)
125 650604 : _edges[i]->switchNode(new_node, old_node);
126 169959 : for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
127 0 : _interior_nodes[i]->switchNode(new_node, old_node);
128 : }
129 6562567 : }
130 :
131 : bool
132 3181742 : 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 3181742 : master_nodes.clear();
139 3181742 : master_weights.clear();
140 : bool masters_found = false;
141 7729968 : for (unsigned int i = 0; i < _num_edges; ++i) // check element exterior edges
142 : {
143 7729968 : if (_edges[i]->containsNode(node))
144 : {
145 3181742 : masters_found = _edges[i]->getNodeMasters(node, master_nodes, master_weights);
146 3181742 : 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 3181742 : return masters_found;
180 : }
181 :
182 : bool
183 4500 : 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 4500 : if (!isTriOrQuad())
189 0 : EFAError("EFAface::getEdgeNodeParaCoor can only work for quad or tri faces");
190 :
191 8138 : for (unsigned int i = 0; i < _num_edges; ++i)
192 : {
193 8138 : if (_edges[i]->containsNode(node))
194 : {
195 : edge_id = i;
196 : edge_found = true;
197 : break;
198 : }
199 : }
200 4500 : if (edge_found)
201 : {
202 4500 : double rel_dist = _edges[edge_id]->distanceFromNode1(node);
203 4500 : double xi_1d = 2.0 * rel_dist - 1.0; // translate to [-1,1] parent coord syst
204 4500 : mapParametricCoordsFrom1DTo2D(edge_id, xi_1d, xi_2d);
205 : }
206 4500 : return edge_found;
207 : }
208 :
209 : bool
210 4500 : EFAFace::getFaceNodeParametricCoords(EFANode * node, std::vector<double> & xi_2d) const
211 : {
212 : bool node_in_face = false;
213 4500 : if (!isTriOrQuad())
214 0 : EFAError("EFAface::getFaceNodeParaCoor can only work for quad or tri faces");
215 :
216 4500 : 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 4500 : return node_in_face;
233 : }
234 :
235 : unsigned int
236 63460 : EFAFace::numInteriorNodes() const
237 : {
238 63460 : return _interior_nodes.size();
239 : }
240 :
241 : void
242 2504 : EFAFace::createNodes()
243 : {
244 11576 : for (unsigned int i = 0; i < _edges.size(); ++i)
245 : {
246 9072 : if (_edges[i] != nullptr)
247 9072 : _nodes[i] = _edges[i]->getNode(0);
248 : else
249 0 : EFAError("in EFAface::createNodes() _edges[i] does not exist");
250 : }
251 2504 : }
252 :
253 : void
254 9072 : EFAFace::setEdge(unsigned int edge_id, EFAEdge * new_edge)
255 : {
256 9072 : _edges[edge_id] = new_edge;
257 9072 : }
258 :
259 : void
260 244052 : EFAFace::createEdges()
261 : {
262 1134788 : for (unsigned int i = 0; i < _num_nodes; ++i)
263 : {
264 890736 : unsigned int i_plus1(i < (_num_nodes - 1) ? i + 1 : 0);
265 890736 : if (_nodes[i] != nullptr && _nodes[i_plus1] != nullptr)
266 : {
267 890736 : EFAEdge * new_edge = new EFAEdge(_nodes[i], _nodes[i_plus1]);
268 890736 : _edges[i] = new_edge;
269 : }
270 : else
271 0 : EFAError("EFAface::createEdges requires exsiting _nodes");
272 : }
273 244052 : }
274 :
275 : void
276 740 : EFAFace::combineTwoEdges(unsigned int edge_id1, unsigned int edge_id2)
277 : {
278 1110 : if (_edges[edge_id1]->containsNode(_edges[edge_id2]->getNode(0)) ||
279 370 : _edges[edge_id1]->containsNode(_edges[edge_id2]->getNode(1)))
280 : {
281 : // edge_id1 must precede edge_id2
282 740 : unsigned int edge1_next(edge_id1 < (_num_edges - 1) ? edge_id1 + 1 : 0);
283 740 : 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 740 : EFANode * new_node1 = _edges[edge_id1]->getNode(0);
292 740 : EFANode * emb_node = _edges[edge_id1]->getNode(1);
293 740 : EFANode * new_node2 = _edges[edge_id2]->getNode(1);
294 740 : if (emb_node != _edges[edge_id2]->getNode(0))
295 0 : EFAError("in combine_two_edges face edges are not correctly set up");
296 :
297 740 : EFAEdge * full_edge = new EFAEdge(new_node1, new_node2);
298 740 : full_edge->addIntersection(-1.0, emb_node, new_node1); // dummy intersection_x
299 :
300 740 : delete _edges[edge_id1];
301 740 : delete _edges[edge_id2];
302 740 : _edges[edge_id1] = full_edge;
303 740 : _edges.erase(_edges.begin() + edge_id2);
304 :
305 : // update face memeber variables
306 740 : _num_edges -= 1;
307 740 : _num_nodes -= 1;
308 740 : _nodes.resize(_num_nodes, nullptr);
309 3540 : for (unsigned int k = 0; k < _num_edges; ++k)
310 2800 : _nodes[k] = _edges[k]->getNode(0);
311 : }
312 : else
313 0 : EFAError("two edges to be combined are not ajacent to each other");
314 740 : }
315 :
316 : void
317 2504 : EFAFace::sortEdges()
318 : {
319 2504 : std::vector<EFAEdge *> ordered_edges(_num_edges, nullptr);
320 2504 : ordered_edges[0] = _edges[0];
321 9072 : for (unsigned int i = 1; i < _num_edges; ++i)
322 : {
323 6568 : EFAEdge * last_edge = ordered_edges[i - 1];
324 18802 : for (unsigned int j = 0; j < _num_edges; ++j)
325 : {
326 18802 : if (!_edges[j]->equivalent(*last_edge) && _edges[j]->containsNode(last_edge->getNode(1)))
327 : {
328 6568 : ordered_edges[i] = _edges[j];
329 6568 : break;
330 : }
331 : } // j
332 : } // i
333 2504 : _edges = ordered_edges;
334 2504 : }
335 :
336 : void
337 2504 : EFAFace::reverseEdges()
338 : {
339 : // reverse the orientation of the face
340 11576 : for (unsigned int i = 0; i < _edges.size(); ++i)
341 9072 : _edges[i]->reverseNodes();
342 2504 : std::reverse(_edges.begin(), _edges.end());
343 2504 : }
344 :
345 : bool
346 9000 : EFAFace::isTriOrQuad() const
347 : {
348 9000 : if (_num_edges == 3 || _num_edges == 4)
349 : return true;
350 : else
351 0 : return false;
352 : }
353 :
354 : bool
355 45274476 : EFAFace::equivalent(const EFAFace * other_face) const
356 : {
357 45274476 : return std::is_permutation(
358 45274476 : _nodes.begin(), _nodes.end(), other_face->_nodes.begin(), other_face->_nodes.end());
359 : }
360 :
361 : bool
362 93217947 : EFAFace::containsNode(const EFANode * node) const
363 : {
364 322450112 : for (unsigned int i = 0; i < _num_edges; ++i)
365 273958768 : if (_edges[i]->containsNode(node))
366 : return true;
367 :
368 48491344 : 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 20737062 : EFAFace::containsFace(const EFAFace * other_face) const
377 : {
378 : unsigned int counter = 0;
379 100126842 : for (unsigned int i = 0; i < other_face->_num_nodes; ++i)
380 : {
381 79389780 : if (containsNode(other_face->_nodes[i]))
382 40063920 : counter += 1;
383 : }
384 20737062 : if (counter == other_face->_num_nodes)
385 : return true;
386 : else
387 16014355 : return false;
388 : }
389 :
390 : bool
391 19616421 : EFAFace::ownsEdge(const EFAEdge * other_edge) const
392 : {
393 80769394 : for (unsigned int i = 0; i < _edges.size(); ++i)
394 66737711 : 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 9470 : EFAFace::split() const
425 : {
426 : std::vector<EFAFace *> new_faces;
427 9470 : if (getNumCuts() > 0)
428 : {
429 : // construct a fragment from this face
430 6289 : EFAFragment2D * frag_tmp = new EFAFragment2D(nullptr, this);
431 6289 : std::vector<EFAFragment2D *> new_frags_tmp = frag_tmp->split();
432 :
433 : // copy new_frags to new_faces
434 17713 : for (unsigned int i = 0; i < new_frags_tmp.size(); ++i)
435 11424 : new_faces.push_back(new EFAFace(new_frags_tmp[i]));
436 :
437 : // delete frag_tmp and new_frags
438 6289 : delete frag_tmp;
439 17713 : for (unsigned int i = 0; i < new_frags_tmp.size(); ++i)
440 11424 : delete new_frags_tmp[i];
441 6289 : }
442 : else
443 3181 : new_faces.push_back(new EFAFace(*this));
444 :
445 9470 : return new_faces;
446 0 : }
447 :
448 : EFAFace *
449 380 : EFAFace::combineWithFace(const EFAFace * other_face) const
450 : {
451 : // combine this face with another adjacent face
452 : EFAFace * new_face = nullptr;
453 380 : if (isAdjacent(other_face))
454 : {
455 380 : unsigned int this_common_edge_id = adjacentCommonEdge(other_face);
456 : std::vector<EFANode *> common_nodes;
457 380 : common_nodes.push_back(_edges[this_common_edge_id]->getNode(0));
458 380 : common_nodes.push_back(_edges[this_common_edge_id]->getNode(1));
459 :
460 380 : unsigned int other_common_edge_id = other_face->adjacentCommonEdge(this);
461 380 : unsigned int new_n_nodes = _num_edges + other_face->_num_edges - 4;
462 380 : EFAFragment2D * new_frag = new EFAFragment2D(nullptr, false, nullptr); // temp fragment
463 :
464 380 : unsigned int this_edge_id0(this_common_edge_id > 0 ? this_common_edge_id - 1
465 0 : : _num_edges - 1); // common_nodes[0]
466 380 : 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 380 : other_common_edge_id < (other_face->_num_edges - 1) ? other_common_edge_id + 1 : 0);
470 380 : unsigned int other_edge_id1(other_common_edge_id > 0 ? other_common_edge_id - 1
471 : : other_face->_num_edges - 1);
472 :
473 380 : EFAEdge * new_edge0 = new EFAEdge(_edges[this_edge_id0]->getNode(0),
474 380 : other_face->_edges[other_edge_id0]->getNode(1));
475 380 : new_edge0->addIntersection(
476 : -1.0, common_nodes[0], new_edge0->getNode(0)); // dummy intersection_x
477 380 : new_frag->addEdge(new_edge0); // common_nodes[0]'s edge
478 :
479 380 : unsigned int other_iedge(other_edge_id0 < (other_face->_num_edges - 1) ? other_edge_id0 + 1
480 : : 0);
481 700 : while (!other_face->_edges[other_iedge]->equivalent(*other_face->_edges[other_edge_id1]))
482 : {
483 320 : new_frag->addEdge(new EFAEdge(*other_face->_edges[other_iedge]));
484 320 : other_iedge += 1;
485 320 : 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 380 : _edges[this_edge_id1]->getNode(1));
491 380 : new_edge1->addIntersection(
492 : -1.0, common_nodes[1], new_edge1->getNode(0)); // dummy intersection_x
493 380 : new_frag->addEdge(new_edge1);
494 :
495 380 : unsigned int this_iedge(this_edge_id1 < (_num_edges - 1) ? this_edge_id1 + 1 : 0);
496 740 : while (!_edges[this_iedge]->equivalent(*_edges[this_edge_id0])) // common_nodes[1]'s edge
497 : {
498 360 : new_frag->addEdge(new EFAEdge(*_edges[this_iedge]));
499 360 : this_iedge += 1;
500 360 : if (this_iedge == _num_edges)
501 : this_iedge = 0;
502 : } // loop over this_face's edges
503 :
504 380 : new_face = new EFAFace(new_frag);
505 380 : delete new_frag;
506 380 : if (new_face->numNodes() != new_n_nodes)
507 0 : EFAError("combine_with() sanity check fails");
508 380 : }
509 380 : return new_face;
510 : }
511 :
512 : void
513 1120 : 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 5360 : for (unsigned int j = 0; j < _num_edges; ++j)
519 : {
520 4240 : if (_edges[j]->hasIntersection())
521 : {
522 1580 : if (_edges[j]->numEmbeddedNodes() > 1)
523 0 : EFAError("frag face edge can only have 1 emb node at this point");
524 :
525 1580 : EFANode * edge_node1 = _edges[j]->getNode(0);
526 1580 : EFANode * edge_node2 = _edges[j]->getNode(1);
527 1580 : EFANode * emb_node = _edges[j]->getEmbeddedNode(0);
528 1580 : double inters_x = _edges[j]->getIntersection(0, edge_node1);
529 1580 : if (std::abs(inters_x + 1.0) < 1.0e-4) // invalid intersection found
530 : {
531 1500 : std::vector<double> node1_xi2d(2, 0.0);
532 1500 : std::vector<double> node2_xi2d(2, 0.0);
533 1500 : std::vector<double> emb_xi2d(2, 0.0);
534 3000 : if (ref_face->getFaceNodeParametricCoords(edge_node1, node1_xi2d) &&
535 3000 : ref_face->getFaceNodeParametricCoords(edge_node2, node2_xi2d) &&
536 1500 : ref_face->getFaceNodeParametricCoords(emb_node, emb_xi2d))
537 : {
538 : // TODO: this is not correct for unstructured elements. Need a fix
539 : double dist2node1 =
540 1500 : std::sqrt((emb_xi2d[0] - node1_xi2d[0]) * (emb_xi2d[0] - node1_xi2d[0]) +
541 1500 : (emb_xi2d[1] - node1_xi2d[1]) * (emb_xi2d[1] - node1_xi2d[1]));
542 : double full_dist =
543 1500 : std::sqrt((node2_xi2d[0] - node1_xi2d[0]) * (node2_xi2d[0] - node1_xi2d[0]) +
544 1500 : (node2_xi2d[1] - node1_xi2d[1]) * (node2_xi2d[1] - node1_xi2d[1]));
545 1500 : inters_x = dist2node1 / full_dist;
546 : }
547 : else
548 0 : EFAError("reference face does not contain the edge with invalid inters");
549 1500 : _edges[j]->resetIntersection(inters_x, emb_node, edge_node1);
550 1500 : }
551 : }
552 : }
553 1120 : }
554 :
555 : unsigned int
556 325781 : EFAFace::getNumCuts() const
557 : {
558 : unsigned int num_cuts = 0;
559 1523233 : for (unsigned int i = 0; i < _edges.size(); ++i)
560 : {
561 1197452 : if (_edges[i]->hasIntersection())
562 160109 : num_cuts += _edges[i]->numEmbeddedNodes();
563 : }
564 325781 : return num_cuts;
565 : }
566 :
567 : bool
568 289087 : EFAFace::hasIntersection() const
569 : {
570 289087 : if (getNumCuts() > 1)
571 : return true;
572 : else
573 223101 : return false;
574 : }
575 :
576 : void
577 49034 : EFAFace::copyIntersection(const EFAFace & from_face)
578 : {
579 228530 : for (unsigned int i = 0; i < _edges.size(); ++i)
580 179496 : if (from_face._edges[i]->hasIntersection())
581 67128 : _edges[i]->copyIntersection(*from_face._edges[i], 0);
582 :
583 49034 : if (from_face.numInteriorNodes() > 0)
584 0 : _interior_nodes = from_face._interior_nodes;
585 49034 : }
586 :
587 : bool
588 4037496 : 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 19190718 : for (unsigned int i = 0; i < _num_edges; ++i)
593 15153222 : if (other_face->ownsEdge(_edges[i]))
594 3688837 : counter += 1;
595 :
596 4037496 : if (counter == 1)
597 : return true;
598 : else
599 348659 : return false;
600 : }
601 :
602 : unsigned int
603 1895901 : EFAFace::adjacentCommonEdge(const EFAFace * other_face) const
604 : {
605 1895901 : if (isAdjacent(other_face))
606 : {
607 4463199 : for (unsigned int i = 0; i < _num_edges; ++i)
608 4463199 : if (other_face->ownsEdge(_edges[i]))
609 1895901 : return i;
610 : }
611 0 : EFAError("this face is not adjacent with other_face");
612 : }
613 :
614 : bool
615 176792 : EFAFace::hasSameOrientation(const EFAFace * other_face) const
616 : {
617 : bool same_order = false;
618 176792 : if (equivalent(other_face))
619 : {
620 806620 : for (unsigned int i = 0; i < other_face->numNodes(); ++i)
621 : {
622 630876 : if (other_face->_nodes[i] == _nodes[0])
623 : {
624 176792 : unsigned int iplus1(i < (other_face->_num_nodes - 1) ? i + 1 : 0);
625 176792 : if (other_face->_nodes[iplus1] == _nodes[1])
626 : {
627 : same_order = true;
628 : break;
629 : }
630 175744 : 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 176792 : 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 4500 : 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 4500 : xi_2d.resize(2, 0.0);
653 4500 : if (_num_edges == 4)
654 : {
655 3540 : if (edge_id == 0)
656 : {
657 1716 : xi_2d[0] = xi_1d;
658 1716 : xi_2d[1] = -1.0;
659 : }
660 1824 : else if (edge_id == 1)
661 : {
662 644 : xi_2d[0] = 1.0;
663 644 : xi_2d[1] = xi_1d;
664 : }
665 1180 : else if (edge_id == 2)
666 : {
667 1146 : xi_2d[0] = -xi_1d;
668 1146 : 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 4500 : }
|