]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add 37 test files checking many aspects of FEFaceEvaluation.
authorMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Wed, 25 Apr 2018 17:46:07 +0000 (19:46 +0200)
committerMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Fri, 27 Apr 2018 09:58:16 +0000 (11:58 +0200)
88 files changed:
tests/matrix_free/cell_categorization.cc [new file with mode: 0644]
tests/matrix_free/cell_categorization.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/cell_categorization.with_p4est=true.mpirun=7.output [new file with mode: 0644]
tests/matrix_free/compare_faces_by_cells.cc [new file with mode: 0644]
tests/matrix_free/compare_faces_by_cells.with_mpi=true.mpirun=1.output [new file with mode: 0755]
tests/matrix_free/compare_faces_by_cells.with_mpi=true.mpirun=5.output [new file with mode: 0755]
tests/matrix_free/dg_pbc_01.cc [new file with mode: 0644]
tests/matrix_free/dg_pbc_01.with_mpi=true.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/dg_pbc_01.with_mpi=true.with_p4est=true.mpirun=7.output [new file with mode: 0644]
tests/matrix_free/dg_pbc_02.cc [new file with mode: 0644]
tests/matrix_free/dg_pbc_02.with_mpi=true.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/dg_pbc_02.with_mpi=true.with_p4est=true.mpirun=7.output [new file with mode: 0644]
tests/matrix_free/faces_value_optimization.cc [new file with mode: 0644]
tests/matrix_free/faces_value_optimization.output [new file with mode: 0644]
tests/matrix_free/get_functions_faces.cc [new file with mode: 0644]
tests/matrix_free/get_functions_faces.output [new file with mode: 0644]
tests/matrix_free/interpolate_constant.cc [new file with mode: 0644]
tests/matrix_free/interpolate_constant.output [new file with mode: 0644]
tests/matrix_free/interpolate_cubic.cc [new file with mode: 0644]
tests/matrix_free/interpolate_cubic.output [new file with mode: 0644]
tests/matrix_free/interpolate_functions_common.h [new file with mode: 0644]
tests/matrix_free/interpolate_linear.cc [new file with mode: 0644]
tests/matrix_free/interpolate_linear.output [new file with mode: 0644]
tests/matrix_free/interpolate_quadratic.cc [new file with mode: 0644]
tests/matrix_free/interpolate_quadratic.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_01.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_01.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_02.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_02.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_03.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_03.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_04.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_04.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_05.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_05.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_06.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_06.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_07.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_07.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_08.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_08.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_09.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_09.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_10.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_10.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_11.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_11.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_12.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_12.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_13.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_13.with_mpi=true.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_13.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_14.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_14.with_mpi=true.with_p4est=true.mpirun=2.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_14.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_15.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_15.with_mpi=true.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_15.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_16.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_16.with_mpi=true.with_p4est=true.mpirun=11.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_17.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_17.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_18.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_18.with_mpi=true.with_p4est=true.mpirun=4.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_19.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_19.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_20.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_20.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_21.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_21.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_22.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_22.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_23.cc [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_23.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/matrix_vector_faces_common.h [new file with mode: 0644]
tests/matrix_free/matrix_vector_stokes_flux.cc
tests/matrix_free/multigrid_dg_periodic.cc [new file with mode: 0644]
tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/multigrid_dg_sip_01.cc [new file with mode: 0644]
tests/matrix_free/multigrid_dg_sip_01.with_mpi=true.with_p4est=true.mpirun=1.output [new file with mode: 0644]
tests/matrix_free/multigrid_dg_sip_01.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/multigrid_dg_sip_02.cc [new file with mode: 0644]
tests/matrix_free/multigrid_dg_sip_02.with_mpi=true.with_p4est=true.mpirun=5.output [new file with mode: 0644]
tests/matrix_free/thread_correctness.cc
tests/matrix_free/thread_correctness_dg.cc [new file with mode: 0644]
tests/matrix_free/thread_correctness_dg.output [new file with mode: 0644]

diff --git a/tests/matrix_free/cell_categorization.cc b/tests/matrix_free/cell_categorization.cc
new file mode 100644 (file)
index 0000000..7423587
--- /dev/null
@@ -0,0 +1,120 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Tests the categorization of cells for vectorization
+
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include "create_mesh.h"
+#include <deal.II/distributed/tria.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/matrix_free/matrix_free.h>
+
+std::ofstream logfile("output");
+
+template <int dim>
+void test ()
+{
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.refine_global(1);
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<9-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (1);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  MatrixFree<dim> mf_data;
+  typename MatrixFree<dim>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim>::AdditionalData::none;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  data.cell_vectorization_category.resize(tria.n_active_cells());
+  for (const auto &cell : tria.active_cell_iterators())
+    if (cell->is_locally_owned())
+      data.cell_vectorization_category[cell->active_cell_index()] = cell->center()[1] * 10.;
+
+  data.cell_vectorization_categories_strict = false;
+  mf_data.reinit(dof, constraints, QGauss<1>(2), data);
+
+  deallog << "Number of cell batches: " << mf_data.n_macro_cells() << std::endl;
+  for (unsigned int i=0; i<mf_data.n_macro_cells(); ++i)
+    for (unsigned int c=0; c<mf_data.n_components_filled(i); ++c)
+      deallog << mf_data.get_cell_iterator(i,c)->id() << " with "
+              << mf_data.get_cell_category(i) << std::endl;
+  deallog << std::endl;
+
+  data.cell_vectorization_categories_strict = true;
+  mf_data.reinit(dof, constraints, QGauss<1>(2), data);
+  deallog << "Number of cell batches: " << mf_data.n_macro_cells() << std::endl;
+  for (unsigned int i=0; i<mf_data.n_macro_cells(); ++i)
+    for (unsigned int c=0; c<mf_data.n_components_filled(i); ++c)
+      deallog << mf_data.get_cell_iterator(i,c)->id() << " with "
+              << mf_data.get_cell_category(i) << std::endl;
+  deallog << std::endl;
+
+  // set all categories to a fixed large number to make sure the memory
+  // allocation does not depend on the actual number
+  std::fill(data.cell_vectorization_category.begin(),
+            data.cell_vectorization_category.end(), 100000000);
+
+  data.cell_vectorization_categories_strict = false;
+  mf_data.reinit(dof, constraints, QGauss<1>(2), data);
+  deallog << "Number of cell batches: " << mf_data.n_macro_cells() << std::endl;
+  for (unsigned int i=0; i<mf_data.n_macro_cells(); ++i)
+    for (unsigned int c=0; c<mf_data.n_components_filled(i); ++c)
+      deallog << mf_data.get_cell_iterator(i,c)->id() << " with "
+              << mf_data.get_cell_category(i) << std::endl;
+  deallog << std::endl;
+}
+
+
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, testing_max_num_threads());
+  MPILogInitAll log;
+  test<2>();
+  test<3>();
+}
diff --git a/tests/matrix_free/cell_categorization.with_p4est=true.mpirun=1.output b/tests/matrix_free/cell_categorization.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..10f5749
--- /dev/null
@@ -0,0 +1,1072 @@
+
+DEAL:0::Number of cell batches: 59
+DEAL:0::0_3:000 with 0
+DEAL:0::0_3:001 with 0
+DEAL:0::0_3:010 with 0
+DEAL:0::0_3:011 with 0
+DEAL:0::0_3:100 with 0
+DEAL:0::0_3:101 with 0
+DEAL:0::0_3:110 with 0
+DEAL:0::0_3:111 with 0
+DEAL:0::1_3:000 with 0
+DEAL:0::1_3:001 with 0
+DEAL:0::1_3:010 with 0
+DEAL:0::1_3:011 with 0
+DEAL:0::0_4:0020 with 1
+DEAL:0::0_4:0021 with 1
+DEAL:0::0_4:0030 with 1
+DEAL:0::0_4:0031 with 1
+DEAL:0::0_3:012 with 1
+DEAL:0::0_4:0130 with 1
+DEAL:0::0_4:0131 with 1
+DEAL:0::0_3:102 with 1
+DEAL:0::0_3:103 with 1
+DEAL:0::0_3:112 with 1
+DEAL:0::0_3:113 with 1
+DEAL:0::1_3:002 with 1
+DEAL:0::1_3:003 with 1
+DEAL:0::1_3:012 with 1
+DEAL:0::1_3:013 with 1
+DEAL:0::1_2:10 with 1
+DEAL:0::0_5:00220 with 2
+DEAL:0::0_5:00221 with 2
+DEAL:0::0_5:00222 with 2
+DEAL:0::0_6:002230 with 2
+DEAL:0::0_6:002231 with 2
+DEAL:0::0_6:002232 with 2
+DEAL:0::0_6:002233 with 2
+DEAL:0::0_5:00230 with 2
+DEAL:0::0_5:00231 with 2
+DEAL:0::0_5:00232 with 2
+DEAL:0::0_5:00233 with 2
+DEAL:0::0_4:0032 with 2
+DEAL:0::0_4:0033 with 2
+DEAL:0::0_4:0132 with 2
+DEAL:0::0_4:0133 with 2
+DEAL:0::0_5:02000 with 2
+DEAL:0::0_5:02001 with 2
+DEAL:0::0_5:02002 with 2
+DEAL:0::0_5:02003 with 2
+DEAL:0::0_5:02010 with 2
+DEAL:0::0_5:02011 with 2
+DEAL:0::0_5:02012 with 2
+DEAL:0::0_5:02013 with 2
+DEAL:0::0_4:0210 with 2
+DEAL:0::0_4:0211 with 2
+DEAL:0::0_4:1300 with 2
+DEAL:0::0_4:1301 with 2
+DEAL:0::1_2:11 with 2
+DEAL:0::0_4:0202 with 3
+DEAL:0::0_4:0203 with 3
+DEAL:0::0_4:0212 with 3
+DEAL:0::0_4:0213 with 3
+DEAL:0::0_5:02210 with 3
+DEAL:0::0_5:02211 with 3
+DEAL:0::0_3:030 with 3
+DEAL:0::0_3:031 with 3
+DEAL:0::0_3:120 with 3
+DEAL:0::0_3:121 with 3
+DEAL:0::0_4:1302 with 3
+DEAL:0::0_4:1303 with 3
+DEAL:0::0_3:131 with 3
+DEAL:0::1_3:020 with 3
+DEAL:0::1_3:021 with 3
+DEAL:0::1_4:0302 with 3
+DEAL:0::1_4:0303 with 3
+DEAL:0::2_2:00 with 3
+DEAL:0::1_4:0301 with 3
+DEAL:0::1_4:0300 with 3
+DEAL:0::0_4:0220 with 4
+DEAL:0::0_5:02212 with 4
+DEAL:0::0_5:02213 with 4
+DEAL:0::0_4:0222 with 4
+DEAL:0::0_4:0223 with 4
+DEAL:0::0_4:0230 with 4
+DEAL:0::0_4:0231 with 4
+DEAL:0::0_4:0232 with 4
+DEAL:0::0_4:0233 with 4
+DEAL:0::0_3:032 with 4
+DEAL:0::0_3:033 with 4
+DEAL:0::0_3:122 with 4
+DEAL:0::0_3:123 with 4
+DEAL:0::0_3:132 with 4
+DEAL:0::0_3:133 with 4
+DEAL:0::1_3:022 with 4
+DEAL:0::1_3:023 with 4
+DEAL:0::1_2:13 with 4
+DEAL:0::1_2:12 with 4
+DEAL:0::1_3:031 with 4
+DEAL:0::0_3:200 with 5
+DEAL:0::0_3:201 with 5
+DEAL:0::0_4:2100 with 5
+DEAL:0::0_4:2101 with 5
+DEAL:0::0_4:2102 with 5
+DEAL:0::0_4:2103 with 5
+DEAL:0::0_3:211 with 5
+DEAL:0::0_3:300 with 5
+DEAL:0::0_3:301 with 5
+DEAL:0::0_3:310 with 5
+DEAL:0::0_3:311 with 5
+DEAL:0::1_3:200 with 5
+DEAL:0::1_3:201 with 5
+DEAL:0::1_3:210 with 5
+DEAL:0::1_3:211 with 5
+DEAL:0::1_3:300 with 5
+DEAL:0::1_3:301 with 5
+DEAL:0::2_2:01 with 5
+DEAL:0::1_3:033 with 5
+DEAL:0::1_3:032 with 5
+DEAL:0::0_3:202 with 6
+DEAL:0::0_3:203 with 6
+DEAL:0::0_3:212 with 6
+DEAL:0::0_3:213 with 6
+DEAL:0::0_4:3020 with 6
+DEAL:0::0_4:3021 with 6
+DEAL:0::0_3:303 with 6
+DEAL:0::0_3:312 with 6
+DEAL:0::0_4:3130 with 6
+DEAL:0::0_4:3131 with 6
+DEAL:0::1_3:202 with 6
+DEAL:0::1_3:203 with 6
+DEAL:0::1_3:212 with 6
+DEAL:0::1_3:213 with 6
+DEAL:0::1_3:302 with 6
+DEAL:0::2_2:02 with 6
+DEAL:0::0_4:2310 with 7
+DEAL:0::0_4:2311 with 7
+DEAL:0::0_4:3022 with 7
+DEAL:0::0_4:3023 with 7
+DEAL:0::0_4:3132 with 7
+DEAL:0::0_4:3133 with 7
+DEAL:0::0_4:3200 with 7
+DEAL:0::0_4:3201 with 7
+DEAL:0::0_4:3300 with 7
+DEAL:0::0_4:3301 with 7
+DEAL:0::1_2:31 with 7
+DEAL:0::1_3:303 with 7
+DEAL:0::0_2:22 with 8
+DEAL:0::0_3:230 with 8
+DEAL:0::0_4:2312 with 8
+DEAL:0::0_4:2313 with 8
+DEAL:0::0_5:32020 with 8
+DEAL:0::0_5:32021 with 8
+DEAL:0::0_5:32022 with 8
+DEAL:0::0_5:32023 with 8
+DEAL:0::0_4:3203 with 8
+DEAL:0::0_3:321 with 8
+DEAL:0::0_4:3302 with 8
+DEAL:0::0_4:3303 with 8
+DEAL:0::0_4:3312 with 8
+DEAL:0::0_4:3313 with 8
+DEAL:0::1_3:220 with 8
+DEAL:0::1_3:221 with 8
+DEAL:0::1_3:230 with 8
+DEAL:0::2_2:03 with 8
+DEAL:0::0_4:3311 with 8
+DEAL:0::0_4:3310 with 8
+DEAL:0::0_3:232 with 9
+DEAL:0::0_4:2330 with 9
+DEAL:0::0_4:2331 with 9
+DEAL:0::0_4:2332 with 9
+DEAL:0::0_4:2333 with 9
+DEAL:0::0_4:3220 with 9
+DEAL:0::0_4:3221 with 9
+DEAL:0::0_4:3222 with 9
+DEAL:0::0_4:3223 with 9
+DEAL:0::0_3:323 with 9
+DEAL:0::0_3:332 with 9
+DEAL:0::0_3:333 with 9
+DEAL:0::1_3:222 with 9
+DEAL:0::1_2:33 with 9
+DEAL:0::1_2:32 with 9
+DEAL:0::1_3:231 with 9
+DEAL:0::2_1:1 with 10
+DEAL:0::2_1:2 with 10
+DEAL:0::3_3:010 with 10
+DEAL:0::3_3:011 with 10
+DEAL:0::3_3:110 with 10
+DEAL:0::1_3:233 with 10
+DEAL:0::1_3:232 with 10
+DEAL:0::1_3:223 with 10
+DEAL:0::3_2:00 with 11
+DEAL:0::3_3:012 with 11
+DEAL:0::3_3:013 with 11
+DEAL:0::3_2:10 with 11
+DEAL:0::3_3:112 with 11
+DEAL:0::3_3:113 with 11
+DEAL:0::4_2:00 with 11
+DEAL:0::3_3:111 with 11
+DEAL:0::3_2:02 with 13
+DEAL:0::3_2:03 with 13
+DEAL:0::3_2:12 with 13
+DEAL:0::3_2:13 with 13
+DEAL:0::2_1:3 with 15
+DEAL:0::4_2:10 with 15
+DEAL:0::4_2:02 with 15
+DEAL:0::4_2:01 with 15
+DEAL:0::3_2:30 with 16
+DEAL:0::3_2:31 with 16
+DEAL:0::4_2:03 with 16
+DEAL:0::4_2:11 with 16
+DEAL:0::3_1:2 with 17
+DEAL:0::4_3:121 with 17
+DEAL:0::4_2:20 with 17
+DEAL:0::4_3:120 with 17
+DEAL:0::3_2:32 with 18
+DEAL:0::3_2:33 with 18
+DEAL:0::4_3:122 with 18
+DEAL:0::4_3:130 with 18
+DEAL:0::4_3:132 with 20
+DEAL:0::4_2:21 with 20
+DEAL:0::4_3:131 with 20
+DEAL:0::4_3:123 with 20
+DEAL:0::4_2:23 with 22
+DEAL:0::4_2:30 with 22
+DEAL:0::4_3:133 with 22
+DEAL:0::4_2:22 with 22
+DEAL:0::4_4:3111 with 23
+DEAL:0::4_4:3112 with 23
+DEAL:0::4_4:3110 with 23
+DEAL:0::4_3:310 with 23
+DEAL:0::4_3:313 with 25
+DEAL:0::4_2:32 with 25
+DEAL:0::4_3:312 with 25
+DEAL:0::4_4:3113 with 25
+DEAL:0::4_3:333 with 29
+DEAL:0::4_3:332 with 29
+DEAL:0::4_3:331 with 29
+DEAL:0::4_3:330 with 29
+DEAL:0::
+DEAL:0::Number of cell batches: 71
+DEAL:0::0_3:000 with 0
+DEAL:0::0_3:001 with 0
+DEAL:0::0_3:010 with 0
+DEAL:0::0_3:011 with 0
+DEAL:0::0_3:100 with 0
+DEAL:0::0_3:101 with 0
+DEAL:0::0_3:110 with 0
+DEAL:0::0_3:111 with 0
+DEAL:0::1_3:000 with 0
+DEAL:0::1_3:001 with 0
+DEAL:0::1_3:010 with 0
+DEAL:0::1_3:011 with 0
+DEAL:0::0_4:0020 with 1
+DEAL:0::0_4:0021 with 1
+DEAL:0::0_4:0030 with 1
+DEAL:0::0_4:0031 with 1
+DEAL:0::0_3:012 with 1
+DEAL:0::0_4:0130 with 1
+DEAL:0::0_4:0131 with 1
+DEAL:0::0_3:102 with 1
+DEAL:0::0_3:103 with 1
+DEAL:0::0_3:112 with 1
+DEAL:0::0_3:113 with 1
+DEAL:0::1_3:002 with 1
+DEAL:0::1_3:003 with 1
+DEAL:0::1_3:012 with 1
+DEAL:0::1_3:013 with 1
+DEAL:0::1_2:10 with 1
+DEAL:0::1_2:11 with 1
+DEAL:0::0_5:00220 with 2
+DEAL:0::0_5:00221 with 2
+DEAL:0::0_5:00222 with 2
+DEAL:0::0_6:002230 with 2
+DEAL:0::0_6:002231 with 2
+DEAL:0::0_6:002232 with 2
+DEAL:0::0_6:002233 with 2
+DEAL:0::0_5:00230 with 2
+DEAL:0::0_5:00231 with 2
+DEAL:0::0_5:00232 with 2
+DEAL:0::0_5:00233 with 2
+DEAL:0::0_4:0032 with 2
+DEAL:0::0_4:0033 with 2
+DEAL:0::0_4:0132 with 2
+DEAL:0::0_4:0133 with 2
+DEAL:0::0_5:02000 with 2
+DEAL:0::0_5:02001 with 2
+DEAL:0::0_5:02002 with 2
+DEAL:0::0_5:02003 with 2
+DEAL:0::0_5:02010 with 2
+DEAL:0::0_5:02011 with 2
+DEAL:0::0_5:02012 with 2
+DEAL:0::0_5:02013 with 2
+DEAL:0::0_4:0210 with 2
+DEAL:0::0_4:0211 with 2
+DEAL:0::0_4:1300 with 2
+DEAL:0::0_4:1301 with 2
+DEAL:0::1_4:0300 with 2
+DEAL:0::1_4:0301 with 2
+DEAL:0::2_2:00 with 2
+DEAL:0::0_4:0202 with 3
+DEAL:0::0_4:0203 with 3
+DEAL:0::0_4:0212 with 3
+DEAL:0::0_4:0213 with 3
+DEAL:0::0_5:02210 with 3
+DEAL:0::0_5:02211 with 3
+DEAL:0::0_3:030 with 3
+DEAL:0::0_3:031 with 3
+DEAL:0::0_3:120 with 3
+DEAL:0::0_3:121 with 3
+DEAL:0::0_4:1302 with 3
+DEAL:0::0_4:1303 with 3
+DEAL:0::0_3:131 with 3
+DEAL:0::1_3:020 with 3
+DEAL:0::1_3:021 with 3
+DEAL:0::1_4:0302 with 3
+DEAL:0::1_4:0303 with 3
+DEAL:0::1_3:031 with 3
+DEAL:0::1_2:12 with 3
+DEAL:0::1_2:13 with 3
+DEAL:0::0_4:0220 with 4
+DEAL:0::0_5:02212 with 4
+DEAL:0::0_5:02213 with 4
+DEAL:0::0_4:0222 with 4
+DEAL:0::0_4:0223 with 4
+DEAL:0::0_4:0230 with 4
+DEAL:0::0_4:0231 with 4
+DEAL:0::0_4:0232 with 4
+DEAL:0::0_4:0233 with 4
+DEAL:0::0_3:032 with 4
+DEAL:0::0_3:033 with 4
+DEAL:0::0_3:122 with 4
+DEAL:0::0_3:123 with 4
+DEAL:0::0_3:132 with 4
+DEAL:0::0_3:133 with 4
+DEAL:0::1_3:022 with 4
+DEAL:0::1_3:023 with 4
+DEAL:0::1_3:032 with 4
+DEAL:0::1_3:033 with 4
+DEAL:0::0_3:200 with 5
+DEAL:0::0_3:201 with 5
+DEAL:0::0_4:2100 with 5
+DEAL:0::0_4:2101 with 5
+DEAL:0::0_4:2102 with 5
+DEAL:0::0_4:2103 with 5
+DEAL:0::0_3:211 with 5
+DEAL:0::0_3:300 with 5
+DEAL:0::0_3:301 with 5
+DEAL:0::0_3:310 with 5
+DEAL:0::0_3:311 with 5
+DEAL:0::1_3:200 with 5
+DEAL:0::1_3:201 with 5
+DEAL:0::1_3:210 with 5
+DEAL:0::1_3:211 with 5
+DEAL:0::1_3:300 with 5
+DEAL:0::1_3:301 with 5
+DEAL:0::2_2:01 with 5
+DEAL:0::2_2:02 with 5
+DEAL:0::0_3:202 with 6
+DEAL:0::0_3:203 with 6
+DEAL:0::0_3:212 with 6
+DEAL:0::0_3:213 with 6
+DEAL:0::0_4:3020 with 6
+DEAL:0::0_4:3021 with 6
+DEAL:0::0_3:303 with 6
+DEAL:0::0_3:312 with 6
+DEAL:0::0_4:3130 with 6
+DEAL:0::0_4:3131 with 6
+DEAL:0::1_3:202 with 6
+DEAL:0::1_3:203 with 6
+DEAL:0::1_3:212 with 6
+DEAL:0::1_3:213 with 6
+DEAL:0::1_3:302 with 6
+DEAL:0::1_3:303 with 6
+DEAL:0::1_2:31 with 6
+DEAL:0::0_4:2310 with 7
+DEAL:0::0_4:2311 with 7
+DEAL:0::0_4:3022 with 7
+DEAL:0::0_4:3023 with 7
+DEAL:0::0_4:3132 with 7
+DEAL:0::0_4:3133 with 7
+DEAL:0::0_4:3200 with 7
+DEAL:0::0_4:3201 with 7
+DEAL:0::0_4:3300 with 7
+DEAL:0::0_4:3301 with 7
+DEAL:0::0_4:3310 with 7
+DEAL:0::0_4:3311 with 7
+DEAL:0::2_2:03 with 7
+DEAL:0::0_2:22 with 8
+DEAL:0::0_3:230 with 8
+DEAL:0::0_4:2312 with 8
+DEAL:0::0_4:2313 with 8
+DEAL:0::0_5:32020 with 8
+DEAL:0::0_5:32021 with 8
+DEAL:0::0_5:32022 with 8
+DEAL:0::0_5:32023 with 8
+DEAL:0::0_4:3203 with 8
+DEAL:0::0_3:321 with 8
+DEAL:0::0_4:3302 with 8
+DEAL:0::0_4:3303 with 8
+DEAL:0::0_4:3312 with 8
+DEAL:0::0_4:3313 with 8
+DEAL:0::1_3:220 with 8
+DEAL:0::1_3:221 with 8
+DEAL:0::1_3:230 with 8
+DEAL:0::1_3:231 with 8
+DEAL:0::1_2:32 with 8
+DEAL:0::1_2:33 with 8
+DEAL:0::0_3:232 with 9
+DEAL:0::0_4:2330 with 9
+DEAL:0::0_4:2331 with 9
+DEAL:0::0_4:2332 with 9
+DEAL:0::0_4:2333 with 9
+DEAL:0::0_4:3220 with 9
+DEAL:0::0_4:3221 with 9
+DEAL:0::0_4:3222 with 9
+DEAL:0::0_4:3223 with 9
+DEAL:0::0_3:323 with 9
+DEAL:0::0_3:332 with 9
+DEAL:0::0_3:333 with 9
+DEAL:0::1_3:222 with 9
+DEAL:0::1_3:223 with 9
+DEAL:0::1_3:232 with 9
+DEAL:0::1_3:233 with 9
+DEAL:0::2_1:1 with 10
+DEAL:0::2_1:2 with 10
+DEAL:0::3_3:010 with 10
+DEAL:0::3_3:011 with 10
+DEAL:0::3_3:110 with 10
+DEAL:0::3_3:111 with 10
+DEAL:0::3_2:00 with 11
+DEAL:0::3_3:012 with 11
+DEAL:0::3_3:013 with 11
+DEAL:0::3_2:10 with 11
+DEAL:0::3_3:112 with 11
+DEAL:0::3_3:113 with 11
+DEAL:0::4_2:00 with 11
+DEAL:0::3_2:02 with 13
+DEAL:0::3_2:03 with 13
+DEAL:0::3_2:12 with 13
+DEAL:0::3_2:13 with 13
+DEAL:0::4_2:01 with 13
+DEAL:0::4_2:02 with 14
+DEAL:0::4_2:10 with 14
+DEAL:0::2_1:3 with 15
+DEAL:0::4_2:11 with 15
+DEAL:0::3_2:30 with 16
+DEAL:0::3_2:31 with 16
+DEAL:0::4_2:03 with 16
+DEAL:0::4_3:120 with 16
+DEAL:0::3_1:2 with 17
+DEAL:0::4_3:121 with 17
+DEAL:0::4_2:20 with 17
+DEAL:0::3_2:32 with 18
+DEAL:0::3_2:33 with 18
+DEAL:0::4_3:122 with 18
+DEAL:0::4_3:130 with 18
+DEAL:0::4_3:123 with 19
+DEAL:0::4_3:131 with 19
+DEAL:0::4_2:21 with 19
+DEAL:0::4_3:132 with 20
+DEAL:0::4_2:22 with 20
+DEAL:0::4_3:133 with 21
+DEAL:0::4_2:30 with 21
+DEAL:0::4_2:23 with 22
+DEAL:0::4_3:310 with 22
+DEAL:0::4_4:3110 with 22
+DEAL:0::4_4:3111 with 23
+DEAL:0::4_4:3112 with 23
+DEAL:0::4_4:3113 with 24
+DEAL:0::4_3:312 with 24
+DEAL:0::4_3:313 with 25
+DEAL:0::4_2:32 with 25
+DEAL:0::4_3:330 with 26
+DEAL:0::4_3:331 with 27
+DEAL:0::4_3:332 with 28
+DEAL:0::4_3:333 with 29
+DEAL:0::
+DEAL:0::Number of cell batches: 59
+DEAL:0::0_3:000 with 100000000
+DEAL:0::0_3:001 with 100000000
+DEAL:0::0_4:0020 with 100000000
+DEAL:0::0_4:0021 with 100000000
+DEAL:0::0_5:00220 with 100000000
+DEAL:0::0_5:00221 with 100000000
+DEAL:0::0_5:00222 with 100000000
+DEAL:0::0_6:002230 with 100000000
+DEAL:0::0_6:002231 with 100000000
+DEAL:0::0_6:002232 with 100000000
+DEAL:0::0_6:002233 with 100000000
+DEAL:0::0_5:00230 with 100000000
+DEAL:0::0_5:00231 with 100000000
+DEAL:0::0_5:00232 with 100000000
+DEAL:0::0_5:00233 with 100000000
+DEAL:0::0_4:0030 with 100000000
+DEAL:0::0_4:0031 with 100000000
+DEAL:0::0_4:0032 with 100000000
+DEAL:0::0_4:0033 with 100000000
+DEAL:0::0_3:010 with 100000000
+DEAL:0::0_3:011 with 100000000
+DEAL:0::0_3:012 with 100000000
+DEAL:0::0_4:0130 with 100000000
+DEAL:0::0_4:0131 with 100000000
+DEAL:0::0_4:0132 with 100000000
+DEAL:0::0_4:0133 with 100000000
+DEAL:0::0_5:02000 with 100000000
+DEAL:0::0_5:02001 with 100000000
+DEAL:0::0_5:02002 with 100000000
+DEAL:0::0_5:02003 with 100000000
+DEAL:0::0_5:02010 with 100000000
+DEAL:0::0_5:02011 with 100000000
+DEAL:0::0_5:02012 with 100000000
+DEAL:0::0_5:02013 with 100000000
+DEAL:0::0_4:0202 with 100000000
+DEAL:0::0_4:0203 with 100000000
+DEAL:0::0_4:0210 with 100000000
+DEAL:0::0_4:0211 with 100000000
+DEAL:0::0_4:0212 with 100000000
+DEAL:0::0_4:0213 with 100000000
+DEAL:0::0_4:0220 with 100000000
+DEAL:0::0_5:02210 with 100000000
+DEAL:0::0_5:02211 with 100000000
+DEAL:0::0_5:02212 with 100000000
+DEAL:0::0_5:02213 with 100000000
+DEAL:0::0_4:0222 with 100000000
+DEAL:0::0_4:0223 with 100000000
+DEAL:0::0_4:0230 with 100000000
+DEAL:0::0_4:0231 with 100000000
+DEAL:0::0_4:0232 with 100000000
+DEAL:0::0_4:0233 with 100000000
+DEAL:0::0_3:030 with 100000000
+DEAL:0::0_3:031 with 100000000
+DEAL:0::0_3:032 with 100000000
+DEAL:0::0_3:033 with 100000000
+DEAL:0::0_3:100 with 100000000
+DEAL:0::0_3:101 with 100000000
+DEAL:0::0_3:102 with 100000000
+DEAL:0::0_3:103 with 100000000
+DEAL:0::0_3:110 with 100000000
+DEAL:0::0_3:111 with 100000000
+DEAL:0::0_3:112 with 100000000
+DEAL:0::0_3:113 with 100000000
+DEAL:0::0_3:120 with 100000000
+DEAL:0::0_3:121 with 100000000
+DEAL:0::0_3:122 with 100000000
+DEAL:0::0_3:123 with 100000000
+DEAL:0::0_4:1300 with 100000000
+DEAL:0::0_4:1301 with 100000000
+DEAL:0::0_4:1302 with 100000000
+DEAL:0::0_4:1303 with 100000000
+DEAL:0::0_3:131 with 100000000
+DEAL:0::0_3:132 with 100000000
+DEAL:0::0_3:133 with 100000000
+DEAL:0::0_3:200 with 100000000
+DEAL:0::0_3:201 with 100000000
+DEAL:0::0_3:202 with 100000000
+DEAL:0::0_3:203 with 100000000
+DEAL:0::0_4:2100 with 100000000
+DEAL:0::0_4:2101 with 100000000
+DEAL:0::0_4:2102 with 100000000
+DEAL:0::0_4:2103 with 100000000
+DEAL:0::0_3:211 with 100000000
+DEAL:0::0_3:212 with 100000000
+DEAL:0::0_3:213 with 100000000
+DEAL:0::0_2:22 with 100000000
+DEAL:0::0_3:230 with 100000000
+DEAL:0::0_4:2310 with 100000000
+DEAL:0::0_4:2311 with 100000000
+DEAL:0::0_4:2312 with 100000000
+DEAL:0::0_4:2313 with 100000000
+DEAL:0::0_3:232 with 100000000
+DEAL:0::0_4:2330 with 100000000
+DEAL:0::0_4:2331 with 100000000
+DEAL:0::0_4:2332 with 100000000
+DEAL:0::0_4:2333 with 100000000
+DEAL:0::0_3:300 with 100000000
+DEAL:0::0_3:301 with 100000000
+DEAL:0::0_4:3020 with 100000000
+DEAL:0::0_4:3021 with 100000000
+DEAL:0::0_4:3022 with 100000000
+DEAL:0::0_4:3023 with 100000000
+DEAL:0::0_3:303 with 100000000
+DEAL:0::0_3:310 with 100000000
+DEAL:0::0_3:311 with 100000000
+DEAL:0::0_3:312 with 100000000
+DEAL:0::0_4:3130 with 100000000
+DEAL:0::0_4:3131 with 100000000
+DEAL:0::0_4:3132 with 100000000
+DEAL:0::0_4:3133 with 100000000
+DEAL:0::0_4:3200 with 100000000
+DEAL:0::0_4:3201 with 100000000
+DEAL:0::0_5:32020 with 100000000
+DEAL:0::0_5:32021 with 100000000
+DEAL:0::0_5:32022 with 100000000
+DEAL:0::0_5:32023 with 100000000
+DEAL:0::0_4:3203 with 100000000
+DEAL:0::0_3:321 with 100000000
+DEAL:0::0_4:3220 with 100000000
+DEAL:0::0_4:3221 with 100000000
+DEAL:0::0_4:3222 with 100000000
+DEAL:0::0_4:3223 with 100000000
+DEAL:0::0_3:323 with 100000000
+DEAL:0::0_4:3300 with 100000000
+DEAL:0::0_4:3301 with 100000000
+DEAL:0::0_4:3302 with 100000000
+DEAL:0::0_4:3303 with 100000000
+DEAL:0::0_4:3310 with 100000000
+DEAL:0::0_4:3311 with 100000000
+DEAL:0::0_4:3312 with 100000000
+DEAL:0::0_4:3313 with 100000000
+DEAL:0::0_3:332 with 100000000
+DEAL:0::0_3:333 with 100000000
+DEAL:0::1_3:000 with 100000000
+DEAL:0::1_3:001 with 100000000
+DEAL:0::1_3:002 with 100000000
+DEAL:0::1_3:003 with 100000000
+DEAL:0::1_3:010 with 100000000
+DEAL:0::1_3:011 with 100000000
+DEAL:0::1_3:012 with 100000000
+DEAL:0::1_3:013 with 100000000
+DEAL:0::1_3:020 with 100000000
+DEAL:0::1_3:021 with 100000000
+DEAL:0::1_3:022 with 100000000
+DEAL:0::1_3:023 with 100000000
+DEAL:0::1_4:0300 with 100000000
+DEAL:0::1_4:0301 with 100000000
+DEAL:0::1_4:0302 with 100000000
+DEAL:0::1_4:0303 with 100000000
+DEAL:0::1_3:031 with 100000000
+DEAL:0::1_3:032 with 100000000
+DEAL:0::1_3:033 with 100000000
+DEAL:0::1_2:10 with 100000000
+DEAL:0::1_2:11 with 100000000
+DEAL:0::1_2:12 with 100000000
+DEAL:0::1_2:13 with 100000000
+DEAL:0::1_3:200 with 100000000
+DEAL:0::1_3:201 with 100000000
+DEAL:0::1_3:202 with 100000000
+DEAL:0::1_3:203 with 100000000
+DEAL:0::1_3:210 with 100000000
+DEAL:0::1_3:211 with 100000000
+DEAL:0::1_3:212 with 100000000
+DEAL:0::1_3:213 with 100000000
+DEAL:0::1_3:220 with 100000000
+DEAL:0::1_3:221 with 100000000
+DEAL:0::1_3:222 with 100000000
+DEAL:0::1_3:223 with 100000000
+DEAL:0::1_3:230 with 100000000
+DEAL:0::1_3:231 with 100000000
+DEAL:0::1_3:232 with 100000000
+DEAL:0::1_3:233 with 100000000
+DEAL:0::1_3:300 with 100000000
+DEAL:0::1_3:301 with 100000000
+DEAL:0::1_3:302 with 100000000
+DEAL:0::1_3:303 with 100000000
+DEAL:0::1_2:31 with 100000000
+DEAL:0::1_2:32 with 100000000
+DEAL:0::1_2:33 with 100000000
+DEAL:0::2_2:00 with 100000000
+DEAL:0::2_2:01 with 100000000
+DEAL:0::2_2:02 with 100000000
+DEAL:0::2_2:03 with 100000000
+DEAL:0::2_1:1 with 100000000
+DEAL:0::2_1:2 with 100000000
+DEAL:0::2_1:3 with 100000000
+DEAL:0::3_2:00 with 100000000
+DEAL:0::3_3:010 with 100000000
+DEAL:0::3_3:011 with 100000000
+DEAL:0::3_3:012 with 100000000
+DEAL:0::3_3:013 with 100000000
+DEAL:0::3_2:02 with 100000000
+DEAL:0::3_2:03 with 100000000
+DEAL:0::3_2:10 with 100000000
+DEAL:0::3_3:110 with 100000000
+DEAL:0::3_3:111 with 100000000
+DEAL:0::3_3:112 with 100000000
+DEAL:0::3_3:113 with 100000000
+DEAL:0::3_2:12 with 100000000
+DEAL:0::3_2:13 with 100000000
+DEAL:0::3_1:2 with 100000000
+DEAL:0::3_2:30 with 100000000
+DEAL:0::3_2:31 with 100000000
+DEAL:0::3_2:32 with 100000000
+DEAL:0::3_2:33 with 100000000
+DEAL:0::4_2:00 with 100000000
+DEAL:0::4_2:01 with 100000000
+DEAL:0::4_2:02 with 100000000
+DEAL:0::4_2:03 with 100000000
+DEAL:0::4_2:10 with 100000000
+DEAL:0::4_2:11 with 100000000
+DEAL:0::4_3:120 with 100000000
+DEAL:0::4_3:121 with 100000000
+DEAL:0::4_3:122 with 100000000
+DEAL:0::4_3:123 with 100000000
+DEAL:0::4_3:130 with 100000000
+DEAL:0::4_3:131 with 100000000
+DEAL:0::4_3:132 with 100000000
+DEAL:0::4_3:133 with 100000000
+DEAL:0::4_2:20 with 100000000
+DEAL:0::4_2:21 with 100000000
+DEAL:0::4_2:22 with 100000000
+DEAL:0::4_2:23 with 100000000
+DEAL:0::4_2:30 with 100000000
+DEAL:0::4_3:310 with 100000000
+DEAL:0::4_4:3110 with 100000000
+DEAL:0::4_4:3111 with 100000000
+DEAL:0::4_4:3112 with 100000000
+DEAL:0::4_4:3113 with 100000000
+DEAL:0::4_3:312 with 100000000
+DEAL:0::4_3:313 with 100000000
+DEAL:0::4_2:32 with 100000000
+DEAL:0::4_3:330 with 100000000
+DEAL:0::4_3:331 with 100000000
+DEAL:0::4_3:332 with 100000000
+DEAL:0::4_3:333 with 100000000
+DEAL:0::
+DEAL:0::Number of cell batches: 30
+DEAL:0::0_3:000 with 0
+DEAL:0::0_3:002 with 1
+DEAL:0::0_3:003 with 1
+DEAL:0::0_3:006 with 1
+DEAL:0::0_3:007 with 1
+DEAL:0::0_2:01 with 1
+DEAL:0::0_2:04 with 1
+DEAL:0::0_2:05 with 1
+DEAL:0::0_2:10 with 1
+DEAL:0::0_2:11 with 1
+DEAL:0::0_2:14 with 1
+DEAL:0::0_2:15 with 1
+DEAL:0::0_2:40 with 1
+DEAL:0::0_2:41 with 1
+DEAL:0::0_2:44 with 1
+DEAL:0::0_2:45 with 1
+DEAL:0::0_2:50 with 1
+DEAL:0::0_2:51 with 1
+DEAL:0::0_3:005 with 1
+DEAL:0::0_3:004 with 1
+DEAL:0::0_3:001 with 1
+DEAL:0::1_1:0 with 2
+DEAL:0::1_1:1 with 2
+DEAL:0::0_2:55 with 2
+DEAL:0::0_2:54 with 2
+DEAL:0::0_2:02 with 3
+DEAL:0::0_2:03 with 3
+DEAL:0::0_2:06 with 3
+DEAL:0::0_2:07 with 3
+DEAL:0::0_2:12 with 3
+DEAL:0::0_2:13 with 3
+DEAL:0::0_2:16 with 3
+DEAL:0::0_2:17 with 3
+DEAL:0::0_2:42 with 3
+DEAL:0::0_2:43 with 3
+DEAL:0::0_2:46 with 3
+DEAL:0::0_2:47 with 3
+DEAL:0::0_2:52 with 3
+DEAL:0::0_2:53 with 3
+DEAL:0::1_1:5 with 3
+DEAL:0::1_1:4 with 3
+DEAL:0::2_1:0 with 5
+DEAL:0::2_1:4 with 5
+DEAL:0::0_2:57 with 5
+DEAL:0::0_2:56 with 5
+DEAL:0::0_2:20 with 6
+DEAL:0::0_2:21 with 6
+DEAL:0::0_2:24 with 6
+DEAL:0::0_2:25 with 6
+DEAL:0::0_2:30 with 6
+DEAL:0::0_2:31 with 6
+DEAL:0::0_2:34 with 6
+DEAL:0::0_2:35 with 6
+DEAL:0::0_2:60 with 6
+DEAL:0::0_2:61 with 6
+DEAL:0::0_2:64 with 6
+DEAL:0::0_2:65 with 6
+DEAL:0::0_2:70 with 6
+DEAL:0::0_2:71 with 6
+DEAL:0::0_2:74 with 6
+DEAL:0::0_2:75 with 6
+DEAL:0::1_2:60 with 6
+DEAL:0::1_2:61 with 6
+DEAL:0::1_2:64 with 6
+DEAL:0::1_2:65 with 6
+DEAL:0::0_2:22 with 8
+DEAL:0::0_2:23 with 8
+DEAL:0::0_2:26 with 8
+DEAL:0::0_2:27 with 8
+DEAL:0::0_2:32 with 8
+DEAL:0::0_2:33 with 8
+DEAL:0::0_2:36 with 8
+DEAL:0::0_2:37 with 8
+DEAL:0::0_2:62 with 8
+DEAL:0::0_2:63 with 8
+DEAL:0::0_2:66 with 8
+DEAL:0::0_2:67 with 8
+DEAL:0::0_2:72 with 8
+DEAL:0::0_2:73 with 8
+DEAL:0::0_2:76 with 8
+DEAL:0::0_3:770 with 8
+DEAL:0::0_3:771 with 8
+DEAL:0::0_3:774 with 8
+DEAL:0::0_3:775 with 8
+DEAL:0::1_2:62 with 8
+DEAL:0::1_2:63 with 8
+DEAL:0::1_1:7 with 8
+DEAL:0::1_1:3 with 8
+DEAL:0::1_1:2 with 8
+DEAL:0::0_3:772 with 9
+DEAL:0::0_3:773 with 9
+DEAL:0::1_2:67 with 9
+DEAL:0::1_2:66 with 9
+DEAL:0::2_1:1 with 10
+DEAL:0::2_1:2 with 10
+DEAL:0::0_3:777 with 10
+DEAL:0::0_3:776 with 10
+DEAL:0::3_1:0 with 12
+DEAL:0::3_1:1 with 12
+DEAL:0::2_1:6 with 12
+DEAL:0::2_1:5 with 12
+DEAL:0::4_1:0 with 14
+DEAL:0::4_1:4 with 14
+DEAL:0::3_1:5 with 14
+DEAL:0::3_1:4 with 14
+DEAL:0::3_1:2 with 17
+DEAL:0::3_1:3 with 17
+DEAL:0::2_1:7 with 17
+DEAL:0::2_1:3 with 17
+DEAL:0::4_1:5 with 18
+DEAL:0::4_1:1 with 18
+DEAL:0::3_1:7 with 18
+DEAL:0::3_1:6 with 18
+DEAL:0::4_1:7 with 27
+DEAL:0::4_1:3 with 27
+DEAL:0::4_1:6 with 27
+DEAL:0::4_1:2 with 27
+DEAL:0::
+DEAL:0::Number of cell batches: 35
+DEAL:0::0_3:000 with 0
+DEAL:0::0_3:001 with 0
+DEAL:0::0_3:004 with 0
+DEAL:0::0_3:005 with 0
+DEAL:0::0_3:002 with 1
+DEAL:0::0_3:003 with 1
+DEAL:0::0_3:006 with 1
+DEAL:0::0_3:007 with 1
+DEAL:0::0_2:01 with 1
+DEAL:0::0_2:04 with 1
+DEAL:0::0_2:05 with 1
+DEAL:0::0_2:10 with 1
+DEAL:0::0_2:11 with 1
+DEAL:0::0_2:14 with 1
+DEAL:0::0_2:15 with 1
+DEAL:0::0_2:40 with 1
+DEAL:0::0_2:41 with 1
+DEAL:0::0_2:44 with 1
+DEAL:0::0_2:45 with 1
+DEAL:0::0_2:50 with 1
+DEAL:0::0_2:51 with 1
+DEAL:0::0_2:54 with 1
+DEAL:0::0_2:55 with 1
+DEAL:0::1_1:0 with 2
+DEAL:0::1_1:1 with 2
+DEAL:0::1_1:4 with 2
+DEAL:0::1_1:5 with 2
+DEAL:0::0_2:02 with 3
+DEAL:0::0_2:03 with 3
+DEAL:0::0_2:06 with 3
+DEAL:0::0_2:07 with 3
+DEAL:0::0_2:12 with 3
+DEAL:0::0_2:13 with 3
+DEAL:0::0_2:16 with 3
+DEAL:0::0_2:17 with 3
+DEAL:0::0_2:42 with 3
+DEAL:0::0_2:43 with 3
+DEAL:0::0_2:46 with 3
+DEAL:0::0_2:47 with 3
+DEAL:0::0_2:52 with 3
+DEAL:0::0_2:53 with 3
+DEAL:0::0_2:56 with 3
+DEAL:0::0_2:57 with 3
+DEAL:0::2_1:0 with 5
+DEAL:0::2_1:4 with 5
+DEAL:0::0_2:20 with 6
+DEAL:0::0_2:21 with 6
+DEAL:0::0_2:24 with 6
+DEAL:0::0_2:25 with 6
+DEAL:0::0_2:30 with 6
+DEAL:0::0_2:31 with 6
+DEAL:0::0_2:34 with 6
+DEAL:0::0_2:35 with 6
+DEAL:0::0_2:60 with 6
+DEAL:0::0_2:61 with 6
+DEAL:0::0_2:64 with 6
+DEAL:0::0_2:65 with 6
+DEAL:0::0_2:70 with 6
+DEAL:0::0_2:71 with 6
+DEAL:0::0_2:74 with 6
+DEAL:0::0_2:75 with 6
+DEAL:0::1_2:60 with 6
+DEAL:0::1_2:61 with 6
+DEAL:0::1_2:64 with 6
+DEAL:0::1_2:65 with 6
+DEAL:0::1_1:2 with 7
+DEAL:0::1_1:3 with 7
+DEAL:0::1_1:7 with 7
+DEAL:0::0_2:22 with 8
+DEAL:0::0_2:23 with 8
+DEAL:0::0_2:26 with 8
+DEAL:0::0_2:27 with 8
+DEAL:0::0_2:32 with 8
+DEAL:0::0_2:33 with 8
+DEAL:0::0_2:36 with 8
+DEAL:0::0_2:37 with 8
+DEAL:0::0_2:62 with 8
+DEAL:0::0_2:63 with 8
+DEAL:0::0_2:66 with 8
+DEAL:0::0_2:67 with 8
+DEAL:0::0_2:72 with 8
+DEAL:0::0_2:73 with 8
+DEAL:0::0_2:76 with 8
+DEAL:0::0_3:770 with 8
+DEAL:0::0_3:771 with 8
+DEAL:0::0_3:774 with 8
+DEAL:0::0_3:775 with 8
+DEAL:0::1_2:62 with 8
+DEAL:0::1_2:63 with 8
+DEAL:0::1_2:66 with 8
+DEAL:0::1_2:67 with 8
+DEAL:0::0_3:772 with 9
+DEAL:0::0_3:773 with 9
+DEAL:0::0_3:776 with 9
+DEAL:0::0_3:777 with 9
+DEAL:0::2_1:1 with 10
+DEAL:0::2_1:2 with 10
+DEAL:0::2_1:5 with 10
+DEAL:0::2_1:6 with 10
+DEAL:0::3_1:0 with 12
+DEAL:0::3_1:1 with 12
+DEAL:0::3_1:4 with 12
+DEAL:0::3_1:5 with 12
+DEAL:0::4_1:0 with 14
+DEAL:0::4_1:4 with 14
+DEAL:0::2_1:3 with 15
+DEAL:0::2_1:7 with 15
+DEAL:0::3_1:2 with 17
+DEAL:0::3_1:3 with 17
+DEAL:0::3_1:6 with 17
+DEAL:0::3_1:7 with 17
+DEAL:0::4_1:1 with 17
+DEAL:0::4_1:5 with 18
+DEAL:0::4_1:2 with 20
+DEAL:0::4_1:6 with 20
+DEAL:0::4_1:3 with 25
+DEAL:0::4_1:7 with 27
+DEAL:0::
+DEAL:0::Number of cell batches: 30
+DEAL:0::0_3:000 with 100000000
+DEAL:0::0_3:001 with 100000000
+DEAL:0::0_3:002 with 100000000
+DEAL:0::0_3:003 with 100000000
+DEAL:0::0_3:004 with 100000000
+DEAL:0::0_3:005 with 100000000
+DEAL:0::0_3:006 with 100000000
+DEAL:0::0_3:007 with 100000000
+DEAL:0::0_2:01 with 100000000
+DEAL:0::0_2:02 with 100000000
+DEAL:0::0_2:03 with 100000000
+DEAL:0::0_2:04 with 100000000
+DEAL:0::0_2:05 with 100000000
+DEAL:0::0_2:06 with 100000000
+DEAL:0::0_2:07 with 100000000
+DEAL:0::0_2:10 with 100000000
+DEAL:0::0_2:11 with 100000000
+DEAL:0::0_2:12 with 100000000
+DEAL:0::0_2:13 with 100000000
+DEAL:0::0_2:14 with 100000000
+DEAL:0::0_2:15 with 100000000
+DEAL:0::0_2:16 with 100000000
+DEAL:0::0_2:17 with 100000000
+DEAL:0::0_2:20 with 100000000
+DEAL:0::0_2:21 with 100000000
+DEAL:0::0_2:22 with 100000000
+DEAL:0::0_2:23 with 100000000
+DEAL:0::0_2:24 with 100000000
+DEAL:0::0_2:25 with 100000000
+DEAL:0::0_2:26 with 100000000
+DEAL:0::0_2:27 with 100000000
+DEAL:0::0_2:30 with 100000000
+DEAL:0::0_2:31 with 100000000
+DEAL:0::0_2:32 with 100000000
+DEAL:0::0_2:33 with 100000000
+DEAL:0::0_2:34 with 100000000
+DEAL:0::0_2:35 with 100000000
+DEAL:0::0_2:36 with 100000000
+DEAL:0::0_2:37 with 100000000
+DEAL:0::0_2:40 with 100000000
+DEAL:0::0_2:41 with 100000000
+DEAL:0::0_2:42 with 100000000
+DEAL:0::0_2:43 with 100000000
+DEAL:0::0_2:44 with 100000000
+DEAL:0::0_2:45 with 100000000
+DEAL:0::0_2:46 with 100000000
+DEAL:0::0_2:47 with 100000000
+DEAL:0::0_2:50 with 100000000
+DEAL:0::0_2:51 with 100000000
+DEAL:0::0_2:52 with 100000000
+DEAL:0::0_2:53 with 100000000
+DEAL:0::0_2:54 with 100000000
+DEAL:0::0_2:55 with 100000000
+DEAL:0::0_2:56 with 100000000
+DEAL:0::0_2:57 with 100000000
+DEAL:0::0_2:60 with 100000000
+DEAL:0::0_2:61 with 100000000
+DEAL:0::0_2:62 with 100000000
+DEAL:0::0_2:63 with 100000000
+DEAL:0::0_2:64 with 100000000
+DEAL:0::0_2:65 with 100000000
+DEAL:0::0_2:66 with 100000000
+DEAL:0::0_2:67 with 100000000
+DEAL:0::0_2:70 with 100000000
+DEAL:0::0_2:71 with 100000000
+DEAL:0::0_2:72 with 100000000
+DEAL:0::0_2:73 with 100000000
+DEAL:0::0_2:74 with 100000000
+DEAL:0::0_2:75 with 100000000
+DEAL:0::0_2:76 with 100000000
+DEAL:0::0_3:770 with 100000000
+DEAL:0::0_3:771 with 100000000
+DEAL:0::0_3:772 with 100000000
+DEAL:0::0_3:773 with 100000000
+DEAL:0::0_3:774 with 100000000
+DEAL:0::0_3:775 with 100000000
+DEAL:0::0_3:776 with 100000000
+DEAL:0::0_3:777 with 100000000
+DEAL:0::1_1:0 with 100000000
+DEAL:0::1_1:1 with 100000000
+DEAL:0::1_1:2 with 100000000
+DEAL:0::1_1:3 with 100000000
+DEAL:0::1_1:4 with 100000000
+DEAL:0::1_1:5 with 100000000
+DEAL:0::1_2:60 with 100000000
+DEAL:0::1_2:61 with 100000000
+DEAL:0::1_2:62 with 100000000
+DEAL:0::1_2:63 with 100000000
+DEAL:0::1_2:64 with 100000000
+DEAL:0::1_2:65 with 100000000
+DEAL:0::1_2:66 with 100000000
+DEAL:0::1_2:67 with 100000000
+DEAL:0::1_1:7 with 100000000
+DEAL:0::2_1:0 with 100000000
+DEAL:0::2_1:1 with 100000000
+DEAL:0::2_1:2 with 100000000
+DEAL:0::2_1:3 with 100000000
+DEAL:0::2_1:4 with 100000000
+DEAL:0::2_1:5 with 100000000
+DEAL:0::2_1:6 with 100000000
+DEAL:0::2_1:7 with 100000000
+DEAL:0::3_1:0 with 100000000
+DEAL:0::3_1:1 with 100000000
+DEAL:0::3_1:2 with 100000000
+DEAL:0::3_1:3 with 100000000
+DEAL:0::3_1:4 with 100000000
+DEAL:0::3_1:5 with 100000000
+DEAL:0::3_1:6 with 100000000
+DEAL:0::3_1:7 with 100000000
+DEAL:0::4_1:0 with 100000000
+DEAL:0::4_1:1 with 100000000
+DEAL:0::4_1:2 with 100000000
+DEAL:0::4_1:3 with 100000000
+DEAL:0::4_1:4 with 100000000
+DEAL:0::4_1:5 with 100000000
+DEAL:0::4_1:6 with 100000000
+DEAL:0::4_1:7 with 100000000
+DEAL:0::
diff --git a/tests/matrix_free/cell_categorization.with_p4est=true.mpirun=7.output b/tests/matrix_free/cell_categorization.with_p4est=true.mpirun=7.output
new file mode 100644 (file)
index 0000000..0dccca7
--- /dev/null
@@ -0,0 +1,1456 @@
+
+DEAL:0::Number of cell batches: 12
+DEAL:0::0_4:0000 with 0
+DEAL:0::0_4:0001 with 0
+DEAL:0::0_4:0002 with 0
+DEAL:0::0_4:0003 with 0
+DEAL:0::0_5:00100 with 0
+DEAL:0::0_5:00101 with 0
+DEAL:0::0_5:00102 with 0
+DEAL:0::0_5:00103 with 0
+DEAL:0::0_4:0020 with 1
+DEAL:0::0_4:0013 with 1
+DEAL:0::0_4:0012 with 1
+DEAL:0::0_4:0011 with 1
+DEAL:0::0_3:022 with 4
+DEAL:0::0_3:013 with 4
+DEAL:0::0_3:012 with 4
+DEAL:0::0_4:0021 with 4
+DEAL:0::0_3:010 with 0
+DEAL:0::0_4:0110 with 0
+DEAL:0::0_4:0111 with 0
+DEAL:0::0_4:0113 with 0
+DEAL:0::0_4:0212 with 3
+DEAL:0::0_4:0213 with 3
+DEAL:0::0_4:0211 with 3
+DEAL:0::0_4:0033 with 3
+DEAL:0::0_4:0030 with 1
+DEAL:0::0_4:0031 with 1
+DEAL:0::0_4:0112 with 1
+DEAL:0::0_5:00220 with 2
+DEAL:0::0_5:00221 with 2
+DEAL:0::0_6:002220 with 2
+DEAL:0::0_6:002221 with 2
+DEAL:0::0_6:002222 with 2
+DEAL:0::0_6:002223 with 2
+DEAL:0::0_5:00223 with 2
+DEAL:0::0_4:0023 with 2
+DEAL:0::0_4:0032 with 2
+DEAL:0::0_5:02000 with 2
+DEAL:0::0_5:02001 with 2
+DEAL:0::0_5:02002 with 2
+DEAL:0::0_5:02003 with 2
+DEAL:0::0_5:02010 with 2
+DEAL:0::0_5:02011 with 2
+DEAL:0::0_5:02012 with 2
+DEAL:0::0_4:0202 with 3
+DEAL:0::0_4:0203 with 3
+DEAL:0::0_4:0210 with 3
+DEAL:0::0_5:02013 with 3
+DEAL:0::
+DEAL:0::Number of cell batches: 16
+DEAL:0::0_4:0000 with 0
+DEAL:0::0_4:0001 with 0
+DEAL:0::0_4:0002 with 0
+DEAL:0::0_4:0003 with 0
+DEAL:0::0_5:00100 with 0
+DEAL:0::0_5:00101 with 0
+DEAL:0::0_5:00102 with 0
+DEAL:0::0_5:00103 with 0
+DEAL:0::0_4:0011 with 0
+DEAL:0::0_4:0012 with 0
+DEAL:0::0_4:0013 with 0
+DEAL:0::0_4:0020 with 1
+DEAL:0::0_4:0021 with 1
+DEAL:0::0_3:012 with 1
+DEAL:0::0_3:013 with 1
+DEAL:0::0_3:022 with 4
+DEAL:0::0_3:010 with 0
+DEAL:0::0_4:0110 with 0
+DEAL:0::0_4:0111 with 0
+DEAL:0::0_4:0113 with 0
+DEAL:0::0_4:0033 with 2
+DEAL:0::0_4:0211 with 2
+DEAL:0::0_4:0212 with 3
+DEAL:0::0_4:0213 with 3
+DEAL:0::0_4:0112 with 0
+DEAL:0::0_4:0030 with 1
+DEAL:0::0_4:0031 with 1
+DEAL:0::0_5:00220 with 2
+DEAL:0::0_5:00221 with 2
+DEAL:0::0_6:002220 with 2
+DEAL:0::0_6:002221 with 2
+DEAL:0::0_6:002222 with 2
+DEAL:0::0_6:002223 with 2
+DEAL:0::0_5:00223 with 2
+DEAL:0::0_4:0023 with 2
+DEAL:0::0_4:0032 with 2
+DEAL:0::0_5:02000 with 2
+DEAL:0::0_5:02001 with 2
+DEAL:0::0_5:02002 with 2
+DEAL:0::0_5:02003 with 2
+DEAL:0::0_5:02010 with 2
+DEAL:0::0_5:02011 with 2
+DEAL:0::0_5:02012 with 2
+DEAL:0::0_5:02013 with 2
+DEAL:0::0_4:0210 with 2
+DEAL:0::0_4:0202 with 3
+DEAL:0::0_4:0203 with 3
+DEAL:0::
+DEAL:0::Number of cell batches: 12
+DEAL:0::0_4:0000 with 100000000
+DEAL:0::0_4:0001 with 100000000
+DEAL:0::0_4:0002 with 100000000
+DEAL:0::0_4:0003 with 100000000
+DEAL:0::0_5:00100 with 100000000
+DEAL:0::0_5:00101 with 100000000
+DEAL:0::0_5:00102 with 100000000
+DEAL:0::0_5:00103 with 100000000
+DEAL:0::0_4:0011 with 100000000
+DEAL:0::0_4:0012 with 100000000
+DEAL:0::0_4:0013 with 100000000
+DEAL:0::0_4:0020 with 100000000
+DEAL:0::0_4:0021 with 100000000
+DEAL:0::0_3:012 with 100000000
+DEAL:0::0_3:013 with 100000000
+DEAL:0::0_3:022 with 100000000
+DEAL:0::0_4:0033 with 100000000
+DEAL:0::0_3:010 with 100000000
+DEAL:0::0_4:0110 with 100000000
+DEAL:0::0_4:0111 with 100000000
+DEAL:0::0_4:0113 with 100000000
+DEAL:0::0_4:0211 with 100000000
+DEAL:0::0_4:0212 with 100000000
+DEAL:0::0_4:0213 with 100000000
+DEAL:0::0_5:00220 with 100000000
+DEAL:0::0_5:00221 with 100000000
+DEAL:0::0_6:002220 with 100000000
+DEAL:0::0_6:002221 with 100000000
+DEAL:0::0_6:002222 with 100000000
+DEAL:0::0_6:002223 with 100000000
+DEAL:0::0_5:00223 with 100000000
+DEAL:0::0_4:0023 with 100000000
+DEAL:0::0_4:0030 with 100000000
+DEAL:0::0_4:0031 with 100000000
+DEAL:0::0_4:0032 with 100000000
+DEAL:0::0_4:0112 with 100000000
+DEAL:0::0_5:02000 with 100000000
+DEAL:0::0_5:02001 with 100000000
+DEAL:0::0_5:02002 with 100000000
+DEAL:0::0_5:02003 with 100000000
+DEAL:0::0_5:02010 with 100000000
+DEAL:0::0_5:02011 with 100000000
+DEAL:0::0_5:02012 with 100000000
+DEAL:0::0_5:02013 with 100000000
+DEAL:0::0_4:0202 with 100000000
+DEAL:0::0_4:0203 with 100000000
+DEAL:0::0_4:0210 with 100000000
+DEAL:0::
+DEAL:0::Number of cell batches: 4
+DEAL:0::0_3:006 with 1
+DEAL:0::0_3:007 with 1
+DEAL:0::0_2:01 with 1
+DEAL:0::0_3:005 with 1
+DEAL:0::0_2:02 with 3
+DEAL:0::0_2:06 with 3
+DEAL:0::0_2:05 with 3
+DEAL:0::0_2:04 with 3
+DEAL:0::0_3:000 with 0
+DEAL:0::0_3:001 with 0
+DEAL:0::0_3:004 with 0
+DEAL:0::0_2:03 with 3
+DEAL:0::0_2:07 with 3
+DEAL:0::0_3:003 with 3
+DEAL:0::0_3:002 with 3
+DEAL:0::
+DEAL:0::Number of cell batches: 7
+DEAL:0::0_3:005 with 0
+DEAL:0::0_3:006 with 1
+DEAL:0::0_3:007 with 1
+DEAL:0::0_2:01 with 1
+DEAL:0::0_2:04 with 1
+DEAL:0::0_2:05 with 1
+DEAL:0::0_2:02 with 3
+DEAL:0::0_2:06 with 3
+DEAL:0::0_3:000 with 0
+DEAL:0::0_3:001 with 0
+DEAL:0::0_3:004 with 0
+DEAL:0::0_3:002 with 1
+DEAL:0::0_3:003 with 1
+DEAL:0::0_2:03 with 3
+DEAL:0::0_2:07 with 3
+DEAL:0::
+DEAL:0::Number of cell batches: 4
+DEAL:0::0_3:005 with 100000000
+DEAL:0::0_3:006 with 100000000
+DEAL:0::0_3:007 with 100000000
+DEAL:0::0_2:01 with 100000000
+DEAL:0::0_2:02 with 100000000
+DEAL:0::0_2:04 with 100000000
+DEAL:0::0_2:05 with 100000000
+DEAL:0::0_2:06 with 100000000
+DEAL:0::0_3:000 with 100000000
+DEAL:0::0_3:001 with 100000000
+DEAL:0::0_3:002 with 100000000
+DEAL:0::0_3:003 with 100000000
+DEAL:0::0_3:004 with 100000000
+DEAL:0::0_2:03 with 100000000
+DEAL:0::0_2:07 with 100000000
+DEAL:0::
+
+DEAL:1::Number of cell batches: 12
+DEAL:1::0_4:0312 with 3
+DEAL:1::0_4:0313 with 3
+DEAL:1::0_2:11 with 3
+DEAL:1::0_3:103 with 3
+DEAL:1::0_3:032 with 4
+DEAL:1::0_3:130 with 4
+DEAL:1::0_3:121 with 4
+DEAL:1::0_3:120 with 4
+DEAL:1::0_3:213 with 6
+DEAL:1::0_4:2002 with 6
+DEAL:1::0_3:132 with 6
+DEAL:1::0_3:123 with 6
+DEAL:1::0_4:0310 with 2
+DEAL:1::0_3:102 with 2
+DEAL:1::0_3:101 with 2
+DEAL:1::0_3:100 with 2
+DEAL:1::0_3:023 with 4
+DEAL:1::0_3:131 with 4
+DEAL:1::0_3:030 with 4
+DEAL:1::0_4:0311 with 4
+DEAL:1::0_4:2000 with 5
+DEAL:1::0_3:133 with 5
+DEAL:1::0_3:122 with 5
+DEAL:1::0_3:033 with 5
+DEAL:1::0_4:2022 with 7
+DEAL:1::0_4:2023 with 7
+DEAL:1::0_4:2032 with 7
+DEAL:1::0_4:2033 with 7
+DEAL:1::0_4:2122 with 7
+DEAL:1::0_4:2123 with 7
+DEAL:1::0_3:211 with 7
+DEAL:1::0_4:2001 with 7
+DEAL:1::0_4:2003 with 5
+DEAL:1::0_4:2010 with 5
+DEAL:1::0_4:2011 with 5
+DEAL:1::0_4:2020 with 6
+DEAL:1::0_4:2021 with 6
+DEAL:1::0_5:20300 with 6
+DEAL:1::0_5:20301 with 6
+DEAL:1::0_5:20302 with 6
+DEAL:1::0_5:20303 with 6
+DEAL:1::0_4:2031 with 6
+DEAL:1::0_4:2120 with 6
+DEAL:1::0_4:2121 with 6
+DEAL:1::0_3:210 with 6
+DEAL:1::0_4:2013 with 6
+DEAL:1::0_4:2012 with 6
+DEAL:1::
+DEAL:1::Number of cell batches: 19
+DEAL:1::0_3:103 with 1
+DEAL:1::0_2:11 with 1
+DEAL:1::0_4:0312 with 3
+DEAL:1::0_4:0313 with 3
+DEAL:1::0_3:120 with 3
+DEAL:1::0_3:121 with 3
+DEAL:1::0_3:130 with 3
+DEAL:1::0_3:032 with 4
+DEAL:1::0_3:123 with 4
+DEAL:1::0_3:132 with 4
+DEAL:1::0_4:2002 with 5
+DEAL:1::0_3:213 with 6
+DEAL:1::0_3:100 with 0
+DEAL:1::0_3:101 with 0
+DEAL:1::0_3:102 with 1
+DEAL:1::0_4:0310 with 2
+DEAL:1::0_4:0311 with 2
+DEAL:1::0_3:030 with 3
+DEAL:1::0_3:131 with 3
+DEAL:1::0_3:023 with 4
+DEAL:1::0_3:033 with 4
+DEAL:1::0_3:122 with 4
+DEAL:1::0_3:133 with 4
+DEAL:1::0_4:2000 with 5
+DEAL:1::0_4:2001 with 5
+DEAL:1::0_3:211 with 5
+DEAL:1::0_4:2022 with 7
+DEAL:1::0_4:2023 with 7
+DEAL:1::0_4:2032 with 7
+DEAL:1::0_4:2033 with 7
+DEAL:1::0_4:2122 with 7
+DEAL:1::0_4:2123 with 7
+DEAL:1::0_4:2003 with 5
+DEAL:1::0_4:2010 with 5
+DEAL:1::0_4:2011 with 5
+DEAL:1::0_4:2012 with 5
+DEAL:1::0_4:2013 with 5
+DEAL:1::0_3:210 with 5
+DEAL:1::0_4:2020 with 6
+DEAL:1::0_4:2021 with 6
+DEAL:1::0_5:20300 with 6
+DEAL:1::0_5:20301 with 6
+DEAL:1::0_5:20302 with 6
+DEAL:1::0_5:20303 with 6
+DEAL:1::0_4:2031 with 6
+DEAL:1::0_4:2120 with 6
+DEAL:1::0_4:2121 with 6
+DEAL:1::
+DEAL:1::Number of cell batches: 12
+DEAL:1::0_4:0312 with 100000000
+DEAL:1::0_4:0313 with 100000000
+DEAL:1::0_3:032 with 100000000
+DEAL:1::0_3:103 with 100000000
+DEAL:1::0_2:11 with 100000000
+DEAL:1::0_3:120 with 100000000
+DEAL:1::0_3:121 with 100000000
+DEAL:1::0_3:123 with 100000000
+DEAL:1::0_3:130 with 100000000
+DEAL:1::0_3:132 with 100000000
+DEAL:1::0_4:2002 with 100000000
+DEAL:1::0_3:213 with 100000000
+DEAL:1::0_3:023 with 100000000
+DEAL:1::0_3:030 with 100000000
+DEAL:1::0_4:0310 with 100000000
+DEAL:1::0_4:0311 with 100000000
+DEAL:1::0_3:033 with 100000000
+DEAL:1::0_3:100 with 100000000
+DEAL:1::0_3:101 with 100000000
+DEAL:1::0_3:102 with 100000000
+DEAL:1::0_3:122 with 100000000
+DEAL:1::0_3:131 with 100000000
+DEAL:1::0_3:133 with 100000000
+DEAL:1::0_4:2000 with 100000000
+DEAL:1::0_4:2001 with 100000000
+DEAL:1::0_4:2022 with 100000000
+DEAL:1::0_4:2023 with 100000000
+DEAL:1::0_4:2032 with 100000000
+DEAL:1::0_4:2033 with 100000000
+DEAL:1::0_3:211 with 100000000
+DEAL:1::0_4:2122 with 100000000
+DEAL:1::0_4:2123 with 100000000
+DEAL:1::0_4:2003 with 100000000
+DEAL:1::0_4:2010 with 100000000
+DEAL:1::0_4:2011 with 100000000
+DEAL:1::0_4:2012 with 100000000
+DEAL:1::0_4:2013 with 100000000
+DEAL:1::0_4:2020 with 100000000
+DEAL:1::0_4:2021 with 100000000
+DEAL:1::0_5:20300 with 100000000
+DEAL:1::0_5:20301 with 100000000
+DEAL:1::0_5:20302 with 100000000
+DEAL:1::0_5:20303 with 100000000
+DEAL:1::0_4:2031 with 100000000
+DEAL:1::0_3:210 with 100000000
+DEAL:1::0_4:2120 with 100000000
+DEAL:1::0_4:2121 with 100000000
+DEAL:1::
+DEAL:1::Number of cell batches: 6
+DEAL:1::0_2:36 with 8
+DEAL:1::0_2:34 with 8
+DEAL:1::0_2:20 with 8
+DEAL:1::0_2:10 with 8
+DEAL:1::0_2:12 with 3
+DEAL:1::0_2:15 with 3
+DEAL:1::0_2:14 with 3
+DEAL:1::0_2:11 with 3
+DEAL:1::0_2:21 with 6
+DEAL:1::0_2:24 with 6
+DEAL:1::0_2:25 with 6
+DEAL:1::0_2:31 with 6
+DEAL:1::0_2:35 with 6
+DEAL:1::0_2:17 with 6
+DEAL:1::0_2:16 with 6
+DEAL:1::0_2:13 with 6
+DEAL:1::0_2:26 with 8
+DEAL:1::0_2:27 with 8
+DEAL:1::0_2:33 with 8
+DEAL:1::0_2:37 with 8
+DEAL:1::0_2:22 with 8
+DEAL:1::0_2:23 with 8
+DEAL:1::0_2:32 with 8
+DEAL:1::0_2:30 with 8
+DEAL:1::
+DEAL:1::Number of cell batches: 10
+DEAL:1::0_2:10 with 1
+DEAL:1::0_2:20 with 6
+DEAL:1::0_2:34 with 6
+DEAL:1::0_2:36 with 8
+DEAL:1::0_2:11 with 1
+DEAL:1::0_2:14 with 1
+DEAL:1::0_2:15 with 1
+DEAL:1::0_2:12 with 3
+DEAL:1::0_2:13 with 3
+DEAL:1::0_2:16 with 3
+DEAL:1::0_2:17 with 3
+DEAL:1::0_2:21 with 6
+DEAL:1::0_2:24 with 6
+DEAL:1::0_2:25 with 6
+DEAL:1::0_2:31 with 6
+DEAL:1::0_2:35 with 6
+DEAL:1::0_2:26 with 8
+DEAL:1::0_2:27 with 8
+DEAL:1::0_2:33 with 8
+DEAL:1::0_2:37 with 8
+DEAL:1::0_2:30 with 6
+DEAL:1::0_2:22 with 8
+DEAL:1::0_2:23 with 8
+DEAL:1::0_2:32 with 8
+DEAL:1::
+DEAL:1::Number of cell batches: 6
+DEAL:1::0_2:10 with 100000000
+DEAL:1::0_2:20 with 100000000
+DEAL:1::0_2:34 with 100000000
+DEAL:1::0_2:36 with 100000000
+DEAL:1::0_2:11 with 100000000
+DEAL:1::0_2:12 with 100000000
+DEAL:1::0_2:13 with 100000000
+DEAL:1::0_2:14 with 100000000
+DEAL:1::0_2:15 with 100000000
+DEAL:1::0_2:16 with 100000000
+DEAL:1::0_2:17 with 100000000
+DEAL:1::0_2:21 with 100000000
+DEAL:1::0_2:24 with 100000000
+DEAL:1::0_2:25 with 100000000
+DEAL:1::0_2:26 with 100000000
+DEAL:1::0_2:27 with 100000000
+DEAL:1::0_2:31 with 100000000
+DEAL:1::0_2:33 with 100000000
+DEAL:1::0_2:35 with 100000000
+DEAL:1::0_2:37 with 100000000
+DEAL:1::0_2:22 with 100000000
+DEAL:1::0_2:23 with 100000000
+DEAL:1::0_2:30 with 100000000
+DEAL:1::0_2:32 with 100000000
+DEAL:1::
+
+
+DEAL:2::Number of cell batches: 12
+DEAL:2::0_3:303 with 6
+DEAL:2::0_4:3103 with 6
+DEAL:2::0_4:3102 with 6
+DEAL:2::0_3:300 with 6
+DEAL:2::0_3:222 with 9
+DEAL:2::0_4:2230 with 9
+DEAL:2::0_4:2231 with 9
+DEAL:2::0_3:232 with 9
+DEAL:2::0_4:2330 with 9
+DEAL:2::0_4:2331 with 9
+DEAL:2::0_4:2332 with 9
+DEAL:2::0_4:2333 with 9
+DEAL:2::0_4:3323 with 9
+DEAL:2::0_4:3313 with 9
+DEAL:2::0_3:221 with 9
+DEAL:2::0_3:220 with 9
+DEAL:2::0_3:301 with 5
+DEAL:2::0_4:3100 with 5
+DEAL:2::0_4:3101 with 5
+DEAL:2::0_3:311 with 5
+DEAL:2::0_3:230 with 8
+DEAL:2::0_3:231 with 8
+DEAL:2::0_4:3311 with 8
+DEAL:2::0_3:302 with 8
+DEAL:2::0_4:2232 with 9
+DEAL:2::0_4:2233 with 9
+DEAL:2::0_4:3321 with 9
+DEAL:2::0_4:3312 with 9
+DEAL:2::0_4:3210 with 7
+DEAL:2::0_4:3211 with 7
+DEAL:2::0_4:3300 with 7
+DEAL:2::0_4:3301 with 7
+DEAL:2::0_4:3310 with 7
+DEAL:2::0_3:313 with 7
+DEAL:2::0_3:312 with 7
+DEAL:2::0_3:320 with 8
+DEAL:2::0_4:3212 with 8
+DEAL:2::0_4:3213 with 8
+DEAL:2::0_4:3302 with 8
+DEAL:2::0_5:33030 with 8
+DEAL:2::0_5:33031 with 8
+DEAL:2::0_5:33032 with 8
+DEAL:2::0_5:33033 with 8
+DEAL:2::0_3:322 with 9
+DEAL:2::0_3:323 with 9
+DEAL:2::0_4:3320 with 9
+DEAL:2::0_4:3322 with 9
+DEAL:2::
+DEAL:2::Number of cell batches: 17
+DEAL:2::0_3:300 with 5
+DEAL:2::0_4:3102 with 5
+DEAL:2::0_4:3103 with 5
+DEAL:2::0_3:303 with 6
+DEAL:2::0_3:220 with 8
+DEAL:2::0_3:221 with 8
+DEAL:2::0_4:3313 with 8
+DEAL:2::0_3:222 with 9
+DEAL:2::0_4:2230 with 9
+DEAL:2::0_4:2231 with 9
+DEAL:2::0_3:232 with 9
+DEAL:2::0_4:2330 with 9
+DEAL:2::0_4:2331 with 9
+DEAL:2::0_4:2332 with 9
+DEAL:2::0_4:2333 with 9
+DEAL:2::0_4:3323 with 9
+DEAL:2::0_3:301 with 5
+DEAL:2::0_4:3100 with 5
+DEAL:2::0_4:3101 with 5
+DEAL:2::0_3:311 with 5
+DEAL:2::0_3:302 with 6
+DEAL:2::0_4:3311 with 7
+DEAL:2::0_3:230 with 8
+DEAL:2::0_3:231 with 8
+DEAL:2::0_4:3312 with 8
+DEAL:2::0_4:2232 with 9
+DEAL:2::0_4:2233 with 9
+DEAL:2::0_4:3321 with 9
+DEAL:2::0_3:312 with 6
+DEAL:2::0_3:313 with 6
+DEAL:2::0_4:3210 with 7
+DEAL:2::0_4:3211 with 7
+DEAL:2::0_4:3300 with 7
+DEAL:2::0_4:3301 with 7
+DEAL:2::0_4:3310 with 7
+DEAL:2::0_3:320 with 8
+DEAL:2::0_4:3212 with 8
+DEAL:2::0_4:3213 with 8
+DEAL:2::0_4:3302 with 8
+DEAL:2::0_5:33030 with 8
+DEAL:2::0_5:33031 with 8
+DEAL:2::0_5:33032 with 8
+DEAL:2::0_5:33033 with 8
+DEAL:2::0_3:322 with 9
+DEAL:2::0_3:323 with 9
+DEAL:2::0_4:3320 with 9
+DEAL:2::0_4:3322 with 9
+DEAL:2::
+DEAL:2::Number of cell batches: 12
+DEAL:2::0_3:220 with 100000000
+DEAL:2::0_3:221 with 100000000
+DEAL:2::0_3:222 with 100000000
+DEAL:2::0_4:2230 with 100000000
+DEAL:2::0_4:2231 with 100000000
+DEAL:2::0_3:232 with 100000000
+DEAL:2::0_4:2330 with 100000000
+DEAL:2::0_4:2331 with 100000000
+DEAL:2::0_4:2332 with 100000000
+DEAL:2::0_4:2333 with 100000000
+DEAL:2::0_3:300 with 100000000
+DEAL:2::0_3:303 with 100000000
+DEAL:2::0_4:3102 with 100000000
+DEAL:2::0_4:3103 with 100000000
+DEAL:2::0_4:3313 with 100000000
+DEAL:2::0_4:3323 with 100000000
+DEAL:2::0_4:2232 with 100000000
+DEAL:2::0_4:2233 with 100000000
+DEAL:2::0_3:230 with 100000000
+DEAL:2::0_3:231 with 100000000
+DEAL:2::0_3:301 with 100000000
+DEAL:2::0_3:302 with 100000000
+DEAL:2::0_4:3100 with 100000000
+DEAL:2::0_4:3101 with 100000000
+DEAL:2::0_3:311 with 100000000
+DEAL:2::0_4:3311 with 100000000
+DEAL:2::0_4:3312 with 100000000
+DEAL:2::0_4:3321 with 100000000
+DEAL:2::0_3:312 with 100000000
+DEAL:2::0_3:313 with 100000000
+DEAL:2::0_3:320 with 100000000
+DEAL:2::0_4:3210 with 100000000
+DEAL:2::0_4:3211 with 100000000
+DEAL:2::0_4:3212 with 100000000
+DEAL:2::0_4:3213 with 100000000
+DEAL:2::0_3:322 with 100000000
+DEAL:2::0_3:323 with 100000000
+DEAL:2::0_4:3300 with 100000000
+DEAL:2::0_4:3301 with 100000000
+DEAL:2::0_4:3302 with 100000000
+DEAL:2::0_5:33030 with 100000000
+DEAL:2::0_5:33031 with 100000000
+DEAL:2::0_5:33032 with 100000000
+DEAL:2::0_5:33033 with 100000000
+DEAL:2::0_4:3310 with 100000000
+DEAL:2::0_4:3320 with 100000000
+DEAL:2::0_4:3322 with 100000000
+DEAL:2::
+DEAL:2::Number of cell batches: 4
+DEAL:2::0_2:40 with 1
+DEAL:2::0_2:41 with 1
+DEAL:2::0_2:45 with 1
+DEAL:2::0_2:51 with 1
+DEAL:2::0_2:42 with 3
+DEAL:2::0_2:43 with 3
+DEAL:2::0_2:46 with 3
+DEAL:2::0_2:47 with 3
+DEAL:2::0_2:52 with 3
+DEAL:2::0_2:53 with 3
+DEAL:2::0_2:57 with 3
+DEAL:2::0_2:55 with 3
+DEAL:2::0_2:56 with 3
+DEAL:2::0_2:54 with 3
+DEAL:2::0_2:50 with 3
+DEAL:2::0_2:44 with 3
+DEAL:2::
+DEAL:2::Number of cell batches: 6
+DEAL:2::0_2:40 with 1
+DEAL:2::0_2:41 with 1
+DEAL:2::0_2:45 with 1
+DEAL:2::0_2:51 with 1
+DEAL:2::0_2:55 with 1
+DEAL:2::0_2:42 with 3
+DEAL:2::0_2:43 with 3
+DEAL:2::0_2:46 with 3
+DEAL:2::0_2:47 with 3
+DEAL:2::0_2:52 with 3
+DEAL:2::0_2:53 with 3
+DEAL:2::0_2:57 with 3
+DEAL:2::0_2:44 with 1
+DEAL:2::0_2:50 with 1
+DEAL:2::0_2:54 with 1
+DEAL:2::0_2:56 with 3
+DEAL:2::
+DEAL:2::Number of cell batches: 4
+DEAL:2::0_2:40 with 100000000
+DEAL:2::0_2:41 with 100000000
+DEAL:2::0_2:42 with 100000000
+DEAL:2::0_2:43 with 100000000
+DEAL:2::0_2:45 with 100000000
+DEAL:2::0_2:46 with 100000000
+DEAL:2::0_2:47 with 100000000
+DEAL:2::0_2:51 with 100000000
+DEAL:2::0_2:52 with 100000000
+DEAL:2::0_2:53 with 100000000
+DEAL:2::0_2:55 with 100000000
+DEAL:2::0_2:57 with 100000000
+DEAL:2::0_2:44 with 100000000
+DEAL:2::0_2:50 with 100000000
+DEAL:2::0_2:54 with 100000000
+DEAL:2::0_2:56 with 100000000
+DEAL:2::
+
+
+DEAL:3::Number of cell batches: 12
+DEAL:3::1_3:020 with 3
+DEAL:3::1_2:01 with 3
+DEAL:3::1_3:003 with 3
+DEAL:3::1_3:001 with 3
+DEAL:3::1_3:200 with 5
+DEAL:3::1_4:0230 with 5
+DEAL:3::1_3:022 with 5
+DEAL:3::1_3:021 with 5
+DEAL:3::1_4:2023 with 7
+DEAL:3::1_4:2033 with 7
+DEAL:3::1_3:213 with 7
+DEAL:3::1_3:212 with 7
+DEAL:3::1_2:13 with 3
+DEAL:3::1_2:11 with 3
+DEAL:3::1_3:002 with 3
+DEAL:3::1_3:000 with 3
+DEAL:3::1_4:2111 with 5
+DEAL:3::1_4:2113 with 5
+DEAL:3::1_3:123 with 5
+DEAL:3::1_3:122 with 5
+DEAL:3::1_4:2022 with 7
+DEAL:3::1_5:20322 with 7
+DEAL:3::1_5:20323 with 7
+DEAL:3::1_4:2020 with 7
+DEAL:3::0_4:3330 with 9
+DEAL:3::0_4:3331 with 9
+DEAL:3::0_4:3332 with 9
+DEAL:3::0_4:3333 with 9
+DEAL:3::1_3:030 with 3
+DEAL:3::1_3:031 with 3
+DEAL:3::1_2:10 with 3
+DEAL:3::1_4:0231 with 4
+DEAL:3::1_4:0232 with 4
+DEAL:3::1_3:121 with 4
+DEAL:3::1_3:120 with 4
+DEAL:3::1_3:201 with 5
+DEAL:3::1_3:033 with 5
+DEAL:3::1_3:032 with 5
+DEAL:3::1_4:0233 with 5
+DEAL:3::1_4:2021 with 6
+DEAL:3::1_4:2112 with 6
+DEAL:3::1_4:2110 with 6
+DEAL:3::1_3:210 with 6
+DEAL:3::1_5:20320 with 7
+DEAL:3::1_5:20321 with 7
+DEAL:3::1_4:2031 with 7
+DEAL:3::1_4:2030 with 7
+DEAL:3::
+DEAL:3::Number of cell batches: 22
+DEAL:3::1_3:001 with 0
+DEAL:3::1_3:003 with 1
+DEAL:3::1_2:01 with 1
+DEAL:3::1_3:020 with 3
+DEAL:3::1_3:021 with 3
+DEAL:3::1_3:022 with 4
+DEAL:3::1_4:0230 with 4
+DEAL:3::1_3:200 with 5
+DEAL:3::1_3:212 with 6
+DEAL:3::1_3:213 with 6
+DEAL:3::1_4:2023 with 7
+DEAL:3::1_4:2033 with 7
+DEAL:3::1_3:000 with 0
+DEAL:3::1_3:002 with 1
+DEAL:3::1_2:11 with 1
+DEAL:3::1_2:13 with 3
+DEAL:3::1_3:122 with 4
+DEAL:3::1_3:123 with 4
+DEAL:3::1_4:2111 with 5
+DEAL:3::1_4:2113 with 5
+DEAL:3::1_4:2020 with 6
+DEAL:3::1_4:2022 with 7
+DEAL:3::1_5:20322 with 7
+DEAL:3::1_5:20323 with 7
+DEAL:3::0_4:3330 with 9
+DEAL:3::0_4:3331 with 9
+DEAL:3::0_4:3332 with 9
+DEAL:3::0_4:3333 with 9
+DEAL:3::1_2:10 with 1
+DEAL:3::1_3:030 with 3
+DEAL:3::1_3:031 with 3
+DEAL:3::1_3:120 with 3
+DEAL:3::1_3:121 with 3
+DEAL:3::1_4:0231 with 4
+DEAL:3::1_4:0232 with 4
+DEAL:3::1_4:0233 with 4
+DEAL:3::1_3:032 with 4
+DEAL:3::1_3:033 with 4
+DEAL:3::1_3:201 with 5
+DEAL:3::1_3:210 with 5
+DEAL:3::1_4:2110 with 5
+DEAL:3::1_4:2112 with 5
+DEAL:3::1_4:2021 with 6
+DEAL:3::1_4:2030 with 6
+DEAL:3::1_4:2031 with 6
+DEAL:3::1_5:20320 with 7
+DEAL:3::1_5:20321 with 7
+DEAL:3::
+DEAL:3::Number of cell batches: 12
+DEAL:3::1_3:001 with 100000000
+DEAL:3::1_3:003 with 100000000
+DEAL:3::1_2:01 with 100000000
+DEAL:3::1_3:020 with 100000000
+DEAL:3::1_3:021 with 100000000
+DEAL:3::1_3:022 with 100000000
+DEAL:3::1_4:0230 with 100000000
+DEAL:3::1_3:200 with 100000000
+DEAL:3::1_4:2023 with 100000000
+DEAL:3::1_4:2033 with 100000000
+DEAL:3::1_3:212 with 100000000
+DEAL:3::1_3:213 with 100000000
+DEAL:3::0_4:3330 with 100000000
+DEAL:3::0_4:3331 with 100000000
+DEAL:3::0_4:3332 with 100000000
+DEAL:3::0_4:3333 with 100000000
+DEAL:3::1_3:000 with 100000000
+DEAL:3::1_3:002 with 100000000
+DEAL:3::1_2:11 with 100000000
+DEAL:3::1_3:122 with 100000000
+DEAL:3::1_3:123 with 100000000
+DEAL:3::1_2:13 with 100000000
+DEAL:3::1_4:2020 with 100000000
+DEAL:3::1_4:2022 with 100000000
+DEAL:3::1_5:20322 with 100000000
+DEAL:3::1_5:20323 with 100000000
+DEAL:3::1_4:2111 with 100000000
+DEAL:3::1_4:2113 with 100000000
+DEAL:3::1_4:0231 with 100000000
+DEAL:3::1_4:0232 with 100000000
+DEAL:3::1_4:0233 with 100000000
+DEAL:3::1_3:030 with 100000000
+DEAL:3::1_3:031 with 100000000
+DEAL:3::1_3:032 with 100000000
+DEAL:3::1_3:033 with 100000000
+DEAL:3::1_2:10 with 100000000
+DEAL:3::1_3:120 with 100000000
+DEAL:3::1_3:121 with 100000000
+DEAL:3::1_3:201 with 100000000
+DEAL:3::1_4:2021 with 100000000
+DEAL:3::1_4:2030 with 100000000
+DEAL:3::1_4:2031 with 100000000
+DEAL:3::1_5:20320 with 100000000
+DEAL:3::1_5:20321 with 100000000
+DEAL:3::1_3:210 with 100000000
+DEAL:3::1_4:2110 with 100000000
+DEAL:3::1_4:2112 with 100000000
+DEAL:3::
+DEAL:3::Number of cell batches: 4
+DEAL:3::0_2:70 with 6
+DEAL:3::0_2:71 with 6
+DEAL:3::0_2:74 with 6
+DEAL:3::0_2:75 with 6
+DEAL:3::0_2:66 with 8
+DEAL:3::0_2:67 with 8
+DEAL:3::0_2:72 with 8
+DEAL:3::0_2:73 with 8
+DEAL:3::0_2:60 with 6
+DEAL:3::0_2:61 with 6
+DEAL:3::0_2:64 with 6
+DEAL:3::0_2:62 with 8
+DEAL:3::0_2:63 with 8
+DEAL:3::0_2:76 with 8
+DEAL:3::0_2:65 with 8
+DEAL:3::
+DEAL:3::Number of cell batches: 4
+DEAL:3::0_2:70 with 6
+DEAL:3::0_2:71 with 6
+DEAL:3::0_2:74 with 6
+DEAL:3::0_2:75 with 6
+DEAL:3::0_2:66 with 8
+DEAL:3::0_2:67 with 8
+DEAL:3::0_2:72 with 8
+DEAL:3::0_2:73 with 8
+DEAL:3::0_2:60 with 6
+DEAL:3::0_2:61 with 6
+DEAL:3::0_2:64 with 6
+DEAL:3::0_2:65 with 6
+DEAL:3::0_2:62 with 8
+DEAL:3::0_2:63 with 8
+DEAL:3::0_2:76 with 8
+DEAL:3::
+DEAL:3::Number of cell batches: 4
+DEAL:3::0_2:66 with 100000000
+DEAL:3::0_2:67 with 100000000
+DEAL:3::0_2:70 with 100000000
+DEAL:3::0_2:71 with 100000000
+DEAL:3::0_2:72 with 100000000
+DEAL:3::0_2:73 with 100000000
+DEAL:3::0_2:74 with 100000000
+DEAL:3::0_2:75 with 100000000
+DEAL:3::0_2:60 with 100000000
+DEAL:3::0_2:61 with 100000000
+DEAL:3::0_2:62 with 100000000
+DEAL:3::0_2:63 with 100000000
+DEAL:3::0_2:64 with 100000000
+DEAL:3::0_2:65 with 100000000
+DEAL:3::0_2:76 with 100000000
+DEAL:3::
+
+
+DEAL:4::Number of cell batches: 12
+DEAL:4::1_4:2210 with 7
+DEAL:4::1_3:301 with 7
+DEAL:4::1_3:300 with 7
+DEAL:4::2_2:00 with 7
+DEAL:4::1_4:2203 with 8
+DEAL:4::1_4:2212 with 8
+DEAL:4::1_4:2213 with 8
+DEAL:4::2_2:03 with 8
+DEAL:4::2_3:121 with 10
+DEAL:4::1_5:22221 with 10
+DEAL:4::1_4:2221 with 10
+DEAL:4::1_4:2220 with 10
+DEAL:4::1_3:302 with 6
+DEAL:4::2_2:02 with 6
+DEAL:4::1_3:311 with 6
+DEAL:4::1_3:310 with 6
+DEAL:4::1_4:2200 with 7
+DEAL:4::1_4:2201 with 7
+DEAL:4::1_4:2211 with 7
+DEAL:4::1_3:313 with 7
+DEAL:4::1_4:2202 with 8
+DEAL:4::1_3:230 with 8
+DEAL:4::1_3:231 with 8
+DEAL:4::1_2:33 with 8
+DEAL:4::2_3:123 with 11
+DEAL:4::2_3:122 with 11
+DEAL:4::1_5:22222 with 11
+DEAL:4::1_5:22220 with 11
+DEAL:4::1_3:303 with 6
+DEAL:4::2_2:01 with 6
+DEAL:4::1_3:320 with 8
+DEAL:4::1_3:321 with 8
+DEAL:4::2_2:10 with 8
+DEAL:4::1_3:312 with 8
+DEAL:4::1_5:22223 with 9
+DEAL:4::1_4:2223 with 9
+DEAL:4::1_3:223 with 9
+DEAL:4::1_3:232 with 9
+DEAL:4::1_4:2330 with 9
+DEAL:4::1_4:2331 with 9
+DEAL:4::1_4:2332 with 9
+DEAL:4::2_3:120 with 9
+DEAL:4::2_2:11 with 10
+DEAL:4::1_3:323 with 10
+DEAL:4::1_3:322 with 10
+DEAL:4::1_4:2333 with 10
+DEAL:4::
+DEAL:4::Number of cell batches: 21
+DEAL:4::2_2:00 with 2
+DEAL:4::1_3:300 with 5
+DEAL:4::1_3:301 with 5
+DEAL:4::1_4:2210 with 7
+DEAL:4::2_2:03 with 7
+DEAL:4::1_4:2203 with 8
+DEAL:4::1_4:2212 with 8
+DEAL:4::1_4:2213 with 8
+DEAL:4::1_4:2220 with 9
+DEAL:4::1_4:2221 with 9
+DEAL:4::1_5:22221 with 9
+DEAL:4::2_3:121 with 10
+DEAL:4::1_3:310 with 5
+DEAL:4::1_3:311 with 5
+DEAL:4::2_2:02 with 5
+DEAL:4::1_3:302 with 6
+DEAL:4::1_3:313 with 6
+DEAL:4::1_4:2200 with 7
+DEAL:4::1_4:2201 with 7
+DEAL:4::1_4:2211 with 7
+DEAL:4::1_4:2202 with 8
+DEAL:4::1_3:230 with 8
+DEAL:4::1_3:231 with 8
+DEAL:4::1_2:33 with 8
+DEAL:4::1_5:22220 with 9
+DEAL:4::1_5:22222 with 9
+DEAL:4::2_3:122 with 10
+DEAL:4::2_3:123 with 11
+DEAL:4::2_2:01 with 5
+DEAL:4::1_3:303 with 6
+DEAL:4::1_3:312 with 6
+DEAL:4::2_2:10 with 7
+DEAL:4::1_3:320 with 8
+DEAL:4::1_3:321 with 8
+DEAL:4::2_3:120 with 8
+DEAL:4::1_5:22223 with 9
+DEAL:4::1_4:2223 with 9
+DEAL:4::1_3:223 with 9
+DEAL:4::1_3:232 with 9
+DEAL:4::1_4:2330 with 9
+DEAL:4::1_4:2331 with 9
+DEAL:4::1_4:2332 with 9
+DEAL:4::1_4:2333 with 9
+DEAL:4::1_3:322 with 9
+DEAL:4::1_3:323 with 9
+DEAL:4::2_2:11 with 10
+DEAL:4::
+DEAL:4::Number of cell batches: 12
+DEAL:4::1_4:2203 with 100000000
+DEAL:4::1_4:2210 with 100000000
+DEAL:4::1_4:2212 with 100000000
+DEAL:4::1_4:2213 with 100000000
+DEAL:4::1_4:2220 with 100000000
+DEAL:4::1_4:2221 with 100000000
+DEAL:4::1_5:22221 with 100000000
+DEAL:4::1_3:300 with 100000000
+DEAL:4::1_3:301 with 100000000
+DEAL:4::2_2:00 with 100000000
+DEAL:4::2_2:03 with 100000000
+DEAL:4::2_3:121 with 100000000
+DEAL:4::1_4:2200 with 100000000
+DEAL:4::1_4:2201 with 100000000
+DEAL:4::1_4:2202 with 100000000
+DEAL:4::1_4:2211 with 100000000
+DEAL:4::1_5:22220 with 100000000
+DEAL:4::1_5:22222 with 100000000
+DEAL:4::1_3:230 with 100000000
+DEAL:4::1_3:231 with 100000000
+DEAL:4::1_3:302 with 100000000
+DEAL:4::1_3:310 with 100000000
+DEAL:4::1_3:311 with 100000000
+DEAL:4::1_3:313 with 100000000
+DEAL:4::1_2:33 with 100000000
+DEAL:4::2_2:02 with 100000000
+DEAL:4::2_3:122 with 100000000
+DEAL:4::2_3:123 with 100000000
+DEAL:4::1_5:22223 with 100000000
+DEAL:4::1_4:2223 with 100000000
+DEAL:4::1_3:223 with 100000000
+DEAL:4::1_3:232 with 100000000
+DEAL:4::1_4:2330 with 100000000
+DEAL:4::1_4:2331 with 100000000
+DEAL:4::1_4:2332 with 100000000
+DEAL:4::1_4:2333 with 100000000
+DEAL:4::1_3:303 with 100000000
+DEAL:4::1_3:312 with 100000000
+DEAL:4::1_3:320 with 100000000
+DEAL:4::1_3:321 with 100000000
+DEAL:4::1_3:322 with 100000000
+DEAL:4::1_3:323 with 100000000
+DEAL:4::2_2:01 with 100000000
+DEAL:4::2_2:10 with 100000000
+DEAL:4::2_2:11 with 100000000
+DEAL:4::2_3:120 with 100000000
+DEAL:4::
+DEAL:4::Number of cell batches: 6
+DEAL:4::1_2:62 with 8
+DEAL:4::1_1:3 with 8
+DEAL:4::1_2:60 with 8
+DEAL:4::1_1:1 with 8
+DEAL:4::0_3:770 with 8
+DEAL:4::0_3:771 with 8
+DEAL:4::0_3:774 with 8
+DEAL:4::0_3:775 with 8
+DEAL:4::1_2:63 with 8
+DEAL:4::1_2:65 with 8
+DEAL:4::1_2:61 with 8
+DEAL:4::1_1:5 with 8
+DEAL:4::0_3:772 with 9
+DEAL:4::0_3:773 with 9
+DEAL:4::0_3:776 with 9
+DEAL:4::1_2:67 with 9
+DEAL:4::1_1:0 with 2
+DEAL:4::1_1:4 with 2
+DEAL:4::0_3:777 with 9
+DEAL:4::1_2:66 with 9
+DEAL:4::1_1:2 with 9
+DEAL:4::1_2:64 with 9
+DEAL:4::
+DEAL:4::Number of cell batches: 14
+DEAL:4::1_1:1 with 2
+DEAL:4::1_2:60 with 6
+DEAL:4::1_1:3 with 7
+DEAL:4::1_2:62 with 8
+DEAL:4::1_1:5 with 2
+DEAL:4::1_2:61 with 6
+DEAL:4::1_2:65 with 6
+DEAL:4::0_3:770 with 8
+DEAL:4::0_3:771 with 8
+DEAL:4::0_3:774 with 8
+DEAL:4::0_3:775 with 8
+DEAL:4::1_2:63 with 8
+DEAL:4::1_2:67 with 8
+DEAL:4::0_3:772 with 9
+DEAL:4::0_3:773 with 9
+DEAL:4::0_3:776 with 9
+DEAL:4::1_1:0 with 2
+DEAL:4::1_1:4 with 2
+DEAL:4::1_2:64 with 6
+DEAL:4::1_1:2 with 7
+DEAL:4::1_2:66 with 8
+DEAL:4::0_3:777 with 9
+DEAL:4::
+DEAL:4::Number of cell batches: 6
+DEAL:4::1_1:1 with 100000000
+DEAL:4::1_1:3 with 100000000
+DEAL:4::1_2:60 with 100000000
+DEAL:4::1_2:62 with 100000000
+DEAL:4::0_3:770 with 100000000
+DEAL:4::0_3:771 with 100000000
+DEAL:4::0_3:772 with 100000000
+DEAL:4::0_3:773 with 100000000
+DEAL:4::0_3:774 with 100000000
+DEAL:4::0_3:775 with 100000000
+DEAL:4::0_3:776 with 100000000
+DEAL:4::1_1:5 with 100000000
+DEAL:4::1_2:61 with 100000000
+DEAL:4::1_2:63 with 100000000
+DEAL:4::1_2:65 with 100000000
+DEAL:4::1_2:67 with 100000000
+DEAL:4::0_3:777 with 100000000
+DEAL:4::1_1:0 with 100000000
+DEAL:4::1_1:2 with 100000000
+DEAL:4::1_1:4 with 100000000
+DEAL:4::1_2:64 with 100000000
+DEAL:4::1_2:66 with 100000000
+DEAL:4::
+
+
+DEAL:5::Number of cell batches: 12
+DEAL:5::2_3:230 with 11
+DEAL:5::3_3:003 with 11
+DEAL:5::3_3:001 with 11
+DEAL:5::2_2:22 with 11
+DEAL:5::2_3:233 with 13
+DEAL:5::2_2:30 with 13
+DEAL:5::2_3:232 with 13
+DEAL:5::2_3:231 with 13
+DEAL:5::2_3:311 with 15
+DEAL:5::2_3:312 with 15
+DEAL:5::3_3:133 with 15
+DEAL:5::2_3:310 with 15
+DEAL:5::2_3:332 with 17
+DEAL:5::2_3:330 with 17
+DEAL:5::2_3:313 with 17
+DEAL:5::2_2:32 with 17
+DEAL:5::2_2:21 with 10
+DEAL:5::3_3:000 with 10
+DEAL:5::3_3:111 with 10
+DEAL:5::2_2:20 with 10
+DEAL:5::2_3:131 with 12
+DEAL:5::3_3:113 with 12
+DEAL:5::3_3:002 with 12
+DEAL:5::2_3:130 with 12
+DEAL:5::3_3:122 with 14
+DEAL:5::3_3:123 with 14
+DEAL:5::2_3:133 with 14
+DEAL:5::2_3:132 with 14
+DEAL:5::2_3:333 with 18
+DEAL:5::2_3:331 with 18
+DEAL:5::3_2:20 with 18
+DEAL:5::3_3:132 with 18
+DEAL:5::3_2:01 with 11
+DEAL:5::3_3:110 with 11
+DEAL:5::3_3:101 with 11
+DEAL:5::3_3:100 with 11
+DEAL:5::3_4:1300 with 12
+DEAL:5::3_3:112 with 12
+DEAL:5::3_3:103 with 12
+DEAL:5::3_3:102 with 12
+DEAL:5::3_2:02 with 13
+DEAL:5::3_2:03 with 13
+DEAL:5::3_3:120 with 13
+DEAL:5::3_3:121 with 13
+DEAL:5::3_4:1302 with 13
+DEAL:5::3_4:1303 with 13
+DEAL:5::3_3:131 with 13
+DEAL:5::3_4:1301 with 13
+DEAL:5::
+DEAL:5::Number of cell batches: 22
+DEAL:5::2_2:22 with 10
+DEAL:5::3_3:001 with 10
+DEAL:5::2_3:230 with 11
+DEAL:5::3_3:003 with 11
+DEAL:5::2_3:231 with 12
+DEAL:5::2_3:232 with 12
+DEAL:5::2_2:30 with 12
+DEAL:5::2_3:233 with 13
+DEAL:5::2_3:310 with 13
+DEAL:5::3_3:133 with 14
+DEAL:5::2_3:311 with 15
+DEAL:5::2_3:312 with 15
+DEAL:5::2_2:32 with 15
+DEAL:5::2_3:313 with 16
+DEAL:5::2_3:330 with 16
+DEAL:5::2_3:332 with 17
+DEAL:5::2_2:20 with 7
+DEAL:5::2_2:21 with 10
+DEAL:5::3_3:000 with 10
+DEAL:5::3_3:111 with 10
+DEAL:5::2_3:130 with 11
+DEAL:5::3_3:002 with 11
+DEAL:5::3_3:113 with 11
+DEAL:5::2_3:131 with 12
+DEAL:5::2_3:132 with 12
+DEAL:5::2_3:133 with 13
+DEAL:5::3_3:122 with 14
+DEAL:5::3_3:123 with 14
+DEAL:5::3_3:132 with 14
+DEAL:5::3_2:20 with 16
+DEAL:5::2_3:331 with 17
+DEAL:5::2_3:333 with 18
+DEAL:5::3_3:100 with 10
+DEAL:5::3_3:101 with 10
+DEAL:5::3_3:110 with 10
+DEAL:5::3_2:01 with 11
+DEAL:5::3_3:102 with 11
+DEAL:5::3_3:103 with 11
+DEAL:5::3_3:112 with 11
+DEAL:5::3_4:1300 with 12
+DEAL:5::3_4:1301 with 12
+DEAL:5::3_2:02 with 13
+DEAL:5::3_2:03 with 13
+DEAL:5::3_3:120 with 13
+DEAL:5::3_3:121 with 13
+DEAL:5::3_4:1302 with 13
+DEAL:5::3_4:1303 with 13
+DEAL:5::3_3:131 with 13
+DEAL:5::
+DEAL:5::Number of cell batches: 12
+DEAL:5::2_2:22 with 100000000
+DEAL:5::2_3:230 with 100000000
+DEAL:5::2_3:231 with 100000000
+DEAL:5::2_3:232 with 100000000
+DEAL:5::2_3:233 with 100000000
+DEAL:5::2_2:30 with 100000000
+DEAL:5::2_3:310 with 100000000
+DEAL:5::2_3:311 with 100000000
+DEAL:5::2_3:312 with 100000000
+DEAL:5::2_3:313 with 100000000
+DEAL:5::2_2:32 with 100000000
+DEAL:5::2_3:330 with 100000000
+DEAL:5::2_3:332 with 100000000
+DEAL:5::3_3:001 with 100000000
+DEAL:5::3_3:003 with 100000000
+DEAL:5::3_3:133 with 100000000
+DEAL:5::2_3:130 with 100000000
+DEAL:5::2_3:131 with 100000000
+DEAL:5::2_3:132 with 100000000
+DEAL:5::2_3:133 with 100000000
+DEAL:5::2_2:20 with 100000000
+DEAL:5::2_2:21 with 100000000
+DEAL:5::2_3:331 with 100000000
+DEAL:5::2_3:333 with 100000000
+DEAL:5::3_3:000 with 100000000
+DEAL:5::3_3:002 with 100000000
+DEAL:5::3_3:111 with 100000000
+DEAL:5::3_3:113 with 100000000
+DEAL:5::3_3:122 with 100000000
+DEAL:5::3_3:123 with 100000000
+DEAL:5::3_3:132 with 100000000
+DEAL:5::3_2:20 with 100000000
+DEAL:5::3_2:01 with 100000000
+DEAL:5::3_2:02 with 100000000
+DEAL:5::3_2:03 with 100000000
+DEAL:5::3_3:100 with 100000000
+DEAL:5::3_3:101 with 100000000
+DEAL:5::3_3:102 with 100000000
+DEAL:5::3_3:103 with 100000000
+DEAL:5::3_3:110 with 100000000
+DEAL:5::3_3:112 with 100000000
+DEAL:5::3_3:120 with 100000000
+DEAL:5::3_3:121 with 100000000
+DEAL:5::3_4:1300 with 100000000
+DEAL:5::3_4:1301 with 100000000
+DEAL:5::3_4:1302 with 100000000
+DEAL:5::3_4:1303 with 100000000
+DEAL:5::3_3:131 with 100000000
+DEAL:5::
+DEAL:5::Number of cell batches: 5
+DEAL:5::3_1:7 with 17
+DEAL:5::3_1:5 with 17
+DEAL:5::2_1:6 with 17
+DEAL:5::2_1:5 with 17
+DEAL:5::2_1:1 with 10
+DEAL:5::1_1:7 with 10
+DEAL:5::2_1:4 with 10
+DEAL:5::2_1:0 with 10
+DEAL:5::3_1:3 with 17
+DEAL:5::2_1:3 with 17
+DEAL:5::3_1:1 with 17
+DEAL:5::2_1:2 with 17
+DEAL:5::3_1:0 with 12
+DEAL:5::3_1:2 with 17
+DEAL:5::3_1:6 with 17
+DEAL:5::2_1:7 with 17
+DEAL:5::3_1:4 with 17
+DEAL:5::
+DEAL:5::Number of cell batches: 12
+DEAL:5::2_1:5 with 10
+DEAL:5::2_1:6 with 10
+DEAL:5::3_1:5 with 12
+DEAL:5::3_1:7 with 17
+DEAL:5::2_1:0 with 5
+DEAL:5::2_1:4 with 5
+DEAL:5::1_1:7 with 7
+DEAL:5::2_1:1 with 10
+DEAL:5::2_1:2 with 10
+DEAL:5::3_1:1 with 12
+DEAL:5::2_1:3 with 15
+DEAL:5::3_1:3 with 17
+DEAL:5::3_1:0 with 12
+DEAL:5::3_1:4 with 12
+DEAL:5::2_1:7 with 15
+DEAL:5::3_1:2 with 17
+DEAL:5::3_1:6 with 17
+DEAL:5::
+DEAL:5::Number of cell batches: 5
+DEAL:5::2_1:5 with 100000000
+DEAL:5::2_1:6 with 100000000
+DEAL:5::3_1:5 with 100000000
+DEAL:5::3_1:7 with 100000000
+DEAL:5::1_1:7 with 100000000
+DEAL:5::2_1:0 with 100000000
+DEAL:5::2_1:1 with 100000000
+DEAL:5::2_1:2 with 100000000
+DEAL:5::2_1:3 with 100000000
+DEAL:5::2_1:4 with 100000000
+DEAL:5::3_1:1 with 100000000
+DEAL:5::3_1:3 with 100000000
+DEAL:5::2_1:7 with 100000000
+DEAL:5::3_1:0 with 100000000
+DEAL:5::3_1:2 with 100000000
+DEAL:5::3_1:4 with 100000000
+DEAL:5::3_1:6 with 100000000
+DEAL:5::
+
+
+DEAL:6::Number of cell batches: 12
+DEAL:6::4_3:002 with 12
+DEAL:6::4_3:003 with 12
+DEAL:6::4_3:001 with 12
+DEAL:6::4_3:000 with 12
+DEAL:6::4_4:0203 with 14
+DEAL:6::4_3:021 with 14
+DEAL:6::4_4:0201 with 14
+DEAL:6::4_2:01 with 14
+DEAL:6::3_3:213 with 16
+DEAL:6::3_2:30 with 16
+DEAL:6::3_3:312 with 16
+DEAL:6::3_3:313 with 16
+DEAL:6::3_2:22 with 18
+DEAL:6::3_2:23 with 18
+DEAL:6::3_2:32 with 18
+DEAL:6::3_2:33 with 18
+DEAL:6::3_3:210 with 15
+DEAL:6::4_3:022 with 15
+DEAL:6::4_4:0202 with 15
+DEAL:6::4_4:0200 with 15
+DEAL:6::3_3:212 with 16
+DEAL:6::3_3:311 with 16
+DEAL:6::3_3:310 with 16
+DEAL:6::3_3:211 with 16
+DEAL:6::4_3:023 with 15
+DEAL:6::4_3:030 with 15
+DEAL:6::4_2:10 with 15
+DEAL:6::4_3:032 with 16
+DEAL:6::4_3:120 with 16
+DEAL:6::4_2:11 with 16
+DEAL:6::4_3:031 with 16
+DEAL:6::4_3:122 with 18
+DEAL:6::4_2:20 with 18
+DEAL:6::4_3:121 with 18
+DEAL:6::4_3:033 with 18
+DEAL:6::4_2:22 with 20
+DEAL:6::4_2:21 with 20
+DEAL:6::4_2:13 with 20
+DEAL:6::4_3:123 with 20
+DEAL:6::4_3:231 with 22
+DEAL:6::4_3:232 with 22
+DEAL:6::4_2:30 with 22
+DEAL:6::4_3:230 with 22
+DEAL:6::4_2:33 with 27
+DEAL:6::4_2:32 with 27
+DEAL:6::4_3:233 with 27
+DEAL:6::4_2:31 with 27
+DEAL:6::
+DEAL:6::Number of cell batches: 24
+DEAL:6::4_3:000 with 10
+DEAL:6::4_3:001 with 11
+DEAL:6::4_3:002 with 12
+DEAL:6::4_3:003 with 12
+DEAL:6::4_2:01 with 13
+DEAL:6::4_4:0201 with 13
+DEAL:6::4_4:0203 with 14
+DEAL:6::4_3:021 with 14
+DEAL:6::3_3:213 with 16
+DEAL:6::3_2:30 with 16
+DEAL:6::3_3:312 with 16
+DEAL:6::3_3:313 with 16
+DEAL:6::3_2:22 with 18
+DEAL:6::3_2:23 with 18
+DEAL:6::3_2:32 with 18
+DEAL:6::3_2:33 with 18
+DEAL:6::4_4:0200 with 13
+DEAL:6::4_4:0202 with 13
+DEAL:6::4_3:022 with 14
+DEAL:6::3_3:210 with 15
+DEAL:6::3_3:211 with 15
+DEAL:6::3_3:310 with 15
+DEAL:6::3_3:311 with 15
+DEAL:6::3_3:212 with 16
+DEAL:6::4_2:10 with 14
+DEAL:6::4_3:023 with 15
+DEAL:6::4_3:030 with 15
+DEAL:6::4_3:031 with 15
+DEAL:6::4_2:11 with 15
+DEAL:6::4_3:032 with 16
+DEAL:6::4_3:120 with 16
+DEAL:6::4_3:033 with 17
+DEAL:6::4_3:121 with 17
+DEAL:6::4_2:20 with 17
+DEAL:6::4_3:122 with 18
+DEAL:6::4_3:123 with 19
+DEAL:6::4_2:13 with 19
+DEAL:6::4_2:21 with 19
+DEAL:6::4_2:22 with 20
+DEAL:6::4_3:230 with 21
+DEAL:6::4_2:30 with 21
+DEAL:6::4_3:231 with 22
+DEAL:6::4_3:232 with 22
+DEAL:6::4_2:31 with 23
+DEAL:6::4_3:233 with 24
+DEAL:6::4_2:32 with 25
+DEAL:6::4_2:33 with 27
+DEAL:6::
+DEAL:6::Number of cell batches: 12
+DEAL:6::3_3:213 with 100000000
+DEAL:6::3_2:22 with 100000000
+DEAL:6::3_2:23 with 100000000
+DEAL:6::3_2:30 with 100000000
+DEAL:6::3_3:312 with 100000000
+DEAL:6::3_3:313 with 100000000
+DEAL:6::3_2:32 with 100000000
+DEAL:6::3_2:33 with 100000000
+DEAL:6::4_3:000 with 100000000
+DEAL:6::4_3:001 with 100000000
+DEAL:6::4_3:002 with 100000000
+DEAL:6::4_3:003 with 100000000
+DEAL:6::4_2:01 with 100000000
+DEAL:6::4_4:0201 with 100000000
+DEAL:6::4_4:0203 with 100000000
+DEAL:6::4_3:021 with 100000000
+DEAL:6::3_3:210 with 100000000
+DEAL:6::3_3:211 with 100000000
+DEAL:6::3_3:212 with 100000000
+DEAL:6::3_3:310 with 100000000
+DEAL:6::3_3:311 with 100000000
+DEAL:6::4_4:0200 with 100000000
+DEAL:6::4_4:0202 with 100000000
+DEAL:6::4_3:022 with 100000000
+DEAL:6::4_3:023 with 100000000
+DEAL:6::4_3:030 with 100000000
+DEAL:6::4_3:031 with 100000000
+DEAL:6::4_3:032 with 100000000
+DEAL:6::4_3:033 with 100000000
+DEAL:6::4_2:10 with 100000000
+DEAL:6::4_2:11 with 100000000
+DEAL:6::4_3:120 with 100000000
+DEAL:6::4_3:121 with 100000000
+DEAL:6::4_3:122 with 100000000
+DEAL:6::4_3:123 with 100000000
+DEAL:6::4_2:13 with 100000000
+DEAL:6::4_2:20 with 100000000
+DEAL:6::4_2:21 with 100000000
+DEAL:6::4_2:22 with 100000000
+DEAL:6::4_3:230 with 100000000
+DEAL:6::4_3:231 with 100000000
+DEAL:6::4_3:232 with 100000000
+DEAL:6::4_3:233 with 100000000
+DEAL:6::4_2:30 with 100000000
+DEAL:6::4_2:31 with 100000000
+DEAL:6::4_2:32 with 100000000
+DEAL:6::4_2:33 with 100000000
+DEAL:6::
+DEAL:6::Number of cell batches: 4
+DEAL:6::4_2:70 with 23
+DEAL:6::4_1:5 with 23
+DEAL:6::4_1:1 with 23
+DEAL:6::4_1:0 with 23
+DEAL:6::4_1:3 with 25
+DEAL:6::4_1:6 with 25
+DEAL:6::4_1:2 with 25
+DEAL:6::4_1:4 with 25
+DEAL:6::4_2:72 with 27
+DEAL:6::4_2:71 with 27
+DEAL:6::4_2:74 with 27
+DEAL:6::4_2:77 with 32
+DEAL:6::4_2:73 with 32
+DEAL:6::4_2:76 with 32
+DEAL:6::4_2:75 with 32
+DEAL:6::
+DEAL:6::Number of cell batches: 13
+DEAL:6::4_1:0 with 14
+DEAL:6::4_1:1 with 17
+DEAL:6::4_1:5 with 18
+DEAL:6::4_2:70 with 23
+DEAL:6::4_1:4 with 14
+DEAL:6::4_1:2 with 20
+DEAL:6::4_1:6 with 20
+DEAL:6::4_1:3 with 25
+DEAL:6::4_2:74 with 24
+DEAL:6::4_2:71 with 26
+DEAL:6::4_2:72 with 27
+DEAL:6::4_2:75 with 27
+DEAL:6::4_2:76 with 28
+DEAL:6::4_2:73 with 31
+DEAL:6::4_2:77 with 32
+DEAL:6::
+DEAL:6::Number of cell batches: 4
+DEAL:6::4_1:0 with 100000000
+DEAL:6::4_1:1 with 100000000
+DEAL:6::4_1:5 with 100000000
+DEAL:6::4_2:70 with 100000000
+DEAL:6::4_1:2 with 100000000
+DEAL:6::4_1:3 with 100000000
+DEAL:6::4_1:4 with 100000000
+DEAL:6::4_1:6 with 100000000
+DEAL:6::4_2:71 with 100000000
+DEAL:6::4_2:72 with 100000000
+DEAL:6::4_2:73 with 100000000
+DEAL:6::4_2:74 with 100000000
+DEAL:6::4_2:75 with 100000000
+DEAL:6::4_2:76 with 100000000
+DEAL:6::4_2:77 with 100000000
+DEAL:6::
+
diff --git a/tests/matrix_free/compare_faces_by_cells.cc b/tests/matrix_free/compare_faces_by_cells.cc
new file mode 100644 (file)
index 0000000..5e22402
--- /dev/null
@@ -0,0 +1,357 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// compares the computation of the diagonal using a face integration
+// facilities with the alternative reinit(cell_index, face_number) approach
+
+#include "../tests.h"
+
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/mapping_q_generic.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+
+#include "create_mesh.h"
+
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double>
+class LaplaceOperator : public Subscriptor
+{
+public:
+  typedef number value_type;
+
+  LaplaceOperator() {};
+
+  void initialize (const Mapping<dim> &mapping,
+                   const DoFHandler<dim> &dof_handler,
+                   const unsigned int level = numbers::invalid_unsigned_int)
+  {
+    const QGauss<1> quad (n_q_points_1d);
+    typename MatrixFree<dim,number>::AdditionalData addit_data;
+    addit_data.tasks_parallel_scheme = MatrixFree<dim,number>::AdditionalData::none;
+    addit_data.tasks_block_size = 3;
+    addit_data.level_mg_handler = level;
+    addit_data.mapping_update_flags_inner_faces = update_JxW_values | update_normal_vectors | update_jacobians;
+    addit_data.mapping_update_flags_boundary_faces = update_JxW_values | update_normal_vectors | update_jacobians;
+    addit_data.mapping_update_flags_faces_by_cells = update_JxW_values | update_normal_vectors | update_jacobians;
+    ConstraintMatrix constraints;
+    constraints.close();
+
+    data.reinit (mapping, dof_handler, constraints, quad, addit_data);
+  }
+
+  void compute_diagonal_by_face(parallel::distributed::Vector<number> &result) const
+  {
+    int dummy;
+    result = 0;
+    data.loop (&LaplaceOperator::local_diagonal_dummy,
+               &LaplaceOperator::local_diagonal_face,
+               &LaplaceOperator::local_diagonal_boundary,
+               this, result, dummy);
+
+  }
+
+  void compute_diagonal_by_cell(parallel::distributed::Vector<number> &result) const
+  {
+    int dummy;
+    result.zero_out_ghosts();
+    data.cell_loop (&LaplaceOperator::local_diagonal_by_cell,
+                    this, result, dummy);
+  }
+
+  void
+  initialize_dof_vector(parallel::distributed::Vector<number> &vector) const
+  {
+    data.initialize_dof_vector(vector);
+  }
+
+
+private:
+  void
+  local_diagonal_dummy (const MatrixFree<dim,number> &,
+                        parallel::distributed::Vector<number> &,
+                        const int &,
+                        const std::pair<unsigned int,unsigned int> &) const
+  {
+  }
+
+  void
+  local_diagonal_face (const MatrixFree<dim,number>                &data,
+                       parallel::distributed::Vector<number>       &dst,
+                       const int &,
+                       const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi_outer(data,false);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi.reinit (face);
+        phi_outer.reinit (face);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+
+        // Choose a one-sided definition of sigmaF rather than the actual
+        // penalty parameter because the cell-based method cannot read the
+        // sigma parameter on the neighbor
+        VectorizedArray<number> sigmaF =
+          std::abs((phi.get_normal_vector(0)*phi.inverse_jacobian(0))[dim-1]) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0)) * 2.0;
+
+        // Compute phi part
+        for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+          phi_outer.begin_dof_values()[j] = VectorizedArray<number>();
+        phi_outer.evaluate(true, true);
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = (phi.get_value(q)-
+                                                         phi_outer.get_value(q)) * 0.5;
+                VectorizedArray<number> average_valgrad =
+                  phi.get_normal_derivative(q) +
+                  phi_outer.get_normal_derivative(q);
+                average_valgrad = average_value * 2. * sigmaF -
+                                  average_valgrad * 0.5;
+                phi.submit_normal_derivative(-average_value,q);
+                phi.submit_value(average_valgrad,q);
+              }
+            phi.integrate(true,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global(dst);
+
+        // Compute phi_outer part
+        sigmaF =
+          std::abs((phi.get_normal_vector(0)*phi_outer.inverse_jacobian(0))[dim-1]) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0)) * 2.0;
+        for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+          phi.begin_dof_values()[j] = VectorizedArray<number>();
+        phi.evaluate(true, true);
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi_outer.begin_dof_values()[j] = VectorizedArray<number>();
+            phi_outer.begin_dof_values()[i] = 1.;
+            phi_outer.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = (phi.get_value(q)-
+                                                         phi_outer.get_value(q)) * 0.5;
+                VectorizedArray<number> average_valgrad =
+                  phi.get_normal_derivative(q) +
+                  phi_outer.get_normal_derivative(q);
+                average_valgrad = average_value * 2. * sigmaF -
+                                  average_valgrad * 0.5;
+                phi_outer.submit_normal_derivative(-average_value,q);
+                phi_outer.submit_value(-average_valgrad,q);
+              }
+            phi_outer.integrate(true,true);
+            local_diagonal_vector[i] = phi_outer.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi_outer.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi_outer.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_diagonal_boundary (const MatrixFree<dim,number>                &data,
+                           parallel::distributed::Vector<number>       &dst,
+                           const int &,
+                           const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi.reinit (face);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        VectorizedArray<number> sigmaF =
+          std::abs((phi.get_normal_vector(0)*phi.inverse_jacobian(0))[dim-1]) *
+          (number)(std::max(1,fe_degree) * (fe_degree + 1.0)) * 2.;
+
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = phi.get_value(q);
+                VectorizedArray<number> average_valgrad = -phi.get_normal_derivative(q);
+                average_valgrad += average_value * sigmaF * 2.0;
+                phi.submit_normal_derivative(-average_value,q);
+                phi.submit_value(average_valgrad,q);
+              }
+            phi.integrate(true,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_diagonal_by_cell (const MatrixFree<dim,number>                &data,
+                          parallel::distributed::Vector<number>       &dst,
+                          const int &,
+                          const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phif (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        VectorizedArray<number> local_diagonal_vector[phif.static_dofs_per_cell];
+        for (unsigned int i=0; i<phif.static_dofs_per_cell; ++i)
+          local_diagonal_vector[i] = 0.;
+        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+          {
+            phif.reinit(cell, face);
+            VectorizedArray<number> sigmaF =
+              std::abs((phif.get_normal_vector(0)*phif.inverse_jacobian(0))[dim-1]) *
+              (number)(std::max(1,fe_degree) * (fe_degree + 1.0)) * 2.;
+
+            std::array<types::boundary_id,VectorizedArray<number>::n_array_elements>
+            boundary_ids = data.get_faces_by_cells_boundary_id(cell, face);
+            VectorizedArray<number> factor_boundary;
+            for (unsigned int v=0; v<VectorizedArray<number>::n_array_elements; ++v)
+              // interior face
+              if (boundary_ids[v] == numbers::invalid_boundary_id)
+                factor_boundary[v] = 0.5;
+            // Dirichlet boundary
+              else
+                factor_boundary[v] = 1.0;
+            for (unsigned int i=0; i<phif.dofs_per_cell; ++i)
+              {
+                for (unsigned int j=0; j<phif.dofs_per_cell; ++j)
+                  phif.begin_dof_values()[j] = VectorizedArray<number>();
+                phif.begin_dof_values()[i] = 1.;
+                phif.evaluate(true,true);
+                for (unsigned int q=0; q<phif.n_q_points; ++q)
+                  {
+                    VectorizedArray<number> average_value = phif.get_value(q) * factor_boundary;
+                    VectorizedArray<number> average_valgrad =
+                      phif.get_normal_derivative(q) * factor_boundary;
+                    average_valgrad = average_value * 2. * sigmaF -
+                                      average_valgrad;
+                    phif.submit_normal_derivative(-average_value,q);
+                    phif.submit_value(average_valgrad,q);
+                  }
+                phif.integrate(true,true);
+                local_diagonal_vector[i] += phif.begin_dof_values()[i];
+              }
+          }
+        for (unsigned int i=0; i<phif.static_dofs_per_cell; ++i)
+          phif.begin_dof_values()[i] = local_diagonal_vector[i];
+        phif.set_dof_values (dst);
+      }
+  }
+
+  MatrixFree<dim,number> data;
+};
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d, typename number>
+void test ()
+{
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD,
+                                                 dealii::Triangulation<dim>::none,parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy);
+  create_mesh(tria);
+  tria.refine_global(std::max(8-fe_degree-2*dim,1));
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  dof.distribute_mg_dofs(fe);
+  deallog << "Number of DoFs: " << dof.n_dofs() << std::endl;
+
+  MappingQGeneric<dim> mapping(fe_degree+1);
+  LaplaceOperator<dim,fe_degree,n_q_points_1d,number> fine_matrix;
+  fine_matrix.initialize(mapping, dof);
+
+  parallel::distributed::Vector<number> res1, res2;
+  fine_matrix.initialize_dof_vector(res1);
+  fine_matrix.initialize_dof_vector(res2);
+
+  fine_matrix.compute_diagonal_by_face(res1);
+  fine_matrix.compute_diagonal_by_cell(res2);
+  res2 -= res1;
+  deallog << "Error in diagonal on active cells: "
+          << (double)res2.linfty_norm() << std::endl;
+
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    {
+      LaplaceOperator<dim,fe_degree,n_q_points_1d,number> fine_matrix;
+      fine_matrix.initialize(mapping, dof, level);
+
+      parallel::distributed::Vector<number> res1, res2;
+      fine_matrix.initialize_dof_vector(res1);
+      fine_matrix.initialize_dof_vector(res2);
+
+      fine_matrix.compute_diagonal_by_face(res1);
+      fine_matrix.compute_diagonal_by_cell(res2);
+      res2 -= res1;
+      deallog << "Error in diagonal on level " << level << ":      "
+              << (double)res2.linfty_norm() << std::endl;
+    }
+}
+
+
+
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv);
+  mpi_initlog();
+
+  {
+    deallog.push("2d");
+    test<2,1,2,double>();
+    test<2,2,3,double>();
+    test<2,1,2,float>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1,2,double>();
+    test<3,2,3,double>();
+    test<3,1,2,float>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/compare_faces_by_cells.with_mpi=true.mpirun=1.output b/tests/matrix_free/compare_faces_by_cells.with_mpi=true.mpirun=1.output
new file mode 100755 (executable)
index 0000000..2428bdb
--- /dev/null
@@ -0,0 +1,30 @@
+
+DEAL:2d::Number of DoFs: 1280
+DEAL:2d::Error in diagonal on active cells: 0
+DEAL:2d::Error in diagonal on level 0:      0
+DEAL:2d::Error in diagonal on level 1:      0
+DEAL:2d::Error in diagonal on level 2:      0
+DEAL:2d::Error in diagonal on level 3:      0
+DEAL:2d::Number of DoFs: 720
+DEAL:2d::Error in diagonal on active cells: 0
+DEAL:2d::Error in diagonal on level 0:      0
+DEAL:2d::Error in diagonal on level 1:      0
+DEAL:2d::Error in diagonal on level 2:      0
+DEAL:2d::Number of DoFs: 1280
+DEAL:2d::Error in diagonal on active cells: 0
+DEAL:2d::Error in diagonal on level 0:      0
+DEAL:2d::Error in diagonal on level 1:      0
+DEAL:2d::Error in diagonal on level 2:      0
+DEAL:2d::Error in diagonal on level 3:      0
+DEAL:3d::Number of DoFs: 320
+DEAL:3d::Error in diagonal on active cells: 0
+DEAL:3d::Error in diagonal on level 0:      0
+DEAL:3d::Error in diagonal on level 1:      0
+DEAL:3d::Number of DoFs: 1080
+DEAL:3d::Error in diagonal on active cells: 0
+DEAL:3d::Error in diagonal on level 0:      0
+DEAL:3d::Error in diagonal on level 1:      0
+DEAL:3d::Number of DoFs: 320
+DEAL:3d::Error in diagonal on active cells: 0
+DEAL:3d::Error in diagonal on level 0:      0
+DEAL:3d::Error in diagonal on level 1:      0
diff --git a/tests/matrix_free/compare_faces_by_cells.with_mpi=true.mpirun=5.output b/tests/matrix_free/compare_faces_by_cells.with_mpi=true.mpirun=5.output
new file mode 100755 (executable)
index 0000000..2428bdb
--- /dev/null
@@ -0,0 +1,30 @@
+
+DEAL:2d::Number of DoFs: 1280
+DEAL:2d::Error in diagonal on active cells: 0
+DEAL:2d::Error in diagonal on level 0:      0
+DEAL:2d::Error in diagonal on level 1:      0
+DEAL:2d::Error in diagonal on level 2:      0
+DEAL:2d::Error in diagonal on level 3:      0
+DEAL:2d::Number of DoFs: 720
+DEAL:2d::Error in diagonal on active cells: 0
+DEAL:2d::Error in diagonal on level 0:      0
+DEAL:2d::Error in diagonal on level 1:      0
+DEAL:2d::Error in diagonal on level 2:      0
+DEAL:2d::Number of DoFs: 1280
+DEAL:2d::Error in diagonal on active cells: 0
+DEAL:2d::Error in diagonal on level 0:      0
+DEAL:2d::Error in diagonal on level 1:      0
+DEAL:2d::Error in diagonal on level 2:      0
+DEAL:2d::Error in diagonal on level 3:      0
+DEAL:3d::Number of DoFs: 320
+DEAL:3d::Error in diagonal on active cells: 0
+DEAL:3d::Error in diagonal on level 0:      0
+DEAL:3d::Error in diagonal on level 1:      0
+DEAL:3d::Number of DoFs: 1080
+DEAL:3d::Error in diagonal on active cells: 0
+DEAL:3d::Error in diagonal on level 0:      0
+DEAL:3d::Error in diagonal on level 1:      0
+DEAL:3d::Number of DoFs: 320
+DEAL:3d::Error in diagonal on active cells: 0
+DEAL:3d::Error in diagonal on level 0:      0
+DEAL:3d::Error in diagonal on level 1:      0
diff --git a/tests/matrix_free/dg_pbc_01.cc b/tests/matrix_free/dg_pbc_01.cc
new file mode 100644 (file)
index 0000000..a9ef20b
--- /dev/null
@@ -0,0 +1,108 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests that the matrix-free implementation works correctly with periodic
+// boundary conditions by solving a simple linear system and outputting the
+// solution for FE_DGQ(0)
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/distributed/tria.h>
+#include <deal.II/lac/solver_cg.h>
+#include <deal.II/lac/precondition.h>
+
+std::ofstream logfile("output");
+
+
+// We want to use the matrix-vector product provided by this function (which
+// also includes a main function)
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  if (fe_degree > 1)
+    return;
+
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria, 0, 1);
+
+  // set boundary ids on boundaries to the number of the face
+  for (unsigned int face=2; face<GeometryInfo<dim>::faces_per_cell; ++face)
+    tria.begin()->face(face)->set_all_boundary_ids(face);
+
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> >
+  periodic_faces;
+  for (unsigned int d=1; d<dim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  deallog << "Periodic faces: " << periodic_faces.size() << std::endl;
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(8-2*dim);
+
+  FE_DGQ<dim> fe (0);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  MappingQ<dim> mapping(fe_degree+1);
+
+  const QGauss<1> quad (1);
+  typename MatrixFree<dim>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim>::AdditionalData::none;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  MatrixFree<dim> mf_data;
+  mf_data.reinit(dof, constraints, quad, data);
+
+  LinearAlgebra::distributed::Vector<double> rhs, sol;
+  mf_data.initialize_dof_vector(rhs);
+  rhs = 1.;
+  mf_data.initialize_dof_vector(sol);
+
+  MatrixFreeTest<dim,0,1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+
+  SolverControl control(1000, 1e-12*std::sqrt(rhs.size()));
+  SolverCG<LinearAlgebra::distributed::Vector<double> > solver(control);
+  solver.solve(mf, sol, rhs, PreconditionIdentity());
+  // gather all data at root
+  if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0)
+    {
+      Vector<double> solution_gather0(sol.size());
+      double *sol_gather_ptr = solution_gather0.begin();
+      for (unsigned int i=0; i<sol.local_size(); ++i)
+        *sol_gather_ptr++ = sol.local_element(i);
+      for (unsigned int i=1; i<Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD); ++i)
+        {
+          MPI_Recv(sol_gather_ptr,
+                   dof.locally_owned_dofs_per_processor()[i].n_elements(),
+                   MPI_DOUBLE, i, i, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
+          sol_gather_ptr += dof.locally_owned_dofs_per_processor()[i].n_elements();
+        }
+      solution_gather0.print(deallog.get_file_stream());
+    }
+  else
+    MPI_Send(sol.begin(), sol.local_size(), MPI_DOUBLE, 0,
+             Utilities::MPI::this_mpi_process(MPI_COMM_WORLD), MPI_COMM_WORLD);
+
+  deallog << "OK" << std::endl;
+}
diff --git a/tests/matrix_free/dg_pbc_01.with_mpi=true.with_p4est=true.mpirun=1.output b/tests/matrix_free/dg_pbc_01.with_mpi=true.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..4b1c122
--- /dev/null
@@ -0,0 +1,11 @@
+
+DEAL:2d::Periodic faces: 1
+DEAL:2d:cg::Starting value 16.0
+DEAL:2d:cg::Convergence step 8 value 0
+4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 
+DEAL:2d::OK
+DEAL:3d::Periodic faces: 2
+DEAL:3d:cg::Starting value 8.00
+DEAL:3d:cg::Convergence step 2 value 0
+4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 
+DEAL:3d::OK
diff --git a/tests/matrix_free/dg_pbc_01.with_mpi=true.with_p4est=true.mpirun=7.output b/tests/matrix_free/dg_pbc_01.with_mpi=true.with_p4est=true.mpirun=7.output
new file mode 100644 (file)
index 0000000..4b1c122
--- /dev/null
@@ -0,0 +1,11 @@
+
+DEAL:2d::Periodic faces: 1
+DEAL:2d:cg::Starting value 16.0
+DEAL:2d:cg::Convergence step 8 value 0
+4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 4.000e+00 1.100e+01 4.000e+00 1.100e+01 1.700e+01 2.200e+01 1.700e+01 2.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 2.600e+01 2.900e+01 2.600e+01 2.900e+01 3.100e+01 3.200e+01 3.100e+01 3.200e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 3.200e+01 3.100e+01 3.200e+01 3.100e+01 2.900e+01 2.600e+01 2.900e+01 2.600e+01 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 2.200e+01 1.700e+01 2.200e+01 1.700e+01 1.100e+01 4.000e+00 1.100e+01 4.000e+00 
+DEAL:2d::OK
+DEAL:3d::Periodic faces: 2
+DEAL:3d:cg::Starting value 8.00
+DEAL:3d:cg::Convergence step 2 value 0
+4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 8.000e+00 4.000e+00 
+DEAL:3d::OK
diff --git a/tests/matrix_free/dg_pbc_02.cc b/tests/matrix_free/dg_pbc_02.cc
new file mode 100644 (file)
index 0000000..4287974
--- /dev/null
@@ -0,0 +1,135 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests that the matrix-free implementation works correctly with periodic
+// boundary conditions by counting the number of faces in the different categories
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/distributed/tria.h>
+#include <deal.II/lac/solver_cg.h>
+#include <deal.II/lac/precondition.h>
+#include <deal.II/matrix_free/matrix_free.h>
+
+std::ofstream logfile("output");
+
+
+
+template <int dim>
+void test ()
+{
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD, dealii::Triangulation<dim>::none,parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy);
+  std::vector<unsigned int> refinements(dim, 1);
+  refinements[0] = 2;
+  Point<dim> p2;
+  p2[0] = 2;
+  for (unsigned int d=1; d<dim; ++d)
+    p2[d] = 1;
+  GridGenerator::subdivided_hyper_rectangle(tria, refinements, Point<dim>(), p2);
+
+  tria.begin()->face(0)->set_all_boundary_ids(10);
+  tria.last()->face(1)->set_all_boundary_ids(11);
+  if (dim == 3)
+    {
+      tria.begin()->face(4)->set_all_boundary_ids(12);
+      tria.begin()->face(5)->set_all_boundary_ids(13);
+      tria.last()->face(4)->set_all_boundary_ids(12);
+      tria.last()->face(5)->set_all_boundary_ids(13);
+    }
+
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> >
+  periodic_faces;
+  GridTools::collect_periodic_faces(tria, 10, 11, 0, periodic_faces);
+  if (dim == 3)
+    GridTools::collect_periodic_faces(tria, 12, 13, 2, periodic_faces);
+
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(8-2*dim);
+
+  FE_DGQ<dim> fe (1);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  dof.distribute_mg_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  const QGauss<1> quad (1);
+  typename MatrixFree<dim>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim>::AdditionalData::none;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  for (unsigned int level=0; level<tria.n_global_levels(); ++level)
+    {
+      MatrixFree<dim> mf_data;
+      data.level_mg_handler = level;
+      mf_data.reinit(dof, constraints, quad, data);
+      std::vector<unsigned int> n_inner_faces(2*dim), n_inner_other_faces(2*dim), n_boundary_faces(2*dim);
+      for (unsigned int f=0; f<mf_data.n_inner_face_batches(); ++f)
+        {
+          for (unsigned int v=0; v<VectorizedArray<double>::n_array_elements; ++v)
+            if (mf_data.get_face_info(f).cells_interior[v] != numbers::invalid_unsigned_int)
+              {
+                n_inner_faces[mf_data.get_face_info(f).interior_face_no]++;
+                n_inner_other_faces[mf_data.get_face_info(f).exterior_face_no]++;
+              }
+        }
+      for (unsigned int f=mf_data.n_inner_face_batches();
+           f<mf_data.n_inner_face_batches()+mf_data.n_boundary_face_batches(); ++f)
+        {
+          for (unsigned int v=0; v<VectorizedArray<double>::n_array_elements; ++v)
+            if (mf_data.get_face_info(f).cells_interior[v] != numbers::invalid_unsigned_int)
+              {
+                n_boundary_faces[mf_data.get_face_info(f).interior_face_no]++;
+              }
+        }
+
+      deallog << "Level: " << level << std::endl;
+      deallog << "Interior faces: ";
+      for (unsigned int f=0; f<n_inner_faces.size(); ++f)
+        deallog << n_inner_faces[f] << " ";
+      deallog << std::endl << "Exterior faces: ";
+      for (unsigned int f=0; f<n_inner_other_faces.size(); ++f)
+        deallog << n_inner_other_faces[f] << " ";
+      deallog << std::endl << "Boundary faces: ";
+      for (unsigned int f=0; f<n_boundary_faces.size(); ++f)
+        deallog << n_boundary_faces[f] << " ";
+      deallog << std::endl;
+    }
+}
+
+
+
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, testing_max_num_threads());
+  MPILogInitAll log;
+  deallog << std::setprecision(3);
+
+  {
+    deallog.push("2d");
+    test<2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/dg_pbc_02.with_mpi=true.with_p4est=true.mpirun=1.output b/tests/matrix_free/dg_pbc_02.with_mpi=true.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..55e37a8
--- /dev/null
@@ -0,0 +1,33 @@
+
+DEAL:0:2d::Level: 0
+DEAL:0:2d::Interior faces: 1 1 0 0 
+DEAL:0:2d::Exterior faces: 1 1 0 0 
+DEAL:0:2d::Boundary faces: 0 0 2 2 
+DEAL:0:2d::Level: 1
+DEAL:0:2d::Interior faces: 6 2 4 0 
+DEAL:0:2d::Exterior faces: 2 6 0 4 
+DEAL:0:2d::Boundary faces: 0 0 4 4 
+DEAL:0:2d::Level: 2
+DEAL:0:2d::Interior faces: 28 4 24 0 
+DEAL:0:2d::Exterior faces: 4 28 0 24 
+DEAL:0:2d::Boundary faces: 0 0 8 8 
+DEAL:0:2d::Level: 3
+DEAL:0:2d::Interior faces: 120 8 112 0 
+DEAL:0:2d::Exterior faces: 8 120 0 112 
+DEAL:0:2d::Boundary faces: 0 0 16 16 
+DEAL:0:2d::Level: 4
+DEAL:0:2d::Interior faces: 496 16 480 0 
+DEAL:0:2d::Exterior faces: 16 496 0 480 
+DEAL:0:2d::Boundary faces: 0 0 32 32 
+DEAL:0:3d::Level: 0
+DEAL:0:3d::Interior faces: 1 1 0 0 0 2 
+DEAL:0:3d::Exterior faces: 1 1 0 0 2 0 
+DEAL:0:3d::Boundary faces: 0 0 2 2 0 0 
+DEAL:0:3d::Level: 1
+DEAL:0:3d::Interior faces: 12 4 8 0 8 8 
+DEAL:0:3d::Exterior faces: 4 12 0 8 8 8 
+DEAL:0:3d::Boundary faces: 0 0 8 8 0 0 
+DEAL:0:3d::Level: 2
+DEAL:0:3d::Interior faces: 112 16 96 0 96 32 
+DEAL:0:3d::Exterior faces: 16 112 0 96 32 96 
+DEAL:0:3d::Boundary faces: 0 0 32 32 0 0 
diff --git a/tests/matrix_free/dg_pbc_02.with_mpi=true.with_p4est=true.mpirun=7.output b/tests/matrix_free/dg_pbc_02.with_mpi=true.with_p4est=true.mpirun=7.output
new file mode 100644 (file)
index 0000000..ba93f2b
--- /dev/null
@@ -0,0 +1,237 @@
+
+DEAL:0:2d::Level: 0
+DEAL:0:2d::Interior faces: 0 0 0 0 
+DEAL:0:2d::Exterior faces: 0 0 0 0 
+DEAL:0:2d::Boundary faces: 0 0 1 1 
+DEAL:0:2d::Level: 1
+DEAL:0:2d::Interior faces: 1 0 0 0 
+DEAL:0:2d::Exterior faces: 0 1 0 0 
+DEAL:0:2d::Boundary faces: 0 0 2 0 
+DEAL:0:2d::Level: 2
+DEAL:0:2d::Interior faces: 2 1 1 3 
+DEAL:0:2d::Exterior faces: 1 2 3 1 
+DEAL:0:2d::Boundary faces: 0 0 3 0 
+DEAL:0:2d::Level: 3
+DEAL:0:2d::Interior faces: 12 5 7 8 
+DEAL:0:2d::Exterior faces: 5 12 8 7 
+DEAL:0:2d::Boundary faces: 0 0 6 0 
+DEAL:0:2d::Level: 4
+DEAL:0:2d::Interior faces: 55 17 44 22 
+DEAL:0:2d::Exterior faces: 17 55 22 44 
+DEAL:0:2d::Boundary faces: 0 0 12 0 
+DEAL:0:3d::Level: 0
+DEAL:0:3d::Interior faces: 0 0 0 0 0 1 
+DEAL:0:3d::Exterior faces: 0 0 0 0 1 0 
+DEAL:0:3d::Boundary faces: 0 0 1 1 0 0 
+DEAL:0:3d::Level: 1
+DEAL:0:3d::Interior faces: 0 1 0 1 0 0 
+DEAL:0:3d::Exterior faces: 1 0 1 0 0 0 
+DEAL:0:3d::Boundary faces: 0 0 2 0 0 0 
+DEAL:0:3d::Level: 2
+DEAL:0:3d::Interior faces: 12 4 6 6 14 2 
+DEAL:0:3d::Exterior faces: 4 12 6 6 2 14 
+DEAL:0:3d::Boundary faces: 0 0 8 0 0 0 
+
+DEAL:1:2d::Level: 0
+DEAL:1:2d::Interior faces: 0 0 0 0 
+DEAL:1:2d::Exterior faces: 0 0 0 0 
+DEAL:1:2d::Boundary faces: 0 0 0 0 
+DEAL:1:2d::Level: 1
+DEAL:1:2d::Interior faces: 0 0 1 0 
+DEAL:1:2d::Exterior faces: 0 0 0 1 
+DEAL:1:2d::Boundary faces: 0 0 0 1 
+DEAL:1:2d::Level: 2
+DEAL:1:2d::Interior faces: 3 3 2 1 
+DEAL:1:2d::Exterior faces: 3 3 1 2 
+DEAL:1:2d::Boundary faces: 0 0 1 0 
+DEAL:1:2d::Level: 3
+DEAL:1:2d::Interior faces: 13 5 11 7 
+DEAL:1:2d::Exterior faces: 5 13 7 11 
+DEAL:1:2d::Boundary faces: 0 0 2 0 
+DEAL:1:2d::Level: 4
+DEAL:1:2d::Interior faces: 56 19 48 27 
+DEAL:1:2d::Exterior faces: 19 56 27 48 
+DEAL:1:2d::Boundary faces: 0 0 4 0 
+DEAL:1:3d::Level: 0
+DEAL:1:3d::Interior faces: 0 0 0 0 0 0 
+DEAL:1:3d::Exterior faces: 0 0 0 0 0 0 
+DEAL:1:3d::Boundary faces: 0 0 0 0 0 0 
+DEAL:1:3d::Level: 1
+DEAL:1:3d::Interior faces: 2 0 1 0 2 2 
+DEAL:1:3d::Exterior faces: 0 2 0 1 2 2 
+DEAL:1:3d::Boundary faces: 0 0 1 2 0 0 
+DEAL:1:3d::Level: 2
+DEAL:1:3d::Interior faces: 17 5 12 7 16 9 
+DEAL:1:3d::Exterior faces: 5 17 7 12 9 16 
+DEAL:1:3d::Boundary faces: 0 0 4 8 0 0 
+
+
+DEAL:2:2d::Level: 0
+DEAL:2:2d::Interior faces: 0 0 0 0 
+DEAL:2:2d::Exterior faces: 0 0 0 0 
+DEAL:2:2d::Boundary faces: 0 0 0 0 
+DEAL:2:2d::Level: 1
+DEAL:2:2d::Interior faces: 1 0 1 0 
+DEAL:2:2d::Exterior faces: 0 1 0 1 
+DEAL:2:2d::Boundary faces: 0 0 0 1 
+DEAL:2:2d::Level: 2
+DEAL:2:2d::Interior faces: 2 1 3 1 
+DEAL:2:2d::Exterior faces: 1 2 1 3 
+DEAL:2:2d::Boundary faces: 0 0 0 2 
+DEAL:2:2d::Level: 3
+DEAL:2:2d::Interior faces: 11 8 10 6 
+DEAL:2:2d::Exterior faces: 8 11 6 10 
+DEAL:2:2d::Boundary faces: 0 0 0 4 
+DEAL:2:2d::Level: 4
+DEAL:2:2d::Interior faces: 55 20 47 18 
+DEAL:2:2d::Exterior faces: 20 55 18 47 
+DEAL:2:2d::Boundary faces: 0 0 0 8 
+DEAL:2:3d::Level: 0
+DEAL:2:3d::Interior faces: 0 0 0 0 0 0 
+DEAL:2:3d::Exterior faces: 0 0 0 0 0 0 
+DEAL:2:3d::Boundary faces: 0 0 0 0 0 0 
+DEAL:2:3d::Level: 1
+DEAL:2:3d::Interior faces: 1 0 1 1 1 1 
+DEAL:2:3d::Exterior faces: 0 1 1 1 1 1 
+DEAL:2:3d::Boundary faces: 0 0 1 1 0 0 
+DEAL:2:3d::Level: 2
+DEAL:2:3d::Interior faces: 12 6 9 2 14 1 
+DEAL:2:3d::Exterior faces: 6 12 2 9 1 14 
+DEAL:2:3d::Boundary faces: 0 0 4 4 0 0 
+
+
+DEAL:3:2d::Level: 0
+DEAL:3:2d::Interior faces: 1 1 0 0 
+DEAL:3:2d::Exterior faces: 1 1 0 0 
+DEAL:3:2d::Boundary faces: 0 0 1 1 
+DEAL:3:2d::Level: 1
+DEAL:3:2d::Interior faces: 1 0 0 0 
+DEAL:3:2d::Exterior faces: 0 1 0 0 
+DEAL:3:2d::Boundary faces: 0 0 1 0 
+DEAL:3:2d::Level: 2
+DEAL:3:2d::Interior faces: 1 4 1 1 
+DEAL:3:2d::Exterior faces: 4 1 1 1 
+DEAL:3:2d::Boundary faces: 0 0 2 2 
+DEAL:3:2d::Level: 3
+DEAL:3:2d::Interior faces: 12 6 9 4 
+DEAL:3:2d::Exterior faces: 6 12 4 9 
+DEAL:3:2d::Boundary faces: 0 0 4 4 
+DEAL:3:2d::Level: 4
+DEAL:3:2d::Interior faces: 53 17 48 18 
+DEAL:3:2d::Exterior faces: 17 53 18 48 
+DEAL:3:2d::Boundary faces: 0 0 8 8 
+DEAL:3:3d::Level: 0
+DEAL:3:3d::Interior faces: 1 1 0 0 0 1 
+DEAL:3:3d::Exterior faces: 1 1 0 0 1 0 
+DEAL:3:3d::Boundary faces: 0 0 1 1 0 0 
+DEAL:3:3d::Level: 1
+DEAL:3:3d::Interior faces: 2 1 0 0 1 1 
+DEAL:3:3d::Exterior faces: 1 2 0 0 1 1 
+DEAL:3:3d::Boundary faces: 0 0 1 1 0 0 
+DEAL:3:3d::Level: 2
+DEAL:3:3d::Interior faces: 11 5 9 3 16 0 
+DEAL:3:3d::Exterior faces: 5 11 3 9 0 16 
+DEAL:3:3d::Boundary faces: 0 0 4 4 0 0 
+
+
+DEAL:4:2d::Level: 0
+DEAL:4:2d::Interior faces: 0 0 0 0 
+DEAL:4:2d::Exterior faces: 0 0 0 0 
+DEAL:4:2d::Boundary faces: 0 0 0 0 
+DEAL:4:2d::Level: 1
+DEAL:4:2d::Interior faces: 1 1 0 0 
+DEAL:4:2d::Exterior faces: 1 1 0 0 
+DEAL:4:2d::Boundary faces: 0 0 1 0 
+DEAL:4:2d::Level: 2
+DEAL:4:2d::Interior faces: 3 2 2 1 
+DEAL:4:2d::Exterior faces: 2 3 1 2 
+DEAL:4:2d::Boundary faces: 0 0 2 0 
+DEAL:4:2d::Level: 3
+DEAL:4:2d::Interior faces: 12 6 7 9 
+DEAL:4:2d::Exterior faces: 6 12 9 7 
+DEAL:4:2d::Boundary faces: 0 0 4 0 
+DEAL:4:2d::Level: 4
+DEAL:4:2d::Interior faces: 54 18 44 24 
+DEAL:4:2d::Exterior faces: 18 54 24 44 
+DEAL:4:2d::Boundary faces: 0 0 8 0 
+DEAL:4:3d::Level: 0
+DEAL:4:3d::Interior faces: 0 0 0 0 0 0 
+DEAL:4:3d::Exterior faces: 0 0 0 0 0 0 
+DEAL:4:3d::Boundary faces: 0 0 0 0 0 0 
+DEAL:4:3d::Level: 1
+DEAL:4:3d::Interior faces: 1 2 1 0 0 0 
+DEAL:4:3d::Exterior faces: 2 1 0 1 0 0 
+DEAL:4:3d::Boundary faces: 0 0 1 1 0 0 
+DEAL:4:3d::Level: 2
+DEAL:4:3d::Interior faces: 12 6 10 0 13 3 
+DEAL:4:3d::Exterior faces: 6 12 0 10 3 13 
+DEAL:4:3d::Boundary faces: 0 0 4 4 0 0 
+
+
+DEAL:5:2d::Level: 0
+DEAL:5:2d::Interior faces: 0 0 0 0 
+DEAL:5:2d::Exterior faces: 0 0 0 0 
+DEAL:5:2d::Boundary faces: 0 0 0 0 
+DEAL:5:2d::Level: 1
+DEAL:5:2d::Interior faces: 1 0 1 0 
+DEAL:5:2d::Exterior faces: 0 1 0 1 
+DEAL:5:2d::Boundary faces: 0 0 0 1 
+DEAL:5:2d::Level: 2
+DEAL:5:2d::Interior faces: 3 1 3 2 
+DEAL:5:2d::Exterior faces: 1 3 2 3 
+DEAL:5:2d::Boundary faces: 0 0 0 2 
+DEAL:5:2d::Level: 3
+DEAL:5:2d::Interior faces: 14 5 13 6 
+DEAL:5:2d::Exterior faces: 5 14 6 13 
+DEAL:5:2d::Boundary faces: 0 0 0 2 
+DEAL:5:2d::Level: 4
+DEAL:5:2d::Interior faces: 56 18 56 20 
+DEAL:5:2d::Exterior faces: 18 56 20 56 
+DEAL:5:2d::Boundary faces: 0 0 0 4 
+DEAL:5:3d::Level: 0
+DEAL:5:3d::Interior faces: 0 0 0 0 0 0 
+DEAL:5:3d::Exterior faces: 0 0 0 0 0 0 
+DEAL:5:3d::Boundary faces: 0 0 0 0 0 0 
+DEAL:5:3d::Level: 1
+DEAL:5:3d::Interior faces: 2 1 1 0 3 3 
+DEAL:5:3d::Exterior faces: 1 2 0 1 3 3 
+DEAL:5:3d::Boundary faces: 0 0 2 1 0 0 
+DEAL:5:3d::Level: 2
+DEAL:5:3d::Interior faces: 15 7 10 10 20 4 
+DEAL:5:3d::Exterior faces: 7 15 10 10 4 20 
+DEAL:5:3d::Boundary faces: 0 0 8 4 0 0 
+
+
+DEAL:6:2d::Level: 0
+DEAL:6:2d::Interior faces: 0 0 0 0 
+DEAL:6:2d::Exterior faces: 0 0 0 0 
+DEAL:6:2d::Boundary faces: 0 0 0 0 
+DEAL:6:2d::Level: 1
+DEAL:6:2d::Interior faces: 1 1 1 0 
+DEAL:6:2d::Exterior faces: 1 1 0 1 
+DEAL:6:2d::Boundary faces: 0 0 0 1 
+DEAL:6:2d::Level: 2
+DEAL:6:2d::Interior faces: 4 2 3 0 
+DEAL:6:2d::Exterior faces: 2 4 0 3 
+DEAL:6:2d::Boundary faces: 0 0 0 2 
+DEAL:6:2d::Level: 3
+DEAL:6:2d::Interior faces: 10 9 13 2 
+DEAL:6:2d::Exterior faces: 9 10 2 13 
+DEAL:6:2d::Boundary faces: 0 0 0 6 
+DEAL:6:2d::Level: 4
+DEAL:6:2d::Interior faces: 57 17 58 6 
+DEAL:6:2d::Exterior faces: 17 57 6 58 
+DEAL:6:2d::Boundary faces: 0 0 0 12 
+DEAL:6:3d::Level: 0
+DEAL:6:3d::Interior faces: 0 0 0 0 0 0 
+DEAL:6:3d::Exterior faces: 0 0 0 0 0 0 
+DEAL:6:3d::Boundary faces: 0 0 0 0 0 0 
+DEAL:6:3d::Level: 1
+DEAL:6:3d::Interior faces: 2 1 2 0 1 1 
+DEAL:6:3d::Exterior faces: 1 2 0 2 1 1 
+DEAL:6:3d::Boundary faces: 0 0 0 2 0 0 
+DEAL:6:3d::Level: 2
+DEAL:6:3d::Interior faces: 12 4 9 3 13 3 
+DEAL:6:3d::Exterior faces: 4 12 3 9 3 13 
+DEAL:6:3d::Boundary faces: 0 0 0 8 0 0 
+
diff --git a/tests/matrix_free/faces_value_optimization.cc b/tests/matrix_free/faces_value_optimization.cc
new file mode 100644 (file)
index 0000000..125e375
--- /dev/null
@@ -0,0 +1,245 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation with the option to compress
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+#include <deal.II/lac/constraint_matrix.h>
+
+std::ofstream logfile("output");
+
+template <int dim, int fe_degree, typename number>
+class MatrixFreeTest
+{
+public:
+  MatrixFreeTest (const MatrixFree<dim,number> &data)
+    :
+    data(data),
+    error(2)
+  {}
+
+  ~MatrixFreeTest()
+  {
+    deallog << "Error between variants: " << error[0] / error[1] << std::endl;
+  }
+
+  void check_error(Vector<number> &src) const
+  {
+    data.loop (&MatrixFreeTest::local_apply,
+               &MatrixFreeTest::local_apply_face,
+               &MatrixFreeTest::local_apply_face,
+               this, src, src);
+  }
+
+private:
+  void local_apply (const MatrixFree<dim,number> &,
+                    Vector<number> &,
+                    const Vector<number> &,
+                    const std::pair<unsigned int,unsigned int> &) const
+  {
+  }
+
+  void local_apply_face (const MatrixFree<dim,number>    &data,
+                         Vector<number> &,
+                         const Vector<number>            &src,
+                         const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,fe_degree+1,1,number> ref(data,true);
+    FEFaceEvaluation<dim,fe_degree,fe_degree+1,1,number> check(data,true);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        ref.reinit (face);
+        check.reinit (face);
+
+        ref.read_dof_values(src);
+        ref.evaluate(true,false);
+        check.gather_evaluate(src,true,false);
+
+        for (unsigned int q=0; q<ref.n_q_points; ++q)
+          {
+            VectorizedArray<number> diff = (ref.get_value(q)-check.get_value(q));
+            for (unsigned int v=0; v<VectorizedArray<number>::n_array_elements; ++v)
+              {
+                if (std::abs(diff[v]) > 1e-12)
+                  {
+                    deallog << "Error detected on face" << face << ", v=" << v
+                            << "!" << std::endl;
+                    deallog << "ref: ";
+                    for (unsigned int i=0; i<ref.dofs_per_cell; ++i)
+                      deallog << ref.get_dof_value(i)[v] << " ";
+                    deallog << std::endl;
+                    deallog << "done: "
+                            << check.get_value(q)[v]
+                            << " instead of "
+                            << ref.get_value(q)[v] << std::endl;
+
+                    deallog << data.get_face_info(face).cells_interior[v] <<  " "
+                            << (int)data.get_face_info(face).interior_face_no << " "
+                            << (int)data.get_face_info(face).face_orientation << " "
+                            << (int)data.get_face_info(face).subface_index << std::endl;
+                    deallog << std::endl;
+                  }
+                error[0] += std::abs(diff[v]);
+                error[1] += std::abs(ref.get_value(q)[v]);
+              }
+          }
+      }
+
+    FEFaceEvaluation<dim,fe_degree,fe_degree+1,1,number> refr(data,false);
+    FEFaceEvaluation<dim,fe_degree,fe_degree+1,1,number> checkr(data,false);
+
+    for (unsigned int face=face_range.first; face<std::min(data.n_inner_face_batches(),
+                                                           face_range.second); face++)
+      {
+        refr.reinit (face);
+        checkr.reinit (face);
+
+        refr.read_dof_values(src);
+        refr.evaluate(true,false);
+        checkr.gather_evaluate(src,true,false);
+
+        for (unsigned int q=0; q<ref.n_q_points; ++q)
+          {
+            VectorizedArray<number> diff = (refr.get_value(q)-checkr.get_value(q));
+            for (unsigned int v=0; v<VectorizedArray<number>::n_array_elements; ++v)
+              {
+                if (std::abs(diff[v]) > 1e-12)
+                  {
+                    deallog << "Error detected on face" << face << ", v=" << v
+                            << "!" << std::endl;
+                    deallog << "ref: ";
+                    for (unsigned int i=0; i<ref.dofs_per_cell; ++i)
+                      deallog << refr.get_dof_value(i)[v] << " ";
+                    deallog << std::endl;
+                    deallog << "done: "
+                            << check.get_value(q)[v]
+                            << " instead of "
+                            << ref.get_value(q)[v] << std::endl;
+
+                    deallog << data.get_face_info(face).cells_exterior[v] << " "
+                            << (int)data.get_face_info(face).exterior_face_no << " "
+                            << (int)data.get_face_info(face).face_orientation << " "
+                            << (int)data.get_face_info(face).subface_index << std::endl;
+                    deallog << std::endl;
+                  }
+                error[0] += std::abs(diff[v]);
+                error[1] += std::abs(refr.get_value(q)[v]);
+              }
+          }
+      }
+  }
+
+  const MatrixFree<dim,number>     &data;
+  mutable std::vector<double> error;
+};
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_ball (tria);
+  static const HyperBallBoundary<dim> boundary;
+  tria.set_boundary (0, boundary);
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.refine_global(1);
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<10-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  typedef double number;
+
+  MatrixFree<dim,number> mf_data;
+  {
+    const QGauss<1> quad (fe_degree+1);
+    typename MatrixFree<dim,number>::AdditionalData data;
+    data.tasks_parallel_scheme =
+      MatrixFree<dim,number>::AdditionalData::none;
+    data.tasks_block_size = 3;
+    data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+    data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+    mf_data.reinit (dof, constraints, quad, data);
+  }
+
+  MatrixFreeTest<dim,fe_degree,number> mf(mf_data);
+
+  Vector<number> in (dof.n_dofs());
+
+  for (unsigned int i=0; i<dof.n_dofs(); ++i)
+    {
+      if (constraints.is_constrained(i))
+        continue;
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in(i) = entry;
+    }
+
+  mf.check_error(in);
+}
+
+
+
+int main ()
+{
+  initlog();
+
+  deallog << std::setprecision (3);
+
+  {
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/faces_value_optimization.output b/tests/matrix_free/faces_value_optimization.output
new file mode 100644 (file)
index 0000000..0bb2968
--- /dev/null
@@ -0,0 +1,5 @@
+
+DEAL:2d::Error between variants: 0
+DEAL:2d::Error between variants: 0
+DEAL:3d::Error between variants: 0
+DEAL:3d::Error between variants: 0
diff --git a/tests/matrix_free/get_functions_faces.cc b/tests/matrix_free/get_functions_faces.cc
new file mode 100644 (file)
index 0000000..acae4c8
--- /dev/null
@@ -0,0 +1,156 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2014-2014 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation in a very simple form
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+#include <deal.II/numerics/vector_tools.h>
+
+std::ofstream logfile("output");
+
+
+
+template <int dim, int fe_degree, typename number>
+class MatrixFreeTest
+{
+public:
+  MatrixFreeTest (const MatrixFree<dim,number> &data)
+    :
+    data(data)
+  {}
+
+  void action(Vector<number> &src) const
+  {
+    data.loop (&MatrixFreeTest::dummy,
+               &MatrixFreeTest::dummy,
+               &MatrixFreeTest::local_apply_boundary_face,
+               this, src, src);
+  }
+
+private:
+  void dummy (const MatrixFree<dim,number> &,
+              Vector<number> &, const Vector<number> &,
+              const std::pair<unsigned int,unsigned int> &) const
+  {
+  }
+  void local_apply_boundary_face (const MatrixFree<dim,number>    &data,
+                                  Vector<number> &,
+                                  const Vector<number>            &src,
+                                  const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,fe_degree+1,1,number> fe_eval(data, true);
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+
+        // Only one vectorization component is filled in this case because we
+        // only have one cell (otherwise the output will not be stable among
+        // systems...)
+        deallog << "Face " << face << ": ";
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            deallog << fe_eval.get_value(q)[0] << " "
+                    << fe_eval.get_normal_derivative(q)[0] << "   ";
+          }
+        deallog << std::endl;
+      }
+  }
+
+  const MatrixFree<dim,number>     &data;
+};
+
+
+
+template <int dim>
+class BoundaryFunction : public Function<dim>
+{
+public:
+  virtual double value(const Point<dim> &p,
+                       const unsigned int) const
+  {
+    return p[0]+0.2*p[1];
+  }
+};
+
+
+
+template <int dim>
+Point<dim> grid_transform (const Point<dim> &in)
+{
+  Point<dim> out;
+  for (unsigned int d=0; d<dim; ++d)
+    out[d] = in[d] + 0.75 * d * in[0];
+  return out;
+}
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria, 0, 1);
+  GridTools::transform (&grid_transform<dim>, tria);
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  MatrixFree<dim,double> mf_data;
+  {
+    const QGauss<1> quad (fe_degree+1);
+    typename MatrixFree<dim,double>::AdditionalData data;
+    data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+    data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+    data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+    mf_data.reinit (dof, constraints, quad, data);
+  }
+  MatrixFreeTest<dim,fe_degree,double> mf (mf_data);
+  Vector<double> in (dof.n_dofs());
+  VectorTools::interpolate(dof, BoundaryFunction<dim>(), in);
+  mf.action(in);
+}
+
+
+int main ()
+{
+  initlog();
+
+  deallog << std::setprecision (3);
+
+  {
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/get_functions_faces.output b/tests/matrix_free/get_functions_faces.output
new file mode 100644 (file)
index 0000000..583e1fa
--- /dev/null
@@ -0,0 +1,15 @@
+
+DEAL:2d::Face 0: 0.0423 -1.00   0.158 -1.00   
+DEAL:2d::Face 1: 1.19 1.00   1.31 1.00   
+DEAL:2d::Face 2: 0.243 0.440   0.907 0.440   
+DEAL:2d::Face 3: 0.443 -0.440   1.11 -0.440   
+DEAL:2d::Face 0: 0.0225 -1.00   0.100 -1.00   0.177 -1.00   
+DEAL:2d::Face 1: 1.17 1.00   1.25 1.00   1.33 1.00   
+DEAL:2d::Face 2: 0.130 0.440   0.575 0.440   1.02 0.440   
+DEAL:2d::Face 3: 0.330 -0.440   0.775 -0.440   1.22 -0.440   
+DEAL:3d::Face 0: 0.0423 -1.00   0.158 -1.00   0.0423 -1.00   0.158 -1.00   
+DEAL:3d::Face 1: 1.19 1.00   1.31 1.00   1.19 1.00   1.31 1.00   
+DEAL:3d::Face 2: 0.243 0.440   0.243 0.440   0.907 0.440   0.907 0.440   
+DEAL:3d::Face 3: 0.443 -0.440   0.443 -0.440   1.11 -0.440   1.11 -0.440   
+DEAL:3d::Face 4: 0.285 0.832   0.949 0.832   0.401 0.832   1.06 0.832   
+DEAL:3d::Face 5: 0.285 -0.832   0.949 -0.832   0.401 -0.832   1.06 -0.832   
diff --git a/tests/matrix_free/interpolate_constant.cc b/tests/matrix_free/interpolate_constant.cc
new file mode 100644 (file)
index 0000000..9359153
--- /dev/null
@@ -0,0 +1,88 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// this function tests the correctness of the implementation of matrix free
+// operations in getting the function values, the function gradients, and the
+// function Laplacians on a cartesian mesh (hyper cube). This tests whether
+// cartesian meshes are treated correctly. The test case is without any
+// constraints
+
+#include "../tests.h"
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_dgq.h>
+
+
+#include "interpolate_functions_common.h"
+
+
+template <int dim>
+class CompareFunction : public Function<dim>
+{
+public:
+  virtual double value (const Point<dim> &p, const unsigned int ) const
+  {
+    return 1;
+  }
+  virtual Tensor<1,dim> gradient (const Point<dim> &p, const unsigned int ) const
+  {
+    return Tensor<1,dim>();
+  }
+  virtual SymmetricTensor<2,dim> hessian (const Point<dim> &p, const unsigned int ) const
+  {
+    return SymmetricTensor<2,dim>();
+  }
+
+};
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  tria.refine_global(1);
+
+  if (fe_degree > 0)
+    {
+      FE_Q<dim> fe (fe_degree);
+      DoFHandler<dim> dof (tria);
+      dof.distribute_dofs(fe);
+
+      ConstraintMatrix constraints;
+      constraints.close();
+      do_test<dim, fe_degree, double> (dof, constraints);
+    }
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  deallog << "Test without templates on FEEvaluation" << std::endl;
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, -1, double> (dof, constraints);
+  }
+}
diff --git a/tests/matrix_free/interpolate_constant.output b/tests/matrix_free/interpolate_constant.output
new file mode 100644 (file)
index 0000000..2785518
--- /dev/null
@@ -0,0 +1,360 @@
+
+DEAL:1d::Testing FE_DGQ<1>(0)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Test without templates on FEEvaluation
+DEAL:1d::Testing FE_DGQ<1>(0)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Testing FE_Q<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Testing FE_DGQ<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Test without templates on FEEvaluation
+DEAL:1d::Testing FE_DGQ<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:2d::Testing FE_DGQ<2>(0)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(0)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Test without templates on FEEvaluation
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Test without templates on FEEvaluation
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
diff --git a/tests/matrix_free/interpolate_cubic.cc b/tests/matrix_free/interpolate_cubic.cc
new file mode 100644 (file)
index 0000000..744c48f
--- /dev/null
@@ -0,0 +1,113 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// this function tests the correctness of the implementation of matrix free
+// operations in getting the function values, the function gradients, and the
+// function Laplacians on a cartesian mesh (hyper cube). This tests whether
+// cartesian meshes are treated correctly. The test case is without any
+// constraints
+
+#include "../tests.h"
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_dgq.h>
+
+
+#include "interpolate_functions_common.h"
+
+
+template <int dim>
+class CompareFunction : public Function<dim>
+{
+public:
+  virtual double value (const Point<dim> &p, const unsigned int ) const
+  {
+    double value = 1.;
+    for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int e=0; e<dim; ++e)
+        for (unsigned int f=0; f<dim; ++f)
+          value += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * p[d] * p[e] * p[f];
+    return value;
+  }
+  virtual Tensor<1,dim> gradient (const Point<dim> &p, const unsigned int ) const
+  {
+    Tensor<1,dim> grad;
+    for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int e=0; e<dim; ++e)
+        for (unsigned int f=0; f<dim; ++f)
+          {
+            grad[d] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * p[e] * p[f];
+            grad[e] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * p[d] * p[f];
+            grad[f] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * p[d] * p[e];
+          }
+    return grad;
+  }
+  virtual SymmetricTensor<2,dim> hessian (const Point<dim> &p, const unsigned int ) const
+  {
+    SymmetricTensor<2,dim> hess;
+    for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int e=0; e<dim; ++e)
+        for (unsigned int f=0; f<dim; ++f)
+          {
+            hess[d][e] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * (d==e ? 2.0 : 1.0) * p[f];
+            hess[d][f] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * (d==f ? 2.0 : 1.0) * p[e];
+            hess[e][f] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.) * f) * (f==e ? 2.0 : 1.0) * p[d];
+          }
+    return hess;
+  }
+
+};
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  if (fe_degree < 3)
+    return;
+
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  tria.refine_global(1);
+
+  {
+    FE_Q<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  deallog << "Test without templates on FEEvaluation" << std::endl;
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, -1, double> (dof, constraints);
+  }
+}
diff --git a/tests/matrix_free/interpolate_cubic.output b/tests/matrix_free/interpolate_cubic.output
new file mode 100644 (file)
index 0000000..b2cb4c4
--- /dev/null
@@ -0,0 +1,87 @@
+
+DEAL:2d::Testing FE_Q<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
diff --git a/tests/matrix_free/interpolate_functions_common.h b/tests/matrix_free/interpolate_functions_common.h
new file mode 100644 (file)
index 0000000..13dff44
--- /dev/null
@@ -0,0 +1,326 @@
+//------------------  interpolate_functions_common.h  ------------------------
+//
+// 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.
+//
+//------------------  interpolate_functions_common.h  ------------------------
+
+
+// this is a template for getting the function values and comparing them with
+// an analytical function for different meshes
+
+#include "../tests.h"
+
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+#include <deal.II/base/function.h>
+
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/fe/mapping_q.h>
+#include <deal.II/numerics/vector_tools.h>
+
+#include <fstream>
+#include <iostream>
+
+
+// forward declare this function. will be implemented in .cc files
+template <int dim, int fe_degree>
+void test ();
+
+template <int dim> class CompareFunction;
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d=fe_degree+1,typename Number=double>
+class MatrixFreeTest
+{
+public:
+  MatrixFreeTest(const MatrixFree<dim,Number> &data_in):
+    data   (data_in)
+  {};
+
+  MatrixFreeTest(const MatrixFree<dim,Number> &data_in,
+                 const Mapping<dim>               &mapping):
+    data   (data_in)
+  {};
+
+  virtual ~MatrixFreeTest ()
+  {}
+
+  // make function virtual to allow derived classes to define a different
+  // function
+  virtual void
+  cell (const MatrixFree<dim,Number> &data,
+        Vector<Number> &,
+        const Vector<Number> &src,
+        const std::pair<unsigned int,unsigned int> &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,Number> fe_eval (data);
+
+    CompareFunction<dim> function;
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        fe_eval.reinit (cell);
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate (true,true,true);
+
+        for (unsigned int j=0; j<data.n_components_filled(cell); ++j)
+          for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+            {
+              ++cell_times;
+              Point<dim> p;
+              for (unsigned int d=0; d<dim; ++d)
+                p[d] = fe_eval.quadrature_point(q)[d][j];
+              cell_errors[0] += std::abs(fe_eval.get_value(q)[j]-
+                                         function.value(p, 0));
+              for (unsigned int d=0; d<dim; ++d)
+                cell_errors[1] += std::abs(fe_eval.get_gradient(q)[d][j]-
+                                           function.gradient(p, 0)[d]);
+              for (unsigned int d=0; d<dim; ++d)
+                for (unsigned int e=0; e<dim; ++e)
+                  cell_errors[2] += std::abs(fe_eval.get_hessian(q)[d][e][j]-
+                                             function.hessian(p, 0)[d][e]);
+            }
+      }
+  }
+
+  virtual void
+  face (const MatrixFree<dim,Number> &data,
+        Vector<Number> &,
+        const Vector<Number> &src,
+        const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,Number> fe_evalm (data, true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,Number> fe_evalp (data, false);
+
+    CompareFunction<dim> function;
+
+    for (unsigned int face=face_range.first; face<face_range.second; ++face)
+      {
+        fe_evalm.reinit (face);
+        fe_evalm.read_dof_values(src);
+        fe_evalm.evaluate (true,true);
+        fe_evalp.reinit (face);
+        fe_evalp.read_dof_values(src);
+        fe_evalp.evaluate (true,true);
+
+        for (unsigned int j=0; j<VectorizedArray<Number>::n_array_elements; ++j)
+          {
+            // skip empty components in VectorizedArray
+            if (data.get_face_info(face).cells_interior[j] == numbers::invalid_unsigned_int)
+              break;
+            for (unsigned int q=0; q<fe_evalm.n_q_points; ++q)
+              {
+                ++facem_times;
+                ++facep_times;
+                Point<dim> p;
+                for (unsigned int d=0; d<dim; ++d)
+                  p[d] = fe_evalm.quadrature_point(q)[d][j];
+                facem_errors[0] += std::abs(fe_evalm.get_value(q)[j]-
+                                            function.value(p, 0));
+                for (unsigned int d=0; d<dim; ++d)
+                  {
+                    //std::cout << fe_evalm.get_gradient(q)[d][j] << " ";
+                    facem_errors[1] += std::abs(fe_evalm.get_gradient(q)[d][j]-
+                                                function.gradient(p, 0)[d]);
+                  }
+                double normal_derivative = 0;
+                for (unsigned int d=0; d<dim; ++d)
+                  normal_derivative += function.gradient(p, 0)[d] * fe_evalm.get_normal_vector(q)[d][j];
+                facem_errors[3] += std::abs(fe_evalm.get_normal_derivative(q)[j]-
+                                            normal_derivative);
+                facep_errors[0] += std::abs(fe_evalp.get_value(q)[j]-
+                                            function.value(p, 0));
+                for (unsigned int d=0; d<dim; ++d)
+                  facep_errors[1] += std::abs(fe_evalp.get_gradient(q)[d][j]-
+                                              function.gradient(p, 0)[d]);
+                facep_errors[3] += std::abs(fe_evalp.get_normal_derivative(q)[j]-
+                                            normal_derivative);
+                // hessians not currently implemented in FEFaceEvaluation
+                //for (unsigned int d=0; d<dim; ++d)
+                //  for (unsigned int e=0; e<dim; ++e)
+                //    facem_errors[2] += std::abs(fe_evalm.get_hessian(q)[d][e][j]-
+                //                                function.hessian(q)[d][e]);
+              }
+            //std::cout << std::endl;
+          }
+      }
+  }
+
+  virtual void
+  boundary (const MatrixFree<dim,Number> &data,
+            Vector<Number> &,
+            const Vector<Number> &src,
+            const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,Number> fe_evalm (data, true);
+
+    CompareFunction<dim> function;
+
+    for (unsigned int face=face_range.first; face<face_range.second; ++face)
+      {
+        fe_evalm.reinit (face);
+        fe_evalm.read_dof_values(src);
+        fe_evalm.evaluate (true,true);
+
+        for (unsigned int j=0; j<VectorizedArray<Number>::n_array_elements; ++j)
+          {
+            // skip empty components in VectorizedArray
+            if (data.get_face_info(face).cells_interior[j] == numbers::invalid_unsigned_int)
+              break;
+            for (unsigned int q=0; q<fe_evalm.n_q_points; ++q)
+              {
+                ++boundary_times;
+                Point<dim> p;
+                for (unsigned int d=0; d<dim; ++d)
+                  p[d] = fe_evalm.quadrature_point(q)[d][j];
+                boundary_errors[0] += std::abs(fe_evalm.get_value(q)[j]-
+                                               function.value(p, 0));
+                for (unsigned int d=0; d<dim; ++d)
+                  boundary_errors[1] += std::abs(fe_evalm.get_gradient(q)[d][j]-
+                                                 function.gradient(p, 0)[d]);
+                double normal_derivative = 0;
+                for (unsigned int d=0; d<dim; ++d)
+                  normal_derivative += function.gradient(p, 0)[d] * fe_evalm.get_normal_vector(q)[d][j];
+                boundary_errors[3] += std::abs(fe_evalm.get_normal_derivative(q)[j]-
+                                               normal_derivative);
+                // hessians not currently implemented in FEFaceEvaluation
+                //for (unsigned int d=0; d<dim; ++d)
+                //  for (unsigned int e=0; e<dim; ++e)
+                //    boundary_errors[2] += std::abs(fe_evalm.get_hessian(q)[d][e][j]-
+                //                                   function.hessian(q)[d][e]);
+              }
+          }
+      }
+  }
+
+
+
+  void test_functions (const Vector<Number> &src) const
+  {
+    for (unsigned int i=0; i<4; ++i)
+      {
+        cell_errors[i] = 0;
+        facem_errors[i] = 0;
+        facep_errors[i] = 0;
+        boundary_errors[i] = 0;
+      }
+    cell_times = facem_times = facep_times = boundary_times = 0;
+
+    Vector<Number> dst_dummy;
+    data.loop (&MatrixFreeTest::cell, &MatrixFreeTest::face,
+               &MatrixFreeTest::boundary, this, dst_dummy, src);
+
+    if (std::is_same<Number,float>::value)
+      for (unsigned int i=0; i<4; ++i)
+        {
+          if (cell_errors[i]/cell_times < 1e-5)
+            cell_errors[i] = 0;
+          if (facem_errors[i]/cell_times < 1e-5)
+            facem_errors[i] = 0;
+          if (facep_errors[i]/cell_times < 1e-5)
+            facep_errors[i] = 0;
+          if (boundary_errors[i]/cell_times < 1e-5)
+            boundary_errors[i] = 0;
+        }
+    deallog << "Error cell values:      " << cell_errors[0]/cell_times << std::endl;
+    deallog << "Error cell gradients:   " << cell_errors[1]/cell_times << std::endl;
+    deallog << "Error cell Hessians:    " << cell_errors[2]/cell_times << std::endl;
+    deallog << "Error face- values:     " << facem_errors[0]/facem_times << std::endl;
+    deallog << "Error face- gradients:  " << facem_errors[1]/facem_times << std::endl;
+    //deallog << "Error face- Hessians:   " << facem_errors[2]/facem_times << std::endl;
+    deallog << "Error face- grad*normal:" << facem_errors[3]/facem_times << std::endl;
+    deallog << "Error face+ values:     " << facep_errors[0]/facep_times << std::endl;
+    deallog << "Error face+ gradients:  " << facep_errors[1]/facep_times << std::endl;
+    //deallog << "Error face+ Hessians:   " << facep_errors[2]/facep_times << std::endl;
+    deallog << "Error face+ grad*normal:" << facem_errors[3]/facep_times << std::endl;
+    deallog << "Error face b values:    " << boundary_errors[0]/boundary_times << std::endl;
+    deallog << "Error face b gradients: " << boundary_errors[1]/boundary_times << std::endl;
+    //deallog << "Error face b Hessians:  " << boundary_errors[2]/boundary_times << std::endl;
+    deallog << "Error face b grad*norm: " << boundary_errors[3]/boundary_times << std::endl;
+    deallog << std::endl;
+  };
+
+protected:
+  const MatrixFree<dim,Number> &data;
+  mutable double cell_errors[4], facem_errors[4], facep_errors[4], boundary_errors[4];
+  mutable unsigned long long cell_times, facem_times, facep_times, boundary_times;
+};
+
+
+
+
+template <int dim, int fe_degree, typename number>
+void do_test (const DoFHandler<dim> &dof,
+              const ConstraintMatrix &constraints)
+{
+  deallog << "Testing " << dof.get_fe().get_name() << std::endl;
+  // use this for info on problem
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells()
+  //          << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  Vector<number> interpolated (dof.n_dofs());
+  VectorTools::interpolate(dof, CompareFunction<dim>(), interpolated);
+
+  constraints.distribute(interpolated);
+  MatrixFree<dim,number> mf_data;
+  {
+    const QGauss<1> quad (dof.get_fe().degree+1);
+    typename MatrixFree<dim,number>::AdditionalData data;
+    data.tasks_parallel_scheme = MatrixFree<dim,number>::AdditionalData::none;
+    data.mapping_update_flags = update_gradients | update_second_derivatives |
+                                update_quadrature_points;
+    data.mapping_update_flags_boundary_faces = update_gradients | update_second_derivatives |
+                                               update_quadrature_points;
+    data.mapping_update_flags_inner_faces = update_gradients | update_second_derivatives |
+                                            update_quadrature_points;
+    mf_data.reinit (dof, constraints, quad, data);
+  }
+
+  MatrixFreeTest<dim,fe_degree,fe_degree+1,number> mf (mf_data);
+  mf.test_functions(interpolated);
+}
+
+
+int main ()
+{
+  initlog();
+
+  deallog << std::setprecision (3);
+  {
+    deallog.push("1d");
+    test<1,0>();
+    test<1,2>();
+    deallog.pop();
+    deallog.push("2d");
+    test<2,0>();
+    test<2,1>();
+    test<2,2>();
+    test<2,3>();
+    test<2,4>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/interpolate_linear.cc b/tests/matrix_free/interpolate_linear.cc
new file mode 100644 (file)
index 0000000..9fcbf37
--- /dev/null
@@ -0,0 +1,97 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// this function tests the correctness of the implementation of matrix free
+// operations in getting the function values, the function gradients, and the
+// function Laplacians on a cartesian mesh (hyper cube). This tests whether
+// cartesian meshes are treated correctly. The test case is without any
+// constraints
+
+#include "../tests.h"
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_dgq.h>
+
+
+#include "interpolate_functions_common.h"
+
+
+template <int dim>
+class CompareFunction : public Function<dim>
+{
+public:
+  virtual double value (const Point<dim> &p, const unsigned int ) const
+  {
+    double value = 1.2*p[0];
+    for (unsigned int d=1; d<dim; ++d)
+      value -= 2.7 * d * p[d];
+    return value;
+  }
+  virtual Tensor<1,dim> gradient (const Point<dim> &p, const unsigned int ) const
+  {
+    Tensor<1,dim> grad;
+    grad[0] = 1.2;
+    for (unsigned int d=1; d<dim; ++d)
+      grad[d] = -2.7 * d;
+    return grad;
+  }
+  virtual SymmetricTensor<2,dim> hessian (const Point<dim> &p, const unsigned int ) const
+  {
+    return SymmetricTensor<2,dim>();
+  }
+
+};
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  if (fe_degree == 0)
+    return;
+
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  tria.refine_global(1);
+
+  {
+    FE_Q<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  deallog << "Test without templates on FEEvaluation" << std::endl;
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, -1, double> (dof, constraints);
+  }
+}
diff --git a/tests/matrix_free/interpolate_linear.output b/tests/matrix_free/interpolate_linear.output
new file mode 100644 (file)
index 0000000..f432ded
--- /dev/null
@@ -0,0 +1,302 @@
+
+DEAL:1d::Testing FE_Q<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Testing FE_DGQ<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Test without templates on FEEvaluation
+DEAL:1d::Testing FE_DGQ<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Test without templates on FEEvaluation
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Test without templates on FEEvaluation
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
diff --git a/tests/matrix_free/interpolate_quadratic.cc b/tests/matrix_free/interpolate_quadratic.cc
new file mode 100644 (file)
index 0000000..55e7dbd
--- /dev/null
@@ -0,0 +1,105 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// this function tests the correctness of the implementation of matrix free
+// operations in getting the function values, the function gradients, and the
+// function Laplacians on a cartesian mesh (hyper cube). This tests whether
+// cartesian meshes are treated correctly. The test case is without any
+// constraints
+
+#include "../tests.h"
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_dgq.h>
+
+
+#include "interpolate_functions_common.h"
+
+
+template <int dim>
+class CompareFunction : public Function<dim>
+{
+public:
+  virtual double value (const Point<dim> &p, const unsigned int ) const
+  {
+    double value = 1.;
+    for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int e=0; e<dim; ++e)
+        value += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.)) * p[d] * p[e];
+    return value;
+  }
+  virtual Tensor<1,dim> gradient (const Point<dim> &p, const unsigned int ) const
+  {
+    Tensor<1,dim> grad;
+    for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int e=0; e<dim; ++e)
+        {
+          grad[d] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.)) * p[e];
+          grad[e] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.)) * p[d];
+        }
+    return grad;
+  }
+  virtual SymmetricTensor<2,dim> hessian (const Point<dim> &p, const unsigned int ) const
+  {
+    SymmetricTensor<2,dim> hess;
+    for (unsigned int d=0; d<dim; ++d)
+      for (unsigned int e=0; e<dim; ++e)
+        hess[d][e] += (1.3 + 0.9 * d * (e+1) - 1.4 * (d+1) * (e-1.)) * (d==e ? 2.0 : 1.0);
+    return hess;
+  }
+
+};
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  if (fe_degree < 2)
+    return;
+
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  tria.refine_global(1);
+
+  {
+    FE_Q<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, fe_degree, double> (dof, constraints);
+  }
+  deallog << "Test without templates on FEEvaluation" << std::endl;
+  {
+    FE_DGQ<dim> fe (fe_degree);
+    DoFHandler<dim> dof (tria);
+    dof.distribute_dofs(fe);
+
+    ConstraintMatrix constraints;
+    constraints.close();
+    do_test<dim, -1, double> (dof, constraints);
+  }
+}
diff --git a/tests/matrix_free/interpolate_quadratic.output b/tests/matrix_free/interpolate_quadratic.output
new file mode 100644 (file)
index 0000000..8886b38
--- /dev/null
@@ -0,0 +1,216 @@
+
+DEAL:1d::Testing FE_Q<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Testing FE_DGQ<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:1d::Test without templates on FEEvaluation
+DEAL:1d::Testing FE_DGQ<1>(2)
+DEAL:1d::Error cell values:      0
+DEAL:1d::Error cell gradients:   0
+DEAL:1d::Error cell Hessians:    0
+DEAL:1d::Error face- values:     0
+DEAL:1d::Error face- gradients:  0
+DEAL:1d::Error face- grad*normal:0
+DEAL:1d::Error face+ values:     0
+DEAL:1d::Error face+ gradients:  0
+DEAL:1d::Error face+ grad*normal:0
+DEAL:1d::Error face b values:    0
+DEAL:1d::Error face b gradients: 0
+DEAL:1d::Error face b grad*norm: 0
+DEAL:1d::
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:2d::Test without templates on FEEvaluation
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Error cell values:      0
+DEAL:2d::Error cell gradients:   0
+DEAL:2d::Error cell Hessians:    0
+DEAL:2d::Error face- values:     0
+DEAL:2d::Error face- gradients:  0
+DEAL:2d::Error face- grad*normal:0
+DEAL:2d::Error face+ values:     0
+DEAL:2d::Error face+ gradients:  0
+DEAL:2d::Error face+ grad*normal:0
+DEAL:2d::Error face b values:    0
+DEAL:2d::Error face b gradients: 0
+DEAL:2d::Error face b grad*norm: 0
+DEAL:2d::
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
+DEAL:3d::Test without templates on FEEvaluation
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Error cell values:      0
+DEAL:3d::Error cell gradients:   0
+DEAL:3d::Error cell Hessians:    0
+DEAL:3d::Error face- values:     0
+DEAL:3d::Error face- gradients:  0
+DEAL:3d::Error face- grad*normal:0
+DEAL:3d::Error face+ values:     0
+DEAL:3d::Error face+ gradients:  0
+DEAL:3d::Error face+ grad*normal:0
+DEAL:3d::Error face b values:    0
+DEAL:3d::Error face b gradients: 0
+DEAL:3d::Error face b grad*norm: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_01.cc b/tests/matrix_free/matrix_vector_faces_01.cc
new file mode 100644 (file)
index 0000000..0cceb31
--- /dev/null
@@ -0,0 +1,44 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation, matrix-vector products as compared to
+// the same implementation with MeshWorker. This example uses a hypercube mesh
+// without any hanging nodes
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  tria.refine_global(5-dim);
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_01.output b/tests/matrix_free/matrix_vector_faces_01.output
new file mode 100644 (file)
index 0000000..07c965d
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_02.cc b/tests/matrix_free/matrix_vector_faces_02.cc
new file mode 100644 (file)
index 0000000..4441b99
--- /dev/null
@@ -0,0 +1,76 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation, matrix-vector products as compared to
+// the same implementation with MeshWorker. This example uses a hypercube mesh
+// with hanging nodes
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  if (dim < 3 || fe_degree < 2)
+    tria.refine_global(2);
+  else
+    tria.refine_global(1);
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active (),
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<1e-8)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  cell = tria.begin_active ();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.2)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<10-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // test with threads enabled as well
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, true);
+
+  // and finally a float test
+  do_test<dim, fe_degree, fe_degree+1, float> (dof, constraints);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_02.output b/tests/matrix_free/matrix_vector_faces_02.output
new file mode 100644 (file)
index 0000000..a01498e
--- /dev/null
@@ -0,0 +1,29 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d:float::Testing FE_DGQ<2>(1)
+DEAL:2d:float::Norm of difference:          0
+DEAL:2d:float::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d:float::Testing FE_DGQ<2>(2)
+DEAL:2d:float::Norm of difference:          0
+DEAL:2d:float::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d:float::Testing FE_DGQ<3>(1)
+DEAL:3d:float::Norm of difference:          0
+DEAL:3d:float::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d:float::Testing FE_DGQ<3>(2)
+DEAL:3d:float::Norm of difference:          0
+DEAL:3d:float::
diff --git a/tests/matrix_free/matrix_vector_faces_03.cc b/tests/matrix_free/matrix_vector_faces_03.cc
new file mode 100644 (file)
index 0000000..48ba9af
--- /dev/null
@@ -0,0 +1,73 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation, matrix-vector products as compared to
+// the same implementation with MeshWorker. This example uses a general mesh
+// with various cell types and hanging nodes
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  create_mesh (tria);
+
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  //if (fe_degree == 1)
+  //  tria.refine_global(1);
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<9-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // also test with threads
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_03.output b/tests/matrix_free/matrix_vector_faces_03.output
new file mode 100644 (file)
index 0000000..07c965d
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_04.cc b/tests/matrix_free/matrix_vector_faces_04.cc
new file mode 100644 (file)
index 0000000..e5515b4
--- /dev/null
@@ -0,0 +1,50 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation, matrix-vector products as compared to
+// the same implementation with MeshWorker. This example uses a hyperball mesh
+// with both hanging nodes and curved boundaries
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_ball (tria);
+  static const HyperBallBoundary<dim> boundary;
+  tria.set_boundary (0, boundary);
+  tria.refine_global(4-dim);
+  tria.begin_active()->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // test with threads enabled as well
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_04.output b/tests/matrix_free/matrix_vector_faces_04.output
new file mode 100644 (file)
index 0000000..07c965d
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_05.cc b/tests/matrix_free/matrix_vector_faces_05.cc
new file mode 100644 (file)
index 0000000..78eabaf
--- /dev/null
@@ -0,0 +1,47 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation, matrix-vector products as compared to
+// the same implementation with MeshWorker. Same as matrix_vector_faces_01 but
+// using FE_Q instead of FE_DGQ (i.e., we do not actually have any
+// contributions from interior faces but the algorithm should have get them to
+// zero)
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_q.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube (tria);
+  tria.refine_global(5-dim);
+
+  FE_Q<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // test with threads enabled as well
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_05.output b/tests/matrix_free/matrix_vector_faces_05.output
new file mode 100644 (file)
index 0000000..6dcc6a1
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_06.cc b/tests/matrix_free/matrix_vector_faces_06.cc
new file mode 100644 (file)
index 0000000..1d8f507
--- /dev/null
@@ -0,0 +1,69 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// same as matrix_vector_faces_03 (general mesh, various cell types, hanging
+// nodes), but using more quadrature points than fe_degree+1.
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  create_mesh (tria);
+
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<9-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  do_test<dim, fe_degree, fe_degree, double> (dof, constraints, true);
+  do_test<dim, fe_degree, fe_degree+2, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_06.output b/tests/matrix_free/matrix_vector_faces_06.output
new file mode 100644 (file)
index 0000000..5c89f98
--- /dev/null
@@ -0,0 +1,33 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_07.cc b/tests/matrix_free/matrix_vector_faces_07.cc
new file mode 100644 (file)
index 0000000..93b1e57
--- /dev/null
@@ -0,0 +1,74 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// same as matrix_vector_faces_03 but using a Lagrange polynomial based on
+// Gauss points rather than Gauss-Lobatto points where the mass matrix is
+// diagonal
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  create_mesh (tria);
+
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  if (fe_degree == 1)
+    tria.refine_global(1);
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<9-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQArbitraryNodes<dim> fe (QGauss<1>(fe_degree+1));
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // also test with threads
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_07.output b/tests/matrix_free/matrix_vector_faces_07.output
new file mode 100644 (file)
index 0000000..89be638
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQArbitraryNodes<2>(QGauss(2))
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQArbitraryNodes<2>(QGauss(3))
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQArbitraryNodes<3>(QGauss(2))
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQArbitraryNodes<3>(QGauss(3))
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_08.cc b/tests/matrix_free/matrix_vector_faces_08.cc
new file mode 100644 (file)
index 0000000..0980158
--- /dev/null
@@ -0,0 +1,74 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// same as matrix_vector_faces_03 but without setting a template on the
+// polynomial degree, i.e., we use the path "-1" of FEEvaluation that does
+// runtime expansion of loops
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  create_mesh (tria);
+
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  if (fe_degree == 1)
+    tria.refine_global(1);
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<9-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // also test with threads
+  do_test<dim, -1, 0, double> (dof, constraints, true);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_08.output b/tests/matrix_free/matrix_vector_faces_08.output
new file mode 100644 (file)
index 0000000..07c965d
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Norm of difference parallel: 0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Norm of difference parallel: 0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_09.cc b/tests/matrix_free/matrix_vector_faces_09.cc
new file mode 100644 (file)
index 0000000..0c39d10
--- /dev/null
@@ -0,0 +1,113 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_03 but we now compare against the combined
+// evaluation with gather_evaluate and integrate_scatter
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> tria;
+  create_mesh (tria);
+
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator cell, endc;
+  cell = tria.begin_active ();
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  if (fe_degree == 1)
+    tria.refine_global(1);
+  cell = tria.begin_active ();
+  for (unsigned int i=0; i<9-3*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (7-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+    }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  Vector<double> in (dof.n_dofs()), out (dof.n_dofs());
+  Vector<double> out_dist (out);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<dof.n_dofs(); ++i)
+    {
+      if (constraints.is_constrained(i))
+        continue;
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in(i) = entry;
+    }
+
+  MatrixFree<dim,double> mf_data;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  MatrixFreeTest<dim,fe_degree,fe_degree+1> mf (mf_data);
+  mf.vmult(out, in);
+
+  MatrixFreeVariant<dim,fe_degree,fe_degree+1> mf2(mf_data, false);
+  mf2.vmult(out_dist, in);
+  mf2.vmult(out_dist, in);
+
+  out_dist -= out;
+  const double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_09.output b/tests/matrix_free/matrix_vector_faces_09.output
new file mode 100644 (file)
index 0000000..190c597
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
diff --git a/tests/matrix_free/matrix_vector_faces_10.cc b/tests/matrix_free/matrix_vector_faces_10.cc
new file mode 100644 (file)
index 0000000..04ccedd
--- /dev/null
@@ -0,0 +1,110 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_09 but including MPI and a few different
+// variants for the loop
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by two to test cubic and quartic shape functions
+  // rather than linears and quadratics according to
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+2;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  if (dim == 2)
+    tria.refine_global(1);
+  {
+    typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active ();
+    typename Triangulation<dim>::active_cell_iterator endc = tria.end();
+    unsigned int counter = 0;
+    for (; cell!=endc; ++cell, ++counter)
+      if (cell->is_locally_owned() && counter % 3 == 0)
+        cell->set_refine_flag();
+    tria.execute_coarsening_and_refinement();
+  }
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+  MatrixFree<dim,double> mf_data;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+  mf_data.initialize_dof_vector(out_dist);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in.local_element(i) = entry;
+    }
+
+
+  MatrixFreeTest<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+  mf.vmult(out, in);
+
+  MatrixFreeVariant<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> >
+  mf2(mf_data, false);
+  mf2.vmult(out_dist, in);
+  mf2.vmult(out_dist, in);
+
+  out_dist -= out;
+
+  const double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_10.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/matrix_vector_faces_10.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..35f75eb
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(3)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Testing FE_DGQHermite<2>(4)
+DEAL:2d::Norm of difference:          0
+DEAL:3d::Testing FE_DGQHermite<3>(3)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Testing FE_DGQHermite<3>(4)
+DEAL:3d::Norm of difference:          0
diff --git a/tests/matrix_free/matrix_vector_faces_11.cc b/tests/matrix_free/matrix_vector_faces_11.cc
new file mode 100644 (file)
index 0000000..04a2969
--- /dev/null
@@ -0,0 +1,111 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_10 but using integrate_scatter in
+// matrix_vector_faces_common.h to zero the vector rather than doing it
+// outside.
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by two to test cubic and quartic shape functions
+  // rather than linears and quadratics according to
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+2;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  if (dim == 2)
+    tria.refine_global(1);
+  {
+    typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active ();
+    typename Triangulation<dim>::active_cell_iterator endc = tria.end();
+    unsigned int counter = 0;
+    for (; cell!=endc; ++cell, ++counter)
+      if (cell->is_locally_owned() && counter % 3 == 0)
+        cell->set_refine_flag();
+    tria.execute_coarsening_and_refinement();
+  }
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+  MatrixFree<dim,double> mf_data;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+  mf_data.initialize_dof_vector(out_dist);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in.local_element(i) = entry;
+    }
+
+
+  MatrixFreeTest<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+  mf.vmult(out, in);
+
+  MatrixFreeVariant<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> >
+  mf2(mf_data, false);
+  mf2.vmult(out_dist, in);
+  mf2.vmult(out_dist, in);
+
+  out_dist -= out;
+
+  const double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_11.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/matrix_vector_faces_11.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..35f75eb
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(3)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::Testing FE_DGQHermite<2>(4)
+DEAL:2d::Norm of difference:          0
+DEAL:3d::Testing FE_DGQHermite<3>(3)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::Testing FE_DGQHermite<3>(4)
+DEAL:3d::Norm of difference:          0
diff --git a/tests/matrix_free/matrix_vector_faces_12.cc b/tests/matrix_free/matrix_vector_faces_12.cc
new file mode 100644 (file)
index 0000000..e0f98b6
--- /dev/null
@@ -0,0 +1,256 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// tests matrix-free face evaluation, matrix-vector products as compared to
+// the same implementation with MeshWorker. This example uses a mesh described
+// through a complicated manifold
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+double f_x(double x_m)
+{
+  double x = x_m*1000.0;
+  double y_m = 0.0;
+
+  if (x <= 9.0)
+    y_m = 0.001*(-28.0 + std::min(28.0, 2.8e1 + 6.775070969851e-3*x*x - 2.124527775800e-3*x*x*x));
+
+  else if (x > 9.0 && x <= 14.0)
+    y_m = 0.001*(-28.0 + 2.507355893131e1 + 9.754803562315e-1*x - 1.016116352781e-1*x*x + 1.889794677828e-3*x*x*x);
+
+  else if (x > 14.0 && x <= 20.0)
+    y_m = 0.001*(-28.0 + 2.579601052357e1 + 8.206693007457e-1*x - 9.055370274339e-2*x*x + 1.626510569859e-3*x*x*x);
+
+  else if (x > 20.0 && x <= 30.0)
+    y_m = 0.001*(-28.0 + 4.046435022819e1 - 1.379581654948*x + 1.945884504128e-2*x*x - 2.070318932190e-4*x*x*x);
+
+  else if (x > 30.0 && x <= 40.0)
+    y_m = 0.001*(-28.0 + 1.792461334664e1 + 8.743920332081e-1*x - 5.567361123058e-2*x*x + 6.277731764683e-4*x*x*x);
+
+  else if (x > 40.0 && x <= 54.0)
+    y_m = 0.001*(-28.0 + std::max(0.0, 5.639011190988e1 - 2.010520359035*x + 1.644919857549e-2*x*x + 2.674976141766e-5*x*x*x));
+
+  else if (x > 54.0)
+    y_m = 0.001*(-28.0);
+
+  return y_m;
+}
+
+double gamma_x(double x_m)
+{
+  double xmod = x_m/0.028;
+  double gamma = 1.;
+  if (xmod >6.3 && xmod <=8.3)
+    {
+      xmod = 8.3 - xmod;
+      gamma = (-0.02*std::cos(xmod*numbers::PI)+1.02);
+    }
+  else if (xmod > 8.3) //move mesh closer to the wall to get a lower y+ value at the peak
+    {
+      xmod = 9. - xmod;
+      gamma = (-0.05*std::cos(xmod*numbers::PI*2./0.7)+1.05);
+    }
+  return 1.0*gamma;
+}
+
+
+
+template <int dim>
+class PeriodicHillManifold : public ChartManifold<dim>
+{
+public:
+  PeriodicHillManifold ()
+    :
+    ChartManifold<dim>(),
+    h     (0.028),
+    x_max (9.0*h),
+    y_max (2.036*h),
+    y_FoR (h)
+  {}
+
+  virtual std::unique_ptr<Manifold<dim> > clone() const override
+  {
+    return std_cxx14::make_unique<PeriodicHillManifold<dim> >();
+  }
+
+  virtual Point<dim> push_forward(const Point<dim> &xi) const override
+  {
+    Point<dim> x = xi;
+
+    const double gamma = gamma_x(xi[0]);
+    const double tanh_gamma = std::tanh(gamma);
+    double s_y = std::tanh(gamma*(2.0*((xi[1] - y_FoR)/y_max)-1.0))/tanh_gamma;
+    double t_y = std::tanh(gamma*(2.0*(1.0 - (xi[1] - y_FoR)/y_max)-1.0))/tanh_gamma;
+    if (xi[0] <= x_max/2.0)
+      x[1] = y_max/2.0*s_y+4.036*h/2.0 + (0.5*t_y + 0.5)*f_x(xi[0]);
+    // y_max/2.0*t_y+4.036*h/2.0
+    else if (xi[0] > x_max/2.0)
+      x[1] = y_max/2.0*s_y+4.036*h/2.0  + (0.5*t_y + 0.5)*f_x(x_max - xi[0]);
+
+    return x;
+  }
+
+  virtual Point<dim> pull_back(const Point<dim> &x) const override
+  {
+    Point<dim> xi = x;
+
+    // y component
+    unsigned int iter = 0;
+    unsigned int maxiter = 100;
+    double tol = 1.0e-14;
+    double eps = 1.;
+
+    // get a good estimate for Y (pullBack without stretching the cells)
+    double Y = 0.0;
+    if (x[0] <= x_max/2.0)
+      Y = (x[1] - f_x(x[0])*(1 + y_FoR/y_max))/(1.0 - f_x(x[0])/y_max);
+    else if (x[0] > x_max/2.0)
+      Y = (x[1] - f_x(x_max - x[0])*(1 + y_FoR/y_max))/(1.0 - f_x(x_max - x[0])/y_max);
+
+    if (x[0] <= x_max/2.0)
+      {
+        const double gamma = gamma_x(x[0]);
+        const double tanh_gamma = std::tanh(gamma);
+        while (eps > tol && iter < maxiter)
+          {
+            const double arg = gamma*(2.0*(1.0-(Y-y_FoR)/y_max)-1.0);
+            const double arg2 = gamma*(2.0*((Y-y_FoR)/y_max)-1.0);
+            const double t_y = std::tanh(arg)/tanh_gamma;
+            const double s_y = std::tanh(arg2)/tanh_gamma;
+            const double ts_y = 1.0/(std::cosh(arg)*std::cosh(arg))*gamma*(-2.0/y_max)/tanh_gamma;
+            const double ss_y = 1.0/(std::cosh(arg2)*std::cosh(arg2))*gamma*(2.0/y_max)/tanh_gamma;
+            const double Yn = Y - (y_max/2.0*s_y+4.036*h/2.0 + (0.5*t_y + 0.5)*f_x(x[0]) -x[1])
+                              / (y_max/2.0*ss_y  + 0.5*ts_y*f_x(x[0]));
+
+            eps = std::abs(Yn-Y);
+            Y = Yn;
+            iter++;
+          }
+        AssertThrow(iter < maxiter,
+                    ExcMessage("Newton within PullBack did not find the solution. "));
+        xi[1] = Y;
+      }
+    else if (x[0] > x_max/2.0)
+      {
+        const double gamma = gamma_x(x[0]);
+        const double tanh_gamma = std::tanh(gamma);
+        while (eps > tol && iter < maxiter)
+          {
+            const double arg = gamma*(2.0*(1.0-(Y-y_FoR)/y_max)-1.0);
+            const double arg2 = gamma*(2.0*((Y-y_FoR)/y_max)-1.0);
+            const double t_y = std::tanh(arg)/tanh_gamma;
+            const double s_y = std::tanh(arg2)/tanh_gamma;
+            const double ts_y = 1.0/(std::cosh(arg)*std::cosh(arg))*gamma*(-2.0/y_max)/tanh_gamma;
+            const double ss_y = 1.0/(std::cosh(arg2)*std::cosh(arg2))*gamma*(2.0/y_max)/tanh_gamma;
+            const double Yn = Y - (y_max/2.0*s_y+4.036*h/2.0 + (0.5*t_y + 0.5)*f_x(x_max - x[0]) -x[1])
+                              / (y_max/2.0*ss_y  + 0.5*ts_y*f_x(x_max - x[0]));
+
+            eps = std::abs(Yn-Y);
+            Y = Yn;
+            iter++;
+          }
+        AssertThrow(iter < maxiter,
+                    ExcMessage("Newton within PullBack did not find the solution. "));
+        xi[1] = Y;
+      }
+    return xi;
+  }
+
+private:
+  const double h = 0.028;
+
+  // data from initial block
+  const double x_max = 9.0*h;//9.0*h;
+  const double y_max = 2.036*h;
+
+  const double y_FoR = h;
+};
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  Triangulation<dim> triangulation;
+  /* --------------- Generate grid ------------------- */
+  const double h = 0.028;
+  Point<dim> coordinates;
+  coordinates[0] = 9.0*h;//9.0*h;
+  coordinates[1] = 3.036*h;//2.036*h;
+  if (dim == 3)
+    coordinates[2] = 2.25*h;//4.5*h;
+  std::vector<unsigned int> refinements(dim, 1);
+  refinements[0] = 2;
+
+  // start with a cube
+  Point<dim> p;
+  p[0] = 0.;
+  p[1] = h;
+  if (dim==3)
+    p[2] = -2.25*h;
+
+  GridGenerator::subdivided_hyper_rectangle (triangulation,refinements,p,coordinates);
+
+  triangulation.last()->vertex(0)[1] = 0.;
+  if (dim==3)
+    triangulation.last()->vertex(4)[1] = 0.;
+  // boundary ids for refinements[0] = 2:
+  //periodicity in x-direction
+  //add 10 to avoid conflicts with dirichlet boundary, which is 0
+  triangulation.begin()->face(0)->set_all_boundary_ids(0+10);
+  triangulation.last()->face(1)->set_all_boundary_ids(1+10);
+
+  //periodicity in z-direction, if dim==3
+  if (dim == 3)
+    {
+      triangulation.begin()->face(4)->set_all_boundary_ids(2+10);
+      triangulation.begin()->face(5)->set_all_boundary_ids(3+10);
+      triangulation.last()->face(4)->set_all_boundary_ids(2+10);
+      triangulation.last()->face(5)->set_all_boundary_ids(3+10);
+    }
+
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> > periodic_faces;
+  GridTools::collect_periodic_faces(triangulation, 0+10, 1+10, 0, periodic_faces);
+  if (dim == 3)
+    {
+      GridTools::collect_periodic_faces(triangulation, 2+10, 3+10, 2, periodic_faces);
+    }
+
+  triangulation.add_periodicity(periodic_faces);
+  triangulation.set_all_manifold_ids(111);
+
+  static PeriodicHillManifold<dim> manifold;
+  triangulation.set_manifold(111, manifold);
+  triangulation.refine_global(2);
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (triangulation);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  // cannot test threads right now
+  do_test<dim, fe_degree, fe_degree+1, double> (dof, constraints, false);
+}
diff --git a/tests/matrix_free/matrix_vector_faces_12.output b/tests/matrix_free/matrix_vector_faces_12.output
new file mode 100644 (file)
index 0000000..a388fab
--- /dev/null
@@ -0,0 +1,13 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Norm of difference:          0
+DEAL:2d::
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Norm of difference:          0
+DEAL:3d::
diff --git a/tests/matrix_free/matrix_vector_faces_13.cc b/tests/matrix_free/matrix_vector_faces_13.cc
new file mode 100644 (file)
index 0000000..b777e1e
--- /dev/null
@@ -0,0 +1,121 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_11 but using a renumbering of degrees of
+// freedom for better vectorized access
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by two to test cubic and quartic shape functions
+  // rather than linears and quadratics according to
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+2;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  if (dim == 2)
+    tria.refine_global(1);
+  {
+    typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active ();
+    typename Triangulation<dim>::active_cell_iterator endc = tria.end();
+    unsigned int counter = 0;
+    for (; cell!=endc; ++cell, ++counter)
+      if (cell->is_locally_owned() && counter % 3 == 0)
+        cell->set_refine_flag();
+    tria.execute_coarsening_and_refinement();
+  }
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+  MatrixFree<dim,double> mf_data;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+  data.initialize_mapping = false;
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  std::vector<types::global_dof_index> renumbering;
+  mf_data.renumber_dofs(renumbering);
+  dof.renumber_dofs(renumbering);
+
+  data.initialize_mapping = true;
+  mf_data.reinit(mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+  mf_data.initialize_dof_vector(out_dist);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in.local_element(i) = entry;
+    }
+
+  MatrixFreeTest<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+  mf.vmult(out, in);
+
+  MatrixFreeVariant<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf2(mf_data);
+  mf2.vmult(out_dist, in);
+
+  out_dist -= out;
+
+  double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << " ";
+
+  // test again, now doing matrix-vector product twice
+  mf2.vmult(out_dist, in);
+  mf2.vmult(out_dist, in);
+  out_dist -= out;
+  diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_13.with_mpi=true.with_p4est=true.mpirun=1.output b/tests/matrix_free/matrix_vector_faces_13.with_mpi=true.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..8568b9d
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(3)
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(4)
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3)
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(4)
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_13.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/matrix_vector_faces_13.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..8568b9d
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(3)
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(4)
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3)
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(4)
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_14.cc b/tests/matrix_free/matrix_vector_faces_14.cc
new file mode 100644 (file)
index 0000000..217f7f4
--- /dev/null
@@ -0,0 +1,127 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_13 (renumbering of degrees of freedom to
+// better vectorized access, gather_evaluate and integrate_scatter) but on a
+// different mesh that can trigger different element types
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/distributed/tria.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by one to test quadratic and cubic shape functions
+  // rather than linears and quadratics according to the main function in
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+1;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria, -1, 1);
+
+  for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
+       cell != tria.end(); ++cell)
+    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+      if (cell->at_boundary(f))
+        cell->face(f)->set_all_boundary_ids(f);
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> > periodic_faces;
+  for (unsigned int d=0; d<dim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(3-dim);
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  for (unsigned int test=0; test<2; ++test)
+    {
+      tria.refine_global(1);
+
+      dof.distribute_dofs(fe);
+
+      deallog << "Testing " << dof.get_fe().get_name();
+      deallog << " on " << dof.n_dofs() << " DoFs";
+      deallog << std::endl;
+
+      MappingQGeneric<dim> mapping(dof.get_fe().degree+1);
+
+      LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+      MatrixFree<dim,double> mf_data;
+      const QGauss<1> quad (fe_degree+1);
+      typename MatrixFree<dim,double>::AdditionalData data;
+      data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+      data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+      data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+      data.initialize_mapping = false;
+
+      mf_data.reinit (mapping, dof, constraints, quad, data);
+
+      std::vector<types::global_dof_index> renumbering;
+      mf_data.renumber_dofs(renumbering);
+      dof.renumber_dofs(renumbering);
+
+      data.initialize_mapping = true;
+      mf_data.reinit(mapping, dof, constraints, quad, data);
+
+      mf_data.initialize_dof_vector(in);
+      mf_data.initialize_dof_vector(out);
+      mf_data.initialize_dof_vector(out_dist);
+
+      // Set random seed for reproducibility
+      Testing::srand(42);
+      for (unsigned int i=0; i<in.local_size(); ++i)
+        {
+          const double entry = Testing::rand()/(double)RAND_MAX;
+          in.local_element(i) = entry;
+        }
+
+      MatrixFreeTest<dim,fe_degree,fe_degree+1,double,
+                     LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+      mf.vmult(out, in);
+
+      MatrixFreeVariant<dim,fe_degree,fe_degree+1,double,
+                        LinearAlgebra::distributed::Vector<double> > mf2(mf_data);
+      mf2.vmult(out_dist, in);
+
+      out_dist -= out;
+
+      double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference:          " << diff_norm << " ";
+
+      // test again, now doing matrix-vector product twice
+      mf2.vmult(out_dist, in);
+      mf2.vmult(out_dist, in);
+      out_dist -= out;
+      diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << diff_norm << std::endl;
+    }
+}
diff --git a/tests/matrix_free/matrix_vector_faces_14.with_mpi=true.with_p4est=true.mpirun=2.output b/tests/matrix_free/matrix_vector_faces_14.with_mpi=true.with_p4est=true.mpirun=2.output
new file mode 100644 (file)
index 0000000..bf136d0
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(2) on 144 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(2) on 576 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(3) on 256 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(3) on 1024 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(2) on 216 DoFs
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(2) on 1728 DoFs
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3) on 512 DoFs
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3) on 4096 DoFs
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_14.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/matrix_vector_faces_14.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..bf136d0
--- /dev/null
@@ -0,0 +1,17 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(2) on 144 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(2) on 576 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(3) on 256 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(3) on 1024 DoFs
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(2) on 216 DoFs
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(2) on 1728 DoFs
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3) on 512 DoFs
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3) on 4096 DoFs
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_15.cc b/tests/matrix_free/matrix_vector_faces_15.cc
new file mode 100644 (file)
index 0000000..62bf3a5
--- /dev/null
@@ -0,0 +1,134 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_13 but for advection operator rather than
+// Poisson
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by two to test cubic and quartic shape functions
+  // rather than linears and quadratics according to
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+2;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  if (dim == 2)
+    tria.refine_global(1);
+  {
+    typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active ();
+    typename Triangulation<dim>::active_cell_iterator endc = tria.end();
+    unsigned int counter = 0;
+    for (; cell!=endc; ++cell, ++counter)
+      if (cell->is_locally_owned() && counter % 3 == 0)
+        cell->set_refine_flag();
+    tria.execute_coarsening_and_refinement();
+  }
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof_orig (tria);
+  DoFHandler<dim> dof (tria);
+  dof_orig.distribute_dofs(fe);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, in_orig, out, out_orig;
+
+  // create MatrixFree with DoFHandler in original numbering
+  MatrixFree<dim,double> mf_data_orig;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+  data.initialize_mapping = true;
+
+  mf_data_orig.reinit (mapping, dof_orig, constraints, quad, data);
+  mf_data_orig.initialize_dof_vector(in_orig);
+  mf_data_orig.initialize_dof_vector(out_orig);
+
+  // create MatrixFree with renumbered degrees of freedom
+  MatrixFree<dim,double> mf_data;
+  data.initialize_mapping = false;
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  std::vector<types::global_dof_index> renumbering;
+  mf_data.renumber_dofs(renumbering);
+  dof.renumber_dofs(renumbering);
+
+  data.initialize_mapping = true;
+  mf_data.reinit(mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in_orig.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in_orig.local_element(i) = entry;
+      in(renumbering[i]) = entry;
+    }
+
+  MatrixFreeAdvection<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data_orig);
+  mf.vmult(out_orig, in_orig);
+
+  MatrixFreeAdvection<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf2(mf_data);
+  mf2.vmult(out, in);
+
+  for (unsigned int i=0; i<out.local_size(); ++i)
+    out(renumbering[i]) -= out_orig.local_element(i);
+
+  double diff_norm = out.linfty_norm() / out_orig.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << " ";
+
+  // test again, now doing matrix-vector product twice
+  mf2.vmult(out, in);
+  mf2.vmult(out, in);
+  for (unsigned int i=0; i<out.local_size(); ++i)
+    out(renumbering[i]) -= out_orig.local_element(i);
+  diff_norm = out.linfty_norm() / out_orig.linfty_norm();
+  deallog << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_15.with_mpi=true.with_p4est=true.mpirun=1.output b/tests/matrix_free/matrix_vector_faces_15.with_mpi=true.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..1e1589d
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQ<3>(3)
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQ<3>(4)
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_15.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/matrix_vector_faces_15.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..1e1589d
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQ<2>(3)
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQ<2>(4)
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQ<3>(3)
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQ<3>(4)
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_16.cc b/tests/matrix_free/matrix_vector_faces_16.cc
new file mode 100644 (file)
index 0000000..2804e5d
--- /dev/null
@@ -0,0 +1,112 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_13 but using another mesh that triggers a
+// more difficult case in terms of the numbers in the mesh
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  // only run linears in 3D
+
+  if (dim == 2 || fe_degree > 1)
+    return;
+
+  constexpr unsigned int mydim = 3;
+
+  parallel::distributed::Triangulation<mydim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube (tria);
+  for (unsigned int f=0; f<GeometryInfo<mydim>::faces_per_cell; ++f)
+    tria.begin_active()->face(f)->set_all_boundary_ids(f);
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<mydim>::cell_iterator> > periodic_faces;
+  for (unsigned int d=0; d<mydim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(4);
+  std::cout << "Number of cells: " << tria.n_global_active_cells() << std::endl;
+
+  FE_DGQ<mydim> fe (1);
+  DoFHandler<mydim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  LinearAlgebra::distributed::Vector<double> in, out, in2, out2;
+
+  MatrixFree<mydim,double> mf_data;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<mydim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<mydim,double>::AdditionalData::none;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  mf_data.reinit (dof, constraints, quad, data);
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in.local_element(i) = entry;
+    }
+
+  MatrixFreeTest<3,1,2,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+  mf.vmult(out, in);
+
+  std::vector<types::global_dof_index> renumbering;
+  mf_data.renumber_dofs(renumbering);
+  dof.renumber_dofs(renumbering);
+
+  mf_data.reinit(dof, constraints, quad, data);
+  mf_data.initialize_dof_vector(in2);
+  mf_data.initialize_dof_vector(out2);
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    {
+      in2(renumbering[i]) = in.local_element(i);
+    }
+
+  mf.vmult(out2, in2);
+
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    out2(renumbering[i]) -= out.local_element(i);
+
+  double diff_norm = out2.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_16.with_mpi=true.with_p4est=true.mpirun=11.output b/tests/matrix_free/matrix_vector_faces_16.with_mpi=true.with_p4est=true.mpirun=11.output
new file mode 100644 (file)
index 0000000..d54d92d
--- /dev/null
@@ -0,0 +1,3 @@
+
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0
diff --git a/tests/matrix_free/matrix_vector_faces_17.cc b/tests/matrix_free/matrix_vector_faces_17.cc
new file mode 100644 (file)
index 0000000..2839f3d
--- /dev/null
@@ -0,0 +1,129 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_15 except FE_DGQArbitraryNodes rather than
+// FE_DGQ
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  if (dim == 2)
+    tria.refine_global(1);
+  {
+    typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active ();
+    typename Triangulation<dim>::active_cell_iterator endc = tria.end();
+    unsigned int counter = 0;
+    for (; cell!=endc; ++cell, ++counter)
+      if (cell->is_locally_owned() && counter % 3 == 0)
+        cell->set_refine_flag();
+    tria.execute_coarsening_and_refinement();
+  }
+
+  FE_DGQArbitraryNodes<dim> fe (QGauss<1>(fe_degree+1));
+  DoFHandler<dim> dof_orig (tria);
+  DoFHandler<dim> dof (tria);
+  dof_orig.distribute_dofs(fe);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, in_orig, out, out_orig;
+
+  // create MatrixFree with DoFHandler in original numbering
+  MatrixFree<dim,double> mf_data_orig;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+  data.initialize_mapping = true;
+
+  mf_data_orig.reinit (mapping, dof_orig, constraints, quad, data);
+  mf_data_orig.initialize_dof_vector(in_orig);
+  mf_data_orig.initialize_dof_vector(out_orig);
+
+  // create MatrixFree with renumbered degrees of freedom
+  MatrixFree<dim,double> mf_data;
+  data.initialize_mapping = false;
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  std::vector<types::global_dof_index> renumbering;
+  mf_data.renumber_dofs(renumbering);
+  dof.renumber_dofs(renumbering);
+
+  data.initialize_mapping = true;
+  mf_data.reinit(mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in_orig.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in_orig.local_element(i) = entry;
+      in(renumbering[i]) = entry;
+    }
+
+  MatrixFreeAdvection<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data_orig);
+  mf.vmult(out_orig, in_orig);
+
+  MatrixFreeAdvection<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf2(mf_data);
+  mf2.vmult(out, in);
+
+  for (unsigned int i=0; i<out.local_size(); ++i)
+    out(renumbering[i]) -= out_orig.local_element(i);
+
+  double diff_norm = out.linfty_norm() / out_orig.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << " ";
+
+  // test again, now doing matrix-vector product twice
+  mf2.vmult(out, in);
+  mf2.vmult(out, in);
+  for (unsigned int i=0; i<out.local_size(); ++i)
+    out(renumbering[i]) -= out_orig.local_element(i);
+  diff_norm = out.linfty_norm() / out_orig.linfty_norm();
+  deallog << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_17.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/matrix_vector_faces_17.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..c55523d
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQArbitraryNodes<2>(QGauss(2))
+DEAL:2d::Norm of difference:          0.00 0.00
+DEAL:2d::Testing FE_DGQArbitraryNodes<2>(QGauss(3))
+DEAL:2d::Norm of difference:          0.00 0.00
+DEAL:3d::Testing FE_DGQArbitraryNodes<3>(QGauss(2))
+DEAL:3d::Norm of difference:          0.00 0.00
+DEAL:3d::Testing FE_DGQArbitraryNodes<3>(QGauss(3))
+DEAL:3d::Norm of difference:          0.00 0.00
diff --git a/tests/matrix_free/matrix_vector_faces_18.cc b/tests/matrix_free/matrix_vector_faces_18.cc
new file mode 100644 (file)
index 0000000..f5b5c6e
--- /dev/null
@@ -0,0 +1,210 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// same as matrix_vector_faces_15 except for a larger mesh
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  if (fe_degree > 1)
+    return;
+
+  const double h = 1;
+  const double Lx = 30*h;
+  const double Li = 10*h;
+  const double Ly = 6*h;
+  const double Lz = 4*h;
+  const double ER = Ly / (Ly-h);
+  Triangulation<dim> left, right, bottom, temp;
+  Point<dim> left_one, left_two, right_one, right_two, bottom_one, bottom_two;
+
+  left_one[0] = -Li;
+  left_one[1] = h;
+
+  left_two[0] = 0;
+  left_two[1] = Ly;
+
+  right_one[0] = 0;
+  right_one[1] = h;
+
+  right_two[0] = Lx-Li;
+  right_two[1] = Ly;
+
+  bottom_one[0] = 0;
+  bottom_one[1] = 0;
+
+  bottom_two[0] = Lx-Li;
+  bottom_two[1] = h;
+
+  if (dim == 3)
+    {
+      left_one[2] = 0;
+      right_one[2] = 0;
+      bottom_one[2] = 0;
+      left_two[2] = Lz;
+      right_two[2] = Lz;
+      bottom_two[2] = Lz;
+    }
+
+  std::vector<unsigned int> refinements_left(dim, 1);
+  std::vector<unsigned int> refinements_right(dim, 1);
+  std::vector<unsigned int> refinements_bottom(dim, 1);
+
+  refinements_left[1] = 5;
+  refinements_right[1] = 5;
+  refinements_bottom[1] = 1;
+  refinements_left[2] = 4;
+  refinements_right[2] = 4;
+  refinements_bottom[2] = 4;
+  refinements_left[0] = 10;
+  refinements_right[0] = 20;
+  refinements_bottom[0] = 20;
+
+  GridGenerator::subdivided_hyper_rectangle(left, refinements_left,left_one,left_two,false);
+  GridGenerator::subdivided_hyper_rectangle(right, refinements_right,right_one,right_two,false);
+  GridGenerator::subdivided_hyper_rectangle(bottom, refinements_bottom,bottom_one,bottom_two,false);
+
+  GridGenerator::merge_triangulations (left, right, temp);
+
+  parallel::distributed::Triangulation<dim> triangulation(MPI_COMM_WORLD,
+                                                          Triangulation<dim>::limit_level_difference_at_vertices,
+                                                          parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy);
+
+  GridGenerator::merge_triangulations (temp, bottom, triangulation);
+
+  if (dim == 3)
+    for (typename Triangulation<dim>::active_cell_iterator cell=triangulation.begin(); cell != triangulation.end(); ++cell)
+      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+        if (cell->face(f)->at_boundary())
+          {
+            if (std::abs(cell->face(f)->center()[2])< 1e-12)
+              cell->face(f)->set_all_boundary_ids(10);
+            else if (std::abs(cell->face(f)->center()[2] - Lz)< 1e-12)
+              cell->face(f)->set_all_boundary_ids(11);
+            else if (std::abs(cell->face(f)->center()[1] - h)< 1e-12)
+              cell->face(f)->set_all_boundary_ids(0);
+            else if (std::abs(cell->face(f)->center()[1])< 1e-12)
+              cell->face(f)->set_all_boundary_ids(0);
+            else if (std::abs(cell->face(f)->center()[0])< 1e-12)
+              cell->face(f)->set_all_boundary_ids(0);
+            else if (std::abs(cell->face(f)->center()[1] - Ly)< 1e-12)
+              cell->face(f)->set_all_boundary_ids(3);
+            else if (std::abs(cell->face(f)->center()[0] + Li)< 1e-12)
+              cell->face(f)->set_all_boundary_ids(1);
+            else if (std::abs(cell->face(f)->center()[0] - (Lx-Li))< 1e-12)
+              cell->face(f)->set_all_boundary_ids(2);
+          }
+
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> >
+  periodic_faces;
+
+  if (dim == 3)
+    {
+      GridTools::collect_periodic_faces(triangulation, 10, 11, 2, periodic_faces);
+      triangulation.add_periodicity(periodic_faces);
+    }
+
+  FE_DGQ<dim> fe(fe_degree);
+  DoFHandler<dim> dof_orig (triangulation);
+  DoFHandler<dim> dof (triangulation);
+  dof_orig.distribute_dofs(fe);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, in_orig, out, out_orig;
+
+  // create MatrixFree with DoFHandler in original numbering
+  MatrixFree<dim,double> mf_data_orig;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+  data.initialize_mapping = true;
+
+  mf_data_orig.reinit (mapping, dof_orig, constraints, quad, data);
+  mf_data_orig.initialize_dof_vector(in_orig);
+  mf_data_orig.initialize_dof_vector(out_orig);
+
+  // create MatrixFree with renumbered degrees of freedom
+  MatrixFree<dim,double> mf_data;
+  data.initialize_mapping = false;
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  std::vector<types::global_dof_index> renumbering;
+  mf_data.renumber_dofs(renumbering);
+  dof.renumber_dofs(renumbering);
+
+  data.initialize_mapping = true;
+  mf_data.reinit(mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in_orig.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in_orig.local_element(i) = entry;
+      in(renumbering[i]) = entry;
+    }
+
+  MatrixFreeAdvection<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data_orig);
+  mf.vmult(out_orig, in_orig);
+
+  MatrixFreeAdvection<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf2(mf_data);
+  mf2.vmult(out, in);
+
+  for (unsigned int i=0; i<out.local_size(); ++i)
+    out(renumbering[i]) -= out_orig.local_element(i);
+
+  double diff_norm = out.linfty_norm() / out_orig.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << " ";
+
+  // test again, now doing matrix-vector product twice
+  mf2.vmult(out, in);
+  mf2.vmult(out, in);
+  for (unsigned int i=0; i<out.local_size(); ++i)
+    out(renumbering[i]) -= out_orig.local_element(i);
+  diff_norm = out.linfty_norm() / out_orig.linfty_norm();
+  deallog << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_18.with_mpi=true.with_p4est=true.mpirun=4.output b/tests/matrix_free/matrix_vector_faces_18.with_mpi=true.with_p4est=true.mpirun=4.output
new file mode 100644 (file)
index 0000000..aa34fe5
--- /dev/null
@@ -0,0 +1,5 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Norm of difference:          0.00 0.00
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference:          0.00 0.00
diff --git a/tests/matrix_free/matrix_vector_faces_19.cc b/tests/matrix_free/matrix_vector_faces_19.cc
new file mode 100644 (file)
index 0000000..23aa1db
--- /dev/null
@@ -0,0 +1,124 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// similar to matrix_vector_faces_13 (integrate_scatter, renumbered degrees of
+// freedom) but testing a vmult_add operation
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/distributed/tria.h>
+#include "create_mesh.h"
+#include <deal.II/grid/grid_tools.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by two to test cubic and quartic shape functions
+  // rather than linears and quadratics according to
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+2;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  create_mesh (tria);
+
+  if (dim == 2)
+    tria.refine_global(1);
+  {
+    typename Triangulation<dim>::active_cell_iterator cell = tria.begin_active ();
+    typename Triangulation<dim>::active_cell_iterator endc = tria.end();
+    unsigned int counter = 0;
+    for (; cell!=endc; ++cell, ++counter)
+      if (cell->is_locally_owned() && counter % 3 == 0)
+        cell->set_refine_flag();
+    tria.execute_coarsening_and_refinement();
+  }
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  dof.distribute_dofs(fe);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQ<dim> mapping(dof.get_fe().degree+1);
+
+  LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+  MatrixFree<dim,double> mf_data;
+  const QGauss<1> quad (fe_degree+1);
+  typename MatrixFree<dim,double>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+  data.initialize_mapping = false;
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  std::vector<types::global_dof_index> renumbering;
+  mf_data.renumber_dofs(renumbering);
+  dof.renumber_dofs(renumbering);
+
+  data.initialize_mapping = true;
+  mf_data.reinit(mapping, dof, constraints, quad, data);
+
+  mf_data.initialize_dof_vector(in);
+  mf_data.initialize_dof_vector(out);
+  mf_data.initialize_dof_vector(out_dist);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<in.local_size(); ++i)
+    {
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in.local_element(i) = entry;
+    }
+
+
+  MatrixFreeTest<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf (mf_data);
+  mf.vmult(out, in);
+
+  MatrixFreeVariant<dim,fe_degree,fe_degree+1,double,LinearAlgebra::distributed::Vector<double> > mf2(mf_data);
+  mf2.vmult_add(out_dist, in);
+
+  out_dist -= out;
+
+  double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << " ";
+
+  // test again, now doing a matrix-vector product and then an add, which
+  // should give twice the reference result
+  mf2.vmult(out_dist, in);
+  mf2.vmult_add(out_dist, in);
+  out_dist -= out;
+  out_dist -= out;
+  diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << diff_norm << std::endl;
+}
diff --git a/tests/matrix_free/matrix_vector_faces_19.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/matrix_vector_faces_19.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..8568b9d
--- /dev/null
@@ -0,0 +1,9 @@
+
+DEAL:2d::Testing FE_DGQHermite<2>(3)
+DEAL:2d::Norm of difference:          0 0
+DEAL:2d::Testing FE_DGQHermite<2>(4)
+DEAL:2d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(3)
+DEAL:3d::Norm of difference:          0 0
+DEAL:3d::Testing FE_DGQHermite<3>(4)
+DEAL:3d::Norm of difference:          0 0
diff --git a/tests/matrix_free/matrix_vector_faces_20.cc b/tests/matrix_free/matrix_vector_faces_20.cc
new file mode 100644 (file)
index 0000000..3e5bcb1
--- /dev/null
@@ -0,0 +1,200 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// extension of matrix_vector_faces_14 (gather_evaluate and integrate_scatter)
+// to the vector-valued case in form of multiple components with different
+// vector entries but otherwise similar setup. this test differs from
+// matrix_vector_faces_21 only by not applying a renumbering
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/distributed/tria.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by one to test quadratic and cubic shape functions
+  // rather than linears and quadratics according to the main function in
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+1;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria, -1, 1);
+
+  for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
+       cell != tria.end(); ++cell)
+    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+      if (cell->at_boundary(f))
+        cell->face(f)->set_all_boundary_ids(f);
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> > periodic_faces;
+  for (unsigned int d=0; d<dim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(3-dim);
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  FESystem<dim> fe_system(fe, dim);
+  DoFHandler<dim> dof (tria);
+  DoFHandler<dim> dof_system (tria);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  for (unsigned int test=0; test<3; ++test)
+    {
+      tria.refine_global(1);
+
+      dof.distribute_dofs(fe);
+      dof_system.distribute_dofs(fe_system);
+
+      deallog << "Testing " << dof_system.get_fe().get_name();
+      deallog << " on " << dof_system.n_dofs() << " DoFs";
+      deallog << std::endl;
+
+      // first build a vector-valued system that contains all components in
+      // analogy to matrix_vector_faces_14
+      LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+      MatrixFree<dim,double> mf_data;
+      const QGauss<1> quad (fe_degree+2);
+      typename MatrixFree<dim,double>::AdditionalData data;
+      data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+      data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+      data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+      mf_data.reinit (dof_system, constraints, quad, data);
+
+      mf_data.initialize_dof_vector(in);
+      mf_data.initialize_dof_vector(out);
+      mf_data.initialize_dof_vector(out_dist);
+
+      // Set random seed for reproducibility
+      Testing::srand(42);
+      for (unsigned int i=0; i<in.local_size(); ++i)
+        {
+          const double entry = Testing::rand()/(double)RAND_MAX;
+          in.local_element(i) = entry;
+        }
+
+      MatrixFreeTest<dim,fe_degree,fe_degree+2,double,
+                     LinearAlgebra::distributed::Vector<double>, dim> mf (mf_data);
+      mf.vmult(out, in);
+
+      MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                        LinearAlgebra::distributed::Vector<double>, dim> mf2(mf_data, true);
+      mf2.vmult(out_dist, in);
+
+      out_dist -= out;
+
+      double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference to no-gather:         " << diff_norm << std::endl;
+
+      // now compare the result to a scalar implementation on each of the dim
+      // components, using vmult_add in subsequent steps
+      mf2.vmult(out, in);
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, d);
+          if (d==0)
+            mf3.vmult(out_dist, in);
+          else
+            mf3.vmult_add(out_dist, in);
+        }
+
+      out_dist -= out;
+      diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference to sum of scalar:     " << diff_norm << std::endl;
+
+      if (dim == 3)
+        {
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 2> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data, true, 2);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to vector/scalar sum: " << diff_norm << std::endl;
+        }
+      if (dim == 3)
+        {
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 2> mf4(mf_data, true, 1);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to scalar/vector sum: " << diff_norm << std::endl;
+        }
+
+      // finally compare to a series of scalar problems
+      MatrixFree<dim,double> mf_data_scalar;
+      mf_data_scalar.reinit (dof, constraints, quad, data);
+
+      LinearAlgebra::distributed::Vector<double> in_small, out_small, ref_small;
+      mf_data_scalar.initialize_dof_vector(in_small);
+      mf_data_scalar.initialize_dof_vector(out_small);
+      mf_data_scalar.initialize_dof_vector(ref_small);
+
+      MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                        LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data_scalar, true);
+
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          std::vector<types::global_dof_index> dof_indices_system(fe_system.dofs_per_cell);
+          std::vector<types::global_dof_index> dof_indices_scalar(fe.dofs_per_cell);
+          for (typename DoFHandler<dim>::active_cell_iterator cell_scalar=dof.begin_active(),
+               cell_system=dof_system.begin_active(); cell_scalar != dof.end();
+               ++cell_scalar, ++cell_system)
+            if (cell_scalar->is_locally_owned())
+              {
+                cell_scalar->get_dof_indices(dof_indices_scalar);
+                cell_system->get_dof_indices(dof_indices_system);
+                for (unsigned int i=0; i<fe_system.dofs_per_cell; ++i)
+                  if (fe_system.system_to_component_index(i).first == d)
+                    {
+                      in_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        in(dof_indices_system[i]);
+                      out_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        out(dof_indices_system[i]);
+                    }
+              }
+
+          mf4.vmult(ref_small, in_small);
+
+          out_small -= ref_small;
+          diff_norm = out_small.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to single scalar:     " << diff_norm << std::endl;
+        }
+    }
+}
diff --git a/tests/matrix_free/matrix_vector_faces_20.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/matrix_vector_faces_20.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..09273f8
--- /dev/null
@@ -0,0 +1,79 @@
+
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(2)^2] on 288 DoFs
+DEAL:2d::Norm of difference to no-gather:         0.00
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(2)^2] on 1152 DoFs
+DEAL:2d::Norm of difference to no-gather:         1.24e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     6.18e-17
+DEAL:2d::Norm of difference to single scalar:     1.24e-16
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(2)^2] on 4608 DoFs
+DEAL:2d::Norm of difference to no-gather:         2.28e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.14e-16
+DEAL:2d::Norm of difference to single scalar:     2.28e-16
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(3)^2] on 512 DoFs
+DEAL:2d::Norm of difference to no-gather:         1.94e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.94e-16
+DEAL:2d::Norm of difference to single scalar:     6.45e-17
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(3)^2] on 2048 DoFs
+DEAL:2d::Norm of difference to no-gather:         2.30e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.73e-16
+DEAL:2d::Norm of difference to single scalar:     2.30e-16
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(3)^2] on 8192 DoFs
+DEAL:2d::Norm of difference to no-gather:         2.27e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.14e-16
+DEAL:2d::Norm of difference to single scalar:     1.14e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(2)^3] on 648 DoFs
+DEAL:3d::Norm of difference to no-gather:         2.19e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     1.10e-16
+DEAL:3d::Norm of difference to single scalar:     2.19e-16
+DEAL:3d::Norm of difference to single scalar:     1.10e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(2)^3] on 5184 DoFs
+DEAL:3d::Norm of difference to no-gather:         7.55e-17
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     7.55e-17
+DEAL:3d::Norm of difference to single scalar:     7.55e-17
+DEAL:3d::Norm of difference to single scalar:     7.55e-17
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(2)^3] on 41472 DoFs
+DEAL:3d::Norm of difference to no-gather:         1.35e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     1.35e-16
+DEAL:3d::Norm of difference to single scalar:     3.37e-16
+DEAL:3d::Norm of difference to single scalar:     2.02e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(3)^3] on 1536 DoFs
+DEAL:3d::Norm of difference to no-gather:         1.52e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     1.52e-16
+DEAL:3d::Norm of difference to single scalar:     1.52e-16
+DEAL:3d::Norm of difference to single scalar:     1.52e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(3)^3] on 12288 DoFs
+DEAL:3d::Norm of difference to no-gather:         2.98e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     2.98e-16
+DEAL:3d::Norm of difference to single scalar:     7.44e-17
+DEAL:3d::Norm of difference to single scalar:     7.44e-17
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(3)^3] on 98304 DoFs
+DEAL:3d::Norm of difference to no-gather:         2.65e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     2.65e-16
+DEAL:3d::Norm of difference to single scalar:     3.32e-16
+DEAL:3d::Norm of difference to single scalar:     2.65e-16
diff --git a/tests/matrix_free/matrix_vector_faces_21.cc b/tests/matrix_free/matrix_vector_faces_21.cc
new file mode 100644 (file)
index 0000000..7166cab
--- /dev/null
@@ -0,0 +1,210 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// extension of matrix_vector_faces_14 (renumbering of degrees of freedom to
+// better vectorized access, gather_evaluate and integrate_scatter) to the
+// vector-valued case in form of multiple components with different vector
+// entries but otherwise similar setup. this test differs from
+// matrix_vector_faces_20 only by applying a renumbering
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/distributed/tria.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by one to test quadratic and cubic shape functions
+  // rather than linears and quadratics according to the main function in
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+1;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria, -1, 1);
+
+  for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
+       cell != tria.end(); ++cell)
+    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+      if (cell->at_boundary(f))
+        cell->face(f)->set_all_boundary_ids(f);
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> > periodic_faces;
+  for (unsigned int d=0; d<dim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(3-dim);
+
+  FE_DGQHermite<dim> fe (fe_degree);
+  FESystem<dim> fe_system(fe, dim);
+  DoFHandler<dim> dof (tria);
+  DoFHandler<dim> dof_system (tria);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  for (unsigned int test=0; test<3; ++test)
+    {
+      tria.refine_global(1);
+
+      dof.distribute_dofs(fe);
+      dof_system.distribute_dofs(fe_system);
+
+      deallog << "Testing " << dof_system.get_fe().get_name();
+      deallog << " on " << dof_system.n_dofs() << " DoFs";
+      deallog << std::endl;
+
+      // first build a vector-valued system that contains all components in
+      // analogy to matrix_vector_faces_14
+      LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+      MatrixFree<dim,double> mf_data;
+      const QGauss<1> quad (fe_degree+2);
+      typename MatrixFree<dim,double>::AdditionalData data;
+      data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+      data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+      data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+      data.initialize_mapping = false;
+
+      mf_data.reinit (dof_system, constraints, quad, data);
+
+      std::vector<types::global_dof_index> renumbering;
+      mf_data.renumber_dofs(renumbering);
+      dof_system.renumber_dofs(renumbering);
+
+      data.initialize_mapping = true;
+      mf_data.reinit(dof_system, constraints, quad, data);
+
+      mf_data.initialize_dof_vector(in);
+      mf_data.initialize_dof_vector(out);
+      mf_data.initialize_dof_vector(out_dist);
+
+      // Set random seed for reproducibility
+      Testing::srand(42);
+      for (unsigned int i=0; i<in.local_size(); ++i)
+        {
+          const double entry = Testing::rand()/(double)RAND_MAX;
+          in.local_element(i) = entry;
+        }
+
+      MatrixFreeTest<dim,fe_degree,fe_degree+2,double,
+                     LinearAlgebra::distributed::Vector<double>, dim> mf (mf_data);
+      mf.vmult(out, in);
+
+      MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                        LinearAlgebra::distributed::Vector<double>, dim> mf2(mf_data, true);
+      mf2.vmult(out_dist, in);
+
+      out_dist -= out;
+
+      double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference to no-gather:         " << diff_norm << std::endl;
+
+      // now compare the result to a scalar implementation on each of the dim
+      // components, using vmult_add in subsequent steps
+      mf2.vmult(out, in);
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, d);
+          if (d==0)
+            mf3.vmult(out_dist, in);
+          else
+            mf3.vmult_add(out_dist, in);
+        }
+
+      out_dist -= out;
+      diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference to sum of scalar:     " << diff_norm << std::endl;
+
+      if (dim == 3)
+        {
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 2> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data, true, 2);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to vector/scalar sum: " << diff_norm << std::endl;
+        }
+      if (dim == 3)
+        {
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                            LinearAlgebra::distributed::Vector<double>, 2> mf4(mf_data, true, 1);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to scalar/vector sum: " << diff_norm << std::endl;
+        }
+
+      // finally compare to a series of scalar problems
+      MatrixFree<dim,double> mf_data_scalar;
+      mf_data_scalar.reinit (dof, constraints, quad, data);
+
+      LinearAlgebra::distributed::Vector<double> in_small, out_small, ref_small;
+      mf_data_scalar.initialize_dof_vector(in_small);
+      mf_data_scalar.initialize_dof_vector(out_small);
+      mf_data_scalar.initialize_dof_vector(ref_small);
+
+      MatrixFreeVariant<dim,fe_degree,fe_degree+2,double,
+                        LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data_scalar, true);
+
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          std::vector<types::global_dof_index> dof_indices_system(fe_system.dofs_per_cell);
+          std::vector<types::global_dof_index> dof_indices_scalar(fe.dofs_per_cell);
+          for (typename DoFHandler<dim>::active_cell_iterator cell_scalar=dof.begin_active(),
+               cell_system=dof_system.begin_active(); cell_scalar != dof.end();
+               ++cell_scalar, ++cell_system)
+            if (cell_scalar->is_locally_owned())
+              {
+                cell_scalar->get_dof_indices(dof_indices_scalar);
+                cell_system->get_dof_indices(dof_indices_system);
+                for (unsigned int i=0; i<fe_system.dofs_per_cell; ++i)
+                  if (fe_system.system_to_component_index(i).first == d)
+                    {
+                      in_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        in(dof_indices_system[i]);
+                      out_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        out(dof_indices_system[i]);
+                    }
+              }
+
+          mf4.vmult(ref_small, in_small);
+
+          out_small -= ref_small;
+          diff_norm = out_small.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to single scalar:     " << diff_norm << std::endl;
+        }
+    }
+}
diff --git a/tests/matrix_free/matrix_vector_faces_21.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/matrix_vector_faces_21.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..09273f8
--- /dev/null
@@ -0,0 +1,79 @@
+
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(2)^2] on 288 DoFs
+DEAL:2d::Norm of difference to no-gather:         0.00
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(2)^2] on 1152 DoFs
+DEAL:2d::Norm of difference to no-gather:         1.24e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     6.18e-17
+DEAL:2d::Norm of difference to single scalar:     1.24e-16
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(2)^2] on 4608 DoFs
+DEAL:2d::Norm of difference to no-gather:         2.28e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.14e-16
+DEAL:2d::Norm of difference to single scalar:     2.28e-16
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(3)^2] on 512 DoFs
+DEAL:2d::Norm of difference to no-gather:         1.94e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.94e-16
+DEAL:2d::Norm of difference to single scalar:     6.45e-17
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(3)^2] on 2048 DoFs
+DEAL:2d::Norm of difference to no-gather:         2.30e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.73e-16
+DEAL:2d::Norm of difference to single scalar:     2.30e-16
+DEAL:2d::Testing FESystem<2>[FE_DGQHermite<2>(3)^2] on 8192 DoFs
+DEAL:2d::Norm of difference to no-gather:         2.27e-16
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     1.14e-16
+DEAL:2d::Norm of difference to single scalar:     1.14e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(2)^3] on 648 DoFs
+DEAL:3d::Norm of difference to no-gather:         2.19e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     1.10e-16
+DEAL:3d::Norm of difference to single scalar:     2.19e-16
+DEAL:3d::Norm of difference to single scalar:     1.10e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(2)^3] on 5184 DoFs
+DEAL:3d::Norm of difference to no-gather:         7.55e-17
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     7.55e-17
+DEAL:3d::Norm of difference to single scalar:     7.55e-17
+DEAL:3d::Norm of difference to single scalar:     7.55e-17
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(2)^3] on 41472 DoFs
+DEAL:3d::Norm of difference to no-gather:         1.35e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     1.35e-16
+DEAL:3d::Norm of difference to single scalar:     3.37e-16
+DEAL:3d::Norm of difference to single scalar:     2.02e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(3)^3] on 1536 DoFs
+DEAL:3d::Norm of difference to no-gather:         1.52e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     1.52e-16
+DEAL:3d::Norm of difference to single scalar:     1.52e-16
+DEAL:3d::Norm of difference to single scalar:     1.52e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(3)^3] on 12288 DoFs
+DEAL:3d::Norm of difference to no-gather:         2.98e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     2.98e-16
+DEAL:3d::Norm of difference to single scalar:     7.44e-17
+DEAL:3d::Norm of difference to single scalar:     7.44e-17
+DEAL:3d::Testing FESystem<3>[FE_DGQHermite<3>(3)^3] on 98304 DoFs
+DEAL:3d::Norm of difference to no-gather:         2.65e-16
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     2.65e-16
+DEAL:3d::Norm of difference to single scalar:     3.32e-16
+DEAL:3d::Norm of difference to single scalar:     2.65e-16
diff --git a/tests/matrix_free/matrix_vector_faces_22.cc b/tests/matrix_free/matrix_vector_faces_22.cc
new file mode 100644 (file)
index 0000000..9b1a67a
--- /dev/null
@@ -0,0 +1,189 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// extension of matrix_vector_faces_15 (advection, gather_evaluate and
+// integrate_scatter) to the vector-valued case in form of multiple components
+// with different vector entries but otherwise similar setup.
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/distributed/tria.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by one to test quadratic and cubic shape functions
+  // rather than linears and quadratics according to the main function in
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+1;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria, -1, 1);
+
+  for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
+       cell != tria.end(); ++cell)
+    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+      if (cell->at_boundary(f))
+        cell->face(f)->set_all_boundary_ids(f);
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> > periodic_faces;
+  for (unsigned int d=0; d<dim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(3-dim);
+
+  FE_DGQ<dim> fe (fe_degree);
+  FESystem<dim> fe_system(fe, dim);
+  DoFHandler<dim> dof (tria);
+  DoFHandler<dim> dof_system (tria);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  for (unsigned int test=0; test<3; ++test)
+    {
+      tria.refine_global(1);
+
+      dof.distribute_dofs(fe);
+      dof_system.distribute_dofs(fe_system);
+
+      deallog << "Testing " << dof_system.get_fe().get_name();
+      deallog << " on " << dof_system.n_dofs() << " DoFs";
+      deallog << std::endl;
+
+      // first build a vector-valued system that contains all components in
+      // analogy to matrix_vector_faces_14
+      LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+      MatrixFree<dim,double> mf_data;
+      const QGauss<1> quad (fe_degree+2);
+      typename MatrixFree<dim,double>::AdditionalData data;
+      data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+      data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+      data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+      mf_data.reinit (dof_system, constraints, quad, data);
+
+      mf_data.initialize_dof_vector(in);
+      mf_data.initialize_dof_vector(out);
+      mf_data.initialize_dof_vector(out_dist);
+
+      // Set random seed for reproducibility
+      Testing::srand(42);
+      for (unsigned int i=0; i<in.local_size(); ++i)
+        {
+          const double entry = Testing::rand()/(double)RAND_MAX;
+          in.local_element(i) = entry;
+        }
+
+      MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                          LinearAlgebra::distributed::Vector<double>, dim> mf2(mf_data, true);
+
+      // now compare the result to a scalar implementation on each of the dim
+      // components, using vmult_add in subsequent steps
+      mf2.vmult(out, in);
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, d);
+          if (d==0)
+            mf3.vmult(out_dist, in);
+          else
+            mf3.vmult_add(out_dist, in);
+        }
+
+      out_dist -= out;
+      double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference to sum of scalar:     " << diff_norm << std::endl;
+
+      if (dim == 3)
+        {
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 2> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data, true, 2);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to vector/scalar sum: " << diff_norm << std::endl;
+        }
+      if (dim == 3)
+        {
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 2> mf4(mf_data, true, 1);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to scalar/vector sum: " << diff_norm << std::endl;
+        }
+
+      // finally compare to a series of scalar problems
+      MatrixFree<dim,double> mf_data_scalar;
+      mf_data_scalar.reinit (dof, constraints, quad, data);
+
+      LinearAlgebra::distributed::Vector<double> in_small, out_small, ref_small;
+      mf_data_scalar.initialize_dof_vector(in_small);
+      mf_data_scalar.initialize_dof_vector(out_small);
+      mf_data_scalar.initialize_dof_vector(ref_small);
+
+      MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                          LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data_scalar, true);
+
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          std::vector<types::global_dof_index> dof_indices_system(fe_system.dofs_per_cell);
+          std::vector<types::global_dof_index> dof_indices_scalar(fe.dofs_per_cell);
+          for (typename DoFHandler<dim>::active_cell_iterator cell_scalar=dof.begin_active(),
+               cell_system=dof_system.begin_active(); cell_scalar != dof.end();
+               ++cell_scalar, ++cell_system)
+            if (cell_scalar->is_locally_owned())
+              {
+                cell_scalar->get_dof_indices(dof_indices_scalar);
+                cell_system->get_dof_indices(dof_indices_system);
+                for (unsigned int i=0; i<fe_system.dofs_per_cell; ++i)
+                  if (fe_system.system_to_component_index(i).first == d)
+                    {
+                      in_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        in(dof_indices_system[i]);
+                      out_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        out(dof_indices_system[i]);
+                    }
+              }
+
+          mf4.vmult(ref_small, in_small);
+
+          out_small -= ref_small;
+          diff_norm = out_small.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to single scalar:     " << diff_norm << std::endl;
+        }
+    }
+}
diff --git a/tests/matrix_free/matrix_vector_faces_22.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/matrix_vector_faces_22.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..3ad0d7d
--- /dev/null
@@ -0,0 +1,67 @@
+
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(2)^2] on 288 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(2)^2] on 1152 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(2)^2] on 4608 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(3)^2] on 512 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(3)^2] on 2048 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(3)^2] on 8192 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(2)^3] on 648 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(2)^3] on 5184 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(2)^3] on 41472 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     3.83e-16
+DEAL:3d::Norm of difference to single scalar:     5.11e-16
+DEAL:3d::Norm of difference to single scalar:     2.56e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(3)^3] on 1536 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(3)^3] on 12288 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(3)^3] on 98304 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     5.07e-16
+DEAL:3d::Norm of difference to single scalar:     4.06e-16
+DEAL:3d::Norm of difference to single scalar:     4.06e-16
diff --git a/tests/matrix_free/matrix_vector_faces_23.cc b/tests/matrix_free/matrix_vector_faces_23.cc
new file mode 100644 (file)
index 0000000..1ddd412
--- /dev/null
@@ -0,0 +1,200 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// extension of matrix_vector_faces_15 (advection, renumbering of degrees of
+// freedom to better vectorized access, gather_evaluate and integrate_scatter)
+// to the vector-valued case in form of multiple components with different
+// vector entries but otherwise similar setup. this test differs from
+// matrix_vector_faces_22 only by applying a renumbering
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/distributed/tria.h>
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+
+template <int dim, int fe_degree_>
+void test ()
+{
+  // raise element degree by one to test quadratic and cubic shape functions
+  // rather than linears and quadratics according to the main function in
+  // matrix_vector_faces_common.h
+
+  const unsigned int fe_degree = fe_degree_+1;
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria, -1, 1);
+
+  for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
+       cell != tria.end(); ++cell)
+    for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+      if (cell->at_boundary(f))
+        cell->face(f)->set_all_boundary_ids(f);
+  std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> > periodic_faces;
+  for (unsigned int d=0; d<dim; ++d)
+    GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+  tria.add_periodicity(periodic_faces);
+
+  tria.refine_global(3-dim);
+
+  FE_DGQ<dim> fe (fe_degree);
+  FESystem<dim> fe_system(fe, dim);
+  DoFHandler<dim> dof (tria);
+  DoFHandler<dim> dof_system (tria);
+  ConstraintMatrix constraints;
+  constraints.close();
+
+  for (unsigned int test=0; test<3; ++test)
+    {
+      tria.refine_global(1);
+
+      dof.distribute_dofs(fe);
+      dof_system.distribute_dofs(fe_system);
+
+      deallog << "Testing " << dof_system.get_fe().get_name();
+      deallog << " on " << dof_system.n_dofs() << " DoFs";
+      deallog << std::endl;
+
+      // first build a vector-valued system that contains all components in
+      // analogy to matrix_vector_faces_14
+      LinearAlgebra::distributed::Vector<double> in, out, out_dist;
+
+      MatrixFree<dim,double> mf_data;
+      const QGauss<1> quad (fe_degree+2);
+      typename MatrixFree<dim,double>::AdditionalData data;
+      data.tasks_parallel_scheme = MatrixFree<dim,double>::AdditionalData::none;
+      data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+      data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+      data.initialize_mapping = false;
+
+      mf_data.reinit (dof_system, constraints, quad, data);
+
+      std::vector<types::global_dof_index> renumbering;
+      mf_data.renumber_dofs(renumbering);
+      dof_system.renumber_dofs(renumbering);
+
+      data.initialize_mapping = true;
+      mf_data.reinit(dof_system, constraints, quad, data);
+
+      mf_data.initialize_dof_vector(in);
+      mf_data.initialize_dof_vector(out);
+      mf_data.initialize_dof_vector(out_dist);
+
+      // Set random seed for reproducibility
+      Testing::srand(42);
+      for (unsigned int i=0; i<in.local_size(); ++i)
+        {
+          const double entry = Testing::rand()/(double)RAND_MAX;
+          in.local_element(i) = entry;
+        }
+
+      MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                          LinearAlgebra::distributed::Vector<double>, dim> mf2(mf_data, true);
+
+      // now compare the result to a scalar implementation on each of the dim
+      // components, using vmult_add in subsequent steps
+      mf2.vmult(out, in);
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, d);
+          if (d==0)
+            mf3.vmult(out_dist, in);
+          else
+            mf3.vmult_add(out_dist, in);
+        }
+
+      out_dist -= out;
+      double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference to sum of scalar:     " << diff_norm << std::endl;
+
+      if (dim == 3)
+        {
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 2> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data, true, 2);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to vector/scalar sum: " << diff_norm << std::endl;
+        }
+      if (dim == 3)
+        {
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 1> mf3(mf_data, true, 0);
+          mf3.vmult(out_dist, in);
+          MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                              LinearAlgebra::distributed::Vector<double>, 2> mf4(mf_data, true, 1);
+          mf4.vmult_add(out_dist, in);
+
+          out_dist -= out;
+          diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to scalar/vector sum: " << diff_norm << std::endl;
+        }
+
+      // finally compare to a series of scalar problems
+      MatrixFree<dim,double> mf_data_scalar;
+      mf_data_scalar.reinit (dof, constraints, quad, data);
+
+      LinearAlgebra::distributed::Vector<double> in_small, out_small, ref_small;
+      mf_data_scalar.initialize_dof_vector(in_small);
+      mf_data_scalar.initialize_dof_vector(out_small);
+      mf_data_scalar.initialize_dof_vector(ref_small);
+
+      MatrixFreeAdvection<dim,fe_degree,fe_degree+2,double,
+                          LinearAlgebra::distributed::Vector<double>, 1> mf4(mf_data_scalar, true);
+
+      for (unsigned int d=0; d<dim; ++d)
+        {
+          std::vector<types::global_dof_index> dof_indices_system(fe_system.dofs_per_cell);
+          std::vector<types::global_dof_index> dof_indices_scalar(fe.dofs_per_cell);
+          for (typename DoFHandler<dim>::active_cell_iterator cell_scalar=dof.begin_active(),
+               cell_system=dof_system.begin_active(); cell_scalar != dof.end();
+               ++cell_scalar, ++cell_system)
+            if (cell_scalar->is_locally_owned())
+              {
+                cell_scalar->get_dof_indices(dof_indices_scalar);
+                cell_system->get_dof_indices(dof_indices_system);
+                for (unsigned int i=0; i<fe_system.dofs_per_cell; ++i)
+                  if (fe_system.system_to_component_index(i).first == d)
+                    {
+                      in_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        in(dof_indices_system[i]);
+                      out_small(dof_indices_scalar[fe_system.system_to_component_index(i).second]) =
+                        out(dof_indices_system[i]);
+                    }
+              }
+
+          mf4.vmult(ref_small, in_small);
+
+          out_small -= ref_small;
+          diff_norm = out_small.linfty_norm() / out.linfty_norm();
+          deallog << "Norm of difference to single scalar:     " << diff_norm << std::endl;
+        }
+    }
+}
diff --git a/tests/matrix_free/matrix_vector_faces_23.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/matrix_vector_faces_23.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..3ad0d7d
--- /dev/null
@@ -0,0 +1,67 @@
+
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(2)^2] on 288 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(2)^2] on 1152 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(2)^2] on 4608 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(3)^2] on 512 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(3)^2] on 2048 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Testing FESystem<2>[FE_DGQ<2>(3)^2] on 8192 DoFs
+DEAL:2d::Norm of difference to sum of scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:2d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(2)^3] on 648 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(2)^3] on 5184 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(2)^3] on 41472 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     3.83e-16
+DEAL:3d::Norm of difference to single scalar:     5.11e-16
+DEAL:3d::Norm of difference to single scalar:     2.56e-16
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(3)^3] on 1536 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(3)^3] on 12288 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Norm of difference to single scalar:     0.00
+DEAL:3d::Testing FESystem<3>[FE_DGQ<3>(3)^3] on 98304 DoFs
+DEAL:3d::Norm of difference to sum of scalar:     0.00
+DEAL:3d::Norm of difference to vector/scalar sum: 0.00
+DEAL:3d::Norm of difference to scalar/vector sum: 0.00
+DEAL:3d::Norm of difference to single scalar:     5.07e-16
+DEAL:3d::Norm of difference to single scalar:     4.06e-16
+DEAL:3d::Norm of difference to single scalar:     4.06e-16
diff --git a/tests/matrix_free/matrix_vector_faces_common.h b/tests/matrix_free/matrix_vector_faces_common.h
new file mode 100644 (file)
index 0000000..b5ce5d9
--- /dev/null
@@ -0,0 +1,659 @@
+//------------------  matrix_vector_faces_common.h  ------------------------
+//
+// 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.
+//
+//------------------  matrix_vector_faces_common.h  ------------------------
+
+
+// this is a template for matrix-vector products with face integration (DG
+// case, symmetric interior penalty + Nitsche) on different kinds of meshes
+// (Cartesian, general, with and without hanging nodes). It also tests the
+// multithreading in case it was enabled
+
+#include "../tests.h"
+
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/lac/sparse_matrix.h>
+#include <deal.II/lac/dynamic_sparsity_pattern.h>
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/mapping_q.h>
+#include <deal.II/numerics/vector_tools.h>
+
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+
+// To generate a reference solution
+#include <deal.II/meshworker/dof_info.h>
+#include <deal.II/meshworker/integration_info.h>
+#include <deal.II/meshworker/assembler.h>
+#include <deal.II/meshworker/loop.h>
+#include <deal.II/integrators/laplace.h>
+
+#include <iostream>
+
+
+// forward declare this function. will be implemented in .cc files
+template <int dim, int fe_degree>
+void test ();
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double,
+          typename VectorType = Vector<number>, int n_components=1>
+class MatrixFreeTest
+{
+public:
+  MatrixFreeTest (const MatrixFree<dim,number> &data)
+    :
+    data(data)
+  {}
+
+  void vmult(VectorType &dst,
+             const VectorType &src) const
+  {
+    dst = 0;
+    data.loop (&MatrixFreeTest::local_apply,
+               &MatrixFreeTest::local_apply_face,
+               &MatrixFreeTest::local_apply_boundary_face,
+               this, dst, src);
+  }
+
+private:
+  void local_apply (const MatrixFree<dim,number> &data,
+                    VectorType                   &dst,
+                    const VectorType             &src,
+                    const std::pair<unsigned int,unsigned int> &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> phi (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+        phi.read_dof_values(src);
+        phi.evaluate (false,true,false);
+        for (unsigned int q=0; q<phi.n_q_points; ++q)
+          phi.submit_gradient (phi.get_gradient(q), q);
+        phi.integrate (false,true);
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  void local_apply_face (const MatrixFree<dim,number> &data,
+                         VectorType                   &dst,
+                         const VectorType             &src,
+                         const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval_neighbor(data,false);
+    typedef typename FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number>::value_type value_type;
+    const int actual_degree = data.get_dof_handler().get_fe().degree;
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval_neighbor.reinit (face);
+
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        fe_eval_neighbor.read_dof_values(src);
+        fe_eval_neighbor.evaluate(true,true);
+        VectorizedArray<number> sigmaF =
+          (std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) +
+           std::abs((fe_eval.get_normal_vector(0)*fe_eval_neighbor.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(actual_degree,1) * (actual_degree + 1.0));
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            value_type average_value = (fe_eval.get_value(q)-
+                                        fe_eval_neighbor.get_value(q)) * make_vectorized_array<number>(0.5);
+            value_type average_valgrad =
+              fe_eval.get_normal_derivative(q) +
+              fe_eval_neighbor.get_normal_derivative(q);
+            average_valgrad = average_value * sigmaF -
+                              average_valgrad * make_vectorized_array<number>(0.5);
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval_neighbor.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+            fe_eval_neighbor.submit_value(-average_valgrad,q);
+          }
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+        fe_eval_neighbor.integrate(true,true);
+        fe_eval_neighbor.distribute_local_to_global(dst);
+      }
+  }
+
+
+  void local_apply_boundary_face (const MatrixFree<dim,number> &data,
+                                  VectorType                   &dst,
+                                  const VectorType             &src,
+                                  const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval(data, true);
+    typedef typename FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number>::value_type value_type;
+    const int actual_degree = data.get_dof_handler().get_fe().degree;
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        VectorizedArray<number> sigmaF = 2.0*std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) *
+                                         number(std::max(actual_degree, 1) * (actual_degree+1.0));
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            value_type average_value = fe_eval.get_value(q);
+            value_type average_valgrad = -fe_eval.get_normal_derivative(q);
+            average_valgrad += average_value * sigmaF;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+          }
+
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+      }
+  }
+
+  const MatrixFree<dim,number>     &data;
+};
+
+
+
+// A variant class used in some of the tests that goes through the combined
+// vector-access/evaluate routines that typically give better performance
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double,
+          typename VectorType = Vector<number>, int n_components=1>
+class MatrixFreeVariant
+{
+public:
+  MatrixFreeVariant (const MatrixFree<dim,number> &data,
+                     const bool                    zero_within_loop = true,
+                     const unsigned int            start_vector_component = 0)
+    :
+    data(data),
+    zero_within_loop(zero_within_loop),
+    start_vector_component(start_vector_component)
+  {}
+
+  void vmult(VectorType &dst,
+             const VectorType &src) const
+  {
+    if (!zero_within_loop)
+      dst = 0;
+    data.loop (&MatrixFreeVariant::local_apply,
+               &MatrixFreeVariant::local_apply_face,
+               &MatrixFreeVariant::local_apply_boundary_face,
+               this, dst, src, zero_within_loop,
+               MatrixFree<dim,number>::DataAccessOnFaces::gradients,
+               MatrixFree<dim,number>::DataAccessOnFaces::gradients);
+  }
+
+  void vmult_add(VectorType &dst,
+                 const VectorType &src) const
+  {
+    data.loop (&MatrixFreeVariant::local_apply,
+               &MatrixFreeVariant::local_apply_face,
+               &MatrixFreeVariant::local_apply_boundary_face,
+               this, dst, src, false,
+               MatrixFree<dim,number>::DataAccessOnFaces::gradients,
+               MatrixFree<dim,number>::DataAccessOnFaces::gradients);
+  }
+
+private:
+  void local_apply (const MatrixFree<dim,number> &data,
+                    VectorType                   &dst,
+                    const VectorType             &src,
+                    const std::pair<unsigned int,unsigned int> &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> phi (data, 0, 0, start_vector_component);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+        phi.gather_evaluate (src, false,true);
+        for (unsigned int q=0; q<phi.n_q_points; ++q)
+          phi.submit_gradient (phi.get_gradient(q), q);
+        phi.integrate_scatter (false,true,dst);
+      }
+  }
+
+  void local_apply_face (const MatrixFree<dim,number> &data,
+                         VectorType                   &dst,
+                         const VectorType             &src,
+                         const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval(data,true, 0, 0, start_vector_component);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval_neighbor(data,false, 0, 0, start_vector_component);
+    typedef typename FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number>::value_type value_type;
+    const int actual_degree = data.get_dof_handler().get_fe().degree;
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval_neighbor.reinit (face);
+
+        fe_eval.gather_evaluate(src,true,true);
+        fe_eval_neighbor.gather_evaluate(src,true,true);
+
+        VectorizedArray<number> sigmaF =
+          (std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) +
+           std::abs((fe_eval.get_normal_vector(0)*fe_eval_neighbor.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(actual_degree,1) * (actual_degree + 1.0));
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            value_type average_value = (fe_eval.get_value(q)-
+                                        fe_eval_neighbor.get_value(q)) * make_vectorized_array<number>(0.5);
+            value_type average_valgrad =
+              fe_eval.get_normal_derivative(q) +
+              fe_eval_neighbor.get_normal_derivative(q);
+            average_valgrad = average_value * sigmaF -
+                              average_valgrad * make_vectorized_array<number>(0.5);
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval_neighbor.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+            fe_eval_neighbor.submit_value(-average_valgrad,q);
+          }
+        fe_eval.integrate_scatter(true,true,dst);
+        fe_eval_neighbor.integrate_scatter(true,true,dst);
+      }
+  }
+
+  void local_apply_boundary_face (const MatrixFree<dim,number> &data,
+                                  VectorType                   &dst,
+                                  const VectorType             &src,
+                                  const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval(data, true, 0, 0, start_vector_component);
+    typedef typename FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number>::value_type value_type;
+    const int actual_degree = data.get_dof_handler().get_fe().degree;
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.gather_evaluate(src,true,true);
+        VectorizedArray<number> sigmaF = std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) *
+                                         number(std::max(actual_degree, 1) * (actual_degree+1.0)) * 2.0;
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            value_type average_value = fe_eval.get_value(q);
+            value_type average_valgrad = -fe_eval.get_normal_derivative(q);
+            average_valgrad += average_value * sigmaF;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+          }
+
+        fe_eval.integrate_scatter(true,true,dst);
+      }
+  }
+
+  const MatrixFree<dim,number>     &data;
+  const bool                        zero_within_loop;
+  const unsigned int                start_vector_component;
+};
+
+
+
+template <int dim, int n_components, typename Number>
+Tensor<1, n_components, Tensor<1, dim, Number> >
+multiply_by_advection(const Tensor<1,dim,Number> &advection,
+                      const Tensor<1,n_components,Number> &values)
+{
+  Tensor<1, n_components, Tensor<1, dim, Number> > out;
+  for (unsigned int c=0; c<n_components; ++c)
+    for (unsigned int d=0; d<dim; ++d)
+      out[c][d] = advection[d] * values[c];
+  return out;
+}
+
+
+
+template <int dim, typename Number>
+Tensor<1, dim, Number>
+multiply_by_advection(const Tensor<1,dim,Number> &advection,
+                      const Number &values)
+{
+  Tensor<1, dim, Number> out;
+  for (unsigned int d=0; d<dim; ++d)
+    out[d] = advection[d] * values;
+  return out;
+}
+
+
+
+// An implementation of matrix-free advection operator
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double,
+          typename VectorType = Vector<number>, int n_components=1>
+class MatrixFreeAdvection
+{
+public:
+  MatrixFreeAdvection (const MatrixFree<dim,number> &data,
+                       const bool                    zero_within_loop = true,
+                       const unsigned int            start_vector_component = 0)
+    :
+    data(data),
+    zero_within_loop(zero_within_loop),
+    start_vector_component(start_vector_component)
+  {
+    for (unsigned int d=0; d<dim; ++d)
+      advection[d] = 0.4 + 0.12 * d;
+  }
+
+  void vmult(VectorType &dst,
+             const VectorType &src) const
+  {
+    if (!zero_within_loop)
+      dst = 0;
+    data.loop (&MatrixFreeAdvection::local_apply,
+               &MatrixFreeAdvection::local_apply_face,
+               &MatrixFreeAdvection::local_apply_boundary_face,
+               this, dst, src, zero_within_loop,
+               MatrixFree<dim,number>::DataAccessOnFaces::values,
+               MatrixFree<dim,number>::DataAccessOnFaces::values);
+  }
+
+  void vmult_add(VectorType &dst,
+                 const VectorType &src) const
+  {
+    data.loop (&MatrixFreeAdvection::local_apply,
+               &MatrixFreeAdvection::local_apply_face,
+               &MatrixFreeAdvection::local_apply_boundary_face,
+               this, dst, src, false,
+               MatrixFree<dim,number>::DataAccessOnFaces::values,
+               MatrixFree<dim,number>::DataAccessOnFaces::values);
+  }
+
+private:
+  void local_apply (const MatrixFree<dim,number> &data,
+                    VectorType                   &dst,
+                    const VectorType             &src,
+                    const std::pair<unsigned int,unsigned int> &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> phi (data, 0, 0, start_vector_component);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit(cell);
+        phi.gather_evaluate (src, true, false);
+        for (unsigned int q=0; q<phi.n_q_points; ++q)
+          phi.submit_gradient(multiply_by_advection(advection, phi.get_value(q)), q);
+        phi.integrate_scatter(false, true, dst);
+      }
+  }
+
+  void local_apply_face (const MatrixFree<dim,number> &data,
+                         VectorType                   &dst,
+                         const VectorType             &src,
+                         const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> phi_m(data,true, 0, 0, start_vector_component);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> phi_p(data,false, 0, 0, start_vector_component);
+    typedef typename FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number>::value_type value_type;
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi_m.reinit (face);
+        phi_m.gather_evaluate(src,true,false);
+        phi_p.reinit (face);
+        phi_p.gather_evaluate(src,true,false);
+
+        for (unsigned int q=0; q<phi_m.n_q_points; ++q)
+          {
+            value_type u_minus = phi_m.get_value(q),
+                       u_plus  = phi_p.get_value(q);
+            const VectorizedArray<number> normal_times_advection =
+              advection * phi_m.get_normal_vector(q);
+            const value_type flux_times_normal = make_vectorized_array<number>(0.5) *
+                                                 ((u_minus+u_plus) * normal_times_advection +
+                                                  std::abs(normal_times_advection) * (u_minus-u_plus));
+            phi_m.submit_value(-flux_times_normal,q);
+            phi_p.submit_value(flux_times_normal,q);
+          }
+
+        phi_m.integrate_scatter(true, false, dst);
+        phi_p.integrate_scatter(true, false, dst);
+      }
+  }
+
+  void local_apply_boundary_face (const MatrixFree<dim,number>    &data,
+                                  VectorType                      &dst,
+                                  const VectorType                &src,
+                                  const std::pair<unsigned int,unsigned int> &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number> fe_eval(data, true, 0, 0, start_vector_component);
+    typedef typename FEFaceEvaluation<dim,fe_degree,n_q_points_1d,n_components,number>::value_type value_type;
+    value_type u_plus;
+    u_plus = make_vectorized_array<number>(1.3);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.gather_evaluate(src,true,false);
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            value_type u_minus = fe_eval.get_value(q);
+            const VectorizedArray<number> normal_times_advection =
+              advection * fe_eval.get_normal_vector(q);
+            const value_type flux_times_normal = make_vectorized_array<number>(0.5) *
+                                                 ((u_minus+u_plus) * normal_times_advection +
+                                                  std::abs(normal_times_advection) * (u_minus-u_plus));
+            fe_eval.submit_value(-flux_times_normal,q);
+          }
+
+        fe_eval.integrate_scatter(true,false,dst);
+      }
+  }
+
+  const MatrixFree<dim,number>     &data;
+  const bool                        zero_within_loop;
+  const unsigned int                start_vector_component;
+  Tensor<1,dim,VectorizedArray<number> > advection;
+};
+
+
+
+// Reference solution created with MeshWorker
+template <int dim>
+class MatrixIntegrator : public MeshWorker::LocalIntegrator<dim>
+{
+public:
+  void cell(MeshWorker::DoFInfo<dim> &dinfo,
+            typename MeshWorker::IntegrationInfo<dim> &info) const;
+  void boundary(MeshWorker::DoFInfo<dim> &dinfo,
+                typename MeshWorker::IntegrationInfo<dim> &info) const;
+  void face(MeshWorker::DoFInfo<dim> &dinfo1,
+            MeshWorker::DoFInfo<dim> &dinfo2,
+            typename MeshWorker::IntegrationInfo<dim> &info1,
+            typename MeshWorker::IntegrationInfo<dim> &info2) const;
+};
+
+
+
+template <int dim>
+void MatrixIntegrator<dim>::cell(
+  MeshWorker::DoFInfo<dim> &dinfo,
+  typename MeshWorker::IntegrationInfo<dim> &info) const
+{
+  LocalIntegrators::Laplace::cell_matrix(dinfo.matrix(0,false).matrix, info.fe_values());
+}
+
+
+
+template <int dim>
+void MatrixIntegrator<dim>::face(
+  MeshWorker::DoFInfo<dim> &dinfo1,
+  MeshWorker::DoFInfo<dim> &dinfo2,
+  typename MeshWorker::IntegrationInfo<dim> &info1,
+  typename MeshWorker::IntegrationInfo<dim> &info2) const
+{
+  const unsigned int deg = info1.fe_values(0).get_fe().tensor_degree();
+  // Manually compute penalty parameter instead of using the function
+  // compute_penalty because we do it slightly differently on non-Cartesian
+  // meshes.
+  Tensor<2,dim> inverse_jacobian = transpose(info1.fe_values(0).jacobian(0).covariant_form());
+  const double normal_volume_fraction1 = std::abs((inverse_jacobian[GeometryInfo<dim>::unit_normal_direction[dinfo1.face_number]]*info1.fe_values(0).normal_vector(0)));
+  inverse_jacobian = transpose(info2.fe_values(0).jacobian(0).covariant_form());
+  const double normal_volume_fraction2 = std::abs((inverse_jacobian[GeometryInfo<dim>::unit_normal_direction[dinfo2.face_number]]*info1.fe_values(0).normal_vector(0)));
+  double penalty = 0.5*(normal_volume_fraction1+normal_volume_fraction2)*
+                   std::max(1U,deg)*(deg+1.0);
+  LocalIntegrators::Laplace
+  ::ip_matrix(dinfo1.matrix(0,false).matrix, dinfo1.matrix(0,true).matrix,
+              dinfo2.matrix(0,true).matrix, dinfo2.matrix(0,false).matrix,
+              info1.fe_values(0), info2.fe_values(0), penalty);
+}
+
+
+
+template <int dim>
+void MatrixIntegrator<dim>::boundary(
+  MeshWorker::DoFInfo<dim> &dinfo,
+  typename MeshWorker::IntegrationInfo<dim> &info) const
+{
+  const unsigned int deg = info.fe_values(0).get_fe().tensor_degree();
+  Tensor<2,dim> inverse_jacobian = transpose(info.fe_values(0).jacobian(0).covariant_form());
+  const double normal_volume_fraction = std::abs((inverse_jacobian[GeometryInfo<dim>::unit_normal_direction[dinfo.face_number]]*info.fe_values(0).normal_vector(0)));
+  double penalty = normal_volume_fraction * std::max(1U,deg) * (deg + 1.0);
+  LocalIntegrators::Laplace
+  ::nitsche_matrix(dinfo.matrix(0,false).matrix, info.fe_values(0), penalty);
+}
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d, typename number>
+void do_test (const DoFHandler<dim>  &dof,
+              const ConstraintMatrix &constraints,
+              const bool              also_test_parallel = false)
+{
+  if (types_are_equal<number,float>::value == true)
+    deallog.push("float");
+
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+  //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+  //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+  MappingQGeneric<dim> mapping(dof.get_fe().degree+1);
+
+  Vector<number> in (dof.n_dofs()), out (dof.n_dofs());
+  Vector<number> out_dist (out);
+
+  // Set random seed for reproducibility
+  Testing::srand(42);
+  for (unsigned int i=0; i<dof.n_dofs(); ++i)
+    {
+      if (constraints.is_constrained(i))
+        continue;
+      const double entry = Testing::rand()/(double)RAND_MAX;
+      in(i) = entry;
+    }
+
+  // assemble sparse matrix with MeshWorker
+  SparsityPattern sparsity;
+  SparseMatrix<double> matrix;
+  {
+    DynamicSparsityPattern d_sparsity(dof.n_dofs());
+    DoFTools::make_flux_sparsity_pattern(dof, d_sparsity);
+    sparsity.copy_from(d_sparsity);
+  }
+  matrix.reinit(sparsity);
+  MeshWorker::IntegrationInfoBox<dim> info_box;
+  UpdateFlags update_flags = update_values | update_gradients | update_jacobians;
+  info_box.add_update_flags_all(update_flags);
+  info_box.initialize_gauss_quadrature(n_q_points_1d, n_q_points_1d, n_q_points_1d);
+  info_box.initialize(dof.get_fe(), mapping);
+
+  MeshWorker::DoFInfo<dim> dof_info(dof);
+
+  MeshWorker::Assembler::MatrixSimple<SparseMatrix<double> > assembler;
+  assembler.initialize(matrix);
+
+  MatrixIntegrator<dim> integrator;
+  MeshWorker::integration_loop<dim, dim>
+  (dof.begin_active(), dof.end(), dof_info, info_box, integrator, assembler);
+
+  matrix.vmult (out, in);
+
+  MatrixFree<dim,number> mf_data;
+  const QGauss<1> quad (n_q_points_1d > 0 ? n_q_points_1d : dof.get_fe().degree+1);
+  typename MatrixFree<dim,number>::AdditionalData data;
+  data.tasks_parallel_scheme = MatrixFree<dim,number>::AdditionalData::none;
+  data.tasks_block_size = 3;
+  data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+  data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+
+  mf_data.reinit (mapping, dof, constraints, quad, data);
+
+  MatrixFreeTest<dim,fe_degree,n_q_points_1d,number> mf (mf_data);
+  mf.vmult(out_dist, in);
+
+  out_dist -= out;
+  const double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+  deallog << "Norm of difference:          " << diff_norm << std::endl;
+
+  if (also_test_parallel)
+    {
+      mf_data.clear();
+      data.tasks_parallel_scheme =
+        MatrixFree<dim,number>::AdditionalData::partition_partition;
+      mf_data.reinit(mapping, dof, constraints, quad, data);
+
+      MatrixFreeTest<dim,fe_degree,n_q_points_1d,number> mf (mf_data);
+      mf.vmult(out_dist, in);
+      out_dist -= out;
+
+      const double diff_norm = out_dist.linfty_norm() / out.linfty_norm();
+      deallog << "Norm of difference parallel: " << diff_norm
+              << std::endl;
+    }
+  deallog << std::endl;
+
+  if (types_are_equal<number,float>::value == true)
+    deallog.pop();
+}
+
+
+
+#ifdef DEAL_II_WITH_MPI
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, testing_max_num_threads());
+  mpi_initlog();
+#else
+int main (int argc, char **argv)
+{
+  initlog();
+#endif
+  deallog << std::setprecision(3);
+
+  {
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
index 4963b0882ed277e0e6e3c30c24bd1e902350b512..d4bc21b41170864b698cbd45c0a5cd6e56868632 100644 (file)
@@ -1,6 +1,6 @@
 // ---------------------------------------------------------------------
 //
-// Copyright (C) 2013 - 2016 by the deal.II authors
+// Copyright (C) 2018 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
diff --git a/tests/matrix_free/multigrid_dg_periodic.cc b/tests/matrix_free/multigrid_dg_periodic.cc
new file mode 100644 (file)
index 0000000..92adece
--- /dev/null
@@ -0,0 +1,586 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// same as multigrid_dg_sip but using periodic boundary conditions
+
+#include "../tests.h"
+
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/solver_cg.h>
+#include <deal.II/lac/precondition.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/mapping_q.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/numerics/vector_tools.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/multigrid/multigrid.h>
+#include <deal.II/multigrid/mg_transfer.h>
+#include <deal.II/multigrid/mg_tools.h>
+#include <deal.II/multigrid/mg_coarse.h>
+#include <deal.II/multigrid/mg_smoother.h>
+#include <deal.II/multigrid/mg_matrix.h>
+
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+
+std::ofstream logfile("output");
+
+
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double>
+class LaplaceOperator : public Subscriptor
+{
+public:
+  typedef number value_type;
+
+  LaplaceOperator() {};
+
+  void initialize (const Mapping<dim> &mapping,
+                   const DoFHandler<dim> &dof_handler,
+                   const unsigned int level = numbers::invalid_unsigned_int)
+  {
+    const QGauss<1> quad (n_q_points_1d);
+    typename MatrixFree<dim,number>::AdditionalData addit_data;
+    addit_data.tasks_parallel_scheme = MatrixFree<dim,number>::AdditionalData::none;
+    addit_data.tasks_block_size = 3;
+    addit_data.level_mg_handler = level;
+    addit_data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+    addit_data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+    ConstraintMatrix constraints;
+    constraints.close();
+
+    data.reinit (mapping, dof_handler, constraints, quad, addit_data);
+
+    compute_inverse_diagonal();
+  }
+
+  void vmult(parallel::distributed::Vector<number> &dst,
+             const parallel::distributed::Vector<number> &src) const
+  {
+    dst = 0;
+    vmult_add(dst, src);
+  }
+
+  void Tvmult(parallel::distributed::Vector<number> &dst,
+              const parallel::distributed::Vector<number> &src) const
+  {
+    dst = 0;
+    vmult_add(dst, src);
+  }
+
+  void Tvmult_add(parallel::distributed::Vector<number> &dst,
+                  const parallel::distributed::Vector<number> &src) const
+  {
+    vmult_add(dst, src);
+  }
+
+  void vmult_add(parallel::distributed::Vector<number> &dst,
+                 const parallel::distributed::Vector<number> &src) const
+  {
+    Assert(src.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner), ExcInternalError());
+    Assert(dst.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner), ExcInternalError());
+    data.loop (&LaplaceOperator::local_apply,
+               &LaplaceOperator::local_apply_face,
+               &LaplaceOperator::local_apply_boundary,
+               this, dst, src);
+  }
+
+  types::global_dof_index m() const
+  {
+    return data.get_vector_partitioner()->size();
+  }
+
+  types::global_dof_index n() const
+  {
+    return data.get_vector_partitioner()->size();
+  }
+
+  number el (const unsigned int row,  const unsigned int col) const
+  {
+    AssertThrow(false, ExcMessage("Matrix-free does not allow for entry access"));
+    return number();
+  }
+
+  void
+  initialize_dof_vector(parallel::distributed::Vector<number> &vector) const
+  {
+    if (!vector.partitioners_are_compatible(*data.get_dof_info(0).vector_partitioner))
+      data.initialize_dof_vector(vector);
+  }
+
+  const parallel::distributed::Vector<number> &
+  get_matrix_diagonal_inverse() const
+  {
+    return inverse_diagonal_entries;
+  }
+
+
+private:
+  void
+  local_apply (const MatrixFree<dim,number>                &data,
+               parallel::distributed::Vector<number>       &dst,
+               const parallel::distributed::Vector<number> &src,
+               const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+        phi.read_dof_values(src);
+        phi.evaluate (false,true,false);
+        for (unsigned int q=0; q<phi.n_q_points; ++q)
+          phi.submit_gradient (phi.get_gradient(q), q);
+        phi.integrate (false,true);
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  void
+  local_apply_face (const MatrixFree<dim,number>                &data,
+                    parallel::distributed::Vector<number>       &dst,
+                    const parallel::distributed::Vector<number> &src,
+                    const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval_neighbor(data,false);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval_neighbor.reinit (face);
+
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        fe_eval_neighbor.read_dof_values(src);
+        fe_eval_neighbor.evaluate(true,true);
+        VectorizedArray<number> sigmaF =
+          (std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) +
+           std::abs((fe_eval.get_normal_vector(0)*fe_eval_neighbor.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0));
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            VectorizedArray<number> average_value = (fe_eval.get_value(q)-
+                                                     fe_eval_neighbor.get_value(q)) * 0.5;
+            VectorizedArray<number> average_valgrad =
+              fe_eval.get_normal_derivative(q) +
+              fe_eval_neighbor.get_normal_derivative(q);
+            average_valgrad = average_value * 2. * sigmaF -
+                              average_valgrad * 0.5;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval_neighbor.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+            fe_eval_neighbor.submit_value(-average_valgrad,q);
+          }
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+        fe_eval_neighbor.integrate(true,true);
+        fe_eval_neighbor.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_apply_boundary (const MatrixFree<dim,number>                &data,
+                        parallel::distributed::Vector<number>       &dst,
+                        const parallel::distributed::Vector<number> &src,
+                        const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval(data, true);
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        VectorizedArray<number> sigmaF =
+          std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) *
+          (number)(std::max(1,fe_degree) * (fe_degree + 1.0)) * 2.;
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            VectorizedArray<number> average_value = fe_eval.get_value(q);
+            VectorizedArray<number> average_valgrad = -fe_eval.get_normal_derivative(q);
+            average_valgrad += average_value * sigmaF * 2.0;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+          }
+
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  compute_inverse_diagonal ()
+  {
+    data.initialize_dof_vector(inverse_diagonal_entries);
+    unsigned int dummy;
+    data.loop (&LaplaceOperator::local_diagonal_cell,
+               &LaplaceOperator::local_diagonal_face,
+               &LaplaceOperator::local_diagonal_boundary,
+               this, inverse_diagonal_entries, dummy);
+
+    for (unsigned int i=0; i<inverse_diagonal_entries.local_size(); ++i)
+      if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10)
+        inverse_diagonal_entries.local_element(i) = 1./inverse_diagonal_entries.local_element(i);
+      else
+        inverse_diagonal_entries.local_element(i) = 1.;
+  }
+
+  void
+  local_diagonal_cell (const MatrixFree<dim,number>                &data,
+                       parallel::distributed::Vector<number>       &dst,
+                       const unsigned int &,
+                       const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate (false,true,false);
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              phi.submit_gradient (phi.get_gradient(q), q);
+            phi.integrate (false,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.static_dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  void
+  local_diagonal_face (const MatrixFree<dim,number>                &data,
+                       parallel::distributed::Vector<number>       &dst,
+                       const unsigned int &,
+                       const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi_outer(data,false);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi.reinit (face);
+        phi_outer.reinit (face);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        VectorizedArray<number> sigmaF =
+          (std::abs((phi.get_normal_vector(0)*phi.inverse_jacobian(0))[dim-1]) +
+           std::abs((phi.get_normal_vector(0)*phi_outer.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0));
+
+        // Compute phi part
+        for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+          phi_outer.begin_dof_values()[j] = VectorizedArray<number>();
+        phi_outer.evaluate(true, true);
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = (phi.get_value(q)-
+                                                         phi_outer.get_value(q)) * 0.5;
+                VectorizedArray<number> average_valgrad =
+                  phi.get_normal_derivative(q) +
+                  phi_outer.get_normal_derivative(q);
+                average_valgrad = average_value * 2. * sigmaF -
+                                  average_valgrad * 0.5;
+                phi.submit_normal_derivative(-average_value,q);
+                phi.submit_value(average_valgrad,q);
+              }
+            phi.integrate(true,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global(dst);
+
+        // Compute phi_outer part
+        for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+          phi.begin_dof_values()[j] = VectorizedArray<number>();
+        phi.evaluate(true, true);
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi_outer.begin_dof_values()[j] = VectorizedArray<number>();
+            phi_outer.begin_dof_values()[i] = 1.;
+            phi_outer.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = (phi.get_value(q)-
+                                                         phi_outer.get_value(q)) * 0.5;
+                VectorizedArray<number> average_valgrad =
+                  phi.get_normal_derivative(q) +
+                  phi_outer.get_normal_derivative(q);
+                average_valgrad = average_value * 2. * sigmaF -
+                                  average_valgrad * 0.5;
+                phi_outer.submit_normal_derivative(-average_value,q);
+                phi_outer.submit_value(-average_valgrad,q);
+              }
+            phi_outer.integrate(true,true);
+            local_diagonal_vector[i] = phi_outer.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi_outer.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi_outer.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_diagonal_boundary (const MatrixFree<dim,number>                &data,
+                           parallel::distributed::Vector<number>       &dst,
+                           const unsigned int &,
+                           const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi.reinit (face);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        VectorizedArray<number> sigmaF = std::abs((phi.get_normal_vector(0)*phi.inverse_jacobian(0))[dim-1]) *
+                                         (number)(std::max(1,fe_degree) * (fe_degree + 1.0)) * 2.;
+
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = phi.get_value(q);
+                VectorizedArray<number> average_valgrad = -phi.get_normal_derivative(q);
+                average_valgrad += average_value * sigmaF * 2.0;
+                phi.submit_normal_derivative(-average_value,q);
+                phi.submit_value(average_valgrad,q);
+              }
+
+            phi.integrate(true,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global(dst);
+      }
+  }
+
+
+  MatrixFree<dim,number> data;
+  parallel::distributed::Vector<number> inverse_diagonal_entries;
+};
+
+
+
+template<typename MATRIX, typename Number>
+class MGCoarseIterative : public MGCoarseGridBase<parallel::distributed::Vector<Number> >
+{
+public:
+  MGCoarseIterative() {}
+
+  void initialize(const MATRIX &matrix)
+  {
+    coarse_matrix = &matrix;
+  }
+
+  virtual void operator() (const unsigned int ,
+                           parallel::distributed::Vector<double> &dst,
+                           const parallel::distributed::Vector<double> &src) const
+  {
+    ReductionControl solver_control (1e4, 1e-50, 1e-7, false, false);
+    SolverCG<parallel::distributed::Vector<double> > solver_coarse (solver_control);
+    solver_coarse.solve (*coarse_matrix, dst, src, PreconditionIdentity());
+  }
+
+  const MATRIX *coarse_matrix;
+};
+
+
+
+template <typename LAPLACEOPERATOR>
+class MGTransferMF : public MGTransferPrebuilt<parallel::distributed::Vector<typename LAPLACEOPERATOR::value_type> >
+{
+public:
+  MGTransferMF(const MGLevelObject<LAPLACEOPERATOR> &laplace)
+    :
+    laplace_operator (laplace)
+  {};
+
+  /**
+   * Overload copy_to_mg from MGTransferPrebuilt
+   */
+  template <int dim, class InVector, int spacedim>
+  void
+  copy_to_mg (const DoFHandler<dim,spacedim> &mg_dof,
+              MGLevelObject<parallel::distributed::Vector<typename LAPLACEOPERATOR::value_type> > &dst,
+              const InVector &src) const
+  {
+    for (unsigned int level=dst.min_level();
+         level<=dst.max_level(); ++level)
+      laplace_operator[level].initialize_dof_vector(dst[level]);
+    MGTransferPrebuilt<parallel::distributed::Vector<typename LAPLACEOPERATOR::value_type> >::copy_to_mg(mg_dof, dst, src);
+  }
+
+private:
+  const MGLevelObject<LAPLACEOPERATOR> &laplace_operator;
+};
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d, typename number>
+void do_test (const DoFHandler<dim>  &dof)
+{
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+
+  MappingQ<dim> mapping(fe_degree+1);
+  LaplaceOperator<dim,fe_degree,n_q_points_1d,number> fine_matrix;
+  fine_matrix.initialize(mapping, dof);
+
+  parallel::distributed::Vector<number> in, sol;
+  fine_matrix.initialize_dof_vector(in);
+  fine_matrix.initialize_dof_vector(sol);
+
+  in = 1.;
+
+  // set up multigrid in analogy to step-37
+  typedef LaplaceOperator<dim,fe_degree,n_q_points_1d,number> LevelMatrixType;
+
+  MGLevelObject<LevelMatrixType> mg_matrices;
+  mg_matrices.resize(0, dof.get_triangulation().n_global_levels()-1);
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    mg_matrices[level].initialize(mapping, dof, level);
+
+
+  MGCoarseIterative<LevelMatrixType,number> mg_coarse;
+  mg_coarse.initialize(mg_matrices[0]);
+
+  typedef PreconditionChebyshev<LevelMatrixType,parallel::distributed::Vector<number> > SMOOTHER;
+  MGSmootherPrecondition<LevelMatrixType, SMOOTHER, parallel::distributed::Vector<number> >
+  mg_smoother;
+
+  MGLevelObject<typename SMOOTHER::AdditionalData> smoother_data;
+  smoother_data.resize(0, dof.get_triangulation().n_global_levels()-1);
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    {
+      smoother_data[level].smoothing_range = 20.;
+      smoother_data[level].degree = 5;
+      smoother_data[level].eig_cg_n_iterations = 15;
+      smoother_data[level].matrix_diagonal_inverse =
+        mg_matrices[level].get_matrix_diagonal_inverse();
+    }
+  mg_smoother.initialize(mg_matrices, smoother_data);
+
+  MGTransferMF<LevelMatrixType> mg_transfer(mg_matrices);
+  mg_transfer.build_matrices(dof);
+
+  mg::Matrix<parallel::distributed::Vector<double> >
+  mg_matrix(mg_matrices);
+
+  Multigrid<parallel::distributed::Vector<double> > mg(dof,
+                                                       mg_matrix,
+                                                       mg_coarse,
+                                                       mg_transfer,
+                                                       mg_smoother,
+                                                       mg_smoother);
+  PreconditionMG<dim, parallel::distributed::Vector<double>,
+                 MGTransferMF<LevelMatrixType> >
+                 preconditioner(dof, mg, mg_transfer);
+
+  {
+    ReductionControl control(30, 1e-20, 1e-10);
+    SolverCG<parallel::distributed::Vector<double> > solver(control);
+    solver.solve(fine_matrix, sol, in, preconditioner);
+  }
+}
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  for (int i=5; i<9-fe_degree; ++i)
+    {
+      parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD,
+                                                     dealii::Triangulation<dim>::none,
+                                                     parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy);
+      GridGenerator::hyper_cube (tria);
+      // set boundary ids on boundaries to the number of the face
+      for (unsigned int face=2; face<GeometryInfo<dim>::faces_per_cell; ++face)
+        tria.begin()->face(face)->set_all_boundary_ids(face);
+
+      std::vector<GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator> >
+      periodic_faces;
+      for (unsigned int d=1; d<dim; ++d)
+        GridTools::collect_periodic_faces(tria, 2*d, 2*d+1, d, periodic_faces);
+      tria.add_periodicity(periodic_faces);
+
+      tria.refine_global(i-dim);
+
+      FE_DGQ<dim> fe (fe_degree);
+      DoFHandler<dim> dof (tria);
+      dof.distribute_dofs(fe);
+      dof.distribute_mg_dofs(fe);
+
+      do_test<dim, fe_degree, fe_degree+1, double> (dof);
+    }
+}
+
+
+
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1);
+  mpi_initlog();
+
+  {
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=1.output b/tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..9465de8
--- /dev/null
@@ -0,0 +1,41 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 256
+DEAL:2d:cg::Starting value 16.0000
+DEAL:2d:cg::Convergence step 6 value 3.31973e-12
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 1024
+DEAL:2d:cg::Starting value 32.0000
+DEAL:2d:cg::Convergence step 6 value 1.50088e-09
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 4096
+DEAL:2d:cg::Starting value 64.0000
+DEAL:2d:cg::Convergence step 7 value 7.89595e-10
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 576
+DEAL:2d:cg::Starting value 24.0000
+DEAL:2d:cg::Convergence step 6 value 2.18769e-10
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 2304
+DEAL:2d:cg::Starting value 48.0000
+DEAL:2d:cg::Convergence step 6 value 1.04858e-09
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 512
+DEAL:3d:cg::Starting value 22.6274
+DEAL:3d:cg::Convergence step 4 value 1.39603e-17
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 4096
+DEAL:3d:cg::Starting value 64.0000
+DEAL:3d:cg::Convergence step 6 value 2.68072e-11
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 32768
+DEAL:3d:cg::Starting value 181.019
+DEAL:3d:cg::Convergence step 7 value 8.70647e-10
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 1728
+DEAL:3d:cg::Starting value 41.5692
+DEAL:3d:cg::Convergence step 7 value 1.39310e-09
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 13824
+DEAL:3d:cg::Starting value 117.576
+DEAL:3d:cg::Convergence step 8 value 1.40299e-09
diff --git a/tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..07dcc35
--- /dev/null
@@ -0,0 +1,41 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 256
+DEAL:2d:cg::Starting value 16.0000
+DEAL:2d:cg::Convergence step 6 value 3.31973e-12
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 1024
+DEAL:2d:cg::Starting value 32.0000
+DEAL:2d:cg::Convergence step 6 value 1.50088e-09
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 4096
+DEAL:2d:cg::Starting value 64.0000
+DEAL:2d:cg::Convergence step 7 value 7.89595e-10
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 576
+DEAL:2d:cg::Starting value 24.0000
+DEAL:2d:cg::Convergence step 6 value 2.18769e-10
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 2304
+DEAL:2d:cg::Starting value 48.0000
+DEAL:2d:cg::Convergence step 6 value 1.04858e-09
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 512
+DEAL:3d:cg::Starting value 22.6274
+DEAL:3d:cg::Convergence step 4 value 1.45014e-17
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 4096
+DEAL:3d:cg::Starting value 64.0000
+DEAL:3d:cg::Convergence step 6 value 2.68072e-11
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 32768
+DEAL:3d:cg::Starting value 181.019
+DEAL:3d:cg::Convergence step 7 value 8.70647e-10
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 1728
+DEAL:3d:cg::Starting value 41.5692
+DEAL:3d:cg::Convergence step 7 value 1.39310e-09
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 13824
+DEAL:3d:cg::Starting value 117.576
+DEAL:3d:cg::Convergence step 8 value 1.40299e-09
diff --git a/tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/multigrid_dg_periodic.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..6d3556b
--- /dev/null
@@ -0,0 +1,41 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 256
+DEAL:2d:cg::Starting value 16.0000
+DEAL:2d:cg::Convergence step 6 value 3.31973e-12
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 1024
+DEAL:2d:cg::Starting value 32.0000
+DEAL:2d:cg::Convergence step 6 value 1.50088e-09
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 4096
+DEAL:2d:cg::Starting value 64.0000
+DEAL:2d:cg::Convergence step 7 value 7.89595e-10
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 576
+DEAL:2d:cg::Starting value 24.0000
+DEAL:2d:cg::Convergence step 6 value 2.18769e-10
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 2304
+DEAL:2d:cg::Starting value 48.0000
+DEAL:2d:cg::Convergence step 6 value 1.04858e-09
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 512
+DEAL:3d:cg::Starting value 22.6274
+DEAL:3d:cg::Convergence step 4 value 1.18679e-17
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 4096
+DEAL:3d:cg::Starting value 64.0000
+DEAL:3d:cg::Convergence step 6 value 2.68072e-11
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 32768
+DEAL:3d:cg::Starting value 181.019
+DEAL:3d:cg::Convergence step 7 value 8.70647e-10
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 1728
+DEAL:3d:cg::Starting value 41.5692
+DEAL:3d:cg::Convergence step 7 value 1.39310e-09
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 13824
+DEAL:3d:cg::Starting value 117.576
+DEAL:3d:cg::Convergence step 8 value 1.40299e-09
diff --git a/tests/matrix_free/multigrid_dg_sip_01.cc b/tests/matrix_free/multigrid_dg_sip_01.cc
new file mode 100644 (file)
index 0000000..5fe468a
--- /dev/null
@@ -0,0 +1,595 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// test of a multigrid solver including face integration (DG case, symmetric
+// interior penalty + Nitsche).
+
+#include "../tests.h"
+
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/solver_cg.h>
+#include <deal.II/lac/precondition.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/mapping_q.h>
+#include <deal.II/numerics/vector_tools.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/multigrid/multigrid.h>
+#include <deal.II/multigrid/mg_transfer_matrix_free.h>
+#include <deal.II/multigrid/mg_tools.h>
+#include <deal.II/multigrid/mg_smoother.h>
+#include <deal.II/multigrid/mg_matrix.h>
+
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+
+std::ofstream logfile("output");
+
+
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double>
+class LaplaceOperator : public Subscriptor
+{
+public:
+  typedef number value_type;
+
+  LaplaceOperator() {};
+
+  void initialize (const Mapping<dim> &mapping,
+                   const DoFHandler<dim> &dof_handler,
+                   const unsigned int level = numbers::invalid_unsigned_int)
+  {
+    const QGauss<1> quad (n_q_points_1d);
+    typename MatrixFree<dim,number>::AdditionalData addit_data;
+    addit_data.tasks_parallel_scheme = MatrixFree<dim,number>::AdditionalData::none;
+    addit_data.tasks_block_size = 3;
+    addit_data.level_mg_handler = level;
+    addit_data.mapping_update_flags_inner_faces = (update_gradients | update_JxW_values);
+    addit_data.mapping_update_flags_boundary_faces = (update_gradients | update_JxW_values);
+    ConstraintMatrix constraints;
+    constraints.close();
+
+    data.reinit (mapping, dof_handler, constraints, quad, addit_data);
+
+    compute_inverse_diagonal();
+  }
+
+  void vmult(parallel::distributed::Vector<number> &dst,
+             const parallel::distributed::Vector<number> &src) const
+  {
+    dst = 0;
+    vmult_add(dst, src);
+  }
+
+  void Tvmult(parallel::distributed::Vector<number> &dst,
+              const parallel::distributed::Vector<number> &src) const
+  {
+    dst = 0;
+    vmult_add(dst, src);
+  }
+
+  void Tvmult_add(parallel::distributed::Vector<number> &dst,
+                  const parallel::distributed::Vector<number> &src) const
+  {
+    vmult_add(dst, src);
+  }
+
+  void vmult_add(parallel::distributed::Vector<number> &dst,
+                 const parallel::distributed::Vector<number> &src) const
+  {
+    if (!src.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner))
+      {
+        parallel::distributed::Vector<number> src_copy;
+        src_copy.reinit(data.get_dof_info().vector_partitioner);
+        src_copy = src;
+        const_cast<parallel::distributed::Vector<number> &>(src).swap(src_copy);
+      }
+    if (!dst.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner))
+      {
+        parallel::distributed::Vector<number> dst_copy;
+        dst_copy.reinit(data.get_dof_info().vector_partitioner);
+        dst_copy = dst;
+        dst.swap(dst_copy);
+      }
+    dst.zero_out_ghosts();
+    data.loop (&LaplaceOperator::local_apply,
+               &LaplaceOperator::local_apply_face,
+               &LaplaceOperator::local_apply_boundary,
+               this, dst, src);
+  }
+
+  types::global_dof_index m() const
+  {
+    return data.get_vector_partitioner()->size();
+  }
+
+  types::global_dof_index n() const
+  {
+    return data.get_vector_partitioner()->size();
+  }
+
+  number el (const unsigned int row,  const unsigned int col) const
+  {
+    AssertThrow(false, ExcMessage("Matrix-free does not allow for entry access"));
+    return number();
+  }
+
+  void
+  initialize_dof_vector(parallel::distributed::Vector<number> &vector) const
+  {
+    data.initialize_dof_vector(vector);
+  }
+
+  const parallel::distributed::Vector<number> &
+  get_matrix_diagonal_inverse() const
+  {
+    return inverse_diagonal_entries;
+  }
+
+
+private:
+  void
+  local_apply (const MatrixFree<dim,number>                &data,
+               parallel::distributed::Vector<number>       &dst,
+               const parallel::distributed::Vector<number> &src,
+               const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+        phi.read_dof_values(src);
+        phi.evaluate (false,true,false);
+        for (unsigned int q=0; q<phi.n_q_points; ++q)
+          phi.submit_gradient (phi.get_gradient(q), q);
+        phi.integrate (false,true);
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  void
+  local_apply_face (const MatrixFree<dim,number>                &data,
+                    parallel::distributed::Vector<number>       &dst,
+                    const parallel::distributed::Vector<number> &src,
+                    const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval_neighbor(data,false);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval_neighbor.reinit (face);
+
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        fe_eval_neighbor.read_dof_values(src);
+        fe_eval_neighbor.evaluate(true,true);
+        VectorizedArray<number> sigmaF =
+          (std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) +
+           std::abs((fe_eval.get_normal_vector(0)*fe_eval_neighbor.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0));
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            VectorizedArray<number> average_value = (fe_eval.get_value(q)-
+                                                     fe_eval_neighbor.get_value(q)) * 0.5;
+            VectorizedArray<number> average_valgrad =
+              fe_eval.get_normal_derivative(q) +
+              fe_eval_neighbor.get_normal_derivative(q);
+            average_valgrad = average_value * 2. * sigmaF -
+                              average_valgrad * 0.5;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval_neighbor.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+            fe_eval_neighbor.submit_value(-average_valgrad,q);
+          }
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+        fe_eval_neighbor.integrate(true,true);
+        fe_eval_neighbor.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_apply_boundary (const MatrixFree<dim,number>                &data,
+                        parallel::distributed::Vector<number>       &dst,
+                        const parallel::distributed::Vector<number> &src,
+                        const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval(data, true);
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        VectorizedArray<number> sigmaF = std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) *
+                                         number(std::max(fe_degree, 1) * (fe_degree+1.0)) * 2.0;
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            VectorizedArray<number> average_value = fe_eval.get_value(q);
+            VectorizedArray<number> average_valgrad = -fe_eval.get_normal_derivative(q);
+            average_valgrad += average_value * sigmaF * 2.0;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+          }
+
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  compute_inverse_diagonal ()
+  {
+    data.initialize_dof_vector(inverse_diagonal_entries);
+    unsigned int dummy;
+    data.loop (&LaplaceOperator::local_diagonal_cell,
+               &LaplaceOperator::local_diagonal_face,
+               &LaplaceOperator::local_diagonal_boundary,
+               this, inverse_diagonal_entries, dummy);
+
+    for (unsigned int i=0; i<inverse_diagonal_entries.local_size(); ++i)
+      if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10)
+        inverse_diagonal_entries.local_element(i) = 1./inverse_diagonal_entries.local_element(i);
+  }
+
+  void
+  local_diagonal_cell (const MatrixFree<dim,number>                &data,
+                       parallel::distributed::Vector<number>       &dst,
+                       const unsigned int &,
+                       const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate (false,true,false);
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              phi.submit_gradient (phi.get_gradient(q), q);
+            phi.integrate (false,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.static_dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  void
+  local_diagonal_face (const MatrixFree<dim,number>                &data,
+                       parallel::distributed::Vector<number>       &dst,
+                       const unsigned int &,
+                       const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi_outer(data,false);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi.reinit (face);
+        phi_outer.reinit (face);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        VectorizedArray<number> sigmaF =
+          (std::abs((phi.get_normal_vector(0)*phi.inverse_jacobian(0))[dim-1]) +
+           std::abs((phi.get_normal_vector(0)*phi_outer.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0));
+
+        // Compute phi part
+        for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+          phi_outer.begin_dof_values()[j] = VectorizedArray<number>();
+        phi_outer.evaluate(true, true);
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = (phi.get_value(q)-
+                                                         phi_outer.get_value(q)) * 0.5;
+                VectorizedArray<number> average_valgrad =
+                  phi.get_normal_derivative(q) +
+                  phi_outer.get_normal_derivative(q);
+                average_valgrad = average_value * 2. * sigmaF -
+                                  average_valgrad * 0.5;
+                phi.submit_normal_derivative(-average_value,q);
+                phi.submit_value(average_valgrad,q);
+              }
+            phi.integrate(true,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global(dst);
+
+        // Compute phi_outer part
+        for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+          phi.begin_dof_values()[j] = VectorizedArray<number>();
+        phi.evaluate(true, true);
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi_outer.begin_dof_values()[j] = VectorizedArray<number>();
+            phi_outer.begin_dof_values()[i] = 1.;
+            phi_outer.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = (phi.get_value(q)-
+                                                         phi_outer.get_value(q)) * 0.5;
+                VectorizedArray<number> average_valgrad =
+                  phi.get_normal_derivative(q) +
+                  phi_outer.get_normal_derivative(q);
+                average_valgrad = average_value * 2. * sigmaF -
+                                  average_valgrad * 0.5;
+                phi_outer.submit_normal_derivative(-average_value,q);
+                phi_outer.submit_value(-average_valgrad,q);
+              }
+            phi_outer.integrate(true,true);
+            local_diagonal_vector[i] = phi_outer.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi_outer.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi_outer.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_diagonal_boundary (const MatrixFree<dim,number>                &data,
+                           parallel::distributed::Vector<number>       &dst,
+                           const unsigned int &,
+                           const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        phi.reinit (face);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        VectorizedArray<number> sigmaF = std::abs((phi.get_normal_vector(0)*phi.inverse_jacobian(0))[dim-1]) *
+                                         number(std::max(fe_degree, 1) * (fe_degree+1.0)) * 2.0;
+
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate(true,true);
+
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              {
+                VectorizedArray<number> average_value = phi.get_value(q);
+                VectorizedArray<number> average_valgrad = -phi.get_normal_derivative(q);
+                average_valgrad += average_value * sigmaF * 2.0;
+                phi.submit_normal_derivative(-average_value,q);
+                phi.submit_value(average_valgrad,q);
+              }
+
+            phi.integrate(true,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global(dst);
+      }
+  }
+
+
+  MatrixFree<dim,number> data;
+  parallel::distributed::Vector<number> inverse_diagonal_entries;
+};
+
+
+
+template<typename MATRIX, typename Number>
+class MGCoarseIterative : public MGCoarseGridBase<parallel::distributed::Vector<Number> >
+{
+public:
+  MGCoarseIterative() {}
+
+  void initialize(const MATRIX &matrix)
+  {
+    coarse_matrix = &matrix;
+  }
+
+  virtual void operator() (const unsigned int,
+                           parallel::distributed::Vector<double> &dst,
+                           const parallel::distributed::Vector<double> &src) const
+  {
+    ReductionControl solver_control (1e4, 1e-50, 1e-10, false, false);
+    SolverCG<parallel::distributed::Vector<double> > solver_coarse (solver_control);
+    solver_coarse.solve (*coarse_matrix, dst, src, PreconditionIdentity());
+  }
+
+  const MATRIX *coarse_matrix;
+};
+
+
+
+template <int dim, typename LAPLACEOPERATOR>
+class MGTransferMF : public MGTransferMatrixFree<dim, typename LAPLACEOPERATOR::value_type>
+{
+public:
+  MGTransferMF(const MGLevelObject<LAPLACEOPERATOR> &laplace,
+               const MGConstrainedDoFs &mg_constrained_dofs)
+    :
+    MGTransferMatrixFree<dim, typename LAPLACEOPERATOR::value_type>(mg_constrained_dofs),
+    laplace_operator (laplace)
+  {};
+
+  /**
+   * Overload copy_to_mg from MGTransferPrebuilt
+   */
+  template <class InVector, int spacedim>
+  void
+  copy_to_mg (const DoFHandler<dim,spacedim> &mg_dof_handler,
+              MGLevelObject<LinearAlgebra::distributed::Vector<typename LAPLACEOPERATOR::value_type> > &dst,
+              const InVector &src) const
+  {
+    for (unsigned int level=dst.min_level();
+         level<=dst.max_level(); ++level)
+      laplace_operator[level].initialize_dof_vector(dst[level]);
+    MGTransferMatrixFree<dim, typename LAPLACEOPERATOR::value_type>::
+    copy_to_mg(mg_dof_handler, dst, src);
+  }
+
+private:
+  const MGLevelObject<LAPLACEOPERATOR> &laplace_operator;
+};
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d, typename number>
+void do_test (const DoFHandler<dim>  &dof,
+              const bool              also_test_parallel = false)
+{
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+
+  MappingQ<dim> mapping(fe_degree+1);
+  LaplaceOperator<dim,fe_degree,n_q_points_1d,number> fine_matrix;
+  fine_matrix.initialize(mapping, dof);
+
+  parallel::distributed::Vector<number> in, sol;
+  fine_matrix.initialize_dof_vector(in);
+  fine_matrix.initialize_dof_vector(sol);
+
+  in = 1.;
+
+  // set up multigrid in analogy to step-37
+  typedef LaplaceOperator<dim,fe_degree,n_q_points_1d,number> LevelMatrixType;
+
+  MGLevelObject<LevelMatrixType> mg_matrices;
+  mg_matrices.resize(0, dof.get_triangulation().n_global_levels()-1);
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    {
+      mg_matrices[level].initialize(mapping, dof, level);
+    }
+
+  MGCoarseIterative<LevelMatrixType,number> mg_coarse;
+  mg_coarse.initialize(mg_matrices[0]);
+
+  typedef PreconditionChebyshev<LevelMatrixType,parallel::distributed::Vector<number> > SMOOTHER;
+  MGSmootherPrecondition<LevelMatrixType, SMOOTHER, parallel::distributed::Vector<number> >
+  mg_smoother;
+
+  MGLevelObject<typename SMOOTHER::AdditionalData> smoother_data;
+  smoother_data.resize(0, dof.get_triangulation().n_global_levels()-1);
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    {
+      smoother_data[level].smoothing_range = 20.;
+      smoother_data[level].degree = 5;
+      smoother_data[level].eig_cg_n_iterations = 15;
+      smoother_data[level].matrix_diagonal_inverse =
+        mg_matrices[level].get_matrix_diagonal_inverse();
+    }
+  mg_smoother.initialize(mg_matrices, smoother_data);
+
+  MGConstrainedDoFs mg_constrained_dofs;
+  ZeroFunction<dim> zero_function;
+  typename FunctionMap<dim>::type dirichlet_boundary;
+  dirichlet_boundary[0] = &zero_function;
+  mg_constrained_dofs.initialize(dof, dirichlet_boundary);
+
+  MGTransferMF<dim,LevelMatrixType> mg_transfer(mg_matrices,
+                                                mg_constrained_dofs);
+  mg_transfer.build(dof);
+
+  mg::Matrix<parallel::distributed::Vector<double> >
+  mg_matrix(mg_matrices);
+
+  Multigrid<parallel::distributed::Vector<double> > mg(dof,
+                                                       mg_matrix,
+                                                       mg_coarse,
+                                                       mg_transfer,
+                                                       mg_smoother,
+                                                       mg_smoother);
+  PreconditionMG<dim, parallel::distributed::Vector<double>,
+                 MGTransferMF<dim,LevelMatrixType> >
+                 preconditioner(dof, mg, mg_transfer);
+
+  {
+    ReductionControl control(30, 1e-20, 1e-7);
+    SolverCG<parallel::distributed::Vector<double> > solver(control);
+    solver.solve(fine_matrix, sol, in, preconditioner);
+  }
+}
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  for (int i=5; i<9-fe_degree; ++i)
+    {
+      parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD,
+                                                     dealii::Triangulation<dim>::none,parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy);
+      GridGenerator::hyper_cube (tria);
+      tria.refine_global(i-dim);
+
+      FE_DGQ<dim> fe (fe_degree);
+      DoFHandler<dim> dof (tria);
+      dof.distribute_dofs(fe);
+      dof.distribute_mg_dofs(fe);
+
+      do_test<dim, fe_degree, fe_degree+1, double> (dof, true);
+    }
+}
+
+
+
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1);
+  mpi_initlog();
+
+  {
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/multigrid_dg_sip_01.with_mpi=true.with_p4est=true.mpirun=1.output b/tests/matrix_free/multigrid_dg_sip_01.with_mpi=true.with_p4est=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..29dbbfa
--- /dev/null
@@ -0,0 +1,41 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 256
+DEAL:2d:cg::Starting value 16.0000
+DEAL:2d:cg::Convergence step 4 value 1.45213e-06
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 1024
+DEAL:2d:cg::Starting value 32.0000
+DEAL:2d:cg::Convergence step 5 value 8.09074e-08
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 4096
+DEAL:2d:cg::Starting value 64.0000
+DEAL:2d:cg::Convergence step 5 value 9.08540e-07
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 576
+DEAL:2d:cg::Starting value 24.0000
+DEAL:2d:cg::Convergence step 5 value 4.02774e-08
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 2304
+DEAL:2d:cg::Starting value 48.0000
+DEAL:2d:cg::Convergence step 5 value 7.58404e-08
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 512
+DEAL:3d:cg::Starting value 22.6274
+DEAL:3d:cg::Convergence step 5 value 2.70681e-07
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 4096
+DEAL:3d:cg::Starting value 64.0000
+DEAL:3d:cg::Convergence step 5 value 3.69638e-06
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 32768
+DEAL:3d:cg::Starting value 181.019
+DEAL:3d:cg::Convergence step 5 value 5.56024e-06
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 1728
+DEAL:3d:cg::Starting value 41.5692
+DEAL:3d:cg::Convergence step 5 value 5.30416e-07
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 13824
+DEAL:3d:cg::Starting value 117.576
+DEAL:3d:cg::Convergence step 6 value 8.58800e-07
diff --git a/tests/matrix_free/multigrid_dg_sip_01.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/multigrid_dg_sip_01.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..29dbbfa
--- /dev/null
@@ -0,0 +1,41 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 256
+DEAL:2d:cg::Starting value 16.0000
+DEAL:2d:cg::Convergence step 4 value 1.45213e-06
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 1024
+DEAL:2d:cg::Starting value 32.0000
+DEAL:2d:cg::Convergence step 5 value 8.09074e-08
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 4096
+DEAL:2d:cg::Starting value 64.0000
+DEAL:2d:cg::Convergence step 5 value 9.08540e-07
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 576
+DEAL:2d:cg::Starting value 24.0000
+DEAL:2d:cg::Convergence step 5 value 4.02774e-08
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 2304
+DEAL:2d:cg::Starting value 48.0000
+DEAL:2d:cg::Convergence step 5 value 7.58404e-08
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 512
+DEAL:3d:cg::Starting value 22.6274
+DEAL:3d:cg::Convergence step 5 value 2.70681e-07
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 4096
+DEAL:3d:cg::Starting value 64.0000
+DEAL:3d:cg::Convergence step 5 value 3.69638e-06
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 32768
+DEAL:3d:cg::Starting value 181.019
+DEAL:3d:cg::Convergence step 5 value 5.56024e-06
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 1728
+DEAL:3d:cg::Starting value 41.5692
+DEAL:3d:cg::Convergence step 5 value 5.30416e-07
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 13824
+DEAL:3d:cg::Starting value 117.576
+DEAL:3d:cg::Convergence step 6 value 8.58800e-07
diff --git a/tests/matrix_free/multigrid_dg_sip_02.cc b/tests/matrix_free/multigrid_dg_sip_02.cc
new file mode 100644 (file)
index 0000000..d4cd524
--- /dev/null
@@ -0,0 +1,510 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// test of a multigrid solver including face integration (DG case, symmetric
+// interior penalty + Nitsche). As opposed to multigrid_dg_sip_01, this test
+// computes the diagonal using the alternative reinit(cell_index, face_number)
+
+#include "../tests.h"
+
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/utilities.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/solver_cg.h>
+#include <deal.II/lac/precondition.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/mapping_q.h>
+#include <deal.II/numerics/vector_tools.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/multigrid/multigrid.h>
+#include <deal.II/multigrid/mg_transfer_matrix_free.h>
+#include <deal.II/multigrid/mg_tools.h>
+#include <deal.II/multigrid/mg_smoother.h>
+#include <deal.II/multigrid/mg_matrix.h>
+
+#include <deal.II/matrix_free/matrix_free.h>
+#include <deal.II/matrix_free/fe_evaluation.h>
+
+std::ofstream logfile("output");
+
+
+template <int dim, int fe_degree, int n_q_points_1d = fe_degree+1, typename number=double>
+class LaplaceOperator : public Subscriptor
+{
+public:
+  typedef number value_type;
+
+  LaplaceOperator() {};
+
+  void initialize (const Mapping<dim> &mapping,
+                   const DoFHandler<dim> &dof_handler,
+                   const unsigned int level = numbers::invalid_unsigned_int)
+  {
+    const QGauss<1> quad (n_q_points_1d);
+    typename MatrixFree<dim,number>::AdditionalData addit_data;
+    addit_data.tasks_parallel_scheme = MatrixFree<dim,number>::AdditionalData::none;
+    addit_data.tasks_block_size = 3;
+    addit_data.level_mg_handler = level;
+    addit_data.mapping_update_flags_inner_faces = update_JxW_values | update_normal_vectors | update_jacobians;
+    addit_data.mapping_update_flags_boundary_faces = update_JxW_values | update_normal_vectors | update_jacobians;
+    addit_data.mapping_update_flags_faces_by_cells = update_JxW_values | update_normal_vectors | update_jacobians;
+    ConstraintMatrix constraints;
+    constraints.close();
+
+    data.reinit (mapping, dof_handler, constraints, quad, addit_data);
+
+    compute_inverse_diagonal();
+  }
+
+  void vmult(parallel::distributed::Vector<number> &dst,
+             const parallel::distributed::Vector<number> &src) const
+  {
+    dst = 0;
+    vmult_add(dst, src);
+  }
+
+  void Tvmult(parallel::distributed::Vector<number> &dst,
+              const parallel::distributed::Vector<number> &src) const
+  {
+    dst = 0;
+    vmult_add(dst, src);
+  }
+
+  void Tvmult_add(parallel::distributed::Vector<number> &dst,
+                  const parallel::distributed::Vector<number> &src) const
+  {
+    vmult_add(dst, src);
+  }
+
+  void vmult_add(parallel::distributed::Vector<number> &dst,
+                 const parallel::distributed::Vector<number> &src) const
+  {
+    if (!src.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner))
+      {
+        parallel::distributed::Vector<number> src_copy;
+        src_copy.reinit(data.get_dof_info().vector_partitioner);
+        src_copy = src;
+        const_cast<parallel::distributed::Vector<number> &>(src).swap(src_copy);
+      }
+    if (!dst.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner))
+      {
+        parallel::distributed::Vector<number> dst_copy;
+        dst_copy.reinit(data.get_dof_info().vector_partitioner);
+        dst_copy = dst;
+        dst.swap(dst_copy);
+      }
+    dst.zero_out_ghosts();
+    data.loop (&LaplaceOperator::local_apply,
+               &LaplaceOperator::local_apply_face,
+               &LaplaceOperator::local_apply_boundary,
+               this, dst, src);
+  }
+
+  types::global_dof_index m() const
+  {
+    return data.get_vector_partitioner()->size();
+  }
+
+  types::global_dof_index n() const
+  {
+    return data.get_vector_partitioner()->size();
+  }
+
+  number el (const unsigned int row,  const unsigned int col) const
+  {
+    AssertThrow(false, ExcMessage("Matrix-free does not allow for entry access"));
+    return number();
+  }
+
+  void
+  initialize_dof_vector(parallel::distributed::Vector<number> &vector) const
+  {
+    data.initialize_dof_vector(vector);
+  }
+
+  const parallel::distributed::Vector<number> &
+  get_matrix_diagonal_inverse() const
+  {
+    return inverse_diagonal_entries;
+  }
+
+
+private:
+  void
+  local_apply (const MatrixFree<dim,number>                &data,
+               parallel::distributed::Vector<number>       &dst,
+               const parallel::distributed::Vector<number> &src,
+               const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+        phi.read_dof_values(src);
+        phi.evaluate (false,true,false);
+        for (unsigned int q=0; q<phi.n_q_points; ++q)
+          phi.submit_gradient (phi.get_gradient(q), q);
+        phi.integrate (false,true);
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  void
+  local_apply_face (const MatrixFree<dim,number>                &data,
+                    parallel::distributed::Vector<number>       &dst,
+                    const parallel::distributed::Vector<number> &src,
+                    const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval(data,true);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval_neighbor(data,false);
+
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval_neighbor.reinit (face);
+
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        fe_eval_neighbor.read_dof_values(src);
+        fe_eval_neighbor.evaluate(true,true);
+        VectorizedArray<number> sigmaF =
+          (std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) +
+           std::abs((fe_eval.get_normal_vector(0)*fe_eval_neighbor.inverse_jacobian(0))[dim-1])) *
+          (number)(std::max(fe_degree,1) * (fe_degree + 1.0));
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            VectorizedArray<number> average_value = (fe_eval.get_value(q)-
+                                                     fe_eval_neighbor.get_value(q)) * 0.5;
+            VectorizedArray<number> average_valgrad =
+              fe_eval.get_normal_derivative(q) +
+              fe_eval_neighbor.get_normal_derivative(q);
+            average_valgrad = average_value * 2. * sigmaF -
+                              average_valgrad * 0.5;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval_neighbor.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+            fe_eval_neighbor.submit_value(-average_valgrad,q);
+          }
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+        fe_eval_neighbor.integrate(true,true);
+        fe_eval_neighbor.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  local_apply_boundary (const MatrixFree<dim,number>                &data,
+                        parallel::distributed::Vector<number>       &dst,
+                        const parallel::distributed::Vector<number> &src,
+                        const std::pair<unsigned int,unsigned int>  &face_range) const
+  {
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> fe_eval(data, true);
+    for (unsigned int face=face_range.first; face<face_range.second; face++)
+      {
+        fe_eval.reinit (face);
+        fe_eval.read_dof_values(src);
+        fe_eval.evaluate(true,true);
+        VectorizedArray<number> sigmaF =
+          std::abs((fe_eval.get_normal_vector(0)*fe_eval.inverse_jacobian(0))[dim-1]) *
+          (number)(std::max(1,fe_degree) * (fe_degree + 1.0)) * 2.;
+
+        for (unsigned int q=0; q<fe_eval.n_q_points; ++q)
+          {
+            VectorizedArray<number> average_value = fe_eval.get_value(q);
+            VectorizedArray<number> average_valgrad = -fe_eval.get_normal_derivative(q);
+            average_valgrad += average_value * sigmaF * 2.0;
+            fe_eval.submit_normal_derivative(-average_value,q);
+            fe_eval.submit_value(average_valgrad,q);
+          }
+
+        fe_eval.integrate(true,true);
+        fe_eval.distribute_local_to_global(dst);
+      }
+  }
+
+  void
+  compute_inverse_diagonal ()
+  {
+    data.initialize_dof_vector(inverse_diagonal_entries);
+    unsigned int dummy;
+    data.cell_loop (&LaplaceOperator::local_diagonal_cell,
+                    this, inverse_diagonal_entries, dummy);
+
+    for (unsigned int i=0; i<inverse_diagonal_entries.local_size(); ++i)
+      if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10)
+        inverse_diagonal_entries.local_element(i) = 1./inverse_diagonal_entries.local_element(i);
+  }
+
+  void
+  local_diagonal_cell (const MatrixFree<dim,number>                &data,
+                       parallel::distributed::Vector<number>       &dst,
+                       const unsigned int &,
+                       const std::pair<unsigned int,unsigned int>  &cell_range) const
+  {
+    FEEvaluation<dim,fe_degree,n_q_points_1d,1,number> phi (data);
+    FEFaceEvaluation<dim,fe_degree,n_q_points_1d,1,number> phif (data);
+
+    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
+      {
+        phi.reinit (cell);
+
+        VectorizedArray<number> local_diagonal_vector[phi.static_dofs_per_cell];
+        for (unsigned int i=0; i<phi.dofs_per_cell; ++i)
+          {
+            for (unsigned int j=0; j<phi.dofs_per_cell; ++j)
+              phi.begin_dof_values()[j] = VectorizedArray<number>();
+            phi.begin_dof_values()[i] = 1.;
+            phi.evaluate (false,true,false);
+            for (unsigned int q=0; q<phi.n_q_points; ++q)
+              phi.submit_gradient (phi.get_gradient(q), q);
+            phi.integrate (false,true);
+            local_diagonal_vector[i] = phi.begin_dof_values()[i];
+          }
+        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+          {
+            phif.reinit(cell, face);
+            VectorizedArray<number> sigmaF =
+              std::abs((phif.get_normal_vector(0)*phif.inverse_jacobian(0))[dim-1]) *
+              (number)(std::max(1,fe_degree) * (fe_degree + 1.0)) * 2.;
+            std::array<types::boundary_id,VectorizedArray<number>::n_array_elements>
+            boundary_ids = data.get_faces_by_cells_boundary_id(cell, face);
+            VectorizedArray<number> factor_boundary;
+            for (unsigned int v=0; v<VectorizedArray<number>::n_array_elements; ++v)
+              // interior face
+              if (boundary_ids[v] == numbers::invalid_boundary_id)
+                factor_boundary[v] = 0.5;
+            // Dirichlet boundary
+              else
+                factor_boundary[v] = 1.0;
+            for (unsigned int i=0; i<phif.dofs_per_cell; ++i)
+              {
+                for (unsigned int j=0; j<phif.dofs_per_cell; ++j)
+                  phif.begin_dof_values()[j] = VectorizedArray<number>();
+                phif.begin_dof_values()[i] = 1.;
+                phif.evaluate(true,true);
+                for (unsigned int q=0; q<phif.n_q_points; ++q)
+                  {
+                    VectorizedArray<number> average_value = phif.get_value(q) * factor_boundary;
+                    VectorizedArray<number> average_valgrad =
+                      phif.get_normal_derivative(q) * factor_boundary;
+                    average_valgrad = average_value * 2. * sigmaF -
+                                      average_valgrad;
+                    phif.submit_normal_derivative(-average_value,q);
+                    phif.submit_value(average_valgrad,q);
+                  }
+                phif.integrate(true,true);
+                local_diagonal_vector[i] += phif.begin_dof_values()[i];
+              }
+          }
+        for (unsigned int i=0; i<phi.static_dofs_per_cell; ++i)
+          phi.begin_dof_values()[i] = local_diagonal_vector[i];
+        phi.distribute_local_to_global (dst);
+      }
+  }
+
+  MatrixFree<dim,number> data;
+  parallel::distributed::Vector<number> inverse_diagonal_entries;
+};
+
+
+
+template<typename MATRIX, typename Number>
+class MGCoarseIterative : public MGCoarseGridBase<parallel::distributed::Vector<Number> >
+{
+public:
+  MGCoarseIterative() {}
+
+  void initialize(const MATRIX &matrix)
+  {
+    coarse_matrix = &matrix;
+  }
+
+  virtual void operator() (const unsigned int   ,
+                           parallel::distributed::Vector<double> &dst,
+                           const parallel::distributed::Vector<double> &src) const
+  {
+    ReductionControl solver_control (1e4, 1e-50, 1e-10, false, false);
+    SolverCG<parallel::distributed::Vector<double> > solver_coarse (solver_control);
+    solver_coarse.solve (*coarse_matrix, dst, src, PreconditionIdentity());
+  }
+
+  const MATRIX *coarse_matrix;
+};
+
+
+
+template <int dim, typename LAPLACEOPERATOR>
+class MGTransferMF : public MGTransferMatrixFree<dim, typename LAPLACEOPERATOR::value_type>
+{
+public:
+  MGTransferMF(const MGLevelObject<LAPLACEOPERATOR> &laplace,
+               const MGConstrainedDoFs &mg_constrained_dofs)
+    :
+    MGTransferMatrixFree<dim, typename LAPLACEOPERATOR::value_type>(mg_constrained_dofs),
+    laplace_operator (laplace)
+  {};
+
+  /**
+   * Overload copy_to_mg from MGTransferPrebuilt
+   */
+  template <class InVector, int spacedim>
+  void
+  copy_to_mg (const DoFHandler<dim,spacedim> &mg_dof_handler,
+              MGLevelObject<LinearAlgebra::distributed::Vector<typename LAPLACEOPERATOR::value_type> > &dst,
+              const InVector &src) const
+  {
+    for (unsigned int level=dst.min_level();
+         level<=dst.max_level(); ++level)
+      laplace_operator[level].initialize_dof_vector(dst[level]);
+    MGTransferMatrixFree<dim, typename LAPLACEOPERATOR::value_type>::
+    copy_to_mg(mg_dof_handler, dst, src);
+  }
+
+private:
+  const MGLevelObject<LAPLACEOPERATOR> &laplace_operator;
+};
+
+
+
+template <int dim, int fe_degree, int n_q_points_1d, typename number>
+void do_test (const DoFHandler<dim>  &dof,
+              const bool              also_test_parallel = false)
+{
+  deallog << "Testing " << dof.get_fe().get_name();
+  deallog << std::endl;
+  deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+
+  MappingQ<dim> mapping(fe_degree+1);
+  LaplaceOperator<dim,fe_degree,n_q_points_1d,number> fine_matrix;
+  fine_matrix.initialize(mapping, dof);
+
+  parallel::distributed::Vector<number> in, sol;
+  fine_matrix.initialize_dof_vector(in);
+  fine_matrix.initialize_dof_vector(sol);
+
+  in = 1.;
+
+  // set up multigrid in analogy to step-37
+  typedef LaplaceOperator<dim,fe_degree,n_q_points_1d,number> LevelMatrixType;
+
+  MGLevelObject<LevelMatrixType> mg_matrices;
+  mg_matrices.resize(0, dof.get_triangulation().n_global_levels()-1);
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    {
+      mg_matrices[level].initialize(mapping, dof, level);
+    }
+
+  MGCoarseIterative<LevelMatrixType,number> mg_coarse;
+  mg_coarse.initialize(mg_matrices[0]);
+
+  typedef PreconditionChebyshev<LevelMatrixType,parallel::distributed::Vector<number> > SMOOTHER;
+  MGSmootherPrecondition<LevelMatrixType, SMOOTHER, parallel::distributed::Vector<number> >
+  mg_smoother;
+
+  MGLevelObject<typename SMOOTHER::AdditionalData> smoother_data;
+  smoother_data.resize(0, dof.get_triangulation().n_global_levels()-1);
+  for (unsigned int level = 0; level<dof.get_triangulation().n_global_levels(); ++level)
+    {
+      smoother_data[level].smoothing_range = 20.;
+      smoother_data[level].degree = 5;
+      smoother_data[level].eig_cg_n_iterations = 15;
+      smoother_data[level].matrix_diagonal_inverse =
+        mg_matrices[level].get_matrix_diagonal_inverse();
+    }
+  mg_smoother.initialize(mg_matrices, smoother_data);
+
+  MGConstrainedDoFs mg_constrained_dofs;
+  ZeroFunction<dim> zero_function;
+  typename FunctionMap<dim>::type dirichlet_boundary;
+  dirichlet_boundary[0] = &zero_function;
+  mg_constrained_dofs.initialize(dof, dirichlet_boundary);
+
+  MGTransferMF<dim,LevelMatrixType> mg_transfer(mg_matrices,
+                                                mg_constrained_dofs);
+  mg_transfer.build(dof);
+
+  mg::Matrix<parallel::distributed::Vector<double> >
+  mg_matrix(mg_matrices);
+
+  Multigrid<parallel::distributed::Vector<double> > mg(dof,
+                                                       mg_matrix,
+                                                       mg_coarse,
+                                                       mg_transfer,
+                                                       mg_smoother,
+                                                       mg_smoother);
+  PreconditionMG<dim, parallel::distributed::Vector<double>,
+                 MGTransferMF<dim,LevelMatrixType> >
+                 preconditioner(dof, mg, mg_transfer);
+
+  {
+    ReductionControl control(30, 1e-20, 1e-7);
+    SolverCG<parallel::distributed::Vector<double> > solver(control);
+    solver.solve(fine_matrix, sol, in, preconditioner);
+  }
+}
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  for (int i=5; i<9-fe_degree; ++i)
+    {
+      parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD,
+                                                     dealii::Triangulation<dim>::none,parallel::distributed::Triangulation<dim>::construct_multigrid_hierarchy);
+      GridGenerator::hyper_cube (tria);
+      tria.refine_global(i-dim);
+
+      FE_DGQ<dim> fe (fe_degree);
+      DoFHandler<dim> dof (tria);
+      dof.distribute_dofs(fe);
+      dof.distribute_mg_dofs(fe);
+
+      do_test<dim, fe_degree, fe_degree+1, double> (dof, true);
+    }
+}
+
+
+
+int main (int argc, char **argv)
+{
+  Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1);
+
+  mpi_initlog();
+
+  {
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/multigrid_dg_sip_02.with_mpi=true.with_p4est=true.mpirun=5.output b/tests/matrix_free/multigrid_dg_sip_02.with_mpi=true.with_p4est=true.mpirun=5.output
new file mode 100644 (file)
index 0000000..29dbbfa
--- /dev/null
@@ -0,0 +1,41 @@
+
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 256
+DEAL:2d:cg::Starting value 16.0000
+DEAL:2d:cg::Convergence step 4 value 1.45213e-06
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 1024
+DEAL:2d:cg::Starting value 32.0000
+DEAL:2d:cg::Convergence step 5 value 8.09074e-08
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Number of degrees of freedom: 4096
+DEAL:2d:cg::Starting value 64.0000
+DEAL:2d:cg::Convergence step 5 value 9.08540e-07
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 576
+DEAL:2d:cg::Starting value 24.0000
+DEAL:2d:cg::Convergence step 5 value 4.02774e-08
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Number of degrees of freedom: 2304
+DEAL:2d:cg::Starting value 48.0000
+DEAL:2d:cg::Convergence step 5 value 7.58404e-08
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 512
+DEAL:3d:cg::Starting value 22.6274
+DEAL:3d:cg::Convergence step 5 value 2.70681e-07
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 4096
+DEAL:3d:cg::Starting value 64.0000
+DEAL:3d:cg::Convergence step 5 value 3.69638e-06
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Number of degrees of freedom: 32768
+DEAL:3d:cg::Starting value 181.019
+DEAL:3d:cg::Convergence step 5 value 5.56024e-06
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 1728
+DEAL:3d:cg::Starting value 41.5692
+DEAL:3d:cg::Convergence step 5 value 5.30416e-07
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Number of degrees of freedom: 13824
+DEAL:3d:cg::Starting value 117.576
+DEAL:3d:cg::Convergence step 6 value 8.58800e-07
index cacda5bb1acab468a9e4d6b05e0b2b2bed57acb1..cd29d22cc997098d8c361e865e0834a479b9a83c 100644 (file)
@@ -1,6 +1,6 @@
 // ---------------------------------------------------------------------
 //
-// Copyright (C) 2013 - 2017-2014 by the deal.II authors
+// Copyright (C) 2013 - 2018 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
diff --git a/tests/matrix_free/thread_correctness_dg.cc b/tests/matrix_free/thread_correctness_dg.cc
new file mode 100644 (file)
index 0000000..056d9bb
--- /dev/null
@@ -0,0 +1,154 @@
+// ---------------------------------------------------------------------
+//
+// 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// this function tests the correctness of the thread parallelization of the
+// matrix-free class extensively
+
+#include "../tests.h"
+#include <deal.II/base/function.h>
+#include <deal.II/fe/fe_dgq.h>
+#include "create_mesh.h"
+
+std::ofstream logfile("output");
+
+#include "matrix_vector_faces_common.h"
+
+
+template <int dim, int fe_degree, typename number>
+void sub_test()
+{
+  Triangulation<dim> tria;
+  create_mesh (tria);
+  tria.begin_active ()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  typename Triangulation<dim>::active_cell_iterator
+  cell = tria.begin_active (),
+  endc = tria.end();
+  for (; cell!=endc; ++cell)
+    if (cell->center().norm()<0.5)
+      cell->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  tria.refine_global(1);
+#ifndef DEBUG
+  if (dim < 3 || fe_degree < 2)
+    tria.refine_global(1);
+  tria.begin(tria.n_levels()-1)->set_refine_flag();
+  tria.last()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  if (dim==2 && fe_degree < 2)
+    tria.refine_global(2);
+  else
+    tria.refine_global(1);
+#endif
+
+  FE_DGQ<dim> fe (fe_degree);
+  DoFHandler<dim> dof (tria);
+  deallog << "Testing " << fe.get_name() << std::endl;
+
+  // run test for several different meshes
+  for (unsigned int i=0; i<8-2*dim; ++i)
+    {
+      cell = tria.begin_active ();
+      endc = tria.end();
+      unsigned int counter = 0;
+      for (; cell!=endc; ++cell, ++counter)
+        if (counter % (9-i) == 0)
+          cell->set_refine_flag();
+      tria.execute_coarsening_and_refinement();
+
+      dof.distribute_dofs(fe);
+      ConstraintMatrix constraints;
+      constraints.close();
+
+      //std::cout << "Number of cells: " << dof.get_triangulation().n_active_cells() << std::endl;
+      //std::cout << "Number of degrees of freedom: " << dof.n_dofs() << std::endl;
+      //std::cout << "Number of constraints: " << constraints.n_constraints() << std::endl;
+
+      MatrixFree<dim,number> mf_data, mf_data_color, mf_data_partition;
+      {
+        const QGauss<1> quad (fe_degree+1);
+        mf_data.reinit (dof, constraints, quad,
+                        typename MatrixFree<dim,number>::AdditionalData(MatrixFree<dim,number>::AdditionalData::none));
+
+        // choose block size of 3 which introduces
+        // some irregularity to the blocks (stress the
+        // non-overlapping computation harder)
+        mf_data_color.reinit (dof, constraints, quad,
+                              typename MatrixFree<dim,number>::AdditionalData
+                              (MatrixFree<dim,number>::AdditionalData::partition_color,
+                               3));
+
+        mf_data_partition.reinit (dof, constraints, quad,
+                                  typename MatrixFree<dim,number>::AdditionalData
+                                  (MatrixFree<dim,number>::AdditionalData::partition_partition,
+                                   3));
+      }
+
+      MatrixFreeTest<dim,fe_degree,fe_degree+1,number> mf_ref (mf_data);
+      MatrixFreeTest<dim,fe_degree,fe_degree+1,number> mf_color (mf_data_color);
+      MatrixFreeTest<dim,fe_degree,fe_degree+1,number> mf_partition (mf_data_partition);
+      Vector<number> in_dist (dof.n_dofs());
+      Vector<number> out_dist (in_dist), out_color (in_dist),
+             out_partition(in_dist);
+
+      for (unsigned int i=0; i<dof.n_dofs(); ++i)
+        {
+          if (constraints.is_constrained(i))
+            continue;
+          const double entry = Testing::rand()/(double)RAND_MAX;
+          in_dist(i) = entry;
+        }
+
+      mf_ref.vmult (out_dist, in_dist);
+
+      // make 10 sweeps in order to get in some
+      // variation to the threaded program
+      for (unsigned int sweep = 0; sweep < 10; ++sweep)
+        {
+          mf_color.vmult (out_color, in_dist);
+          mf_partition.vmult (out_partition, in_dist);
+
+          out_color -= out_dist;
+          double diff_norm = out_color.linfty_norm();
+          if (std::is_same<number,float>::value && diff_norm < 5e-6)
+            diff_norm = 0;
+          deallog << "Sweep " << sweep
+                  << ", error in partition/color:                  " << diff_norm
+                  << std::endl;
+          out_partition -= out_dist;
+          diff_norm = out_partition.linfty_norm();
+          if (std::is_same<number,float>::value && diff_norm < 5e-6)
+            diff_norm = 0;
+          deallog << "Sweep " << sweep
+                  << ", error in partition/partition:              " << diff_norm
+                  << std::endl;
+        }
+      deallog << std::endl;
+    }
+  deallog << std::endl;
+
+}
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  deallog << "Test doubles" << std::endl;
+  sub_test<dim,fe_degree,double>();
+  deallog << "Test floats" << std::endl;
+  sub_test<dim,fe_degree,float>();
+}
diff --git a/tests/matrix_free/thread_correctness_dg.output b/tests/matrix_free/thread_correctness_dg.output
new file mode 100644 (file)
index 0000000..dfe550f
--- /dev/null
@@ -0,0 +1,529 @@
+
+DEAL:2d::Test doubles
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              5.55e-16
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              5.55e-16
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              5.97e-16
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              5.97e-16
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              7.77e-16
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              7.77e-16
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              3.00e-15
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              3.00e-15
+DEAL:2d::
+DEAL:2d::
+DEAL:2d::Test floats
+DEAL:2d::Testing FE_DGQ<2>(1)
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::
+DEAL:2d::Test doubles
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              3.11e-15
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              3.11e-15
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              3.11e-15
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              6.44e-15
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              6.44e-15
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              5.33e-15
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              5.33e-15
+DEAL:2d::
+DEAL:2d::
+DEAL:2d::Test floats
+DEAL:2d::Testing FE_DGQ<2>(2)
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::Sweep 0, error in partition/color:                  0.00
+DEAL:2d::Sweep 0, error in partition/partition:              0.00
+DEAL:2d::Sweep 1, error in partition/color:                  0.00
+DEAL:2d::Sweep 1, error in partition/partition:              0.00
+DEAL:2d::Sweep 2, error in partition/color:                  0.00
+DEAL:2d::Sweep 2, error in partition/partition:              0.00
+DEAL:2d::Sweep 3, error in partition/color:                  0.00
+DEAL:2d::Sweep 3, error in partition/partition:              0.00
+DEAL:2d::Sweep 4, error in partition/color:                  0.00
+DEAL:2d::Sweep 4, error in partition/partition:              0.00
+DEAL:2d::Sweep 5, error in partition/color:                  0.00
+DEAL:2d::Sweep 5, error in partition/partition:              0.00
+DEAL:2d::Sweep 6, error in partition/color:                  0.00
+DEAL:2d::Sweep 6, error in partition/partition:              0.00
+DEAL:2d::Sweep 7, error in partition/color:                  0.00
+DEAL:2d::Sweep 7, error in partition/partition:              0.00
+DEAL:2d::Sweep 8, error in partition/color:                  0.00
+DEAL:2d::Sweep 8, error in partition/partition:              0.00
+DEAL:2d::Sweep 9, error in partition/color:                  0.00
+DEAL:2d::Sweep 9, error in partition/partition:              0.00
+DEAL:2d::
+DEAL:2d::
+DEAL:3d::Test doubles
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              2.22e-16
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              2.22e-16
+DEAL:3d::
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              2.78e-16
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              2.78e-16
+DEAL:3d::
+DEAL:3d::
+DEAL:3d::Test floats
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              0.00
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              0.00
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              0.00
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              0.00
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              0.00
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              0.00
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              0.00
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              0.00
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              0.00
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              0.00
+DEAL:3d::
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              0.00
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              0.00
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              0.00
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              0.00
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              0.00
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              0.00
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              0.00
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              0.00
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              0.00
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              0.00
+DEAL:3d::
+DEAL:3d::
+DEAL:3d::Test doubles
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              2.22e-15
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              2.22e-15
+DEAL:3d::
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              9.99e-16
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              9.99e-16
+DEAL:3d::
+DEAL:3d::
+DEAL:3d::Test floats
+DEAL:3d::Testing FE_DGQ<3>(2)
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              0.00
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              0.00
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              0.00
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              0.00
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              0.00
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              0.00
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              0.00
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              0.00
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              0.00
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              0.00
+DEAL:3d::
+DEAL:3d::Sweep 0, error in partition/color:                  0.00
+DEAL:3d::Sweep 0, error in partition/partition:              0.00
+DEAL:3d::Sweep 1, error in partition/color:                  0.00
+DEAL:3d::Sweep 1, error in partition/partition:              0.00
+DEAL:3d::Sweep 2, error in partition/color:                  0.00
+DEAL:3d::Sweep 2, error in partition/partition:              0.00
+DEAL:3d::Sweep 3, error in partition/color:                  0.00
+DEAL:3d::Sweep 3, error in partition/partition:              0.00
+DEAL:3d::Sweep 4, error in partition/color:                  0.00
+DEAL:3d::Sweep 4, error in partition/partition:              0.00
+DEAL:3d::Sweep 5, error in partition/color:                  0.00
+DEAL:3d::Sweep 5, error in partition/partition:              0.00
+DEAL:3d::Sweep 6, error in partition/color:                  0.00
+DEAL:3d::Sweep 6, error in partition/partition:              0.00
+DEAL:3d::Sweep 7, error in partition/color:                  0.00
+DEAL:3d::Sweep 7, error in partition/partition:              0.00
+DEAL:3d::Sweep 8, error in partition/color:                  0.00
+DEAL:3d::Sweep 8, error in partition/partition:              0.00
+DEAL:3d::Sweep 9, error in partition/color:                  0.00
+DEAL:3d::Sweep 9, error in partition/partition:              0.00
+DEAL:3d::
+DEAL:3d::

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.