]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Split coupling.h into coupling.cc and coupling.inst
authorLuca Heltai <luca.heltai@sissa.it>
Tue, 6 Mar 2018 11:08:09 +0000 (12:08 +0100)
committerLuca Heltai <luca.heltai@sissa.it>
Tue, 6 Mar 2018 13:58:30 +0000 (14:58 +0100)
cmake/config/template-arguments.in
include/deal.II/non_matching/coupling.h
source/non_matching/CMakeLists.txt
source/non_matching/coupling.cc [new file with mode: 0644]
source/non_matching/coupling.inst.in [new file with mode: 0644]

index 5a239ba1b690fc805c8ab5e7c7356f59359b186f..fc9466d78d37a092098f1a072333707fd6ca513c 100644 (file)
@@ -174,9 +174,6 @@ VECTORS_WITH_MATRIX := { Vector<double>;
 SPARSE_MATRICES := { SparseMatrix<double>;
                     SparseMatrix<float>;
 
-                    SparseMatrixEZ<double>;
-                    SparseMatrixEZ<float>;
-
                     BlockSparseMatrix<double>;
                     BlockSparseMatrix<float>;
                   
index 3b8be3e477f2cbf7d4590f916cd593741147c752..9bdbd19e5aa8bd65dfe602db62d1d63dca552929 100644 (file)
@@ -1,6 +1,6 @@
 // ---------------------------------------------------------------------
 //
-// Copyright (C) 1998 - 2017 by the deal.II authors
+// Copyright (C) 2018 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -43,32 +43,34 @@ namespace NonMatching
    *
    * Given two non-matching triangulations, representing the domains $\Omega$
    * and $B$, with $B \subseteq \Omega$, and two finite element spaces
-   * $V(\Omega)$ and $Q(B)$, compute the sparsity pattern that would be
+   * $V(\Omega) = \text{span}\{v_i\}_{i=0}^n$ and $Q(B) =
+   * \text{span}\{w_j\}_{j=0}^m$, compute the sparsity pattern that would be
    * necessary to assemble the matrix
-   *
    * \f[
-   * M_{ij} := \int_{B} v_i(x) w_j(x) dx, \quad \foreach v_i \in V(\Omega), w_j \in Q(B)
+   * M_{ij} := \int_{B} v_i(x) w_j(x) dx, \quad i \in [0,n), j \in [0,m),
    * \f]
-   *
-   * where $V(\Omega)$ is the finite element space associated with `space_dh`
-   * (or part of it, if specified in `space_comps`), while $Q(B)$ is the finite
-   * element space associated with `immersed_dh` (or part of it, if specified
-   * in a `immersed_comps`).
-   *
-   * The `sparsity` is constructed by locating the position of quadrature
-   * points (obtained by the reference quadrature `quad`) defined on elements
-   * of $B$ with respect to the embedding triangulation $\Omega$. For each
-   * overlapping cell, the entries corresponding to `space_comps` in `space_dh`
-   * and `immersed_comps` in `immersed_dh` are added to the sparsity pattern.
+   * where $V(\Omega)$ is the finite element space associated with the
+   * `space_dh` passed to this function (or part of it, if specified in
+   * `space_comps`), while $Q(B)$ is the finite element space associated with
+   * the `immersed_dh` passed to this function (or part of it, if specified in
+   * `immersed_comps`).
+   *
+   * The `sparsity` is filled by locating the position of quadrature points
+   * (obtained by the reference quadrature `quad`) defined on elements of $B$
+   * with respect to the embedding triangulation $\Omega$. For each overlapping
+   * cell, the entries corresponding to `space_comps` in `space_dh` and
+   * `immersed_comps` in `immersed_dh` are added to the sparsity pattern.
    *
    * The `space_comps` and `immersed_comps` masks are assumed to be ordered in
    * the same way: the first component of `space_comps` will couple with the
    * first component of `immersed_comps`, the second with the second, and so
-   * on. If one of the two masks has more non-zero entries w.r.t. the other,
-   * then the excess components will be ignored.
+   * on. If one of the two masks has more non-zero than the other, then the
+   * excess components will be ignored.
    *
    * If the domain $B$ does not fall withing $\Omega$, an exception will be
-   * thrown by the algorithm that computes the quadrature point locations.
+   * thrown by the algorithm that computes the quadrature point locations. In
+   * particular, notice that this function only makes sens for `dim1` lower or
+   * equal than `dim0`. A static assert guards that this is actually the case.
    *
    * For both spaces, it is possible to specify a custom Mapping, which
    * defaults to StaticMappingQ1 for both.
@@ -88,20 +90,21 @@ namespace NonMatching
   /**
    * Create a coupling mass matrix for non-matching, overlapping grids.
    *
+   *
    * Given two non-matching triangulations, representing the domains $\Omega$
    * and $B$, with $B \subseteq \Omega$, and two finite element spaces
-   * $V(\Omega)$ and $Q(B)$, compute the matrix
-   *
+   * $V(\Omega) = \text{span}\{v_i\}_{i=0}^n$ and $Q(B) =
+   * \text{span}\{w_j\}_{j=0}^m$, compute the coupling matrix
    * \f[
-   * M_{ij} := \int_{B} v_i(x) w_j(x) dx, \quad \foreach v_i \in V(\Omega), w_j \in Q(B)
+   * M_{ij} := \int_{B} v_i(x) w_j(x) dx, \quad i \in [0,n), j \in [0,m),
    * \f]
+   * where $V(\Omega)$ is the finite element space associated with the
+   * `space_dh` passed to this function (or part of it, if specified in
+   * `space_comps`), while $Q(B)$ is the finite element space associated with
+   * the `immersed_dh` passed to this function (or part of it, if specified in
+   * `immersed_comps`).
    *
-   * where $V(\Omega)$ is the finite element space associated with `space_dh`
-   * (or part of it, if specified in `space_comps`), while $Q(B)$ is the finite
-   * element space associated with `immersed_dh` (or part of it, if specified
-   * in a `immersed_comps`).
-   *
-   * The corresponding `sparsity` can be computed by calling the
+   * The corresponding sparsity patterns can be computed by calling the
    * make_coupling_sparsity_pattern function. The elements of the matrix are
    * computed by locating the position of quadrature points defined on elements
    * of $B$ with respect to the embedding triangulation $\Omega$.
@@ -109,11 +112,13 @@ namespace NonMatching
    * The `space_comps` and `immersed_comps` masks are assumed to be ordered in
    * the same way: the first component of `space_comps` will couple with the
    * first component of `immersed_comps`, the second with the second, and so
-   * on. If one of the two masks has more non-zero entries w.r.t. the other,
-   * then the excess components will be ignored.
+   * on. If one of the two masks has more non-zero entries non-zero than the
+   * other, then the excess components will be ignored.
    *
    * If the domain $B$ does not fall withing $\Omega$, an exception will be
-   * thrown by the algorithm that computes the quadrature point locations.
+   * thrown by the algorithm that computes the quadrature point locations. In
+   * particular, notice that this function only makes sens for `dim1` lower or
+   * equal than `dim0`. A static assert guards that this is actually the case.
    *
    * For both spaces, it is possible to specify a custom Mapping, which
    * defaults to StaticMappingQ1 for both.
@@ -130,218 +135,6 @@ namespace NonMatching
                                    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);
-
-
-
-
-// === inline and template functions ===
-
-
-
-  template<int dim0, int dim1, int spacedim, typename Sparsity>
-  void create_coupling_sparsity_pattern(const DoFHandler<dim0, spacedim> &space_dh,
-                                        const DoFHandler<dim1, spacedim> &immersed_dh,
-                                        const Quadrature<dim1>           &quad,
-                                        Sparsity                         &sparsity,
-                                        const ComponentMask              &space_comps,
-                                        const ComponentMask              &immersed_comps,
-                                        const Mapping<dim0, spacedim>    &space_mapping,
-                                        const Mapping<dim1, spacedim>    &immersed_mapping)
-  {
-    AssertDimension(sparsity.n_rows(), space_dh.n_dofs());
-    AssertDimension(sparsity.n_cols(), immersed_dh.n_dofs());
-
-    const auto &space_fe = space_dh.get_fe();
-    const auto &immersed_fe = immersed_dh.get_fe();
-
-    // Now we run on ech cell, get a quadrature formula
-    typename DoFHandler<dim1,spacedim>::active_cell_iterator
-    cell = immersed_dh.begin_active(),
-    endc = immersed_dh.end();
-
-    // Dof indices
-    std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
-    std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
-
-    FEValues<dim1,spacedim> fe_v(immersed_mapping, immersed_fe, quad,
-                                 update_quadrature_points);
-
-    GridTools::Cache<dim0,spacedim> cache(space_dh.get_triangulation(), space_mapping);
-
-    // Take care of components
-    ComponentMask space_c = space_comps;
-    ComponentMask immersed_c = immersed_comps;
-    if (space_c.size() == 0)
-      space_c = ComponentMask(space_fe.n_components(), true);
-    if (immersed_c.size() == 0)
-      immersed_c = ComponentMask(immersed_fe.n_components(), true);
-
-    AssertDimension(space_c.size(), space_fe.n_components());
-    AssertDimension(immersed_c.size(), immersed_fe.n_components());
-
-
-    std::vector<unsigned int> space_gtl(space_fe.n_components(), numbers::invalid_unsigned_int);
-    std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(), numbers::invalid_unsigned_int);
-
-    for (unsigned int i=0, j=0; i<space_gtl.size(); ++i)
-      if (space_c[i])
-        space_gtl[i] = j++;
-
-    for (unsigned int i=0, j=0; i<immersed_gtl.size(); ++i)
-      if (immersed_c[i])
-        immersed_gtl[i] = j++;
-
-    for (; cell != endc; ++cell)
-      //    if(cell->subdomain_id() == this_mpi_process)
-      {
-        // Reinitialize the cell and the fe_values
-        fe_v.reinit(cell);
-        cell->get_dof_indices(dofs);
-
-        const std::vector<Point<spacedim> > &Xpoints = fe_v.get_quadrature_points();
-
-        // Get a list of outer cells, qpoints and maps.
-        const auto cpm = GridTools::compute_point_locations(cache, Xpoints);
-        const auto &cells = std::get<0>(cpm);
-
-        for (unsigned int c=0; c<cells.size(); ++c)
-          {
-            // Get the ones in the current outer cell
-            typename DoFHandler<dim0,spacedim>::cell_iterator
-            ocell(*cells[c], &space_dh);
-            ocell->get_dof_indices(odofs);
-            for (unsigned int i=0; i<odofs.size(); ++i)
-              {
-                const auto comp_i = space_fe.system_to_component_index(i).first;
-                if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
-                  {
-                    for (unsigned int j=0; j<dofs.size(); ++j)
-                      {
-                        const auto comp_j = immersed_fe.system_to_component_index(j).first;
-                        if (immersed_gtl[comp_j] == space_gtl[comp_i])
-                          sparsity.add(odofs[i],dofs[j]);
-                      }
-                  }
-              }
-          }
-      }
-  }
-
-
-
-  template<int dim0, int dim1, int spacedim, typename Matrix>
-  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,
-                                   const ComponentMask              &space_comps,
-                                   const ComponentMask              &immersed_comps,
-                                   const Mapping<dim0, spacedim>    &space_mapping,
-                                   const Mapping<dim1, spacedim>    &immersed_mapping)
-  {
-    AssertDimension(matrix.m(), space_dh.n_dofs());
-    AssertDimension(matrix.n(), immersed_dh.n_dofs());
-
-    const auto &space_fe = space_dh.get_fe();
-    const auto &immersed_fe = immersed_dh.get_fe();
-
-    // Dof indices
-    std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
-    std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
-
-    GridTools::Cache<dim0,spacedim> cache(space_dh.get_triangulation(), space_mapping);
-
-    // Take care of components
-    ComponentMask space_c = space_comps;
-    ComponentMask immersed_c = immersed_comps;
-    if (space_c.size() == 0)
-      space_c = ComponentMask(space_fe.n_components(), true);
-    if (immersed_c.size() == 0)
-      immersed_c = ComponentMask(immersed_fe.n_components(), true);
-
-    AssertDimension(space_c.size(), space_fe.n_components());
-    AssertDimension(immersed_c.size(), immersed_fe.n_components());
-
-    std::vector<unsigned int> space_gtl(space_fe.n_components(), numbers::invalid_unsigned_int);
-    std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(), numbers::invalid_unsigned_int);
-
-    for (unsigned int i=0, j=0; i<space_gtl.size(); ++i)
-      if (space_c[i])
-        space_gtl[i] = j++;
-
-    for (unsigned int i=0, j=0; i<immersed_gtl.size(); ++i)
-      if (immersed_c[i])
-        immersed_gtl[i] = j++;
-
-    FullMatrix<double> cell_matrix(space_dh.get_fe().dofs_per_cell,
-                                   immersed_dh.get_fe().dofs_per_cell);
-
-    FEValues<dim1,spacedim> fe_v(immersed_mapping, immersed_dh.get_fe(), quad,
-                                 update_JxW_values |
-                                 update_quadrature_points |
-                                 update_values);
-
-    // Now we run on ech cell, get a quadrature formula
-    typename DoFHandler<dim1,spacedim>::active_cell_iterator
-    cell = immersed_dh.begin_active(),
-    endc = immersed_dh.end();
-
-    for (; cell != endc; ++cell)
-      {
-        // Reinitialize the cell and the fe_values
-        fe_v.reinit(cell);
-        cell->get_dof_indices(dofs);
-
-        const std::vector<Point<spacedim> > &Xpoints = fe_v.get_quadrature_points();
-
-        // Get a list of outer cells, qpoints and maps.
-        const auto cpm      = GridTools::compute_point_locations(cache, Xpoints);
-        const auto &cells   = std::get<0>(cpm);
-        const auto &qpoints = std::get<1>(cpm);
-        const auto &maps    = std::get<2>(cpm);
-
-        for (unsigned int c=0; c<cells.size(); ++c)
-          {
-            // Get the ones in the current outer cell
-            typename DoFHandler<dim0,spacedim>::active_cell_iterator
-            ocell(*cells[c], &space_dh);
-            const std::vector< Point<spacedim> > &qps = qpoints[c];
-            const std::vector< unsigned int > &ids = maps[c];
-
-            FEValues<dim0,spacedim> o_fe_v(space_mapping, space_dh.get_fe(), qps,
-                                           update_values);
-            o_fe_v.reinit(ocell);
-            ocell->get_dof_indices(odofs);
-
-            // Reset the matrices.
-            cell_matrix = 0;
-
-            for (unsigned int i=0; i<space_dh.get_fe().dofs_per_cell; ++i)
-              {
-                const auto comp_i = space_dh.get_fe().system_to_component_index(i).first;
-                if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
-                  for (unsigned int j=0; j<immersed_dh.get_fe().dofs_per_cell; ++j)
-                    {
-                      const auto comp_j = immersed_dh.get_fe().system_to_component_index(j).first;
-                      if (space_gtl[comp_i] == immersed_gtl[comp_j])
-                        for (unsigned int oq=0; oq<o_fe_v.n_quadrature_points; ++oq)
-                          {
-                            // Get the corrisponding q point
-                            const unsigned int q=ids[oq];
-
-                            cell_matrix(i,j) += ( fe_v.shape_value(j,q) *
-                                                  o_fe_v.shape_value(i,oq) *
-                                                  fe_v.JxW(q) );
-                          }
-                    }
-              }
-
-            // Now assemble the matrices
-            constraints.distribute_local_to_global (cell_matrix, odofs, dofs, matrix);
-          }
-      }
-  }
 }
 DEAL_II_NAMESPACE_CLOSE
 
index f637e6d0de0948ca60dc135d53e20f53fd9d7f79..1dc55a371d0d5c3283a555538b490e77f4ba9816 100644 (file)
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
 SET(_src
+  coupling.cc
   immersed_surface_quadrature.cc
   )
 
 SET(_inst
+  coupling.inst.in
   )
 
 FILE(GLOB _header
diff --git a/source/non_matching/coupling.cc b/source/non_matching/coupling.cc
new file mode 100644 (file)
index 0000000..e4300f0
--- /dev/null
@@ -0,0 +1,249 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/non_matching/coupling.h>
+
+#include <deal.II/lac/sparsity_pattern.h>
+#include <deal.II/lac/sparse_matrix.h>
+#include <deal.II/lac/block_sparsity_pattern.h>
+#include <deal.II/lac/block_sparse_matrix.h>
+
+#include <deal.II/lac/trilinos_sparsity_pattern.h>
+#include <deal.II/lac/trilinos_sparse_matrix.h>
+#include <deal.II/lac/trilinos_block_sparse_matrix.h>
+
+#include <deal.II/lac/petsc_sparse_matrix.h>
+#include <deal.II/lac/petsc_parallel_sparse_matrix.h>
+#include <deal.II/lac/petsc_parallel_block_sparse_matrix.h>
+
+DEAL_II_NAMESPACE_OPEN
+namespace NonMatching
+{
+  template<int dim0, int dim1, int spacedim, typename Sparsity>
+  void create_coupling_sparsity_pattern(const DoFHandler<dim0, spacedim> &space_dh,
+                                        const DoFHandler<dim1, spacedim> &immersed_dh,
+                                        const Quadrature<dim1>           &quad,
+                                        Sparsity                         &sparsity,
+                                        const ComponentMask              &space_comps,
+                                        const ComponentMask              &immersed_comps,
+                                        const Mapping<dim0, spacedim>    &space_mapping,
+                                        const Mapping<dim1, spacedim>    &immersed_mapping)
+  {
+    AssertDimension(sparsity.n_rows(), space_dh.n_dofs());
+    AssertDimension(sparsity.n_cols(), immersed_dh.n_dofs());
+    static_assert(dim1 <= dim0, "This function can only work if dim1 <= dim0");
+
+    const auto &space_fe = space_dh.get_fe();
+    const auto &immersed_fe = immersed_dh.get_fe();
+
+    // Now we run on ech cell, get a quadrature formula
+    typename DoFHandler<dim1,spacedim>::active_cell_iterator
+    cell = immersed_dh.begin_active(),
+    endc = immersed_dh.end();
+
+    // Dof indices
+    std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
+    std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
+
+    FEValues<dim1,spacedim> fe_v(immersed_mapping, immersed_fe, quad,
+                                 update_quadrature_points);
+
+    GridTools::Cache<dim0,spacedim> cache(space_dh.get_triangulation(), space_mapping);
+
+    // Take care of components
+    const ComponentMask space_c
+      = (space_comps.size() == 0 ?
+         ComponentMask(space_fe.n_components(), true) :
+         space_comps);
+
+    const ComponentMask immersed_c
+      = (immersed_comps.size() == 0 ?
+         ComponentMask(immersed_fe.n_components(), true) :
+         immersed_comps);
+
+    AssertDimension(space_c.size(), space_fe.n_components());
+    AssertDimension(immersed_c.size(), immersed_fe.n_components());
+
+    std::vector<unsigned int> space_gtl(space_fe.n_components(), numbers::invalid_unsigned_int);
+    std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(), numbers::invalid_unsigned_int);
+
+    for (unsigned int i=0, j=0; i<space_gtl.size(); ++i)
+      if (space_c[i])
+        space_gtl[i] = j++;
+
+    for (unsigned int i=0, j=0; i<immersed_gtl.size(); ++i)
+      if (immersed_c[i])
+        immersed_gtl[i] = j++;
+
+    for (; cell != endc; ++cell)
+      {
+        // Reinitialize the cell and the fe_values
+        fe_v.reinit(cell);
+        cell->get_dof_indices(dofs);
+
+        const std::vector<Point<spacedim> > &Xpoints = fe_v.get_quadrature_points();
+
+        // Get a list of outer cells, qpoints and maps.
+        const auto cpm = GridTools::compute_point_locations(cache, Xpoints);
+        const auto &cells = std::get<0>(cpm);
+
+        for (unsigned int c=0; c<cells.size(); ++c)
+          {
+            // Get the ones in the current outer cell
+            typename DoFHandler<dim0,spacedim>::cell_iterator
+            ocell(*cells[c], &space_dh);
+            ocell->get_dof_indices(odofs);
+            for (unsigned int i=0; i<odofs.size(); ++i)
+              {
+                const auto comp_i = space_fe.system_to_component_index(i).first;
+                if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
+                  {
+                    for (unsigned int j=0; j<dofs.size(); ++j)
+                      {
+                        const auto comp_j = immersed_fe.system_to_component_index(j).first;
+                        if (immersed_gtl[comp_j] == space_gtl[comp_i])
+                          sparsity.add(odofs[i],dofs[j]);
+                      }
+                  }
+              }
+          }
+      }
+  }
+
+
+
+  template<int dim0, int dim1, int spacedim, typename Matrix>
+  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,
+                                   const ComponentMask              &space_comps,
+                                   const ComponentMask              &immersed_comps,
+                                   const Mapping<dim0, spacedim>    &space_mapping,
+                                   const Mapping<dim1, spacedim>    &immersed_mapping)
+  {
+    AssertDimension(matrix.m(), space_dh.n_dofs());
+    AssertDimension(matrix.n(), immersed_dh.n_dofs());
+    static_assert(dim1 <= dim0, "This function can only work if dim1 <= dim0");
+
+    const auto &space_fe = space_dh.get_fe();
+    const auto &immersed_fe = immersed_dh.get_fe();
+
+    // Dof indices
+    std::vector<types::global_dof_index> dofs(immersed_fe.dofs_per_cell);
+    std::vector<types::global_dof_index> odofs(space_fe.dofs_per_cell);
+
+    GridTools::Cache<dim0,spacedim> cache(space_dh.get_triangulation(), space_mapping);
+
+    // Take care of components
+    const ComponentMask space_c
+      = (space_comps.size() == 0 ?
+         ComponentMask(space_fe.n_components(), true) :
+         space_comps);
+
+    const ComponentMask immersed_c
+      = (immersed_comps.size() == 0 ?
+         ComponentMask(immersed_fe.n_components(), true) :
+         immersed_comps);
+
+    AssertDimension(space_c.size(), space_fe.n_components());
+    AssertDimension(immersed_c.size(), immersed_fe.n_components());
+
+    std::vector<unsigned int> space_gtl(space_fe.n_components(), numbers::invalid_unsigned_int);
+    std::vector<unsigned int> immersed_gtl(immersed_fe.n_components(), numbers::invalid_unsigned_int);
+
+    for (unsigned int i=0, j=0; i<space_gtl.size(); ++i)
+      if (space_c[i])
+        space_gtl[i] = j++;
+
+    for (unsigned int i=0, j=0; i<immersed_gtl.size(); ++i)
+      if (immersed_c[i])
+        immersed_gtl[i] = j++;
+
+    FullMatrix<typename Matrix::value_type> cell_matrix(space_dh.get_fe().dofs_per_cell,
+                                                        immersed_dh.get_fe().dofs_per_cell);
+
+    FEValues<dim1,spacedim> fe_v(immersed_mapping, immersed_dh.get_fe(), quad,
+                                 update_JxW_values |
+                                 update_quadrature_points |
+                                 update_values);
+
+    // Now we run on ech cell, get a quadrature formula
+    typename DoFHandler<dim1,spacedim>::active_cell_iterator
+    cell = immersed_dh.begin_active(),
+    endc = immersed_dh.end();
+
+    for (; cell != endc; ++cell)
+      {
+        // Reinitialize the cell and the fe_values
+        fe_v.reinit(cell);
+        cell->get_dof_indices(dofs);
+
+        const std::vector<Point<spacedim> > &Xpoints = fe_v.get_quadrature_points();
+
+        // Get a list of outer cells, qpoints and maps.
+        const auto cpm      = GridTools::compute_point_locations(cache, Xpoints);
+        const auto &cells   = std::get<0>(cpm);
+        const auto &qpoints = std::get<1>(cpm);
+        const auto &maps    = std::get<2>(cpm);
+
+        for (unsigned int c=0; c<cells.size(); ++c)
+          {
+            // Get the ones in the current outer cell
+            typename DoFHandler<dim0,spacedim>::active_cell_iterator
+            ocell(*cells[c], &space_dh);
+            const std::vector< Point<dim0> > &qps = qpoints[c];
+            const std::vector< unsigned int > &ids = maps[c];
+
+            FEValues<dim0,spacedim> o_fe_v(space_mapping, space_dh.get_fe(), qps,
+                                           update_values);
+            o_fe_v.reinit(ocell);
+            ocell->get_dof_indices(odofs);
+
+            // Reset the matrices.
+            cell_matrix = 0;
+
+            for (unsigned int i=0; i<space_dh.get_fe().dofs_per_cell; ++i)
+              {
+                const auto comp_i = space_dh.get_fe().system_to_component_index(i).first;
+                if (space_gtl[comp_i] != numbers::invalid_unsigned_int)
+                  for (unsigned int j=0; j<immersed_dh.get_fe().dofs_per_cell; ++j)
+                    {
+                      const auto comp_j = immersed_dh.get_fe().system_to_component_index(j).first;
+                      if (space_gtl[comp_i] == immersed_gtl[comp_j])
+                        for (unsigned int oq=0; oq<o_fe_v.n_quadrature_points; ++oq)
+                          {
+                            // Get the corrisponding q point
+                            const unsigned int q=ids[oq];
+
+                            cell_matrix(i,j) += ( fe_v.shape_value(j,q) *
+                                                  o_fe_v.shape_value(i,oq) *
+                                                  fe_v.JxW(q) );
+                          }
+                    }
+              }
+
+            // Now assemble the matrices
+            constraints.distribute_local_to_global (cell_matrix, odofs, dofs, matrix);
+          }
+      }
+  }
+
+#include "coupling.inst"
+}
+
+
+DEAL_II_NAMESPACE_CLOSE
diff --git a/source/non_matching/coupling.inst.in b/source/non_matching/coupling.inst.in
new file mode 100644 (file)
index 0000000..be53517
--- /dev/null
@@ -0,0 +1,48 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+for (dim0 : DIMENSIONS; dim1 :DIMENSIONS; spacedim :  SPACE_DIMENSIONS;
+        Sparsity : SPARSITY_PATTERNS)
+{
+#if dim1 <= dim0 && dim0 <= spacedim
+    template void create_coupling_sparsity_pattern(const DoFHandler<dim0, spacedim> &space_dh,
+            const DoFHandler<dim1, spacedim> &immersed_dh,
+            const Quadrature<dim1>           &quad,
+            Sparsity                         &sparsity,
+            const ComponentMask              &space_comps,
+            const ComponentMask              &immersed_comps,
+            const Mapping<dim0, spacedim>    &space_mapping,
+            const Mapping<dim1, spacedim>    &immersed_mapping);
+#endif
+}
+
+
+for (dim0 : DIMENSIONS; dim1 :DIMENSIONS; spacedim : SPACE_DIMENSIONS;
+        Matrix : SPARSE_MATRICES)
+{
+#if dim1 <= dim0 && dim0 <= spacedim
+    template
+    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,
+                                     const ComponentMask              &space_comps,
+                                     const ComponentMask              &immersed_comps,
+                                     const Mapping<dim0, spacedim>    &space_mapping,
+                                     const Mapping<dim1, spacedim>    &immersed_mapping);
+#endif
+}

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.