--- /dev/null
+// ---------------------------------------------------------------------
+// $Id: step-11.cc 31349 2013-10-20 19:07:06Z maier $
+//
+// Copyright (C) 2005 - 2013 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// copied from bits/step-11 with slight modifications to make it run faster
+
+#include <deal.II/base/logstream.h>
+
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/table_handler.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/sparse_matrix.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/grid/tria_accessor.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_tools.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/numerics/matrix_tools.h>
+
+#include <deal.II/lac/compressed_sparsity_pattern.h>
+
+#include <algorithm>
+#include <iomanip>
+#include <iomanip>
+#include <cmath>
+
+using namespace dealii;
+
+
+template <int dim>
+class LaplaceProblem
+{
+public:
+ LaplaceProblem (const unsigned int mapping_degree);
+ void run ();
+
+private:
+ void setup_system ();
+ void assemble_and_solve ();
+ void solve ();
+
+ Triangulation<dim> triangulation;
+ FE_Q<dim> fe;
+ DoFHandler<dim> dof_handler;
+ MappingQ<dim> mapping;
+
+ SparsityPattern sparsity_pattern;
+ SparseMatrix<double> system_matrix;
+ ConstraintMatrix mean_value_constraints;
+
+ Vector<double> solution;
+ Vector<double> system_rhs;
+
+ TableHandler output_table;
+
+ double last_error;
+};
+
+
+
+template <int dim>
+LaplaceProblem<dim>::LaplaceProblem (const unsigned int mapping_degree) :
+ fe (1),
+ dof_handler (triangulation),
+ mapping (mapping_degree)
+{
+ deallog << "Using mapping with degree " << mapping_degree << ":"
+ << std::endl
+ << "============================"
+ << std::endl;
+}
+
+
+
+template <int dim>
+void LaplaceProblem<dim>::setup_system ()
+{
+ dof_handler.distribute_dofs (fe);
+ solution.reinit (dof_handler.n_dofs());
+ system_rhs.reinit (dof_handler.n_dofs());
+
+ std::vector<bool> boundary_dofs (dof_handler.n_dofs(), false);
+ DoFTools::extract_boundary_dofs (dof_handler, std::vector<bool>(1,true),
+ boundary_dofs);
+
+ const unsigned int first_boundary_dof
+ = std::distance (boundary_dofs.begin(),
+ std::find (boundary_dofs.begin(),
+ boundary_dofs.end(),
+ true));
+
+ mean_value_constraints.clear ();
+ mean_value_constraints.add_line (first_boundary_dof);
+ for (unsigned int i=first_boundary_dof+1; i<dof_handler.n_dofs(); ++i)
+ if (boundary_dofs[i] == true)
+ mean_value_constraints.add_entry (first_boundary_dof,
+ i, -1);
+ mean_value_constraints.close ();
+
+ CompressedSparsityPattern csp (dof_handler.n_dofs(),
+ dof_handler.n_dofs());
+ DoFTools::make_sparsity_pattern (dof_handler, csp);
+ mean_value_constraints.condense (csp);
+
+ sparsity_pattern.copy_from (csp);
+ system_matrix.reinit (sparsity_pattern);
+}
+
+
+
+template <int dim>
+void LaplaceProblem<dim>::assemble_and_solve ()
+{
+
+ const unsigned int gauss_degree
+ = std::max (static_cast<unsigned int>(std::ceil(1.*(mapping.get_degree()+1)/2)),
+ 2U);
+ MatrixTools::create_laplace_matrix (mapping, dof_handler,
+ QGauss<dim>(gauss_degree),
+ system_matrix);
+ VectorTools::create_right_hand_side (mapping, dof_handler,
+ QGauss<dim>(gauss_degree),
+ ConstantFunction<dim>(-2),
+ system_rhs);
+ Vector<double> tmp (system_rhs.size());
+ VectorTools::create_boundary_right_hand_side (mapping, dof_handler,
+ QGauss<dim-1>(gauss_degree),
+ ConstantFunction<dim>(1),
+ tmp);
+ system_rhs += tmp;
+
+ mean_value_constraints.condense (system_matrix);
+ mean_value_constraints.condense (system_rhs);
+
+ solve ();
+ mean_value_constraints.distribute (solution);
+
+ Vector<float> norm_per_cell (triangulation.n_active_cells());
+ VectorTools::integrate_difference (mapping, dof_handler,
+ solution,
+ ZeroFunction<dim>(),
+ norm_per_cell,
+ QGauss<dim>(gauss_degree+1),
+ VectorTools::H1_seminorm);
+ const double norm = norm_per_cell.l2_norm();
+
+ output_table.add_value ("cells", triangulation.n_active_cells());
+ output_table.add_value ("|u|_1", norm);
+ output_table.add_value ("error", std::fabs(norm-std::sqrt(3.14159265358/2)));
+
+ last_error = std::fabs(norm-std::sqrt(3.14159265358/2));
+}
+
+
+
+template <int dim>
+void LaplaceProblem<dim>::solve ()
+{
+ SolverControl solver_control (1000, 1e-12);
+ SolverCG<> cg (solver_control);
+
+ PreconditionSSOR<> preconditioner;
+ preconditioner.initialize(system_matrix, 1.2);
+
+ cg.solve (system_matrix, solution, system_rhs,
+ preconditioner);
+}
+
+
+
+template <int dim>
+void LaplaceProblem<dim>::run ()
+{
+ GridGenerator::hyper_ball (triangulation);
+ static const HyperBallBoundary<dim> boundary;
+ triangulation.set_boundary (0, boundary);
+
+ for (unsigned int cycle=0; cycle<6; ++cycle, triangulation.refine_global(1))
+ {
+ setup_system ();
+ assemble_and_solve ();
+ };
+
+ AssertThrow (last_error<1e-3, ExcMessage("solution is not converging"));
+
+
+
+ output_table.set_precision("|u|_1", 6);
+ output_table.set_precision("error", 6);
+ output_table.write_text (std::cout);
+ deallog << std::endl;
+}
+
+
+
+int main ()
+{
+ try
+ {
+ LaplaceProblem<2>(1).run ();
+ }
+ catch (std::exception &exc)
+ {
+ deallog << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ deallog << "Exception on processing: " << std::endl
+ << exc.what() << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return -1;
+ }
+ catch (...)
+ {
+ deallog << std::endl << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ deallog << "Unknown exception!" << std::endl
+ << "Aborting!" << std::endl
+ << "----------------------------------------------------"
+ << std::endl;
+ return -1;
+ };
+
+ return 0;
+}