Fluid structure interaction suite
boundary_conditions.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2022 by Luca Heltai
4 //
5 // This file is part of the FSI-suite platform, based on the deal.II library.
6 //
7 // The FSI-suite platform is free software; you can use it, redistribute it,
8 // and/or modify it under the terms of the GNU Lesser General Public License as
9 // published by the Free Software Foundation; either version 3.0 of the License,
10 // or (at your option) any later version. The full text of the license can be
11 // found in the file LICENSE at the top level of the FSI-suite platform
12 // distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
18 
20 #include "parsed_tools/grid_info.h"
22 
23 #ifdef DEAL_II_WITH_SYMENGINE
24 
25 using namespace dealii;
26 
27 namespace ParsedTools
28 {
29  template <int spacedim>
31  const std::string &section_name,
32  const std::string &component_names,
33  const std::vector<std::set<dealii::types::boundary_id>> &ids,
34  const std::vector<std::string> &selected_components,
35  const std::vector<BoundaryConditionType> &bc_type,
36  const std::vector<std::string> &expressions)
37  : ParameterAcceptor(section_name)
38  , component_names(component_names)
39  , n_components(Components::n_components(component_names))
40  , ids(ids)
41  , selected_components(selected_components)
42  , bc_type(bc_type)
43  , expressions(expressions)
44  , grid_info(2)
45  {
46  Patterns::List expr_pattern(
48  0,
50  "%");
51 
52  Patterns::List comp_pattern(
54  0,
56  ";");
57 
58  Patterns::List id_pattern(Patterns::List(Patterns::UnsignedInteger(),
59  0,
61  ","),
62  0,
64  ";");
65 
66  add_parameter("Boundary id sets (" + component_names + ")",
67  this->ids,
68  "",
69  this->prm,
70  id_pattern);
71 
72  add_parameter("Selected components (" + component_names + ")",
73  this->selected_components,
74  "",
75  this->prm,
76  comp_pattern);
77 
78  add_parameter("Boundary condition types (" + component_names + ")",
79  this->bc_type);
80 
81  add_parameter("Expressions (" + component_names + ")",
82  this->expressions,
83  "",
84  this->prm,
85  expr_pattern);
86 
87  this->parse_parameters_call_back.connect([&]() {
88  // Parse expressions into functions.
89  functions.clear();
90  for (const auto &exp : this->expressions)
91  functions.emplace_back(
92  std::make_unique<dealii::Functions::SymbolicFunction<spacedim>>(exp));
93 
94  // Parse components into masks and types
95  masks.clear();
96  types.clear();
97  for (const auto &comp : this->selected_components)
98  {
99  masks.push_back(Components::mask(this->component_names, comp));
100  types.push_back(Components::type(this->component_names, comp));
101  }
102 
103  // Check that everything is consistent
106  });
107  }
108 
109 
110 
111  template <int spacedim>
112  void
114  {
115  n_boundary_conditions = ids.size();
116  AssertThrow(n_boundary_conditions == bc_type.size(),
117  ExcMessage("The number of boundary ids must be equal to the "
118  "number of boundary condition types."));
119  AssertThrow(n_boundary_conditions == expressions.size(),
120  ExcMessage("The number of boundary ids must be equal to the "
121  "number of expressions."));
122  AssertThrow(n_boundary_conditions == selected_components.size(),
123  ExcMessage("The number of boundary ids "
124  "must be equal to the number "
125  "of selected components."));
126 
127  std::set<types::boundary_id> all_ids;
128  unsigned int n_ids = 0;
129  for (const auto &id : ids)
130  {
131  all_ids.insert(id.begin(), id.end());
132  n_ids += id.size();
133  }
134 
135  // Special meaning of boundary id numbers::invalid_boundary_id:
136  if (all_ids.find(numbers::invalid_boundary_id) != all_ids.end())
137  {
138  AssertThrow(all_ids.size() == 1,
139  ExcMessage("If you use the boundary id -1, then no other "
140  "boundary ids can be specified"));
141  AssertThrow(n_boundary_conditions == 1,
142  ExcMessage("Only one BoundaryCondition can be specified "
143  "with the special boundary id -1"));
144  }
145  // This is no longer the case for complex types: we could have a boundary id
146  // specified for one component, and another one specified for a different
147  // component.
148  // else
149  // {
150  // AssertThrow(all_ids.size() == n_ids,
151  // ExcMessage("You specified the same "
152  // " boundary id more than once "
153  // "in two different boundary conditions"));
154  // // We check consistency with the triangulation
155  // if (grid_info.n_active_cells > 0)
156  // {
157  // AssertThrow(all_ids.size() == grid_info.boundary_ids.size(),
158  // ExcMessage("The number of boundary ids specified in "
159  // "the input file does not match the number "
160  // "of boundary ids in the triangulation"));
161  // }
162  // }
163 
164  // Now check that the types are valid in this dimension
165  AssertDimension(n_boundary_conditions, types.size());
166  AssertDimension(n_boundary_conditions, masks.size());
167  for (unsigned int i = 0; i < n_boundary_conditions; ++i)
168  {
169  if (types[i] == Components::Type::vector ||
172  {
173  AssertThrow(masks[i].n_selected_components() == spacedim,
174  ExcDimensionMismatch(masks[i].n_selected_components(),
175  spacedim));
176  }
177 
178  if (types[i] == Components::Type::normal ||
180  {
181  AssertThrow(functions[i]->n_components == spacedim,
182  ExcDimensionMismatch(functions[i]->n_components,
183  spacedim));
184  }
185  else
186  {
187  // In all other cases, it is the mask that determines the number
188  // of of components, but the function needs to be of the correct
189  // dimension
190  AssertThrow(functions[i]->n_components == n_components,
191  ExcDimensionMismatch(functions[i]->n_components,
192  n_components));
193  }
194  }
195  }
196 
197 
198 
199  template <int spacedim>
200  void
202  const dealii::Differentiation::SD::types::substitution_map
203  &substitution_map)
204  {
205  auto smap = substitution_map;
206  smap["E"] = numbers::E;
207  smap["LOG2E"] = numbers::LOG2E;
208  smap["LOG10E"] = numbers::LOG10E;
209  smap["LN2"] = numbers::LN2;
210  smap["LN10"] = numbers::LN10;
211  smap["PI"] = numbers::PI;
212  smap["PI_2"] = numbers::PI_2;
213  smap["PI_4"] = numbers::PI_4;
214  smap["SQRT2"] = numbers::SQRT2;
215  smap["SQRT1_2"] = numbers::SQRT1_2;
216  for (auto &f : functions)
217  f->update_user_substitution_map(smap);
218  }
219 
220 
221 
222  template <int spacedim>
223  void
226  {
227  for (auto &f : functions)
228  f->set_additional_function_arguments(arguments);
229  }
230 
231 
232 
233  template <int spacedim>
234  void
236  {
237  for (auto &f : functions)
238  f->set_time(time);
239  }
240 
241 
242 
243  template <int spacedim>
244  std::set<dealii::types::boundary_id>
246  {
247  std::set<dealii::types::boundary_id> essential_boundary_ids;
248  for (unsigned int i = 0; i < ids.size(); ++i)
249  {
250  if (bc_type[i] == BoundaryConditionType::dirichlet ||
251  bc_type[i] == BoundaryConditionType::first_dof)
252  essential_boundary_ids.insert(ids[i].begin(), ids[i].end());
253  }
254  return essential_boundary_ids;
255  }
256 
257 
258 
259  template <int spacedim>
260  std::set<dealii::types::boundary_id>
262  {
263  std::set<dealii::types::boundary_id> natural_boundary_ids;
264  for (unsigned int i = 0; i < ids.size(); ++i)
265  {
266  if (bc_type[i] == BoundaryConditionType::neumann)
267  natural_boundary_ids.insert(ids[i].begin(), ids[i].end());
268  }
269  return natural_boundary_ids;
270  }
271 
272 
273 
274  template class BoundaryConditions<1>;
275  template class BoundaryConditions<2>;
276  template class BoundaryConditions<3>;
277 } // namespace ParsedTools
278 #endif
static ParameterHandler prm
boost::signals2::signal< void()> parse_parameters_call_back
void add_parameter(const std::string &entry, ParameterType &parameter, const std::string &documentation="", ParameterHandler &prm_=prm, const Patterns::PatternBase &pattern=*Patterns::Tools::Convert< ParameterType >::to_pattern())
static const unsigned int max_int_value
A wrapper for boundary conditions.
void set_time(const double &time)
Update time in each Functions::SymbolicFunction defined in this object.
std::vector< BoundaryConditionType > bc_type
Type of boundary conditions.
const unsigned int n_components
Number of components of the problem.
const std::string component_names
Component names of the boundary conditions.
void check_consistency() const
Make sure the specified boundary conditions make sense.
std::vector< std::unique_ptr< Functions::SymbolicFunction< spacedim > > > functions
The actual functions.
std::set< types::boundary_id > get_essential_boundary_ids() const
Get all ids where we impose essential boundary conditions.
void set_additional_function_arguments(const Differentiation::SD::types::substitution_map &arguments)
Call Functions::SymbolicFunction::set_additional_function_arguments() for every function defined in t...
std::vector< ComponentMask > masks
Component on which to apply the boundary condition.
std::set< types::boundary_id > get_natural_boundary_ids() const
Get all ids where we impose natural boundary conditions.
void update_user_substitution_map(const Differentiation::SD::types::substitution_map &substitution_map)
Update the substitition map of every Functions::SymbolicFunction defined in this object.
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::map< SD::Expression, SD::Expression, internal::ExpressionKeyLess > substitution_map
Expression exp(const Expression &exponent)
@ tangential
Tangential component of a vector.
@ normal
Normal component of a vector.
Type type(const std::string &component_name, const std::string &selected_component)
Return the component type for the given selected component.
Definition: components.cc:186
ComponentMask mask(const std::string &component_names, const std::string &selected_component)
Return a component mask corresponding to a given selected component, from a list of comma separated c...
Definition: components.cc:226
unsigned int n_components(const std::string &component_names)
Count the number of components in the given list of comma separated components.
Definition: components.cc:32
We collect in this namespace some wrappers around commonly used deal.II classes, derived from the Par...
static constexpr double LOG10E
static constexpr double PI_2
const types::boundary_id invalid_boundary_id
static constexpr double E
static constexpr double PI
static constexpr double SQRT2
static constexpr double SQRT1_2
static constexpr double PI_4
static constexpr double LN10
static constexpr double LN2
static constexpr double LOG2E