]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement FE_SimplexPoly::get_restriction_matrix() 11819/head
authorPeter Munch <peterrmuench@gmail.com>
Sun, 28 Feb 2021 06:13:53 +0000 (07:13 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Mon, 1 Mar 2021 11:42:33 +0000 (12:42 +0100)
include/deal.II/fe/fe_simplex_p.h
include/deal.II/fe/fe_tools.templates.h
source/fe/fe_simplex_p.cc

index 43fb6b08a3009edcc6084a6d52599e24b6891564..2d240489c67b9a46a3f73807a13a7098f2d82c27 100644 (file)
@@ -60,6 +60,17 @@ public:
     const RefinementCase<dim> &refinement_case =
       RefinementCase<dim>::isotropic_refinement) const override;
 
+  /**
+   * @copydoc dealii::FiniteElement::get_restriction_matrix()
+   *
+   * @note Only implemented for RefinementCase::isotropic_refinement.
+   */
+  virtual const FullMatrix<double> &
+  get_restriction_matrix(
+    const unsigned int         child,
+    const RefinementCase<dim> &refinement_case =
+      RefinementCase<dim>::isotropic_refinement) const override;
+
   /**
    * @copydoc dealii::FiniteElement::get_face_interpolation_matrix()
    */
index f96914254c5c3bf3f09c7bd505294a170024801f..48512f06fcd8e0fef6413c09ef114d8f3219d9c8 100644 (file)
@@ -2164,9 +2164,15 @@ namespace FETools
     const unsigned int nd     = fe.n_components();
     const unsigned int degree = fe.degree;
 
+    const ReferenceCell reference_cell = fe.reference_cell();
+
+    const auto &mapping =
+      reference_cell.template get_default_linear_mapping<dim, spacedim>();
+    const auto &q_fine =
+      reference_cell.get_gauss_type_quadrature<dim>(degree + 1);
+
     // prepare FEValues, quadrature etc on
     // coarse cell
-    QGauss<dim>        q_fine(degree + 1);
     const unsigned int nq = q_fine.size();
 
     // create mass matrix on coarse cell.
@@ -2174,9 +2180,10 @@ namespace FETools
     {
       // set up a triangulation for coarse cell
       Triangulation<dim, spacedim> tr;
-      GridGenerator::hyper_cube(tr, 0, 1);
+      GridGenerator::reference_cell(reference_cell, tr);
 
-      FEValues<dim, spacedim> coarse(fe,
+      FEValues<dim, spacedim> coarse(mapping,
+                                     fe,
                                      q_fine,
                                      update_JxW_values | update_values);
 
@@ -2212,9 +2219,10 @@ namespace FETools
 
 
     const auto compute_one_case =
-      [&fe, &q_fine, n, nd, nq](const unsigned int        ref_case,
-                                const FullMatrix<double> &inverse_mass_matrix,
-                                std::vector<FullMatrix<double>> &matrices) {
+      [&reference_cell, &mapping, &fe, &q_fine, n, nd, nq](
+        const unsigned int               ref_case,
+        const FullMatrix<double> &       inverse_mass_matrix,
+        std::vector<FullMatrix<double>> &matrices) {
         const unsigned int nc =
           GeometryInfo<dim>::n_children(RefinementCase<dim>(ref_case));
 
@@ -2228,11 +2236,12 @@ namespace FETools
 
         // create a respective refinement on the triangulation
         Triangulation<dim, spacedim> tr;
-        GridGenerator::hyper_cube(tr, 0, 1);
+        GridGenerator::reference_cell(reference_cell, tr);
         tr.begin_active()->set_refine_flag(RefinementCase<dim>(ref_case));
         tr.execute_coarsening_and_refinement();
 
-        FEValues<dim, spacedim> fine(fe,
+        FEValues<dim, spacedim> fine(mapping,
+                                     fe,
                                      q_fine,
                                      update_quadrature_points |
                                        update_JxW_values | update_values);
index 9f32a2f2933f3929e2760d8b60c84f6e7ab2fa1c..fe9b39cab5d6b9c33b689876fea746a09a44f781 100644 (file)
@@ -354,6 +354,48 @@ FE_SimplexPoly<dim, spacedim>::get_prolongation_matrix(
 
 
 
+template <int dim, int spacedim>
+const FullMatrix<double> &
+FE_SimplexPoly<dim, spacedim>::get_restriction_matrix(
+  const unsigned int         child,
+  const RefinementCase<dim> &refinement_case) const
+{
+  Assert(refinement_case == RefinementCase<dim>::isotropic_refinement,
+         ExcNotImplemented());
+  AssertDimension(dim, spacedim);
+
+  // initialization upon first request
+  if (this->restriction[refinement_case - 1][child].n() == 0)
+    {
+      std::lock_guard<std::mutex> lock(this->mutex);
+
+      // if matrix got updated while waiting for the lock
+      if (this->restriction[refinement_case - 1][child].n() ==
+          this->n_dofs_per_cell())
+        return this->restriction[refinement_case - 1][child];
+
+      // now do the work. need to get a non-const version of data in order to
+      // be able to modify them inside a const function
+      auto &this_nonconst = const_cast<FE_SimplexPoly<dim, spacedim> &>(*this);
+
+      std::vector<std::vector<FullMatrix<double>>> isotropic_matrices(
+        RefinementCase<dim>::isotropic_refinement);
+      isotropic_matrices.back().resize(
+        GeometryInfo<dim>::n_children(RefinementCase<dim>(refinement_case)),
+        FullMatrix<double>(this->n_dofs_per_cell(), this->n_dofs_per_cell()));
+
+      FETools::compute_projection_matrices(*this, isotropic_matrices, true);
+
+      this_nonconst.restriction[refinement_case - 1].swap(
+        isotropic_matrices.back());
+    }
+
+  // finally return the matrix
+  return this->restriction[refinement_case - 1][child];
+}
+
+
+
 template <int dim, int spacedim>
 void
 FE_SimplexPoly<dim, spacedim>::get_face_interpolation_matrix(

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.