Fluid structure interaction suite
non_matching_coupling.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 // ---------------------------------------------------------------------
16 
18 
19 #include <boost/geometry.hpp>
20 
22 #include "compute_intersections.h"
24 #include "lac.h"
25 #include "parsed_tools/enum.h"
26 
27 using namespace magic_enum::bitwise_operators;
28 
29 using namespace dealii;
30 
31 namespace ParsedTools
32 {
33  template <int dim, int spacedim>
35  const std::string &section_name,
36  const dealii::ComponentMask &embedded_mask,
37  const dealii::ComponentMask &space_mask,
40  refinement_strategy,
41  const unsigned int space_pre_refinement,
42  const unsigned int embedded_post_refinement,
43  const std::string &quadrature_type,
44  const unsigned int quadrature_order,
45  const unsigned int quadrature_repetitions,
46  double quadrature_tolerance)
47  : ParameterAcceptor(section_name)
48  , embedded_mask(embedded_mask)
49  , space_mask(space_mask)
50  , coupling_type(coupling_type)
51  , refinement_strategy(refinement_strategy)
52  , space_pre_refinement(space_pre_refinement)
53  , embedded_post_refinement(embedded_post_refinement)
54  , embedded_quadrature_type(quadrature_type)
55  , quadrature_order(quadrature_order)
56  , embedded_quadrature_repetitions(quadrature_repetitions)
57  , quadrature_tolerance(quadrature_tolerance)
58  {
59  add_parameter("Coupling type", this->coupling_type);
60 
61  add_parameter("Refinement strategy", this->refinement_strategy);
62 
63  add_parameter("Space pre-refinement", this->space_pre_refinement);
64 
65  add_parameter("Embedded post-refinement", this->embedded_post_refinement);
66 
67  add_parameter("Embedded quadrature type",
69  "",
70  this->prm,
73 
74  add_parameter("Embedded quadrature order", this->quadrature_order);
75 
76  add_parameter("Embedded quadrature retpetitions",
78 
80  "Quadrature tolerance",
81  this->quadrature_tolerance,
82  "If an intersection integrates to a value smaller than this tolerance, "
83  "it is discarded during exact intersection.");
84  }
85 
86 
87 
88  template <int dim, int spacedim>
91  {
92  return this->coupling_type;
93  }
94 
95 
96 
97  template <int dim, int spacedim>
98  void
100  const GridTools::Cache<spacedim, spacedim> &space_cache,
101  const DoFHandler<spacedim, spacedim> &space_dh,
102  const AffineConstraints<double> &space_constraints,
103  const GridTools::Cache<dim, spacedim> &embedded_cache,
104  const DoFHandler<dim, spacedim> &embedded_dh,
105  const AffineConstraints<double> &embedded_constraints)
106  {
107  this->space_cache = &space_cache;
108  this->space_dh = &space_dh;
109  this->space_constraints = &space_constraints;
110  this->embedded_cache = &embedded_cache;
111  this->embedded_dh = &embedded_dh;
112  this->embedded_constraints = &embedded_constraints;
113 
114  embedded_quadrature =
115  QIterated<dim>(QuadratureSelector<1>(this->embedded_quadrature_type,
116  this->quadrature_order),
117  this->embedded_quadrature_repetitions);
118  }
119 
120 
121 
122  template <int dim, int spacedim>
123  void
126  Triangulation<dim, spacedim> &embedded_tria,
127  const bool apply_delta_refinements) const
128  {
129  Assert(space_dh, ExcNotInitialized());
130  Assert(&embedded_tria == &embedded_dh->get_triangulation(),
131  ExcMessage(
132  "The passed embedded triangulation must be the same as the "
133  "one used by the embedded DoFHandler with which you "
134  "initialized this class."));
135  Assert(&space_tria == &space_dh->get_triangulation(),
136  ExcMessage("The passed space triangulation must be the same as the "
137  "one used by the space DoFHandler with which you "
138  "initialized this class."));
139 
140  namespace bgi = boost::geometry::index;
141 
142  auto refine = [&]() {
143  bool done = false;
144 
145  double min_embedded = 1e10;
146  double max_embedded = 0;
147  double min_space = 1e10;
148  double max_space = 0;
149 
150  while (done == false)
151  {
152  // Bounding boxes of the space grid
153  const auto &tree =
155 
156  // Bounding boxes of the embedded grid
157  const auto &embedded_tree =
158  embedded_cache->get_cell_bounding_boxes_rtree();
159 
160  // Let's check all cells whose bounding box contains an embedded
161  // bounding box
162  done = true;
163 
164  const bool use_space =
165  ((this->refinement_strategy & RefinementStrategy::refine_space) ==
166  RefinementStrategy::refine_space);
167 
168  const bool use_embedded = ((this->refinement_strategy &
169  RefinementStrategy::refine_embedded) ==
170  RefinementStrategy::refine_embedded);
171  AssertThrow(!(use_embedded && use_space),
172  ExcMessage("You can't refine both the embedded and "
173  "the space grid at the same time."));
174 
175  for (const auto &[embedded_box, embedded_cell] : embedded_tree)
176  {
177  const auto &[p1, p2] = embedded_box.get_boundary_points();
178  const auto diameter = p1.distance(p2);
179  min_embedded = std::min(min_embedded, diameter);
180  max_embedded = std::max(max_embedded, diameter);
181 
182  for (const auto &[space_box, space_cell] :
183  tree | bgi::adaptors::queried(bgi::intersects(embedded_box)))
184  {
185  const auto &[sp1, sp2] = space_box.get_boundary_points();
186  const auto space_diameter = sp1.distance(sp2);
187  min_space = std::min(min_space, space_diameter);
188  max_space = std::max(max_space, space_diameter);
189 
190  if (use_embedded && space_diameter < diameter)
191  {
192  embedded_cell->set_refine_flag();
193  done = false;
194  }
195  if (use_space && diameter < space_diameter)
196  {
197  space_cell->set_refine_flag();
198  done = false;
199  }
200  }
201  }
202  if (done == false)
203  {
204  if (use_embedded)
205  {
206  // Compute again the embedded displacement grid
207  embedded_tria.execute_coarsening_and_refinement();
208  embedded_post_refinemnt_signal();
209  }
210  if (use_space)
211  {
212  // Compute again the embedded displacement grid
214  space_post_refinemnt_signal();
215  }
216  }
217  }
218  return std::make_tuple(min_space, max_space, min_embedded, max_embedded);
219  };
220 
221  // Do the refinement loop once, to make sure we satisfy our criterions
222  refine();
223 
224  // Pre refine the space grid according to the delta refinement
225  if (apply_delta_refinements && space_pre_refinement != 0)
226  for (unsigned int i = 0; i < space_pre_refinement; ++i)
227  {
228  const auto &tree =
230 
231  const auto &embedded_tree =
232  embedded_cache->get_cell_bounding_boxes_rtree();
233 
234  for (const auto &[embedded_box, embedded_cell] : embedded_tree)
235  for (const auto &[space_box, space_cell] :
236  tree | bgi::adaptors::queried(bgi::intersects(embedded_box)))
237  space_cell->set_refine_flag();
239 
240  // Make sure we signal post refinement on the space grid
241  space_post_refinemnt_signal();
242 
243  // Make sure again we satisfy our criterion after the space refinement
244  refine();
245  }
246 
247  // Post refinement on embedded grid is easy
248  if (apply_delta_refinements && embedded_post_refinement != 0)
249  {
250  embedded_tria.refine_global(embedded_post_refinement);
251  embedded_post_refinemnt_signal();
252  }
253 
254  // Check once again we satisfy our criterion, and record min/max
255  const auto [sm, sM, em, eM] = refine();
256 
257  deallog << "Space local min/max diameters : " << sm << "/" << sM
258  << std::endl
259  << "Embedded space min/max diameters: " << em << "/" << eM
260  << std::endl;
261  }
262 
263 
264 
265  template class NonMatchingCoupling<1, 1>;
266  template class NonMatchingCoupling<1, 2>;
267  template class NonMatchingCoupling<1, 3>;
268  template class NonMatchingCoupling<2, 2>;
269  template class NonMatchingCoupling<2, 3>;
270  template class NonMatchingCoupling<3, 3>;
271 
272 } // namespace ParsedTools
const Triangulation< dim, spacedim > & get_triangulation() const
const RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > & get_locally_owned_cell_bounding_boxes_rtree() const
const RTree< std::pair< BoundingBox< spacedim >, typename Triangulation< dim, spacedim >::active_cell_iterator > > & get_cell_bounding_boxes_rtree() const
static ParameterHandler prm
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())
void refine_global(const unsigned int times=1)
virtual void execute_coarsening_and_refinement()
Wrapper around several functions in the NonMatching namespace.
void adjust_grid_refinements(Triangulation< spacedim, spacedim > &space_tria, Triangulation< dim, spacedim > &embedded_tria, const bool apply_delta_refinements=true) const
Adjust grid refinements according to the selected strategy.
void initialize(const GridTools::Cache< spacedim, spacedim > &space_cache, const DoFHandler< spacedim, spacedim > &space_dh, const AffineConstraints< double > &space_constraints, const GridTools::Cache< dim, spacedim > &embedded_cache, const DoFHandler< dim, spacedim > &embedded_dh, const AffineConstraints< double > &embedded_constraints)
Initialize the class and return a linear operator representing the coupling matrix.
CouplingType
Types of coupling that can used in non-matching coupling.
unsigned int embedded_quadrature_repetitions
Number of iterations of the base embedded quadrature.
CouplingType get_coupling_type() const
Get the coupling type object.
std::string embedded_quadrature_type
Embedded quadrature type.
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
LogStream deallog
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
double diameter(const Triangulation< dim, spacedim > &tria)
We collect in this namespace some wrappers around commonly used deal.II classes, derived from the Par...
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)