]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Enable using MatrixFree and multigrid together in parallel, including test 1650/head
authorMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Tue, 22 Sep 2015 17:15:10 +0000 (19:15 +0200)
committerMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Wed, 23 Sep 2015 15:17:28 +0000 (17:17 +0200)
include/deal.II/matrix_free/matrix_free.h
include/deal.II/matrix_free/matrix_free.templates.h
tests/matrix_free/parallel_multigrid.cc [new file with mode: 0644]
tests/matrix_free/parallel_multigrid.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=3.output [new file with mode: 0644]
tests/matrix_free/parallel_multigrid.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=7.output [new file with mode: 0644]

index b66c121a63953663fc94e616713f7a9072f6a55a..e4929e663fde95c423ebc31507cbf8718f45f12d 100644 (file)
@@ -1440,12 +1440,23 @@ namespace internal
         if (level == numbers::invalid_unsigned_int)
           locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
         else
-          {
-            // TODO: not distributed yet
-            IndexSet new_set (dofh[j]->n_dofs(level));
-            new_set.add_range (0, dofh[j]->n_dofs(level));
-            locally_owned_set.push_back(new_set);
-          }
+          AssertThrow(false, ExcNotImplemented());
+      return locally_owned_set;
+    }
+
+    template <int dim, int spacedim>
+    inline
+    std::vector<IndexSet>
+    extract_locally_owned_index_sets (const std::vector<const ::dealii::DoFHandler<dim,spacedim> *> &dofh,
+                                      const unsigned int level)
+    {
+      std::vector<IndexSet> locally_owned_set;
+      locally_owned_set.reserve (dofh.size());
+      for (unsigned int j=0; j<dofh.size(); j++)
+        if (level == numbers::invalid_unsigned_int)
+          locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
+        else
+          locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(level));
       return locally_owned_set;
     }
   }
index d62b1fd062f37b028c88121d2d8d34708fc81045..68b6a8a71d05d67c757a4cb04aa25d0a49d519d2 100644 (file)
@@ -408,13 +408,17 @@ initialize_dof_handlers (const std::vector<const DoFHandler<dim>*> &dof_handler,
     }
   else
     {
-      AssertIndexRange (level, tria.n_levels());
-      cell_level_index.reserve (tria.n_cells(level));
-      typename Triangulation<dim>::cell_iterator cell = tria.begin(level),
-                                                 end_cell = tria.end(level);
-      for ( ; cell != end_cell; ++cell)
-        cell_level_index.push_back (std::pair<unsigned int,unsigned int>
-                                    (cell->level(), cell->index()));
+      AssertIndexRange (level, tria.n_global_levels());
+      if (level < tria.n_levels())
+        {
+          cell_level_index.reserve (tria.n_cells(level));
+          typename Triangulation<dim>::cell_iterator cell = tria.begin(level),
+                                                     end_cell = tria.end(level);
+          for ( ; cell != end_cell; ++cell)
+            if (cell->level_subdomain_id() == my_pid)
+              cell_level_index.push_back (std::pair<unsigned int,unsigned int>
+                                          (cell->level(), cell->index()));
+        }
     }
 }
 
diff --git a/tests/matrix_free/parallel_multigrid.cc b/tests/matrix_free/parallel_multigrid.cc
new file mode 100644 (file)
index 0000000..bb0b463
--- /dev/null
@@ -0,0 +1,440 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2014-2015 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 running a multigrid solver on continuous FE_Q finite elements with
+// MatrixFree data structures (otherwise similar to step-37)
+
+#include "../tests.h"
+
+#include <deal.II/base/logstream.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/dofs/dof_handler.h>
+#include <deal.II/lac/constraint_matrix.h>
+#include <deal.II/fe/fe_q.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.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:
+  LaplaceOperator() {};
+
+  void initialize (const Mapping<dim> &mapping,
+                   const DoFHandler<dim> &dof_handler,
+                   const std::set<types::boundary_id> &dirichlet_boundaries,
+                   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.level_mg_handler = level;
+    addit_data.mpi_communicator = MPI_COMM_WORLD;
+
+    // extract the constraints due to Dirichlet boundary conditions
+    ConstraintMatrix constraints;
+    ZeroFunction<dim> zero;
+    typename FunctionMap<dim>::type functions;
+    for (std::set<types::boundary_id>::const_iterator it=dirichlet_boundaries.begin();
+         it != dirichlet_boundaries.end(); ++it)
+      functions[*it] = &zero;
+    if (level == numbers::invalid_unsigned_int)
+      VectorTools::interpolate_boundary_values(dof_handler, functions, constraints);
+    else
+      {
+        std::vector<types::global_dof_index> local_dofs;
+        typename DoFHandler<dim>::cell_iterator
+        cell = dof_handler.begin(level),
+        endc = dof_handler.end(level);
+        for (; cell!=endc; ++cell)
+          {
+            if (dof_handler.get_tria().locally_owned_subdomain()!=numbers::invalid_subdomain_id
+                && cell->level_subdomain_id()==numbers::artificial_subdomain_id)
+              continue;
+            const FiniteElement<dim> &fe = cell->get_fe();
+            local_dofs.resize(fe.dofs_per_face);
+
+            for (unsigned int face_no = 0; face_no < GeometryInfo<dim>::faces_per_cell;
+                 ++face_no)
+              if (cell->at_boundary(face_no) == true)
+                {
+                  const typename DoFHandler<dim>::face_iterator
+                  face = cell->face(face_no);
+                  const types::boundary_id bi = face->boundary_id();
+                  if (functions.find(bi) != functions.end())
+                    {
+                      face->get_mg_dof_indices(level, local_dofs);
+                      for (unsigned int i=0; i<fe.dofs_per_face; ++i)
+                        constraints.add_line(local_dofs[i]);
+                    }
+                }
+          }
+      }
+    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
+  {
+    data.cell_loop (&LaplaceOperator::local_apply,
+                    this, dst, src);
+
+    const std::vector<unsigned int> &
+    constrained_dofs = data.get_constrained_dofs();
+    for (unsigned int i=0; i<constrained_dofs.size(); ++i)
+      dst.local_element(constrained_dofs[i]) += src.local_element(constrained_dofs[i]);
+  }
+
+  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);
+    Assert(vector.partitioners_are_globally_compatible(*data.get_dof_info(0).vector_partitioner),
+           ExcInternalError());
+  }
+
+  const parallel::distributed::Vector<number> &
+  get_matrix_diagonal_inverse() const
+  {
+    Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized());
+    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
+  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);
+      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.tensor_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.tensor_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>
+class MGTransferPrebuiltMF : public MGTransferPrebuilt<parallel::distributed::Vector<double> >
+{
+public:
+  MGTransferPrebuiltMF(const MGLevelObject<MATRIX> &laplace)
+    :
+    laplace_operator (laplace)
+  {};
+
+  /**
+   * Overload copy_to_mg from MGTransferPrebuilt to get the vectors compatible
+   * with MatrixFree and bypass the crude initialization in MGTransferPrebuilt
+   */
+  template <int dim, class InVector, int spacedim>
+  void
+  copy_to_mg (const DoFHandler<dim,spacedim> &mg_dof,
+              MGLevelObject<parallel::distributed::Vector<double> > &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<double> >::copy_to_mg(mg_dof, dst, src);
+  }
+
+private:
+  const MGLevelObject<MATRIX> &laplace_operator;
+};
+
+
+
+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   level,
+                           parallel::distributed::Vector<double> &dst,
+                           const parallel::distributed::Vector<double> &src) const
+  {
+    ReductionControl solver_control (1e4, 1e-50, 1e-10);
+    SolverCG<parallel::distributed::Vector<double> > solver_coarse (solver_control);
+    solver_coarse.solve (*coarse_matrix, dst, src, PreconditionIdentity());
+  }
+
+  const MATRIX *coarse_matrix;
+};
+
+
+
+
+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)
+{
+  if (types_are_equal<number,float>::value == true)
+    {
+      deallog.push("float");
+      deallog.threshold_double(1e-6);
+    }
+  else
+    {
+      deallog.threshold_double(5.e-11);
+    }
+
+  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;
+  std::set<types::boundary_id> dirichlet_boundaries;
+  dirichlet_boundaries.insert(0);
+  fine_matrix.initialize(mapping, dof, dirichlet_boundaries);
+
+  parallel::distributed::Vector<number> in, sol;
+  fine_matrix.initialize_dof_vector(in);
+  fine_matrix.initialize_dof_vector(sol);
+
+  // set constant rhs vector
+  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_tria().n_levels()-1);
+  for (unsigned int level = 0; level<dof.get_tria().n_levels(); ++level)
+    {
+      mg_matrices[level].initialize(mapping, dof, dirichlet_boundaries, level);
+    }
+
+  MGTransferPrebuiltMF<LevelMatrixType> mg_transfer(mg_matrices);
+  mg_transfer.build_matrices(dof);
+
+  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_tria().n_levels()-1);
+  for (unsigned int level = 0; level<dof.get_tria().n_levels(); ++level)
+    {
+      smoother_data[level].smoothing_range = 15.;
+      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);
+
+  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>,
+                 MGTransferPrebuiltMF<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);
+  }
+
+  if (types_are_equal<number,float>::value == true)
+    deallog.pop();
+}
+
+
+
+template <int dim, int fe_degree>
+void test ()
+{
+  for (unsigned int i=5; i<8; ++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_Q<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);
+
+  if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0)
+    {
+      deallog.attach(logfile);
+      deallog.depth_console(4);
+      deallog << std::setprecision (4);
+    }
+  else
+    deallog.depth_console(0);
+
+  {
+    deallog.threshold_double(1.e-10);
+    deallog.push("2d");
+    test<2,1>();
+    test<2,2>();
+    deallog.pop();
+    deallog.push("3d");
+    test<3,1>();
+    test<3,2>();
+    deallog.pop();
+  }
+}
diff --git a/tests/matrix_free/parallel_multigrid.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=3.output b/tests/matrix_free/parallel_multigrid.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=3.output
new file mode 100644 (file)
index 0000000..9d5dea0
--- /dev/null
@@ -0,0 +1,239 @@
+
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Number of degrees of freedom: 81
+DEAL:2d:cg::Starting value 0.8660
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 10 value 0
+DEAL:2d:cg::Starting value 9.000
+DEAL:2d:cg:cg::Starting value 0.004670
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 3.232e-06
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 3.457e-08
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg::Convergence step 3 value 4.626e-07
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Number of degrees of freedom: 289
+DEAL:2d:cg::Starting value 0.8660
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 10 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 2.432e-05
+DEAL:2d:cg::Starting value 17.00
+DEAL:2d:cg:cg::Starting value 0.01350
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 2.583e-06
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 4.246e-10
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg::Convergence step 3 value 3.600e-07
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Number of degrees of freedom: 1089
+DEAL:2d:cg::Starting value 0.8660
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 10 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 2.432e-05
+DEAL:2d:cg::Starting value 0.9995
+DEAL:2d:cg::Failure step 15 value 0.1302
+DEAL:2d:cg::Starting value 33.00
+DEAL:2d:cg:cg::Starting value 0.04871
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 1.396e-06
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 5.548e-08
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 8.781e-11
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg::Convergence step 4 value 1.484e-08
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Number of degrees of freedom: 289
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 11 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 0.001560
+DEAL:2d:cg::Starting value 17.00
+DEAL:2d:cg:cg::Starting value 0.5165
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 7.798e-05
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 4.794e-07
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 1.177e-09
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg::Convergence step 4 value 1.404e-08
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Number of degrees of freedom: 1089
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 11 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 0.001560
+DEAL:2d:cg::Starting value 0.9995
+DEAL:2d:cg::Failure step 15 value 0.5714
+DEAL:2d:cg::Starting value 33.00
+DEAL:2d:cg:cg::Starting value 1.948
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 7.876e-05
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 9.527e-07
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 1.973e-09
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg::Convergence step 4 value 1.627e-08
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Number of degrees of freedom: 4225
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 11 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 0.001560
+DEAL:2d:cg::Starting value 0.9995
+DEAL:2d:cg::Failure step 15 value 0.5714
+DEAL:2d:cg::Starting value 0.9999
+DEAL:2d:cg::Failure step 15 value 2.322
+DEAL:2d:cg::Starting value 65.00
+DEAL:2d:cg:cg::Starting value 7.684
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 0.0004225
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 5.550e-07
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 8.109e-09
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg::Convergence step 4 value 3.009e-08
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Number of degrees of freedom: 125
+DEAL:3d:cg::Starting value 0.9354
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 11.18
+DEAL:3d:cg:cg::Starting value 0.07042
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 3.438e-05
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 2.189e-09
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg::Convergence step 3 value 8.878e-09
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Number of degrees of freedom: 729
+DEAL:3d:cg::Starting value 0.9354
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 13 value 9.706e-11
+DEAL:3d:cg::Starting value 27.00
+DEAL:3d:cg:cg::Starting value 0.01748
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 0.0001434
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 7.360e-08
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg::Convergence step 3 value 1.327e-06
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Number of degrees of freedom: 4913
+DEAL:3d:cg::Starting value 0.9354
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 13 value 9.706e-11
+DEAL:3d:cg::Starting value 0.9999
+DEAL:3d:cg::Failure step 15 value 2.351e-05
+DEAL:3d:cg::Starting value 70.09
+DEAL:3d:cg:cg::Starting value 0.03090
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 3.917e-05
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 5.305e-07
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 7.196e-10
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg::Convergence step 4 value 6.374e-08
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Number of degrees of freedom: 729
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 15 value 5.276e-11
+DEAL:3d:cg::Starting value 27.00
+DEAL:3d:cg:cg::Starting value 1.155
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 0.0001365
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 1.471e-07
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg::Convergence step 3 value 5.042e-08
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Number of degrees of freedom: 4913
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 15 value 5.276e-11
+DEAL:3d:cg::Starting value 0.9999
+DEAL:3d:cg::Failure step 15 value 0.001572
+DEAL:3d:cg::Starting value 70.09
+DEAL:3d:cg:cg::Starting value 6.474
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 0.0005841
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 2.220e-06
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg::Convergence step 3 value 2.560e-06
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Number of degrees of freedom: 35937
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 15 value 5.276e-11
+DEAL:3d:cg::Starting value 0.9999
+DEAL:3d:cg::Failure step 15 value 0.001572
+DEAL:3d:cg::Starting value 1.000
+DEAL:3d:cg::Failure step 15 value 0.3991
+DEAL:3d:cg::Starting value 189.6
+DEAL:3d:cg:cg::Starting value 47.62
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 0.006356
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 8.271e-06
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg::Convergence step 3 value 1.007e-05
diff --git a/tests/matrix_free/parallel_multigrid.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=7.output b/tests/matrix_free/parallel_multigrid.with_trilinos=true.with_mpi=true.with_p4est=true.mpirun=7.output
new file mode 100644 (file)
index 0000000..9d5dea0
--- /dev/null
@@ -0,0 +1,239 @@
+
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Number of degrees of freedom: 81
+DEAL:2d:cg::Starting value 0.8660
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 10 value 0
+DEAL:2d:cg::Starting value 9.000
+DEAL:2d:cg:cg::Starting value 0.004670
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 3.232e-06
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 3.457e-08
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg::Convergence step 3 value 4.626e-07
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Number of degrees of freedom: 289
+DEAL:2d:cg::Starting value 0.8660
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 10 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 2.432e-05
+DEAL:2d:cg::Starting value 17.00
+DEAL:2d:cg:cg::Starting value 0.01350
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 2.583e-06
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 4.246e-10
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg::Convergence step 3 value 3.600e-07
+DEAL:2d::Testing FE_Q<2>(1)
+DEAL:2d::Number of degrees of freedom: 1089
+DEAL:2d:cg::Starting value 0.8660
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 10 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 2.432e-05
+DEAL:2d:cg::Starting value 0.9995
+DEAL:2d:cg::Failure step 15 value 0.1302
+DEAL:2d:cg::Starting value 33.00
+DEAL:2d:cg:cg::Starting value 0.04871
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 1.396e-06
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 5.548e-08
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg:cg::Starting value 8.781e-11
+DEAL:2d:cg:cg::Convergence step 1 value 0
+DEAL:2d:cg::Convergence step 4 value 1.484e-08
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Number of degrees of freedom: 289
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 11 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 0.001560
+DEAL:2d:cg::Starting value 17.00
+DEAL:2d:cg:cg::Starting value 0.5165
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 7.798e-05
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 4.794e-07
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 1.177e-09
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg::Convergence step 4 value 1.404e-08
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Number of degrees of freedom: 1089
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 11 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 0.001560
+DEAL:2d:cg::Starting value 0.9995
+DEAL:2d:cg::Failure step 15 value 0.5714
+DEAL:2d:cg::Starting value 33.00
+DEAL:2d:cg:cg::Starting value 1.948
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 7.876e-05
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 9.527e-07
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 1.973e-09
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg::Convergence step 4 value 1.627e-08
+DEAL:2d::Testing FE_Q<2>(2)
+DEAL:2d::Number of degrees of freedom: 4225
+DEAL:2d:cg::Starting value 0.9428
+DEAL:2d:cg::Convergence step 1 value 0
+DEAL:2d:cg::Starting value 0.9798
+DEAL:2d:cg::Convergence step 4 value 0
+DEAL:2d:cg::Starting value 0.9938
+DEAL:2d:cg::Convergence step 11 value 0
+DEAL:2d:cg::Starting value 0.9983
+DEAL:2d:cg::Failure step 15 value 0.001560
+DEAL:2d:cg::Starting value 0.9995
+DEAL:2d:cg::Failure step 15 value 0.5714
+DEAL:2d:cg::Starting value 0.9999
+DEAL:2d:cg::Failure step 15 value 2.322
+DEAL:2d:cg::Starting value 65.00
+DEAL:2d:cg:cg::Starting value 7.684
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 0.0004225
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 5.550e-07
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg:cg::Starting value 8.109e-09
+DEAL:2d:cg:cg::Convergence step 2 value 0
+DEAL:2d:cg::Convergence step 4 value 3.009e-08
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Number of degrees of freedom: 125
+DEAL:3d:cg::Starting value 0.9354
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 11.18
+DEAL:3d:cg:cg::Starting value 0.07042
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 3.438e-05
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 2.189e-09
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg::Convergence step 3 value 8.878e-09
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Number of degrees of freedom: 729
+DEAL:3d:cg::Starting value 0.9354
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 13 value 9.706e-11
+DEAL:3d:cg::Starting value 27.00
+DEAL:3d:cg:cg::Starting value 0.01748
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 0.0001434
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 7.360e-08
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg::Convergence step 3 value 1.327e-06
+DEAL:3d::Testing FE_Q<3>(1)
+DEAL:3d::Number of degrees of freedom: 4913
+DEAL:3d:cg::Starting value 0.9354
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 13 value 9.706e-11
+DEAL:3d:cg::Starting value 0.9999
+DEAL:3d:cg::Failure step 15 value 2.351e-05
+DEAL:3d:cg::Starting value 70.09
+DEAL:3d:cg:cg::Starting value 0.03090
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 3.917e-05
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 5.305e-07
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg:cg::Starting value 7.196e-10
+DEAL:3d:cg:cg::Convergence step 1 value 0
+DEAL:3d:cg::Convergence step 4 value 6.374e-08
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Number of degrees of freedom: 729
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 15 value 5.276e-11
+DEAL:3d:cg::Starting value 27.00
+DEAL:3d:cg:cg::Starting value 1.155
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 0.0001365
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 1.471e-07
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg::Convergence step 3 value 5.042e-08
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Number of degrees of freedom: 4913
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 15 value 5.276e-11
+DEAL:3d:cg::Starting value 0.9999
+DEAL:3d:cg::Failure step 15 value 0.001572
+DEAL:3d:cg::Starting value 70.09
+DEAL:3d:cg:cg::Starting value 6.474
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 0.0005841
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 2.220e-06
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg::Convergence step 3 value 2.560e-06
+DEAL:3d::Testing FE_Q<3>(2)
+DEAL:3d::Number of degrees of freedom: 35937
+DEAL:3d:cg::Starting value 0.9813
+DEAL:3d:cg::Convergence step 1 value 0
+DEAL:3d:cg::Starting value 0.9960
+DEAL:3d:cg::Convergence step 5 value 0
+DEAL:3d:cg::Starting value 0.9993
+DEAL:3d:cg::Convergence step 15 value 5.276e-11
+DEAL:3d:cg::Starting value 0.9999
+DEAL:3d:cg::Failure step 15 value 0.001572
+DEAL:3d:cg::Starting value 1.000
+DEAL:3d:cg::Failure step 15 value 0.3991
+DEAL:3d:cg::Starting value 189.6
+DEAL:3d:cg:cg::Starting value 47.62
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 0.006356
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg:cg::Starting value 8.271e-06
+DEAL:3d:cg:cg::Convergence step 2 value 0
+DEAL:3d:cg::Convergence step 3 value 1.007e-05

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.