Reference documentation for deal.II version 9.1.0-pre
coupling.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/exceptions.h>
17 #include <deal.II/base/point.h>
18 #include <deal.II/base/tensor.h>
19 
20 #include <deal.II/distributed/shared_tria.h>
21 #include <deal.II/distributed/tria.h>
22 
23 #include <deal.II/fe/fe_values.h>
24 
25 #include <deal.II/grid/grid_tools.h>
26 #include <deal.II/grid/grid_tools_cache.h>
27 
28 #include <deal.II/lac/block_sparse_matrix.h>
29 #include <deal.II/lac/block_sparsity_pattern.h>
30 #include <deal.II/lac/petsc_block_sparse_matrix.h>
31 #include <deal.II/lac/petsc_sparse_matrix.h>
32 #include <deal.II/lac/sparse_matrix.h>
33 #include <deal.II/lac/sparsity_pattern.h>
34 #include <deal.II/lac/trilinos_block_sparse_matrix.h>
35 #include <deal.II/lac/trilinos_sparse_matrix.h>
36 #include <deal.II/lac/trilinos_sparsity_pattern.h>
37 
38 #include <deal.II/non_matching/coupling.h>
39 
40 DEAL_II_NAMESPACE_OPEN
41 namespace NonMatching
42 {
43  template <int dim0,
44  int dim1,
45  int spacedim,
46  typename Sparsity,
47  typename number>
48  void
50  const DoFHandler<dim0, spacedim> &space_dh,
51  const DoFHandler<dim1, spacedim> &immersed_dh,
52  const Quadrature<dim1> & quad,
53  Sparsity & sparsity,
54  const AffineConstraints<number> & constraints,
55  const ComponentMask & space_comps,
56  const ComponentMask & immersed_comps,
57  const Mapping<dim0, spacedim> & space_mapping,
58  const Mapping<dim1, spacedim> & immersed_mapping)
59  {
61  space_mapping);
63  space_dh,
64  immersed_dh,
65  quad,
66  sparsity,
67  constraints,
68  space_comps,
69  immersed_comps,
70  immersed_mapping);
71  }
72 
73 
74 
75  template <int dim0,
76  int dim1,
77  int spacedim,
78  typename Sparsity,
79  typename number>
80  void
83  const DoFHandler<dim0, spacedim> & space_dh,
84  const DoFHandler<dim1, spacedim> & immersed_dh,
85  const Quadrature<dim1> & quad,
86  Sparsity & sparsity,
87  const AffineConstraints<number> & constraints,
88  const ComponentMask & space_comps,
89  const ComponentMask & immersed_comps,
90  const Mapping<dim1, spacedim> & immersed_mapping)
91  {
92  AssertDimension(sparsity.n_rows(), space_dh.n_dofs());
93  AssertDimension(sparsity.n_cols(), immersed_dh.n_dofs());
94  static_assert(dim1 <= dim0, "This function can only work if dim1 <= dim0");
95  Assert((dynamic_cast<
97  &immersed_dh.get_triangulation()) == nullptr),
99 
100  const auto &space_fe = space_dh.get_fe();
101  const auto &immersed_fe = immersed_dh.get_fe();
102 
103  // Now we run on ech cell, get a quadrature formula
105  cell = immersed_dh.begin_active(),
106  endc = immersed_dh.end();
107 
108  // Dof indices
109  std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
110  std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
111 
112  FEValues<dim1, spacedim> fe_v(immersed_mapping,
113  immersed_fe,
114  quad,
116 
117  // Take care of components
118  const ComponentMask space_c =
119  (space_comps.size() == 0 ? ComponentMask(space_fe.n_components(), true) :
120  space_comps);
121 
122  const ComponentMask immersed_c =
123  (immersed_comps.size() == 0 ?
124  ComponentMask(immersed_fe.n_components(), true) :
125  immersed_comps);
126 
127  AssertDimension(space_c.size(), space_fe.n_components());
128  AssertDimension(immersed_c.size(), immersed_fe.n_components());
129 
130  std::vector<unsigned int> space_gtl(space_fe.n_components(),
132  std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(),
134 
135  for (unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
136  if (space_c[i])
137  space_gtl[i] = j++;
138 
139  for (unsigned int i = 0, j = 0; i < immersed_gtl.size(); ++i)
140  if (immersed_c[i])
141  immersed_gtl[i] = j++;
142 
143  // [TODO]: when the add_entries_local_to_global below will implement
144  // the version with the dof_mask, this should be uncommented.
145  //
146  // // Construct a dof_mask, used to distribute entries to the sparsity
147  // able< 2, bool > dof_mask(space_fe.dofs_per_cell,
148  // immersed_fe.dofs_per_cell);
149  // of_mask.fill(false);
150  // or (unsigned int i=0; i<space_fe.dofs_per_cell; ++i)
151  // {
152  // const auto comp_i = space_fe.system_to_component_index(i).first;
153  // if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
154  // for (unsigned int j=0; j<immersed_fe.dofs_per_cell; ++j)
155  // {
156  // const auto comp_j =
157  // immersed_fe.system_to_component_index(j).first; if
158  // (immersed_gtl[comp_j] == space_gtl[comp_i])
159  // dof_mask(i,j) = true;
160  // }
161  // }
162 
163  for (; cell != endc; ++cell)
164  {
165  // Reinitialize the cell and the fe_values
166  fe_v.reinit(cell);
167  cell->get_dof_indices(dofs);
168 
169  const std::vector<Point<spacedim>> &Xpoints =
170  fe_v.get_quadrature_points();
171 
172  // Get a list of outer cells, qpoints and maps.
173  const auto cpm = GridTools::compute_point_locations(cache, Xpoints);
174  const auto &cells = std::get<0>(cpm);
175 
176  for (unsigned int c = 0; c < cells.size(); ++c)
177  {
178  // Get the ones in the current outer cell
179  typename DoFHandler<dim0, spacedim>::cell_iterator ocell(*cells[c],
180  &space_dh);
181  // Make sure we act only on locally_owned cells
182  if (ocell->is_locally_owned())
183  {
184  ocell->get_dof_indices(odofs);
185  // [TODO]: When the following function will be implemented
186  // for the case of non-trivial dof_mask, we should
187  // uncomment the missing part.
188  constraints.add_entries_local_to_global(
189  odofs, dofs, sparsity); //, true, dof_mask);
190  }
191  }
192  }
193  }
194 
195 
196 
197  template <int dim0, int dim1, int spacedim, typename Matrix>
198  void
200  const DoFHandler<dim0, spacedim> & space_dh,
201  const DoFHandler<dim1, spacedim> & immersed_dh,
202  const Quadrature<dim1> & quad,
203  Matrix & matrix,
205  const ComponentMask & space_comps,
206  const ComponentMask & immersed_comps,
207  const Mapping<dim0, spacedim> & space_mapping,
208  const Mapping<dim1, spacedim> & immersed_mapping)
209  {
211  space_mapping);
213  space_dh,
214  immersed_dh,
215  quad,
216  matrix,
217  constraints,
218  space_comps,
219  immersed_comps,
220  immersed_mapping);
221  }
222 
223 
224 
225  template <int dim0, int dim1, int spacedim, typename Matrix>
226  void
228  const GridTools::Cache<dim0, spacedim> & cache,
229  const DoFHandler<dim0, spacedim> & space_dh,
230  const DoFHandler<dim1, spacedim> & immersed_dh,
231  const Quadrature<dim1> & quad,
232  Matrix & matrix,
234  const ComponentMask & space_comps,
235  const ComponentMask & immersed_comps,
236  const Mapping<dim1, spacedim> & immersed_mapping)
237  {
238  AssertDimension(matrix.m(), space_dh.n_dofs());
239  AssertDimension(matrix.n(), immersed_dh.n_dofs());
240  static_assert(dim1 <= dim0, "This function can only work if dim1 <= dim0");
241  Assert((dynamic_cast<
243  &immersed_dh.get_triangulation()) == nullptr),
245 
246  const auto &space_fe = space_dh.get_fe();
247  const auto &immersed_fe = immersed_dh.get_fe();
248 
249  // Dof indices
250  std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
251  std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
252 
253  // Take care of components
254  const ComponentMask space_c =
255  (space_comps.size() == 0 ? ComponentMask(space_fe.n_components(), true) :
256  space_comps);
257 
258  const ComponentMask immersed_c =
259  (immersed_comps.size() == 0 ?
260  ComponentMask(immersed_fe.n_components(), true) :
261  immersed_comps);
262 
263  AssertDimension(space_c.size(), space_fe.n_components());
264  AssertDimension(immersed_c.size(), immersed_fe.n_components());
265 
266  std::vector<unsigned int> space_gtl(space_fe.n_components(),
268  std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(),
270 
271  for (unsigned int i = 0, j = 0; i < space_gtl.size(); ++i)
272  if (space_c[i])
273  space_gtl[i] = j++;
274 
275  for (unsigned int i = 0, j = 0; i < immersed_gtl.size(); ++i)
276  if (immersed_c[i])
277  immersed_gtl[i] = j++;
278 
280  space_dh.get_fe().dofs_per_cell, immersed_dh.get_fe().dofs_per_cell);
281 
282  FEValues<dim1, spacedim> fe_v(immersed_mapping,
283  immersed_dh.get_fe(),
284  quad,
286  update_values);
287 
288  // Now we run on ech cell, get a quadrature formula
290  cell = immersed_dh.begin_active(),
291  endc = immersed_dh.end();
292 
293  for (; cell != endc; ++cell)
294  {
295  // Reinitialize the cell and the fe_values
296  fe_v.reinit(cell);
297  cell->get_dof_indices(dofs);
298 
299  const std::vector<Point<spacedim>> &Xpoints =
300  fe_v.get_quadrature_points();
301 
302  // Get a list of outer cells, qpoints and maps.
303  const auto cpm = GridTools::compute_point_locations(cache, Xpoints);
304  const auto &cells = std::get<0>(cpm);
305  const auto &qpoints = std::get<1>(cpm);
306  const auto &maps = std::get<2>(cpm);
307 
308  for (unsigned int c = 0; c < cells.size(); ++c)
309  {
310  // Get the ones in the current outer cell
312  *cells[c], &space_dh);
313  // Make sure we act only on locally_owned cells
314  if (ocell->is_locally_owned())
315  {
316  const std::vector<Point<dim0>> & qps = qpoints[c];
317  const std::vector<unsigned int> &ids = maps[c];
318 
319  FEValues<dim0, spacedim> o_fe_v(cache.get_mapping(),
320  space_dh.get_fe(),
321  qps,
322  update_values);
323  o_fe_v.reinit(ocell);
324  ocell->get_dof_indices(odofs);
325 
326  // Reset the matrices.
327  cell_matrix = typename Matrix::value_type();
328 
329  for (unsigned int i = 0; i < space_dh.get_fe().dofs_per_cell;
330  ++i)
331  {
332  const auto comp_i =
333  space_dh.get_fe().system_to_component_index(i).first;
334  if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
335  for (unsigned int j = 0;
336  j < immersed_dh.get_fe().dofs_per_cell;
337  ++j)
338  {
339  const auto comp_j = immersed_dh.get_fe()
340  .system_to_component_index(j)
341  .first;
342  if (space_gtl[comp_i] == immersed_gtl[comp_j])
343  for (unsigned int oq = 0;
344  oq < o_fe_v.n_quadrature_points;
345  ++oq)
346  {
347  // Get the corresponding q point
348  const unsigned int q = ids[oq];
349 
350  cell_matrix(i, j) +=
351  (fe_v.shape_value(j, q) *
352  o_fe_v.shape_value(i, oq) * fe_v.JxW(q));
353  }
354  }
355  }
356 
357  // Now assemble the matrices
358  constraints.distribute_local_to_global(cell_matrix,
359  odofs,
360  dofs,
361  matrix);
362  }
363  }
364  }
365  }
366 
367 #include "coupling.inst"
368 } // namespace NonMatching
369 
370 
371 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
Shape function values.
static const unsigned int invalid_unsigned_int
Definition: types.h:173
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: dof_handler.cc:943
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
Transformed quadrature points.
const Triangulation< dim, spacedim > & get_triangulation() const
void create_coupling_sparsity_pattern(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, Sparsity &sparsity, const AffineConstraints< number > &constraints=AffineConstraints< number >(), const ComponentMask &space_comps=ComponentMask(), const ComponentMask &immersed_comps=ComponentMask(), const Mapping< dim0, spacedim > &space_mapping=StaticMappingQ1< dim0, spacedim >::mapping, const Mapping< dim1, spacedim > &immersed_mapping=StaticMappingQ1< dim1, spacedim >::mapping)
Definition: coupling.cc:49
const std::vector< Point< spacedim > > & get_quadrature_points() const
#define Assert(cond, exc)
Definition: exceptions.h:1227
types::global_dof_index n_dofs() const
Abstract base class for mapping classes.
Definition: dof_tools.h:57
unsigned int size() const
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
cell_iterator end() const
Definition: dof_handler.cc:959
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access >> &cell)
Definition: fe_values.cc:4638
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=ComponentMask(), const ComponentMask &immersed_comps=ComponentMask(), const Mapping< dim0, spacedim > &space_mapping=StaticMappingQ1< dim0, spacedim >::mapping, const Mapping< dim1, spacedim > &immersed_mapping=StaticMappingQ1< dim1, spacedim >::mapping)
Definition: coupling.cc:199
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
void add_entries_local_to_global(const std::vector< size_type > &local_dof_indices, SparsityPatternType &sparsity_pattern, const bool keep_constrained_entries=true, const Table< 2, bool > &dof_mask=Table< 2, bool >()) const
Definition: fe.h:36
static::ExceptionBase & ExcNotImplemented()
return_type compute_point_locations(const Cache< dim, spacedim > &cache, const std::vector< Point< spacedim >> &points, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell_hint=typename Triangulation< dim, spacedim >::active_cell_iterator())
Definition: grid_tools.cc:3999
const Mapping< dim, spacedim > & get_mapping() const
typename ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:268
typename ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:240