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