Fluid structure interaction suite
reduced_lagrange.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 
17 
19 #include <deal.II/base/logstream.h>
21 
23 
24 #include <deal.II/dofs/dof_tools.h>
25 
28 
32 
34 
38 
39 #include <boost/geometry.hpp>
40 
41 #include <fstream>
42 #include <iostream>
43 
44 #include "parsed_tools/enum.h"
45 #include "projection_operator.h"
46 
47 using namespace dealii;
48 
49 namespace PDEs
50 {
51  namespace Serial
52  {
53  template <int dim, int spacedim>
55  : ParameterAcceptor("/")
56  , space_dh(space_grid)
57  , embedded_dh(embedded_grid)
58  , embedded_configuration_dh(embedded_grid)
59  , monitor(std::cout,
60  TimerOutput::summary,
61  TimerOutput::cpu_and_wall_times)
62  , grid_generator("/Grid/Ambient")
63  , grid_refinement("/Grid/Refinement")
64  , embedded_grid_generator("/Grid/Embedded")
65  , embedded_mapping(embedded_configuration_dh, "/Grid/Embedded/Mapping")
66  , constants("/Functions")
67  , embedded_value_function("/Functions", "0", "Embedded value")
68  , forcing_term("/Functions", "0", "Forcing term")
69  , exact_solution("/Functions", "0", "Exact solution")
70  , boundary_conditions("/Boundary conditions")
71  , stiffness_inverse_operator("/Solver/Stiffness")
72  , stiffness_preconditioner("/Solver/Stiffness AMG")
73  , mass_preconditioner("/Solver/Mass AMG")
74  , schur_inverse_operator("/Solver/Schur")
75  , data_out("/Data out/Space", "output/space")
76  , embedded_data_out("/Data out/Embedded", "output/embedded")
77  , error_table_space("/Error table/Space")
78  , error_table_embedded("/Error table/Embedded")
79  {
80  add_parameter("Coupling quadrature order", coupling_quadrature_order);
81  add_parameter("Console level", console_level);
82  add_parameter("Delta refinement", delta_refinement);
83  add_parameter("Number of basis functions", n_basis);
84  add_parameter("Finite element degree (ambient space)",
86  add_parameter("Finite element degree (embedded space)",
88  add_parameter("Finite element degree (configuration)",
90  enter_subsection("Solver");
91  enter_subsection("Stiffness");
92  add_parameter("Use direct solver", use_direct_solver);
95  enter_subsection("Solver");
96  enter_subsection("Schur");
97  add_parameter("Preconditioner type", schur_preconditioner);
100  }
101 
102 
103 
104  template <int dim, int spacedim>
105  void
107  {
108  TimerOutput::Scope timer_section(monitor, "generate_grids_and_fes");
109  grid_generator.generate(space_grid);
110  embedded_grid_generator.generate(embedded_grid);
111 
113  space_grid, finite_element_degree);
114 
116  embedded_grid, embedded_space_finite_element_degree);
117 
118  const auto embedded_base_fe =
120  embedded_grid, embedded_space_finite_element_degree);
121 
122  embedded_configuration_fe.reset(
123  new FESystem<dim, spacedim>(*embedded_base_fe, spacedim));
124 
125  space_mapping = std::make_unique<MappingFE<spacedim>>(*space_fe);
126 
127  space_grid_tools_cache =
128  std::make_unique<GridTools::Cache<spacedim, spacedim>>(space_grid,
129  *space_mapping);
130 
131  embedded_configuration_dh.distribute_dofs(*embedded_configuration_fe);
132  embedded_configuration.reinit(embedded_configuration_dh.n_dofs());
133  embedded_mapping.initialize(embedded_configuration);
134 
135  embedded_grid_tools_cache =
136  std::make_unique<GridTools::Cache<dim, spacedim>>(embedded_grid,
137  embedded_mapping());
138  adjust_grid_refinements();
139  }
140 
141 
142 
143  template <int dim, int spacedim>
144  void
146  const bool apply_delta_refinement)
147  {
148  TimerOutput::Scope timer_section(monitor, "adjust_grid_refinements");
149  namespace bgi = boost::geometry::index;
150  // Now get a vector of all bounding boxes of the embedded grid and refine
151  // them untill every cell is of diameter smaller than the space
152  // surrounding cells
153 
154  auto refine_embedded = [&]() {
155  bool done = false;
156  while (done == false)
157  {
158  // Bounding boxes of the space grid
159  const auto &tree =
160  space_grid_tools_cache
161  ->get_locally_owned_cell_bounding_boxes_rtree();
162 
163  // Bounding boxes of the embedded grid
164  const auto &embedded_tree =
165  embedded_grid_tools_cache
166  ->get_locally_owned_cell_bounding_boxes_rtree();
167 
168  // Let's check all cells whose bounding box contains an embedded
169  // bounding box
170  done = true;
171  for (const auto &[embedded_box, embedded_cell] : embedded_tree)
172  {
173  const auto &[p1, p2] = embedded_box.get_boundary_points();
174  const auto diameter = p1.distance(p2);
175 
176  for (const auto &[space_box, space_cell] :
177  tree |
178  bgi::adaptors::queried(bgi::intersects(embedded_box)))
179  if (space_cell->diameter() < diameter)
180  {
181  embedded_cell->set_refine_flag();
182  done = false;
183  }
184  }
185  if (done == false)
186  {
187  // Compute again the embedded displacement grid
188  embedded_grid.execute_coarsening_and_refinement();
189  embedded_configuration_dh.distribute_dofs(
190  *embedded_configuration_fe);
191  embedded_configuration.reinit(
192  embedded_configuration_dh.n_dofs());
193  embedded_mapping.initialize(embedded_configuration);
194  embedded_grid_tools_cache =
195  std::make_unique<GridTools::Cache<dim, spacedim>>(
196  embedded_grid, embedded_mapping());
197  }
198  }
199  };
200 
201  // first refine the embededd grid
202  refine_embedded();
203 
204  // Then refine the space grid according to the delta refinement
205  if (apply_delta_refinement && delta_refinement != 0)
206  for (unsigned int i = 0; i < delta_refinement; ++i)
207  {
208  const auto &tree =
209  space_grid_tools_cache
210  ->get_locally_owned_cell_bounding_boxes_rtree();
211 
212  const auto &embedded_tree =
213  embedded_grid_tools_cache
214  ->get_locally_owned_cell_bounding_boxes_rtree();
215 
216  for (const auto &[embedded_box, embedded_cell] : embedded_tree)
217  for (const auto &[space_box, space_cell] :
218  tree | bgi::adaptors::queried(bgi::intersects(embedded_box)))
219  space_cell->set_refine_flag();
220  space_grid.execute_coarsening_and_refinement();
221 
222  // Correct the embedded grid once again
223  refine_embedded();
224  }
225 
226 
227  const double embedded_space_maximal_diameter =
228  GridTools::maximal_cell_diameter(embedded_grid, embedded_mapping());
229  const double embedded_space_minimal_diameter =
230  GridTools::minimal_cell_diameter(embedded_grid, embedded_mapping());
231 
232  double space_minimal_diameter =
234  double space_maximal_diameter =
236 
237  deallog << "Space min/max diameters: " << space_minimal_diameter << "/"
238  << space_maximal_diameter << std::endl
239  << "Embedded space min/max diameters: "
240  << embedded_space_minimal_diameter << "/"
241  << embedded_space_maximal_diameter << std::endl;
242  }
243 
244 
245 
246  template <int dim, int spacedim>
247  void
249  {
250  basis_functions.resize(n_basis, Vector<double>(embedded_dh.n_dofs()));
251 
252  if (n_basis > 0)
253  basis_functions[0] = 1.0;
254 
255  for (unsigned int c = 1; c < n_basis; ++c)
256  {
257  unsigned int k = (c + 1) / 2;
258 
260  "sqrt(pi^k*(2*k + 2))*(x^2 + y^2)^(k/2)*cos(k*atan2(y, x))",
261  "k=" + std::to_string(k) + ", pi=" + std::to_string(M_PI));
263  "sqrt(pi^k*(2*k + 2))*(x^2 + y^2)^(k/2)*sin(k*atan2(y, x))",
264  "k=" + std::to_string(k) + ", pi=" + std::to_string(M_PI));
265 
266  if ((c + 1) % 2 == 0)
267  {
268  VectorTools::interpolate(embedded_mapping(),
269  embedded_dh,
270  b1,
271  basis_functions[c]);
272  }
273  else
274  {
275  VectorTools::interpolate(embedded_mapping(),
276  embedded_dh,
277  b2,
278  basis_functions[c]);
279  }
280  deallog << "Basis function " << c
281  << " norm: " << basis_functions[c].l2_norm() << std::endl;
282  }
283  }
284 
285 
286  template <int dim, int spacedim>
287  void
289  {
290  TimerOutput::Scope timer_section(monitor, "setup_dofs");
291 
292  space_dh.distribute_dofs(*space_fe);
293  constraints.clear();
294  DoFTools::make_hanging_node_constraints(space_dh, constraints);
295  boundary_conditions.apply_essential_boundary_conditions(*space_mapping,
296  space_dh,
297  constraints);
298  constraints.close();
299  {
300  DynamicSparsityPattern dsp(space_dh.n_dofs(), space_dh.n_dofs());
301  DoFTools::make_sparsity_pattern(space_dh, dsp, constraints);
302  stiffness_sparsity.copy_from(dsp);
303  stiffness_matrix.reinit(stiffness_sparsity);
304  }
305 
306  solution.reinit(space_dh.n_dofs());
307  reduced_solution.reinit(space_dh.n_dofs());
308  rhs.reinit(space_dh.n_dofs());
309 
310  deallog << "Space dofs: " << space_dh.n_dofs() << std::endl;
311 
312  embedded_dh.distribute_dofs(*embedded_fe);
313  embedded_constraints.clear();
315  embedded_constraints);
316  embedded_constraints.close();
317  {
318  DynamicSparsityPattern dsp(embedded_dh.n_dofs(), embedded_dh.n_dofs());
319  DoFTools::make_sparsity_pattern(embedded_dh, dsp, embedded_constraints);
320  embedded_sparsity.copy_from(dsp);
321  embedded_mass_matrix.reinit(embedded_sparsity);
322  embedded_stiffness_matrix.reinit(embedded_sparsity);
323  }
324 
325  lambda.reinit(embedded_dh.n_dofs());
326  reduced_lambda.reinit(embedded_dh.n_dofs());
327 
328  embedded_rhs.reinit(embedded_dh.n_dofs());
329  embedded_value.reinit(embedded_dh.n_dofs());
330  reduced_embedded_value.reinit(embedded_dh.n_dofs());
331 
332  small_rhs.reinit(n_basis);
333  small_lambda.reinit(n_basis);
334  small_value.reinit(n_basis);
335 
336  deallog << "Embedded dofs: " << embedded_dh.n_dofs() << std::endl;
337  deallog << "Reduced dofs: " << n_basis << std::endl;
338 
339  boundary_conditions.apply_natural_boundary_conditions(
340  *space_mapping, space_dh, constraints, stiffness_matrix, rhs);
341  }
342 
343 
344 
345  template <int dim, int spacedim>
346  void
348  {
349  TimerOutput::Scope timer_section(monitor, "Setup coupling");
350  const auto embedded_quad = ParsedTools::Components::get_cell_quadrature(
351  embedded_grid, embedded_fe->tensor_degree() + 1);
352 
353  DynamicSparsityPattern dsp(space_dh.n_dofs(), embedded_dh.n_dofs());
354  NonMatching::create_coupling_sparsity_pattern(*space_grid_tools_cache,
355  space_dh,
356  embedded_dh,
357  embedded_quad,
358  dsp,
359  constraints,
360  ComponentMask(),
361  ComponentMask(),
362  embedded_mapping(),
363  embedded_constraints);
364  coupling_sparsity.copy_from(dsp);
365  coupling_matrix.reinit(coupling_sparsity);
366  }
367 
368 
369 
370  template <int dim, int spacedim>
371  void
373  {
374  const auto space_quad = ParsedTools::Components::get_cell_quadrature(
375  space_grid, space_fe->tensor_degree() + 1);
376  const auto embedded_quad = ParsedTools::Components::get_cell_quadrature(
377  embedded_grid, embedded_fe->tensor_degree() + 1);
378  {
379  TimerOutput::Scope timer_section(monitor, "Assemble system");
380  // Stiffness matrix and rhs
381  MatrixTools::create_laplace_matrix(
382  space_dh,
383  space_quad,
384  stiffness_matrix,
385  forcing_term,
386  rhs,
387  static_cast<const Function<spacedim> *>(nullptr),
388  constraints);
389 
390  // Embedded mass matrix
392  embedded_mapping(),
393  embedded_dh,
394  embedded_quad,
395  embedded_mass_matrix,
396  static_cast<const Function<spacedim> *>(nullptr),
397  embedded_constraints);
398 
399  // Embedded stiffness matrix. Only for preconditioner.
401  tmp.merge(embedded_constraints);
402  tmp.add_line(0);
403  tmp.set_inhomogeneity(0, 0.0);
404  tmp.close();
405  MatrixTools::create_laplace_matrix(
406  embedded_mapping(),
407  embedded_dh,
408  embedded_quad,
409  embedded_stiffness_matrix,
410  static_cast<const Function<spacedim> *>(nullptr),
411  tmp);
412  }
413  {
414  TimerOutput::Scope timer_section(monitor, "Assemble coupling system");
415  NonMatching::create_coupling_mass_matrix(*space_grid_tools_cache,
416  space_dh,
417  embedded_dh,
418  embedded_quad,
419  coupling_matrix,
420  constraints,
421  ComponentMask(),
422  ComponentMask(),
423  embedded_mapping(),
424  embedded_constraints);
425 
426  // The rhs of the Lagrange multiplier as a function to plot
427  VectorTools::interpolate(embedded_mapping(),
428  embedded_dh,
429  embedded_value_function,
430  embedded_value);
431 
432  // The rhs of the Lagrange multiplier
433  VectorTools::create_right_hand_side(embedded_mapping(),
434  embedded_dh,
435  embedded_quad,
436  embedded_value_function,
437  embedded_rhs);
438  }
439  update_basis_functions();
440  }
441  template <int dim, int spacedim>
442  void
444  {
445  TimerOutput::Scope timer_section(monitor, "Solve system");
446 
447  auto A = linear_operator(stiffness_matrix);
448  auto Bt = linear_operator(coupling_matrix);
449  auto B = transpose_operator(Bt);
450  auto A_inv = A;
451  SparseDirectUMFPACK A_inv_direct;
452 
453  if (use_direct_solver)
454  {
455  A_inv_direct.initialize(stiffness_matrix);
456  A_inv = linear_operator(A, A_inv_direct);
457  }
458  else
459  {
460  stiffness_preconditioner.initialize(stiffness_matrix);
461  A_inv = stiffness_inverse_operator(A, stiffness_preconditioner);
462  }
463 
464  auto M = linear_operator(embedded_mass_matrix);
465  auto K = linear_operator(embedded_stiffness_matrix);
466 
467  mass_preconditioner.initialize(embedded_mass_matrix);
468  auto Minv = linear_operator(M, mass_preconditioner);
469 
470  auto S = B * A_inv * Bt;
471  auto S_prec = identity_operator(S);
472  switch (schur_preconditioner)
473  {
474  case SchurPreconditioner::identity:
475  break;
476  case SchurPreconditioner::M:
477  S_prec = M;
478  break;
479  case SchurPreconditioner::Minv:
480  S_prec = Minv;
481  break;
482  case SchurPreconditioner::K:
483  S_prec = K;
484  break;
485  case SchurPreconditioner::Minv_K_Minv:
486  S_prec = Minv * K * Minv;
487  break;
488  default:
489  Assert(false, ExcInternalError());
490  }
491  auto S_inv = schur_inverse_operator(S, S_prec);
492 
493  deallog << "Solving full order system" << std::endl;
494 
495  lambda = S_inv * (B * A_inv * rhs - embedded_rhs);
496  embedded_constraints.distribute(lambda);
497 
498  solution = A_inv * (rhs - Bt * lambda);
499  constraints.distribute(solution);
500 
501  if (n_basis > 0)
502  {
503  deallog << "Solving Reduced order system" << std::endl;
504  Vector<double> reduced(n_basis);
505  std::vector<std::reference_wrapper<const Vector<double>>> basis(
506  basis_functions.begin(), basis_functions.end());
507 
508  FullMatrix<double> G(n_basis, n_basis);
509  for (unsigned int i = 0; i < n_basis; ++i)
510  {
511  embedded_value = M * basis_functions[i];
512  for (unsigned int j = 0; j < n_basis; ++j)
513  G(i, j) = basis_functions[j] * embedded_value;
514  }
515  FullMatrix<double> Ginv(n_basis, n_basis);
516  Ginv.invert(G);
517 
518  auto R = projection_operator(reduced, basis);
519  auto Rt = transpose_operator(R);
520 
521  auto Ct = Bt * Rt;
522  auto C = R * B;
523  auto RS = C * A_inv * Ct;
524  auto RS_prec = identity_operator(RS);
525  auto RS_inv = schur_inverse_operator(RS, RS_prec);
526  small_rhs = R * embedded_rhs;
527  Ginv.vmult(small_value, small_rhs);
528  small_lambda = RS_inv * (C * A_inv * rhs - small_rhs);
529  reduced_solution = A_inv * (rhs - Ct * small_lambda);
530  constraints.distribute(reduced_solution);
531 
532  reduced_lambda = Rt * small_lambda;
533  embedded_constraints.distribute(reduced_lambda);
534 
535  reduced_embedded_value = Rt * small_value;
536  embedded_constraints.distribute(reduced_embedded_value);
537 
538  deallog << "Small lambda: " << small_lambda << std::endl;
539  deallog << "Small value: " << small_value << std::endl;
540  deallog << "Small rhs: " << small_rhs << std::endl;
541  }
542  }
543 
544 
545 
546  template <int dim, int spacedim>
547  void
549  {
550  TimerOutput::Scope timer_section(monitor, "Output results");
551  const auto suffix =
554  grid_refinement.get_n_refinement_cycles()));
555 
556  data_out.attach_dof_handler(space_dh, suffix);
557  data_out.add_data_vector(solution, component_names);
558  data_out.add_data_vector(reduced_solution, component_names + "_reduced");
559  data_out.write_data_and_clear(*space_mapping);
560 
561  embedded_data_out.attach_dof_handler(embedded_dh, suffix);
562  embedded_data_out.add_data_vector(
563  lambda, "lambda", dealii::DataOut<dim, spacedim>::type_dof_data);
564  embedded_data_out.add_data_vector(
565  embedded_value, "g", dealii::DataOut<dim, spacedim>::type_dof_data);
566  embedded_data_out.add_data_vector(
567  reduced_lambda,
568  "lambda_reduced",
569  dealii::DataOut<dim, spacedim>::type_dof_data);
570  embedded_data_out.add_data_vector(
571  reduced_embedded_value,
572  "g_reduced",
573  dealii::DataOut<dim, spacedim>::type_dof_data);
574 
575  unsigned int c = 0;
576  for (const auto &basis : basis_functions)
577  {
578  embedded_data_out.add_data_vector(
579  basis,
580  "phi_" + std::to_string(c++),
581  dealii::DataOut<dim, spacedim>::type_dof_data);
582  }
583  embedded_data_out.write_data_and_clear(embedded_mapping);
584  }
585 
586 
587 
588  template <int dim, int spacedim>
589  void
591  {
592  deallog.depth_console(console_level);
593  generate_grids_and_fes();
594  for (const auto &cycle : grid_refinement.get_refinement_cycles())
595  {
596  deallog.push("Cycle " + Utilities::int_to_string(cycle));
597  setup_dofs();
598  setup_coupling();
599  assemble_system();
600  solve();
601  if (n_basis == 0)
602  {
603  error_table_space.error_from_exact(*space_mapping,
604  space_dh,
605  solution,
606  exact_solution);
607  }
608  else
609  {
610  error_table_space.difference(*space_mapping,
611  space_dh,
612  solution,
613  reduced_solution);
614  error_table_embedded.difference(embedded_mapping(),
615  embedded_dh,
616  lambda,
617  reduced_lambda);
618  }
619 
620  output_results(cycle);
621  if (cycle < grid_refinement.get_n_refinement_cycles() - 1)
622  {
623  grid_refinement.estimate_mark_refine(space_dh,
624  solution,
625  space_grid);
626  adjust_grid_refinements(false);
627  }
628  deallog.pop();
629  }
630  error_table_space.output_table(std::cout);
631  if (n_basis > 0)
632  error_table_embedded.output_table(std::cout);
633  }
634 
635  template class ReducedLagrange<1, 2>;
636  template class ReducedLagrange<2, 2>;
637  template class ReducedLagrange<2, 3>;
638  template class ReducedLagrange<3, 3>;
639  } // namespace Serial
640 } // namespace PDEs
void add_line(const size_type line_n)
void merge(const AffineConstraints< other_number > &other_constraints, const MergeConflictBehavior merge_conflict_behavior=no_conflicts_allowed, const bool allow_different_local_lines=false)
void set_inhomogeneity(const size_type constrained_dof_index, const number value)
void vmult(Vector< number2 > &w, const Vector< number2 > &v, const bool adding=false) const
void invert(const FullMatrix< number2 > &M)
void push(const std::string &text)
unsigned int depth_console(const unsigned int n)
void pop()
void enter_subsection(const std::string &subsection)
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 initialize(const SparsityPattern &sparsity_pattern)
void output_results(const unsigned int cycle)
unsigned int embedded_space_finite_element_degree
unsigned int embedded_configuration_finite_element_degree
SchurPreconditioner schur_preconditioner
void adjust_grid_refinements(const bool apply_delta_refinement=true)
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
LinearOperator< Range, Range, Payload > identity_operator(const std::function< void(Range &, bool)> &reinit_vector)
LinearOperator< Domain, Range, Payload > transpose_operator(const LinearOperator< Range, Domain, Payload > &op)
LinearOperator< Range, Domain, TrilinosWrappers::internal::LinearOperatorImplementation::TrilinosPayload > linear_operator(const TrilinosWrappers::SparseMatrix &operator_exemplar, const Matrix &matrix)
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
LogStream deallog
double minimal_cell_diameter(const Triangulation< dim, spacedim > &triangulation, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()))
double diameter(const Triangulation< dim, spacedim > &tria)
double maximal_cell_diameter(const Triangulation< dim, spacedim > &triangulation, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()))
void create_mass_matrix(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim > &q, MatrixType &matrix, const Function< spacedim, typename MatrixType::value_type > *const a=nullptr, const AffineConstraints< typename MatrixType::value_type > &constraints=AffineConstraints< typename MatrixType::value_type >())
void create_coupling_sparsity_pattern(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, SparsityPatternBase &sparsity, const AffineConstraints< number > &constraints={}, const ComponentMask &space_comps={}, const ComponentMask &immersed_comps={}, const Mapping< dim0, spacedim > &space_mapping=StaticMappingQ1< dim0, spacedim >::mapping, const Mapping< dim1, spacedim > &immersed_mapping=StaticMappingQ1< dim1, spacedim >::mapping, const AffineConstraints< number > &immersed_constraints=AffineConstraints< number >())
void create_coupling_mass_matrix(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, Matrix &matrix, const AffineConstraints< typename Matrix::value_type > &constraints=AffineConstraints< typename Matrix::value_type >(), const ComponentMask &space_comps={}, const ComponentMask &immersed_comps={}, const Mapping< dim0, spacedim > &space_mapping=StaticMappingQ1< dim0, spacedim >::mapping, const Mapping< dim1, spacedim > &immersed_mapping=StaticMappingQ1< dim1, spacedim >::mapping, const AffineConstraints< typename Matrix::value_type > &immersed_constraints=AffineConstraints< typename Matrix::value_type >())
SymmetricTensor< 2, dim, Number > C(const Tensor< 2, dim, Number > &F)
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
unsigned int needed_digits(const unsigned int max_number)
void interpolate(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Function< spacedim, typename VectorType::value_type > &function, VectorType &vec, const ComponentMask &component_mask={})
void create_right_hand_side(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim > &q, const Function< spacedim, typename VectorType::value_type > &rhs, VectorType &rhs_vector, const AffineConstraints< typename VectorType::value_type > &constraints=AffineConstraints< typename VectorType::value_type >())
We collect in this namespace all PDEs that are relevant to Fluid Structure Interaction Problems.
std::unique_ptr< FiniteElement< dim, spacedim > > get_lagrangian_finite_element(const Triangulation< dim, spacedim > &tria, const unsigned int degree=1, const int continuity=0)
Get a Lagrangian FiniteElement object compatible with the given Triangulation object.
Quadrature< dim > get_cell_quadrature(const Triangulation< dim, spacedim > &tria, const unsigned int degree)
Return a Quadrature object that can be used on the given Triangulation cells.
LinearOperator< Range, Domain, Payload > projection_operator(const Range &range_exemplar, const std::vector< std::reference_wrapper< const Domain >> &local_basis, const Domain *domain_exemplar=nullptr, const Payload &payload=Payload())
Construct a LinearOperator object that projects a vector onto a basis.
STL namespace.