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 "EFAEdge.h" 11 : 12 : #include "EFANode.h" 13 : #include "EFAError.h" 14 : #include "XFEMFuncs.h" 15 : 16 2422789 : EFAEdge::EFAEdge(EFANode * node1, EFANode * node2) : _edge_node1(node1), _edge_node2(node2) 17 : { 18 2422789 : _embedded_nodes.clear(); 19 2422789 : _intersection_x.clear(); 20 2422789 : _edge_interior_node = nullptr; 21 2422789 : consistencyCheck(); 22 2422789 : } 23 : 24 1841004 : EFAEdge::EFAEdge(const EFAEdge & other_edge) 25 : { 26 1841004 : _edge_node1 = other_edge._edge_node1; 27 1841004 : _edge_node2 = other_edge._edge_node2; 28 1841004 : _intersection_x = other_edge._intersection_x; 29 1841004 : _embedded_nodes = other_edge._embedded_nodes; 30 1841004 : consistencyCheck(); 31 1841004 : } 32 : 33 4262993 : EFAEdge::~EFAEdge() // do not delete edge node - they will be deleted 34 : { // in EFAelement's destructor 35 4262993 : } 36 : 37 : bool 38 61960399 : EFAEdge::equivalent(const EFAEdge & other) const 39 : { 40 : if (getSortedNodes() == other.getSortedNodes()) 41 : { 42 : // For cut along the edge case 43 5120783 : if (isEmbeddedPermanent()) 44 : return false; 45 : return true; 46 : } 47 : 48 : return false; 49 : } 50 : 51 : bool 52 23234159 : EFAEdge::isEmbeddedPermanent() const 53 : { 54 23234247 : return _edge_node1->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT && 55 88 : _edge_node2->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT; 56 : } 57 : 58 : bool 59 36 : EFAEdge::isPartialOverlap(const EFAEdge & other) const 60 : { 61 36 : return containsEdge(other) || other.containsEdge(*this); 62 : } 63 : 64 : bool 65 28424843 : EFAEdge::containsEdge(const EFAEdge & other) const 66 : { 67 28424843 : return containsNode(other._edge_node1) && containsNode(other._edge_node2); 68 : } 69 : 70 : bool 71 6980959 : EFAEdge::getNodeMasters(EFANode * node, 72 : std::vector<EFANode *> & master_nodes, 73 : std::vector<double> & master_weights) const 74 : { 75 6980959 : master_nodes.clear(); 76 6980959 : master_weights.clear(); 77 : bool masters_found = false; 78 6980959 : if (_edge_node1 == node || _edge_node2 == node) 79 : { 80 605930 : master_nodes.push_back(node); 81 605930 : master_weights.push_back(1.0); 82 605930 : masters_found = true; 83 : } 84 : else 85 : { 86 6376955 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 87 : { 88 6376955 : if (_embedded_nodes[i] == node) 89 : { 90 6375029 : master_nodes.push_back(_edge_node1); 91 6375029 : master_nodes.push_back(_edge_node2); 92 6375029 : master_weights.push_back(1.0 - _intersection_x[i]); 93 6375029 : master_weights.push_back(_intersection_x[i]); 94 : masters_found = true; 95 6375029 : break; 96 : } 97 : } 98 : } 99 6980959 : return masters_found; 100 : } 101 : 102 : // TODO: Saving because I don't want to throw it away, but it needs more work to be used. 103 : // bool 104 : // EFAEdge::operator < (const edge_t & other) const 105 : //{ 106 : // node_t * this_min_node; 107 : // node_t * this_max_node; 108 : // node_t * other_min_node; 109 : // node_t * other_max_node; 110 : // 111 : // int this_node1_unique_index = ((int) edge_node1->category + 1) * edge_node1->id; 112 : // int this_node2_unique_index = ((int) edge_node2->category + 1) * edge_node2->id; 113 : // int other_node1_unique_index = ((int) other.edge_node1->category + 1) * edge_node1->id; 114 : // int other_node2_unique_index = ((int) other.edge_node2->category + 1) * edge_node2->id; 115 : // int this_min_index = std::min(this_node1_unique_index, this_node2_unique_index); 116 : // int other_min_index = std::min(other_node1_unique_index, other_node2_unique_index); 117 : // 118 : // if (this_min_index < other_min_index) 119 : // return true; 120 : // else if (this_min_index == other_min_index) 121 : // { 122 : // int this_max_index = std::max(this_node1_unique_index, this_node2_unique_index); 123 : // int other_max_index = std::max(other_node1_unique_index, other_node2_unique_index); 124 : // 125 : // if (this_max_index < other_max_index) 126 : // return true; 127 : // } 128 : // return false; 129 : //} 130 : 131 : void 132 20526 : EFAEdge::addIntersection(double position, EFANode * embedded_node_tmp, EFANode * from_node) 133 : { 134 20526 : _embedded_nodes.push_back(embedded_node_tmp); 135 20526 : if (from_node == _edge_node1) 136 20526 : _intersection_x.push_back(position); 137 0 : else if (from_node == _edge_node2) 138 0 : _intersection_x.push_back(1.0 - position); 139 : else 140 0 : EFAError("In addIntersection from_node does not exist on edge"); 141 20526 : } 142 : 143 : void 144 1036 : EFAEdge::resetIntersection(double position, EFANode * embedded_node_tmp, EFANode * from_node) 145 : { 146 1036 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 147 : { 148 1036 : if (_embedded_nodes[i] == embedded_node_tmp) 149 : { 150 1036 : if (from_node == _edge_node1) 151 1036 : _intersection_x[i] = position; 152 0 : else if (from_node == _edge_node2) 153 0 : _intersection_x[i] = 1.0 - position; 154 : else 155 0 : EFAError("In resetIntersection from_node does not exist on edge"); 156 : break; 157 : } 158 : } 159 1036 : } 160 : 161 : void 162 148621 : EFAEdge::copyIntersection(const EFAEdge & other, unsigned int from_node_id) 163 : { 164 148621 : _embedded_nodes.clear(); 165 148621 : _intersection_x.clear(); 166 148621 : _embedded_nodes = other._embedded_nodes; 167 148621 : if (from_node_id == 0) 168 148621 : _intersection_x = other._intersection_x; 169 0 : else if (from_node_id == 1) 170 : { 171 0 : for (unsigned int i = 0; i < other.numEmbeddedNodes(); ++i) 172 0 : _intersection_x.push_back(1.0 - other._intersection_x[i]); 173 : } 174 : else 175 0 : EFAError("from_node_id out of bounds"); 176 148621 : if (_embedded_nodes.size() != _intersection_x.size()) 177 0 : EFAError("in copyIntersection num emb_nodes must == num of inters_x"); 178 148621 : } 179 : 180 : EFANode * 181 18248025 : EFAEdge::getNode(unsigned int index) const 182 : { 183 18248025 : if (index == 0) 184 9788451 : return _edge_node1; 185 8459574 : else if (index == 1) 186 8459574 : return _edge_node2; 187 : else 188 0 : EFAError("In getNode index out of bounds"); 189 : } 190 : 191 : void 192 8752 : EFAEdge::reverseNodes() 193 : { 194 : std::swap(_edge_node1, _edge_node2); 195 8752 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 196 0 : _intersection_x[i] = 1.0 - _intersection_x[i]; 197 8752 : } 198 : 199 : bool 200 3284734 : EFAEdge::hasIntersection() const 201 : { 202 : bool has = false; 203 3284734 : if (_edge_node1->parent() != nullptr) 204 63178 : has = has || _edge_node1->parent()->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT; 205 : 206 3284734 : if (_edge_node2->parent() != nullptr) 207 63362 : has = has || _edge_node2->parent()->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT; 208 : 209 3284206 : return has || _embedded_nodes.size() > 0; 210 : } 211 : 212 : bool 213 206547 : EFAEdge::hasIntersectionAtPosition(double position, EFANode * from_node) const 214 : { 215 : bool has_int = false; 216 206547 : if (hasIntersection()) 217 : { 218 : double tmp_intersection_x = -1.0; 219 181718 : if (from_node == _edge_node1) 220 : tmp_intersection_x = position; 221 3666 : else if (from_node == _edge_node2) 222 3666 : tmp_intersection_x = 1.0 - position; 223 : else 224 0 : EFAError("In hasIntersectionAtPosition from_node does not exist on edge"); 225 : 226 181958 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 227 : { 228 181742 : if (std::abs(tmp_intersection_x - _intersection_x[i]) < Xfem::tol) 229 : { 230 : has_int = true; 231 : break; 232 : } 233 : } 234 : } 235 206547 : return has_int; 236 : } 237 : 238 : double 239 1100 : EFAEdge::getIntersection(unsigned int emb_id, EFANode * from_node) const 240 : { 241 1100 : if (from_node == _edge_node1) 242 1100 : return _intersection_x[emb_id]; 243 0 : else if (from_node == _edge_node2) 244 0 : return 1.0 - _intersection_x[emb_id]; 245 : else 246 0 : EFAError("In getIntersection node not in edge"); 247 : } 248 : 249 : double 250 8606 : EFAEdge::distanceFromNode1(EFANode * node) const 251 : { 252 : double xi = -100.0; 253 8606 : if (_edge_node1 == node) 254 : xi = 0.0; 255 6107 : else if (_edge_node2 == node) 256 : xi = 1.0; 257 2632 : else if (isEmbeddedNode(node)) 258 : { 259 2632 : unsigned int embedded_node_id = getEmbeddedNodeIndex(node); 260 2632 : xi = _intersection_x[embedded_node_id]; 261 : } 262 : else 263 0 : EFAError("the given node is not found in the current edge"); 264 8606 : return xi; 265 : } 266 : 267 : bool 268 257227687 : EFAEdge::isEmbeddedNode(const EFANode * node) const 269 : { 270 : bool is_emb = false; 271 325594780 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 272 : { 273 101343012 : if (_embedded_nodes[i] == node) 274 : { 275 : is_emb = true; 276 : break; 277 : } 278 : } 279 257227687 : return is_emb; 280 : } 281 : 282 : unsigned int 283 2632 : EFAEdge::getEmbeddedNodeIndex(EFANode * node) const 284 : { 285 : unsigned int index; 286 : bool have_index = false; 287 2632 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 288 : { 289 2632 : if (_embedded_nodes[i] == node) 290 : { 291 : have_index = true; 292 : index = i; 293 : break; 294 : } 295 : } 296 2632 : if (!have_index) 297 0 : EFAError("In getEmbeddedNodeIndex, could not find index"); 298 2632 : return index; 299 : } 300 : 301 : unsigned int 302 181086 : EFAEdge::getEmbeddedNodeIndex(double position, EFANode * from_node) const 303 : { 304 : bool have_index = false; 305 : unsigned int index; 306 181086 : if (hasIntersection()) 307 : { 308 : double tmp_intersection_x = -1.0; // dist from edge_node1 309 181086 : if (from_node == _edge_node1) 310 : tmp_intersection_x = position; 311 3666 : else if (from_node == _edge_node2) 312 3666 : tmp_intersection_x = 1.0 - position; 313 : else 314 0 : EFAError("In getEmbeddedNodeIndex, from_node does not exist on edge"); 315 : 316 181110 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 317 : { 318 181110 : if (std::abs(tmp_intersection_x - _intersection_x[i]) < Xfem::tol) 319 : { 320 : have_index = true; 321 : index = i; 322 : break; 323 : } 324 : } 325 : } 326 181086 : if (!have_index) 327 0 : EFAError("In getEmbeddedNodeIndex, could not find index"); 328 181086 : return index; 329 : } 330 : 331 : EFANode * 332 260199 : EFAEdge::getEmbeddedNode(unsigned int index) const 333 : { 334 260199 : if (index < _embedded_nodes.size()) 335 260199 : return _embedded_nodes[index]; 336 : else 337 0 : EFAError("in getEmbeddedNode index out of bounds"); 338 : } 339 : 340 : unsigned int 341 479653 : EFAEdge::numEmbeddedNodes() const 342 : { 343 479653 : return _embedded_nodes.size(); 344 : } 345 : 346 : void 347 4263793 : EFAEdge::consistencyCheck() 348 : { 349 : bool consistent = true; 350 4727957 : if ((_edge_node1->category() == EFANode::N_CATEGORY_PERMANENT || 351 8103021 : _edge_node1->category() == EFANode::N_CATEGORY_TEMP) && 352 3839228 : _edge_node2->category() == EFANode::N_CATEGORY_LOCAL_INDEX) 353 : consistent = false; 354 4727957 : else if ((_edge_node2->category() == EFANode::N_CATEGORY_PERMANENT || 355 8103021 : _edge_node2->category() == EFANode::N_CATEGORY_TEMP) && 356 3839228 : _edge_node1->category() == EFANode::N_CATEGORY_LOCAL_INDEX) 357 : consistent = false; 358 : if (!consistent) 359 0 : EFAError("In consistencyCheck nodes on edge are not consistent"); 360 4263793 : if (_embedded_nodes.size() != _intersection_x.size()) 361 0 : EFAError("In consistencyCheck num of emb_nodes must be = num of inters_x"); 362 4263793 : } 363 : 364 : void 365 3365705 : EFAEdge::switchNode(EFANode * new_node, EFANode * old_node) 366 : { 367 3365705 : if (_edge_node1 == old_node) 368 301386 : _edge_node1 = new_node; 369 3064319 : else if (_edge_node2 == old_node) 370 301386 : _edge_node2 = new_node; 371 2762933 : else if (isEmbeddedNode(old_node)) 372 : { 373 0 : unsigned int id = getEmbeddedNodeIndex(old_node); 374 0 : _embedded_nodes[id] = new_node; 375 : } 376 3365705 : } 377 : 378 : bool 379 288676855 : EFAEdge::containsNode(const EFANode * node) const 380 : { 381 288676855 : return _edge_node1 == node || _edge_node2 == node || isEmbeddedNode(node); 382 : } 383 : 384 : void 385 72 : EFAEdge::removeEmbeddedNodes() 386 : { 387 72 : _embedded_nodes.clear(); 388 72 : _intersection_x.clear(); 389 72 : } 390 : 391 : void 392 79 : EFAEdge::removeEmbeddedNode(EFANode * node) 393 : { 394 : unsigned int index = 0; 395 : bool node_found = false; 396 79 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 397 : { 398 79 : if (_embedded_nodes[i] == node) 399 : { 400 : index = i; 401 : node_found = true; 402 : break; 403 : } 404 : } 405 79 : if (node_found) 406 : { 407 79 : _embedded_nodes.erase(_embedded_nodes.begin() + index); 408 79 : _intersection_x.erase(_intersection_x.begin() + index); 409 : } 410 79 : }