1 // The libMesh Finite Element Library. 2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 4 // This library is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU Lesser General Public 6 // License as published by the Free Software Foundation; either 7 // version 2.1 of the License, or (at your option) any later version. 8 9 // This library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 // Lesser General Public License for more details. 13 14 // You should have received a copy of the GNU Lesser General Public 15 // License along with this library; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 18 #ifndef LIBMESH_MULTI_PREDICATES_H 19 #define LIBMESH_MULTI_PREDICATES_H 20 21 // Local includes 22 #include "libmesh/libmesh.h" // libMesh::invalid_uint 23 #include "libmesh/single_predicates.h" 24 25 // C++ includes 26 #include <vector> 27 28 namespace libMesh { 29 class Elem; 30 } 31 32 namespace libMesh 33 { 34 35 // Forward declarations 36 class BoundaryInfo; 37 38 /** 39 * This namespace defines several multi_predicates which are used by 40 * the element and node iterators. These classes are not in general 41 * used by the user, although they could be. 42 * 43 * \author John W. Peterson 44 * \date 2004 45 */ 46 namespace Predicates 47 { 48 49 // Empty place-holder base class for multi_predicates 50 struct multi_predicate {}; 51 52 53 // This class represents a generic combination of more than one predicate. 54 // It is meant to be derived from to actually be used. 55 template <typename T> 56 struct abstract_multi_predicate : multi_predicate 57 { 58 // virtual destructor. ~abstract_multi_predicateabstract_multi_predicate59 virtual ~abstract_multi_predicate() 60 { 61 // Clean-up vector 62 for (auto p : _predicates) 63 delete p; 64 } 65 66 // operator= (perform deep copy of entries in _predicates vector 67 abstract_multi_predicate & operator=(const abstract_multi_predicate & rhs) 68 { 69 // First clear out the predicates vector 70 for (auto p : _predicates) 71 delete p; 72 73 // Now copy over the information from the rhs. 74 this->deep_copy(rhs); 75 76 return *this; 77 } 78 79 // operator() checks all the predicates in the vector. operatorabstract_multi_predicate80 virtual bool operator()(const T & it) const 81 { 82 for (const auto pred : _predicates) 83 { 84 libmesh_assert (pred); 85 86 if (!(*pred)(it)) 87 return false; 88 } 89 90 return true; 91 } 92 93 protected: 94 // Do not instantiate the base class. abstract_multi_predicateabstract_multi_predicate95 abstract_multi_predicate() {} 96 97 // Copy constructor. abstract_multi_predicateabstract_multi_predicate98 abstract_multi_predicate(const abstract_multi_predicate & rhs) 99 { 100 this->deep_copy(rhs); 101 } 102 103 // The deep_copy function is used by both the op= and 104 // copy constructors. This function uses the default (empty) 105 // copy constructor for the predicate class. deep_copyabstract_multi_predicate106 void deep_copy(const abstract_multi_predicate & rhs) 107 { 108 for (auto p : rhs._predicates) 109 _predicates.push_back(p->clone()); 110 } 111 112 // Predicates to be evaluated. 113 std::vector<predicate<T> *> _predicates; 114 }; 115 116 117 118 /** 119 * Used to iterate over nullptr entries in a container. 120 */ 121 template <typename T> 122 struct IsNull : abstract_multi_predicate<T> 123 { 124 // Constructor, pushes back a single predicate IsNullIsNull125 IsNull() 126 { 127 this->_predicates.push_back(new is_null<T>); 128 } 129 }; 130 131 132 133 /** 134 * Used to iterate over non-nullptr entries in a container. 135 */ 136 template <typename T> 137 struct NotNull : abstract_multi_predicate<T> 138 { 139 // Constructor, pushes back a single predicate NotNullNotNull140 NotNull() 141 { 142 this->_predicates.push_back(new not_null<T>); 143 } 144 }; 145 146 147 148 /** 149 * Used to iterate over non-nullptr, active entries in a container. 150 */ 151 template <typename T> 152 struct Active : abstract_multi_predicate<T> 153 { 154 // Constructor, pushes back two single predicates ActiveActive155 Active() 156 { 157 this->_predicates.push_back(new not_null<T>); 158 this->_predicates.push_back(new active<T>); 159 } 160 }; 161 162 163 164 /** 165 * Used to iterate over non-nullptr, inactive entries in a container. 166 */ 167 template <typename T> 168 struct NotActive : abstract_multi_predicate<T> 169 { 170 // Constructor, pushes back two single predicates NotActiveNotActive171 NotActive() 172 { 173 this->_predicates.push_back(new not_null<T>); 174 this->_predicates.push_back(new not_active<T>); 175 } 176 }; 177 178 179 180 181 /** 182 * Used to iterate over non-nullptr, entries that have children (i.e. are 183 * ancestors) in a container. 184 */ 185 template <typename T> 186 struct Ancestor : abstract_multi_predicate<T> 187 { 188 // Constructor, pushes back two single predicates AncestorAncestor189 Ancestor() 190 { 191 this->_predicates.push_back(new not_null<T>); 192 this->_predicates.push_back(new ancestor<T>); 193 } 194 }; 195 196 197 198 199 /** 200 * Used to iterate over non-nullptr, entries that have no children (i.e. are not 201 * ancestors) in a container. 202 */ 203 template <typename T> 204 struct NotAncestor : abstract_multi_predicate<T> 205 { 206 // Constructor, pushes back two single predicates NotAncestorNotAncestor207 NotAncestor() 208 { 209 this->_predicates.push_back(new not_null<T>); 210 this->_predicates.push_back(new not_ancestor<T>); 211 } 212 }; 213 214 215 216 217 /** 218 * Used to iterate over non-nullptr, subactive entries (i.e. has no 219 * active children) in a container. 220 */ 221 template <typename T> 222 struct SubActive : abstract_multi_predicate<T> 223 { 224 // Constructor, pushes back two single predicates SubActiveSubActive225 SubActive() 226 { 227 this->_predicates.push_back(new not_null<T>); 228 this->_predicates.push_back(new subactive<T>); 229 } 230 }; 231 232 233 234 235 /** 236 * Used to iterate over non-nullptr, non-subactive entries (i.e. has one 237 * or more active children) in a container. 238 */ 239 template <typename T> 240 struct NotSubActive : abstract_multi_predicate<T> 241 { 242 // Constructor, pushes back two single predicates NotSubActiveNotSubActive243 NotSubActive() 244 { 245 this->_predicates.push_back(new not_null<T>); 246 this->_predicates.push_back(new not_subactive<T>); 247 } 248 }; 249 250 251 252 /** 253 * Used to iterate over non-nullptr, local entries (i.e. owned by the 254 * current processor) in a container. 255 */ 256 template <typename T> 257 struct Local : abstract_multi_predicate<T> 258 { 259 // Constructor, pushes back two single predicates LocalLocal260 Local(processor_id_type my_pid) 261 { 262 this->_predicates.push_back(new not_null<T>); 263 this->_predicates.push_back(new pid<T>(my_pid)); 264 } 265 }; 266 267 268 /** 269 * Used to iterate over non-nullptr, semi-local entries (i.e. are not 270 * subactive and have are owned by an attached processor) in a 271 * container. 272 * 273 * FIXME: This is not currently safe to use on adaptively-refined 274 * grids, it should be added back when Elem::is_semilocal() has been 275 * patched to not require the Elem to be active. 276 */ 277 // template <typename T> 278 // struct SemiLocal : abstract_multi_predicate<T> 279 // { 280 // // Constructor, pushes back two single predicates 281 // SemiLocal(processor_id_type my_pid) 282 // { 283 // this->_predicates.push_back(new not_null<T>); 284 // this->_predicates.push_back(new not_subactive<T>); 285 // this->_predicates.push_back(new semilocal_pid<T>(my_pid)); 286 // } 287 // }; 288 289 290 /** 291 * Used to iterate over non-nullptr, active, non sub-active, semi-local 292 * elements in a container. 293 */ 294 template <typename T> 295 struct ActiveSemiLocal : abstract_multi_predicate<T> 296 { 297 // Constructor, pushes back two single predicates ActiveSemiLocalActiveSemiLocal298 ActiveSemiLocal(processor_id_type my_pid) 299 { 300 this->_predicates.push_back(new not_null<T>); 301 this->_predicates.push_back(new active<T>); 302 this->_predicates.push_back(new not_subactive<T>); 303 this->_predicates.push_back(new semilocal_pid<T>(my_pid)); 304 } 305 }; 306 307 308 /** 309 * Used to iterate over non-nullptr, face-local entries (i.e. are not 310 * subactive and are on or have a neighbor on processor my_pid) in a 311 * container. 312 */ 313 template <typename T> 314 struct FaceLocal : abstract_multi_predicate<T> 315 { 316 // Constructor, pushes back two single predicates FaceLocalFaceLocal317 FaceLocal(processor_id_type my_pid) 318 { 319 this->_predicates.push_back(new not_null<T>); 320 this->_predicates.push_back(new not_subactive<T>); 321 this->_predicates.push_back(new facelocal_pid<T>(my_pid)); 322 } 323 }; 324 325 326 327 /** 328 * Used to iterate over non-nullptr, non-local entries in a 329 * container. 330 */ 331 template <typename T> 332 struct NotLocal : abstract_multi_predicate<T> 333 { 334 // Constructor, pushes back two single predicates NotLocalNotLocal335 NotLocal(processor_id_type my_pid) 336 { 337 this->_predicates.push_back(new not_null<T>); 338 this->_predicates.push_back(new not_pid<T>(my_pid)); 339 } 340 }; 341 342 343 /** 344 * Used to iterate over non-nullptr, active, non-local entries in a 345 * container. 346 */ 347 template <typename T> 348 struct ActiveNotLocal : abstract_multi_predicate<T> 349 { 350 // Constructor, pushes back two single predicates ActiveNotLocalActiveNotLocal351 ActiveNotLocal(processor_id_type my_pid) 352 { 353 this->_predicates.push_back(new not_null<T>); 354 this->_predicates.push_back(new active<T>); 355 this->_predicates.push_back(new not_pid<T>(my_pid)); 356 } 357 }; 358 359 360 /** 361 * Used to iterate over non-nullptr, elements of a given geometric type. 362 */ 363 template <typename T> 364 struct Type : abstract_multi_predicate<T> 365 { TypeType366 Type(ElemType type) 367 { 368 this->_predicates.push_back(new not_null<T>); 369 this->_predicates.push_back(new elem_type<T>(type)); 370 } 371 }; 372 373 374 375 /** 376 * Used to iterate over non-nullptr, active elements of a given geometric type. 377 */ 378 template <typename T> 379 struct ActiveType : abstract_multi_predicate<T> 380 { ActiveTypeActiveType381 ActiveType(ElemType type) 382 { 383 this->_predicates.push_back(new not_null<T>); 384 this->_predicates.push_back(new active<T>); 385 this->_predicates.push_back(new elem_type<T>(type)); 386 } 387 }; 388 389 390 391 #ifdef LIBMESH_ENABLE_AMR 392 /** 393 * Used to iterate over non-nullptr, elements with a given refinement 394 * flag. 395 */ 396 template <typename T> 397 struct Flagged : abstract_multi_predicate<T> 398 { FlaggedFlagged399 Flagged(unsigned char rflag) 400 { 401 this->_predicates.push_back(new not_null<T>); 402 this->_predicates.push_back(new flagged<T>(rflag)); 403 } 404 }; 405 406 407 408 /** 409 * Used to iterate over non-nullptr, elements with a given refinement 410 * flag belonging to a given processor. 411 */ 412 template <typename T> 413 struct FlaggedPID : abstract_multi_predicate<T> 414 { FlaggedPIDFlaggedPID415 FlaggedPID(unsigned char rflag, processor_id_type proc_id) 416 { 417 this->_predicates.push_back(new not_null<T>); 418 this->_predicates.push_back(new flagged<T>(rflag)); 419 this->_predicates.push_back(new pid<T>(proc_id)); 420 } 421 }; 422 423 #endif // LIBMESH_ENABLE_AMR 424 425 426 427 428 /** 429 * Used to iterate over non-nullptr, active elements owned by a given 430 * processor. 431 */ 432 template <typename T> 433 struct ActivePID : abstract_multi_predicate<T> 434 { ActivePIDActivePID435 ActivePID(processor_id_type proc_id) 436 { 437 this->_predicates.push_back(new not_null<T>); 438 this->_predicates.push_back(new active<T>); 439 this->_predicates.push_back(new pid<T>(proc_id)); 440 } 441 }; 442 443 444 445 446 447 /** 448 * Used to iterate over non-nullptr, active, local elements owned by a 449 * given processor. 450 */ 451 template <typename T> 452 struct ActiveLocal : abstract_multi_predicate<T> 453 { ActiveLocalActiveLocal454 ActiveLocal(processor_id_type my_pid) 455 { 456 this->_predicates.push_back(new not_null<T>); 457 this->_predicates.push_back(new active<T>); 458 this->_predicates.push_back(new pid<T>(my_pid)); 459 } 460 }; 461 462 463 464 465 466 /** 467 * Used to iterate over non-nullptr elements owned by a given processor. 468 */ 469 template <typename T> 470 struct PID : abstract_multi_predicate<T> 471 { PIDPID472 PID(processor_id_type proc_id) 473 { 474 this->_predicates.push_back(new not_null<T>); 475 this->_predicates.push_back(new pid<T>(proc_id)); 476 } 477 }; 478 479 480 481 /** 482 * Used to iterate over non-nullptr elements on the boundary with a given 483 * ID. 484 */ 485 template <typename T> 486 struct BID : abstract_multi_predicate<T> 487 { BIDBID488 BID(boundary_id_type bndry_id, const BoundaryInfo & bndry_info) 489 { 490 this->_predicates.push_back(new not_null<T>); 491 this->_predicates.push_back(new bid<T>(bndry_id, bndry_info)); 492 } 493 }; 494 495 496 497 /** 498 * Used to iterate over non-nullptr elements on the boundary. 499 */ 500 template <typename T> 501 struct BND : abstract_multi_predicate<T> 502 { BNDBND503 BND(const BoundaryInfo & bndry_info) 504 { 505 this->_predicates.push_back(new not_null<T>); 506 this->_predicates.push_back(new bnd<T>(bndry_info)); 507 } 508 }; 509 510 511 512 /** 513 * Used to iterate over non-nullptr elements *not* owned by a given 514 * processor. 515 */ 516 template <typename T> 517 struct NotPID : abstract_multi_predicate<T> 518 { NotPIDNotPID519 NotPID(processor_id_type proc_id) 520 { 521 this->_predicates.push_back(new not_null<T>); 522 this->_predicates.push_back(new not_pid<T>(proc_id)); 523 } 524 }; 525 526 527 528 /** 529 * Used to iterate over non-nullptr elements of a specified (refinement) level. 530 */ 531 template <typename T> 532 struct Level : abstract_multi_predicate<T> 533 { LevelLevel534 Level(unsigned int l) 535 { 536 this->_predicates.push_back(new not_null<T>); 537 this->_predicates.push_back(new level<T>(l)); 538 } 539 }; 540 541 542 543 /** 544 * Used to iterate over non-nullptr elements *not* of a specified 545 * (refinement) level. 546 */ 547 template <typename T> 548 struct NotLevel : abstract_multi_predicate<T> 549 { NotLevelNotLevel550 NotLevel(unsigned int l) 551 { 552 this->_predicates.push_back(new not_null<T>); 553 this->_predicates.push_back(new not_level<T>(l)); 554 } 555 }; 556 557 558 559 /** 560 * Used to iterate over non-nullptr local elements with a specified 561 * (refinement) level. 562 */ 563 template <typename T> 564 struct LocalLevel : abstract_multi_predicate<T> 565 { LocalLevelLocalLevel566 LocalLevel(processor_id_type my_pid, 567 unsigned int l) 568 { 569 this->_predicates.push_back(new not_null<T>); 570 this->_predicates.push_back(new pid<T>(my_pid)); 571 this->_predicates.push_back(new level<T>(l)); 572 } 573 }; 574 575 576 577 /** 578 * Used to iterate over non-nullptr local elements *not* of a specified 579 * (refinement) level. 580 */ 581 template <typename T> 582 struct LocalNotLevel : abstract_multi_predicate<T> 583 { LocalNotLevelLocalNotLevel584 LocalNotLevel(processor_id_type my_pid, 585 unsigned int l) 586 { 587 this->_predicates.push_back(new not_null<T>); 588 this->_predicates.push_back(new pid<T>(my_pid)); 589 this->_predicates.push_back(new not_level<T>(l)); 590 } 591 }; 592 593 594 595 /** 596 * Used to iterate over non-nullptr, active elements which are on the 597 * boundary. 598 */ 599 template <typename T> 600 struct ActiveOnBoundary : abstract_multi_predicate<T> 601 { ActiveOnBoundaryActiveOnBoundary602 ActiveOnBoundary() 603 { 604 this->_predicates.push_back(new not_null<T>); 605 this->_predicates.push_back(new active<T>); 606 this->_predicates.push_back(new null_neighbor<T>); 607 } 608 }; 609 610 611 612 /** 613 * Used to iterate over the sides of an element which are on the 614 * boundary of the Mesh. 615 */ 616 template <typename T> 617 struct BoundarySide : abstract_multi_predicate<T> 618 { BoundarySideBoundarySide619 BoundarySide() 620 { 621 this->_predicates.push_back(new boundary_side<T>); 622 } 623 }; 624 625 626 627 /** 628 * Used to iterate over non-nullptr, active elements with a given PID on 629 * a given subdomain. 630 */ 631 template <typename T> 632 struct ActiveLocalSubdomain : abstract_multi_predicate<T> 633 { ActiveLocalSubdomainActiveLocalSubdomain634 ActiveLocalSubdomain(processor_id_type my_pid, 635 subdomain_id_type subdomain_id) 636 { 637 this->_predicates.push_back(new not_null<T>); 638 this->_predicates.push_back(new active<T>); 639 this->_predicates.push_back(new pid<T>(my_pid)); 640 this->_predicates.push_back(new subdomain<T>(subdomain_id)); 641 } 642 }; 643 644 645 646 /** 647 * Used to iterate over non-nullptr, active elements on a given 648 * subdomain. 649 */ 650 template <typename T> 651 struct ActiveSubdomain : abstract_multi_predicate<T> 652 { ActiveSubdomainActiveSubdomain653 ActiveSubdomain(subdomain_id_type subdomain_id) 654 { 655 this->_predicates.push_back(new not_null<T>); 656 this->_predicates.push_back(new active<T>); 657 this->_predicates.push_back(new subdomain<T>(subdomain_id)); 658 } 659 }; 660 661 662 663 /** 664 * Used to iterate over non-nullptr, active elements whose 665 * subdomains are in a user-specified set. 666 */ 667 template <typename T> 668 struct ActiveSubdomainSet : abstract_multi_predicate<T> 669 { ActiveSubdomainSetActiveSubdomainSet670 ActiveSubdomainSet(std::set<subdomain_id_type> sset) 671 { 672 this->_predicates.push_back(new not_null<T>); 673 this->_predicates.push_back(new active<T>); 674 this->_predicates.push_back(new subdomain_set<T>(sset)); 675 } 676 }; 677 678 679 680 /** 681 * Used to iterate over non-nullptr elements not owned by a given 682 * processor but semi-local to that processor, i.e. ghost elements. 683 */ 684 template <typename T> 685 struct Ghost : abstract_multi_predicate<T> 686 { GhostGhost687 Ghost(processor_id_type my_pid) 688 { 689 this->_predicates.push_back(new not_null<T>); 690 this->_predicates.push_back(new active<T>); 691 this->_predicates.push_back(new not_pid<T>(my_pid)); 692 this->_predicates.push_back(new semilocal_pid<T>(my_pid)); 693 } 694 }; 695 696 697 698 /** 699 * Used to iterate over elements where solutions indexed by a given 700 * DofMap are evaluable for a given variable var_num. 701 */ 702 template <typename T> 703 struct Evaluable: abstract_multi_predicate<T> 704 { 705 Evaluable(const DofMap & dof_map, 706 unsigned int var_num = libMesh::invalid_uint) 707 { 708 this->_predicates.push_back(new not_null<T>); 709 this->_predicates.push_back(new active<T>); 710 this->_predicates.push_back(new evaluable<T>(dof_map, var_num)); 711 } 712 }; 713 714 } 715 716 717 } // namespace libMesh 718 719 #endif // LIBMESH_MULTI_PREDICATES_H 720