Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 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 : #include <memory>
28 : #include <iterator> // std::make_move_iterator
29 : #include <initializer_list> // std::initializer_list
30 :
31 : namespace libMesh {
32 : class Elem;
33 : }
34 :
35 : namespace libMesh
36 : {
37 :
38 : // Forward declarations
39 : class BoundaryInfo;
40 :
41 : /**
42 : * This namespace defines several multi_predicates which are used by
43 : * the element and node iterators. These classes are not in general
44 : * used by the user, although they could be.
45 : *
46 : * \author John W. Peterson
47 : * \date 2004
48 : */
49 : namespace Predicates
50 : {
51 :
52 : // Empty place-holder base class for multi_predicates
53 : struct multi_predicate {};
54 :
55 : // Alias declaration for the predicate pointer we use
56 : template <typename T>
57 : using pred_ptr = std::unique_ptr<predicate<T>>;
58 :
59 : // This class represents a generic combination of more than one predicate.
60 : // It is meant to be derived from to actually be used.
61 : template <typename T>
62 : struct abstract_multi_predicate : multi_predicate
63 : {
64 : // virtual destructor.
65 351826531 : virtual ~abstract_multi_predicate() = default;
66 :
67 : // operator= (perform deep copy of entries in _predicates vector
68 : abstract_multi_predicate & operator=(const abstract_multi_predicate & rhs)
69 : {
70 : // Copy over the information from the rhs.
71 : this->deep_copy(rhs);
72 :
73 : return *this;
74 : }
75 :
76 : // operator() checks all the predicates in the vector.
77 6152883316 : virtual bool operator()(const T & it) const
78 : {
79 14646143558 : for (const auto & pred : _predicates)
80 : {
81 485034945 : libmesh_assert (pred);
82 :
83 11696084431 : if (!(*pred)(it))
84 92934021 : return false;
85 : }
86 :
87 183112267 : return true;
88 : }
89 :
90 : protected:
91 : // Do not instantiate the base class.
92 : abstract_multi_predicate() = default;
93 :
94 : // Construct from a vector of single predicates
95 84169039 : abstract_multi_predicate(std::vector<pred_ptr<T>> && predicates)
96 84169039 : : _predicates(std::move(predicates))
97 2526464 : {}
98 :
99 : // Copy constructor.
100 267657492 : abstract_multi_predicate(const abstract_multi_predicate & rhs)
101 267657492 : {
102 267657492 : this->deep_copy(rhs);
103 267657492 : }
104 :
105 : // The deep_copy function is used by both the op= and
106 : // copy constructors. This function uses the default (empty)
107 : // copy constructor for the predicate class.
108 267657492 : void deep_copy(const abstract_multi_predicate & rhs)
109 : {
110 : // First clear out the predicates vector
111 267657492 : _predicates.clear();
112 :
113 751450755 : for (const auto & p : rhs._predicates)
114 953768416 : _predicates.push_back(p->clone());
115 267657492 : }
116 :
117 : // Predicates to be evaluated.
118 : std::vector<pred_ptr<T>> _predicates;
119 : };
120 :
121 : /**
122 : * Helper object for creating a std::vector from a std::initializer_list
123 : * https://stackoverflow.com/questions/46737054/vectorunique-ptra-using-initialization-list
124 : */
125 : template<class T>
126 151436346 : struct movable_il
127 : {
128 : /**
129 : * Construct from rvalue reference of type T
130 : */
131 : movable_il(T && in) : t(std::move(in)) {}
132 :
133 : /**
134 : * Construct from rvalue reference of type U, using forwarding
135 : */
136 : template <typename U>
137 3753314 : movable_il(U && in): t(std::forward<U>(in)) {}
138 :
139 : /**
140 : * Return an rvalue reference to ourself
141 : */
142 3753314 : operator T() const&& { return std::move(t); }
143 :
144 : mutable T t;
145 : };
146 :
147 : /**
148 : * Helper function that creates a std::vector from an initializer_list of movable_il objects
149 : */
150 : template<class T>
151 82347093 : std::vector<T> make_vec( std::initializer_list< movable_il<T> > il )
152 : {
153 84169039 : std::vector<T> r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
154 82347093 : return r;
155 : }
156 :
157 :
158 : /**
159 : * Used to iterate over nullptr entries in a container.
160 : */
161 : template <typename T>
162 : struct IsNull : abstract_multi_predicate<T>
163 : {
164 : IsNull() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
165 : {
166 : std::make_unique<is_null<T>>()
167 : })) {}
168 : };
169 :
170 :
171 :
172 : /**
173 : * Used to iterate over non-nullptr entries in a container.
174 : */
175 : template <typename T>
176 109996647 : struct NotNull : abstract_multi_predicate<T>
177 : {
178 51702114 : NotNull() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
179 : {
180 : std::make_unique<not_null<T>>()
181 52775128 : })) {}
182 : };
183 :
184 :
185 :
186 : /**
187 : * Used to iterate over non-nullptr, active entries in a container.
188 : */
189 : template <typename T>
190 43725588 : struct Active : abstract_multi_predicate<T>
191 : {
192 29016450 : Active() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
193 : {
194 : std::make_unique<not_null<T>>(),
195 : std::make_unique<active<T>>()
196 29451006 : })) {}
197 : };
198 :
199 :
200 :
201 : /**
202 : * Used to iterate over non-nullptr, inactive entries in a container.
203 : */
204 : template <typename T>
205 0 : struct NotActive : abstract_multi_predicate<T>
206 : {
207 0 : NotActive() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
208 : {
209 : std::make_unique<not_null<T>>(),
210 : std::make_unique<not_active<T>>()
211 0 : })) {}
212 : };
213 :
214 :
215 :
216 :
217 : /**
218 : * Used to iterate over non-nullptr, entries that have children (i.e. are
219 : * ancestors) in a container.
220 : */
221 : template <typename T>
222 1243300 : struct Ancestor : abstract_multi_predicate<T>
223 : {
224 759044 : Ancestor() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
225 : {
226 : std::make_unique<not_null<T>>(),
227 : std::make_unique<ancestor<T>>()
228 765564 : })) {}
229 : };
230 :
231 :
232 :
233 :
234 : /**
235 : * Used to iterate over non-nullptr, entries that have no children (i.e. are not
236 : * ancestors) in a container.
237 : */
238 : template <typename T>
239 0 : struct NotAncestor : abstract_multi_predicate<T>
240 : {
241 0 : NotAncestor() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
242 : {
243 : std::make_unique<not_null<T>>(),
244 : std::make_unique<not_ancestor<T>>()
245 0 : })) {}
246 : };
247 :
248 :
249 :
250 :
251 : /**
252 : * Used to iterate over non-nullptr, subactive entries (i.e. has no
253 : * active children) in a container.
254 : */
255 : template <typename T>
256 0 : struct SubActive : abstract_multi_predicate<T>
257 : {
258 0 : SubActive() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
259 : {
260 : std::make_unique<not_null<T>>(),
261 : std::make_unique<subactive<T>>()
262 0 : })) {}
263 : };
264 :
265 :
266 :
267 :
268 : /**
269 : * Used to iterate over non-nullptr, non-subactive entries (i.e. has one
270 : * or more active children) in a container.
271 : */
272 : template <typename T>
273 0 : struct NotSubActive : abstract_multi_predicate<T>
274 : {
275 0 : NotSubActive() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
276 : {
277 : std::make_unique<not_null<T>>(),
278 : std::make_unique<not_subactive<T>>()
279 0 : })) {}
280 : };
281 :
282 :
283 :
284 : /**
285 : * Used to iterate over non-nullptr, local entries (i.e. owned by the
286 : * current processor) in a container.
287 : */
288 : template <typename T>
289 29987905 : struct Local : abstract_multi_predicate<T>
290 : {
291 24752409 : Local(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
292 : {
293 : std::make_unique<not_null<T>>(),
294 : std::make_unique<pid<T>>(my_pid)
295 25073829 : })) {}
296 : };
297 :
298 :
299 : /**
300 : * Used to iterate over non-nullptr, semi-local entries (i.e. are not
301 : * subactive and have are owned by an attached processor) in a
302 : * container.
303 : *
304 : * FIXME: This is not currently safe to use on adaptively-refined
305 : * grids, it should be added back when Elem::is_semilocal() has been
306 : * patched to not require the Elem to be active.
307 : */
308 : // template <typename T>
309 : // struct SemiLocal : abstract_multi_predicate<T>
310 : // {
311 : // SemiLocal(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
312 : // {
313 : // std::make_unique<not_null<T>>(),
314 : // std::make_unique<not_subactive<T>>(),
315 : // std::make_unique<semilocal_pid<T>>(my_pid)
316 : // })) {}
317 : // };
318 :
319 :
320 : /**
321 : * Used to iterate over non-nullptr, active, non sub-active, semi-local
322 : * elements in a container.
323 : */
324 : template <typename T>
325 0 : struct ActiveSemiLocal : abstract_multi_predicate<T>
326 : {
327 0 : ActiveSemiLocal(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
328 : {
329 : std::make_unique<not_null<T>>(),
330 : std::make_unique<active<T>>(),
331 : std::make_unique<not_subactive<T>>(),
332 : std::make_unique<semilocal_pid<T>>(my_pid),
333 0 : })) {}
334 : };
335 :
336 :
337 : /**
338 : * Used to iterate over non-nullptr, face-local entries (i.e. are not
339 : * subactive and are on or have a neighbor on processor my_pid) in a
340 : * container.
341 : */
342 : template <typename T>
343 0 : struct FaceLocal : abstract_multi_predicate<T>
344 : {
345 0 : FaceLocal(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
346 : {
347 : std::make_unique<not_null<T>>(),
348 : std::make_unique<not_subactive<T>>(),
349 : std::make_unique<facelocal_pid<T>>(my_pid)
350 0 : })) {}
351 : };
352 :
353 :
354 :
355 : /**
356 : * Used to iterate over non-nullptr, non-local entries in a
357 : * container.
358 : */
359 : template <typename T>
360 568276 : struct NotLocal : abstract_multi_predicate<T>
361 : {
362 310880 : NotLocal(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
363 : {
364 : std::make_unique<not_null<T>>(),
365 : std::make_unique<not_pid<T>>(my_pid)
366 311064 : })) {}
367 : };
368 :
369 :
370 : /**
371 : * Used to iterate over non-nullptr, active, non-local entries in a
372 : * container.
373 : */
374 : template <typename T>
375 882860 : struct ActiveNotLocal : abstract_multi_predicate<T>
376 : {
377 714280 : ActiveNotLocal(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
378 : {
379 : std::make_unique<not_null<T>>(),
380 : std::make_unique<active<T>>(),
381 : std::make_unique<not_pid<T>>(my_pid)
382 727600 : })) {}
383 : };
384 :
385 :
386 : /**
387 : * Used to iterate over non-nullptr, elements of a given geometric type.
388 : */
389 : template <typename T>
390 0 : struct Type : abstract_multi_predicate<T>
391 : {
392 0 : Type(ElemType type) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
393 : {
394 : std::make_unique<not_null<T>>(),
395 : std::make_unique<elem_type<T>>(type)
396 0 : })) {}
397 : };
398 :
399 :
400 :
401 : /**
402 : * Used to iterate over non-nullptr, active elements of a given geometric type.
403 : */
404 : template <typename T>
405 0 : struct ActiveType : abstract_multi_predicate<T>
406 : {
407 0 : ActiveType(ElemType type) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
408 : {
409 : std::make_unique<not_null<T>>(),
410 : std::make_unique<active<T>>(),
411 : std::make_unique<elem_type<T>>(type)
412 0 : })) {}
413 : };
414 :
415 :
416 :
417 : #ifdef LIBMESH_ENABLE_AMR
418 : /**
419 : * Used to iterate over non-nullptr, elements with a given refinement
420 : * flag.
421 : */
422 : template <typename T>
423 0 : struct Flagged : abstract_multi_predicate<T>
424 : {
425 0 : Flagged(unsigned char rflag) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
426 : {
427 : std::make_unique<not_null<T>>(),
428 : std::make_unique<flagged<T>>(rflag)
429 0 : })) {}
430 : };
431 :
432 :
433 :
434 : /**
435 : * Used to iterate over non-nullptr, elements with a given refinement
436 : * flag belonging to a given processor.
437 : */
438 : template <typename T>
439 11592 : struct FlaggedPID : abstract_multi_predicate<T>
440 : {
441 9288 : FlaggedPID(unsigned char rflag, processor_id_type proc_id) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
442 : {
443 : std::make_unique<not_null<T>>(),
444 : std::make_unique<flagged<T>>(rflag),
445 : std::make_unique<pid<T>>(proc_id)
446 9312 : })) {}
447 : };
448 :
449 : #endif // LIBMESH_ENABLE_AMR
450 :
451 :
452 :
453 :
454 : /**
455 : * Used to iterate over non-nullptr, active elements owned by a given
456 : * processor.
457 : */
458 : template <typename T>
459 21917298 : struct ActivePID : abstract_multi_predicate<T>
460 : {
461 20279336 : ActivePID(processor_id_type proc_id) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
462 : {
463 : std::make_unique<not_null<T>>(),
464 : std::make_unique<active<T>>(),
465 : std::make_unique<pid<T>>(proc_id)
466 20304272 : })) {}
467 : };
468 :
469 :
470 :
471 :
472 :
473 : /**
474 : * Used to iterate over non-nullptr, active, local elements owned by a
475 : * given processor.
476 : */
477 : template <typename T>
478 29649828 : struct ActiveLocal : abstract_multi_predicate<T>
479 : {
480 31378482 : ActiveLocal(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
481 : {
482 : std::make_unique<not_null<T>>(),
483 : std::make_unique<active<T>>(),
484 : std::make_unique<pid<T>>(my_pid)
485 31809504 : })) {}
486 : };
487 :
488 :
489 :
490 :
491 :
492 : /**
493 : * Used to iterate over non-nullptr elements owned by a given processor.
494 : */
495 : template <typename T>
496 83012948 : struct PID : abstract_multi_predicate<T>
497 : {
498 67077526 : PID(processor_id_type proc_id) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
499 : {
500 : std::make_unique<not_null<T>>(),
501 : std::make_unique<pid<T>>(proc_id)
502 67376442 : })) {}
503 : };
504 :
505 :
506 :
507 : /**
508 : * Used to iterate over non-nullptr elements on the boundary with a given
509 : * ID.
510 : */
511 : template <typename T>
512 0 : struct BID : abstract_multi_predicate<T>
513 : {
514 0 : BID(boundary_id_type bndry_id, const BoundaryInfo & bndry_info) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
515 : {
516 : std::make_unique<not_null<T>>(),
517 : std::make_unique<bid<T>>(bndry_id, bndry_info)
518 0 : })) {}
519 : };
520 :
521 :
522 :
523 : /**
524 : * Used to iterate over non-nullptr elements on the boundary.
525 : */
526 : template <typename T>
527 0 : struct BND : abstract_multi_predicate<T>
528 : {
529 0 : BND(const BoundaryInfo & bndry_info) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
530 : {
531 : std::make_unique<not_null<T>>(),
532 : std::make_unique<bnd<T>>(bndry_info)
533 0 : })) {}
534 : };
535 :
536 :
537 :
538 : /**
539 : * Used to iterate over non-nullptr elements *not* owned by a given
540 : * processor.
541 : */
542 : template <typename T>
543 : struct NotPID : abstract_multi_predicate<T>
544 : {
545 : NotPID(processor_id_type proc_id) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
546 : {
547 : std::make_unique<not_null<T>>(),
548 : std::make_unique<not_pid<T>>(proc_id)
549 : })) {}
550 : };
551 :
552 :
553 :
554 : /**
555 : * Used to iterate over non-nullptr elements of a specified (refinement) level.
556 : */
557 : template <typename T>
558 16948110 : struct Level : abstract_multi_predicate<T>
559 : {
560 10531574 : Level(unsigned int l) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
561 : {
562 : std::make_unique<not_null<T>>(),
563 : std::make_unique<level<T>>(l)
564 10652862 : })) {}
565 : };
566 :
567 :
568 :
569 : /**
570 : * Used to iterate over non-nullptr elements *not* of a specified
571 : * (refinement) level.
572 : */
573 : template <typename T>
574 0 : struct NotLevel : abstract_multi_predicate<T>
575 : {
576 0 : NotLevel(unsigned int l) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
577 : {
578 : std::make_unique<not_null<T>>(),
579 : std::make_unique<not_level<T>>(l)
580 0 : })) {}
581 : };
582 :
583 :
584 :
585 : /**
586 : * Used to iterate over non-nullptr local elements with a specified
587 : * (refinement) level.
588 : */
589 : template <typename T>
590 75450 : struct LocalLevel : abstract_multi_predicate<T>
591 : {
592 16794 : LocalLevel(processor_id_type my_pid,
593 48762 : unsigned int l) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
594 : {
595 : std::make_unique<not_null<T>>(),
596 : std::make_unique<pid<T>>(my_pid),
597 : std::make_unique<level<T>>(l)
598 67176 : })) {}
599 : };
600 :
601 :
602 :
603 : /**
604 : * Used to iterate over non-nullptr local elements *not* of a specified
605 : * (refinement) level.
606 : */
607 : template <typename T>
608 0 : struct LocalNotLevel : abstract_multi_predicate<T>
609 : {
610 0 : LocalNotLevel(processor_id_type my_pid,
611 0 : unsigned int l) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
612 : {
613 : std::make_unique<not_null<T>>(),
614 : std::make_unique<pid<T>>(my_pid),
615 : std::make_unique<not_level<T>>(l)
616 0 : })) {}
617 : };
618 :
619 :
620 :
621 : /**
622 : * Used to iterate over non-nullptr, active elements which are on the
623 : * boundary.
624 : */
625 : template <typename T>
626 : struct ActiveOnBoundary : abstract_multi_predicate<T>
627 : {
628 : ActiveOnBoundary() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
629 : {
630 : std::make_unique<not_null<T>>(),
631 : std::make_unique<active<T>>(),
632 : std::make_unique<null_neighbor<T>>()
633 : })) {}
634 : };
635 :
636 :
637 :
638 : /**
639 : * Used to iterate over the sides of an element which are on the
640 : * boundary of the Mesh.
641 : */
642 : template <typename T>
643 0 : struct BoundarySide : abstract_multi_predicate<T>
644 : {
645 0 : BoundarySide() : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
646 : {
647 : std::make_unique<boundary_side<T>>()
648 0 : })) {}
649 : };
650 :
651 :
652 :
653 : /**
654 : * Used to iterate over non-nullptr, active elements with a given PID on
655 : * a given subdomain.
656 : */
657 : template <typename T>
658 4860 : struct ActiveLocalSubdomain : abstract_multi_predicate<T>
659 : {
660 1260 : ActiveLocalSubdomain(processor_id_type my_pid,
661 4896 : subdomain_id_type subdomain_id) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
662 : {
663 : std::make_unique<not_null<T>>(),
664 : std::make_unique<active<T>>(),
665 : std::make_unique<pid<T>>(my_pid),
666 : std::make_unique<subdomain<T>>(subdomain_id)
667 6300 : })) {}
668 : };
669 :
670 :
671 :
672 : /**
673 : * Used to iterate over non-nullptr, active elements on a given
674 : * subdomain.
675 : */
676 : template <typename T>
677 25020 : struct ActiveSubdomain : abstract_multi_predicate<T>
678 : {
679 23308 : ActiveSubdomain(subdomain_id_type subdomain_id) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
680 : {
681 : std::make_unique<not_null<T>>(),
682 : std::make_unique<active<T>>(),
683 : std::make_unique<subdomain<T>>(subdomain_id)
684 24664 : })) {}
685 : };
686 :
687 :
688 :
689 : /**
690 : * Used to iterate over non-nullptr, active elements whose
691 : * subdomains are in a user-specified set.
692 : */
693 : template <typename T>
694 0 : struct ActiveSubdomainSet : abstract_multi_predicate<T>
695 : {
696 0 : ActiveSubdomainSet(std::set<subdomain_id_type> sset) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
697 : {
698 : std::make_unique<not_null<T>>(),
699 : std::make_unique<active<T>>(),
700 : std::make_unique<subdomain_set<T>>(sset)
701 0 : })) {}
702 : };
703 :
704 :
705 :
706 : /**
707 : * Used to iterate over non-nullptr, active elements with a given PID
708 : * whose subdomains are in a user-specified set.
709 : */
710 : template <typename T>
711 0 : struct ActiveLocalSubdomainSet : abstract_multi_predicate<T>
712 : {
713 0 : ActiveLocalSubdomainSet(processor_id_type my_pid,
714 0 : std::set<subdomain_id_type> sset) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
715 : {
716 : std::make_unique<not_null<T>>(),
717 : std::make_unique<active<T>>(),
718 : std::make_unique<pid<T>>(my_pid),
719 : std::make_unique<subdomain_set<T>>(sset)
720 0 : })) {}
721 : };
722 :
723 :
724 :
725 :
726 :
727 :
728 : /**
729 : * Used to iterate over non-nullptr elements not owned by a given
730 : * processor but semi-local to that processor, i.e. ghost elements.
731 : */
732 : template <typename T>
733 0 : struct Ghost : abstract_multi_predicate<T>
734 : {
735 0 : Ghost(processor_id_type my_pid) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
736 : {
737 : std::make_unique<not_null<T>>(),
738 : std::make_unique<active<T>>(),
739 : std::make_unique<not_pid<T>>(my_pid),
740 : std::make_unique<semilocal_pid<T>>(my_pid)
741 0 : })) {}
742 : };
743 :
744 :
745 :
746 : /**
747 : * Used to iterate over elements where solutions indexed by a given
748 : * DofMap are evaluable for a given variable var_num.
749 : */
750 : template <typename T>
751 2460 : struct Evaluable: abstract_multi_predicate<T>
752 : {
753 852 : Evaluable(const DofMap & dof_map,
754 2484 : unsigned int var_num = libMesh::invalid_uint) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
755 : {
756 : std::make_unique<not_null<T>>(),
757 : std::make_unique<active<T>>(),
758 : std::make_unique<evaluable<T>>(dof_map, var_num)
759 3408 : })) {}
760 : };
761 :
762 :
763 :
764 : /**
765 : * Used to iterate over elements where solutions indexed by a given
766 : * vector of DofMaps are evaluable for all variables
767 : */
768 : template <typename T>
769 410 : struct MultiEvaluable: abstract_multi_predicate<T>
770 : {
771 556 : MultiEvaluable(const std::vector<const DofMap *> & dof_maps) : abstract_multi_predicate<T>(make_vec<pred_ptr<T>>(
772 : {
773 : std::make_unique<not_null<T>>(),
774 : std::make_unique<active<T>>(),
775 : std::make_unique<multi_evaluable<T>>(dof_maps)
776 572 : })) {}
777 : };
778 :
779 : }
780 :
781 :
782 : } // namespace libMesh
783 :
784 : #endif // LIBMESH_MULTI_PREDICATES_H
|