--- /dev/null
+//----------------------------------------------------------------------
+// $Id$
+// Version: $Name$
+//
+// Copyright (C) 2000, 2001, 2003, 2004, 2007, 2008, 2009, 2010, 2011 by the deal.II authors
+//
+// This file is subject to QPL and may not be distributed
+// without copyright and license information. Please refer
+// to the file deal.II/doc/license.html for the text and
+// further information on this license.
+//
+//----------------------------------------------------------------------
+
+// Test whether Assember::CellsAndFaces adds up correctly.
+
+#include "../tests.h"
+#include "empty_info.h"
+#include <numerics/mesh_worker.h>
+#include <numerics/mesh_worker_assembler.h>
+#include <numerics/mesh_worker_loop.h>
+
+#include <base/std_cxx1x/function.h>
+#include <base/logstream.h>
+#include <grid/grid_generator.h>
+#include <dofs/dof_tools.h>
+#include <fe/fe_dgp.h>
+#include <lac/block_vector.h>
+
+#include <fstream>
+#include <iomanip>
+
+using namespace dealii;
+
+
+// Define a class that fills all available entries in the info objects
+// with recognizable numbers.
+
+// Fills the following functionals:
+// 0: number of cells
+// 1: number of interior faces
+// 2: number of boundary faces
+
+const unsigned int n_functionals = 3;
+
+template <int dim>
+class Local : public Subscriptor
+{
+ public:
+ typedef EmptyInfo CellInfo;
+
+ void cell(MeshWorker::DoFInfo<dim>& dinfo, CellInfo& info) const;
+ void bdry(MeshWorker::DoFInfo<dim>& dinfo, CellInfo& info) const;
+ void face(MeshWorker::DoFInfo<dim>& dinfo1, MeshWorker::DoFInfo<dim>& dinfo2,
+ CellInfo& info1, CellInfo& info2) const;
+};
+
+
+template <int dim>
+void
+Local<dim>::cell(MeshWorker::DoFInfo<dim>& info, CellInfo&) const
+{
+ info.value(0) = 1.;
+}
+
+
+template <int dim>
+void
+Local<dim>::bdry(MeshWorker::DoFInfo<dim>& info, CellInfo&) const
+{
+ info.value(2) = 1.;
+}
+
+
+template <int dim>
+void
+Local<dim>::face(MeshWorker::DoFInfo<dim>& info1, MeshWorker::DoFInfo<dim>& info2,
+ CellInfo&, CellInfo&) const
+{
+ info1.value(1) = 1./2.;
+ info2.value(1) = 1./2.;
+}
+
+
+template <int dim>
+void
+test_mesh(MGDoFHandler<dim>& mgdofs)
+{
+ const DoFHandler<dim>& dofs = mgdofs;
+
+ BlockVector<double> cells(n_functionals);
+ BlockVector<double> faces(n_functionals);
+ for (unsigned int i=0;i<n_functionals;++i)
+ {
+ cells.block(i).reinit(dofs.get_tria().n_cells());
+ faces.block(i).reinit(dofs.get_tria().n_faces());
+ }
+ cells.collect_sizes();
+ faces.collect_sizes();
+
+ NamedData<BlockVector<double>* > out_data;
+ BlockVector<double>* p = &cells;
+ out_data.add(p, "cells");
+ p = &faces;
+ out_data.add(p, "faces");
+
+ Local<dim> local;
+ EmptyInfoBox info_box;
+ MeshWorker::DoFInfo<dim> dof_info(dofs);
+
+ MeshWorker::Assembler::CellsAndFaces<double> assembler;
+ assembler.initialize(out_data, true);
+
+ MeshWorker::loop<dim, dim, MeshWorker::DoFInfo<dim>, EmptyInfoBox>
+ (dofs.begin_active(), dofs.end(),
+ dof_info, info_box,
+ std_cxx1x::bind (&Local<dim>::cell, local, _1, _2),
+ std_cxx1x::bind (&Local<dim>::bdry, local, _1, _2),
+ std_cxx1x::bind (&Local<dim>::face, local, _1, _2, _3, _4),
+ assembler, true);
+
+ deallog << " Results cells";
+ for (unsigned int i=0;i<n_functionals;++i)
+ deallog << '\t' << cells.block(i).l1_norm();
+ deallog << std::endl;
+
+ deallog << " Results faces";
+ for (unsigned int i=0;i<n_functionals;++i)
+ deallog << '\t' << faces.block(i).l1_norm();
+ deallog << std::endl;
+
+ cells = 0.;
+ faces = 0.;
+
+ MeshWorker::DoFInfo<dim> mg_dof_info(mgdofs);
+ MeshWorker::loop<dim, dim, MeshWorker::DoFInfo<dim>, EmptyInfoBox>
+ (mgdofs.begin(), mgdofs.end(),
+ mg_dof_info, info_box,
+ std_cxx1x::bind (&Local<dim>::cell, local, _1, _2),
+ std_cxx1x::bind (&Local<dim>::bdry, local, _1, _2),
+ std_cxx1x::bind (&Local<dim>::face, local, _1, _2, _3, _4),
+ assembler, true);
+
+ deallog << "MGResults cells";
+ for (unsigned int i=0;i<n_functionals;++i)
+ deallog << '\t' << cells.block(i).l1_norm();
+ deallog << std::endl;
+
+ deallog << "MGResults faces";
+ for (unsigned int i=0;i<n_functionals;++i)
+ deallog << '\t' << faces.block(i).l1_norm();
+ deallog << std::endl;
+}
+
+
+template<int dim>
+void
+test(const FiniteElement<dim>& fe)
+{
+ Triangulation<dim> tr;
+ MGDoFHandler<dim> dofs(tr);
+ GridGenerator::hyper_cube(tr);
+ tr.refine_global(1);
+ deallog.push("1");
+ dofs.distribute_dofs(fe);
+ test_mesh(dofs);
+ deallog.pop();
+ tr.begin(1)->set_refine_flag();
+ tr.execute_coarsening_and_refinement();
+ deallog.push("2");
+ dofs.distribute_dofs(fe);
+ test_mesh(dofs);
+ deallog.pop();
+ tr.begin(2)->set_refine_flag();
+ tr.execute_coarsening_and_refinement();
+ deallog.push("3");
+ dofs.distribute_dofs(fe);
+ test_mesh(dofs);
+ deallog.pop();
+}
+
+
+int main ()
+{
+ const std::string logname = JobIdentifier::base_name(__FILE__) + std::string("/output");
+ std::ofstream logfile(logname.c_str());
+ deallog.attach(logfile);
+ deallog.depth_console (0);
+
+ FE_DGP<2> el2(0);
+ FE_DGP<3> el3(0);
+
+ deallog.push("2D");
+ test(el2);
+ deallog.pop();
+ deallog.push("3D");
+ test(el3);
+ deallog.pop();
+}
--- /dev/null
+
+DEAL:2D:1:: Results cells 4.00000 0 0
+DEAL:2D:1:: Results faces 0 4.00000 8.00000
+DEAL:2D:1::MGResults cells 5.00000 0 0
+DEAL:2D:1::MGResults faces 0 4.00000 12.0000
+DEAL:2D:2:: Results cells 7.00000 0 0
+DEAL:2D:2:: Results faces 0 14.0000 10.0000
+DEAL:2D:2::MGResults cells 9.00000 0 0
+DEAL:2D:2::MGResults faces 0 16.0000 16.0000
+DEAL:2D:3:: Results cells 10.0000 0 0
+DEAL:2D:3:: Results faces 0 24.0000 12.0000
+DEAL:2D:3::MGResults cells 13.0000 0 0
+DEAL:2D:3::MGResults faces 0 28.0000 20.0000
+DEAL:3D:1:: Results cells 8.00000 0 0
+DEAL:3D:1:: Results faces 0 12.0000 24.0000
+DEAL:3D:1::MGResults cells 9.00000 0 0
+DEAL:3D:1::MGResults faces 0 12.0000 30.0000
+DEAL:3D:2:: Results cells 15.0000 0 0
+DEAL:3D:2:: Results faces 0 45.0000 33.0000
+DEAL:3D:2::MGResults cells 17.0000 0 0
+DEAL:3D:2::MGResults faces 0 48.0000 42.0000
+DEAL:3D:3:: Results cells 22.0000 0 0
+DEAL:3D:3:: Results faces 0 78.0000 42.0000
+DEAL:3D:3::MGResults cells 25.0000 0 0
+DEAL:3D:3::MGResults faces 0 84.0000 54.0000