--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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>();
+}
--- /dev/null
+
+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::
--- /dev/null
+
+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::
+
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
+
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+DEAL:2d::Error between variants: 0
+DEAL:2d::Error between variants: 0
+DEAL:3d::Error between variants: 0
+DEAL:3d::Error between variants: 0
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+ }
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+ }
+}
--- /dev/null
+
+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::
--- /dev/null
+//------------------ 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();
+ }
+}
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+ }
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+ }
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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);
+}
--- /dev/null
+
+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::
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+DEAL:3d::Testing FE_DGQ<3>(1)
+DEAL:3d::Norm of difference: 0
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+ }
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+ }
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+ }
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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;
+ }
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+//------------------ 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();
+ }
+}
// ---------------------------------------------------------------------
//
-// 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.
//
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+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
--- /dev/null
+
+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
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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();
+ }
+}
--- /dev/null
+
+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
// ---------------------------------------------------------------------
//
-// 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.
//
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// 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>();
+}
--- /dev/null
+
+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::