libMesh
multi_predicates.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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 
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>
63 {
64  // virtual destructor.
65  virtual ~abstract_multi_predicate() = default;
66 
67  // operator= (perform deep copy of entries in _predicates vector
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  virtual bool operator()(const T & it) const
78  {
79  for (const auto & pred : _predicates)
80  {
81  libmesh_assert (pred);
82 
83  if (!(*pred)(it))
84  return false;
85  }
86 
87  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  abstract_multi_predicate(std::vector<pred_ptr<T>> && predicates)
96  : _predicates(std::move(predicates))
97  {}
98 
99  // Copy constructor.
101  {
102  this->deep_copy(rhs);
103  }
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.
109  {
110  // First clear out the predicates vector
111  _predicates.clear();
112 
113  for (const auto & p : rhs._predicates)
114  _predicates.push_back(p->clone());
115  }
116 
117  // Predicates to be evaluated.
118  std::vector<pred_ptr<T>> _predicates;
119 };
120 
125 template<class T>
127 {
131  movable_il(T && in) : t(std::move(in)) {}
132 
136  template <typename U>
137  movable_il(U && in): t(std::forward<U>(in)) {}
138 
142  operator T() const&& { return std::move(t); }
143 
144  mutable T t;
145 };
146 
150 template<class T>
151 std::vector<T> make_vec( std::initializer_list< movable_il<T> > il )
152 {
153  std::vector<T> r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
154  return r;
155 }
156 
157 
161 template <typename T>
163 {
165  {
166  std::make_unique<is_null<T>>()
167  })) {}
168 };
169 
170 
171 
175 template <typename T>
177 {
179  {
180  std::make_unique<not_null<T>>()
181  })) {}
182 };
183 
184 
185 
189 template <typename T>
191 {
193  {
194  std::make_unique<not_null<T>>(),
195  std::make_unique<active<T>>()
196  })) {}
197 };
198 
199 
200 
204 template <typename T>
206 {
208  {
209  std::make_unique<not_null<T>>(),
210  std::make_unique<not_active<T>>()
211  })) {}
212 };
213 
214 
215 
216 
221 template <typename T>
223 {
225  {
226  std::make_unique<not_null<T>>(),
227  std::make_unique<ancestor<T>>()
228  })) {}
229 };
230 
231 
232 
233 
238 template <typename T>
240 {
242  {
243  std::make_unique<not_null<T>>(),
244  std::make_unique<not_ancestor<T>>()
245  })) {}
246 };
247 
248 
249 
250 
255 template <typename T>
257 {
259  {
260  std::make_unique<not_null<T>>(),
261  std::make_unique<subactive<T>>()
262  })) {}
263 };
264 
265 
266 
267 
272 template <typename T>
274 {
276  {
277  std::make_unique<not_null<T>>(),
278  std::make_unique<not_subactive<T>>()
279  })) {}
280 };
281 
282 
283 
288 template <typename T>
290 {
292  {
293  std::make_unique<not_null<T>>(),
294  std::make_unique<pid<T>>(my_pid)
295  })) {}
296 };
297 
298 
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 
324 template <typename T>
326 {
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  })) {}
334 };
335 
336 
342 template <typename T>
344 {
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  })) {}
351 };
352 
353 
354 
359 template <typename T>
361 {
363  {
364  std::make_unique<not_null<T>>(),
365  std::make_unique<not_pid<T>>(my_pid)
366  })) {}
367 };
368 
369 
374 template <typename T>
376 {
378  {
379  std::make_unique<not_null<T>>(),
380  std::make_unique<active<T>>(),
381  std::make_unique<not_pid<T>>(my_pid)
382  })) {}
383 };
384 
385 
389 template <typename T>
391 {
393  {
394  std::make_unique<not_null<T>>(),
395  std::make_unique<elem_type<T>>(type)
396  })) {}
397 };
398 
399 
400 
404 template <typename T>
406 {
408  {
409  std::make_unique<not_null<T>>(),
410  std::make_unique<active<T>>(),
411  std::make_unique<elem_type<T>>(type)
412  })) {}
413 };
414 
415 
416 
417 #ifdef LIBMESH_ENABLE_AMR
418 
422 template <typename T>
424 {
425  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  })) {}
430 };
431 
432 
433 
438 template <typename T>
440 {
442  {
443  std::make_unique<not_null<T>>(),
444  std::make_unique<flagged<T>>(rflag),
445  std::make_unique<pid<T>>(proc_id)
446  })) {}
447 };
448 
449 #endif // LIBMESH_ENABLE_AMR
450 
451 
452 
453 
458 template <typename T>
460 {
462  {
463  std::make_unique<not_null<T>>(),
464  std::make_unique<active<T>>(),
465  std::make_unique<pid<T>>(proc_id)
466  })) {}
467 };
468 
469 
470 
471 
472 
477 template <typename T>
479 {
481  {
482  std::make_unique<not_null<T>>(),
483  std::make_unique<active<T>>(),
484  std::make_unique<pid<T>>(my_pid)
485  })) {}
486 };
487 
488 
489 
490 
491 
495 template <typename T>
497 {
499  {
500  std::make_unique<not_null<T>>(),
501  std::make_unique<pid<T>>(proc_id)
502  })) {}
503 };
504 
505 
506 
511 template <typename T>
513 {
515  {
516  std::make_unique<not_null<T>>(),
517  std::make_unique<bid<T>>(bndry_id, bndry_info)
518  })) {}
519 };
520 
521 
522 
526 template <typename T>
528 {
530  {
531  std::make_unique<not_null<T>>(),
532  std::make_unique<bnd<T>>(bndry_info)
533  })) {}
534 };
535 
536 
537 
542 template <typename T>
544 {
546  {
547  std::make_unique<not_null<T>>(),
548  std::make_unique<not_pid<T>>(proc_id)
549  })) {}
550 };
551 
552 
553 
557 template <typename T>
559 {
561  {
562  std::make_unique<not_null<T>>(),
563  std::make_unique<level<T>>(l)
564  })) {}
565 };
566 
567 
568 
573 template <typename T>
575 {
577  {
578  std::make_unique<not_null<T>>(),
579  std::make_unique<not_level<T>>(l)
580  })) {}
581 };
582 
583 
584 
589 template <typename T>
591 {
593  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  })) {}
599 };
600 
601 
602 
607 template <typename T>
609 {
611  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  })) {}
617 };
618 
619 
620 
625 template <typename T>
627 {
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 
642 template <typename T>
644 {
646  {
647  std::make_unique<boundary_side<T>>()
648  })) {}
649 };
650 
651 
652 
657 template <typename T>
659 {
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  })) {}
668 };
669 
670 
671 
676 template <typename T>
678 {
680  {
681  std::make_unique<not_null<T>>(),
682  std::make_unique<active<T>>(),
683  std::make_unique<subdomain<T>>(subdomain_id)
684  })) {}
685 };
686 
687 
688 
693 template <typename T>
695 {
696  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  })) {}
702 };
703 
704 
705 
710 template <typename T>
712 {
714  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  })) {}
721 };
722 
723 
724 
725 
726 
727 
732 template <typename T>
734 {
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  })) {}
742 };
743 
744 
745 
750 template <typename T>
752 {
753  Evaluable(const DofMap & dof_map,
754  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  })) {}
760 };
761 
762 
763 
768 template <typename T>
770 {
771  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  })) {}
777 };
778 
779 }
780 
781 
782 } // namespace libMesh
783 
784 #endif // LIBMESH_MULTI_PREDICATES_H
Ghost(processor_id_type my_pid)
FlaggedPID(unsigned char rflag, processor_id_type proc_id)
ActiveLocalSubdomainSet(processor_id_type my_pid, std::set< subdomain_id_type > sset)
NotLocal(processor_id_type my_pid)
ElemType
Defines an enum for geometric element types.
Used to iterate over non-nullptr, elements of a given geometric type.
Used to iterate over non-nullptr, active, local elements owned by a given processor.
movable_il(T &&in)
Construct from rvalue reference of type T.
std::unique_ptr< predicate< T > > pred_ptr
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:286
Used to iterate over non-nullptr, entries that have children (i.e.
BND(const BoundaryInfo &bndry_info)
Used to iterate over non-nullptr, elements with a given refinement flag.
ActiveLocalSubdomain(processor_id_type my_pid, subdomain_id_type subdomain_id)
ActiveSubdomainSet(std::set< subdomain_id_type > sset)
Used to iterate over non-nullptr elements of a specified (refinement) level.
ActiveSemiLocal(processor_id_type my_pid)
Used to iterate over non-nullptr, active elements on a given subdomain.
Used to iterate over non-nullptr, active entries in a container.
Used to iterate over non-nullptr local elements not of a specified (refinement) level.
The libMesh namespace provides an interface to certain functionality in the library.
Helper object for creating a std::vector from a std::initializer_list https://stackoverflow.com/questions/46737054/vectorunique-ptra-using-initialization-list.
Used to iterate over non-nullptr entries in a container.
uint8_t processor_id_type
Definition: id_types.h:104
Used to iterate over nullptr entries in a container.
Evaluable(const DofMap &dof_map, unsigned int var_num=libMesh::invalid_uint)
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:169
Used to iterate over elements where solutions indexed by a given vector of DofMaps are evaluable for ...
ActivePID(processor_id_type proc_id)
int8_t boundary_id_type
Definition: id_types.h:51
abstract_multi_predicate & operator=(const abstract_multi_predicate &rhs)
PID(processor_id_type proc_id)
Used to iterate over non-nullptr, non-local entries in a container.
void deep_copy(const abstract_multi_predicate &rhs)
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
Used to iterate over non-nullptr, elements with a given refinement flag belonging to a given processo...
Used to iterate over non-nullptr, inactive entries in a container.
NotPID(processor_id_type proc_id)
abstract_multi_predicate(std::vector< pred_ptr< T >> &&predicates)
Used to iterate over non-nullptr elements owned by a given processor.
Used to iterate over non-nullptr, active elements owned by a given processor.
Used to iterate over non-nullptr elements not of a specified (refinement) level.
LocalNotLevel(processor_id_type my_pid, unsigned int l)
ActiveLocal(processor_id_type my_pid)
Used to iterate over non-nullptr, entries that have no children (i.e.
abstract_multi_predicate(const abstract_multi_predicate &rhs)
Flagged(unsigned char rflag)
Used to iterate over non-nullptr elements on the boundary with a given ID.
Used to iterate over non-nullptr, face-local entries (i.e.
Used to iterate over non-nullptr elements not owned by a given processor.
Used to iterate over non-nullptr, active, non-local entries in a container.
Local(processor_id_type my_pid)
Used to iterate over non-nullptr, active elements whose subdomains are in a user-specified set...
FaceLocal(processor_id_type my_pid)
Used to iterate over non-nullptr elements not owned by a given processor but semi-local to that proce...
Used to iterate over non-nullptr, active elements which are on the boundary.
Used to iterate over non-nullptr, active elements with a given PID whose subdomains are in a user-spe...
Used to iterate over non-nullptr, local entries (i.e.
Used to iterate over non-nullptr, subactive entries (i.e.
ActiveSubdomain(subdomain_id_type subdomain_id)
Used to iterate over non-nullptr, semi-local entries (i.e.
MultiEvaluable(const std::vector< const DofMap *> &dof_maps)
Used to iterate over non-nullptr elements on the boundary.
virtual bool operator()(const T &it) const
Used to iterate over non-nullptr local elements with a specified (refinement) level.
ActiveNotLocal(processor_id_type my_pid)
BID(boundary_id_type bndry_id, const BoundaryInfo &bndry_info)
Used to iterate over non-nullptr, active elements of a given geometric type.
std::vector< T > make_vec(std::initializer_list< movable_il< T > > il)
Helper function that creates a std::vector from an initializer_list of movable_il objects...
LocalLevel(processor_id_type my_pid, unsigned int l)
Used to iterate over elements where solutions indexed by a given DofMap are evaluable for a given var...
movable_il(U &&in)
Construct from rvalue reference of type U, using forwarding.
Used to iterate over non-nullptr, non-subactive entries (i.e.
Used to iterate over the sides of an element which are on the boundary of the Mesh.
Used to iterate over non-nullptr, active elements with a given PID on a given subdomain.