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 3917529 : EFAEdge::EFAEdge(EFANode * node1, EFANode * node2) : _edge_node1(node1), _edge_node2(node2) 17 : { 18 3917529 : _embedded_nodes.clear(); 19 3917529 : _intersection_x.clear(); 20 3917529 : _edge_interior_node = nullptr; 21 3917529 : consistencyCheck(); 22 3917529 : } 23 : 24 2646120 : EFAEdge::EFAEdge(const EFAEdge & other_edge) 25 : { 26 2646120 : _edge_node1 = other_edge._edge_node1; 27 2646120 : _edge_node2 = other_edge._edge_node2; 28 2646120 : _intersection_x = other_edge._intersection_x; 29 2646120 : _embedded_nodes = other_edge._embedded_nodes; 30 2646120 : consistencyCheck(); 31 2646120 : } 32 : 33 6562849 : EFAEdge::~EFAEdge() // do not delete edge node - they will be deleted 34 : { // in EFAelement's destructor 35 6562849 : } 36 : 37 : bool 38 71442409 : EFAEdge::equivalent(const EFAEdge & other) const 39 : { 40 : if (getSortedNodes() == other.getSortedNodes()) 41 : { 42 : // For cut along the edge case 43 5788627 : if (isEmbeddedPermanent()) 44 : return false; 45 : return true; 46 : } 47 : 48 : return false; 49 : } 50 : 51 : bool 52 24755827 : EFAEdge::isEmbeddedPermanent() const 53 : { 54 24755915 : 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 29076140 : EFAEdge::containsEdge(const EFAEdge & other) const 66 : { 67 29076140 : return containsNode(other._edge_node1) && containsNode(other._edge_node2); 68 : } 69 : 70 : bool 71 7664957 : EFAEdge::getNodeMasters(EFANode * node, 72 : std::vector<EFANode *> & master_nodes, 73 : std::vector<double> & master_weights) const 74 : { 75 7664957 : master_nodes.clear(); 76 7664957 : master_weights.clear(); 77 : bool masters_found = false; 78 7664957 : if (_edge_node1 == node || _edge_node2 == node) 79 : { 80 636104 : master_nodes.push_back(node); 81 636104 : master_weights.push_back(1.0); 82 636104 : masters_found = true; 83 : } 84 : else 85 : { 86 7030779 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 87 : { 88 7030779 : if (_embedded_nodes[i] == node) 89 : { 90 7028853 : master_nodes.push_back(_edge_node1); 91 7028853 : master_nodes.push_back(_edge_node2); 92 7028853 : master_weights.push_back(1.0 - _intersection_x[i]); 93 7028853 : master_weights.push_back(_intersection_x[i]); 94 : masters_found = true; 95 7028853 : break; 96 : } 97 : } 98 : } 99 7664957 : 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 21466 : EFAEdge::addIntersection(double position, EFANode * embedded_node_tmp, EFANode * from_node) 133 : { 134 21466 : _embedded_nodes.push_back(embedded_node_tmp); 135 21466 : if (from_node == _edge_node1) 136 21466 : _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 21466 : } 142 : 143 : void 144 1500 : EFAEdge::resetIntersection(double position, EFANode * embedded_node_tmp, EFANode * from_node) 145 : { 146 1500 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 147 : { 148 1500 : if (_embedded_nodes[i] == embedded_node_tmp) 149 : { 150 1500 : if (from_node == _edge_node1) 151 1500 : _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 1500 : } 160 : 161 : void 162 156821 : EFAEdge::copyIntersection(const EFAEdge & other, unsigned int from_node_id) 163 : { 164 156821 : _embedded_nodes.clear(); 165 156821 : _intersection_x.clear(); 166 156821 : _embedded_nodes = other._embedded_nodes; 167 156821 : if (from_node_id == 0) 168 156821 : _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 156821 : if (_embedded_nodes.size() != _intersection_x.size()) 177 0 : EFAError("in copyIntersection num emb_nodes must == num of inters_x"); 178 156821 : } 179 : 180 : EFANode * 181 30108134 : EFAEdge::getNode(unsigned int index) const 182 : { 183 30108134 : if (index == 0) 184 16080335 : return _edge_node1; 185 14027799 : else if (index == 1) 186 14027799 : return _edge_node2; 187 : else 188 0 : EFAError("In getNode index out of bounds"); 189 : } 190 : 191 : void 192 9072 : EFAEdge::reverseNodes() 193 : { 194 : std::swap(_edge_node1, _edge_node2); 195 9072 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 196 0 : _intersection_x[i] = 1.0 - _intersection_x[i]; 197 9072 : } 198 : 199 : bool 200 4214962 : EFAEdge::hasIntersection() const 201 : { 202 : bool has = false; 203 4214962 : if (_edge_node1->parent() != nullptr) 204 64814 : has = has || _edge_node1->parent()->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT; 205 : 206 4214962 : if (_edge_node2->parent() != nullptr) 207 65002 : has = has || _edge_node2->parent()->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT; 208 : 209 4214434 : return has || _embedded_nodes.size() > 0; 210 : } 211 : 212 : bool 213 219167 : EFAEdge::hasIntersectionAtPosition(double position, EFANode * from_node) const 214 : { 215 : bool has_int = false; 216 219167 : if (hasIntersection()) 217 : { 218 : double tmp_intersection_x = -1.0; 219 193630 : if (from_node == _edge_node1) 220 : tmp_intersection_x = position; 221 3794 : else if (from_node == _edge_node2) 222 3794 : tmp_intersection_x = 1.0 - position; 223 : else 224 0 : EFAError("In hasIntersectionAtPosition from_node does not exist on edge"); 225 : 226 193870 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 227 : { 228 193654 : if (std::abs(tmp_intersection_x - _intersection_x[i]) < Xfem::tol) 229 : { 230 : has_int = true; 231 : break; 232 : } 233 : } 234 : } 235 219167 : return has_int; 236 : } 237 : 238 : double 239 1580 : EFAEdge::getIntersection(unsigned int emb_id, EFANode * from_node) const 240 : { 241 1580 : if (from_node == _edge_node1) 242 1580 : 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 10118 : EFAEdge::distanceFromNode1(EFANode * node) const 251 : { 252 : double xi = -100.0; 253 10118 : if (_edge_node1 == node) 254 : xi = 0.0; 255 7331 : else if (_edge_node2 == node) 256 : xi = 1.0; 257 3104 : else if (isEmbeddedNode(node)) 258 : { 259 3104 : unsigned int embedded_node_id = getEmbeddedNodeIndex(node); 260 3104 : xi = _intersection_x[embedded_node_id]; 261 : } 262 : else 263 0 : EFAError("the given node is not found in the current edge"); 264 10118 : return xi; 265 : } 266 : 267 : bool 268 309745995 : EFAEdge::isEmbeddedNode(const EFANode * node) const 269 : { 270 : bool is_emb = false; 271 391275720 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 272 : { 273 118939068 : if (_embedded_nodes[i] == node) 274 : { 275 : is_emb = true; 276 : break; 277 : } 278 : } 279 309745995 : return is_emb; 280 : } 281 : 282 : unsigned int 283 3104 : EFAEdge::getEmbeddedNodeIndex(EFANode * node) const 284 : { 285 : unsigned int index; 286 : bool have_index = false; 287 3104 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 288 : { 289 3104 : if (_embedded_nodes[i] == node) 290 : { 291 : have_index = true; 292 : index = i; 293 : break; 294 : } 295 : } 296 3104 : if (!have_index) 297 0 : EFAError("In getEmbeddedNodeIndex, could not find index"); 298 3104 : return index; 299 : } 300 : 301 : unsigned int 302 193014 : EFAEdge::getEmbeddedNodeIndex(double position, EFANode * from_node) const 303 : { 304 : bool have_index = false; 305 : unsigned int index; 306 193014 : if (hasIntersection()) 307 : { 308 : double tmp_intersection_x = -1.0; // dist from edge_node1 309 193014 : if (from_node == _edge_node1) 310 : tmp_intersection_x = position; 311 3794 : else if (from_node == _edge_node2) 312 3794 : tmp_intersection_x = 1.0 - position; 313 : else 314 0 : EFAError("In getEmbeddedNodeIndex, from_node does not exist on edge"); 315 : 316 193038 : for (unsigned int i = 0; i < _embedded_nodes.size(); ++i) 317 : { 318 193038 : 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 193014 : if (!have_index) 327 0 : EFAError("In getEmbeddedNodeIndex, could not find index"); 328 193014 : return index; 329 : } 330 : 331 : EFANode * 332 275779 : EFAEdge::getEmbeddedNode(unsigned int index) const 333 : { 334 275779 : if (index < _embedded_nodes.size()) 335 275779 : return _embedded_nodes[index]; 336 : else 337 0 : EFAError("in getEmbeddedNode index out of bounds"); 338 : } 339 : 340 : unsigned int 341 506617 : EFAEdge::numEmbeddedNodes() const 342 : { 343 506617 : return _embedded_nodes.size(); 344 : } 345 : 346 : void 347 6563649 : EFAEdge::consistencyCheck() 348 : { 349 : bool consistent = true; 350 7057609 : if ((_edge_node1->category() == EFANode::N_CATEGORY_PERMANENT || 351 12674117 : _edge_node1->category() == EFANode::N_CATEGORY_TEMP) && 352 6110468 : _edge_node2->category() == EFANode::N_CATEGORY_LOCAL_INDEX) 353 : consistent = false; 354 7057609 : else if ((_edge_node2->category() == EFANode::N_CATEGORY_PERMANENT || 355 12674117 : _edge_node2->category() == EFANode::N_CATEGORY_TEMP) && 356 6110468 : _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 6563649 : if (_embedded_nodes.size() != _intersection_x.size()) 361 0 : EFAError("In consistencyCheck num of emb_nodes must be = num of inters_x"); 362 6563649 : } 363 : 364 : void 365 3466593 : EFAEdge::switchNode(EFANode * new_node, EFANode * old_node) 366 : { 367 3466593 : if (_edge_node1 == old_node) 368 319834 : _edge_node1 = new_node; 369 3146759 : else if (_edge_node2 == old_node) 370 319834 : _edge_node2 = new_node; 371 2826925 : else if (isEmbeddedNode(old_node)) 372 : { 373 0 : unsigned int id = getEmbeddedNodeIndex(old_node); 374 0 : _embedded_nodes[id] = new_node; 375 : } 376 3466593 : } 377 : 378 : bool 379 346109342 : EFAEdge::containsNode(const EFANode * node) const 380 : { 381 346109342 : 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 : }