Reference documentation for deal.II version 9.0.0
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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/exceptions.h>
17 
18 #include <deal.II/non_matching/coupling.h>
19 
20 #include <deal.II/lac/sparsity_pattern.h>
21 #include <deal.II/lac/sparse_matrix.h>
22 #include <deal.II/lac/block_sparsity_pattern.h>
23 #include <deal.II/lac/block_sparse_matrix.h>
24 
25 #include <deal.II/lac/trilinos_sparsity_pattern.h>
26 #include <deal.II/lac/trilinos_sparse_matrix.h>
27 #include <deal.II/lac/trilinos_block_sparse_matrix.h>
28 
29 #include <deal.II/lac/petsc_sparse_matrix.h>
30 #include <deal.II/lac/petsc_parallel_sparse_matrix.h>
31 #include <deal.II/lac/petsc_parallel_block_sparse_matrix.h>
32 
33 #include <deal.II/fe/fe_values.h>
34 
35 #include <deal.II/base/point.h>
36 #include <deal.II/base/tensor.h>
37 
38 #include <deal.II/grid/grid_tools.h>
39 #include <deal.II/grid/grid_tools_cache.h>
40 
41 #include <deal.II/distributed/tria.h>
42 #include <deal.II/distributed/shared_tria.h>
43 
44 DEAL_II_NAMESPACE_OPEN
45 namespace NonMatching
46 {
47  template<int dim0, int dim1, int spacedim, typename Sparsity>
49  const DoFHandler<dim1, spacedim> &immersed_dh,
50  const Quadrature<dim1> &quad,
51  Sparsity &sparsity,
52  const ConstraintMatrix &constraints,
53  const ComponentMask &space_comps,
54  const ComponentMask &immersed_comps,
55  const Mapping<dim0, spacedim> &space_mapping,
56  const Mapping<dim1, spacedim> &immersed_mapping)
57  {
58  GridTools::Cache<dim0,spacedim> cache(space_dh.get_triangulation(), space_mapping);
59  create_coupling_sparsity_pattern(cache, space_dh, immersed_dh,
60  quad, sparsity, constraints,
61  space_comps, immersed_comps,
62  immersed_mapping);
63  }
64 
65 
66 
67  template<int dim0, int dim1, int spacedim, typename Sparsity>
69  const DoFHandler<dim0, spacedim> &space_dh,
70  const DoFHandler<dim1, spacedim> &immersed_dh,
71  const Quadrature<dim1> &quad,
72  Sparsity &sparsity,
73  const ConstraintMatrix &constraints,
74  const ComponentMask &space_comps,
75  const ComponentMask &immersed_comps,
76  const Mapping<dim1, spacedim> &immersed_mapping)
77  {
78  AssertDimension(sparsity.n_rows(), space_dh.n_dofs());
79  AssertDimension(sparsity.n_cols(), immersed_dh.n_dofs());
80  static_assert(dim1 <= dim0, "This function can only work if dim1 <= dim0");
82  (&immersed_dh.get_triangulation()) == nullptr), ExcNotImplemented());
83 
84  const auto &space_fe = space_dh.get_fe();
85  const auto &immersed_fe = immersed_dh.get_fe();
86 
87  // Now we run on ech cell, get a quadrature formula
89  cell = immersed_dh.begin_active(),
90  endc = immersed_dh.end();
91 
92  // Dof indices
93  std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
94  std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
95 
96  FEValues<dim1,spacedim> fe_v(immersed_mapping, immersed_fe, quad,
98 
99  // Take care of components
100  const ComponentMask space_c
101  = (space_comps.size() == 0 ?
102  ComponentMask(space_fe.n_components(), true) :
103  space_comps);
104 
105  const ComponentMask immersed_c
106  = (immersed_comps.size() == 0 ?
107  ComponentMask(immersed_fe.n_components(), true) :
108  immersed_comps);
109 
110  AssertDimension(space_c.size(), space_fe.n_components());
111  AssertDimension(immersed_c.size(), immersed_fe.n_components());
112 
113  std::vector<unsigned int> space_gtl(space_fe.n_components(), numbers::invalid_unsigned_int);
114  std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(), numbers::invalid_unsigned_int);
115 
116  for (unsigned int i=0, j=0; i<space_gtl.size(); ++i)
117  if (space_c[i])
118  space_gtl[i] = j++;
119 
120  for (unsigned int i=0, j=0; i<immersed_gtl.size(); ++i)
121  if (immersed_c[i])
122  immersed_gtl[i] = j++;
123 
124  // [TODO]: when the add_entries_local_to_global below will implement
125  // the version with the dof_mask, this should be uncommented.
126  //
127  // // Construct a dof_mask, used to distribute entries to the sparsity
128  // able< 2, bool > dof_mask(space_fe.dofs_per_cell,
129  // immersed_fe.dofs_per_cell);
130  // of_mask.fill(false);
131  // or (unsigned int i=0; i<space_fe.dofs_per_cell; ++i)
132  // {
133  // const auto comp_i = space_fe.system_to_component_index(i).first;
134  // if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
135  // for (unsigned int j=0; j<immersed_fe.dofs_per_cell; ++j)
136  // {
137  // const auto comp_j = immersed_fe.system_to_component_index(j).first;
138  // if (immersed_gtl[comp_j] == space_gtl[comp_i])
139  // dof_mask(i,j) = true;
140  // }
141  // }
142 
143  for (; cell != endc; ++cell)
144  {
145  // Reinitialize the cell and the fe_values
146  fe_v.reinit(cell);
147  cell->get_dof_indices(dofs);
148 
149  const std::vector<Point<spacedim> > &Xpoints = fe_v.get_quadrature_points();
150 
151  // Get a list of outer cells, qpoints and maps.
152  const auto cpm = GridTools::compute_point_locations(cache, Xpoints);
153  const auto &cells = std::get<0>(cpm);
154 
155  for (unsigned int c=0; c<cells.size(); ++c)
156  {
157  // Get the ones in the current outer cell
159  ocell(*cells[c], &space_dh);
160  // Make sure we act only on locally_owned cells
161  if (ocell->is_locally_owned())
162  {
163  ocell->get_dof_indices(odofs);
164  // [TODO]: When the following function will be implemented
165  // for the case of non-trivial dof_mask, we should
166  // uncomment the missing part.
167  constraints.add_entries_local_to_global(odofs, dofs, sparsity); //, true, dof_mask);
168  }
169  }
170  }
171  }
172 
173 
174 
175  template<int dim0, int dim1, int spacedim, typename Matrix>
177  const DoFHandler<dim1, spacedim> &immersed_dh,
178  const Quadrature<dim1> &quad,
179  Matrix &matrix,
180  const ConstraintMatrix &constraints,
181  const ComponentMask &space_comps,
182  const ComponentMask &immersed_comps,
183  const Mapping<dim0, spacedim> &space_mapping,
184  const Mapping<dim1, spacedim> &immersed_mapping)
185  {
186  GridTools::Cache<dim0,spacedim> cache(space_dh.get_triangulation(), space_mapping);
187  create_coupling_mass_matrix(cache, space_dh, immersed_dh,
188  quad, matrix, constraints, space_comps, immersed_comps,
189  immersed_mapping);
190  }
191 
192 
193 
194  template<int dim0, int dim1, int spacedim, typename Matrix>
196  const DoFHandler<dim0, spacedim> &space_dh,
197  const DoFHandler<dim1, spacedim> &immersed_dh,
198  const Quadrature<dim1> &quad,
199  Matrix &matrix,
200  const ConstraintMatrix &constraints,
201  const ComponentMask &space_comps,
202  const ComponentMask &immersed_comps,
203  const Mapping<dim1, spacedim> &immersed_mapping)
204  {
205  AssertDimension(matrix.m(), space_dh.n_dofs());
206  AssertDimension(matrix.n(), immersed_dh.n_dofs());
207  static_assert(dim1 <= dim0, "This function can only work if dim1 <= dim0");
209  (&immersed_dh.get_triangulation()) == nullptr), ExcNotImplemented());
210 
211  const auto &space_fe = space_dh.get_fe();
212  const auto &immersed_fe = immersed_dh.get_fe();
213 
214  // Dof indices
215  std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
216  std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
217 
218  // Take care of components
219  const ComponentMask space_c
220  = (space_comps.size() == 0 ?
221  ComponentMask(space_fe.n_components(), true) :
222  space_comps);
223 
224  const ComponentMask immersed_c
225  = (immersed_comps.size() == 0 ?
226  ComponentMask(immersed_fe.n_components(), true) :
227  immersed_comps);
228 
229  AssertDimension(space_c.size(), space_fe.n_components());
230  AssertDimension(immersed_c.size(), immersed_fe.n_components());
231 
232  std::vector<unsigned int> space_gtl(space_fe.n_components(), numbers::invalid_unsigned_int);
233  std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(), numbers::invalid_unsigned_int);
234 
235  for (unsigned int i=0, j=0; i<space_gtl.size(); ++i)
236  if (space_c[i])
237  space_gtl[i] = j++;
238 
239  for (unsigned int i=0, j=0; i<immersed_gtl.size(); ++i)
240  if (immersed_c[i])
241  immersed_gtl[i] = j++;
242 
243  FullMatrix<typename Matrix::value_type> cell_matrix(space_dh.get_fe().dofs_per_cell,
244  immersed_dh.get_fe().dofs_per_cell);
245 
246  FEValues<dim1,spacedim> fe_v(immersed_mapping, immersed_dh.get_fe(), quad,
249  update_values);
250 
251  // Now we run on ech cell, get a quadrature formula
253  cell = immersed_dh.begin_active(),
254  endc = immersed_dh.end();
255 
256  for (; cell != endc; ++cell)
257  {
258  // Reinitialize the cell and the fe_values
259  fe_v.reinit(cell);
260  cell->get_dof_indices(dofs);
261 
262  const std::vector<Point<spacedim> > &Xpoints = fe_v.get_quadrature_points();
263 
264  // Get a list of outer cells, qpoints and maps.
265  const auto cpm = GridTools::compute_point_locations(cache, Xpoints);
266  const auto &cells = std::get<0>(cpm);
267  const auto &qpoints = std::get<1>(cpm);
268  const auto &maps = std::get<2>(cpm);
269 
270  for (unsigned int c=0; c<cells.size(); ++c)
271  {
272  // Get the ones in the current outer cell
274  ocell(*cells[c], &space_dh);
275  // Make sure we act only on locally_owned cells
276  if (ocell->is_locally_owned())
277  {
278  const std::vector< Point<dim0> > &qps = qpoints[c];
279  const std::vector< unsigned int > &ids = maps[c];
280 
281  FEValues<dim0,spacedim> o_fe_v(cache.get_mapping(), space_dh.get_fe(), qps,
282  update_values);
283  o_fe_v.reinit(ocell);
284  ocell->get_dof_indices(odofs);
285 
286  // Reset the matrices.
287  cell_matrix = typename Matrix::value_type();
288 
289  for (unsigned int i=0; i<space_dh.get_fe().dofs_per_cell; ++i)
290  {
291  const auto comp_i = space_dh.get_fe().system_to_component_index(i).first;
292  if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
293  for (unsigned int j=0; j<immersed_dh.get_fe().dofs_per_cell; ++j)
294  {
295  const auto comp_j = immersed_dh.get_fe().system_to_component_index(j).first;
296  if (space_gtl[comp_i] == immersed_gtl[comp_j])
297  for (unsigned int oq=0; oq<o_fe_v.n_quadrature_points; ++oq)
298  {
299  // Get the corresponding q point
300  const unsigned int q=ids[oq];
301 
302  cell_matrix(i,j) += ( fe_v.shape_value(j,q) *
303  o_fe_v.shape_value(i,oq) *
304  fe_v.JxW(q) );
305  }
306  }
307  }
308 
309  // Now assemble the matrices
310  constraints.distribute_local_to_global (cell_matrix, odofs, dofs, matrix);
311  }
312  }
313  }
314  }
315 
316 #include "coupling.inst"
317 }
318 
319 
320 DEAL_II_NAMESPACE_CLOSE
Transformed quadrature weights.
Shape function values.
static const unsigned int invalid_unsigned_int
Definition: types.h:173
void create_coupling_mass_matrix(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, Matrix &matrix, const ConstraintMatrix &constraints=ConstraintMatrix(), 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:176
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
void create_coupling_sparsity_pattern(const DoFHandler< dim0, spacedim > &space_dh, const DoFHandler< dim1, spacedim > &immersed_dh, const Quadrature< dim1 > &quad, Sparsity &sparsity, const ConstraintMatrix &constraints=ConstraintMatrix(), 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:48
const Mapping< dim, spacedim > & get_mapping() const
cell_iterator end() const
Definition: dof_handler.cc:751
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:229
Transformed quadrature points.
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: dof_handler.cc:735
const std::vector< Point< spacedim > > & get_quadrature_points() const
ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:257
#define Assert(cond, exc)
Definition: exceptions.h:1142
Abstract base class for mapping classes.
Definition: dof_tools.h:46
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
types::global_dof_index n_dofs() const
unsigned int size() const
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:3841
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=default_empty_table) const
Definition: fe.h:33
static ::ExceptionBase & ExcNotImplemented()
const Triangulation< dim, spacedim > & get_triangulation() const
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
Definition: fe_values.cc:4106