Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
boundary_condition_manager.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2024, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
15 #include <memory>
16 #include <set>
17 
20 
21 namespace serac {
22 
28 template <typename Iter, typename Pred>
29 class FilterView {
30 public:
35  public:
42  FilterViewIterator(Iter curr, Iter end, const Pred& pred) : curr_(curr), end_(end), pred_(pred) {}
43 
49  {
50  // Move forward once to advance the element, then continue
51  // advancing until a predicate-satisfying element is found
52  ++curr_;
53  while ((curr_ != end_) && (!pred_(*curr_))) {
54  ++curr_;
55  }
56  return *this;
57  }
58 
63  const auto& operator*() const { return *curr_; }
64 
68  auto& operator*() { return *curr_; }
69 
73  bool operator!=(const FilterViewIterator& other) const { return curr_ != other.curr_; }
74 
75  private:
79  Iter curr_;
80 
84  Iter end_;
85 
89  const Pred& pred_;
90  };
91 
98  FilterView(Iter begin, Iter end, Pred&& pred) : begin_(begin), end_(end), pred_(std::move(pred))
99  {
100  // Skip to the first element that meets the predicate, making sure not to deref the "end" iterator
101  while ((begin_ != end_) && (!pred_(*begin_))) {
102  ++begin_;
103  }
104  }
105 
110  FilterViewIterator begin() { return FilterViewIterator(begin_, end_, pred_); }
111 
115  const FilterViewIterator begin() const { return FilterViewIterator(begin_, end_, pred_); }
116 
120  FilterViewIterator end() { return FilterViewIterator(end_, end_, pred_); }
121 
125  const FilterViewIterator end() const { return FilterViewIterator(end_, end_, pred_); }
126 
127 private:
131  Iter begin_;
132 
136  Iter end_;
137 
141  Pred pred_;
142 };
143 
150 template <class Iter, class Pred>
151 FilterView(Iter, Iter, Pred&&) -> FilterView<Iter, Pred>;
152 
157 public:
163  explicit BoundaryConditionManager(const mfem::ParMesh& mesh) : num_attrs_(mesh.bdr_attributes.Max()) {}
164 
173  void addEssential(const std::set<int>& ess_bdr, serac::GeneralCoefficient ess_bdr_coef,
174  mfem::ParFiniteElementSpace& space, const std::optional<int> component = {});
175 
187  void addEssential(const mfem::Array<int>& true_dofs, std::shared_ptr<mfem::VectorCoefficient> ess_bdr_coef,
188  mfem::ParFiniteElementSpace& space);
189 
198  void addNatural(const std::set<int>& nat_bdr, serac::GeneralCoefficient nat_bdr_coef,
199  mfem::ParFiniteElementSpace& space, const std::optional<int> component = {});
200 
212  template <typename Tag>
213  void addGeneric(const std::set<int>& bdr_attr, serac::GeneralCoefficient bdr_coef, const Tag tag,
214  mfem::ParFiniteElementSpace& space, const std::optional<int> component = {})
215  {
216  other_bdr_.emplace_back(bdr_coef, component, space, bdr_attr);
217  other_bdr_.back().setTag(tag);
218  all_dofs_valid_ = false;
219  }
220 
225  const mfem::Array<int>& allEssentialTrueDofs() const
226  {
227  if (!all_dofs_valid_) {
228  updateAllDofs();
229  }
230  return all_true_dofs_;
231  }
232 
237  const mfem::Array<int>& allEssentialLocalDofs() const
238  {
239  if (!all_dofs_valid_) {
240  updateAllDofs();
241  }
242  return all_local_dofs_;
243  }
244 
252  std::unique_ptr<mfem::HypreParMatrix> eliminateAllEssentialDofsFromMatrix(mfem::HypreParMatrix& matrix) const
253  {
254  return std::unique_ptr<mfem::HypreParMatrix>(matrix.EliminateRowsCols(allEssentialTrueDofs()));
255  }
256 
260  std::vector<BoundaryCondition>& essentials() { return ess_bdr_; }
264  std::vector<BoundaryCondition>& naturals() { return nat_bdr_; }
268  std::vector<BoundaryCondition>& generics() { return other_bdr_; }
269 
273  const std::vector<BoundaryCondition>& essentials() const { return ess_bdr_; }
277  const std::vector<BoundaryCondition>& naturals() const { return nat_bdr_; }
281  const std::vector<BoundaryCondition>& generics() const { return other_bdr_; }
282 
289  template <typename Tag>
290  auto genericsWithTag(const Tag tag)
291  {
292  static_assert(std::is_enum_v<Tag>, "Only enumerations can be used to tag a boundary condition.");
293  return FilterView(other_bdr_.begin(), other_bdr_.end(), [tag](const auto& bc) { return bc.tagEquals(tag); });
294  }
295 
296 private:
300  void updateAllDofs() const;
301 
305  const int num_attrs_;
306 
310  std::vector<BoundaryCondition> ess_bdr_;
311 
315  std::vector<BoundaryCondition> nat_bdr_;
316 
320  std::vector<BoundaryCondition> other_bdr_;
321 
327  std::set<int> attrs_in_use_;
328 
333  mutable mfem::Array<int> all_true_dofs_;
334 
339  mutable mfem::Array<int> all_local_dofs_;
340 
344  mutable bool all_dofs_valid_ = false;
345 };
346 
347 } // namespace serac
This file contains the declaration of the boundary condition class.
A container for the boundary condition information relating to a specific physics module.
BoundaryConditionManager(const mfem::ParMesh &mesh)
Construct a new Boundary Condition Manager object.
auto genericsWithTag(const Tag tag)
View over all "other"/generic boundary conditions with a specific tag.
std::unique_ptr< mfem::HypreParMatrix > eliminateAllEssentialDofsFromMatrix(mfem::HypreParMatrix &matrix) const
Eliminates all essential BCs from a matrix.
void addGeneric(const std::set< int > &bdr_attr, serac::GeneralCoefficient bdr_coef, const Tag tag, mfem::ParFiniteElementSpace &space, const std::optional< int > component={})
Set a generic boundary condition from a list of boundary markers and a coefficient.
std::vector< BoundaryCondition > & generics()
Accessor for the generic BC objects.
void addNatural(const std::set< int > &nat_bdr, serac::GeneralCoefficient nat_bdr_coef, mfem::ParFiniteElementSpace &space, const std::optional< int > component={})
Set the natural boundary conditions from a list of boundary markers and a coefficient.
const std::vector< BoundaryCondition > & generics() const
Accessor for the generic BC objects.
const mfem::Array< int > & allEssentialLocalDofs() const
Returns all the local degrees of freedom associated with all the essential BCs.
const std::vector< BoundaryCondition > & essentials() const
Accessor for the essential BC objects.
void addEssential(const std::set< int > &ess_bdr, serac::GeneralCoefficient ess_bdr_coef, mfem::ParFiniteElementSpace &space, const std::optional< int > component={})
Set the essential boundary conditions from a list of boundary markers and a coefficient.
std::vector< BoundaryCondition > & essentials()
Accessor for the essential BC objects.
std::vector< BoundaryCondition > & naturals()
Accessor for the natural BC objects.
const std::vector< BoundaryCondition > & naturals() const
Accessor for the natural BC objects.
const mfem::Array< int > & allEssentialTrueDofs() const
Returns all the true degrees of freedom associated with all the essential BCs.
bool operator!=(const FilterViewIterator &other) const
Comparison operation, checks for iterator inequality.
const auto & operator*() const
Dereferences the iterator.
FilterViewIterator(Iter curr, Iter end, const Pred &pred)
Constructs a new iterator object.
FilterViewIterator & operator++()
Advances the pointed-to container element to the next element that satisfies the predicate.
A "view" for filtering a container.
const FilterViewIterator end() const
FilterView(Iter begin, Iter end, Pred &&pred)
Constructs a new lazily-evaluated filtering view over a container.
const FilterViewIterator begin() const
FilterViewIterator begin()
Returns the first filtered element, i.e., the first element in the underlying container that satisfie...
FilterViewIterator end()
Returns one past the end of the container, primarily for bounds-checking.
This file contains the declaration of structure that manages the MFEM objects that make up the state ...
Accelerator functionality.
Definition: serac.cpp:38
FilterView(Iter, Iter, Pred &&) -> FilterView< Iter, Pred >
Deduction guide - iterator and lambda types must be deduced, so this mitigates a "builder" function.