]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
merged from trunk
authorheltai <heltai@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 18 Aug 2013 16:48:15 +0000 (16:48 +0000)
committerheltai <heltai@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 18 Aug 2013 16:48:15 +0000 (16:48 +0000)
git-svn-id: https://svn.dealii.org/branches/branch_manifold_id@30335 0785d39b-7218-0410-832d-ea1e28bc413d

231 files changed:
deal.II/CMakeLists.txt
deal.II/bundled/CMakeLists.txt
deal.II/bundled/boost-1.49.0/include/boost/signals2/detail/foreign_ptr.hpp
deal.II/cmake/checks/check_01_cpu_features.cmake
deal.II/cmake/checks/check_02_system_features.cmake
deal.II/cmake/checks/check_03_compiler_bugs.cmake
deal.II/cmake/config/CMakeLists.txt
deal.II/cmake/config/Make.global_options.in
deal.II/cmake/configure/configure_1_lapack.cmake
deal.II/cmake/configure/configure_1_mpi.cmake
deal.II/cmake/configure/configure_1_threads.cmake
deal.II/cmake/configure/configure_2_metis.cmake
deal.II/cmake/configure/configure_2_trilinos.cmake
deal.II/cmake/configure/configure_boost.cmake
deal.II/cmake/configure/configure_slepc.cmake
deal.II/cmake/macros/macro_clear_cmake_required.cmake [new file with mode: 0644]
deal.II/cmake/macros/macro_deal_ii_initialize_cached_variables.cmake
deal.II/cmake/macros/macro_deal_ii_setup_target.cmake
deal.II/cmake/macros/macro_enable_if_links.cmake
deal.II/cmake/macros/macro_enable_language_optional.cmake
deal.II/cmake/macros/macro_reset_cmake_required.cmake [new file with mode: 0644]
deal.II/cmake/modules/FindARPACK.cmake
deal.II/cmake/modules/FindDEALII_LAPACK.cmake [new file with mode: 0644]
deal.II/cmake/modules/FindMETIS.cmake
deal.II/cmake/modules/FindP4EST.cmake
deal.II/cmake/modules/FindPETSC.cmake
deal.II/cmake/modules/FindSCALAPACK.cmake
deal.II/cmake/modules/FindSLEPC.cmake
deal.II/cmake/modules/FindTRILINOS.cmake
deal.II/cmake/modules/FindUMFPACK.cmake
deal.II/cmake/setup_cached_variables.cmake
deal.II/cmake/setup_compiler_flags.cmake
deal.II/cmake/setup_compiler_flags_gnu.cmake
deal.II/cmake/setup_compiler_flags_intel.cmake
deal.II/cmake/setup_deal_ii.cmake
deal.II/cmake/setup_finalize.cmake
deal.II/cmake/setup_post_project_call.cmake [new file with mode: 0644]
deal.II/contrib/mesh_conversion/README.txt
deal.II/doc/CMakeLists.txt
deal.II/doc/authors.html
deal.II/doc/development/Config.sample
deal.II/doc/development/cmake-internals.html
deal.II/doc/development/cmake.html
deal.II/doc/development/cmakelists.html
deal.II/doc/development/doxygen.html
deal.II/doc/development/porting.html
deal.II/doc/doxygen/headers/global_dof_index.h
deal.II/doc/doxygen/headers/glossary.h
deal.II/doc/doxygen/headers/instantiations.h
deal.II/doc/doxygen/headers/vector_valued.h
deal.II/doc/doxygen/options.dox.in
deal.II/doc/external-libs/arpack.html
deal.II/doc/external-libs/mumps.html
deal.II/doc/external-libs/p4est.html
deal.II/doc/license.html
deal.II/doc/mail.html
deal.II/doc/news/2001/3.1.0-vs-3.2.0.html
deal.II/doc/news/6.3.0-vs-7.0.0.h
deal.II/doc/news/7.0.0-vs-7.1.0.h
deal.II/doc/news/7.2.0-vs-7.3.0.h
deal.II/doc/news/changes.h
deal.II/doc/news/news.html
deal.II/doc/publications/index.html
deal.II/doc/readme.html
deal.II/examples/step-1/step-1.cc
deal.II/examples/step-10/step-10.cc
deal.II/examples/step-11/step-11.cc
deal.II/examples/step-12/step-12.cc
deal.II/examples/step-13/step-13.cc
deal.II/examples/step-14/step-14.cc
deal.II/examples/step-15/doc/intro.dox
deal.II/examples/step-15/step-15.cc
deal.II/examples/step-16/step-16.cc
deal.II/examples/step-17/CMakeLists.txt
deal.II/examples/step-17/step-17.cc
deal.II/examples/step-18/CMakeLists.txt
deal.II/examples/step-18/doc/intro.dox
deal.II/examples/step-18/doc/results.dox
deal.II/examples/step-18/step-18.cc
deal.II/examples/step-19/step-19.cc
deal.II/examples/step-2/step-2.cc
deal.II/examples/step-20/step-20.cc
deal.II/examples/step-21/step-21.cc
deal.II/examples/step-22/CMakeLists.txt
deal.II/examples/step-22/doc/intro.dox
deal.II/examples/step-22/doc/results.dox
deal.II/examples/step-22/step-22.cc
deal.II/examples/step-23/doc/intro.dox
deal.II/examples/step-23/doc/results.dox
deal.II/examples/step-23/step-23.cc
deal.II/examples/step-24/doc/intro.dox
deal.II/examples/step-24/step-24.cc
deal.II/examples/step-25/doc/intro.dox
deal.II/examples/step-25/step-25.cc
deal.II/examples/step-26/step-26.cc
deal.II/examples/step-27/step-27.cc
deal.II/examples/step-28/doc/intro.dox
deal.II/examples/step-28/step-28.cc
deal.II/examples/step-29/CMakeLists.txt
deal.II/examples/step-29/doc/intro.dox
deal.II/examples/step-29/step-29.cc
deal.II/examples/step-3/step-3.cc
deal.II/examples/step-30/step-30.cc
deal.II/examples/step-31/CMakeLists.txt
deal.II/examples/step-31/step-31.cc
deal.II/examples/step-32/CMakeLists.txt
deal.II/examples/step-32/step-32.cc
deal.II/examples/step-33/CMakeLists.txt
deal.II/examples/step-33/step-33.cc
deal.II/examples/step-34/CMakeLists.txt
deal.II/examples/step-34/step-34.cc
deal.II/examples/step-35/CMakeLists.txt
deal.II/examples/step-35/step-35.cc
deal.II/examples/step-36/CMakeLists.txt
deal.II/examples/step-36/doc/intro.dox
deal.II/examples/step-36/step-36.cc
deal.II/examples/step-37/CMakeLists.txt
deal.II/examples/step-37/step-37.cc
deal.II/examples/step-38/step-38.cc
deal.II/examples/step-39/step-39.cc
deal.II/examples/step-4/step-4.cc
deal.II/examples/step-40/CMakeLists.txt
deal.II/examples/step-40/step-40.cc
deal.II/examples/step-41/CMakeLists.txt
deal.II/examples/step-41/step-41.cc
deal.II/examples/step-42/CMakeLists.txt
deal.II/examples/step-42/doc/intro-step-42.tex
deal.II/examples/step-42/p1_adaptive.prm [new file with mode: 0644]
deal.II/examples/step-42/p1_global.prm [new file with mode: 0644]
deal.II/examples/step-42/p2_adaptive.prm [new file with mode: 0644]
deal.II/examples/step-42/p2_global.prm [new file with mode: 0644]
deal.II/examples/step-42/step-42.cc
deal.II/examples/step-43/CMakeLists.txt
deal.II/examples/step-43/step-43.cc
deal.II/examples/step-44/step-44.cc
deal.II/examples/step-45/step-45.cc
deal.II/examples/step-46/CMakeLists.txt
deal.II/examples/step-46/step-46.cc
deal.II/examples/step-47/step-47.cc
deal.II/examples/step-48/step-48.cc
deal.II/examples/step-49/step-49.cc
deal.II/examples/step-5/step-5.cc
deal.II/examples/step-50/CMakeLists.txt
deal.II/examples/step-50/step-50.cc
deal.II/examples/step-51/CMakeLists.txt [new file with mode: 0644]
deal.II/examples/step-51/doc/builds-on [new file with mode: 0644]
deal.II/examples/step-51/doc/intro.dox [new file with mode: 0644]
deal.II/examples/step-51/doc/kind [new file with mode: 0644]
deal.II/examples/step-51/doc/results.dox [new file with mode: 0644]
deal.II/examples/step-51/doc/tooltip [new file with mode: 0644]
deal.II/examples/step-51/step-51.cc [new file with mode: 0644]
deal.II/examples/step-6/step-6.cc
deal.II/examples/step-7/step-7.cc
deal.II/examples/step-8/step-8.cc
deal.II/examples/step-9/step-9.cc
deal.II/include/deal.II/base/config.h.in
deal.II/include/deal.II/base/data_out_base.h
deal.II/include/deal.II/base/derivative_form.h
deal.II/include/deal.II/base/geometry_info.h
deal.II/include/deal.II/base/partitioner.h
deal.II/include/deal.II/base/subscriptor.h
deal.II/include/deal.II/base/symmetric_tensor.h
deal.II/include/deal.II/base/table_handler.h
deal.II/include/deal.II/base/template_constraints.h
deal.II/include/deal.II/base/tensor_function.h
deal.II/include/deal.II/base/utilities.h
deal.II/include/deal.II/dofs/dof_handler.h
deal.II/include/deal.II/fe/fe.h
deal.II/include/deal.II/fe/fe_base.h
deal.II/include/deal.II/fe/fe_face.h
deal.II/include/deal.II/fe/fe_q_base.h
deal.II/include/deal.II/fe/fe_system.h
deal.II/include/deal.II/fe/mapping.h
deal.II/include/deal.II/grid/grid_generator.h
deal.II/include/deal.II/grid/grid_tools.h
deal.II/include/deal.II/grid/tria_accessor.h
deal.II/include/deal.II/hp/fe_values.h
deal.II/include/deal.II/lac/block_matrix_base.h
deal.II/include/deal.II/lac/constraint_matrix.h
deal.II/include/deal.II/lac/petsc_parallel_block_vector.h
deal.II/include/deal.II/lac/petsc_parallel_sparse_matrix.h
deal.II/include/deal.II/lac/petsc_parallel_vector.h
deal.II/include/deal.II/lac/slepc_solver.h
deal.II/include/deal.II/lac/sparsity_pattern.h
deal.II/include/deal.II/lac/sparsity_tools.h
deal.II/include/deal.II/lac/trilinos_parallel_block_vector.h
deal.II/include/deal.II/lac/trilinos_precondition.h
deal.II/include/deal.II/matrix_free/dof_info.templates.h
deal.II/include/deal.II/multigrid/mg_transfer_component.h
deal.II/include/deal.II/multigrid/multigrid.h
deal.II/include/deal.II/numerics/data_out.h
deal.II/include/deal.II/numerics/data_out_faces.h
deal.II/include/deal.II/numerics/data_out_rotation.h
deal.II/include/deal.II/numerics/data_postprocessor.h
deal.II/include/deal.II/numerics/vector_tools.h
deal.II/source/base/data_out_base.cc
deal.II/source/base/geometry_info.cc
deal.II/source/base/index_set.cc
deal.II/source/base/logstream.cc
deal.II/source/base/table_handler.cc
deal.II/source/dofs/dof_tools.cc
deal.II/source/fe/fe.cc
deal.II/source/fe/fe_data.cc
deal.II/source/fe/fe_face.cc
deal.II/source/fe/fe_q_base.cc
deal.II/source/fe/fe_system.cc
deal.II/source/fe/fe_values.cc
deal.II/source/fe/mapping_q.cc
deal.II/source/fe/mapping_q_eulerian.cc
deal.II/source/fe/mapping_q_eulerian.inst.in
deal.II/source/grid/grid_generator.cc
deal.II/source/grid/grid_generator.inst.in
deal.II/source/grid/grid_tools.cc
deal.II/source/grid/grid_tools.inst.in
deal.II/source/lac/chunk_sparsity_pattern.cc
deal.II/source/lac/constraint_matrix.cc
deal.II/source/lac/petsc_matrix_free.cc
deal.II/source/lac/petsc_parallel_sparse_matrix.cc
deal.II/source/lac/petsc_parallel_vector.cc
deal.II/source/lac/slepc_solver.cc
deal.II/source/lac/slepc_spectral_transformation.cc
deal.II/source/lac/sparsity_pattern.cc
deal.II/source/lac/sparsity_tools.cc
deal.II/source/lac/trilinos_block_vector.cc
deal.II/source/lac/trilinos_precondition.cc
deal.II/source/lac/trilinos_solver.cc
deal.II/source/numerics/data_out.cc
deal.II/source/numerics/data_out.inst.in
deal.II/source/numerics/data_out_faces.cc
deal.II/source/numerics/data_out_rotation.cc
deal.II/source/numerics/vector_tools.inst.in

index 04dba539c696ceb060503a5d8e6d5094a214a21c..714613a8c7f85a71fb7ba5a089abfda27301942d 100644 (file)
@@ -49,7 +49,7 @@ FOREACH(_file ${_macro_files})
 ENDFOREACH()
 
 #
-# Check whether the doc and bundled folders are available:
+# Check for the existence of various optional folders:
 #
 IF(EXISTS ${CMAKE_SOURCE_DIR}/bundled/CMakeLists.txt)
   SET(DEAL_II_HAVE_BUNDLED_DIRECTORY TRUE)
@@ -59,6 +59,14 @@ IF(EXISTS ${CMAKE_SOURCE_DIR}/doc/CMakeLists.txt)
   SET(DEAL_II_HAVE_DOC_DIRECTORY TRUE)
 ENDIF()
 
+IF(NOT DEFINED TEST_DIR)
+  GET_FILENAME_COMPONENT(TEST_DIR "${CMAKE_SOURCE_DIR}" PATH)
+  SET(TEST_DIR "${TEST_DIR}/tests")
+ENDIF()
+IF(EXISTS ${TEST_DIR}/CMakeLists.txt)
+  SET(DEAL_II_HAVE_TESTS_DIRECTORY TRUE)
+ENDIF()
+
 #
 # We have to initialize some cached variables before PROJECT is called, so
 # do it at this point:
@@ -72,6 +80,8 @@ PROJECT(deal.II CXX)
 ENABLE_LANGUAGE_OPTIONAL(C)
 ENABLE_LANGUAGE_OPTIONAL(Fortran)
 
+INCLUDE(setup_post_project_call)
+
 INCLUDE(setup_deal_ii)
 INCLUDE(setup_compiler_flags)
 
@@ -135,6 +145,10 @@ ADD_SUBDIRECTORY(cmake/config) # has to be included after source
 ADD_SUBDIRECTORY(contrib) # has to be included after source
 ADD_SUBDIRECTORY(examples)
 
+IF(DEAL_II_HAVE_TESTS_DIRECTORY)
+  ADD_SUBDIRECTORY(${TEST_DIR} ${CMAKE_BINARY_DIR}/tests)
+ENDIF()
+
 #
 # And finally, print the configuration:
 #
index 1e0d8a1e9bb4394f6321cf785db58dc5db481cdf..846b614f2ae08e78d929ecc6e6271264f68c2819 100644 (file)
@@ -68,9 +68,10 @@ ENDIF()
 #
 # Threading Building Blocks library
 #
-IF(NOT CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
+IF(NOT CMAKE_SYSTEM_NAME MATCHES "CYGWIN"
+   AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
   #
-  # Cygwin is unsupported by tbb
+  # Cygwin is unsupported by tbb, Windows due to the way we compile tbb...
   #
   SET(FEATURE_THREADS_HAVE_BUNDLED TRUE)
   OPTION(DEAL_II_FORCE_BUNDLED_THREADS
index 3e2357b8e863c1d5a2183446e2b1f71e6110be97..2e7be178390539e720ed9800b6e9e4b23ec9bde5 100644 (file)
 #include <boost/smart_ptr/bad_weak_ptr.hpp>
 #include <boost/utility/swap.hpp>
 
-#if !defined(BOOST_INTEL_STDCXX0X)
-namespace std
-{
-  template<typename T> class shared_ptr;
-  template<typename T> class weak_ptr;
-}
-#endif
-
 namespace boost
 {
   template<typename T> class shared_ptr;
@@ -39,10 +31,20 @@ namespace boost
     {
       typedef boost::shared_ptr<T> shared_type;
     };
+
+// Workaround for a bug in boost:
+// https://svn.boost.org/trac/boost/ticket/6655
+//
+// It should be safe to depend on DEAL macros at this point as this header
+// should only be used by deal.II and dependent projects...
+//
+// - Maier, 2013
+#ifdef DEAL_II_CAN_USE_CXX11
     template<typename T> struct weak_ptr_traits<std::weak_ptr<T> >
     {
       typedef std::shared_ptr<T> shared_type;
     };
+#endif
 
     template<typename SharedPtr> struct shared_ptr_traits
     {};
@@ -51,10 +53,13 @@ namespace boost
     {
       typedef boost::weak_ptr<T> weak_type;
     };
+// as above
+#ifdef DEAL_II_CAN_USE_CXX11
     template<typename T> struct shared_ptr_traits<std::shared_ptr<T> >
     {
       typedef std::weak_ptr<T> weak_type;
     };
+#endif
 
     namespace detail
     {
index d8c275b5783f8432e20c1f0f77926cf6b773c34b..9639b89497285aedbc9584f547537832a614f1f2 100644 (file)
 #
 IF(CMAKE_C_COMPILER_WORKS)
   INCLUDE(TestBigEndian)
+
+  CLEAR_CMAKE_REQUIRED()
   TEST_BIG_ENDIAN(DEAL_II_WORDS_BIGENDIAN)
+  RESET_CMAKE_REQUIRED()
 ELSE()
   MESSAGE(STATUS
     "No suitable C compiler was found! Assuming little endian platform."
     )
+  SET(DEAL_II_WORDS_BIGENDIAN "0")
 ENDIF()
 
 
 IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
-
-  #
-  # These tests depend on certain cpu instruction sets being enabled, so
-  # use the user supplied compiler flags for the tests as well:
-  #
-  SET(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS_SAVED}")
-
-
   #
   # Take care that the following tests are rerun if CMAKE_REQUIRED_FLAGS
   # changes..
@@ -143,10 +139,9 @@ IF(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
     }
     "
     DEAL_II_HAVE_AVX)
-
-  SET(CMAKE_REQUIRED_FLAGS "")
 ENDIF()
 
+
 IF(DEAL_II_HAVE_SSE2)
   IF(DEAL_II_HAVE_AVX)
     SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 2)
@@ -156,4 +151,3 @@ IF(DEAL_II_HAVE_SSE2)
 ELSE()
   SET(DEAL_II_COMPILER_VECTORIZATION_LEVEL 0)
 ENDIF()
-
index 25d54167f5ec48f8e11626840cb79c146c882e4f..22e6a8a88b2226595779ddc1e050f5b65e0fcf8b 100644 (file)
@@ -68,9 +68,9 @@ SWITCH_LIBRARY_PREFERENCE()
 MARK_AS_ADVANCED(m_LIBRARY)
 
 IF(NOT m_LIBRARY MATCHES "-NOTFOUND")
-  SET(CMAKE_REQUIRED_LIBRARIES ${m_LIBRARY})
+  LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${m_LIBRARY})
   CHECK_CXX_SYMBOL_EXISTS("jn" "math.h" HAVE_JN)
-  SET(CMAKE_REQUIRED_LIBRARIES)
+  RESET_CMAKE_REQUIRED()
   IF(HAVE_JN)
     LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${m_LIBRARY})
   ENDIF()
@@ -116,12 +116,32 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
   SET(DEAL_II_MSVC TRUE)
 
   #
-  # Disable shared libraries on native Windows targets for the moment.
+  # Shared library handling:
   #
-  MESSAGE(WARNING "\n"
-    "BUILD_SHARED_LIBS forced to OFF\n\n"
-    )
-  SET(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
+  IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+    #
+    # With MinGW we're lucky:
+    #
+    ENABLE_IF_LINKS(DEAL_II_LINKER_FLAGS "-Wl,--export-all-symbols")
+    ENABLE_IF_LINKS(DEAL_II_LINKER_FLAGS "-Wl,--enable-auto-import")
+    ENABLE_IF_LINKS(DEAL_II_LINKER_FLAGS "-Wl,--allow-multiple-definition")
+
+    #
+    # Workaround for a miscompilation and linkage issue with shared libraries
+    # with MinGW. Replacing -O0 with -O1 seems to help..
+    #
+    REPLACE_FLAG(DEAL_II_CXX_FLAGS_DEBUG "-O0" "-O1")
+
+  ELSE()
+
+    #
+    # Otherwise disable shared libraries:
+    #
+    MESSAGE(WARNING "\n"
+      "BUILD_SHARED_LIBS forced to OFF\n\n"
+      )
+    SET(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
+  ENDIF()
 
   #
   # Disable -ggdb and -g on Windows/MinGW targets for the moment until the
@@ -135,6 +155,7 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
   STRIP_FLAG(DEAL_II_LINKER_FLAGS_DEBUG "-g")
 ENDIF()
 
+
 IF(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
   #
   # Workaround for a miscompilation and linkage issue with shared libraries
@@ -143,5 +164,4 @@ IF(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
   # - Matthias Maier, 2013
   #
   REPLACE_FLAG(DEAL_II_CXX_FLAGS_DEBUG "-O0" "-O1")
-
 ENDIF()
index cf49fb0e579e65cc7a008799f60092e9117c96db..bb63ba07404e9665c70b92fcfea422859832ef65 100644 (file)
 ########################################################################
 
 
-#
-# Some compiler versions, notably ICC, have trouble with the
-# following code in which we explicitly call a destructor.
-# This has to be worked around with a typedef. The problem is
-# that the workaround fails with some other compilers, so that
-# we can not unconditionally use the workaround...
-#
-# - Wolfgang Bangerth, Matthias Maier, rewritten 2012
-#
-CHECK_CXX_COMPILER_BUG(
-  "
-  namespace dealii
-  {
-    namespace FEValuesViews
-    {
-      template <int dim, int spacedim> struct Scalar {};
-    }
-
-    template <int dim, int spacedim>
-    struct X
-    {
-        FEValuesViews::Scalar<dim,spacedim> scalars[dim*spacedim];
-
-        void f()
-          {
-            scalars[0].dealii::FEValuesViews::Scalar<dim,spacedim>::~Scalar ();
-          }
-    };
-
-    template struct X<2,2>;
-  }
-  int main() { return 0; }
-  "
-  DEAL_II_EXPLICIT_DESTRUCTOR_BUG
-  )
-
-
 #
 # On some gcc 4.3 snapshots, a 'const' qualifier on a return type triggers a
 # warning. This is unfortunate, since we happen to stumble on this
index 037af96e8c22d816ab68a371d74843440a0a44f3..071ba6110bfad9f5f91bbdeda6ada12d6c7e4c5c 100644 (file)
@@ -81,7 +81,7 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
     )
   LIST(APPEND CONFIG_LIBRARIES
     ${_keyword}
-    ${CONFIG_LIBRARIES_${_build}}
+    \${DEAL_II_LIBRARIES_${_build}}
     )
 
   SET(CONFIG_TARGET_${_build}
@@ -89,7 +89,7 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
     )
   LIST(APPEND CONFIG_TARGET
     ${_keyword}
-    ${DEAL_II_BASE_NAME}${DEAL_II_${_build}_SUFFIX}
+    \${DEAL_II_TARGET_${_build}}
     )
 ENDFOREACH()
 
index bcedebb257f9ca1ec1ee8e69b9ccc4aa2650dc4e..a32109a4643addc26254d023ebb7e571c414630d 100644 (file)
@@ -1,22 +1,28 @@
-# $Id$
-
-#
-# Compatibility Make.global_options file
-#
-
-###############################################################################
-## Please note:
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2012 - 2013 by the deal.II authors
 ##
-##   This is a compatibility Make.global_options file generated by CMake
-##   from the ./cmake/config/Make.global_options.in file.
+## 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.
+##
+## ---------------------------------------------------------------------
 
 
 #
-# the following lines will be replaced by cmake
+# Please note:
+#
+# This is a compatibility Make.global_options file generated by CMake
+# from the ./cmake/config/Make.global_options.in file.
 #
 
+
 D                    = @CMAKE_INSTALL_PREFIX@
 CXX                  = @CMAKE_CXX_COMPILER@
 CXX-ID               = @CMAKE_CXX_COMPILER_ID@
@@ -62,15 +68,12 @@ EXEEXT     =
 
 
 # set paths to all the libraries we need:
-lib-deal2.o     = ${MAKEFILE_TARGETS_RELEASE}
-lib-deal2.g     = ${MAKEFILE_TARGETS_DEBUG}
+lib-deal2.o     = @MAKEFILE_TARGETS_RELEASE@
+lib-deal2.g     = @MAKEFILE_TARGETS_DEBUG@
 
 
-# include paths as command line flags. while compilers allow a space between
-# the '-I' and the actual path, we also send these flags to the
-# make_dependencies program that doesn't support the extra space.
-#
-INCLUDE = ${MAKEFILE_INCLUDE_DIRS}
+# Include paths as command line flags
+INCLUDE = @MAKEFILE_INCLUDE_DIRS@
 
 
 # compiler flags for debug and optimized mode
index a319fe155b5fdd9859aa01d7745a31834d77f132..455a4944b493ac2cd0fd69eb436d4f2be5f97182 100644 (file)
 #
 
 MACRO(FEATURE_LAPACK_FIND_EXTERNAL var)
-  FIND_PACKAGE(LAPACK)
-
-  #
-  # So, well... LAPACK_LINKER_FLAGS and LAPACK_LIBRARIES should contain the
-  # complete link interface. But for invalid user overrides we include
-  # BLAS_LIBRARIES and BLAS_LINKER_FLAGS as well..
-  #
-  IF(NOT LAPACK_LINKER_FLAGS MATCHES "${BLAS_LINKER_FLAGS}")
-    MESSAGE(STATUS
-      "Manually adding BLAS_LINKER_FLAGS to LAPACK_LINKER_FLAGS"
-      )
-    ADD_FLAGS(LAPACK_LINKER_FLAGS "${BLAS_LINKER_FLAGS}")
-  ENDIF()
-  IF(NOT "${LAPACK_LIBRARIES}" MATCHES "${BLAS_LIBRARIES}")
-    MESSAGE(STATUS
-      "Manually adding BLAS_LIBRARIES to LAPACK_LIBRARIES"
-      )
-    LIST(APPEND LAPACK_LIBRARIES ${BLAS_LIBRARIES})
-  ENDIF()
-
-  MARK_AS_ADVANCED(
-    atlas_LIBRARY
-    blas_LIBRARY
-    gslcblas_LIBRARY
-    lapack_LIBRARY
-    m_LIBRARY
-    ptf77blas_LIBRARY
-    ptlapack_LIBRARY
-    refblas_LIBRARY
-    reflapack_LIBRARY
-    )
+  FIND_PACKAGE(DEALII_LAPACK)
 
   IF(LAPACK_FOUND)
-    #
-    # Well, in case of static archives we have to manually pick up the
-    # complete link interface. *sigh*
-    #
-    # Do this unconditionally for the most common case:
-    # TODO: Non-GNU setups...
-    #
-    #
-    # Switch the library preference back to prefer dynamic libraries if
-    # DEAL_II_PREFER_STATIC_LIBS=TRUE but DEAL_II_STATIC_EXECUTABLE=FALSE. In
-    # this case system libraries should be linked dynamically.
-    #
-    SWITCH_LIBRARY_PREFERENCE()
-    FOREACH(_lib gfortran m quadmath)
-      FIND_LIBRARY(${_lib}_LIBRARY
-        NAMES ${_lib}
-        HINTS ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
-      MARK_AS_ADVANCED(${_lib}_LIBRARY)
-
-      IF(NOT ${_lib}_LIBRARY MATCHES "-NOTFOUND")
-        LIST(APPEND LAPACK_LIBRARIES ${${_lib}_LIBRARY})
-      ENDIF()
-    ENDFOREACH()
-    SWITCH_LIBRARY_PREFERENCE()
-
     SET(${var} TRUE)
   ENDIF()
 ENDMACRO()
@@ -97,8 +42,12 @@ SET(DEAL_II_LAPACK_FUNCTIONS
   )
 
 MACRO(CHECK_FOR_LAPACK_FUNCTIONS)
+  #
+  # Clear the test flags because the following test will use a C compiler
+  #
+  CLEAR_CMAKE_REQUIRED()
+  SET(CMAKE_REQUIRED_FLAGS "${LAPACK_LINKER_FLAGS}")
   SET(CMAKE_REQUIRED_LIBRARIES ${LAPACK_LIBRARIES})
-  ADD_FLAGS(CMAKE_REQUIRED_FLAGS "${LAPACK_LINKER_FLAGS}")
   #
   # Push -pthread as well:
   #
@@ -118,9 +67,7 @@ MACRO(CHECK_FOR_LAPACK_FUNCTIONS)
     ENDFOREACH()
   ENDIF()
 
-  SET(CMAKE_REQUIRED_LIBRARIES)
-  STRIP_FLAG(CMAKE_REQUIRED_FLAGS "${LAPACK_LINKER_FLAGS}")
-  STRIP_FLAG(CMAKE_REQUIRED_FLAGS "-pthread")
+  RESET_CMAKE_REQUIRED()
 ENDMACRO()
 
 
index 85de2a41c2ec721d2dc7ffe0911379e21545ef4a..2eb6bd3847771a695d08d83904aa1ca763d95992 100644 (file)
@@ -107,10 +107,15 @@ MACRO(FEATURE_MPI_ERROR_MESSAGE)
   MESSAGE(FATAL_ERROR "\n"
     "Could not find any suitable mpi library!\n"
     "Please ensure that an mpi library is installed on your computer\n"
-    "and set CMAKE_CXX_COMPILER and CMAKE_C_COMPILER to the appropriate mpi\n"
-    "wrappers:\n"
-    "    $ CC=\".../mpicc\" CXX=\".../mpicxx\" cmake <...>\n"
-    "    $ cmake -DCMAKE_C_COMPILER=\".../mpicc\" -DCMAKE_CXX_COMPIER=\".../mpicxx\" <...>\n"
+    "and set CMAKE_CXX_COMPILER to the appropriate mpi wrappers:\n"
+    "    $ CXX=\".../mpicxx\" cmake <...>\n"
+    "    $ cmake -DCMAKE_CXX_COMPILER=\".../mpicxx\" <...>\n"
+    "Or with additional C and Fortran wrappers (recommended!):\n"
+    "    $ CC=\".../mpicc\" CXX=\".../mpicxx\" F90=\".../mpif90\" cmake <...>\n"
+    "    $ cmake -DCMAKE_C_COMPILER=\".../mpicc\"\\\n"
+    "            -DCMAKE_CXX_COMPILER=\".../mpicxx\"\\\n"
+    "            -DCMAKE_Fortran_COMPILER=\".../mpif90\"\\\n"
+    "            <...>\n"
     )
 ENDMACRO()
 
index 8525ad770ea16b5c61560ce9c0203143e94c548b..d43fd3ea49d29f30041d3927e594672fca95be35 100644 (file)
@@ -36,7 +36,15 @@ MACRO(SETUP_THREADING)
     # this case system libraries should be linked dynamically.
     #
     SWITCH_LIBRARY_PREFERENCE()
+
+    #
+    # Clear the test flags because FindThreads.cmake will use a C compiler:
+    #
+    CLEAR_CMAKE_REQUIRED()
+
     FIND_PACKAGE(Threads)
+
+    RESET_CMAKE_REQUIRED()
     SWITCH_LIBRARY_PREFERENCE()
 
   ELSE()
@@ -112,7 +120,7 @@ MACRO(SETUP_THREADING)
     }
     "
     DEAL_II_HAVE_MT_POSIX_BARRIERS)
-    STRIP_FLAG(CMAKE_REQUIRED_FLAGS "${CMAKE_THREAD_LIBS_INIT}")
+    RESET_CMAKE_REQUIRED()
     IF(NOT DEAL_II_HAVE_MT_POSIX_BARRIERS)
       SET(DEAL_II_USE_MT_POSIX_NO_BARRIERS TRUE)
     ENDIF()
index 92a1f10880435ab8969ad5efba384b1b0e8c237a..8d83b9661d61d70fa8d1a7df3d2060186f7f0b7f 100644 (file)
@@ -22,7 +22,7 @@ MACRO(FEATURE_METIS_FIND_EXTERNAL var)
   FIND_PACKAGE(METIS)
 
   IF(METIS_FOUND)
-    IF(METIS_MAJOR GREATER 4)
+    IF(METIS_VERSION_MAJOR GREATER 4)
       SET(${var} TRUE)
     ELSE()
       MESSAGE(STATUS "Insufficient metis installation found: "
index 41a5f93bf5bd9988242059a9ee8498f70284f711..3669492796fab047a6afeb9114f7110b639c31f3 100644 (file)
@@ -131,10 +131,10 @@ MACRO(FEATURE_TRILINOS_FIND_EXTERNAL var)
         "has to be configured to use the same number of bits as deal.II, but "
         "found:\n"
         "  DEAL_II_WITH_64BIT_INDICES = ${DEAL_II_WITH_64BIT_INDICES}\n"
-        "  TRILINOS_WITH_NO_32BIT_INDICES = ${TRILINOS_WITH_NO_32_BIT_INDICES}\n" 
+        "  TRILINOS_WITH_NO_32BIT_INDICES = ${TRILINOS_WITH_NO_32_BIT_INDICES}\n"
         )
       SET(${var} FALSE)
-    ENDIF()  
+    ENDIF()
 
     #
     # Trilinos has to be configured with 64bit indices if deal.II uses unsigned long
@@ -143,74 +143,41 @@ MACRO(FEATURE_TRILINOS_FIND_EXTERNAL var)
     IF(TRILINOS_WITH_NO_64BIT_INDICES AND DEAL_II_WITH_64BIT_INDICES)
       MESSAGE(STATUS "deal.II was configured to use 64bit global indices but "
         "Trilinos was not."
-        ) 
+        )
       SET(TRILINOS_ADDITIONAL_ERROR_STRING
         ${TRILINOS_ADDITIONAL_ERROR_STRING}
         "The Trilinos installation (found at \"${TRILINOS_DIR}\")\n"
         "has to be configured to use the same number of bits as deal.II, but "
         "found:\n"
         "  DEAL_II_WITH_64BIT_INDICES = ${DEAL_II_WITH_64BIT_INDICES}\n"
-        "  TRILINOS_WITH_NO_64BIT_INDICES = ${TRILINOS_WITH_NO_64_BIT_INDICES}\n" 
+        "  TRILINOS_WITH_NO_64BIT_INDICES = ${TRILINOS_WITH_NO_64_BIT_INDICES}\n"
         )
       SET(${var} FALSE)
-    ENDIF()  
-
+    ENDIF()
 
     #
     # Some versions of Sacado_cmath.hpp do things that aren't compatible
     # with the -std=c++0x flag of GCC, see deal.II FAQ.
     # Test whether that is indeed the case
     #
-    IF(${var})
-      SET(CMAKE_REQUIRED_INCLUDES ${TRILINOS_INCLUDE_DIRS})
-      PUSH_TEST_FLAG("${DEAL_II_CXX11_FLAG}")
-
-      CHECK_CXX_SOURCE_COMPILES(
-        "
-        #include <Sacado_cmath.hpp>
-        int main(){ return 0; }
-        "
-        TRILINOS_SUPPORTS_CPP11)
-
-      IF(DEAL_II_CAN_USE_CXX11 AND NOT TRILINOS_SUPPORTS_CPP11)
-        #
-        # Try whether exporting HAS_C99_TR1_CMATH helps:
-        #
-        PUSH_TEST_FLAG("-DHAS_C99_TR1_CMATH")
-        CHECK_CXX_SOURCE_COMPILES(
-          "
-          #include <Sacado_cmath.hpp>
-          int main(){ return 0; }
-          "
-          TRILINOS_HAS_C99_TR1_WORKAROUND)
-        POP_TEST_FLAG()
-
-        IF(TRILINOS_HAS_C99_TR1_WORKAROUND)
-          LIST(APPEND DEAL_II_DEFINITIONS "HAS_C99_TR1_CMATH")
-          LIST(APPEND DEAL_II_USER_DEFINITIONS "HAS_C99_TR1_CMATH")
-        ELSE()
-          MESSAGE(STATUS "Could not find a sufficient Trilinos installation: "
-            "The installation is not compatible with the C++ standard selected for "
-            "this compiler."
-            )
-          SET(TRILINOS_ADDITIONAL_ERROR_STRING
-            ${TRILINOS_ADDITIONAL_ERROR_STRING}
-            "The Trilinos installation (found at \"${TRILINOS_DIR}\")\n"
-            "is not compatible with the C++ standard selected for\n"
-            "this compiler. See the deal.II FAQ page for a solution.\n\n"
-            )
-          SET(${var} FALSE)
-        ENDIF()
-      ENDIF()
+    IF(DEAL_II_CAN_USE_CXX11 AND NOT TRILINOS_SUPPORTS_CPP11)
 
-      POP_TEST_FLAG()
-      SET(CMAKE_REQUIRED_INCLUDES)
-
-      #
-      # Remove the following variables from the cache to force a recheck:
-      #
-      UNSET(TRILINOS_SUPPORTS_CPP11 CACHE)
-      UNSET(TRILINOS_HAS_C99_TR1_WORKAROUND CACHE)
+      IF(TRILINOS_HAS_C99_TR1_WORKAROUND)
+        LIST(APPEND DEAL_II_DEFINITIONS "HAS_C99_TR1_CMATH")
+        LIST(APPEND DEAL_II_USER_DEFINITIONS "HAS_C99_TR1_CMATH")
+      ELSE()
+        MESSAGE(STATUS "Could not find a sufficient Trilinos installation: "
+          "The installation is not compatible with the C++ standard selected for "
+          "this compiler."
+          )
+        SET(TRILINOS_ADDITIONAL_ERROR_STRING
+          ${TRILINOS_ADDITIONAL_ERROR_STRING}
+          "The Trilinos installation (found at \"${TRILINOS_DIR}\")\n"
+          "is not compatible with the C++ standard selected for\n"
+          "this compiler. See the deal.II FAQ page for a solution.\n\n"
+          )
+        SET(${var} FALSE)
+      ENDIF()
     ENDIF()
 
   ENDIF(TRILINOS_FOUND)
@@ -218,13 +185,6 @@ ENDMACRO()
 
 
 MACRO(FEATURE_TRILINOS_CONFIGURE_EXTERNAL)
-  #
-  # *Boy* Sanitize the include paths given by TrilinosConfig.cmake...
-  #
-  STRING(REGEX REPLACE
-    "(lib64|lib)\\/cmake\\/Trilinos\\/\\.\\.\\/\\.\\.\\/\\.\\.\\/" ""
-    TRILINOS_INCLUDE_DIRS "${TRILINOS_INCLUDE_DIRS}"
-    )
 
   INCLUDE_DIRECTORIES(${TRILINOS_INCLUDE_DIRS})
 
index 7d017236b4c2bb19bbdb995eb32923e7e4fbafa3..f2071971ea5b63ced0ab9358ab0d29316ab952b3 100644 (file)
@@ -38,6 +38,11 @@ SET(DEAL_II_WITH_BOOST ON # Always true. We need it :-]
 
 MACRO(FEATURE_BOOST_FIND_EXTERNAL var)
 
+  SET_IF_EMPTY(BOOST_DIR "$ENV{BOOST_DIR}")
+  IF(NOT "${BOOST_DIR}" STREQUAL "")
+    SET(BOOST_ROOT "${BOOST_DIR}")
+  ENDIF()
+
   IF(DEAL_II_WITH_THREADS)
     SET(_boost_components serialization system thread)
   ELSE()
@@ -65,11 +70,24 @@ MACRO(FEATURE_BOOST_FIND_EXTERNAL var)
 
   MARK_AS_ADVANCED(Boost_DIR)
 
+  SET(BOOST_VERSION_MAJOR "${Boost_MAJOR_VERSION}")
+  SET(BOOST_VERSION_MINOR "${Boost_MINOR_VERSION}")
+  SET(BOOST_VERSION_SUBMINOR "${Boost_SUBMINOR_VERSION}")
+  SET(BOOST_VERSION
+    "${BOOST_VERSION_MAJOR}.${BOOST_VERSION_MINOR}.${BOOST_VERSION_SUBMINOR}"
+    )
+
+
   IF( Boost_SERIALIZATION_FOUND AND
       Boost_SYSTEM_FOUND AND
       (NOT DEAL_II_WITH_THREADS OR Boost_THREAD_FOUND)
     )
+    MARK_AS_ADVANCED(BOOST_DIR)
     SET(${var} TRUE)
+  ELSE()
+    SET(BOOST_DIR "" CACHE PATH
+      "An optional hint to a boost directory"
+      )
   ENDIF()
 ENDMACRO()
 
index 269f85daa1a0cf3f0e815d6c6c41800eb400cfb0..c0d1b212b0b6fe3865a1147d614a9b5a7fc0a857 100644 (file)
@@ -25,9 +25,14 @@ MACRO(FEATURE_SLEPC_FIND_EXTERNAL var)
 
   IF(SLEPC_FOUND)
     #
-    # Check whether SLEPc and PETSc are compatible.
+    # Check whether SLEPc and PETSc are compatible according to
+    # SLEPc's rules: This is equivalent to asking if the VERSION_MAJOR
+    # and VERSION_MINOR of PETSc and SLEPc are
+    # equivalent; and where VERSION_SUBMINORs are allowed to differ.
     #
-    IF("${SLEPC_VERSION}" STREQUAL "${PETSC_VERSION}")
+    IF( ("${SLEPC_VERSION_MAJOR}" STREQUAL "${PETSC_VERSION_MAJOR}")
+       AND
+       ("${SLEPC_VERSION_MINOR}" STREQUAL "${PETSC_VERSION_MINOR}"))
       SET(${var} TRUE)
     ELSE()
 
diff --git a/deal.II/cmake/macros/macro_clear_cmake_required.cmake b/deal.II/cmake/macros/macro_clear_cmake_required.cmake
new file mode 100644 (file)
index 0000000..186004f
--- /dev/null
@@ -0,0 +1,29 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 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.
+##
+## ---------------------------------------------------------------------
+
+#
+# A small macro to clear the CMAKE_REQUIRED_* variables.
+#
+# Usage:
+#     CLEAR_CMAKE_REQUIRED_FLAGS
+#
+
+MACRO(CLEAR_CMAKE_REQUIRED)
+  SET(CMAKE_REQUIRED_FLAGS)
+  SET(CMAKE_REQUIRED_INCLUDES)
+  SET(CMAKE_REQUIRED_LIBRARIES)
+ENDMACRO()
+
index bcd842eb097fcd5ef0ccdac9a02fa98d705f5411..8f355ff1c9d31068b82933f2c9381f98e2edbc3a 100644 (file)
@@ -51,9 +51,15 @@ MACRO(DEAL_II_INITIALIZE_CACHED_VARIABLES)
   ENDIF()
 
   #
-  # Reset build type if unsupported:
+  # Reset build type if unsupported, i.e. if it is not (case insensitively
+  # equal to Debug or Release or unsupported by the current build type:
   #
-  IF(NOT DEAL_II_BUILD_TYPE MATCHES "${CMAKE_BUILD_TYPE}")
+  STRING(TOLOWER "${CMAKE_BUILD_TYPE}" _cmake_build_type)
+  STRING(TOLOWER "${DEAL_II_BUILD_TYPE}" _deal_ii_build_type)
+
+  IF( NOT "${_cmake_build_type}" MATCHES "^(debug|release)$"
+      OR NOT _deal_ii_build_type MATCHES "${_cmake_build_type}" )
+
     IF("${DEAL_II_BUILD_TYPE}" STREQUAL "DebugRelease")
       SET(_new_build_type "Debug")
     ELSE()
index e98bd2557632d6ca15e6cf9749bf275b560ece09..28b88dd1d09ad93770c160729c46a8e47bafdc49 100644 (file)
@@ -61,16 +61,16 @@ MACRO(DEAL_II_SETUP_TARGET _target)
     )
 
   #
-  # Append build type dependend flags and definitions.
+  # Append build type dependent flags and definitions.
   #
 
   #
   # For this we obey the behaviour of the "optimized" and "debug"
   # keywords and this is a bit tricky:
   #
-  # If the global property DEBUG_CONFIGURATIONS is set all build
-  # types that (case insensitive) match one of the listed build types is
-  # considered a "debug" build. The rest is "optimized".
+  # If the global property DEBUG_CONFIGURATIONS is set all build types that
+  # (case insensitively) match one of the listed build types is considered
+  # a "debug" build. The rest is "optimized".
   #
   # Otherwise every build type that (case insensitively) matches "debug" is
   # considered a debug build.
@@ -97,7 +97,12 @@ MACRO(DEAL_II_SETUP_TARGET _target)
     ENDIF()
   ENDIF()
 
-  IF(_on_debug_build)
+  #
+  # We can only append DEBUG link flags and compile definitions if deal.II
+  # was build with Debug or DebugRelease build type. So test for this:
+  #
+  IF( _on_debug_build
+      AND DEAL_II_BUILD_TYPE MATCHES "Debug" )
     SET_PROPERTY(TARGET ${_target} APPEND_STRING PROPERTY
       LINK_FLAGS " ${DEAL_II_LINKER_FLAGS_DEBUG}"
       )
index 0f4ef07e965dd60217f757a4ba4df91f94f88735..6c2bfeb6d1b667cfa182cba1d6fd465c6f4d49af 100644 (file)
@@ -30,7 +30,7 @@ MACRO(ENABLE_IF_LINKS _variable _flag)
     STRING(REPLACE "," "" _flag_name "${_flag_name}")
     STRING(REPLACE "--" "__" _flag_name "${_flag_name}")
     SET(_backup ${CMAKE_REQUIRED_LIBRARIES})
-    SET(CMAKE_REQUIRED_LIBRARIES "${_flag_stripped}")
+    LIST(APPEND CMAKE_REQUIRED_LIBRARIES "${_flag_stripped}")
     CHECK_CXX_COMPILER_FLAG(
       ""
       DEAL_II_HAVE_FLAG_${_flag_name}
index 885b960f8c47e52b43a83210f6d029ca3b19fe8b..fccb978ae428c08c9b4a1fe79ae2d41712476a1d 100644 (file)
 #
 
 MACRO(ENABLE_LANGUAGE_OPTIONAL _language)
-  #
-  # Run this check exactly once:
-  #
   IF(NOT ${_language}_CHECKED)
+    #
+    # Run this check exactly once:
+    #
     SET(${_language}_CHECKED TRUE CACHE INTERNAL "" FORCE)
 
     SET(_tmp ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/${_language}_test)
@@ -58,9 +58,17 @@ MACRO(ENABLE_LANGUAGE_OPTIONAL _language)
       )
 
     IF("${_result}" STREQUAL "0")
+      SET(DEAL_II_${_language}_COMPILER_WORKS TRUE CACHE INTERNAL "" FORCE)
       ENABLE_LANGUAGE(${_language})
     ELSE()
       MESSAGE(STATUS "No working ${_language} compiler found, disabling ${_language}")
     ENDIF()
+  ELSE()
+    #
+    # Enable the language depending on the cached result from a former run:
+    #
+    IF(DEAL_II_${_language}_COMPILER_WORKS)
+      ENABLE_LANGUAGE(${_language})
+    ENDIF()
   ENDIF()
 ENDMACRO()
diff --git a/deal.II/cmake/macros/macro_reset_cmake_required.cmake b/deal.II/cmake/macros/macro_reset_cmake_required.cmake
new file mode 100644 (file)
index 0000000..0f2865a
--- /dev/null
@@ -0,0 +1,30 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 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.
+##
+## ---------------------------------------------------------------------
+
+#
+# A small macro to reset the CMAKE_REQUIRED_* variables to its default
+# values
+#
+# Usage:
+#     RESET_CMAKE_REQUIRED_FLAGS
+#
+
+MACRO(RESET_CMAKE_REQUIRED)
+  SET(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS_SAVED})
+  SET(CMAKE_REQUIRED_INCLUDES)
+  SET(CMAKE_REQUIRED_LIBRARIES)
+ENDMACRO()
+
index 243899b9e0062937cc1d597f3b7c888ca46b5465..f2bb51d628a4bbc322c9c9afe29a207f2c0f3b39 100644 (file)
@@ -34,7 +34,7 @@ SET_IF_EMPTY(ARPACK_DIR "$ENV{ARPACK_DIR}")
 #
 # ARPACK needs LAPACK and BLAS as dependencies:
 #
-FIND_PACKAGE(LAPACK)
+FIND_PACKAGE(DEALII_LAPACK)
 
 FIND_LIBRARY(ARPACK_LIBRARY
   NAMES arpack
diff --git a/deal.II/cmake/modules/FindDEALII_LAPACK.cmake b/deal.II/cmake/modules/FindDEALII_LAPACK.cmake
new file mode 100644 (file)
index 0000000..b1c7630
--- /dev/null
@@ -0,0 +1,138 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 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.
+##
+## ---------------------------------------------------------------------
+
+#
+# This module is a wrapper around the FindLAPACK.cmake module provided by
+# CMake.
+#
+# This module exports
+#
+#   LAPACK_FOUND
+#   LAPACK_LIBRARIES
+#   LAPACK_LINKER_FLAGS
+#   BLAS_FOUND
+#   BLAS_LIBRARIES
+#   BLAS_LINKER_FLAGS
+#   METIS_INCLUDE_DIRS
+#
+
+
+
+#
+# We have to use a trick with CMAKE_PREFIX_PATH to make LAPACK_DIR and
+# BLAS_DIR work...
+#
+SET_IF_EMPTY(BLAS_DIR "$ENV{BLAS_DIR}")
+SET_IF_EMPTY(LAPACK_DIR "$ENV{LAPACK_DIR}")
+
+SET(_cmake_prefix_path_backup "${CMAKE_PREFIX_PATH}")
+
+SET(CMAKE_PREFIX_PATH ${BLAS_DIR} ${LAPACK_DIR} ${_cmake_prefix_path_backup})
+
+FIND_PACKAGE(BLAS)
+
+SET(CMAKE_PREFIX_PATH ${LAPACK_DIR} ${_cmake_prefix_path_backup})
+
+FIND_PACKAGE(LAPACK)
+
+SET(CMAKE_PREFIX_PATH ${_cmake_prefix_path_backup})
+
+MARK_AS_ADVANCED(
+  atlas_LIBRARY
+  blas_LIBRARY
+  gslcblas_LIBRARY
+  lapack_LIBRARY
+  m_LIBRARY
+  ptf77blas_LIBRARY
+  ptlapack_LIBRARY
+  refblas_LIBRARY
+  reflapack_LIBRARY
+  )
+
+
+IF(LAPACK_FOUND)
+  SET(DEALII_LAPACK_FOUND TRUE)
+
+  #
+  # So, well... LAPACK_LINKER_FLAGS and LAPACK_LIBRARIES should contain the
+  # complete link interface. But for invalid user overrides we include
+  # BLAS_LIBRARIES and BLAS_LINKER_FLAGS as well..
+  #
+  IF(NOT LAPACK_LINKER_FLAGS MATCHES "${BLAS_LINKER_FLAGS}")
+    MESSAGE(STATUS
+      "Manually adding BLAS_LINKER_FLAGS to LAPACK_LINKER_FLAGS"
+      )
+    ADD_FLAGS(LAPACK_LINKER_FLAGS "${BLAS_LINKER_FLAGS}")
+  ENDIF()
+  IF(NOT "${LAPACK_LIBRARIES}" MATCHES "${BLAS_LIBRARIES}")
+    MESSAGE(STATUS
+      "Manually adding BLAS_LIBRARIES to LAPACK_LIBRARIES"
+      )
+    LIST(APPEND LAPACK_LIBRARIES ${BLAS_LIBRARIES})
+  ENDIF()
+
+  #
+  # Well, in case of static archives we have to manually pick up the
+  # complete link interface. *sigh*
+  #
+  # Do this unconditionally for the most common case:
+  # TODO: Non-GNU setups...
+  #
+  # Switch the library preference back to prefer dynamic libraries if
+  # DEAL_II_PREFER_STATIC_LIBS=TRUE but DEAL_II_STATIC_EXECUTABLE=FALSE. In
+  # this case system libraries should be linked dynamically.
+  #
+  SWITCH_LIBRARY_PREFERENCE()
+  FOREACH(_lib gfortran m quadmath)
+    FIND_LIBRARY(${_lib}_LIBRARY
+      NAMES ${_lib}
+      HINTS ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
+    MARK_AS_ADVANCED(${_lib}_LIBRARY)
+
+    IF(NOT ${_lib}_LIBRARY MATCHES "-NOTFOUND")
+      LIST(APPEND BLAS_LIBRARIES ${${_lib}_LIBRARY})
+      LIST(APPEND LAPACK_LIBRARIES ${${_lib}_LIBRARY})
+    ENDIF()
+  ENDFOREACH()
+  SWITCH_LIBRARY_PREFERENCE()
+
+  MARK_AS_ADVANCED(
+    BLAS_DIR
+    LAPACK_DIR
+    )
+
+ELSE()
+  SET(DEALII_LAPACK_FOUND FALSE)
+
+  SET(LAPACK_DIR "" CACHE PATH
+    "An optional hint to a LAPACK installation"
+    )
+  SET(BLAS_DIR "" CACHE PATH
+    "An optional hint to a BLAS installation"
+    )
+
+  #
+  # If we couldn't find LAPACK, clean up the library variables:
+  #
+
+  IF("${BLAS_LIBRARIES}" STREQUAL "FALSE")
+    SET(BLAS_LIBRARIES "")
+  ENDIF()
+  IF("${LAPACK_LIBRARIES}" STREQUAL "FALSE")
+    SET(LAPACK_LIBRARIES "")
+  ENDIF()
+
+ENDIF()
index f0cfa9eba7c7271bbc5a774510af4b9729c51849..80cbd97d478f612d006d51dbc861ec738a21e5cb 100644 (file)
@@ -21,6 +21,9 @@
 #
 #   METIS_LIBRARIES
 #   METIS_INCLUDE_DIRS
+#   METIS_VERSION
+#   METIS_VERSION_MAJOR
+#   METIS_VERSION_MINOR
 #
 
 INCLUDE(FindPackageHandleStandardArgs)
@@ -87,13 +90,27 @@ IF(METIS_FOUND)
   #
   # Extract the version number out of metis.h
   #
-  FILE(STRINGS "${METIS_INCLUDE_DIR}/metis.h" METIS_MAJOR_STRING
-    REGEX "METIS_VER_MAJOR")
-  STRING(REGEX REPLACE "^.*METIS_VER_MAJOR.* ([0-9]+).*" "\\1" METIS_MAJOR "${METIS_MAJOR_STRING}")
-
-  FILE(STRINGS "${METIS_INCLUDE_DIR}/metis.h" METIS_MINOR_STRING
-    REGEX "METIS_VER_MINOR")
-  STRING(REGEX REPLACE "^.*METIS_VER_MINOR.* ([0-9]+).*" "\\1" METIS_MINOR "${METIS_MINOR_STRING}")
+  FILE(STRINGS "${METIS_INCLUDE_DIR}/metis.h" _metis_major_string
+    REGEX "METIS_VER_MAJOR"
+    )
+  STRING(REGEX REPLACE "^.*METIS_VER_MAJOR.* ([0-9]+).*" "\\1"
+    METIS_VERSION_MAJOR "${_metis_major_string}"
+    )
+  FILE(STRINGS "${METIS_INCLUDE_DIR}/metis.h" _metis_minor_string
+    REGEX "METIS_VER_MINOR"
+    )
+  STRING(REGEX REPLACE "^.*METIS_VER_MINOR.* ([0-9]+).*" "\\1"
+    METIS_VERSION_MINOR "${_metis_minor_string}"
+    )
+  FILE(STRINGS "${METIS_INCLUDE_DIR}/metis.h" _metis_subminor_string
+    REGEX "METIS_VER_SUBMINOR"
+    )
+  STRING(REGEX REPLACE "^.*METIS_VER_SUBMINOR.* ([0-9]+).*" "\\1"
+    METIS_VERSION_SUBMINOR "${_metis_subminor_string}"
+    )
+  SET(METIS_VERSION
+    "${METIS_VERSION_MAJOR}.${METIS_VERSION_MINOR}.${METIS_VERSION_SUBMINOR}"
+    )
 
   MARK_AS_ADVANCED(METIS_DIR)
 ELSE()
index 06e031198a2c8214f0c1ad1530ff966a1d466f5a..173da3893a47c703eb12405735586ce89fa7fa8c 100644 (file)
 #   P4EST_LIBRARIES
 #   P4EST_INCLUDE_DIRS
 #   P4EST_WITH_MPI
+#   P4EST_VERSION
+#   P4EST_VERSION_MAJOR
+#   P4EST_VERSION_MINOR
+#   P4EST_VERSION_SUBMINOR
+#   P4EST_VERSION_PATCH
 #
 
 INCLUDE(FindPackageHandleStandardArgs)
@@ -50,7 +55,7 @@ ENDIF()
 # given, take what we chose for p4est.
 #
 
-FIND_PATH(P4EST_INCLUDE_DIR p4est.h
+FIND_PATH(P4EST_INCLUDE_DIR p4est_config.h
   HINTS
     ${P4EST_DIR}
   PATH_SUFFIXES
@@ -121,6 +126,27 @@ IF(P4EST_FOUND)
     SET(P4EST_WITH_MPI TRUE)
   ENDIF()
 
+  #
+  # Extract version numbers:
+  #
+  FILE(STRINGS "${P4EST_INCLUDE_DIR}/p4est_config.h" P4EST_VERSION
+    REGEX "#define P4EST_VERSION \"")
+  STRING(REGEX REPLACE "^.*P4EST_VERSION.*\"([0-9]+.*)\".*" "\\1"
+    P4EST_VERSION "${P4EST_VERSION}"
+    )
+  STRING(REGEX REPLACE
+    "^([0-9]+).*$" "\\1"
+    P4EST_VERSION_MAJOR "${P4EST_VERSION}")
+  STRING(REGEX REPLACE
+    "^[0-9]+\\.([0-9]+).*$" "\\1"
+    P4EST_VERSION_MINOR "${P4EST_VERSION}")
+  STRING(REGEX REPLACE
+    "^[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1"
+    P4EST_VERSION_SUBMINOR "${P4EST_VERSION}")
+  STRING(REGEX REPLACE
+    "^[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1"
+    P4EST_VERSION_PATCH "${P4EST_VERSION}")
+
   MARK_AS_ADVANCED(P4EST_DIR)
 ELSE()
   SET(P4EST_DIR "" CACHE PATH
index 119fa42026a9d27e7e6b43d3ad35766239990ab4..1b2bce50497884b9d14c3dc6bf266183a4ab99cf 100644 (file)
@@ -199,7 +199,9 @@ IF(PETSC_FOUND)
     PETSC_VERSION_PATCH "${PETSC_VERSION_PATCH_STRING}"
     )
 
-  SET(PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}")
+  SET(PETSC_VERSION
+    "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.${PETSC_VERSION_PATCH}"
+    )
 
   MARK_AS_ADVANCED(PETSC_ARCH PETSC_DIR)
 ELSE()
index 4cd616dbaee956bba9a5d4d2b7b7dc7158422f6c..96a6a539b36f3305282de73209bada6e94086ff2 100644 (file)
@@ -41,7 +41,7 @@ FIND_LIBRARY(SCALAPACK_LIBRARY NAMES scalapack
 # SCALAPACK needs LAPACK and BLAS as dependency, search for them with the help
 # of the LAPACK find module:
 #
-FIND_PACKAGE(LAPACK)
+FIND_PACKAGE(DEALII_LAPACK)
 
 #
 # Well, depending on the version of scalapack and the distribution it might
index ddb706d05b4b47998254d9f9d144585a5b7d258c..9de3500f453cf9b2ae9dd32666458082ecc809bf 100644 (file)
@@ -121,7 +121,9 @@ IF(SLEPC_FOUND)
     SLEPC_VERSION_PATCH "${SLEPC_VERSION_PATCH_STRING}"
     )
 
-  SET(SLEPC_VERSION "${SLEPC_VERSION_MAJOR}.${SLEPC_VERSION_MINOR}.${SLEPC_VERSION_SUBMINOR}")
+  SET(SLEPC_VERSION
+    "${SLEPC_VERSION_MAJOR}.${SLEPC_VERSION_MINOR}.${SLEPC_VERSION_SUBMINOR}.${SLEPC_VERSION_PATCH}"
+    )
 
   MARK_AS_ADVANCED(SLEPC_DIR)
 ELSE()
index f5f8d2240df28728684876897210e93ed334ed34..b347b32ccf7cb9304d2b366a52ede902ffa69f0d 100644 (file)
 #
 # This module exports:
 #
-#   TRILINOS_DIR (cached)
+#   TRILINOS_DIR
 #   TRILINOS_INCLUDE_DIRS
 #   TRILINOS_LIBRARIES
+#   TRILINOS_VERSION
 #   TRILINOS_VERSION_MAJOR
 #   TRILINOS_VERSION_MINOR
 #   TRILINOS_VERSION_SUBMINOR
 #   TRILINOS_WITH_MPI
+#   TRILINOS_SUPPORTS_CPP11
+#   TRILINOS_HAS_C99_TR1_WORKAROUND
 #
 
 INCLUDE(FindPackageHandleStandardArgs)
@@ -33,13 +36,13 @@ INCLUDE(FindPackageHandleStandardArgs)
 SET_IF_EMPTY(TRILINOS_DIR "$ENV{TRILINOS_DIR}")
 
 #
-# Include the trilinos package configuration:
+# Do not include TrilinosConfig.cmake directly, it is just too big o_O
 #
-FIND_PACKAGE(TRILINOS_CONFIG
-  CONFIG QUIET
-  NAMES Trilinos TRILINOS
+# Just search for the file:
+#
+FIND_FILE(TRILINOS_CONFIG
+  NAMES TrilinosConfig.cmake trilinos-config.cmake
   HINTS
-    ${TRILINOS_DIR}/lib/cmake/Trilinos
     ${TRILINOS_DIR}
   PATH_SUFFIXES
     lib64/cmake/Trilinos
@@ -50,7 +53,72 @@ FIND_PACKAGE(TRILINOS_CONFIG
   NO_SYSTEM_ENVIRONMENT_PATH
   )
 
-SET(TRILINOS_INCLUDE_DIRS ${Trilinos_INCLUDE_DIRS})
+IF(NOT "${TRILINOS_CONFIG}" STREQUAL "${TRILINOS_CONFIG_SAVED}")
+  SET(_new_trilinos_config TRUE)
+ENDIF()
+SET(TRILINOS_CONFIG_SAVED "${TRILINOS_CONFIG}" CACHE INTERNAL "" FORCE)
+
+
+IF(NOT TRILINOS_CONFIG MATCHES "-NOTFOUND")
+
+  SET(_filtered_trilinos_config
+    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TrilinosConfig.cmake"
+    )
+
+  IF(_new_trilinos_config)
+    GET_FILENAME_COMPONENT(_trilinos_path "${TRILINOS_CONFIG}" PATH)
+    FILE(WRITE ${_filtered_trilinos_config} "SET(_cmake_current_list_dir ${_trilinos_path})\n")
+
+    #
+    # Only pick up every line that starts with "^SET("...
+    #
+    FILE(STRINGS "${TRILINOS_CONFIG}" _trilinos_config_filtered REGEX "^SET")
+
+    FOREACH(_line ${_trilinos_config_filtered})
+      STRING(REPLACE "CMAKE_CURRENT_LIST_DIR" "_cmake_current_list_dir"
+        _line "${_line}"
+        )
+      FILE(APPEND ${_filtered_trilinos_config} "${_line}\n")
+    ENDFOREACH()
+  ENDIF()
+
+  #
+  # ... and include only that:
+  #
+  INCLUDE(${_filtered_trilinos_config})
+
+  SET(TRILINOS_CONFIG_FOUND TRUE)
+ENDIF()
+
+
+#
+# Look for the one include file that we'll query for further information:
+#
+IF(_new_trilinos_config)
+  UNSET(EPETRA_CONFIG_H CACHE)
+ENDIF()
+FIND_FILE(EPETRA_CONFIG_H Epetra_config.h
+  HINTS ${Trilinos_INCLUDE_DIRS}
+  NO_DEFAULT_PATH
+  NO_CMAKE_ENVIRONMENT_PATH
+  NO_CMAKE_PATH
+  NO_SYSTEM_ENVIRONMENT_PATH
+  NO_CMAKE_SYSTEM_PATH
+  NO_CMAKE_FIND_ROOT_PATH
+  )
+IF(EPETRA_CONFIG_H MATCHES "-NOTFOUND")
+  SET(TRILINOS_CONFIG_FOUND FALSE)
+ELSE()
+  SET(TRILINOS_INCLUDE_DIRS ${Trilinos_INCLUDE_DIRS})
+  #
+  # *Boy* Sanitize the include paths given by TrilinosConfig.cmake...
+  #
+  STRING(REGEX REPLACE
+    "(lib64|lib)\\/cmake\\/Trilinos\\/\\.\\.\\/\\.\\.\\/\\.\\.\\/" ""
+    TRILINOS_INCLUDE_DIRS "${TRILINOS_INCLUDE_DIRS}"
+    )
+ENDIF()
+
 
 #
 # We'd like to have the full library names but the Trilinos package only
@@ -58,6 +126,10 @@ SET(TRILINOS_INCLUDE_DIRS ${Trilinos_INCLUDE_DIRS})
 # So we check again for every lib and store the full path:
 #
 FOREACH(_library ${Trilinos_LIBRARIES})
+  IF(_new_trilinos_config)
+    UNSET(TRILINOS_LIBRARY_${_library} CACHE)
+  ENDIF()
+
   FIND_LIBRARY(TRILINOS_LIBRARY_${_library}
     NAMES ${_library}
     HINTS ${Trilinos_LIBRARY_DIRS}
@@ -69,13 +141,11 @@ FOREACH(_library ${Trilinos_LIBRARIES})
     NO_CMAKE_FIND_ROOT_PATH
     )
 
-  LIST(APPEND TRILINOS_LIBRARIES ${TRILINOS_LIBRARY_${_library}})
-
-  #
-  # Remove the variables from the cache, so that updating TRILINOS_DIR will
-  # find the new libraries..
-  #
-  UNSET(TRILINOS_LIBRARY_${_library} CACHE)
+  IF(TRILINOS_LIBRARY_${_library} MATCHES "-NOTFOUND")
+    SET(TRILINOS_CONFIG_FOUND FALSE)
+  ELSE()
+    LIST(APPEND TRILINOS_LIBRARIES ${TRILINOS_LIBRARY_${_library}})
+  ENDIF()
 ENDFOREACH()
 
 #
@@ -96,8 +166,10 @@ MARK_AS_ADVANCED(TRILINOS_CONFIG_DIR)
 
 IF(TRILINOS_FOUND)
   #
-  # Extract the major and minor version numbers:
+  # Extract version numbers:
   #
+  SET(TRILINOS_VERSION "${Trilinos_VERSION}")
+
   STRING(REGEX REPLACE
     "^([0-9]+).*$" "\\1"
     TRILINOS_VERSION_MAJOR "${Trilinos_VERSION}")
@@ -113,15 +185,6 @@ IF(TRILINOS_FOUND)
   #
   # Determine whether Trilinos was configured with MPI and 64bit indices:
   #
-  FIND_FILE(EPETRA_CONFIG_H Epetra_config.h
-    HINTS ${TRILINOS_INCLUDE_DIRS}
-    NO_DEFAULT_PATH
-    NO_CMAKE_ENVIRONMENT_PATH
-    NO_CMAKE_PATH
-    NO_SYSTEM_ENVIRONMENT_PATH
-    NO_CMAKE_SYSTEM_PATH
-    NO_CMAKE_FIND_ROOT_PATH
-    )
   FILE(STRINGS "${EPETRA_CONFIG_H}" EPETRA_MPI_STRING
     REGEX "#define HAVE_MPI")
   IF("${EPETRA_MPI_STRING}" STREQUAL "")
@@ -144,10 +207,46 @@ IF(TRILINOS_FOUND)
     SET(TRILINOS_WITH_NO_64BITS_INDICES FALSE)
   ENDIF()
 
-  UNSET(EPETRA_CONFIG_H CACHE)
+  #
+  # Some versions of Sacado_cmath.hpp do things that aren't compatible
+  # with the -std=c++0x flag of GCC, see deal.II FAQ.
+  # Test whether that is indeed the case:
+  #
+  IF(_new_trilinos_config)
+    UNSET(TRILINOS_SUPPORTS_CPP11 CACHE)
+    UNSET(TRILINOS_HAS_C99_TR1_WORKAROUND CACHE)
+  ENDIF()
+
+  LIST(APPEND CMAKE_REQUIRED_INCLUDES ${TRILINOS_INCLUDE_DIRS})
+  PUSH_TEST_FLAG("${DEAL_II_CXX11_FLAG}")
+
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    #include <Sacado_cmath.hpp>
+    int main(){ return 0; }
+    "
+    TRILINOS_SUPPORTS_CPP11
+    )
+
+  #
+  # Try whether exporting HAS_C99_TR1_CMATH helps:
+  #
+  PUSH_TEST_FLAG("-DHAS_C99_TR1_CMATH")
+  CHECK_CXX_SOURCE_COMPILES(
+    "
+    #include <Sacado_cmath.hpp>
+    int main(){ return 0; }
+    "
+    TRILINOS_HAS_C99_TR1_WORKAROUND
+    )
+
+  RESET_CMAKE_REQUIRED()
+
 
   MARK_AS_ADVANCED(TRILINOS_DIR)
+
 ELSE()
+
   SET(TRILINOS_DIR "" CACHE PATH
     "An optional hint to a Trilinos installation"
     )
index 378b68cb565078cc8d15a9f8aa125414bada7eb4..746fdf0143ad06fa714bd52c4959a4d3a556b19a 100644 (file)
@@ -36,7 +36,7 @@ ENDFOREACH()
 # TODO: There might be an external dependency for metis, ignore this for
 # now.
 #
-FIND_PACKAGE(LAPACK)
+FIND_PACKAGE(DEALII_LAPACK)
 FIND_PACKAGE(METIS)
 
 #
index e8667e17c112c9ed1fe5c66061a79c5294002e0a..c2e04fe20dd5c0cc5913c5f17187c8d2a94adb6c 100644 (file)
@@ -39,7 +39,6 @@
 #     DEAL_II_PREFER_STATIC_LIBS
 #     DEAL_II_STATIC_EXECUTABLE
 #     CMAKE_INSTALL_RPATH_USE_LINK_PATH
-#     CMAKE_C_FLAGS                     *)
 #     CMAKE_CXX_FLAGS                   *)
 #     DEAL_II_LINKER_FLAGS              *)
 #     DEAL_II_CXX_FLAGS_DEBUG
@@ -48,7 +47,7 @@
 #     DEAL_II_LINKER_FLAGS_RELEASE
 #     DEAL_II_WITH_64BIT_INDICES
 #
-# *)  May also be set via environment variable (CFLAGS, CXXFLAGS, LDFLAGS)
+# *)  May also be set via environment variable (CXXFLAGS, LDFLAGS)
 #     (a nonempty cached variable has precedence and will not be
 #     overwritten by environment)
 #
@@ -142,7 +141,7 @@ ENDIF()
 
 
 OPTION(DEAL_II_ALLOW_PLATFORM_INTROSPECTION
-  "Allow platform introspection for CPU command set, SSE and AVX"
+  "Allow platform introspection for CPU command sets, SSE and AVX"
   ON
   )
 MARK_AS_ADVANCED(DEAL_II_ALLOW_PLATFORM_INTROSPECTION)
@@ -201,7 +200,6 @@ OPTION(DEAL_II_WITH_64BIT_INDICES
   )
 
 
-
 #
 # Tell the user very prominently, that we're doing things differently w.r.t
 # CMAKE_(C|CXX)_FLAGS_(DEBUG|RELEASE)
@@ -213,6 +211,7 @@ FOREACH(_flag
   SHARED_LINKER_FLAGS_DEBUG
   )
   IF(NOT "${CMAKE_${_flag}}" STREQUAL "")
+    UNSET(${CMAKE_${_flag}} CACHE)
     MESSAGE(FATAL_ERROR
       "\nThe deal.II cmake build system does not use CMAKE_${_flag}.\n"
       "Use DEAL_II_${_flag}, instead!\n\n"
@@ -220,6 +219,7 @@ FOREACH(_flag
   ENDIF()
 ENDFOREACH()
 
+
 #
 # Hide all unused compiler flag variables:
 #
@@ -246,6 +246,7 @@ FOREACH(_flag
   SET(${_flag} "" CACHE INTERNAL "" FORCE)
 ENDFOREACH()
 
+
 #
 # Set cached compiler flags to an empty string:
 #
index 4815abf65fafa4af54fa8ac1da7d89f2afa25a42..f82147f9e816f215f3a142bb4d2d2531bb573606 100644 (file)
 #
 # Check the user provided CXX flags:
 #
+
 MESSAGE(STATUS "")
 IF(NOT "${CMAKE_CXX_FLAGS_SAVED}" STREQUAL "${DEAL_II_CXX_FLAGS_SAVED}")
+  # Rerun this test if cxx flags changed:
   UNSET(DEAL_II_HAVE_USABLE_CXX_FLAGS CACHE)
 ENDIF()
 SET(DEAL_II_CXX_FLAGS_SAVED "${CMAKE_CXX_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
 
-SET(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS_SAVED}")
+# Initialize all CMAKE_REQUIRED_* variables a this point:
+RESET_CMAKE_REQUIRED()
+
 CHECK_CXX_SOURCE_COMPILES(
   "int main(){ return 0; }"
   DEAL_II_HAVE_USABLE_CXX_FLAGS)
-SET(CMAKE_REQUIRED_FLAGS "")
 
 IF(NOT DEAL_II_HAVE_USABLE_CXX_FLAGS)
   UNSET(DEAL_II_HAVE_USABLE_CXX_FLAGS CACHE)
   MESSAGE(FATAL_ERROR "\n"
-    "Configuration error: Cannot compile with the specified CXX flags: "
+    "Configuration error: Cannot compile with the user supplied CXX flags:\n"
     "${CMAKE_CXX_FLAGS_SAVED}\n"
     )
 ENDIF()
index 63bf98e31a7f024c6096f90b16289caacb1c8761..14884e265d70bcf72adbd2a9e4b657b0d7a20d36 100644 (file)
@@ -73,6 +73,12 @@ ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-Wswitch")
 #
 ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-Wno-unused-local-typedefs")
 
+#
+# Disable Wlong-long that will trigger a lot of warnings when compiling
+# with disabled C++11 support:
+#
+ENABLE_IF_SUPPORTED(CMAKE_CXX_FLAGS "-Wno-long-long")
+
 #
 # Disable deprecation warnings
 #
@@ -148,7 +154,7 @@ IF (CMAKE_BUILD_TYPE MATCHES "Debug")
   #
   # If -Og is not available, fall back to -O0:
   #
-  IF(NOT DEAL_II_HAVE_FLAG_O0)
+  IF(NOT DEAL_II_HAVE_FLAG_Og)
     ADD_FLAGS(DEAL_II_CXX_FLAGS_DEBUG "-O0")
   ENDIF()
 
index e08b7a382a9398f0b944535cf867aaee9cfdb2df..ed67d96ad3c6c744f47e41360256f6e088522d2f 100644 (file)
@@ -104,11 +104,24 @@ IF (CMAKE_BUILD_TYPE MATCHES "Release")
   #
   # General optimization flags:
   #
-  ADD_FLAGS(DEAL_II_CXX_FLAGS_RELEASE "-O1")
+
+  IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "13.0" )
+    ADD_FLAGS(DEAL_II_CXX_FLAGS_RELEASE "-O2")
+  ELSE()
+    #
+    # Disable aggressive optimization for intel-13* compilers, until we
+    # resolve a lot of funny miscompilations...
+    #
+    # - Maier, 2013
+    #
+    ADD_FLAGS(DEAL_II_CXX_FLAGS_RELEASE "-O1")
+  ENDIF()
+
   ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS_RELEASE "-ip")
 
   ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS_RELEASE "-funroll-loops")
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS_RELEASE "-ansi-alias") # equiv. -fstrict-aliasing
+  # equivalent to -fno-strict-aliasing:
+  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS_RELEASE "-no-ansi-alias")
 ENDIF()
 
 
index 931bf618f37b6ec91cff891645806c1c5b78b99e..a07c54f4658caa48dbab8ebf9d386a403a173a76 100644 (file)
@@ -51,8 +51,6 @@
 #     DEAL_II_PROJECT_CONFIG_RELDIR   *)
 #
 #     DEAL_II_BUILD_TYPES
-#     DEAL_II_WITH_BUNDLED_DIRECTORY
-#     DEAL_II_WITH_DOC_DIRECTORY
 #
 # *)  Can be overwritten by the command line via -D<...>
 #
@@ -112,7 +110,7 @@ IF(DEAL_II_COMPONENT_COMPAT_FILES)
       (NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") )
     #
     # Ensure that in case of an out of source build BINARY_DIR/include !=
-    # INSTALL_PREFIX/include us always true. Otherwise stale headers might
+    # INSTALL_PREFIX/include is always true. Otherwise stale headers might
     # get included resulting in a failing build.
     #
     SET_IF_EMPTY(DEAL_II_INCLUDE_RELDIR "include/install")
@@ -146,49 +144,3 @@ IF(CMAKE_BUILD_TYPE MATCHES "Release")
   LIST(APPEND DEAL_II_BUILD_TYPES "RELEASE")
 ENDIF()
 
-
-########################################################################
-#                                                                      #
-#   Cleanup and setup that has to happen after the call to PROJECT():  #
-#                                                                      #
-########################################################################
-
-#
-# Cleanup some files used for storing the names of all object targets that
-# will be bundled to the deal.II library.
-# (Right now, i.e. cmake 2.8.8, this is the only reliable way to get
-# information into a global scope...)
-#
-FOREACH(_build ${DEAL_II_BUILD_TYPES})
-  STRING(TOLOWER "${_build}" _build_lowercase)
-  FILE(REMOVE
-    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_${_build_lowercase}
-    )
-ENDFOREACH()
-
-IF(DEAL_II_PREFER_STATIC_LIBS)
-  #
-  # Invert the search order for libraries when DEAL_II_PREFER_STATIC_LIBS
-  # is set. This will prefer static archives instead of shared libraries:
-  #
-  # TODO: Does this work on a Windows or CYGWIN target?
-  LIST(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES)
-ENDIF()
-
-#
-# Cross compilation stuff:
-#
-IF(CMAKE_CROSSCOMPILING)
-  #
-  # Disable platform introspection when cross compiling
-  #
-  SET(DEAL_II_ALLOW_PLATFORM_INTROSPECTION OFF CACHE BOOL "" FORCE)
-
-  #
-  # Import native expand_instantiations for use in cross compilation:
-  #
-  SET(DEAL_II_NATIVE "DEAL_II_NATIVE-NOTFOUND" CACHE FILEPATH
-    "A pointer to a native deal.Ii build directory"
-    )
-  INCLUDE(${DEAL_II_NATIVE}/cmake/scripts/importExecutables.cmake)
-ENDIF()
index e2f919a30944e71da64ecfa2648e472807f629c5..a651931f347fa18cf161cb2e85d7ef00fa2fa6a2 100644 (file)
@@ -60,6 +60,19 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
   ENDIF()
 ENDFOREACH()
 
+#
+# Cleanup some files used for storing the names of all object targets that
+# will be bundled to the deal.II library.
+# (Right now, i.e. cmake 2.8.8, this is the only reliable way to get
+# information into a global scope...)
+#
+FOREACH(_build ${DEAL_II_BUILD_TYPES})
+  STRING(TOLOWER "${_build}" _build_lowercase)
+  FILE(REMOVE
+    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_${_build_lowercase}
+    )
+ENDFOREACH()
+
 
 ########################################################################
 #                                                                      #
@@ -159,9 +172,7 @@ FOREACH(_var ${_variables})
     LIST(APPEND _components "${_var}")
   ELSEIF(_var MATCHES "(MPI_CXX_COMPILER|MPI_CXX_COMPILE_FLAGS|MPI_CXX_LINK_FLAGS)")
     LIST(APPEND _features_config ${_var})
-  ELSEIF(_var MATCHES "(LIBRARIES|INCLUDE_PATH|INCLUDE_DIRS|LINKER_FLAGS)"
-         # Avoid a lot of Trilinos variables:
-         AND (NOT _var MATCHES "_TPL_|_MPI_") )
+  ELSEIF(_var MATCHES "(LIBRARIES|INCLUDE_PATH|INCLUDE_DIRS|LINKER_FLAGS)")
     LIST(APPEND _features_config ${_var})
   ENDIF()
 ENDFOREACH()
@@ -173,6 +184,20 @@ FOREACH(_var ${_features})
     IF(FEATURE_${_feature}_EXTERNAL_CONFIGURED)
       _both("#        ${_var} set up with external dependencies\n")
 
+      #
+      # Print out version number:
+      #
+      IF(DEFINED ${_feature}_VERSION)
+        _detailed("#            ${_feature}_VERSION = ${${_feature}_VERSION}\n")
+      ENDIF()
+
+      #
+      # Print out ${_feature}_DIR:
+      #
+      IF(DEFINED ${_feature}_DIR)
+        _detailed("#            ${_feature}_DIR = ${${_feature}_DIR}\n")
+      ENDIF()
+
       #
       # Print the feature configuration:
       #
diff --git a/deal.II/cmake/setup_post_project_call.cmake b/deal.II/cmake/setup_post_project_call.cmake
new file mode 100644 (file)
index 0000000..690acf5
--- /dev/null
@@ -0,0 +1,53 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 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.
+##
+## ---------------------------------------------------------------------
+
+
+########################################################################
+#                                                                      #
+#         Setup that has to happen after the call to PROJECT():        #
+#                                                                      #
+########################################################################
+
+#
+# Library search order:
+#
+IF(DEAL_II_PREFER_STATIC_LIBS)
+  #
+  # Invert the search order for libraries when DEAL_II_PREFER_STATIC_LIBS
+  # is set. This will prefer static archives instead of shared libraries:
+  #
+  # TODO: Does this work on a Windows or CYGWIN target?
+  LIST(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES)
+ENDIF()
+
+
+#
+# Cross compilation stuff:
+#
+IF(CMAKE_CROSSCOMPILING)
+  #
+  # Disable platform introspection when cross compiling
+  #
+  SET(DEAL_II_ALLOW_PLATFORM_INTROSPECTION OFF CACHE BOOL "" FORCE)
+
+  #
+  # Import native expand_instantiations for use in cross compilation:
+  #
+  SET(DEAL_II_NATIVE "DEAL_II_NATIVE-NOTFOUND" CACHE FILEPATH
+    "A pointer to a native deal.Ii build directory"
+    )
+  INCLUDE(${DEAL_II_NATIVE}/cmake/scripts/importExecutables.cmake)
+ENDIF()
index 77f4d27d0fef389d4ee7444c1abc50664838fbaf..ef00b074b1e0133546a4ecb163d187c52cbd1c4d 100644 (file)
@@ -6,7 +6,7 @@ Use: Convert an ABAQUS .inp file to an AVS UCD file.
 
 Author: Jean-Paul Pelteret
         jppelteret.uct@gmail.com
-        modified by: Timo Heister, heister@math.tamu.edu
+        modified by: Timo Heister, heister@clemson.edu
 ===================================================
 
 
index eeb706492875cbfde6809c350db429d41d02564e..8e63586481bf3d8afa700224b58dc3a5a0dc038c 100644 (file)
 ## ---------------------------------------------------------------------
 
 
-#
-# Required packages for the document generation:
-#
-FIND_PACKAGE(Perl)
-FIND_PACKAGE(Doxygen)
 
 
 #
@@ -27,6 +22,12 @@ FIND_PACKAGE(Doxygen)
 #
 IF(DEAL_II_COMPONENT_DOCUMENTATION)
 
+  #
+  # Required packages for the document generation:
+  #
+  FIND_PACKAGE(Perl)
+  FIND_PACKAGE(Doxygen)
+
   #
   # Do we have all necessary dependencies?
   #
index 1af8db86d0892dc3fe541b15ba3a879c23a41709..494df11f7316b27c75d908f81a41cef7a26bf3d1 100644 (file)
@@ -30,9 +30,9 @@
       </li>
 
       <li>
-       <a href="http://www.math.tamu.edu/~heister"
+       <a href="http://www.math.clemson.edu/~heister"
           target="_top">Timo Heister</a>,
-       Texas A&amp;M University, TX, USA
+       Clemson University, SC, USA
       </li>
 
       <li>
        Support for arbitrary nodes in FE_Q. Matrix-free
        framework. step-37 and step-48 tutorial programs.
 
+      <li><em>Oleh Krehel:</em>
+       Many documentation fixes.
+
       <li><em>Martin Kronbichler:</em>
        step-22, step-31, step-32, step-37, step-48, interfaces to
        Trilinos, significant parts of ConstraintMatrix, matrix-free
index 6f4ad89247bf0bfa16ed9fafe4c4a39b6f785e03..aeb340ced39091b0807b00c8cd5709cdedbe2592 100644 (file)
 # BLA_VENDOR will also be recognized by FindLAPACK.cmake.
 #
 # If your BLAS/LAPACK installation resides at a non system location, specify
-# a hint with CMAKE_PREFIX_PATH.
+# a hint with LAPACK_DIR and BLAS_DIR, or CMAKE_PREFIX_PATH:
+#
+# SET(LAPACK_DIR "..." CACHE PATH
+#   "The preferred installation prefix for searching for LAPACK"
+#   )
+#
+# SET(BLAS_DIR "..." CACHE PATH
+#   "The preferred installation prefix for searching for BLAS"
+#   )
 #
 #
 # Manual setup:
index cacc2e4bbe0126b59a68d3154603302eb8c9a212..903af06bfa0e455ab933ad7e29a4c699c87f89b0 100644 (file)
@@ -19,7 +19,7 @@
     <p>
       This page provides details about the CMake build system. Files
       processed by the top level <code>CMakeLists.txt</code> script are
-      listed in the TOC in cronological order.
+      listed in the TOC in chronological order.
     </p>
 
     <p>
       )
       </pre>
       CMake operates almost always with variables in global state. To guard
-      against accidential overwrite of variables the following naming
+      against accidental overwrite of variables the following naming
       conventions must be followed at all times:
       <ul>
         <li>
         <pre>
 
     CHECK_CXX_SOURCE_COMPILES(source variable)
-      - Checks whether it is possible to compile _and_ link the code snipet
-        &lt;source&gt;. If succesful, variable is set to 1.
+      - Checks whether it is possible to compile _and_ link the code snippet
+        &lt;source&gt;. If successful, variable is set to 1.
 
     CHECK_CXX_SOURCE_RUNS(source variable)
-      - variable is set to 1 if &lt;source&gt; coulde be succesfully compiled and
+      - variable is set to 1 if &lt;source&gt; could be successfully compiled and
         linked and the resulting program ran and exited without error.
         Avoid this macro outside of a DEAL_II_ALLOW_PLATFORM_INTROSPECTION
         guard. A sensible fallback should be provided if the check cannot
     POP_TEST_FLAG()
          </pre>
 
-       <li> Libraries necessary for linkage can be set in the list variable
-         <code>CMAKE_REQUIRED_LIBRARIES</code>. It is best two hard set
-         this variable to a specific value and later on cleaning it,
-         instead of appending/removing:
+        <li> Necessary include directories and libraries necessary for
+        linkage can be set in the list variables
+        <code>CMAKE_REQUIRED_INCLUDES</code> and
+        <code>CMAKE_REQUIRED_LIBRARIES</code>. It is best to append these
+        lists and later on reset <code>CMAKE_REQUIRED_*</code> (including
+        <code>CMAKE_REQUIRED_FLAGS</code>) to their default values:
          <pre>
 
-    SET(CMAKE_REQUIRED_LIBRARIES &lt;a list of libraries&gt;
+    LIST(APPEND CMAKE_REQUIRED_INCLUDES &lt;a list of includes&gt;)
+    LIST(APPEND CMAKE_REQUIRED_LIBRARIES &lt;a list of libraries&gt;)
     CHECK_CXX_SOURCE_COMPILES(...)
-    SET(CMAKE_REQUIRED_LIBRARIES)
+    RESET_CMAKE_REQUIRED()
          </pre>
       </ul>
     </p>
 
     FEATURE_&lt;FEATURE&gt;_DEPENDS              (a variable)
       - a variable which contains an optional list of other features
-        this feature depends on (and which have to be enbled for this feature
+        this feature depends on (and which have to be enabled for this feature
         to work.) The features must be given with the full option toggle:
         DEAL_II_WITH_[...]
 
     # Glob for all header files associated with the object target:
     # As this list is only for cosmetic reasons, so that associated header
     # files show up in IDEs, we don't manage an explicit list (with the
-    # tradeoff to have to run "make rebuild_cache" when a new header file
+    # trade-off to have to run "make rebuild_cache" when a new header file
     # emerges...)
     #
     FILE(GLOB _header
     <hr>
 
     <address>
-      <a href="mail.html" target="body">The deal.II Group</a>
+      <a href="../mail.html" target="body">The deal.II Group</a>
       $Date$
     </address>
   </body>
index 05fe95d6e9b9c9627e625eb85589c9af404813dc..8139fdc11090a2a07426a1dc1314f99f3fc441b2 100644 (file)
       </pre>
       switches off support for the METIS library that may have been
       automatically detected during the first invocation of
-      <code>cmake</code> and enables support for Trilinos by enablind
+      <code>cmake</code> and enables support for Trilinos by enabling
       <code>DEAL_II_WITH_TRILINOS</code> and setting
       <code>TRILINOS_DIR</code>.
     </p>
            <pre>
 
     ARPACK_DIR,
+    BOOST_DIR,
     HDF5_DIR,
+    LAPACK_DIR (and BLAS_DIR),
     METIS_DIR,
     MUMPS_DIR (and SCALAPACK_DIR, BLACS_DIR),
     P4EST_DIR (and SC_DIR),
       Alternatively, cached variables set by the
       <code>Find&lt;Module&gt;</code> mechanism may be set,
       hinted or overwritten directly (variable names are highly
-      dependend on the actual library). You can get a list via
+      dependent on the actual library). You can get a list via
       <pre>
 
     make edit_cache
       <ul>
         <li>
           The compiler <i>must</i> be specified at the very first
-          invokation of <code>cmake</code>.
+          invocation of <code>cmake</code>.
         <li>
           A working CXX compiler is needed. It is optional to provide a C
           or Fortran compiler.
     <hr>
 
     <address>
-      <a href="mail.html" target="body">The deal.II Group</a>
+      <a href="../mail.html" target="body">The deal.II Group</a>
       $Date$
     </address>
   </body>
index 5ebc8bc15fbb9593c94f3191416842c15e88bb7d..96f699ef4618821ebb4f21718b93b78287936f70 100644 (file)
     <hr>
 
     <address>
-      <a href="mail.html" target="body">The deal.II Group</a>
+      <a href="../mail.html" target="body">The deal.II Group</a>
       $Date$
     </address>
   </body>
index 2db340d6a20dfc8d35f4c1828ed4ede4bc4aab95..ff8d4f55d199dc01cd7ef8ad84010a09dcf09e77 100644 (file)
@@ -18,7 +18,7 @@
 
   <p>deal.II has an extensive reference documentation generated
   by <a href="http://www.doxygen.org">Doxygen</a>. One of the many
-  features of Doxygen is, that all class names, function noames and so
+  features of Doxygen is, that all class names, function names and so
   on are cross-linked in the documentation, and a single click
   suffices to jump to the documentation of an object.</p>
 
index ee4d340d9018b8cd43c70c365521ce6eadc034b8..07281a23168d3e46a1329da921f57cc6d13049a0 100644 (file)
@@ -5,7 +5,7 @@
     <title>Porting deal.II</title>
     <link href="../screen.css" rel="StyleSheet" media="screen">
     <meta name="author" content="the deal.II authors <authors@dealii.org>">
-    <meta name="copyright" content="Copyright (C) 2000, 2001, 2002, 2005, 2010, 2012 by the deal.II authors">
+    <meta name="copyright" content="Copyright (C) 2000, 2001, 2002, 2005, 2010, 2012, 2013 by the deal.II authors">
     <meta name="date" content="$Date$">
     <meta name="svn_id" content="$Id$">
     <meta name="keywords" content="deal.II porting">
@@ -23,7 +23,7 @@
 
       Consequently, there is a good chance that <acronym>deal.II</acronym>
       will run on a reasonably well behaved system besides the ones listed
-      in the <a href="readme.html" target="body">ReadMe</a>. Nevertheless,
+      in the <a href="../readme.html" target="body">ReadMe</a>. Nevertheless,
       there are cases where some adjustments are necessary.
     </p>
 
index a4b55424168cf465353f951935b605ce17535759..51ebce36d7a40e91181a8ea3cfc2f617f38326c4 100644 (file)
@@ -65,6 +65,7 @@
  * can solve now, there is no reason for the number of non-zero entries in a 
  * sparse matrix to go over four billions. Thus, we still use unsigned int
  * for, e.g., row_lengths in the object.
+ * </dd>
  *
- * 
+ * </dl>
  */
index a84c1a6612c4f582d5f39f3b7299e9627a4222db..a4acb8b8c6ce7e928c106809f69a11ddcdb2e6f1 100644 (file)
  * faces and edges. In this case, the boundary object associated with a particular
  * boundary indicator is also used to move the new center points of cells back
  * onto the manifold that the triangulation describes whenever a cell is refined.
+ *
+ * @note For parallel triangulations of type parallel::distributed::Triangulation,
+ * it is not enough to set boundary indicators only once at the beginning. See
+ * the long discussion on this topic in the class documentation of
+ * parallel::distributed::Triangulation .
  * </dd>
  *
  * @see @ref boundary "The module on boundaries"
  * to adding elements or setting them.  In some cases, not all processors may
  * be adding elements, for example if a processor does not own any cells when
  * using a very coarse (initial) mesh.  For this reason, compress() takes an
- * argument of type VectorOperation, which can be either ::add, or ::insert.
+ * argument of type VectorOperation, which can be either ::%add, or ::%insert.
  * This argument is required for vectors and matrices starting with the 7.3
  * release.
  *
  * is pointing the other direction. There are not very many places in
  * application programs where you need this information actually, but
  * a few places in the library make use of this. Note that in 2d, the
- * result is always @p true.
+ * result is always @p true. However, while every face in 2d is always
+ * in standard orientation, you can sometimes specify something to
+ * assume that this is not so; an example is the function
+ * DoFTools::make_periodicity_constraints().
  *
  * There are two other flags that describe the orientation of a face:
  * face_flip and face_rotation. Some documentation for these
@@ -1210,7 +1218,7 @@ Article{JK10,
  *      // in 3d
  *      for (cell=dof_handler.begin_active();
  *           cell!=dof_handler.end(); ++cell)
- *        for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++l)
+ *        for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
  *          if (cell->line(l)->at_boundary())
  *            {
  *               do something with this line
@@ -1266,7 +1274,7 @@ Article{JK10,
  *   @code
  *      for (cell=dof_handler.begin_active();
  *           cell!=dof_handler.end(); ++cell)
- *        for (unsigned int line=0; line<GeometryInfo<dim>::lines_per_cell; ++l)
+ *        for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
  *          if (cell->line(l)->at_boundary())
  *            {
  *              cell->line(l)->set_user_index(42);
index 91e95805d0469a08fcf5c6811df533646bb55465..59c2b3424c2aff6af11eba1eff436838cdd5c204 100644 (file)
  * 
  * @subsection Inst2p Provided instances
  *
- * Like with the classes in section Inst1, the instances provided in the
+ * Like with the classes in section @ref Inst1, the instances provided in the
  * library are often listed in the documentation of that class in a form
  * similar to this:
  @verbatim
index 9c24a2f7c5a898b30df0b5a4b55f69737f4eb8b2..2edcd2d5a8b85dfc5698642cd49ba917353164cf 100644 (file)
   \right)_\Omega,
 @f}
  * where $\varepsilon(\mathbf u) = \frac 12 \left([\nabla\mathbf u] +
- * [\nabla\mathbf u]^2\right)$ is the symmetrized gradient.
+ * [\nabla\mathbf u]^T\right)$ is the symmetrized gradient.
  * In the second to last step, we used that the scalar product between
  * an arbitrary tensor $\nabla\mathbf u$ and a symmetric tensor
  * $\frac 12[\partial_i v_j + \partial_j v_i]$ equals the scalar product
index e17e334cbf8de4f38fbf9486f7c483a9365fb076..b57c0c62915c6d97aa0849bed18348f33b739a62 100644 (file)
@@ -1000,7 +1000,8 @@ PREDEFINED             = DOXYGEN=1 \
                         DEAL_II_WITH_ARPACK=1 \
                         DEAL_II_WITH_METIS=1 \
                         DEAL_II_WITH_MUMPS=1 \
-                        DEAL_II_WITH_P4EST=1
+                        DEAL_II_WITH_P4EST=1 \
+                        DEAL_II_WITH_MPI=1
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
 # this tag can be used to specify a list of macro names that should be expanded.
index ef6593db095393e34475394966e89ea09cc605d9..52a6c37202dc73133d54c6863ddb6717b3725ca6 100644 (file)
@@ -6,8 +6,8 @@
     <title>The deal.II Readme on interfacing to ARPACK</title>
     <link href="../screen.css" rel="StyleSheet">
     <meta name="author" content="the deal.II authors <authors @ dealii.org>"> 
-    <meta name="copyright" content="Copyright (C) 2010 by the deal.II authors">
-    <meta name="date" content="$Date: 2010-05-05 (Thu, 05 May 2010) $">
+    <meta name="copyright" content="Copyright (C) 2010, 2013 by the deal.II authors">
+    <meta name="date" content="$Date$">
     <meta name="svn_id" content="$Id: readme-arpack.html$">
     <meta name="keywords" content="deal.II"> 
   </head>                                                                      
 
     <hr>
     <address>
-      <a href="mail.html">The deal.II Group</a>
+      <a href="../mail.html">The deal.II Group</a>
        $Date$
     </address>
   </body>
index 6f26ade6677ca8f383ffebb6df90b4ee1a15babe..9459e54e4ee4cbd2e8d6838199e81e8934c04b3b 100644 (file)
@@ -7,7 +7,7 @@
     <link href="../screen.css" rel="StyleSheet">
     <meta name="author" content="the deal.II authors <authors @ dealii.org>">
     <meta name="copyright" content="Copyright (C) 2010, 2011, 2012, 2013 by the deal.II authors">
-    <meta name="date" content="$Date: 2010-05-05 (Thu, 05 May 2010) $">
+    <meta name="date" content="$Date$">
     <meta name="svn_id" content="$Id: readme-mumps.html$">
     <meta name="keywords" content="deal.II">
   </head>
 
     <hr>
     <address>
-      <a href="mail.html">The deal.II Group</a>
+      <a href="../mail.html">The deal.II Group</a>
        $Date$
     </address>
   </body>
index 735d088210ded1c3d6b5a528c55a603304581afd..67fea34c44e479f9483adaf071d486d9657417e5 100644 (file)
       line like
       <pre>
 
-    cmake -DP4EST_DIR=/path/to/installation -DDEAL_II_WITH_P4EST=ON -DDEAL_II_WITH_MPI=ON <...>
+    cmake -DP4EST_DIR=/path/to/installation/FAST -DDEAL_II_WITH_P4EST=ON -DDEAL_II_WITH_MPI=ON <...>
       </pre>
-      if the p4est library isn't picked up automatically. Obviously, you
+      if the p4est library isn't picked up automatically. Note the presence
+      of <code>/FAST</code>  at the end of the path necessary when using
+      the <code>./p4est-setup.sh</code> script to select the release
+      version of p4est. Obviously, you
       can also add additional flags to <code>cmake</code> as described in
       the general <a href="../readme.html">ReadMe file</a>.
     </p>
 
     <hr>
     <address>
-      <a href="mail.html">The deal.II Group</a>
+      <a href="../mail.html">The deal.II Group</a>
        $Date$
     </address>
   </body>
index 5470e7573f55659fa074875cda3a9101acdd7485..0073a3b4520a671f28f9dd41f3c15abcd1fd4c86 100644 (file)
           Wolfgang Bangerth &lt; bangerth@gmail.com &gt;
         </li>
         <li>
-          Timo Heister &lt; heister@math.tamu.edu &gt;
+          Timo Heister &lt; heister@clemson.edu &gt;
         </li>
         <li>
           Guido Kanschat &lt; dr.guido.kanschat@gmail.com &gt;
     </p>
 
 
+    <a name="license-text"></a>
     <h3>Full license text</h3>
 
     <pre>
index 66574112c150847152163e1ed394c1a6cf46bbc8..7e69fbb4bb7a441c75d8ecd89a1bdb08fae1a3ed 100644 (file)
@@ -77,7 +77,7 @@
         Wolfgang Bangerth &lt; bangerth@gmail.com &gt;
       </li>
       <li>
-        Timo Heister &lt; heister@math.tamu.edu &gt;
+        Timo Heister &lt; heister@clemson.edu &gt;
       </li>
       <li>
         Guido Kanschat &lt; dr.guido.kanschat@gmail.com &gt;
index 2bacdd45b24445e03fbd104add726836aa59382e..cd0b779b753666ca2c4bc229c265b0102a46333b 100644 (file)
@@ -144,9 +144,6 @@ documentation, etc</a>.
        New: There is now some support to include and use routines from the 
        <a href="http://www.cse.clrc.ac.uk/Activity/HSL" 
        target="_top">Harwell Subroutine Library</a>.
-       (See the <a href="../../readme.html#hsl" target="body">ReadMe</a>
-       file for more information on installation of HSL
-       subroutines.)
        <br>
        (WB 2001/01/30)
        </p>
@@ -156,9 +153,7 @@ documentation, etc</a>.
        existence of a Fortran 77 compiler, and sets its path, some
        compiler flags and the libraries to be linked in when mixing
        C++ and F77 in some variables in the file
-       <code>common/Make.global_options</code> (see also
-       <a href="../../development/makefiles.html" target="body">this
-       page</a>).
+       <code>common/Make.global_options</code>.
        <br>
        (WB 2000/12/30)
        </p>
@@ -602,9 +597,6 @@ documentation, etc</a>.
        <code class="class">SparseDirectMA27</code> and
        <code class="class">SparseDirectMA47</code>
        for the sparse direct solvers MA27 and MA47.
-       (See the <a href="../../readme.html#hsl" target="body">ReadMe</a>
-       file for more information on installation of HSL
-       subroutines.)
        <br>
        (WB 2001/01/30)
        </p>
index 6dc8e87c4b5ca48a570db43a0007a38994a32dac..df23b1594faca7d891e37760ddf40867465ddb47 100644 (file)
@@ -51,8 +51,7 @@ more naturally preserves consistency.
        <br>
        As a consequence, if your makefile makes any assumption on the
        location of deal.II include files or the name of the deal.II library
-       it will need to be changed. The <a
-       href="../../development/makefiles.html">sample Makefiles</a> have been
+       it will need to be changed. The sample Makefiles have been
        updated for this.
        <br>
        (WB 2010/10/25)
index 6d4ef48ce170e8721864f08f05b5c465ef2975f3..5e6decd05c3e6052232a6aed46d83c114426e1ab 100644 (file)
@@ -727,7 +727,7 @@ were not properly mapped. This is now fixed.
 
 <li> New: Restructured the internals of <code>PETScWrappers::Precondition*</code>
 to allow a PETSc PC object to exist without a solver. New: Use
-<code>Precondition*::vmult()</code> to apply the preconditioner once.
+<code>Precondition*::%vmult()</code> to apply the preconditioner once.
 Preconditioners now have a default constructor and an <code>initialize()</code>
 function and are no longer initialized in the solver call,
 but in the constructor or <code>initialize()</code>.
index e40b25cb1998bf667ed88baacc2afb63d100ab5b..52808bccd73f07cc0b25f7c98eddee825f88a54d 100644 (file)
@@ -224,7 +224,7 @@ that takes a std::vector<IndexSet> (same interface as in Trilinos).
 <br>
 (Timo Heister, 2013/02/19)
 
-<li> New: PETScWrappers::*Matrix::add(other, factor) to
+<li> New: PETScWrappers::*Matrix::%add(other, factor) to
 add a scaled other matrix to the current matrix.
 <br>
 (Jose Javier Munoz Criollo, 2013/02/19)
index 59758c96011b47449da81db96d77db49b10b166d..93d16b5ed883ce946a1b95168c766419a9a66a09 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @page changes_after_8_0 Changes after Version 8.0
+// * @page changes_after_8_0 Changes after Version 8.0
 
 <p>
 This is the list of changes made after the release of
@@ -24,7 +24,13 @@ inconvenience this causes.
 </p>
 
 <ol>
-
+  <li>
+  Removed: The member function face_to_equivalent_cell_index() in
+  FiniteElementData has been removed. It had been deprecated a while
+  back already. Please use FiniteElement::face_to_cell_index() instead.
+  <br>
+  (Wolfgang Bangerth, 2013/08/09)
+  </li>
 </ol>
 
 
@@ -35,6 +41,12 @@ inconvenience this causes.
 
 
 <ol>
+  <li>
+  New: It is now possible to compile and link deal.II against LLVM's libcxx. For
+  this, a few issues with C++ standard violations are resolved.
+  <br>
+  (Matthias Maier, 2013/08/09)
+  </li>
 </ol>
 
 
@@ -44,7 +56,145 @@ inconvenience this causes.
 <h3>Specific improvements</h3>
 
 <ol>
-
+  <li>
+  Fixed: Under some circumstances (see http://code.google.com/p/dealii/issues/detail?id=82)
+  the DoFTools::make_periodicity_constraints() function could create cycles in
+  the ConstraintMatrix object. This is now fixed.
+  <br>
+  (David Emerson, Wolfgang Bangerth, 2013/08/16)
+  </li>
+
+  <li>
+  New: There is now a function ConstraintMatrix::are_identity_constrained().
+  <br>
+  (Wolfgang Bangerth, 2013/08/16)
+  </li>
+
+  <li>
+  New: TableHandler::write_text() now also supports output in
+  org-mode (http://orgmode.org/) format via a new entry in the
+  TableHandler::TextOutputFormat enumeration.
+  <br>
+  (Oleh Krehel, 2013/08/15)
+  </li>
+
+  <li>
+  New: There are now global functions <code>scalar_product</code>
+  that compute the scalar product (double contraction) between
+  tensors of rank 2.
+  <br>
+  (Scott Miller, 2013/08/14)
+  </li>
+
+  <li>
+  Fixed: Creating objects of type MappingQ was previously only possible
+  for low order polynomials. For orders higher than around 6, one ran
+  into assertions that tested for internal consistency. These assertions
+  have now been appropriately relaxes for the growth of round-off errors
+  with growing polynomial degrees.
+  <br>
+  (Juan Carlos Araujo Cabarcas, Wolfgang Bangerth, 2013/08/14)
+  </li>
+
+  <li>
+  New: MappingQEulerian is now also instantiated for vector elements
+  of type TrilinosWrappers::Vector as well as the MPI and block
+  variants.
+  <br>
+  (Armin Ghajar Jazi, 2013/08/14)
+  </li>
+
+  <li>
+  Fixed: The FiniteElement::face_to_cell_index() function had a bug
+  that made it work incorrectly for elements that have more than one
+  degree of freedom per line (in 2d) or per quad (in 3d). This is now
+  fixed for the most common cases, namely the FE_Q elements as well
+  as elements composed of FESystem elements. For all other cases, an
+  exception is generated reporting that this case is not implemented.
+  If you run into this, let us know.
+  <br>
+  (Wolfgang Bangerth, 2013/08/10)
+  </li>
+
+  <li>
+  New: DataOutBase::VtkFlags now has a flag
+  DataOutBase::VtkFlags::print_date_and_time that can be used to suppress output
+  of date and time in output files. This is useful in test suites where a newer
+  run at a different time produces differences against previously stored files,
+  even though the actual data is exactly the same.
+  <br>
+  (Oleh Krehel, 2013/08/06)
+  </li>
+
+  <li>
+  Fixed: The various block matrix classes are all derived from BlockMatrixBase
+  which had race conditions when the set() or add() functions were called from
+  different threads. This is now fixed.
+  <br>
+  (Wolfgang Bangerth, 2013/08/05)
+  </li>
+
+  <li>
+  Fixed: various fixes with assignment and reinit of PETScWrappers::MPI::Vector.
+  <br>
+  (Timo Heister, 2013/08/05)
+  </li>
+
+  <li>Fixed: An assertion wrongly triggered in
+  DoFTools::make_hanging_node_constraints when used with a particular
+  combination of FESystem elements containing FE_Nothing. This is now fixed.
+  <br>
+  (Denis Davydov, Wolfgang Bangerth, 2013/08/01)
+  </li>
+
+  <li>
+  New: Add has_ghost_elements() for PETScWrappers::MPI::BlockVector and
+  TrilinosWrappers::MPI::BlockVector.
+  <br>
+  (Timo Heister, 2013/08/01)
+  </li>
+
+  <li>
+  SparsityTools::distribute_sparsity_pattern did not work correctly for
+  block systems, this has been fixed (function has a different signature).
+  <br>
+  (Timo Heister, 2013/07/31)
+  </li>
+
+  <li>Fixed: When typing <code>make run</code> in the step-32 directory,
+  the program was executed with <code>mpirun -np 2 ./step-32</code>. This
+  assumes that a program <code>mpirun</code> exists, but also does that
+  deal.II was in fact compiled with MPI support on. Neither was intended.
+  This is now fixed.
+  <br>
+  (Wolfgang Bangerth, 2013/07/24)
+  </li>
+
+  <li>New: The DataOut, DataOutFaces, and DataOutRotation classes now allow
+  the output of data vectors using different DoFHandler objects (based on the
+  same triangulation), by new functions add_data_vector. This is used in the
+  step-31 tutorial program which avoids creating a joint DoFHandler just for
+  output.
+  <br>
+  (Martin Kronbichler, 2013/07/24)
+  </li>
+
+  <li>Changed: GridGenerator used to be a class with only static members
+  but is now a namespace, like all other similar constructs in deal.II.
+  <br>
+  (Wolfgang Bangerth, 2013/07/24)
+  </li>
+
+  <li>Changed: In GridGenerator, several functions had erroneously been changed
+  to take an argument of type <code>size_type</code> rather than <code>unsigned
+  int</code>. <code>GridGenerator::size_type</code> was a typedef to
+  types::global_dof_index, which for most users was <code>unsigned int</code>
+  anyway, but could also be set to be a 64-bit integer type. In any case, the
+  change has been reverted and these functions take just a regular
+  <code>unsigned int</code> again.
+  <br>
+  (Wolfgang Bangerth, 2013/07/24)
+  </li>
 </ol>
 
 
index 79fa7929fbfa1915971d391040e467b0fb18fd6d..bd812602cd20d2e03600bb7ef6dd609d98d81b58 100644 (file)
          unknowns, and many more. A full list of changes can be
          found <a href="../doxygen/deal.II/changes_between_7_3_and_8_0.html"
          target="body">here</a>.
+         <br>
+         deal.II can be downloaded at
+         <a href="https://code.google.com/p/dealii/downloads/list"
+         target="_top">this site</a>.
       </dd>
 
       <dt>
           library that, among much other functionality, offers some
           sparse direct solvers. We have added support for an
           interface to these solvers to the library.
-          (See the <a href="../readme.html#hsl" target="body">ReadMe</a>
-          file for more information on installation of HSL
-          subroutines.)
       </dd>
 
       <dt>
index eea2a46b95750906b106fb88589536f45e318161..4ce3eff9f5791f225d5b2fb45b13af3d31ed49af 100644 (file)
          Journal of Scientific Computing, vol. 55, pp. 432-454, 2013.
        </li>
 
+       <li> T. Fankhauser, T. Wihler, M. Wirz
+         <br>
+         <strong>The hp-adaptive FEM based on continuous Sobolev embeddings: Isotropic
+       refinements</strong>
+         <br>
+         Computers & Mathematics with Applications (in press), 2013.
+       </li>
+
        <li> A. Geringer, B. Lenhof, S. Diebels
          <br>
           <strong>Macroscopic modeling of foams: an order-parameter
          pp. 46-72, 2013.
         </li>
 
+       <li> N. Klein
+         <br>
+          <strong>Consistent FE-Analysis of elliptic Variational Inequalities
+          </strong>
+         <br>
+         PhD thesis, University of Siegen, Germany, 2013.
+       </li>
+
        <li> T. Kr&uuml;ger
          <br>
           <strong>Regularization-based fictitious domain methods
@@ -739,6 +755,15 @@ a monolithic ALE framework
          pp. 114-124, 2013.
        </li>
 
+       <li> <a href="http://www.ippt.gov.pl/~tyoung"
+               target="_top">T. D. Young</a>
+         <br>
+         <strong>A finite basis grid analysis of the Hartree-Fock wavefunction method for one- and two-electron atoms
+         </strong>
+         <br>
+         AIP Conf. Proc., Accepted, 2013.
+        </li>
+
        <li> <a href="http://www.ippt.gov.pl/~tyoung"
                target="_top">T. D. Young</a>, E. Romero, J. E. Roman
          <br>
@@ -2898,12 +2923,7 @@ A Goal Oriented Software Library for Solving PDEs and Optimization Problems with
             basis
           </strong>
           <br>
-          In George Maroulis and Theodore E. Simos, editors,
-          Computational Methods in Science and Engineering: Advances in
-          Computational Science, number 1108, New York, USA, Mar
-          2009. Proceedings of the International Conference on Computational
-          Methods in Sciences and Engineering, American Institute of Physics
-          Conference Proceedings, 2009.
+          AIP Conf. Proc., vol. 1148, pp. 285-289 2009.
        </li>
 
        <li> R. Ziegler, B. Brendel, A. Schipper, R. Harbers, M. van Beek,
index 46a57e77da6d82274c2c7155b4da59cc3e1b325f..b08a508c308c7455df6e5ae4953f6c98d032d18b 100644 (file)
@@ -15,9 +15,9 @@
 
 
     <h2 align="center" style="color: red">
-     <strong class="red">Note: Current development sources
-       use <a href="http://www.cmake.org" target="_top">CMake</a> to
-       build <acronym>deal.II</acronym>. For using the previous build
+     <strong class="red">Note: <acronym>deal.II</acronym> uses
+       <a href="http://www.cmake.org" target="_top">CMake</a> to
+       configure and build. For using the previous build
        system used until <acronym>deal.II</acronym> version 7.3, see
        <a href="http://www.dealii.org/7.3.0/readme.html"
        target="_top">the old ReadMe file</a>.
 
        mkdir build
        cd build
-       cmake -DCMAKE_INSTALL_PREFIX=/path/install/dir ../deal.II
+       cmake -DCMAKE_INSTALL_PREFIX=/path/to/install/dir ../deal.II
        make install
       </pre>
       These steps compile, link and install the deal.II library. The
     <p>
       <b>Note:</b>
       <ul>
-       <li> <code>/path/install/dir</code> is the directory which deal.II
+       <li> <code>/path/to/install/dir</code> is the directory which deal.II
          should be installed into. This can be a directory in your home
          directory (e.g., <code>~/bin/deal.II</code>) or a directory
          such as <code>/usr/local</code> if you have root privileges. 
-         Another option is to use <code>`pwd`/../installed/</code> (note the
-         backticks).
+         Another option is to use something like <code>`pwd`/../installed/</code> (note the
+         backticks). Make sure the installation directory is not the same
+         as the location where you unpacked <tt>deal.II/</tt>.
 
        <li> If your machine has multiple processors, use <code>make
          -jN</code> in the last step, where <code>N</code> is the
index c887721bed9fd48301f2e1cb03dd8035f225f549..09599c7935cfe09ca8a4a3096cd04aa67db8b250 100644 (file)
@@ -1,18 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1999 - 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.
-//
-// ---------------------------------------------------------------------
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 1999 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ */
 
 
 // @sect3{Include files}
@@ -91,7 +93,7 @@ void second_grid ()
   // We then fill it with a ring domain. The center of the ring shall be the
   // point (1,0), and inner and outer radius shall be 0.5 and 1. The number of
   // circumferential cells could be adjusted automatically by this function,
-  // but we choose to set it explicitely to 10 as the last argument:
+  // but we choose to set it explicitly to 10 as the last argument:
   const Point<2> center (1,0);
   const double inner_radius = 0.5,
                outer_radius = 1.0;
index ca6507013b7eb4eddd55a04dbe8fe6bf4ed17041..f62c273b827df7ef675cac04891855f39f16407f 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2001 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2001 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Wolfgang Bangerth, Ralf Hartmann, University of Heidelberg, 2001
  */
 
index c4f76476463b2180aca8ae98b38123cf29e6d8f7..49cfda2b255adcf888440840c16851f048965989 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2001 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2001 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 2001
  */
 
index e50de11a6f7f7ad27cf670f539e5acf5c968c6f8..26c26d3acf88092228e297ce4113b382ffbc6175 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Guido Kanschat, Texas A&M University, 2009
  */
 
index 4334e9053420051b620017546e840b93d185cf93..24ab2a6d5d763412260992f124c481e94797e236 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2001 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2001 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 2001, 2002
  */
 
@@ -170,7 +170,7 @@ namespace Step13
     // macros. We use this mechanism here again.
     //
     // From this, the actual declaration of this class should be evident. Note
-    // that of course even if we do not list a destructor explicitely, an
+    // that of course even if we do not list a destructor explicitly, an
     // implicit destructor is generated from the compiler, and it is virtual
     // just as the one of the base class.
     template <int dim>
@@ -848,8 +848,8 @@ namespace Step13
           // lead to deadlocks. A similar situation arises, when one changes
           // the code to have a return statement somewhere in the middle of
           // the locked block, and forgets that before we call
-          // <code>return</code>, we also have to unlock the mutex. This all
-          // is not be a problem here, but we want to show the general
+          // <code>return</code>, we also have to unlock the mutex. All this
+          // is no problem here, but we want to show the general
           // technique to cope with these problems nevertheless: have an
           // object that upon initialization (i.e. in its constructor) locks
           // the mutex, and on running the destructor unlocks it again. This
index a8e28833684f4ca10582418a9fe2f7fce144aa70..f91bbfc666f86db6d09e5f3d417964a2b0ec5f27 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2002 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2002 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, ETH Zurich, 2002
  */
 
@@ -2589,7 +2589,7 @@ namespace Step14
       Assert (cell->neighbor(face_no).state() == IteratorState::valid,
               ExcInternalError());
       // If we have that, then we need to find out with which face of the
-      // neighboring cell we have to work, i.e. the <code>home-many</code>the
+      // neighboring cell we have to work, i.e. the <code>how-many'th</code> the
       // neighbor the present cell is of the cell behind the present face. For
       // this, there is a function, and we put the result into a variable with
       // the name <code>neighbor_neighbor</code>:
@@ -2671,7 +2671,7 @@ namespace Step14
               ExcInternalError());
 
       // Then find out which neighbor the present cell is of the adjacent
-      // cell. Note that we will operator on the children of this adjacent
+      // cell. Note that we will operate on the children of this adjacent
       // cell, but that their orientation is the same as that of their mother,
       // i.e. the neigbor direction is the same.
       const unsigned int
@@ -2836,7 +2836,7 @@ namespace Step14
 
       // Finally, we have a variable that denotes the maximum number of
       // degrees of freedom we allow for the (primal) discretization. If it is
-      // exceeded, we stop the process of solving and intermittend mesh
+      // exceeded, we stop the process of solving and intermittent mesh
       // refinement. Its default value is 20,000.
       unsigned int max_degrees_of_freedom;
 
index 33494379ebcca539b095191b5ef115850227be48..344cd54f5fd1871c03fb43497252c3159a728c91 100644 (file)
@@ -95,7 +95,7 @@ u^{0}=g$ in the first step and with $\delta u^{n}=0$ in all the following steps.
 <h3>Weak formulation of the problem</h3>
 
 Starting with the strong formulation above, we get the weak formulation by multiplying
-both sides of the PDE with a testfunction $\varphi$ and integrating by parts on both sides:
+both sides of the PDE with a test function $\varphi$ and integrating by parts on both sides:
   @f[
   \left( \nabla \varphi , \frac{1}{(1+|\nabla u^{n}|^{2})^{\frac{1}{2}}}\nabla
   \delta u^{n} \right)-\left(\nabla \varphi ,\frac{\nabla u^{n} \cdot \nabla
@@ -112,7 +112,7 @@ Reducing this space to a finite dimensional space with basis $\left\{
   \delta u^{n}=\sum_{j=0}^{N-1} U_{j} \varphi_{j}
 @f]
 
-Using the basis functions as testfunctions and defining $a_{n}:=\frac{1}
+Using the basis functions as test functions and defining $a_{n}:=\frac{1}
 {\sqrt{1+|\nabla u^{n}|^{2}}}$, we can rewrite the weak formualtion:
 
 @f[
index 4ec576c051bbdb561fa3f861b40350265e123094..dca38227eb7be50e5f275a8735f3b9e95314be93 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2012 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2012 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Sven Wetterauer, University of Heidelberg, 2012
  */
 
@@ -81,7 +81,7 @@ namespace Step15
   //   $\delta u^n$, and one for the current iterate $u^n$.
   // - The <code>setup_system</code> function takes an argument that denotes whether
   //   this is the first time it is called or not. The difference is that the
-  //   first time around we need to distributed degrees of freedom and set the
+  //   first time around we need to distribute the degrees of freedom and set the
   //   solution vector for $u^n$ to the correct size. The following times, the
   //   function is called after we have already done these steps as part of
   //   refining the mesh in <code>refine_mesh</code>.
@@ -267,12 +267,12 @@ namespace Step15
         // For the assembly of the linear system, we have to obtain the values
         // of the previous solution's gradients at the quadrature
         // points. There is a standard way of doing this: the
-        // FEValues::get_function function takes a vector that represents a
-        // finite element field defined on a DoFHandler, and evaluates the
-        // gradients of this field at the quadrature points of the cell with
-        // which the FEValues object has last been reinitialized. The values
-        // of the gradients at all quadrature points are then written into the
-        // second argument:
+        // FEValues::get_function_gradients function takes a vector that
+        // represents a finite element field defined on a DoFHandler, and
+        // evaluates the gradients of this field at the quadrature points of the
+        // cell with which the FEValues object has last been reinitialized.
+        // The values of the gradients at all quadrature points are then written
+        // into the second argument:
         fe_values.get_function_gradients(present_solution,
                                          old_solution_gradients);
 
@@ -520,7 +520,7 @@ namespace Step15
     const unsigned int           dofs_per_cell = fe.dofs_per_cell;
     const unsigned int           n_q_points    = quadrature_formula.size();
 
-    Vector<double>               cell_rhs (dofs_per_cell);
+    Vector<double>               cell_residual (dofs_per_cell);
     std::vector<Tensor<1, dim> > gradients(n_q_points);
 
     std::vector<types::global_dof_index>    local_dof_indices (dofs_per_cell);
@@ -530,7 +530,7 @@ namespace Step15
     endc = dof_handler.end();
     for (; cell!=endc; ++cell)
       {
-        cell_rhs = 0;
+        cell_residual = 0;
         fe_values.reinit (cell);
 
         // The actual computation is much as in
@@ -549,7 +549,7 @@ namespace Step15
                                              gradients[q_point]);
 
             for (unsigned int i = 0; i < dofs_per_cell; ++i)
-              cell_rhs(i) -= (fe_values.shape_grad(i, q_point)
+              cell_residual(i) -= (fe_values.shape_grad(i, q_point)
                               * coeff
                               * gradients[q_point]
                               * fe_values.JxW(q_point));
@@ -557,7 +557,7 @@ namespace Step15
 
         cell->get_dof_indices (local_dof_indices);
         for (unsigned int i=0; i<dofs_per_cell; ++i)
-          residual(local_dof_indices[i]) += cell_rhs(i);
+          residual(local_dof_indices[i]) += cell_residual(i);
       }
 
     // At the end of this function we also have to deal with the hanging node
@@ -596,7 +596,7 @@ namespace Step15
   // As discussed in the introduction, Newton's method frequently does not
   // converge if we always take full steps, i.e., compute $u^{n+1}=u^n+\delta
   // u^n$. Rather, one needs a damping parameter (step length) $\alpha^n$ and
-  // set $u^{n+1}=u^n+\alpha^n\delta u^n$. This function is the one called
+  // set $u^{n+1}=u^n+\alpha^n\delta u^n$. This function is the one called
   // to compute $\alpha^n$.
   //
   // Here, we simply always return 0.1. This is of course a sub-optimal
index 81e5ff040d8c89f69e44eca0b8c4cf3017fdc104..f5e657493ea6c93ad4523bd9b3d20c65ed427b4e 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2003 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2003 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Guido Kanschat, University of Heidelberg, 2003
  *          Baerbel Janssen, University of Heidelberg, 2010
  *          Wolfgang Bangerth, Texas A&M University, 2010
@@ -99,7 +99,7 @@ namespace Step16
   class LaplaceProblem
   {
   public:
-    LaplaceProblem (const unsigned int deg);
+    LaplaceProblem (const unsigned int degree);
     void run ();
 
   private:
@@ -130,7 +130,7 @@ namespace Step16
     const unsigned int degree;
 
     // The following four objects are the only additional member variables,
-    // compared to step-6. They first three represent the operators that act
+    // compared to step-6. The first three represent the operators that act
     // on individual levels of the multilevel hierarchy, rather than on the
     // finest mesh as do the objects above while the last object stores
     // information about the boundary indices on each level and information
@@ -351,7 +351,7 @@ namespace Step16
 
   // @sect4{LaplaceProblem::assemble_system}
 
-  // The following function assembles the linear system on the finesh level of
+  // The following function assembles the linear system on the finest level of
   // the mesh. It is almost exactly the same as in step-6, with the exception
   // that we don't eliminate hanging nodes and boundary values after
   // assembling, but while copying local contributions into the global
@@ -472,9 +472,9 @@ namespace Step16
     // The indices just identified will later be used to decide where the
     // assembled value has to be added into on each level.  On the other hand,
     // we also have to impose zero boundary conditions on the external
-    // boundary of each level. But this the <code>MGConstraints</code> knows
-    // it. So we simply ask for them by calling <code>get_boundary_indices
-    // ()</code>.  The third step is to construct constraints on all those
+    // boundary of each level. But this the <code>MGConstraints</code> knows.
+    // So we simply ask for them by calling <code>get_boundary_indices()</code>.
+    // The third step is to construct constraints on all those
     // degrees of freedom: their value should be zero after each application
     // of the level operators. To this end, we construct ConstraintMatrix
     // objects for each level, and add to each of these constraints for each
index 77d825f29b0c64575e63fb81d45b72137614fe7b..c32373d4834496b0968a41e327c691f37196a4e5 100644 (file)
@@ -34,7 +34,7 @@ IF(NOT DEAL_II_WITH_PETSC)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_PETSC = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 43e274a2b6590d05c8dadf5ab6fdd592bb537cd4..0b9499c8489861870524de170890227168445390 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2000 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2000 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Texas at Austin, 2000, 2004
  */
 
@@ -245,10 +245,11 @@ namespace Step17
   // communicator object that only links a subset of all processes), and call
   // the Utilities helper functions to determine the number of processes and
   // where the present one fits into this picture. In addition, we make sure
-  // that output is only generated by the (globally) first process. As,
-  // this_mpi_process is determined after creation of pcout, we cannot set the
-  // condition through the constructor, i.e. by pcout(std::cout,
-  // this_mpi_process==0), but set the condition separately.
+  // that output is only generated by the (globally) first process. As
+  // <code>this_mpi_process</code> is determined after creation of pcout, we
+  // cannot set the condition through the constructor, i.e. by
+  // <code>pcout(std::cout, this_mpi_process==0)</code>, but set the
+  // condition separately.
   template <int dim>
   ElasticProblem<dim>::ElasticProblem ()
     :
@@ -537,7 +538,7 @@ namespace Step17
     // The last argument to the call just performed allows for some
     // optimizations. It controls whether we should also delete the column
     // corresponding to a boundary node, or keep it (and passing
-    // <code>true</code> as above means: yes, do eliminate the column). If we
+    // <code>true</code> means: yes, do eliminate the column). If we
     // do, then the resulting matrix will be symmetric again if it was before;
     // if we don't, then it won't. The solution of the resulting system should
     // be the same, though. The only reason why we may want to make the system
index c1e1076991e81c7b55779d1db35b5e8ec1559fbe..33af07ee5a4cc8cdafe31dbff923c750b1df68f2 100644 (file)
@@ -34,7 +34,7 @@ IF(NOT DEAL_II_WITH_PETSC)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_PETSC = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 2c37a1d863643647bb2955a2189b5f6decb23d9f..81ff567e4402aedbb4ecfd475047d7786cc1964d 100644 (file)
@@ -107,7 +107,7 @@ following, let us consider some of the tools one would employ when
 simulating problems in which the deformation becomes <i>large</i>.
 
 @note The model we will consider below is not founded on anything that
-would be mathematical sound: we will consider a model in which we
+would be mathematically sound: we will consider a model in which we
 produce a small deformation, deform the physical coordinates of the
 body by this deformation, and then consider the next loading step
 again as a linear problem. This isn't consistent, since the assumption
index 7c3c0228254a91264a385531b7e11a82b732e7c6..b59460a793083c1defcc64028f2e7f19de2252cf 100644 (file)
@@ -111,10 +111,10 @@ examples/\step-18> ../\step-19/\step-19
 
 Converter from deal.II intermediate format to other graphics formats.
 
-Usage: ./\step-19 [-p parameter_file] list_of_input_files [-x output_format] output_file
+Usage: ./\step-19 [-p parameter_file] list_of_input_files [-x output_format] -o output_file
 
-examples/\step-18> ../\step-19/\step-19 solution-0001.0000.d2 -x gmv solution-0001.0000.gmv
-examples/\step-18> ../\step-19/\step-19 solution-0002.0000.d2 -x gmv solution-0002.0000.gmv
+examples/\step-18> ../\step-19/\step-19 solution-0001.0000.d2 -x gmv -o solution-0001.0000.gmv
+examples/\step-18> ../\step-19/\step-19 solution-0002.0000.d2 -x gmv -o solution-0002.0000.gmv
 [...]
 @endcode
 Of course, since we have run the program only in sequential mode, we
index 34ed6cb2804532eab83ae86640da02efe0d21d24..9de024169afd4d575587797e59a36ff005b98a8b 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2000 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2000 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Texas at Austin, 2000, 2004, 2005
  */
 
@@ -106,8 +106,8 @@ namespace Step18
   // in the form $C_{ijkl} = \mu (\delta_{ik} \delta_{jl} + \delta_{il}
   // \delta_{jk}) + \lambda \delta_{ij} \delta_{kl}$. This tensor maps
   // symmetric tensor of rank 2 to symmetric tensors of rank 2. A function
-  // implementing its creation for given values of the Lame constants lambda
-  // and mu is straightforward:
+  // implementing its creation for given values of the Lame constants $\lambda$
+  // and $\mu$ is straightforward:
   template <int dim>
   SymmetricTensor<4,dim>
   get_stress_strain_tensor (const double lambda, const double mu)
@@ -443,7 +443,7 @@ namespace Step18
     // One difference of this program is that we declare the quadrature
     // formula in the class declaration. The reason is that in all the other
     // programs, it didn't do much harm if we had used different quadrature
-    // formulas when computing the matrix and the righ hand side, for
+    // formulas when computing the matrix and the right hand side, for
     // example. However, in the present case it does: we store information in
     // the quadrature points, so we have to make sure all parts of the program
     // agree on where they are and how many there are on each cell. Thus, let
@@ -1330,10 +1330,10 @@ namespace Step18
       subdomain_id (subdomain_id)
     {}
 
-    virtual typename DoFHandler<dim>::cell_iterator
+    virtual typename DataOut<dim>::cell_iterator
     first_cell ()
     {
-      typename DoFHandler<dim>::active_cell_iterator
+      typename DataOut<dim>::active_cell_iterator
       cell = this->dofs->begin_active();
       while ((cell != this->dofs->end()) &&
              (cell->subdomain_id() != subdomain_id))
@@ -1342,8 +1342,8 @@ namespace Step18
       return cell;
     }
 
-    virtual typename DoFHandler<dim>::cell_iterator
-    next_cell (const typename DoFHandler<dim>::cell_iterator &old_cell)
+    virtual typename DataOut<dim>::cell_iterator
+    next_cell (const typename DataOut<dim>::cell_iterator &old_cell)
     {
       if (old_cell != this->dofs->end())
         {
@@ -1352,7 +1352,7 @@ namespace Step18
 
           return
             ++(FilteredIterator
-               <typename DoFHandler<dim>::active_cell_iterator>
+               <typename DataOut<dim>::active_cell_iterator>
                (predicate,old_cell));
         }
       else
@@ -1456,7 +1456,7 @@ namespace Step18
     // As a last piece of data, let us also add the partitioning of the domain
     // into subdomains associated with the processors if this is a parallel
     // job. This works in the exact same way as in the step-17 program:
-    std::vector<unsigned int> partition_int (triangulation.n_active_cells());
+    std::vector<types::subdomain_id> partition_int (triangulation.n_active_cells());
     GridTools::get_subdomain_association (triangulation, partition_int);
     const Vector<double> partitioning(partition_int.begin(),
                                       partition_int.end());
index 6f8b6672813a036be25ba926e40c5db64a92e7b8..17bec2c4abe2f685bb2786b019deee109fd90c0f 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Luca Heltai, Wolfgang Bangerth, 2005
  */
 
@@ -297,7 +297,7 @@ namespace Step19
               prm.get_bool ("Dummy generate output");
             }
             prm.leave_subsection ();
-            // We would assign the result to a variable, or course, but don't
+            // We would assign the result to a variable, of course, but don't
             // here in order not to generate an unused variable that the
             // compiler might warn about.
             //
index 1747f1db35bbe23334fced98d8e9738b2ea32b61..cb6cd25b2e45f253c6198a84917c0c535bafe8ca 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1999 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 1999 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 1999
  */
 
index e71fa739e89d119f2855e44789578f61526282f2..a0e6c251d8f3081605ab1bf731cd98bde477bea5 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2005, 2006
  */
 
index fbf4aee19ea2a38a83bcdbc0323be632ea36a5e8..24c95d3bef34d5afde1b2f394e4aeab00bf79aa5 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2006 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2006 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Yan Li, Wolfgang Bangerth, Texas A&M University, 2006
  */
 
index 00923478ae2477e3d7dfb30baae39d5d752801ec..03e2ef3408638cc59203d0894d27cd3e98ba6f3e 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_UMFPACK)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_UMFPACK = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 73a5674dace1b2f7ec6eb4550de8a3a953b7013c..b57dbed1baf0913595264b39a78eeb26ddaf6bc6 100644 (file)
@@ -566,7 +566,7 @@ struct InnerPreconditioner<3>
 @endcode
 
 From hereon, we can refer to the type <code>typename
-InnerPreconditioner@<dim@>::type</code> and automatically get the correct
+InnerPreconditioner@<dim@>::%type</code> and automatically get the correct
 preconditioner class. Because of the similarity of the interfaces of the two
 classes, we will be able to use them interchangeably using the same syntax in
 all places.
index 3524d69293fcc2d9c33e847ab17e483545485f69..526329912753e94d9eeef47eb743585bcdf47990 100644 (file)
@@ -119,7 +119,7 @@ This plot uses the capability of VTK-based visualization programs (in
 this case of VisIt) to show vector data; this is the result of us
 declaring the velocity components of the finite element in use to be a
 set of vector components, rather than independent scalar components in
-the <code>StokesProblem@<dim@>::output_results</code> function of this
+the <code>StokesProblem@<dim@>::%output_results</code> function of this
 tutorial program.
 
 
index 1fcf3b5a3bf45c4b3def363ffb897f3d19560e71..96ea2b04270445c35b8d9fb59fe519a5b6212966 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2008 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2008 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2008
  */
 
index c7b70487afc512ae3ba84566e334fd4d653785af..1139efd2bd0310c0b85bd5626f7a5a8d9aaee274 100644 (file)
@@ -84,7 +84,7 @@ other time dependent problems, we find that the character of a
 solution changes as time progresses. For example, for the wave
 equation, we may have a single wave travelling through the domain,
 where the solution is smooth or even constant in front of and behind
-the wave &mdash& adaptivity would be really useful for such cases, but the
+the wave &mdash; adaptivity would be really useful for such cases, but the
 key is that the area where we need to refine the mesh changes from
 time step to time step!
 
@@ -156,7 +156,7 @@ time derivatives for both variables, for which it is simple to write
 down time stepping schemes. Note that we do not have boundary
 conditions for $v$ at first. However, we could enforce $v=\frac{\partial
 g}{\partial t}$ on the boundary. It turns out in numerical examples that this
-as actually necessary: without doing so the solution doesn't look particularly
+is actually necessary: without doing so the solution doesn't look particularly
 wrong, but the Crank-Nicolson scheme does not conserve energy if one doesn't
 enforce these boundary conditions.
 
@@ -296,9 +296,9 @@ where
        \\
        A^{n,n-1}_{ij} &=& (\nabla\phi_i^n, \nabla\phi_j^{n-1}),
        \\
-       F^n_{ij} &=& (f^n,\phi_i^n),
+       F^n_{i} &=& (f^n,\phi_i^n),
        \\
-       F^{n-1}_{ij} &=& (f^{n-1},\phi_i^n).
+       F^{n-1}_{i} &=& (f^{n-1},\phi_i^n).
 @f}
 
 If we solve these two equations, we can move the solution one step
index 513699f9f9e9fc35f6090926eef84c41ef470d6b..1c86e3eb7d36a91c8691fb72dad7df5be8fabb14 100644 (file)
@@ -105,8 +105,8 @@ If you want to explore a bit, try out some of the following things:
 
   To make such a change, we would have to compute the mass and Laplace
   matrices with a variable coefficient. Fortunately, this isn't too hard: the
-  functions MatrixTools::create_laplace_matrix and
-  MatrixTools::create_vector_tools have additional default parameters that can
+  functions MatrixCreator::create_laplace_matrix and
+  MatrixCreator::create_mass_matrix have additional default parameters that can
   be used to pass non-constant coefficient functions to them. The required
   changes are therefore relatively small. On the other hand, care must be
   taken again to make sure the time step is within the allowed range.
index 628f840f7aebcfdfa72ec0907668049c31aeed94..3fb30e3476ba686aa93789ed045dfd841b245feb 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2006 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2006 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2006
  */
 
@@ -54,7 +54,7 @@
 // Here are the only three include files of some new interest: The first one
 // is already used, for example, for the
 // VectorTools::interpolate_boundary_values and
-// VectorTools::apply_boundary_values functions. However, we here use another
+// MatrixTools::apply_boundary_values functions. However, we here use another
 // function in that class, VectorTools::project to compute our initial values
 // as the $L^2$ projection of the continuous initial values. Furthermore, we
 // use VectorTools::create_right_hand_side to generate the integrals
@@ -68,8 +68,8 @@
 // mass and Laplace matrices, although it would have only taken copying the
 // relevant code from any number of previous tutorial programs. Rather, we
 // want to focus on the things that are truly new to this program and
-// therefore use the MatrixTools::create_mass_matrix and
-// MatrixTools::create_laplace_matrix functions. They are declared here:
+// therefore use the MatrixCreator::create_mass_matrix and
+// MatrixCreator::create_laplace_matrix functions. They are declared here:
 #include <deal.II/numerics/matrix_tools.h>
 
 // Finally, here is an include file that contains all sorts of tool functions
index 4ee0f37f703f49836ab1bc83f0d3de5af64f5123..c3a23332ccb12a81096d63280961155d537e0692 100644 (file)
@@ -118,7 +118,7 @@ defined as the derivative of the pressure potential:
 v = \frac{\partial\bar{p}}{\partial t} 
 @f]
 
-With the second variables, one then transform the forward problem into
+With the second variable, one then transforms the forward problem into
 two separate equations:
 @f{eqnarray*}
 \bar{p}_{t} - v & = & 0 \\
index ccf969d74db0bebcf01bf1a8998f1a3150162421..e44ea21f12a1f3a86eae012abbf38940552e021f 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2006 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2006 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Xing Jin, Wolfgang Bangerth, Texas A&M University, 2006
  */
 
@@ -132,7 +132,7 @@ namespace Step24
   // pressure. In the physical setting considered in this program, these are
   // small absorbers, which we model as a series of little circles where we
   // assume that the pressure surplus is one, whereas no absorption and
-  // therefore no pressure surplus is anywhere else. This is how we do things
+  // therefore no pressure surplus is everywhere else. This is how we do things
   // (note that if we wanted to expand this program to not only compile but
   // also to run, we would have to initialize the sources with
   // three-dimensional source locations):
@@ -311,7 +311,7 @@ namespace Step24
     //
     // A first observation would be that this matrix is much sparser than the
     // regular mass matrix, since none of the shape functions with purely
-    // interior support contributes to this matrix. We could therefore
+    // interior support contribute to this matrix. We could therefore
     // optimize the storage pattern to this situation and build up a second
     // sparsity pattern that only contains the nonzero entries that we
     // need. There is a trade-off to make here: first, we would have to have a
@@ -475,7 +475,7 @@ namespace Step24
   // consumption of the program, the introduction of a few temporary vectors
   // isn't doing much harm.
   //
-  // The only changes to this function are: First, that we do not have to
+  // The only changes to this function are: first, that we do not have to
   // project initial values for the velocity $v$, since we know that it is
   // zero. And second that we evaluate the solution at the detector locations
   // computed in the constructor. This is done using the
index f43b6a31789ce7a2a2cc8d06632aaed3118e9a95..96f269cc3a4b3cec3bd3072084155821e4c44c48 100644 (file)
@@ -101,8 +101,8 @@ To this end, we can use Newton's method. Given the nonlinear equation $F(u^n) =
   \mbox{ Find } \delta u^n_l \mbox{ s.t. } F'(u^n_l)\delta u^n_l = -F(u^n_l) 
   \mbox{, set }  u^n_{l+1} = u^n_l + \delta u^n_l.
 \f}
-The iteration can be initialized with the old time step, i.e. $u^{n,0} =
-u^{n-1}$, and eventually it will produce a solution to the first equation of
+The iteration can be initialized with the old time step, i.e. $u^n_0 = u^{n-1}$, 
+and eventually it will produce a solution to the first equation of
 the split formulation (see above). For the time discretizaion of the
 sine-Gordon equation under consideration here, we have that 
 \f{eqnarray*}
@@ -120,7 +120,7 @@ With hindsight, we choose both the solution and the test space to be $H^1(\Omega
   &\mbox{ Find}& \delta u^n_l \in H^1(\Omega) \mbox{ s.t. } 
   \left( F'(u^n_l)\delta u^n_l, \varphi \right)_{\Omega} 
   = -\left(F(u^n_l), \varphi \right)_{\Omega} \;\forall\varphi\in H^1(\Omega),
-  \mbox{ set } u^n_{l+1} = u^n_l + \delta u^n_l,\; u^{n,0} = u^{n-1}.\\
+  \mbox{ set } u^n_{l+1} = u^n_l + \delta u^n_l,\; u^n_0 = u^{n-1}.\\
   &\mbox{ Find}& v^n \in H^1(\Omega) \mbox{ s.t. }
   \left( v^n, \varphi \right)_{\Omega} = \left( v^{n-1}, \varphi \right)_{\Omega} 
          - k\theta\left( \nabla u^n, \nabla\varphi \right)_{\Omega} 
@@ -157,9 +157,9 @@ Above, the matrix $F_h'(\cdot)$ and the vector $F_h(\cdot)$ denote the discrete
 \f{eqnarray*}
   F_h(U^{n,l}) &=&  \left[ M+k^2\theta^2A \right] U^{n,l} -  
                 \left[ M-k^2\theta(1-\theta)A \right] U^{n-1} - k MV^{n-1} 
-                + k^2\theta S(u^{n,l}, u^{n-1}),\\
+                + k^2\theta S(u^n_l, u^{n-1}),\\
   F_h'(U^{n,l}) &=& M+k^2\theta^2A 
-                                - k^2\theta^2N(u^{n,l},u^{n-1})
+                                - k^2\theta^2N(u^n_l,u^{n-1})
 \f}
 Again, note that the first matrix equation above is, in fact, the
 defition of an iterative procedure, so it is solved multiple times
@@ -176,9 +176,9 @@ i.e. $N_{ij}(f,g) = \left( \cos\left[ \theta f + (1-\theta) g\right]\varphi_i,
 What solvers can we use for the first equation? Let's look at the matrix we
 have to invert:
 @f[
-  (M-k^2\theta^2N)_{ij} = 
+  (M+k^2\theta^2(A-N))_{ij} = 
   \int_\Omega (1-k^2\theta^2 \cos \alpha) 
\varphi_i\varphi_j \; dx,
 \varphi_i\varphi_j \; dx+\int_\Omega \nabla\varphi_i\nabla\varphi_j \; dx,
 @f]
 for some $\alpha$ that depends on the present and previous solution. First,
 note that the matrix is symmetric. In addition, if the time step $k$ is small
index a03335ce3483cb6e628347bbf9f3b008465882bb..794e09f8703fef1f26a8988d4a344a542e77f3b2 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2006 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2006 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Ivan Christov, Wolfgang Bangerth, Texas A&M University, 2006
  */
 
@@ -333,7 +333,7 @@ namespace Step25
 
   // @sect4{SineGordonProblem::assemble_system}
 
-  // This functions assembles the system matrix and right-hand side vector for
+  // This function assembles the system matrix and right-hand side vector for
   // each iteration of Newton's method. The reader should refer to the
   // Introduction for the explicit formulas for the system matrix and
   // right-hand side.
@@ -350,7 +350,6 @@ namespace Step25
   {
     // First we assemble the Jacobian matrix $F'_h(U^{n,l})$, where $U^{n,l}$
     // is stored in the vector <code>solution</code> for convenience.
-    system_matrix = 0;
     system_matrix.copy_from (mass_matrix);
     system_matrix.add (std::pow(time_step*theta,2), laplace_matrix);
 
@@ -359,9 +358,23 @@ namespace Step25
     system_matrix.add (-std::pow(time_step*theta,2), tmp_matrix);
 
     // Then, we compute the right-hand side vector $-F_h(U^{n,l})$.
+    //
+    // We have to first build up the matrix
+    // $M+k^2\theta^2 A$, which we put into <code>tmp_matrix</code>
+    // use it to compute a contribution to the right hand side vector, and
+    // then build the matrix $M-k^2\theta(1-\theta) A$. We could
+    // build it in the same way as before, i.e., using code like
+    // @code
+    // tmp_matrix.copy_from (mass_matrix);
+    // tmp_matrix.add (-std::pow(time_step,2)*theta*(1-theta), laplace_matrix);
+    // @endcode
+    // but we can save the expense of the <code>copy_from</code> operation
+    // by starting from what is already in the <code>tmp_matrix</code>
+    // variable (i.e., $M+k^2\theta^2 A$) and subtracting from this
+    // $k^2\theta^2 A+k^2\theta(1-\theta) A=k^2\theta A$ when computing the
+    // second matrix:
     system_rhs = 0;
 
-    tmp_matrix = 0;
     tmp_matrix.copy_from (mass_matrix);
     tmp_matrix.add (std::pow(time_step*theta,2), laplace_matrix);
 
@@ -369,17 +382,14 @@ namespace Step25
     tmp_matrix.vmult (tmp_vector, solution);
     system_rhs += tmp_vector;
 
-    tmp_matrix = 0;
-    tmp_matrix.copy_from (mass_matrix);
-    tmp_matrix.add (-std::pow(time_step,2)*theta*(1-theta), laplace_matrix);
 
-    tmp_vector = 0;
+    tmp_matrix.add(-std::pow(time_step, 2) * theta, laplace_matrix);
+
     tmp_matrix.vmult (tmp_vector, old_solution);
     system_rhs -= tmp_vector;
 
     system_rhs.add (-time_step, M_x_velocity);
 
-    tmp_vector = 0;
     compute_nl_term (old_solution, solution, tmp_vector);
     system_rhs.add (std::pow(time_step,2)*theta, tmp_vector);
 
@@ -413,6 +423,7 @@ namespace Step25
                                                 const Vector<double> &new_data,
                                                 Vector<double>       &nl_term) const
   {
+    nl_term = 0;
     const QGauss<dim> quadrature_formula (3);
     FEValues<dim>     fe_values (fe, quadrature_formula,
                                  update_values |
@@ -433,6 +444,7 @@ namespace Step25
 
     for (; cell!=endc; ++cell)
       {
+        local_nl_term = 0;
         // Once we re-initialize our <code>FEValues</code> instantiation to
         // the current cell, we make use of the
         // <code>get_function_values</code> routine to get the values of the
@@ -459,8 +471,6 @@ namespace Step25
 
         for (unsigned int i=0; i<dofs_per_cell; ++i)
           nl_term(local_dof_indices[i]) += local_nl_term(i);
-
-        local_nl_term = 0;
       }
   }
 
@@ -495,6 +505,7 @@ namespace Step25
 
     for (; cell!=endc; ++cell)
       {
+        local_nl_matrix = 0;
         // Again, first we re-initialize our <code>FEValues</code>
         // instantiation to the current cell.
         fe_values.reinit (cell);
@@ -521,8 +532,6 @@ namespace Step25
           for (unsigned int j=0; j<dofs_per_cell; ++j)
             nl_matrix.add(local_dof_indices[i], local_dof_indices[j],
                           local_nl_matrix(i,j));
-
-        local_nl_matrix = 0;
       }
   }
 
@@ -562,7 +571,6 @@ namespace Step25
     PreconditionSSOR<> preconditioner;
     preconditioner.initialize(system_matrix, 1.2);
 
-    solution_update = 0;
     cg.solve (system_matrix, solution_update,
               system_rhs,
               preconditioner);
@@ -686,11 +694,9 @@ namespace Step25
         laplace_matrix.vmult (tmp_vector, solution);
         M_x_velocity.add (-time_step*theta, tmp_vector);
 
-        tmp_vector = 0;
         laplace_matrix.vmult (tmp_vector, old_solution);
         M_x_velocity.add (-time_step*(1-theta), tmp_vector);
 
-        tmp_vector = 0;
         compute_nl_term (old_solution, solution, tmp_vector);
         M_x_velocity.add (-time_step, tmp_vector);
 
index 23c2250e1e8275a1ef7d5df9bf6fcb61b3a3a760..2e16d32ad2d2fd93df4fb126aee6e6d143a68b6e 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2013
  */
 
index 4f9bc6680fb1325e92629c72b11eeec3dcfc1f49..1a4beaca1f84ff99ab0dd070fdbda588e8fc2816 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2006 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2006 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2006, 2007
  */
 
index 179a8fa239628074784bbf96dd2aa8918e4dfda9..b7076cbc86589a80f4db9354345ba70f24a2d5b6 100644 (file)
@@ -179,7 +179,7 @@ one. A stable reactor should have $k_{\mathrm{eff}}=1$.
 [For those who wonder how this can be achieved in practice without
 inadvertently getting slightly larger than one and triggering a nuclear bomb:
 first, fission processes happen on different time scales. While most neutrons
-are releases very quickly after a fission event, a small number of neutrons
+are released very quickly after a fission event, a small number of neutrons
 are only released by daughter nuclei after several further decays, up to 10-60
 seconds after the fission was initiated. If one is therefore slightly beyond
 $k_{\mathrm{eff}}=1$, one therefore has many seconds to react until all the
@@ -431,7 +431,7 @@ these three cases, as follows:
 <li> If the cell $K$ is active on mesh $g$, but not $g'$, then the
   basis functions $\varphi_{g'}^j$ are only defined either on the children
   $K_c,0\le c<2^{\texttt{dim}}$, or on children of these children if cell $K$
-  is refined more than once more on mesh $g'$.
+  is refined more than once on mesh $g'$.
 
   Let us assume for a second that $K$ is only once more refined on mesh $g'$
   than on mesh $g$. Using the fact that we use embedded finite element spaces
index 14ac1ba6be43efba83e759e62f512c7eaacdb758..f4365766fd7722059f8cfe391092857d21112685 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Yaqi Wang, Texas A&M University, 2009, 2010
  */
 
index 14a0f1000daebd386b340dce966e1462d30df6ea..6872bc4bfbeb5234b98ad3628dbc48607d5e20ba 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_UMFPACK)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_UMFPACK = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 73cd997c5eae2dec9f245168c93a404af029a7ab..03f347e791aa936d1bc9b43f7a8f3d18ddd514a3 100644 (file)
@@ -38,7 +38,7 @@ toplevel overview of this topic can be found in the @ref vector_valued module.
 The original purpose of this program is to simulate the focussing properties
 of an ultrasound wave generated by a transducer lens with variable
 geometry. Recent applications in medical imaging use ultrasound waves not only
-for imaging porposes, but also to excite certain local effects in a
+for imaging purposes, but also to excite certain local effects in a
 material, like changes in optical properties, that can then be measured by
 other imaging techniques. A vital ingredient for these methods is the ability
 to focus the intensity of the ultrasound wave in a particular part of the
@@ -180,7 +180,7 @@ of the circle with center at $(0.5, d)$ and a
 radius slightly greater than $d$; this shape should lead to a focusing of the sound
 wave at the center of the circle. Varying $d$ changes the "focus" of the lens
 and affects the spatial distribution of the intensity of $u$, where our main
-concern is how well $|u|=\sqrt{v^2+w^2}$ is.focussed. 
+concern is how well $|u|=\sqrt{v^2+w^2}$ is focussed. 
 
 In the program below, we will implement the complex-valued Helmholtz equations
 using the formulation with split real and imaginary parts. We will also
index d955cd261ea8d9f9d410dc10fe9d2827d5ef6f89..9c3360572bf6e836f3a71abf679ea5c14e691d8c 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2007 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2007 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Moritz Allmaras, Texas A&M University, 2007
  */
 
@@ -367,7 +367,7 @@ namespace Step29
                ExcDimensionMismatch (computed_quantities[i].size(), 1));
         Assert(uh[i].size() == 2, ExcDimensionMismatch (uh[i].size(), 2));
 
-        computed_quantities[i](0) = sqrt(uh[i](0)*uh[i](0) + uh[i](1)*uh[i](1));
+        computed_quantities[i](0) = std::sqrt(uh[i](0)*uh[i](0) + uh[i](1)*uh[i](1));
       }
   }
 
index 884be34c03afc1f9cce340fbf5d9e70f0fd62051..f6ab65581039ea58f8f1812190fd019af74313f5 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1999 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 1999 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Wolfgang Bangerth, 1999,
  *          Guido Kanschat, 2011
  */
index 5e50d7316a6b58a7663ed535916c208ba24c370e..bb1397c71c585986bde9a0f50ccfff7e0263224c 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2007 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2007 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Tobias Leicht, 2007
  */
 
index 645efcfc55cf185e7471ff2ed404dd1260ab4ee4..f21c9612ea4a293d036448223449114d8b6485f7 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_TRILINOS)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index e8d0062099793da92621c8a358279c48878d4ec6..0d33264c199c9c30ea3849f7e6f019ce1e9352f5 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2007 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2007 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Martin Kronbichler, Uppsala University,
  *          Wolfgang Bangerth, Texas A&M University 2007, 2008
  */
@@ -1918,133 +1918,42 @@ namespace Step31
   // This function writes the solution to a VTK output file for visualization,
   // which is done every tenth time step. This is usually quite a simple task,
   // since the deal.II library provides functions that do almost all the job
-  // for us. In this case, the situation is a bit more complicated, since we
-  // want to visualize both the Stokes solution and the temperature as one
-  // data set, but we have done all the calculations based on two different
-  // DoFHandler objects, a situation the DataOut class usually used for output
-  // is not prepared to deal with. The way we're going to achieve this
-  // recombination is to create a joint DoFHandler that collects both
-  // components, the Stokes solution and the temperature solution. This can be
-  // nicely done by combining the finite elements from the two systems to form
-  // one FESystem, and let this collective system define a new DoFHandler
-  // object. To be sure that everything was done correctly, we perform a
-  // sanity check that ensures that we got all the dofs from both Stokes and
-  // temperature even in the combined system.
-  //
-  // Next, we create a vector that will collect the actual solution
-  // values. Since this vector is only going to be used for output, we create
-  // it as a deal.II vector that nicely cooperate with the data output
-  // classes. Remember that we used Trilinos vectors for assembly and solving.
+  // for us. There is one new function compared to previous examples: We want
+  // to visualize both the Stokes solution and the temperature as one data
+  // set, but we have done all the calculations based on two different
+  // DoFHandler objects. Luckily, the DataOut class is prepared to deal with
+  // it. All we have to do is to not attach one single DoFHandler at the
+  // beginning and then use that for all added vector, but specify the
+  // DoFHandler to each vector separately. The rest is done as in step-22. We
+  // create solution names (that are going to appear in the visualization
+  // program for the individual components). The first <code>dim</code>
+  // components are the vector velocity, and then we have pressure for the
+  // Stokes part, whereas temperature is scalar. This information is read out
+  // using the DataComponentInterpretation helper class. Next, we actually
+  // attach the data vectors with their DoFHandler objects, build patches
+  // according to the degree of freedom, which are (sub-) elements that
+  // describe the data for visualization programs. Finally, we set a file name
+  // (that includes the time step number) and write the vtk file.
   template <int dim>
   void BoussinesqFlowProblem<dim>::output_results ()  const
   {
     if (timestep_number % 10 != 0)
       return;
 
-    const FESystem<dim> joint_fe (stokes_fe, 1,
-                                  temperature_fe, 1);
-    DoFHandler<dim> joint_dof_handler (triangulation);
-    joint_dof_handler.distribute_dofs (joint_fe);
-    Assert (joint_dof_handler.n_dofs() ==
-            stokes_dof_handler.n_dofs() + temperature_dof_handler.n_dofs(),
-            ExcInternalError());
-
-    Vector<double> joint_solution (joint_dof_handler.n_dofs());
-
-    // Unfortunately, there is no straight-forward relation that tells us how
-    // to sort Stokes and temperature vector into the joint vector. The way we
-    // can get around this trouble is to rely on the information collected in
-    // the FESystem. For each dof in a cell, the joint finite element knows to
-    // which equation component (velocity component, pressure, or temperature)
-    // it belongs &ndash; that's the information we need!  So we step through
-    // all cells (with iterators into all three DoFHandlers moving in synch),
-    // and for each joint cell dof, we read out that component using the
-    // FiniteElement::system_to_base_index function (see there for a
-    // description of what the various parts of its return value contain). We
-    // also need to keep track whether we're on a Stokes dof or a temperature
-    // dof, which is contained in
-    // <code>joint_fe.system_to_base_index(i).first.first</code>.  Eventually,
-    // the dof_indices data structures on either of the three systems tell us
-    // how the relation between global vector and local dofs looks like on the
-    // present cell, which concludes this tedious work.
-    //
-    // There's one thing worth remembering when looking at the output: In our
-    // algorithm, we first solve for the Stokes system at time level
-    // <i>n-1</i> in each time step and then for the temperature at time level
-    // <i>n</i> using the previously computed velocity. These are the two
-    // components we join for output, so these two parts of the output file
-    // are actually misaligned by one time step. Since we consider graphical
-    // output as only a qualititative means to understand a solution, we
-    // ignore this $\mathcal{O}(h)$ error.
-    {
-      std::vector<types::global_dof_index> local_joint_dof_indices (joint_fe.dofs_per_cell);
-      std::vector<types::global_dof_index> local_stokes_dof_indices (stokes_fe.dofs_per_cell);
-      std::vector<types::global_dof_index> local_temperature_dof_indices (temperature_fe.dofs_per_cell);
-
-      typename DoFHandler<dim>::active_cell_iterator
-      joint_cell       = joint_dof_handler.begin_active(),
-      joint_endc       = joint_dof_handler.end(),
-      stokes_cell      = stokes_dof_handler.begin_active(),
-      temperature_cell = temperature_dof_handler.begin_active();
-      for (; joint_cell!=joint_endc; ++joint_cell, ++stokes_cell, ++temperature_cell)
-        {
-          joint_cell->get_dof_indices (local_joint_dof_indices);
-          stokes_cell->get_dof_indices (local_stokes_dof_indices);
-          temperature_cell->get_dof_indices (local_temperature_dof_indices);
-
-          for (unsigned int i=0; i<joint_fe.dofs_per_cell; ++i)
-            if (joint_fe.system_to_base_index(i).first.first == 0)
-              {
-                Assert (joint_fe.system_to_base_index(i).second
-                        <
-                        local_stokes_dof_indices.size(),
-                        ExcInternalError());
-                joint_solution(local_joint_dof_indices[i])
-                  = stokes_solution(local_stokes_dof_indices[joint_fe.system_to_base_index(i).second]);
-              }
-            else
-              {
-                Assert (joint_fe.system_to_base_index(i).first.first == 1,
-                        ExcInternalError());
-                Assert (joint_fe.system_to_base_index(i).second
-                        <
-                        local_temperature_dof_indices.size(),
-                        ExcInternalError());
-                joint_solution(local_joint_dof_indices[i])
-                  = temperature_solution(local_temperature_dof_indices[joint_fe.system_to_base_index(i).second]);
-              }
-        }
-    }
-
-    // Next, we proceed as we've done in step-22. We create solution names
-    // (that are going to appear in the visualization program for the
-    // individual components), and attach the joint dof handler to a DataOut
-    // object. The first <code>dim</code> components are the vector velocity,
-    // and then we have pressure and temperature. This information is read out
-    // using the DataComponentInterpretation helper class. Next, we attach the
-    // solution values together with the names of its components to the output
-    // object, and build patches according to the degree of freedom, which are
-    // (sub-) elements that describe the data for visualization
-    // programs. Finally, we set a file name (that includes the time step
-    // number) and write the vtk file.
-    std::vector<std::string> joint_solution_names (dim, "velocity");
-    joint_solution_names.push_back ("p");
-    joint_solution_names.push_back ("T");
-
-    DataOut<dim> data_out;
-
-    data_out.attach_dof_handler (joint_dof_handler);
-
+    std::vector<std::string> stokes_names (dim, "velocity");
+    stokes_names.push_back ("p");
     std::vector<DataComponentInterpretation::DataComponentInterpretation>
-    data_component_interpretation
-    (dim+2, DataComponentInterpretation::component_is_scalar);
+    stokes_component_interpretation
+    (dim+1, DataComponentInterpretation::component_is_scalar);
     for (unsigned int i=0; i<dim; ++i)
-      data_component_interpretation[i]
+      stokes_component_interpretation[i]
         = DataComponentInterpretation::component_is_part_of_vector;
 
-    data_out.add_data_vector (joint_solution, joint_solution_names,
-                              DataOut<dim>::type_dof_data,
-                              data_component_interpretation);
+    DataOut<dim> data_out;
+    data_out.add_data_vector (stokes_dof_handler, stokes_solution,
+                              stokes_names, stokes_component_interpretation);
+    data_out.add_data_vector (temperature_dof_handler, temperature_solution,
+                              "T");
     data_out.build_patches (std::min(stokes_degree, temperature_degree));
 
     std::ostringstream filename;
index 4e68fdb21722e44b5a4b62c819f08227e3e584e3..7a72d94c82f4846785c0549d88fa967301b8590c 100644 (file)
@@ -11,9 +11,6 @@ SET(TARGET_SRC
   # You can specify additional files here!
   )
 
-# A custom command line to run the program
-SET(TARGET_RUN mpirun -np 2 ${TARGET})
-
 # Define the output that should be cleaned:
 SET(CLEAN_UP_FILES *.vtu *.pvtu *.visit)
 
@@ -43,7 +40,7 @@ Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_MPI = ON
     DEAL_II_WITH_P4EST = ON
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 1b1d71ea0e8ebeb09f759fcd1b0e2b88f913123b..0c7ccc8a8fc893ffffbbde661b5203374e801f5e 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2008 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2008 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Martin Kronbichler, Uppsala University,
  *          Wolfgang Bangerth, Texas A&M University,
  *          Timo Heister, University of Goettingen, 2008-2011
@@ -3225,14 +3225,36 @@ namespace Step32
   }
 
 
-  // The <code>output_results()</code> function does mostly what the
-  // corresponding one did in to step-31, in particular the merging data from
-  // the two DoFHandler objects (for the Stokes and the temperature parts of
-  // the problem) into one. There is one minor change: we make sure that each
-  // processor only works on the subdomain it owns locally (and not on ghost
-  // or artificial cells) when building the joint solution vector. The same
-  // will then have to be done in DataOut::build_patches(), but that function
-  // does so automatically.
+  // The <code>output_results()</code> function has a similar task to the one
+  // in step-31. However, here we are going to demonstrate a different
+  // technique on how to merge output from different DoFHandler objects. The
+  // way we're going to achieve this recombination is to create a joint
+  // DoFHandler that collects both components, the Stokes solution and the
+  // temperature solution. This can be nicely done by combining the finite
+  // elements from the two systems to form one FESystem, and let this
+  // collective system define a new DoFHandler object. To be sure that
+  // everything was done correctly, we perform a sanity check that ensures
+  // that we got all the dofs from both Stokes and temperature even in the
+  // combined system. We then combine the data vectors. Unfortunately, there
+  // is no straight-forward relation that tells us how to sort Stokes and
+  // temperature vector into the joint vector. The way we can get around this
+  // trouble is to rely on the information collected in the FESystem. For each
+  // dof on a cell, the joint finite element knows to which equation component
+  // (velocity component, pressure, or temperature) it belongs â€“ that's the
+  // information we need! So we step through all cells (with iterators into
+  // all three DoFHandlers moving in synch), and for each joint cell dof, we
+  // read out that component using the FiniteElement::system_to_base_index
+  // function (see there for a description of what the various parts of its
+  // return value contain). We also need to keep track whether we're on a
+  // Stokes dof or a temperature dof, which is contained in
+  // joint_fe.system_to_base_index(i).first.first. Eventually, the dof_indices
+  // data structures on either of the three systems tell us how the relation
+  // between global vector and local dofs looks like on the present cell,
+  // which concludes this tedious work. We make sure that each processor only
+  // works on the subdomain it owns locally (and not on ghost or artificial
+  // cells) when building the joint solution vector. The same will then have
+  // to be done in DataOut::build_patches(), but that function does so
+  // automatically.
   //
   // What we end up with is a set of patches that we can write using the
   // functions in DataOutBase in a variety of output formats. Here, we then
@@ -3306,7 +3328,8 @@ namespace Step32
                 }
           }
     }
-
+    
+    joint_solution.compress(VectorOperation::insert);
 
     IndexSet locally_relevant_joint_dofs(joint_dof_handler.n_dofs());
     DoFTools::extract_locally_relevant_dofs (joint_dof_handler, locally_relevant_joint_dofs);
index 3264dbd6c8f0793ac36eb27e6082749f3a6120d9..308db41050cd0f3132df713fe7d8bd18556d4141 100644 (file)
@@ -36,7 +36,7 @@ IF(NOT DEAL_II_WITH_TRILINOS)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 3d17389c1bea2e9968a8c4f6d7f416c257a9c50a..de464845414eabe9bf6cb416bced6a5a9cb19d00 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2007 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2007 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: David Neckels, Boulder, Colorado, 2007, 2008
  */
 
index 9f2b2ca256146959f32ff8a739cf62c628ee5747..b3b025bd9b4b5fcc6630c9bffc1d0f5569d3f184 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_FUNCTIONPARSER)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_FUNCTIONPARSER = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 9667a2dc9a3f5ea650590a83620d9b028a8accbd..7eb237953a7825a27bb9c3a7d54b9cf12a2a054b 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Luca Heltai, Cataldo Manigrasso, 2009
  */
 
index 416238fcba98ee8de6801fed4c13f3fe54b62c09..c35bddd9cf9066133c4b8101244298532c80963e 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_UMFPACK)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_UMFPACK = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 894966c8f5b4366d6f871b7a14d4061685ce4f80..6dfe49d2e7bce7a136b66761032f94cd98b6fe20 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Abner Salgado, Texas A&M University 2009
  */
 
@@ -1261,8 +1261,8 @@ namespace Step35
   // pieces of data into a single DoFHandler object, and then use that to
   // drive graphical output.
   //
-  // We will not elaborate on this process here, but rather refer to step-31
-  // and step-32, where a similar procedure is used (and is documented) to
+  // We will not elaborate on this process here, but rather refer to step-32,
+  // where a similar procedure is used (and is documented) to
   // create a joint DoFHandler object for all variables.
   //
   // Let us also note that we here compute the vorticity as a scalar quantity
index 5e72c8ca3e2f780490236c2bf3933e0b0e38b4c0..4d1eed8b193887ba01b18367ff3964c05d8df54e 100644 (file)
@@ -34,7 +34,7 @@ IF(NOT DEAL_II_WITH_PETSC OR NOT DEAL_II_WITH_SLEPC)
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_PETSC = ON
     DEAL_II_WITH_SLEPC = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 69a89c4574334ebf5b1db351ed555811d47d12fa..48d23ae0fd9dc016310447461a746baedd7a13ce 100644 (file)
@@ -72,7 +72,7 @@ eigenvalue.
 
 In order to numerically find solutions to this equation, i.e. a set of
 pairs of eigenvalues/eigenfunctions, we use the usual finite element
-approach of multiplying the equation from the left with testfunctions,
+approach of multiplying the equation from the left with test functions,
 integrating by parts, and searching for solutions in finite
 dimensional spaces by approximating $\Psi(\mathbf
 x)\approx\Psi_h(\mathbf x)=\sum_{j}\phi_j(\mathbf x)\tilde\psi_j$,
index 7c93a435c4588045b51adcdb437eb5155353fd49..13869b83ef3839e2c5c1ecc7375b0d84f0540a43 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Toby D. Young, Polish Academy of Sciences,
  *          Wolfgang Bangerth, Texas A&M University
  */
index 4b4e8f3f325378ce9311d83e7fdc1798ccbb5c13..07a25bc701387114f225065510810e8f1d1881a7 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_LAPACK)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_LAPACK = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 62c51b30acd535a7568e7c76ef866dc03828100c..8a2a17723df5e067a1f6da5735efee09bccba530 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Katharina Kormann, Martin Kronbichler, Uppsala University, 2009-2012
  */
 
index d1bcf3bc9898cbc6297320e0e50a225170a0a473..d8d17da2b294a11bb9316c4d5b9b85a8f8049212 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2010 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2010 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Andrea Bonito, Sebastian Pauletti.
  */
 
index 1067a958226ad1414fbe7571d1ff68f73316fda8..61f2eba90e32944befab669176be13b5cb9262b8 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2010 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2010 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Guido Kanschat, Texas A&M University, 2009
  */
 
index 8dc0d0a529f18391f2829a7be11a0cf8c90fd3ff..d8e92fa132a7998135773644ea453498e67578c1 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1999 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 1999 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 1999
  */
 
index ed9f3e4c1da74036fb608ffbe50f576680ef2e7e..f024774a4e6407117dc1621291668d59590d993e 100644 (file)
@@ -34,7 +34,7 @@ IF(NOT DEAL_II_WITH_PETSC OR NOT DEAL_II_WITH_P4EST)
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_PETSC = ON
     DEAL_II_WITH_P4EST = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index d50694e9f9c4122d1ee9bf6ac13c08e3b8e8d030..979f6b060bf15145961f9266eddcfb7c7d9189ec 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2009 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2009 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2009, 2010
  *         Timo Heister, University of Goettingen, 2009, 2010
  */
index c4e08a8cf36c9238e8dc80a3f9c640136be5ca33..1ecef89b0aa7b8af93a61a3a4898f38c83010361 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_TRILINOS)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 80ac9f3305ca8afcc9385ace06fcdc625c1f3d49..b177c92a209cd1b97fb74cfdbcf7ac61079f4c79 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2011 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2011 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Joerg Frohne, Texas A&M University and
  *                        University of Siegen, 2011, 2012
  *          Wolfgang Bangerth, Texas A&M University, 2012
index dc468213e4c8ab9ce85ddcd0269028dc199a515a..78a6df2f1f54c1ad3ebc5f38daee1913bdb5be37 100644 (file)
@@ -11,9 +11,6 @@ SET(TARGET_SRC
   # You can specify additional files here!
   )
 
-# A custom command line to run the program
-SET(TARGET_RUN mpirun -np 2 ${TARGET})
-
 # Define the output that should be cleaned:
 SET(CLEAN_UP_FILES *.vtu *.pvtu *.visit)
 
@@ -43,7 +40,7 @@ Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_MPI = ON
     DEAL_II_WITH_P4EST = ON
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index a6c6b1f75269582ec6922c38483eccae0e663708..7f2e577d33393ff4811dce185cf38ab4935908fe 100644 (file)
@@ -83,7 +83,7 @@ is zero with the outward normal $n$. If there is contact ($u_n = g$) the tangent
 vanishes, because we consider a frictionless situation and the normal stress is
 negative. The gap $g$ comes with the start configuration of the obstacle and the
 deformable body. We refer that you have to ensure that the obstacle does not hit
-the boundary of $\Gamma_C$ 
+the boundary of $\Gamma_C$
 
 \section{Derivation of the variational inequality}
 
@@ -227,7 +227,8 @@ Again the first case is for elastic and the second for plastic deformation.
 
 Just as in step-41 we compose a saddle point problem out of the minimisation
 problem. Again we do so to gain a formulation that allows us to solve a linear
-system of equations finally.\\
+system of equations finally.
+
 We introduce a Lagrange multiplier $\lambda$ and the convex cone $K\subset W'$,
 $W'$ dual space of the trace space $W:=\left[ H_0^{\frac{1}{2}}(\Gamma_C)
 \right]^{\textrm{dim}}$ of $V$ restricted to $\Gamma_C$, $$K:=\{\mu\in W':\mu_T = 0,\quad\langle\mu n,v\rangle_{\Gamma_C}\geq 0,\quad
@@ -236,9 +237,8 @@ of Lagrange multipliers, where $\langle\cdot,\cdot\rangle$
 denotes the duality pairing, i.e. a boundary integral, between $W'$ and $W$.
 Intuitively, $K$ is the cone of all "non-positive functions", except that $ K\subset
 \left( \left[ H_0^{\frac{1}{2}}(\Gamma_C) \right]^{\textrm{dim}} \right)' $ and
-so contains other objects besides regular functions as well. This yields:\\
+so contains other objects besides regular functions as well. This yields:
 
-\noindent
 \textit{Find $u\in V$ and $\lambda\in K$ such that}
 \begin{align*}
  \hat{a}(u,v) + b(v,\lambda) &= f(v),\quad &&v\in V\\
@@ -304,7 +304,7 @@ method for the contact. It sums up the results of the sections before and works
  $$\mathcal{F}_{k+1}:=\lbrace p\in\mathcal{S}:\Lambda^k_p +
  c\left(\left[B^TU^k\right]_p - G_p\right) \leq 0\rbrace.$$
  Projection $U^k$ so that it holds the second equation in (2)
- $$\hat U^K := P_{\mathcal{A}_{k+1}}(U^k).$$ 
+ $$\hat U^K := P_{\mathcal{A}_{k+1}}(U^k).$$
  \item[(5)] If $\mathcal{A}_{k+1} = \mathcal{A}_k$ and $\vert
  F\left(U^{k}\right) \vert < \delta$ then stop, else set $k=k+1$ and go to
  step (1).
@@ -353,7 +353,7 @@ above that we only linearize the problem. In step (2) we have to solve a linear
 criteria. $\mathcal{A}_{k+1} = \mathcal{A}_k$ makes sure that the contact zones
 are iterated out and the second ensures an accurate enough residual which means that the plastic zones are also iterated out.\\
 A similar method can also be found in Brunssen, Schmid, Schaefer, Wohlmuth: A
-fast and robust iterative solver for nonlinear contact problems using a 
+fast and robust iterative solver for nonlinear contact problems using a
 primal-dual active set strategy and algebraic multigrid, Int. J. Numer.
 Meth. Engng, 2007, 69, pp. 524-543. But in advance we apply a line search to
 obtain a more robust method regarding the start value. Solving an elastic
@@ -379,12 +379,12 @@ results it yields a quite reasonable adaptive mesh for the contact zone.
 
 This tutorial is essentailly a mixture of step-40 and step-41 but instead of
 PETSc we let the Trilinos library deal with parallelizing the linear algebra
-(like in step-32). Since we are trying to solve a similar problem like in 
+(like in step-32). Since we are trying to solve a similar problem like in
 step-41 we will use the same methods but now in parallel.
 
 Another difficulty is the handling of the different constraints from
-(the dirichlet conditons), the hanging nodes and the inequality condition that 
-arises from the contact. For this purpose we create three objects of type 
+(the dirichlet conditons), the hanging nodes and the inequality condition that
+arises from the contact. For this purpose we create three objects of type
 ConstraintMatrix.
 
 Beside the ConstitutiveLaw class there is another new class called Input. This
diff --git a/deal.II/examples/step-42/p1_adaptive.prm b/deal.II/examples/step-42/p1_adaptive.prm
new file mode 100644 (file)
index 0000000..dd5f63c
--- /dev/null
@@ -0,0 +1,25 @@
+# Listing of Parameters
+# ---------------------
+
+# polynomial degree of the FE_Q finite element space, typically 1 or 2
+set polynomial degree             = 1
+
+# number of initial global refinements before the first computation
+set number of initial refinements = 3
+
+# number of adaptive cycles to run
+set number of cycles              = 12
+
+# refinement strategy for each cycle:
+# global: one global refinement
+# percentage: fixed percentage gets refined using kelly
+# fix dofs: tries to achieve 2^initial_refinement*300 dofs after cycle 1 (only
+# use 2 cycles!). Changes the coarse mesh!
+set refinement strategy           = percentage
+
+# obstacle file to read, leave empty to use a sphere or 'obstacle_file.pbm'
+set obstacle filename             = 
+
+# directory to put output files (graphical output and benchmark statistics,
+# leave empty to put into current directory
+set output directory              = p1adaptive
diff --git a/deal.II/examples/step-42/p1_global.prm b/deal.II/examples/step-42/p1_global.prm
new file mode 100644 (file)
index 0000000..ead72fb
--- /dev/null
@@ -0,0 +1,25 @@
+# Listing of Parameters
+# ---------------------
+
+# polynomial degree of the FE_Q finite element space, typically 1 or 2
+set polynomial degree             = 1
+
+# number of initial global refinements before the first computation
+set number of initial refinements = 3
+
+# number of adaptive cycles to run
+set number of cycles              = 7
+
+# refinement strategy for each cycle:
+# global: one global refinement
+# percentage: fixed percentage gets refined using kelly
+# fix dofs: tries to achieve 2^initial_refinement*300 dofs after cycle 1 (only
+# use 2 cycles!). Changes the coarse mesh!
+set refinement strategy           = global
+
+# obstacle file to read, leave empty to use a sphere or 'obstacle_file.pbm'
+set obstacle filename             = 
+
+# directory to put output files (graphical output and benchmark statistics,
+# leave empty to put into current directory
+set output directory              = p1global
diff --git a/deal.II/examples/step-42/p2_adaptive.prm b/deal.II/examples/step-42/p2_adaptive.prm
new file mode 100644 (file)
index 0000000..3c06265
--- /dev/null
@@ -0,0 +1,25 @@
+# Listing of Parameters
+# ---------------------
+
+# polynomial degree of the FE_Q finite element space, typically 1 or 2
+set polynomial degree             = 2
+
+# number of initial global refinements before the first computation
+set number of initial refinements = 2
+
+# number of adaptive cycles to run
+set number of cycles              = 11
+
+# refinement strategy for each cycle:
+# global: one global refinement
+# percentage: fixed percentage gets refined using kelly
+# fix dofs: tries to achieve 2^initial_refinement*300 dofs after cycle 1 (only
+# use 2 cycles!). Changes the coarse mesh!
+set refinement strategy           = percentage
+
+# obstacle file to read, leave empty to use a sphere or 'obstacle_file.pbm'
+set obstacle filename             = 
+
+# directory to put output files (graphical output and benchmark statistics,
+# leave empty to put into current directory
+set output directory              = p2adaptive
diff --git a/deal.II/examples/step-42/p2_global.prm b/deal.II/examples/step-42/p2_global.prm
new file mode 100644 (file)
index 0000000..f721e41
--- /dev/null
@@ -0,0 +1,25 @@
+# Listing of Parameters
+# ---------------------
+
+# polynomial degree of the FE_Q finite element space, typically 1 or 2
+set polynomial degree             = 2
+
+# number of initial global refinements before the first computation
+set number of initial refinements = 3
+
+# number of adaptive cycles to run
+set number of cycles              = 6
+
+# refinement strategy for each cycle:
+# global: one global refinement
+# percentage: fixed percentage gets refined using kelly
+# fix dofs: tries to achieve 2^initial_refinement*300 dofs after cycle 1 (only
+# use 2 cycles!). Changes the coarse mesh!
+set refinement strategy           = global
+
+# obstacle file to read, leave empty to use a sphere or 'obstacle_file.pbm'
+set obstacle filename             = 
+
+# directory to put output files (graphical output and benchmark statistics,
+# leave empty to put into current directory
+set output directory              = p2global
index 0ac5426c5c768582322009cd90e48d0625942d31..efcdad4921e6a957744b796f023d08f6564223ba 100644 (file)
@@ -1,34 +1,37 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1999 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
- * Author: Wolfgang Bangerth, University of Heidelberg, 1999
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2012 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
+ * Authors: Joerg Frohne, Texas A&M University and
+ *                        University of Siegen, 2012, 2013
+ *          Wolfgang Bangerth, Texas A&M University, 2012, 2013
+ *          Timo Heister, Texas A&M University, 2013
  */
 
 
 // @sect3{Include files}
-
 // We are using the the same
 // include files as in step-41:
-
 #include <deal.II/grid/tria.h>
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_tools.h>
 #include <deal.II/grid/tria_accessor.h>
 #include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
 #include <deal.II/dofs/dof_accessor.h>
 #include <deal.II/dofs/dof_renumbering.h>
 #include <deal.II/fe/fe_q.h>
@@ -44,7 +47,6 @@
 #include <deal.II/lac/sparse_matrix.h>
 #include <deal.II/lac/block_sparsity_pattern.h>
 #include <deal.II/lac/solver_cg.h>
-#include <deal.II/lac/solver_gmres.h>
 #include <deal.II/lac/solver_bicgstab.h>
 #include <deal.II/lac/precondition.h>
 #include <deal.II/lac/constraint_matrix.h>
@@ -57,6 +59,7 @@
 #include <deal.II/lac/trilinos_solver.h>
 
 #include <deal.II/base/conditional_ostream.h>
+#include <deal.II/base/parameter_handler.h>
 #include <deal.II/base/utilities.h>
 #include <deal.II/base/index_set.h>
 #include <deal.II/lac/sparsity_tools.h>
@@ -65,6 +68,7 @@
 
 #include <deal.II/numerics/data_out.h>
 #include <deal.II/numerics/error_estimator.h>
+#include <deal.II/numerics/fe_field_function.h>
 #include <deal.II/distributed/solution_transfer.h>
 #include <deal.II/base/timer.h>
 #include <fstream>
 #include <list>
 #include <time.h>
 
+#include <sys/stat.h>
 
 #include <deal.II/base/logstream.h>
 
-namespace Step42
-{
-  using namespace dealii;
-
-  // @sect3{The <code>Input</code> class template}
-
-  // This class has the the only purpose
-  // to read in data from a picture file
-  // that has to be stored in pbm ascii
-  // format. This data will be bilinear
-  // interpolated and provides in this way
-  // a function which describes an obstacle.
-  //
-  // The data which we read in by the
-  // function read_obstacle () from the file
-  // "obstacle_file.pbm" will be stored
-  // in a double std::vector named
-  // obstacle_data.
-  // This vector composes the base
-  // to calculate a piecewise bilinear
-  // function as a polynomial interpolation.
-  // This will be done by obstacle_function ().
-  //
-  // In the function run () of the class
-  // PlasticityContactProblem we create
-  // an object of the class Input which will
-  // be used in the class Obstacle to
-  // supply the obstacle function in
-  // update_solution_and_constraints () of
-  // the class PlasticityContactProblem.
-
-  template <int dim>
-  class Input
-  {
-  public:
-    Input (const char *_name) :
-      name (_name),
-      mpi_communicator (MPI_COMM_WORLD),
-      pcout (std::cout,
-             (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)),
-      obstacle_data (0),
-      hx (0),
-      hy (0),
-      nx (0),
-      ny (0)
-    {
-      read_obstacle (name);
-    }
+namespace Step42 {
+using namespace dealii;
 
-    double hv (int i, int j);
+// @sect3{The <code>Input</code> class template}
 
-    double obstacle_function (double x,double y);
+// This class has the the only purpose
+// to read in data from a picture file
+// that has to be stored in pbm ascii
+// format. This data will be bilinear
+// interpolated and provides in this way
+// a function which describes an obstacle.
+//
+// The data which we read in by the
+// function read_obstacle () from the file
+// "obstacle_file.pbm" will be stored
+// in a double std::vector named
+// obstacle_data.
+// This vector composes the base
+// to calculate a piecewise bilinear
+// function as a polynomial interpolation.
+// This will be done by obstacle_function ().
+//
+// In the function run () of the class
+// PlasticityContactProblem we create
+// an object of the class Input which will
+// be used in the class Obstacle to
+// supply the obstacle function in
+// update_solution_and_constraints () of
+// the class PlasticityContactProblem.
+
+template<int dim>
+class Input {
+public:
+       Input(const char* _name) :
+                       name(_name), mpi_communicator(MPI_COMM_WORLD), pcout(std::cout,
+                                       (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)), obstacle_data(
+                                       0), hx(0), hy(0), nx(0), ny(0) {
+               read_obstacle(name);
+       }
+
+       double
+       hv(int i, int j);
+
+       double
+       obstacle_function(double x, double y);
+
+       void
+       read_obstacle(const char* name);
+
+private:
+       const char* name;
+       MPI_Comm mpi_communicator;
+       ConditionalOStream pcout;
+       std::vector<double> obstacle_data;
+       double hx, hy;
+       int nx, ny;
+};
+
+// This function is used in obstacle_function ()
+// to provide the proper value of the obstacle.
+template<int dim>
+double Input<dim>::hv(int i, int j) {
+       assert(i >= 0 && i < nx);
+       assert(j >= 0 && j < ny);
+       return obstacle_data[nx * (ny - 1 - j) + i]; // i indiziert x-werte, j indiziert y-werte
+}
 
-    void read_obstacle (const char *name);
+// obstacle_function () calculates the bilinear interpolated
+// value in the point (x,y).
+template<int dim>
+double Input<dim>::obstacle_function(double x, double y) {
+       int ix = (int) (x / hx);
+       int iy = (int) (y / hy);
+
+       if (ix < 0)
+               ix = 0;
+
+       if (iy < 0)
+               iy = 0;
+
+       if (ix >= nx - 1)
+               ix = nx - 2;
+
+       if (iy >= ny - 1)
+               iy = ny - 2;
+
+       double val = 0.0;
+       {
+               FullMatrix<double> H(4, 4);
+               Vector<double> X(4);
+               Vector<double> b(4);
+
+               double xx = 0.0;
+               double yy = 0.0;
+
+               xx = ix * hx;
+               yy = iy * hy;
+               H(0, 0) = xx;
+               H(0, 1) = yy;
+               H(0, 2) = xx * yy;
+               H(0, 3) = 1.0;
+               b(0) = hv(ix, iy);
+
+               xx = (ix + 1) * hx;
+               yy = iy * hy;
+               H(1, 0) = xx;
+               H(1, 1) = yy;
+               H(1, 2) = xx * yy;
+               H(1, 3) = 1.0;
+               b(1) = hv(ix + 1, iy);
+
+               xx = (ix + 1) * hx;
+               yy = (iy + 1) * hy;
+               H(2, 0) = xx;
+               H(2, 1) = yy;
+               H(2, 2) = xx * yy;
+               H(2, 3) = 1.0;
+               b(2) = hv(ix + 1, iy + 1);
+
+               xx = ix * hx;
+               yy = (iy + 1) * hy;
+               H(3, 0) = xx;
+               H(3, 1) = yy;
+               H(3, 2) = xx * yy;
+               H(3, 3) = 1.0;
+               b(3) = hv(ix, iy + 1);
+
+               H.gauss_jordan();
+               H.vmult(X, b);
+
+               val = X(0) * x + X(1) * y + X(2) * x * y + X(3);
+       }
+
+       return val;
+}
 
-  private:
-    const char          *name;
-    MPI_Comm             mpi_communicator;
-    ConditionalOStream   pcout;
-    std::vector<double>  obstacle_data;
-    double               hx, hy;
-    int                  nx, ny;
-  };
+// As mentioned above this function reads in the
+// obstacle datas and stores them in the std::vector
+// obstacle_data. It will be used only in run ().
+template<int dim>
+void Input<dim>::read_obstacle(const char* name) {
+       std::ifstream f(name);
 
-  // This function is used in obstacle_function ()
-  // to provide the proper value of the obstacle.
-  template <int dim>
-  double Input<dim>::hv (int i, int j)
-  {
-    assert(i>=0 && i<nx);
-    assert(j>=0 && j<ny);
-    return obstacle_data[nx*(ny-1-j)+i]; // i indiziert x-werte, j indiziert y-werte
-  }
+       std::string temp;
+       f >> temp >> nx >> ny;
+       assert(nx > 0 && ny > 0);
 
-  // obstacle_function () calculates the bilinear interpolated
-  // value in the point (x,y).
-  template <int dim>
-  double Input<dim>::obstacle_function (double x,double y)
-  {
-    int ix = (int)(x/hx);
-    int iy = (int)(y/hy);
+       for (int k = 0; k < nx * ny; k++) {
+               double val;
+               f >> val;
+               obstacle_data.push_back(val);
+       }
 
-    if (ix<0)
-      ix = 0;
+       hx = 1.0 / (nx - 1);
+       hy = 1.0 / (ny - 1);
 
-    if (iy<0)
-      iy = 0;
+       pcout << "Resolution of the scanned obstacle picture: " << nx << " x " << ny
+                       << std::endl;
+}
 
-    if (ix>=nx-1)
-      ix = nx-2;
+// @sect3{The <code>ConstitutiveLaw</code> class template}
+
+// This class provides an interface
+// for a constitutive law. In this
+// example we are using an elasto
+// plastic material behavior with linear,
+// isotropic hardening.
+// For gamma = 0 we obtain perfect elasto
+// plasticity behavior.
+template<int dim>
+class ConstitutiveLaw {
+public:
+       ConstitutiveLaw(double _E, double _nu, double _sigma_0, double _gamma,
+                       MPI_Comm _mpi_communicator, ConditionalOStream _pcout);
+
+       void
+       plast_linear_hardening(SymmetricTensor<4, dim> &stress_strain_tensor,
+                       const SymmetricTensor<2, dim> &strain_tensor,
+                       unsigned int &elast_points, unsigned int &plast_points,
+                       double &yield);
+       void
+       linearized_plast_linear_hardening(
+                       SymmetricTensor<4, dim> &stress_strain_tensor_linearized,
+                       SymmetricTensor<4, dim> &stress_strain_tensor,
+                       const SymmetricTensor<2, dim> &strain_tensor);
+       inline SymmetricTensor<2, dim>
+       get_strain(const FEValues<dim> &fe_values, const unsigned int shape_func,
+                       const unsigned int q_point) const;
+       void set_sigma_0(double sigma_hlp) {
+               sigma_0 = sigma_hlp;
+       }
+
+private:
+       SymmetricTensor<4, dim> stress_strain_tensor_mu;
+       SymmetricTensor<4, dim> stress_strain_tensor_kappa;
+       double E;
+       double nu;
+       double sigma_0;
+       double gamma;
+       double mu;
+       double kappa;
+       MPI_Comm mpi_communicator;
+       ConditionalOStream pcout;
+};
+
+// The constructor of the ConstitutiveLaw class sets the
+// required material parameter for our deformable body:
+// E -> elastic modulus
+// nu -> Passion's number
+// sigma_0 -> yield stress
+// gamma -> hardening parameter.
+// Also it supplies the stress strain tensor of forth order
+// of the volumetric and deviator part. For further details
+// see the documentation above.
+template<int dim>
+ConstitutiveLaw<dim>::ConstitutiveLaw(double _E, double _nu, double _sigma_0,
+               double _gamma, MPI_Comm _mpi_communicator, ConditionalOStream _pcout) :
+               E(_E), nu(_nu), sigma_0(_sigma_0), gamma(_gamma), mpi_communicator(
+                               _mpi_communicator), pcout(_pcout) {
+       mu = E / (2 * (1 + nu));
+       kappa = E / (3 * (1 - 2 * nu));
+       stress_strain_tensor_kappa = kappa
+                       * outer_product(unit_symmetric_tensor<dim>(),
+                                       unit_symmetric_tensor<dim>());
+       stress_strain_tensor_mu = 2 * mu
+                       * (identity_tensor<dim>()
+                                       - outer_product(unit_symmetric_tensor<dim>(),
+                                                       unit_symmetric_tensor<dim>()) / 3.0);
+}
 
-    if (iy>=ny-1)
-      iy = ny-2;
+// @sect3{ConstitutiveLaw::ConstitutiveLaw}
 
-    double val = 0.0;
-    {
-      FullMatrix<double> H(4,4);
-      Vector<double>  X(4);
-      Vector<double>  b(4);
-
-      double xx = 0.0;
-      double yy = 0.0;
-
-      xx = ix*hx;
-      yy = iy*hy;
-      H(0,0) = xx;
-      H(0,1) = yy;
-      H(0,2) = xx*yy;
-      H(0,3) = 1.0;
-      b(0)   = hv (ix, iy);
-
-      xx = (ix + 1)*hx;
-      yy = iy*hy;
-      H(1,0) = xx;
-      H(1,1) = yy;
-      H(1,2) = xx*yy;
-      H(1,3) = 1.0;
-      b(1)   = hv (ix + 1, iy);
-
-      xx = (ix + 1)*hx;
-      yy = (iy + 1)*hy;
-      H(2,0) = xx;
-      H(2,1) = yy;
-      H(2,2) = xx*yy;
-      H(2,3) = 1.0;
-      b(2)   = hv (ix + 1, iy + 1);
-
-      xx = ix*hx;
-      yy = (iy + 1)*hy;
-      H(3,0) = xx;
-      H(3,1) = yy;
-      H(3,2) = xx*yy;
-      H(3,3) = 1.0;
-      b(3)   = hv (ix, iy + 1);
-
-      H.gauss_jordan ();
-      H.vmult (X, b);
-
-      val = X(0)*x + X(1)*y + X(2)*x*y + X(3);
-    }
+// Calculates the strain for the shape functions.
+template<int dim>
+inline SymmetricTensor<2, dim> ConstitutiveLaw<dim>::get_strain(
+               const FEValues<dim> &fe_values, const unsigned int shape_func,
+               const unsigned int q_point) const {
+       const FEValuesExtractors::Vector displacement(0);
+       SymmetricTensor < 2, dim > tmp;
 
-    return val;
-  }
+       tmp = fe_values[displacement].symmetric_gradient(shape_func, q_point);
 
-  // As mentioned above this function reads in the
-  // obstacle datas and stores them in the std::vector
-  // obstacle_data. It will be used only in run ().
-  template <int dim>
-  void Input<dim>::read_obstacle (const char *name)
-  {
-    std::ifstream f(name);
+       return tmp;
+}
 
-    std::string temp;
-    f >> temp >> nx >> ny;
-    assert(nx>0 && ny>0);
+// @sect3{ConstitutiveLaw::plast_linear_hardening}
+
+// This is the implemented constitutive law. It projects the
+// deviator part of the stresses in a quadrature point back to
+// the yield stress plus the linear isotropic hardening.
+// Also we sum up the elastic and the plastic quadrature
+// points.
+template<int dim>
+void ConstitutiveLaw<dim>::plast_linear_hardening(
+               SymmetricTensor<4, dim> &stress_strain_tensor,
+               const SymmetricTensor<2, dim> &strain_tensor,
+               unsigned int &elast_points, unsigned int &plast_points, double &yield) {
+       if (dim == 3) {
+               SymmetricTensor < 2, dim > stress_tensor;
+               stress_tensor = (stress_strain_tensor_kappa + stress_strain_tensor_mu)
+                               * strain_tensor;
+
+               SymmetricTensor < 2, dim > deviator_stress_tensor = deviator(
+                               stress_tensor);
+
+               double deviator_stress_tensor_norm = deviator_stress_tensor.norm();
+
+               yield = 0;
+               stress_strain_tensor = stress_strain_tensor_mu;
+               double beta = 1.0;
+               if (deviator_stress_tensor_norm > sigma_0) {
+                       beta = sigma_0 / deviator_stress_tensor_norm;
+                       stress_strain_tensor *= (gamma + (1 - gamma) * beta);
+                       yield = 1;
+                       plast_points += 1;
+               } else
+                       elast_points += 1;
+
+               stress_strain_tensor += stress_strain_tensor_kappa;
+       }
+}
 
-    for (int k=0; k<nx*ny; k++)
-      {
-        double val;
-        f >> val;
-        obstacle_data.push_back(val);
-      }
+// @sect3{ConstitutiveLaw::linearized_plast_linear_hardening}
+
+// This function returns the linearized stress strain tensor.
+// It contains the derivative of the nonlinear constitutive law.
+template<int dim>
+void ConstitutiveLaw<dim>::linearized_plast_linear_hardening(
+               SymmetricTensor<4, dim> &stress_strain_tensor_linearized,
+               SymmetricTensor<4, dim> &stress_strain_tensor,
+               const SymmetricTensor<2, dim> &strain_tensor) {
+       if (dim == 3) {
+               SymmetricTensor < 2, dim > stress_tensor;
+               stress_tensor = (stress_strain_tensor_kappa + stress_strain_tensor_mu)
+                               * strain_tensor;
+
+               SymmetricTensor < 2, dim > deviator_stress_tensor = deviator(
+                               stress_tensor);
+
+               double deviator_stress_tensor_norm = deviator_stress_tensor.norm();
+
+               stress_strain_tensor = stress_strain_tensor_mu;
+               stress_strain_tensor_linearized = stress_strain_tensor_mu;
+               double beta = 1.0;
+               if (deviator_stress_tensor_norm > sigma_0) {
+                       beta = sigma_0 / deviator_stress_tensor_norm;
+                       stress_strain_tensor *= (gamma + (1 - gamma) * beta);
+                       stress_strain_tensor_linearized *= (gamma + (1 - gamma) * beta);
+                       deviator_stress_tensor /= deviator_stress_tensor_norm;
+                       stress_strain_tensor_linearized -= (1 - gamma) * beta * 2 * mu
+                                       * outer_product(deviator_stress_tensor,
+                                                       deviator_stress_tensor);
+               }
+
+               stress_strain_tensor += stress_strain_tensor_kappa;
+               stress_strain_tensor_linearized += stress_strain_tensor_kappa;
+       }
+}
 
-    hx = 1.0/(nx - 1);
-    hy = 1.0/(ny - 1);
+namespace EquationData {
+// It possible to apply an additional body force
+// but in here it is set to zero.
+template<int dim>
+class RightHandSide: public Function<dim> {
+public:
+       RightHandSide() :
+                       Function<dim>(dim) {
+       }
+
+       virtual double
+       value(const Point<dim> &p, const unsigned int component = 0) const;
+
+       virtual void
+       vector_value(const Point<dim> &p, Vector<double> &values) const;
+};
+
+template<int dim>
+double RightHandSide<dim>::value(const Point<dim> &p,
+               const unsigned int component) const {
+       double return_value = 0.0;
+
+       if (component == 0)
+               return_value = 0.0;
+       if (component == 1)
+               return_value = 0.0;
+       if (component == 2)
+         return_value = 0.0;//-26923.07692;
+
+       return return_value;
+}
 
-    pcout << "Resolution of the scanned obstacle picture: " << nx << " x " << ny << std::endl;
-  }
+template<int dim>
+void RightHandSide<dim>::vector_value(const Point<dim> &p,
+               Vector<double> &values) const {
+       for (unsigned int c = 0; c < this->n_components; ++c)
+               values(c) = RightHandSide<dim>::value(p, c);
+}
 
-  // @sect3{The <code>ConstitutiveLaw</code> class template}
-
-  // This class provides an interface
-  // for a constitutive law. In this
-  // example we are using an elasto
-  // plastic material behavior with linear,
-  // isotropic hardening.
-  // For gamma = 0 we obtain perfect elasto
-  // plasticity behavior.
-  template <int dim>
-  class ConstitutiveLaw
-  {
-  public:
-    ConstitutiveLaw (double _E,
-                     double _nu,
-                     double _sigma_0,
-                     double _gamma,
-                     MPI_Comm _mpi_communicator,
-                     ConditionalOStream _pcout);
-
-    void plast_linear_hardening (SymmetricTensor<4,dim>     &stress_strain_tensor,
-                                 const SymmetricTensor<2,dim> &strain_tensor,
-                                 unsigned int               &elast_points,
-                                 unsigned int               &plast_points,
-                                 double                     &yield);
-    void linearized_plast_linear_hardening (SymmetricTensor<4,dim>     &stress_strain_tensor_linearized,
-                                            SymmetricTensor<4,dim>     &stress_strain_tensor,
-                                            const SymmetricTensor<2,dim> &strain_tensor);
-    inline SymmetricTensor<2,dim> get_strain (const FEValues<dim> &fe_values,
-                                              const unsigned int  shape_func,
-                                              const unsigned int  q_point) const;
-    void set_sigma_0 (double sigma_hlp)
-    {
-      sigma_0 = sigma_hlp;
-    }
+// This function class is used to describe the prescribed displacements
+// at the boundary. But again we set this to zero.
+template<int dim>
+class BoundaryValues: public Function<dim> {
+public:
+       BoundaryValues() :
+                       Function<dim>(dim) {
+       }
+       ;
+
+       virtual double
+       value(const Point<dim> &p, const unsigned int component = 0) const;
+
+       virtual void
+       vector_value(const Point<dim> &p, Vector<double> &values) const;
+};
+
+template<int dim>
+double BoundaryValues<dim>::value(const Point<dim> &p,
+               const unsigned int component) const {
+       double return_value = 0;
+
+       if (component == 0)
+               return_value = 0.0;
+       if (component == 1)
+               return_value = 0.0;
+       if (component == 2)
+               return_value = 0.0;
+
+       return return_value;
+}
 
-  private:
-    SymmetricTensor<4,dim>  stress_strain_tensor_mu;
-    SymmetricTensor<4,dim>  stress_strain_tensor_kappa;
-    double E;
-    double nu;
-    double sigma_0;
-    double gamma;
-    double mu;
-    double kappa;
-    MPI_Comm mpi_communicator;
-    ConditionalOStream pcout;
-  };
-
-  // The constructor of the ConstitutiveLaw class sets the
-  // required material parameter for our deformable body:
-  // E -> elastic modulus
-  // nu -> Passion's number
-  // sigma_0 -> yield stress
-  // gamma -> hardening parameter.
-  // Also it supplies the stress strain tensor of forth order
-  // of the volumetric and deviator part. For further details
-  // see the documentation above.
-  template <int dim>
-  ConstitutiveLaw<dim>::ConstitutiveLaw(double _E, double _nu, double _sigma_0, double _gamma, MPI_Comm _mpi_communicator, ConditionalOStream _pcout)
-    :E (_E),
-     nu (_nu),
-     sigma_0 (_sigma_0),
-     gamma (_gamma),
-     mpi_communicator (_mpi_communicator),
-     pcout (_pcout)
-  {
-    mu = E/(2*(1+nu));
-    kappa = E/(3*(1-2*nu));
-    stress_strain_tensor_kappa = kappa*outer_product(unit_symmetric_tensor<dim>(), unit_symmetric_tensor<dim>());
-    stress_strain_tensor_mu = 2*mu*(identity_tensor<dim>() - outer_product(unit_symmetric_tensor<dim>(), unit_symmetric_tensor<dim>())/3.0);
-  }
+template<int dim>
+void BoundaryValues<dim>::vector_value(const Point<dim> &p,
+               Vector<double> &values) const {
+       for (unsigned int c = 0; c < this->n_components; ++c)
+               values(c) = BoundaryValues<dim>::value(p, c);
+}
 
-  // Calculates the strain for the shape functions.
-  template <int dim>
-  inline
-  SymmetricTensor<2,dim> ConstitutiveLaw<dim>::get_strain (const FEValues<dim> &fe_values,
-                                                           const unsigned int   shape_func,
-                                                           const unsigned int   q_point) const
-  {
-    const FEValuesExtractors::Vector displacement (0);
-    SymmetricTensor<2,dim> tmp;
+// This function is obviously implemented to
+// define the obstacle that penetrates our deformable
+// body. You can choose between two ways to define
+// your obstacle: to read it from a file or to use
+// a function (here a ball).
+// z_max_domain is the z value of the surface of the work piece  
+template<int dim>
+class Obstacle: public Function<dim> {
+public:
+       Obstacle(std_cxx1x::shared_ptr<Input<dim> > const &_input,
+                bool _use_read_obstacle, double z_max_domain) :
+                       Function<dim>(dim), input_obstacle_copy(_input), use_read_obstacle(
+                         _use_read_obstacle),
+                       z_max_domain(z_max_domain){
+       }
+
+       virtual double
+       value(const Point<dim> &p, const unsigned int component = 0) const;
+
+       virtual void
+       vector_value(const Point<dim> &p, Vector<double> &values) const;
+
+private:
+       std_cxx1x::shared_ptr<Input<dim> > const &input_obstacle_copy;
+       bool use_read_obstacle;
+    double z_max_domain;
+};
+
+template<int dim>
+double Obstacle<dim>::value(const Point<dim> &p,
+               const unsigned int component) const {
+       if (component == 0)
+         return p(0);
+       if (component == 1)
+         return p(1);
+
+       //component==2:
+       if (use_read_obstacle)
+         {
+           if (p(0) >= 0.0 && p(0) <= 1.0 && p(1) >= 0.0 && p(1) <= 1.0)
+             return z_max_domain + 0.999 - input_obstacle_copy->obstacle_function(p(0), p(1));
+           else
+             return 10000.0;
+         }
+       else
+         {
+           //sphere:
+           return -std::sqrt(
+             0.36 - (p(0) - 0.5) * (p(0) - 0.5)
+             - (p(1) - 0.5) * (p(1) - 0.5)) + z_max_domain + 0.59;
+         }
+}
 
-    tmp = fe_values[displacement].symmetric_gradient (shape_func,q_point);
+template<int dim>
+void Obstacle<dim>::vector_value(const Point<dim> &p,
+               Vector<double> &values) const {
+       for (unsigned int c = 0; c < this->n_components; ++c)
+               values(c) = Obstacle<dim>::value(p, c);
+}
+}
 
-    return tmp;
-  }
+// @sect3{The <code>PlasticityContactProblem</code> class template}
+
+// This class supplies all function
+// and variables needed to describe
+// the nonlinear contact problem. It is
+// close to step-41 but with some additional
+// features like: handling hanging nodes,
+// a newton method, using Trilinos and p4est
+// for parallel distributed computing.
+// To deal with hanging nodes makes
+// life a bit more complicated since
+// we need an other ConstraintMatrix now.
+// We create a newton method for the
+// active set method for the contact
+// situation and to handle the nonlinear
+// operator for the constitutive law.
+
+template<int dim>
+class PlasticityContactProblem {
+public:
+       PlasticityContactProblem(const ParameterHandler &prm);
+       void
+       run();
+
+       static void
+       declare(ParameterHandler &prm);
+
+private:
+       void
+       make_grid();
+       void
+       setup_system();
+       void
+       assemble_nl_system(TrilinosWrappers::MPI::Vector &u);
+       void
+       residual_nl_system(TrilinosWrappers::MPI::Vector &u);
+       void
+       assemble_mass_matrix_diagonal(TrilinosWrappers::SparseMatrix &mass_matrix);
+       void
+       update_solution_and_constraints();
+       void
+       dirichlet_constraints();
+       void
+       solve();
+       void
+       solve_newton();
+       void
+       refine_grid();
+       void
+       move_mesh(
+                       const TrilinosWrappers::MPI::Vector &_complete_displacement) const;
+       void
+       output_results(const std::string &title);
+       void
+       output_for_benchmark(const unsigned int cycle);
+
+       double to_refine_factor;
+       double to_coarsen_factor;
+       unsigned int cycle;
+
+       MPI_Comm mpi_communicator;
+
+       parallel::distributed::Triangulation<dim> triangulation;
+
+        FE_Q<dim>     u;
+       FESystem<dim> fe;
+       DoFHandler<dim> dof_handler;
+
+       std_cxx1x::shared_ptr<
+                       parallel::distributed::SolutionTransfer<dim,
+                                       TrilinosWrappers::MPI::Vector> > soltrans;
+
+       IndexSet locally_owned_dofs;
+       IndexSet locally_relevant_dofs;
+
+       unsigned int number_iterations;
+
+       ConstraintMatrix constraints;
+       ConstraintMatrix constraints_hanging_nodes;
+       ConstraintMatrix constraints_dirichlet_hanging_nodes;
+
+       TrilinosWrappers::SparseMatrix system_matrix_newton;
+
+       TrilinosWrappers::MPI::Vector solution;
+       TrilinosWrappers::MPI::Vector system_rhs_newton;
+       TrilinosWrappers::MPI::Vector system_rhs_lambda;
+       TrilinosWrappers::MPI::Vector resid_vector;
+       TrilinosWrappers::MPI::Vector diag_mass_matrix_vector;
+       Vector<float> cell_constitution;
+       IndexSet active_set;
+
+       ConditionalOStream pcout;
+
+       TrilinosWrappers::PreconditionAMG::AdditionalData additional_data;
+       TrilinosWrappers::PreconditionAMG preconditioner_u;
+
+       std_cxx1x::shared_ptr<Input<dim> > input_obstacle;
+       std_cxx1x::shared_ptr<ConstitutiveLaw<dim> > plast_lin_hard;
+
+       double sigma_0; // Yield stress
+       double gamma; // Parameter for the linear isotropic hardening
+       double e_modul; // E-Modul
+       double nu; // Poisson ratio
+
+       TimerOutput computing_timer;
+
+       unsigned int degree;
+       unsigned int n_initial_refinements;
+       struct RefinementStrategy
+       {
+         enum value
+         {
+           refine_global,
+           refine_percentage,
+           refine_fix_dofs
+         };
+       };
+       typename RefinementStrategy::value refinement_strategy;
+       unsigned int n_cycles;
+       std::string obstacle_filename;
+       std::string output_dir;
+    bool transfer_solution;
+    std::string base_mesh;
+};
+
+// @sect3{Implementation of the <code>PlasticityContactProblem</code> class}
+
+// Next for the implementation of the class
+// template that makes use of the functions
+// above. As before, we will write everything
+
+template<int dim>
+PlasticityContactProblem<dim>::PlasticityContactProblem(
+    const ParameterHandler &prm) :
+               mpi_communicator(MPI_COMM_WORLD), triangulation(mpi_communicator),
+               u(QGaussLobatto< 1 > (prm.get_integer("polynomial degree")+1)),
+               fe(u, dim),
+               dof_handler(triangulation), pcout(
+                               std::cout,
+                               (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)), sigma_0(
+                               400.0), gamma(0.01), e_modul(2.0e+5), nu(0.3), computing_timer(
+                               MPI_COMM_WORLD, pcout, TimerOutput::never,
+                               TimerOutput::wall_times) {
+       // double _E, double _nu, double _sigma_0, double _gamma
+       plast_lin_hard.reset(
+                       new ConstitutiveLaw<dim>(e_modul, nu, sigma_0, gamma,
+                                       mpi_communicator, pcout));
+
+       degree = prm.get_integer("polynomial degree");
+       n_initial_refinements = prm.get_integer("number of initial refinements");
+       std::string strat = prm.get("refinement strategy");
+       if (strat == "global")
+         refinement_strategy = RefinementStrategy::refine_global;
+       else if (strat == "percentage")
+          refinement_strategy = RefinementStrategy::refine_percentage;
+       else if (strat == "fix dofs")
+          refinement_strategy = RefinementStrategy::refine_fix_dofs;
+       else
+         throw ExcNotImplemented();
+
+       n_cycles = prm.get_integer("number of cycles");
+       obstacle_filename = prm.get("obstacle filename");
+       output_dir = prm.get("output directory");
+       if (output_dir!="" && *(output_dir.rbegin())!='/')
+         output_dir += "/";
+       mkdir(output_dir.c_str(), 0777);
+
+       transfer_solution = prm.get_bool("transfer solution");
+       base_mesh = prm.get("base mesh");
+       
+        pcout << "    Using output directory '" << output_dir << "'" << std::endl;
+        pcout << "    FE degree " << degree << std::endl;
+        pcout << "    Obstacle '" << obstacle_filename << "'" << std::endl;
+       pcout << "    transfer solution " << (transfer_solution?"true":"false") << std::endl;
+}
 
-  // This is the implemented constitutive law. It projects the
-  // deviator part of the stresses in a quadrature point back to
-  // the yield stress plus the linear isotropic hardening.
-  // Also we sum up the elastic and the plastic quadrature
-  // points.
-  template <int dim>
-  void ConstitutiveLaw<dim>::plast_linear_hardening (SymmetricTensor<4,dim>     &stress_strain_tensor,
-                                                     const SymmetricTensor<2,dim> &strain_tensor,
-                                                     unsigned int                 &elast_points,
-                                                     unsigned int               &plast_points,
-                                                     double                     &yield)
-  {
-    if (dim == 3)
-      {
-        SymmetricTensor<2,dim> stress_tensor;
-        stress_tensor = (stress_strain_tensor_kappa + stress_strain_tensor_mu)*strain_tensor;
-
-        SymmetricTensor<2,dim> deviator_stress_tensor = deviator(stress_tensor);
-
-        double deviator_stress_tensor_norm = deviator_stress_tensor.norm ();
-
-        yield = 0;
-        stress_strain_tensor = stress_strain_tensor_mu;
-        double beta = 1.0;
-        if (deviator_stress_tensor_norm > sigma_0)
-          {
-            beta = sigma_0/deviator_stress_tensor_norm;
-            stress_strain_tensor *= (gamma + (1 - gamma)*beta);
-            yield = 1;
-            plast_points += 1;
-          }
-        else
-          elast_points += 1;
+// @sect4{PlasticityContactProblem::declare}
 
-        stress_strain_tensor += stress_strain_tensor_kappa;
-      }
-  }
+template <int dim>
+void
+PlasticityContactProblem<dim>::declare(ParameterHandler &prm)
+{
+  prm.declare_entry("polynomial degree","1",Patterns::Integer(),"polynomial degree of the FE_Q finite element space, typically 1 or 2");
+  prm.declare_entry("number of initial refinements","2",Patterns::Integer(),"number of initial global refinements before the first computation");
+  prm.declare_entry("refinement strategy","percentage",Patterns::Selection("global|percentage|fix dofs"),
+      "refinement strategy for each cycle:\n"
+      " global: one global refinement\n"
+      "percentage: fixed percentage gets refined using kelly\n"
+      " fix dofs: tries to achieve 2^initial_refinement*300 dofs after cycle 1 (only use 2 cycles!). Changes the coarse mesh!");
+  prm.declare_entry("number of cycles","5",Patterns::Integer(),"number of adaptive cycles to run");
+  prm.declare_entry("obstacle filename","",Patterns::Anything(),"obstacle file to read, use 'obstacle_file.pbm' or leave empty to use a sphere");
+  prm.declare_entry("output directory","",Patterns::Anything(),"directory to put output files (graphical output and benchmark statistics), leave empty to put into current directory");
+  prm.declare_entry("transfer solution","false",Patterns::Bool(),"decide if the solution should be used as a starting guess for the finer mesh, use 0 otherwise.");
+  prm.declare_entry("base mesh","box",Patterns::Selection("box|half sphere"),
+                   "select the shape of the work piece: 'box' or 'half sphere'");
+  
+}
 
-  // This function returns the linearized stress strain tensor.
-  // It contains the derivative of the nonlinear constitutive law.
-  template <int dim>
-  void ConstitutiveLaw<dim>::linearized_plast_linear_hardening (SymmetricTensor<4,dim>     &stress_strain_tensor_linearized,
-      SymmetricTensor<4,dim>     &stress_strain_tensor,
-      const SymmetricTensor<2,dim> &strain_tensor)
+  Point<3>
+  rotate_half_sphere(const Point<3> &in)
   {
-    if (dim == 3)
-      {
-        SymmetricTensor<2,dim> stress_tensor;
-        stress_tensor = (stress_strain_tensor_kappa + stress_strain_tensor_mu)*strain_tensor;
-
-        SymmetricTensor<2,dim> deviator_stress_tensor = deviator(stress_tensor);
-
-        double deviator_stress_tensor_norm = deviator_stress_tensor.norm ();
-
-        stress_strain_tensor = stress_strain_tensor_mu;
-        stress_strain_tensor_linearized = stress_strain_tensor_mu;
-        double beta = 1.0;
-        if (deviator_stress_tensor_norm > sigma_0)
-          {
-            beta = sigma_0/deviator_stress_tensor_norm;
-            stress_strain_tensor *= (gamma + (1 - gamma)*beta);
-            stress_strain_tensor_linearized *= (gamma + (1 - gamma)*beta);
-            deviator_stress_tensor /= deviator_stress_tensor_norm;
-            stress_strain_tensor_linearized -= (1 - gamma)*beta*2*mu*outer_product(deviator_stress_tensor, deviator_stress_tensor);
-          }
-
-        stress_strain_tensor += stress_strain_tensor_kappa;
-        stress_strain_tensor_linearized += stress_strain_tensor_kappa;
-      }
+    return Point<3>(in(2), in(1), -in(0));
   }
 
-  // In this namespace we provide three functions:
-  // one for the body force, one for the boundary displacement
-  // and one for the Obstacle.
-  namespace EquationData
-  {
-    // It possible to apply an additional body force
-    // but in here it is set to zero.
-    template <int dim>
-    class RightHandSide : public Function<dim>
-    {
-    public:
-      RightHandSide () : Function<dim>(dim) {}
-
-      virtual double value (const Point<dim>   &p,
-                            const unsigned int  component = 0) const;
-
-      virtual void vector_value (const Point<dim> &p,
-                                 Vector<double>   &values) const;
-    };
+// @sect4{PlasticityContactProblem::make_grid}
+  
+template<int dim>
+void PlasticityContactProblem<dim>::make_grid() {
 
-    template <int dim>
-    double RightHandSide<dim>::value (const Point<dim> &p,
-                                      const unsigned int component) const
+  if (base_mesh == "half sphere")
     {
-      double return_value = 0.0;
-
-      if (component == 0)
-        return_value = 0.0;
-      if (component == 1)
-        return_value = 0.0;
-      if (component == 2)
-        return_value = 0.0;
-
-      return return_value;
+      Point < dim > center(0, 0, 0);
+      double radius = 0.8;
+      GridGenerator::half_hyper_ball(triangulation, center, radius);
+      GridTools::transform(&rotate_half_sphere, triangulation);
+      Point < dim > shift(0.5, 0.5, 0.5);
+      GridTools::shift(shift, triangulation);
+      static HyperBallBoundary<dim> boundary_description(Point<dim>(0.5,0.5,0.5), radius);
+      triangulation.set_boundary (0, boundary_description);
+
+      triangulation.refine_global(n_initial_refinements);
+
+      to_refine_factor = 0.3;
+      to_coarsen_factor = 0.03;
+      return;
     }
+  
+  Point < dim > p1(0, 0, 0);
+  Point < dim > p2(1.0, 1.0, 1.0);
+  unsigned int ref = n_initial_refinements;
 
-    template <int dim>
-    void RightHandSide<dim>::vector_value (const Point<dim> &p,
-                                           Vector<double>   &values) const
+  if (refinement_strategy == RefinementStrategy::refine_fix_dofs)
     {
-      for (unsigned int c=0; c<this->n_components; ++c)
-        values(c) = RightHandSide<dim>::value (p, c);
+       /**
+        * This complicated logic creates a mesh and a refinement fraction to_refine_factor,
+        * so that the resulting mesh after adaptive refinement has approximately
+        * 2^n_refinements_global*300 dofs. This allows parallel scalability tests.
+        * About 5%-10% of the cells are being adaptively refined.
+        * We start with a 3x3,4x4, or 5x5 base mesh (whichever is closed in cell
+        * count).
+        */
+       unsigned int ref = (n_initial_refinements + 1) / 3;
+       unsigned int remain = n_initial_refinements + 1 - ref * 3;
+       unsigned int rep = 3;
+       if (remain == 1)
+               rep = 4;
+       else if (remain == 2)
+               rep = 5;
+
+       unsigned int n_cells_x = (1 << ref) * rep;
+       unsigned int goal_dofs = (1 << n_initial_refinements) * 300;
+       double goal_cells = std::pow(std::pow(goal_dofs / 3.0, 1.0 / 3.0) - 1.0,
+                       3.0);
+       double n_cells = std::pow(n_cells_x, 3.0);
+       to_refine_factor = (goal_cells - n_cells) / n_cells;
+       //convert from fraction of cells to add to fraction of cells to refine:
+       to_refine_factor /= 7.0;
+       to_coarsen_factor = 0.0;
+
+       std::vector<unsigned int> repet(3);
+       repet[0] = rep;
+       repet[1] = rep;
+       repet[2] = rep;
+
+       GridGenerator::subdivided_hyper_rectangle(triangulation, repet, p1, p2);
     }
-
-    // This function class is used to describe the prescribed displacements
-    // at the boundary. But again we set this to zero.
-    template <int dim>
-    class BoundaryValues : public Function<dim>
+  else
     {
-    public:
-      BoundaryValues () : Function<dim>(dim) {};
-
-      virtual double value (const Point<dim>   &p,
-                            const unsigned int  component = 0) const;
+      GridGenerator::hyper_rectangle(triangulation, p1, p2);
+      to_refine_factor = 0.3;
+      to_coarsen_factor = 0.03;
+    }
 
-      virtual void vector_value (const Point<dim> &p,
-                                 Vector<double>   &values) const;
-    };
 
-    template <int dim>
-    double BoundaryValues<dim>::value (const Point<dim> &p,
-                                       const unsigned int component) const
-    {
-      double return_value = 0;
+       Triangulation<3>::active_cell_iterator cell = triangulation.begin_active(),
+                       endc = triangulation.end();
+
+       /* boundary_indicators:
+        _______
+        /  1    /|
+        /______ / |
+        8|       | 8|
+        |   8   | /
+        |_______|/
+        6
+        */
+
+       for (; cell != endc; ++cell)
+               for (unsigned int face = 0;
+                               face < GeometryInfo < dim > ::faces_per_cell; ++face) {
+                       if (cell->face(face)->center()[2] == p2(2))
+                               cell->face(face)->set_boundary_indicator(1);
+                       if (cell->face(face)->center()[0] == p1(0)
+                                       || cell->face(face)->center()[0] == p2(0)
+                                       || cell->face(face)->center()[1] == p1(1)
+                                       || cell->face(face)->center()[1] == p2(1))
+                               cell->face(face)->set_boundary_indicator(8);
+                       if (cell->face(face)->center()[2] == p1(2))
+                               cell->face(face)->set_boundary_indicator(6);
+               }
+
+       triangulation.refine_global(ref);
+}
 
-      if (component == 0)
-        return_value = 0.0;
-      if (component == 1)
-        return_value = 0.0;
-      if (component == 2)
-        return_value = 0.0;
+template<int dim>
+void PlasticityContactProblem<dim>::setup_system() {
+       // setup dofs
+       {
+               TimerOutput::Scope t(computing_timer, "Setup: distribute DoFs");
+               dof_handler.distribute_dofs(fe);
+
+               locally_owned_dofs = dof_handler.locally_owned_dofs();
+               locally_relevant_dofs.clear();
+               DoFTools::extract_locally_relevant_dofs(dof_handler,
+                               locally_relevant_dofs);
+       }
+
+       // setup hanging nodes and dirichlet constraints
+       {
+               TimerOutput::Scope t(computing_timer, "Setup: constraints");
+               constraints_hanging_nodes.reinit(locally_relevant_dofs);
+               DoFTools::make_hanging_node_constraints(dof_handler,
+                               constraints_hanging_nodes);
+               constraints_hanging_nodes.close();
+
+               pcout << "   Number of active cells: "
+                               << triangulation.n_global_active_cells() << std::endl
+                               << "   Number of degrees of freedom: " << dof_handler.n_dofs()
+                               << std::endl;
+
+               dirichlet_constraints();
+       }
+
+       // Initialization for matrices and vectors
+       {
+               TimerOutput::Scope t(computing_timer, "Setup: vectors");
+               solution.reinit(locally_relevant_dofs, mpi_communicator);
+               system_rhs_newton.reinit(locally_owned_dofs, mpi_communicator);
+               system_rhs_lambda.reinit(system_rhs_newton);
+               resid_vector.reinit(system_rhs_newton);
+               diag_mass_matrix_vector.reinit(system_rhs_newton);
+               cell_constitution.reinit(triangulation.n_active_cells());
+               active_set.clear();
+               active_set.set_size(locally_relevant_dofs.size());
+       }
+
+       // setup sparsity pattern
+       {
+               TimerOutput::Scope t(computing_timer, "Setup: matrix");
+               TrilinosWrappers::SparsityPattern sp(locally_owned_dofs,
+                               mpi_communicator);
+
+               DoFTools::make_sparsity_pattern(dof_handler, sp,
+                               constraints_dirichlet_hanging_nodes, false,
+                               Utilities::MPI::this_mpi_process(mpi_communicator));
+
+               sp.compress();
+
+               system_matrix_newton.reinit(sp);
+
+               // we are going to reuse the system
+               // matrix for assembling the diagonal
+               // of the mass matrix so that we do not
+               // need to allocate two sparse matrices
+               // at the same time:
+               TrilinosWrappers::SparseMatrix & mass_matrix = system_matrix_newton;
+               assemble_mass_matrix_diagonal(mass_matrix);
+               const unsigned int start = (system_rhs_newton.local_range().first),
+                               end = (system_rhs_newton.local_range().second);
+               for (unsigned int j = start; j < end; j++)
+                 diag_mass_matrix_vector(j) = mass_matrix.diag_element(j);
+
+               number_iterations = 0;
+
+               diag_mass_matrix_vector.compress(VectorOperation::insert);
+
+               // remove the mass matrix entries from the matrix:
+               mass_matrix = 0;
+       }
+}
 
-      return return_value;
-    }
+template<int dim>
+void PlasticityContactProblem<dim>::assemble_nl_system(
+               TrilinosWrappers::MPI::Vector &u) {
+       TimerOutput::Scope t(computing_timer, "Assembling");
+
+        QGauss<dim> quadrature_formula(fe.degree + 1);
+        QGauss<dim - 1> face_quadrature_formula(fe.degree + 1);
+
+       FEValues < dim
+                       > fe_values(fe, quadrature_formula,
+                                       UpdateFlags(
+                                                       update_values | update_gradients | update_q_points
+                                                                       | update_JxW_values));
+
+       FEFaceValues < dim
+                       > fe_values_face(fe, face_quadrature_formula,
+                                       update_values | update_quadrature_points
+                                                       | update_JxW_values);
+
+       const unsigned int dofs_per_cell = fe.dofs_per_cell;
+       const unsigned int n_q_points = quadrature_formula.size();
+       const unsigned int n_face_q_points = face_quadrature_formula.size();
+
+       const EquationData::RightHandSide<dim> right_hand_side;
+       std::vector < Vector<double>
+                       > right_hand_side_values(n_q_points, Vector<double>(dim));
+       std::vector < Vector<double>
+                       > right_hand_side_values_face(n_face_q_points, Vector<double>(dim));
+
+       FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
+       Vector<double> cell_rhs(dofs_per_cell);
+
+       std::vector<unsigned int> local_dof_indices(dofs_per_cell);
+
+       typename DoFHandler<dim>::active_cell_iterator cell =
+                       dof_handler.begin_active(), endc = dof_handler.end();
+
+       const FEValuesExtractors::Vector displacement(0);
+
+       const double kappa = 1.0;
+       for (; cell != endc; ++cell)
+               if (cell->is_locally_owned()) {
+                       fe_values.reinit(cell);
+                       cell_matrix = 0;
+                       cell_rhs = 0;
+
+                       right_hand_side.vector_value_list(fe_values.get_quadrature_points(),
+                                       right_hand_side_values);
+
+                       std::vector < SymmetricTensor<2, dim> > strain_tensor(n_q_points);
+                       fe_values[displacement].get_function_symmetric_gradients(u,
+                                       strain_tensor);
+
+                       for (unsigned int q_point = 0; q_point < n_q_points; ++q_point) {
+                               SymmetricTensor < 4, dim > stress_strain_tensor_linearized;
+                               SymmetricTensor < 4, dim > stress_strain_tensor;
+                               SymmetricTensor < 2, dim > stress_tensor;
+
+                               plast_lin_hard->linearized_plast_linear_hardening(
+                                               stress_strain_tensor_linearized, stress_strain_tensor,
+                                               strain_tensor[q_point]);
+
+                               for (unsigned int i = 0; i < dofs_per_cell; ++i) {
+                                       stress_tensor = stress_strain_tensor_linearized
+                                                       * plast_lin_hard->get_strain(fe_values, i, q_point);
+
+                                       for (unsigned int j = 0; j < dofs_per_cell; ++j) {
+                                               cell_matrix(i, j) += (stress_tensor
+                                                               * plast_lin_hard->get_strain(fe_values, j,
+                                                                               q_point) * fe_values.JxW(q_point));
+                                       }
+
+                                       // the linearized part a(v^i;v^i,v) of the rhs
+                                       cell_rhs(i) += (stress_tensor * strain_tensor[q_point]
+                                                       * fe_values.JxW(q_point));
+
+                                       // the residual part a(v^i;v) of the rhs
+                                       cell_rhs(i) -= (strain_tensor[q_point]
+                                                       * stress_strain_tensor
+                                                       * plast_lin_hard->get_strain(fe_values, i, q_point)
+                                                       * fe_values.JxW(q_point));
+
+                                       // the residual part F(v) of the rhs
+                                       Tensor < 1, dim > rhs_values;
+                                       rhs_values = 0;
+                                       cell_rhs(i) += (fe_values[displacement].value(i, q_point)
+                                                       * rhs_values * fe_values.JxW(q_point));
+                               }
+                       }
+
+                       for (unsigned int face = 0;
+                                       face < GeometryInfo < dim > ::faces_per_cell; ++face) {
+                               if (cell->face(face)->at_boundary()
+                                               && cell->face(face)->boundary_indicator() == 1) {
+                                       fe_values_face.reinit(cell, face);
+
+                                       right_hand_side.vector_value_list(
+                                                       fe_values_face.get_quadrature_points(),
+                                                       right_hand_side_values_face);
+
+                                       for (unsigned int q_point = 0; q_point < n_face_q_points;
+                                                       ++q_point) {
+                                               Tensor < 1, dim > rhs_values;
+                                               rhs_values[2] = right_hand_side_values[q_point][2];
+                                               for (unsigned int i = 0; i < dofs_per_cell; ++i)
+                                                       cell_rhs(i) += (fe_values_face[displacement].value(
+                                                                       i, q_point) * rhs_values
+                                                                       * fe_values_face.JxW(q_point));
+                                       }
+                               }
+                       }
+
+                       cell->get_dof_indices(local_dof_indices);
+                       constraints.distribute_local_to_global(cell_matrix, cell_rhs,
+                                       local_dof_indices, system_matrix_newton, system_rhs_newton,
+                                       true);
+
+
+               };
+
+       system_matrix_newton.compress(VectorOperation::add);
+       system_rhs_newton.compress(VectorOperation::add);
+}
 
-    template <int dim>
-    void BoundaryValues<dim>::vector_value (const Point<dim> &p,
-                                            Vector<double>   &values) const
-    {
-      for (unsigned int c=0; c<this->n_components; ++c)
-        values(c) = BoundaryValues<dim>::value (p, c);
-    }
+template<int dim>
+void PlasticityContactProblem<dim>::residual_nl_system(
+               TrilinosWrappers::MPI::Vector &u) {
+        QGauss<dim> quadrature_formula(fe.degree + 1);
+        QGauss<dim-1> face_quadrature_formula(fe.degree + 1);
+
+       FEValues < dim
+                       > fe_values(fe, quadrature_formula,
+                                       UpdateFlags(
+                                                       update_values | update_gradients | update_q_points
+                                                                       | update_JxW_values));
+
+       FEFaceValues < dim
+                       > fe_values_face(fe, face_quadrature_formula,
+                                       update_values | update_quadrature_points
+                                                       | update_JxW_values);
+
+       const unsigned int dofs_per_cell = fe.dofs_per_cell;
+       const unsigned int n_q_points = quadrature_formula.size();
+       const unsigned int n_face_q_points = face_quadrature_formula.size();
+
+       const EquationData::RightHandSide<dim> right_hand_side;
+       std::vector < Vector<double>
+                       > right_hand_side_values(n_q_points, Vector<double>(dim));
+       std::vector < Vector<double>
+                       > right_hand_side_values_face(n_face_q_points, Vector<double>(dim));
+
+       Vector<double> cell_rhs(dofs_per_cell);
+
+       std::vector<unsigned int> local_dof_indices(dofs_per_cell);
+
+       const FEValuesExtractors::Vector displacement(0);
+
+       typename DoFHandler<dim>::active_cell_iterator cell =
+                       dof_handler.begin_active(), endc = dof_handler.end();
+
+       unsigned int elast_points = 0;
+       unsigned int plast_points = 0;
+       double yield = 0;
+       unsigned int cell_number = 0;
+       cell_constitution = 0;
+
+       for (; cell != endc; ++cell)
+               if (cell->is_locally_owned()) {
+                       fe_values.reinit(cell);
+                       cell_rhs = 0;
+
+                       right_hand_side.vector_value_list(fe_values.get_quadrature_points(),
+                                       right_hand_side_values);
+
+                       std::vector < SymmetricTensor<2, dim> > strain_tensor(n_q_points);
+                       fe_values[displacement].get_function_symmetric_gradients(u,
+                                       strain_tensor);
+
+                       for (unsigned int q_point = 0; q_point < n_q_points; ++q_point) {
+                               SymmetricTensor < 4, dim > stress_strain_tensor;
+                               SymmetricTensor < 2, dim > stress_tensor;
+
+                               plast_lin_hard->plast_linear_hardening(stress_strain_tensor,
+                                               strain_tensor[q_point], elast_points, plast_points,
+                                               yield);
+
+                               cell_constitution(cell_number) += yield;
+                               for (unsigned int i = 0; i < dofs_per_cell; ++i) {
+                                       cell_rhs(i) -= (strain_tensor[q_point]
+                                                       * stress_strain_tensor
+                                                       * //(stress_tensor) *
+                                                       plast_lin_hard->get_strain(fe_values, i, q_point)
+                                                       * fe_values.JxW(q_point));
+
+                                       Tensor < 1, dim > rhs_values;
+                                       rhs_values = 0;
+                                       cell_rhs(i) += ((fe_values[displacement].value(i, q_point)
+                                                       * rhs_values) * fe_values.JxW(q_point));
+                               };
+                       };
+
+                       for (unsigned int face = 0;
+                                       face < GeometryInfo < dim > ::faces_per_cell; ++face) {
+                               if (cell->face(face)->at_boundary()
+                                               && cell->face(face)->boundary_indicator() == 1) {
+                                       fe_values_face.reinit(cell, face);
+
+                                       right_hand_side.vector_value_list(
+                                                       fe_values_face.get_quadrature_points(),
+                                                       right_hand_side_values_face);
+
+                                       for (unsigned int q_point = 0; q_point < n_face_q_points;
+                                                       ++q_point) {
+                                               Tensor < 1, dim > rhs_values;
+                                               rhs_values[2] = right_hand_side_values[q_point][2];
+                                               for (unsigned int i = 0; i < dofs_per_cell; ++i)
+                                                       cell_rhs(i) += (fe_values_face[displacement].value(
+                                                                       i, q_point) * rhs_values
+                                                                       * fe_values_face.JxW(q_point));
+                                       }
+                               }
+                       }
+
+                       cell->get_dof_indices(local_dof_indices);
+                       constraints_dirichlet_hanging_nodes.distribute_local_to_global(
+                                       cell_rhs, local_dof_indices, system_rhs_newton);
+
+                       for (unsigned int i=0; i<dofs_per_cell; i++)
+                         system_rhs_lambda(local_dof_indices[i]) += cell_rhs(i);
+
+                       cell_number += 1;
+               } else {
+                       cell_constitution(cell_number) = 0;
+                       cell_number += 1;
+               };
+
+       cell_constitution /= n_q_points;
+       cell_constitution.compress(VectorOperation::add);
+       system_rhs_newton.compress(VectorOperation::add);
+       system_rhs_lambda.compress(VectorOperation::add);
+
+//     constraints_hanging_nodes.condense(system_rhs_lambda);
+
+       unsigned int sum_elast_points = Utilities::MPI::sum(elast_points,
+                       mpi_communicator);
+       unsigned int sum_plast_points = Utilities::MPI::sum(plast_points,
+                       mpi_communicator);
+       pcout << "      Number of elastic quadrature points: " << sum_elast_points
+                       << " and plastic quadrature points: " << sum_plast_points
+                       << std::endl;
+}
 
-    // This function is obviously implemented to
-    // define the obstacle that penetrates our deformable
-    // body. You can choose between two ways to define
-    // your obstacle: to read it from a file or to use
-    // a function (here a ball).
-    template <int dim>
-    class Obstacle : public Function<dim>
-    {
-    public:
-      Obstacle (std_cxx1x::shared_ptr<Input<dim> > const &_input, bool _use_read_obstacle) :
-        Function<dim>(dim),
-        input_obstacle_copy(_input),
-        use_read_obstacle(_use_read_obstacle)
-      {}
-
-      virtual double value (const Point<dim>   &p,
-                            const unsigned int  component = 0) const;
-
-      virtual void vector_value (const Point<dim> &p,
-                                 Vector<double>   &values) const;
-
-    private:
-      std_cxx1x::shared_ptr<Input<dim> >  const &input_obstacle_copy;
-      bool                    use_read_obstacle;
-    };
-
-    template <int dim>
-    double Obstacle<dim>::value (const Point<dim> &p,
-                                 const unsigned int component) const
-    {
-      double R = 0.03;
-      double return_value = 100.0;
-      if (component == 0)
-        return_value = p(0);
-      if (component == 1)
-        return_value = p(1);
-      if (component == 2)
-        {
-          if (use_read_obstacle)
-            return_value = 1.999 - input_obstacle_copy->obstacle_function (p(0), p(1));
-          else
-            return_value = -std::sqrt (0.36 - (p(0)-0.5)*(p(0)-0.5) - (p(1)-0.5)*(p(1)-0.5)) + 1.59;
-        }
-      return return_value;
-    }
+template<int dim>
+void PlasticityContactProblem<dim>::assemble_mass_matrix_diagonal(
+               TrilinosWrappers::SparseMatrix &mass_matrix) {
+        QGaussLobatto < dim - 1 > face_quadrature_formula(fe.degree + 1);
+
+       FEFaceValues < dim
+                       > fe_values_face(fe, face_quadrature_formula,
+                                       update_values | update_quadrature_points
+                                                       | update_JxW_values);
+
+       const unsigned int dofs_per_cell = fe.dofs_per_cell;
+       const unsigned int n_face_q_points = face_quadrature_formula.size();
+
+       FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
+       Tensor<1, dim, double> ones(dim);
+       for (unsigned i = 0; i < dim; i++)
+               ones[i] = 1.0;
+
+       std::vector<unsigned int> local_dof_indices(dofs_per_cell);
+
+       const FEValuesExtractors::Vector displacement(0);
+
+       typename DoFHandler<dim>::active_cell_iterator cell =
+                       dof_handler.begin_active(), endc = dof_handler.end();
+
+       for (; cell != endc; ++cell)
+               if (cell->is_locally_owned())
+                       for (unsigned int face = 0;
+                                       face < GeometryInfo < dim > ::faces_per_cell; ++face)
+                               if (cell->face(face)->at_boundary()
+                                               && cell->face(face)->boundary_indicator() == 1) {
+                                       fe_values_face.reinit(cell, face);
+                                       cell_matrix = 0;
+
+                                       for (unsigned int q_point = 0; q_point < n_face_q_points;
+                                                       ++q_point)
+                                               for (unsigned int i = 0; i < dofs_per_cell; ++i)
+                                                       cell_matrix(i, i) +=
+                                                                       (fe_values_face[displacement].value(i,
+                                                                                       q_point) * ones
+                                                                                       * fe_values_face.JxW(q_point));
+
+                                       cell->get_dof_indices(local_dof_indices);
+
+//                                     constraints_dirichlet_hanging_nodes.distribute_local_to_global(
+//                                                     cell_matrix, local_dof_indices, mass_matrix);
+
+                                       for (unsigned int i=0; i<dofs_per_cell; i++)
+                                         mass_matrix.add (local_dof_indices[i],
+                                                          local_dof_indices[i],
+                                                          cell_matrix(i,i));
+                               }
+       mass_matrix.compress(VectorOperation::add);
+}
 
-    template <int dim>
-    void Obstacle<dim>::vector_value (const Point<dim> &p,
-                                      Vector<double> &values) const
-    {
-      for (unsigned int c=0; c<this->n_components; ++c)
-        values(c) = Obstacle<dim>::value (p, c);
-    }
-  }
+// @sect4{PlasticityContactProblem::update_solution_and_constraints}
+
+// Projection and updating of the active set
+// for the dofs which penetrates the obstacle.
+template<int dim>
+void PlasticityContactProblem<dim>::update_solution_and_constraints() {
+       const EquationData::Obstacle<dim> obstacle(input_obstacle,
+                                                  (obstacle_filename!=""),
+                                                  (base_mesh=="box"?1.0:0.5));
+       std::vector<bool> vertex_touched(dof_handler.n_dofs(), false);
+
+       typename DoFHandler<dim>::active_cell_iterator cell =
+                       dof_handler.begin_active(), endc = dof_handler.end();
+
+       TrilinosWrappers::MPI::Vector distributed_solution(system_rhs_newton);
+       distributed_solution = solution;
+       TrilinosWrappers::MPI::Vector lambda(solution);
+       lambda = resid_vector;
+       TrilinosWrappers::MPI::Vector diag_mass_matrix_vector_relevant(solution);
+       diag_mass_matrix_vector_relevant = diag_mass_matrix_vector;
+
+       constraints.reinit(locally_relevant_dofs);
+       active_set.clear();
+       IndexSet active_set_locally_owned;
+       active_set_locally_owned.set_size(locally_owned_dofs.size());
+       const double c = 100.0 * e_modul;
+
+       Quadrature<dim-1>          face_quadrature (fe.get_unit_face_support_points());
+       FEFaceValues<dim>          fe_values_face (fe, face_quadrature, update_quadrature_points);
+
+       const unsigned int         dofs_per_face = fe.dofs_per_face;
+       const unsigned int         n_face_q_points = face_quadrature.size ();
+
+       // pcout<< "dofs_per_face = " << dofs_per_face
+       //      << "n_face_q_points = " << n_face_q_points
+       //      <<std::endl;
+       unsigned int counter_hanging_nodes = 0;
+       for (; cell != endc; ++cell)
+               if (!cell->is_artificial())
+                       for (unsigned int face = 0;
+                                       face < GeometryInfo < dim > ::faces_per_cell; ++face)
+                               if (cell->face(face)->at_boundary()
+                                               && cell->face(face)->boundary_indicator() == 1)
+                                 {
+                                       fe_values_face.reinit (cell, face);
+                                       std::vector<unsigned int> dof_indices (dofs_per_face);
+                                       cell->face(face)->get_dof_indices (dof_indices);
+
+                                       for (unsigned int q_point=0; q_point<n_face_q_points; ++q_point)
+                                         {
+                                           unsigned int component =
+                                             fe.face_system_to_component_index (q_point).first;
+
+                                           if (component == 2)
+                                             {
+                                               unsigned int index_z = dof_indices[q_point];
+
+                                               if (vertex_touched[index_z] == false)
+                                                 vertex_touched[index_z] = true;
+                                               else
+                                                 continue;
+
+                                               // the local row where
+                                               Point < dim > point(fe_values_face.quadrature_point(q_point));
+
+                                               double obstacle_value = obstacle.value(point, 2);
+                                               double solution_index_z = solution(index_z);
+                                               double gap = obstacle_value - point(2);
+
+                                               if (lambda(index_z)/diag_mass_matrix_vector_relevant(index_z)
+                                                               + c * (solution_index_z - gap) > 0
+                                                               && !(constraints_hanging_nodes.is_constrained(
+                                                                               index_z))) {
+                                                       constraints.add_line(index_z);
+                                                       constraints.set_inhomogeneity(index_z, gap);
+                                                       distributed_solution(index_z) = gap;
+
+                                                       if (locally_owned_dofs.is_element(index_z)) {
+                                                               active_set_locally_owned.add_index(index_z);
+                                                               if (locally_relevant_dofs.is_element(index_z))
+                                                                       active_set.add_index(index_z);
+                                                       }
+
+                                               }
+                                               else if (lambda(index_z)/diag_mass_matrix_vector_relevant(index_z) 
+                                                        + c * (solution_index_z - gap) > 0
+                                                        && constraints_hanging_nodes.is_constrained(
+                                                                                                    index_z))
+                                                 {
+                                                   if (locally_owned_dofs.is_element(index_z))
+                                                     {
+                                                       counter_hanging_nodes += 1;
+
+//                                                     std::cout << "index_z = " << index_z
+//                                                             << ", lambda = " << lambda (index_z)
+//                                                             << ", solution_index_z - gap = " << solution_index_z - gap
+//                                                             << ", diag_mass_matrix_vector_relevant = " << diag_mass_matrix_vector_relevant (index_z)
+//                                                             << ", x = " << point(0)
+//                                                             << ", y = " << point(1)
+//                                                             << std::endl;
+                                                     }
+                                                 }
+                                           }
+                                       }
+                                 }
+       distributed_solution.compress(VectorOperation::insert);
+
+       unsigned int sum_contact_constraints = Utilities::MPI::sum(
+                       active_set_locally_owned.n_elements(), mpi_communicator);
+       pcout << "         Size of active set: " << sum_contact_constraints
+                       << std::endl;
+       unsigned int sum_contact_hanging_nodes = Utilities::MPI::sum(
+                       counter_hanging_nodes, mpi_communicator);
+       pcout << "         Number of hanging nodes in contact: " << sum_contact_hanging_nodes
+                       << std::endl;
+
+       solution = distributed_solution;
+
+       constraints.close();
+
+ //    constraints_dirichlet_hanging_nodes.print (std::cout);
+
+       constraints.merge(constraints_dirichlet_hanging_nodes);
+
+       //constraints.print (std::cout);
+}
 
-  // @sect3{The <code>PlasticityContactProblem</code> class template}
-
-  // This class supplies all function
-  // and variables needed to describe
-  // the nonlinear contact problem. It is
-  // close to step-41 but with some additional
-  // features like: handling hanging nodes,
-  // a Newton method, using Trilinos and p4est
-  // for parallel distributed computing.
-  // To deal with hanging nodes makes
-  // life a bit more complicated since
-  // we need an other ConstraintMatrix now.
-  // We create a Newton method for the
-  // active set method for the contact
-  // situation and to handle the nonlinear
-  // operator for the constitutive law.
-
-  template <int dim>
-  class PlasticityContactProblem
-  {
-  public:
-    PlasticityContactProblem (int _n_refinements_global);
-    void run ();
-
-  private:
-    void make_grid ();
-    void setup_system();
-    void assemble_nl_system (TrilinosWrappers::MPI::Vector &u);
-    void residual_nl_system (TrilinosWrappers::MPI::Vector &u);
-    void assemble_mass_matrix_diagonal (TrilinosWrappers::SparseMatrix &mass_matrix);
-    void update_solution_and_constraints ();
-    void dirichlet_constraints ();
-    void solve ();
-    void solve_newton ();
-    void refine_grid ();
-    void move_mesh (const TrilinosWrappers::MPI::Vector &_complete_displacement) const;
-    void output_results (const std::string &title) const;
-
-    unsigned int         n_refinements_global;
-    unsigned int         cycle;
-    bool                 use_read_obstacle;
-
-    MPI_Comm             mpi_communicator;
-
-    parallel::distributed::Triangulation<dim>   triangulation;
-
-    FESystem<dim>        fe;
-    DoFHandler<dim>      dof_handler;
-
-    std_cxx1x::shared_ptr<parallel::distributed::SolutionTransfer<dim, TrilinosWrappers::MPI::Vector> > soltrans;
-
-    IndexSet             locally_owned_dofs;
-    IndexSet             locally_relevant_dofs;
-
-    unsigned int         number_iterations;
-
-    ConstraintMatrix     constraints;
-    ConstraintMatrix     constraints_hanging_nodes;
-    ConstraintMatrix     constraints_dirichlet_hanging_nodes;
-
-    TrilinosWrappers::SparseMatrix system_matrix_newton;
-
-    TrilinosWrappers::MPI::Vector       solution;
-    TrilinosWrappers::MPI::Vector       system_rhs_newton;
-    TrilinosWrappers::MPI::Vector       resid_vector;
-    TrilinosWrappers::MPI::Vector       diag_mass_matrix_vector;
-    Vector<float>                       cell_constitution;
-    IndexSet                            active_set;
-
-    ConditionalOStream pcout;
-
-    TrilinosWrappers::PreconditionAMG::AdditionalData additional_data;
-    TrilinosWrappers::PreconditionAMG preconditioner_u;
-
-    std_cxx1x::shared_ptr<Input<dim> >               input_obstacle;
-    std_cxx1x::shared_ptr<ConstitutiveLaw<dim> >     plast_lin_hard;
-
-    double sigma_0;    // Yield stress
-    double gamma;      // Parameter for the linear isotropic hardening
-    double e_modul;    // E-Modul
-    double nu;         // Poisson ratio
-
-    TimerOutput          computing_timer;
-  };
-
-  // @sect3{Implementation of the <code>PlasticityContactProblem</code> class}
-
-  // Next for the implementation of the class
-  // template that makes use of the functions
-  // above. As before, we will write everything
-
-  template <int dim>
-  PlasticityContactProblem<dim>::PlasticityContactProblem (int _n_refinements_global)
-    :
-    n_refinements_global (_n_refinements_global),
-    mpi_communicator (MPI_COMM_WORLD),
-    triangulation (mpi_communicator),
-    fe (FE_Q<dim>(1), dim),
-    dof_handler (triangulation),
-    pcout (std::cout,
-           (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)),
-    sigma_0 (400),
-    gamma (0.01),
-    e_modul (2.0e+5),
-    nu (0.3),
-    computing_timer (MPI_COMM_WORLD,
-                     pcout,
-                     TimerOutput::never,
-                     TimerOutput::wall_times)
-  {
-    plast_lin_hard.reset (new ConstitutiveLaw<dim> (e_modul, nu, sigma_0, gamma, mpi_communicator, pcout));
-  }
+// @sect4{PlasticityContactProblem::dirichlet_constraints}
+
+// This function defines the new ConstraintMatrix
+// constraints_dirichlet_hanging_nodes. It contains
+// the dirichlet boundary values as well as the
+// hanging nodes constraints.
+template<int dim>
+void PlasticityContactProblem<dim>::dirichlet_constraints() {
+       /* boundary_indicators:
+        _______
+        /  1    /|
+        /______ / |
+        8|       | 8|
+        |   8   | /
+        |_______|/
+        6
+        */
+
+       constraints_dirichlet_hanging_nodes.reinit(locally_relevant_dofs);
+       constraints_dirichlet_hanging_nodes.merge(constraints_hanging_nodes);
+
+       // interpolate all components of the solution
+       VectorTools::interpolate_boundary_values(dof_handler, base_mesh=="box"?6:0,
+                       EquationData::BoundaryValues<dim>(),
+                       constraints_dirichlet_hanging_nodes, ComponentMask());
+
+       // interpolate x- and y-components of the
+       // solution (this is a bit mask, so apply
+       // operator| )
+       FEValuesExtractors::Scalar x_displacement(0);
+       FEValuesExtractors::Scalar y_displacement(1);
+       VectorTools::interpolate_boundary_values(dof_handler, 8,
+                       EquationData::BoundaryValues<dim>(),
+                       constraints_dirichlet_hanging_nodes,
+                       (fe.component_mask(x_displacement)
+                                       | fe.component_mask(y_displacement)));
+       constraints_dirichlet_hanging_nodes.close();
+}
 
-  template <int dim>
-  void PlasticityContactProblem<dim>::make_grid ()
-  {
-    std::vector<unsigned int> repet(3);
-    repet[0] = 1;
-    repet[1] = 1;
-    repet[2] = 1;
-
-    Point<dim> p1 (0,0,0);
-    Point<dim> p2 (1.0, 1.0, 1.0);
-    GridGenerator::subdivided_hyper_rectangle (triangulation, repet, p1, p2);
-
-    Triangulation<3>::active_cell_iterator
-    cell = triangulation.begin_active(),
-    endc = triangulation.end();
-
-    /* boundary_indicators:
-              _______
-             /  9    /|
-            /______ / |
-          8|       | 8|
-           |   8   | /
-           |_______|/
-               6
-     */
-
-    for (; cell!=endc; ++cell)
-      for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-        {
-          if (cell->face (face)->center ()[2] == p2(2))
-            cell->face (face)->set_boundary_indicator (9);
-          if (cell->face (face)->center ()[0] == p1(0) ||
-              cell->face (face)->center ()[0] == p2(0) ||
-              cell->face (face)->center ()[1] == p1(1) ||
-              cell->face (face)->center ()[1] == p2(1))
-            cell->face (face)->set_boundary_indicator (8);
-          if (cell->face (face)->center ()[2] == p1(2))
-            cell->face (face)->set_boundary_indicator (6);
-        }
-
-    triangulation.refine_global (n_refinements_global);
-  }
+// @sect4{PlasticityContactProblem::solve}
 
-  // In following function we setup the degrees of freedom before each refinement
-  // cycle. Except that we are using Trilinos here instead of PETSc most of it
-  // is similar to step-40.
+// In addition to step-41 we have
+// to deal with the hanging node
+// constraints. Again we also consider
+// the locally_owned_dofs only by
+// creating the vector distributed_solution.
+//
+// For the hanging nodes we have to apply
+// the set_zero function to system_rhs_newton.
+// This is necessary if a hanging node value x_0
+// has one neighbor which is in contact with
+// value x_0 and one neighbor which is not with
+// value x_1. This leads to an inhomogeneity
+// constraint with value x_1/2 = gap/2 in the
+// ConstraintMatrix.
+// So the corresponding entries in the
+// ride-hang-side are non-zero with a
+// meaningless value. These values have to
+// to set to zero.
+
+// The rest of the function is similar to
+// step-41 except that we use a FGMRES-solver
+// instead of CG. For a very small hardening
+// value gamma the linear system becomes
+// almost semi definite but still symmetric.
+template<int dim>
+void PlasticityContactProblem<dim>::solve() {
+       TimerOutput::Scope t(computing_timer, "Solve");
+
+       TrilinosWrappers::MPI::Vector distributed_solution(system_rhs_newton);
+       distributed_solution = solution;
+
+       constraints_hanging_nodes.set_zero(distributed_solution);
+       constraints_hanging_nodes.set_zero(system_rhs_newton);
+       distributed_solution.compress(VectorOperation::insert);
+       system_rhs_newton.compress(VectorOperation::insert);
+
+       {
+               TimerOutput::Scope t(computing_timer, "Solve: setup preconditioner");
+               preconditioner_u.initialize(system_matrix_newton, additional_data);
+       }
+
+       {
+               TimerOutput::Scope t(computing_timer, "Solve: iterate");
+
+               PrimitiveVectorMemory < TrilinosWrappers::MPI::Vector > mem;
+               TrilinosWrappers::MPI::Vector tmp(system_rhs_newton);
+               // 1e-4 seems to be the fasted option altogether, but to get more
+               // reproducible parallel benchmark results, we use a small residual:
+               double relative_accuracy = 1e-8;
+               if (output_dir.compare("its/") == 0)
+                 relative_accuracy = 1e-4;
+
+               const double solver_tolerance = relative_accuracy
+                 * system_matrix_newton.residual(tmp, distributed_solution,
+                                                 system_rhs_newton);
+
+               SolverControl solver_control(system_matrix_newton.m(),
+                               solver_tolerance);
+               SolverBicgstab < TrilinosWrappers::MPI::Vector
+                               > solver(solver_control, mem/*,
+                                SolverFGMRES<TrilinosWrappers::MPI::Vector>::
+                                AdditionalData(30, true)*/);
+               solver.solve(system_matrix_newton, distributed_solution,
+                               system_rhs_newton, preconditioner_u);
+
+               pcout << "         Error: " << solver_control.initial_value() << " -> "
+                               << solver_control.last_value() << " in "
+                               << solver_control.last_step() << " Bicgstab iterations."
+                               << std::endl;
+
+               number_iterations += solver_control.last_step();
+       }
+
+       constraints.distribute(distributed_solution);
+
+       solution = distributed_solution;
+}
 
-  // We are using TimerOutput to control the scaling for the distributing the dofs
-  // and setting of the sparsity pattern and the system matrix.
-  template <int dim>
-  void PlasticityContactProblem<dim>::setup_system ()
-  {
-    {
-      computing_timer.enter_section("Setup: distribute DoFs");
-      dof_handler.distribute_dofs (fe);
-
-      locally_owned_dofs = dof_handler.locally_owned_dofs ();
-      locally_relevant_dofs.clear();
-      DoFTools::extract_locally_relevant_dofs (dof_handler,
-                                               locally_relevant_dofs);
-      computing_timer.exit_section("Setup: distribute DoFs");
-    }
+// @sect4{PlasticityContactProblem::solve_newton}
+
+// In this function the damped Newton method is implemented.
+// That means two nested loops: the outer loop for the newton
+// iteration and the inner loop for the damping steps which
+// will be used only if necessary. To obtain a good and reasonable
+// starting value we solve an elastic problem in very first step (j=1).
+template<int dim>
+void PlasticityContactProblem<dim>::solve_newton() {
+       TimerOutput::Scope t(computing_timer, "solve newton setup");
+
+       double resid = 0;
+       double resid_old = 100000;
+       TrilinosWrappers::MPI::Vector old_solution(system_rhs_newton);
+       TrilinosWrappers::MPI::Vector res(system_rhs_newton);
+       TrilinosWrappers::MPI::Vector tmp_vector(system_rhs_newton);
+
+       std::vector < std::vector<bool> > constant_modes;
+       DoFTools::extract_constant_modes(dof_handler, ComponentMask(),
+                       constant_modes);
+
+       double sigma_hlp = sigma_0;
+
+       additional_data.constant_modes = constant_modes;
+       additional_data.elliptic = true;
+       additional_data.n_cycles = 1;
+       additional_data.w_cycle = false;
+       additional_data.output_details = false;
+       additional_data.smoother_sweeps = 2;
+       additional_data.aggregation_threshold = 1e-2;
+
+       IndexSet active_set_old(active_set);
+
+       t.stop(); // stop newton setup timer
+
+       unsigned int j = 1;
+       unsigned int number_assemble_system = 0;
+       for (; j <= 100; j++) {
+         if (transfer_solution)
+           {
+             if (transfer_solution && j == 1 && cycle == 0)
+               plast_lin_hard->set_sigma_0(1e+10);
+             else if (transfer_solution && (j == 2 || cycle > 0))
+               plast_lin_hard->set_sigma_0(sigma_hlp);
+           }
+         else
+           {
+             if (j == 1)
+               plast_lin_hard->set_sigma_0(1e+10);
+             else
+               plast_lin_hard->set_sigma_0(sigma_hlp);
+           }
+
+               pcout << " " << std::endl;
+               pcout << "   Newton iteration " << j << std::endl;
+               pcout << "      Updating active set..." << std::endl;
+
+               {
+                       TimerOutput::Scope t(computing_timer, "update active set");
+                       update_solution_and_constraints();
+               }
+
+               pcout << "      Assembling system... " << std::endl;
+               system_matrix_newton = 0;
+               system_rhs_newton = 0;
+               assemble_nl_system(solution); //compute Newton-Matrix
+
+               number_assemble_system += 1;
+
+               pcout << "      Solving system... " << std::endl;
+               solve();
+
+               TrilinosWrappers::MPI::Vector distributed_solution(system_rhs_newton);
+               distributed_solution = solution;
+
+               // We handle a highly nonlinear problem so we have to damp
+               // the Newtons method. We refer that we iterate the new solution
+               // in each Newton step and not only the solution update.
+               // Since the solution set is a convex set and not a space we
+               // compute for the damping a linear combination of the
+               // previous and the current solution to guarantee that the
+               // damped solution is in our solution set again.
+               // At most we apply 10 damping steps.
+               bool damped = false;
+               tmp_vector = old_solution;
+               double a = 0;
+               for (unsigned int i = 0; (i < 5) && (!damped); i++) {
+                       a = std::pow(0.5, static_cast<double>(i));
+                       old_solution = tmp_vector;
+                       old_solution.sadd(1 - a, a, distributed_solution);
+                       old_solution.compress(VectorOperation::add);
+
+                       TimerOutput::Scope t(computing_timer, "Residual and lambda");
+
+                       system_rhs_newton = 0;
+                       system_rhs_lambda = 0;
+
+                       solution = old_solution;
+                       residual_nl_system(solution);
+                       res = system_rhs_newton;
+
+                       const unsigned int start_res = (res.local_range().first), end_res =
+                                       (res.local_range().second);
+                       for (unsigned int n = start_res; n < end_res; ++n)
+                               if (constraints.is_inhomogeneously_constrained(n))
+                                       res(n) = 0;
+
+                       res.compress(VectorOperation::insert);
+
+                       resid = res.l2_norm();
+
+                       if (resid < resid_old)
+                               damped = true;
+
+                       pcout << "      Residual of the non-contact part of the system: "
+                                       << resid << std::endl
+                                       << "         with a damping parameter alpha = " << a
+                                       << std::endl;
+
+                       // The previous iteration of step 0 is the solution of an elastic problem.
+                       // So a linear combination of a plastic and an elastic solution makes no sense
+                       // since the elastic solution is not in the convex set of the plastic solution.
+                       if (!transfer_solution && j == 2)
+                               break;
+                       if (transfer_solution && j == 2 && cycle == 0)
+                               break;
+               }
+
+               resid_old = resid;
+
+               resid_vector = system_rhs_lambda;
+               resid_vector.compress(VectorOperation::insert);
+
+               int is_my_set_changed = (active_set == active_set_old) ? 0 : 1;
+               int num_changed = Utilities::MPI::sum(is_my_set_changed,
+                               MPI_COMM_WORLD);
+               if (num_changed == 0)
+                 {
+                   pcout<< "      Active set did not change!" <<std::endl;
+                   if (output_dir.compare("its/") != 0 && resid < 1e-7)
+                     break;
+                   else if (output_dir.compare("its/") == 0 && resid < 1e-10)
+                     break;
+                 }
+               active_set_old = active_set;
+       }
+
+       pcout << "" << std::endl << "      Number of assembled systems = "
+                       << number_assemble_system << std::endl
+                       << "      Number of Solver-Iterations = " << number_iterations
+                       << std::endl;
+}
 
-    // Setup of the hanging nodes and the Dirichlet constraints.
-    {
-      constraints_hanging_nodes.clear ();
-      constraints_hanging_nodes.reinit (locally_relevant_dofs);
-      DoFTools::make_hanging_node_constraints (dof_handler,
-                                               constraints_hanging_nodes);
-      constraints_hanging_nodes.close ();
-
-      pcout << "   Number of active cells: "
-            << triangulation.n_global_active_cells()
-            << std::endl
-            << "   Number of degrees of freedom: "
-            << dof_handler.n_dofs ()
-            << std::endl;
-
-      dirichlet_constraints ();
-    }
+// @sect3{The <code>refine_grid</code> function}
 
-    // Initialization for matrices and vectors.
+template<int dim>
+void PlasticityContactProblem<dim>::refine_grid() {
+  if (refinement_strategy == RefinementStrategy::refine_global)
     {
-      solution.reinit (locally_relevant_dofs, mpi_communicator);
-      system_rhs_newton.reinit (locally_owned_dofs, mpi_communicator);
-      resid_vector.reinit (system_rhs_newton);
-      diag_mass_matrix_vector.reinit (system_rhs_newton);
-      cell_constitution.reinit (triangulation.n_active_cells ());
-      active_set.clear ();
-      active_set.set_size (locally_relevant_dofs.size ());
+      triangulation.refine_global(1);
     }
-
-    // Here we setup sparsity pattern.
+  else
     {
-      computing_timer.enter_section("Setup: matrix");
-      TrilinosWrappers::SparsityPattern sp (locally_owned_dofs,
-                                            mpi_communicator);
+       Vector<float> estimated_error_per_cell(triangulation.n_active_cells());
+       KellyErrorEstimator < dim
+                             > ::estimate(dof_handler, QGauss < dim - 1 > (fe.degree + 2),
+                                       typename FunctionMap<dim>::type(), solution,
+                                       estimated_error_per_cell);
 
-      DoFTools::make_sparsity_pattern (dof_handler, sp, constraints_dirichlet_hanging_nodes, false,
-                                       Utilities::MPI::this_mpi_process(mpi_communicator));
+       parallel::distributed::GridRefinement::refine_and_coarsen_fixed_number(
+                       triangulation, estimated_error_per_cell, 0.3, 0.03);
 
-      sp.compress();
+       triangulation.prepare_coarsening_and_refinement();
+       if (transfer_solution)
+         soltrans->prepare_for_coarsening_and_refinement(solution);
 
-      system_matrix_newton.reinit (sp);
-
-      // we are going to reuse the system
-      // matrix for assembling the diagonal
-      // of the mass matrix so that we do not
-      // need to allocate two sparse matrices
-      // at the same time:
-      TrilinosWrappers::SparseMatrix &mass_matrix = system_matrix_newton;
-      assemble_mass_matrix_diagonal (mass_matrix);
-      const unsigned int
-      start = (system_rhs_newton.local_range().first),
-      end   = (system_rhs_newton.local_range().second);
-      for (unsigned int j=start; j<end; j++)
-        diag_mass_matrix_vector (j) = mass_matrix.diag_element (j);
-      number_iterations = 0;
-
-      diag_mass_matrix_vector.compress (VectorOperation::insert);
-
-      // remove the mass matrix entries from the matrix:
-      mass_matrix = 0;
-
-      computing_timer.exit_section("Setup: matrix");
+       triangulation.execute_coarsening_and_refinement();
     }
-  }
-
-  template <int dim>
-  void PlasticityContactProblem<dim>::assemble_nl_system (TrilinosWrappers::MPI::Vector &u)
-  {
-    computing_timer.enter_section("Assembling");
-
-    QGauss<dim>  quadrature_formula(2);
-    QGauss<dim-1>  face_quadrature_formula(2);
-
-    FEValues<dim> fe_values (fe, quadrature_formula,
-                             UpdateFlags(update_values    |
-                                         update_gradients |
-                                         update_q_points  |
-                                         update_JxW_values));
-
-    FEFaceValues<dim> fe_values_face (fe, face_quadrature_formula,
-                                      update_values   | update_quadrature_points |
-                                      update_JxW_values);
-
-    const unsigned int   dofs_per_cell = fe.dofs_per_cell;
-    const unsigned int   n_q_points    = quadrature_formula.size ();
-    const unsigned int   n_face_q_points = face_quadrature_formula.size();
-
-    const EquationData::RightHandSide<dim> right_hand_side;
-    std::vector<Vector<double> > right_hand_side_values (n_q_points,
-                                                         Vector<double>(dim));
-    std::vector<Vector<double> > right_hand_side_values_face (n_face_q_points,
-                                                              Vector<double>(dim));
-
-    FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
-    Vector<double>       cell_rhs (dofs_per_cell);
-
-    std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
-
-    typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
-                                                   endc = dof_handler.end();
-
-    const FEValuesExtractors::Vector displacement (0);
-
-    const double kappa = 1.0;
-    for (; cell!=endc; ++cell)
-      if (cell->is_locally_owned())
-        {
-          fe_values.reinit (cell);
-          cell_matrix = 0;
-          cell_rhs = 0;
-
-          right_hand_side.vector_value_list (fe_values.get_quadrature_points(),
-                                             right_hand_side_values);
-
-          std::vector<SymmetricTensor<2,dim> > strain_tensor (n_q_points);
-          fe_values[displacement].get_function_symmetric_gradients (u, strain_tensor);
-
-          for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
-            {
-              SymmetricTensor<4,dim> stress_strain_tensor_linearized;
-              SymmetricTensor<4,dim> stress_strain_tensor;
-              SymmetricTensor<2,dim> stress_tensor;
-
-              plast_lin_hard->linearized_plast_linear_hardening (stress_strain_tensor_linearized,
-                                                                 stress_strain_tensor,
-                                                                 strain_tensor[q_point]);
-
-              for (unsigned int i=0; i<dofs_per_cell; ++i)
-                {
-                  stress_tensor = stress_strain_tensor_linearized * plast_lin_hard->get_strain(fe_values, i, q_point);
-
-                  for (unsigned int j=0; j<dofs_per_cell; ++j)
-                    {
-                      cell_matrix(i,j) += (stress_tensor *
-                                           plast_lin_hard->get_strain(fe_values, j, q_point) *
-                                           fe_values.JxW (q_point));
-                    }
-
-                  // the linearized part a(v^i;v^i,v) of the rhs
-                  cell_rhs(i) += (stress_tensor *
-                                  strain_tensor[q_point] *
-                                  fe_values.JxW (q_point));
-
-                  // the residual part a(v^i;v) of the rhs
-                  cell_rhs(i) -= (strain_tensor[q_point] * stress_strain_tensor *
-                                  plast_lin_hard->get_strain(fe_values, i, q_point) *
-                                  fe_values.JxW (q_point));
-
-                  // the residual part F(v) of the rhs
-                  Tensor<1,dim> rhs_values;
-                  rhs_values = 0;
-                  cell_rhs(i) += (fe_values[displacement].value (i, q_point) *
-                                  rhs_values *
-                                  fe_values.JxW (q_point));
-                }
-            }
-
-          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-            {
-              if (cell->face (face)->at_boundary()
-                  && cell->face (face)->boundary_indicator () == 9)
-                {
-                  fe_values_face.reinit (cell, face);
-
-                  right_hand_side.vector_value_list (fe_values_face.get_quadrature_points(),
-                                                     right_hand_side_values_face);
-
-                  for (unsigned int q_point=0; q_point<n_face_q_points; ++q_point)
-                    {
-                      Tensor<1,dim> rhs_values;
-                      rhs_values = 0;
-                      for (unsigned int i=0; i<dofs_per_cell; ++i)
-                        cell_rhs(i) += (fe_values_face[displacement].value (i, q_point) *
-                                        rhs_values *
-                                        fe_values_face.JxW (q_point));
-                    }
-                }
-            }
-
-          cell->get_dof_indices (local_dof_indices);
-          constraints.distribute_local_to_global (cell_matrix, cell_rhs,
-                                                  local_dof_indices,
-                                                  system_matrix_newton, system_rhs_newton, true);
-        };
-
-    system_matrix_newton.compress (VectorOperation::add);
-    system_rhs_newton.compress (VectorOperation::add);
-
-    computing_timer.exit_section("Assembling");
-  }
-
-  template <int dim>
-  void PlasticityContactProblem<dim>::residual_nl_system (TrilinosWrappers::MPI::Vector &u)
-  {
-    QGauss<dim>  quadrature_formula(2);
-    QGauss<dim-1> face_quadrature_formula(2);
-
-    FEValues<dim> fe_values (fe, quadrature_formula,
-                             UpdateFlags(update_values    |
-                                         update_gradients |
-                                         update_q_points  |
-                                         update_JxW_values));
-
-    FEFaceValues<dim> fe_values_face (fe, face_quadrature_formula,
-                                      update_values   | update_quadrature_points |
-                                      update_JxW_values);
-
-    const unsigned int   dofs_per_cell = fe.dofs_per_cell;
-    const unsigned int   n_q_points    = quadrature_formula.size ();
-    const unsigned int   n_face_q_points = face_quadrature_formula.size();
-
-    const EquationData::RightHandSide<dim> right_hand_side;
-    std::vector<Vector<double> > right_hand_side_values (n_q_points,
-                                                         Vector<double>(dim));
-    std::vector<Vector<double> > right_hand_side_values_face (n_face_q_points,
-                                                              Vector<double>(dim));
-
-    Vector<double>       cell_rhs (dofs_per_cell);
-
-    std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
-
-    const FEValuesExtractors::Vector displacement (0);
-
-    typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
-                                                   endc = dof_handler.end();
-
-    unsigned int elast_points = 0;
-    unsigned int plast_points = 0;
-    double       yield = 0;
-    unsigned int cell_number = 0;
-    cell_constitution = 0;
-
-    for (; cell!=endc; ++cell)
-      if (cell->is_locally_owned())
-        {
-          fe_values.reinit (cell);
-          cell_rhs = 0;
-
-          right_hand_side.vector_value_list (fe_values.get_quadrature_points(),
-                                             right_hand_side_values);
-
-          std::vector<SymmetricTensor<2,dim> > strain_tensor (n_q_points);
-          fe_values[displacement].get_function_symmetric_gradients (u, strain_tensor);
-
-          for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
-            {
-              SymmetricTensor<4,dim> stress_strain_tensor;
-              SymmetricTensor<2,dim> stress_tensor;
-
-              plast_lin_hard->plast_linear_hardening (stress_strain_tensor, strain_tensor[q_point],
-                                                      elast_points, plast_points, yield);
-
-              cell_constitution (cell_number) += yield;
-              for (unsigned int i=0; i<dofs_per_cell; ++i)
-                {
-                  cell_rhs(i) -= (strain_tensor[q_point] * stress_strain_tensor * //(stress_tensor) *
-                                  plast_lin_hard->get_strain(fe_values, i, q_point) *
-                                  fe_values.JxW (q_point));
-
-                  Tensor<1,dim> rhs_values;
-                  rhs_values = 0;
-                  cell_rhs(i) += ((fe_values[displacement].value (i, q_point) *
-                                   rhs_values) *
-                                  fe_values.JxW (q_point));
-                };
-            };
-
-          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-            {
-              if (cell->face (face)->at_boundary()
-                  && cell->face (face)->boundary_indicator () == 9)
-                {
-                  fe_values_face.reinit (cell, face);
-
-                  right_hand_side.vector_value_list (fe_values_face.get_quadrature_points(),
-                                                     right_hand_side_values_face);
-
-                  for (unsigned int q_point=0; q_point<n_face_q_points; ++q_point)
-                    {
-                      Tensor<1,dim> rhs_values;
-                      rhs_values = 0;
-                      for (unsigned int i=0; i<dofs_per_cell; ++i)
-                        cell_rhs(i) += (fe_values_face[displacement].value (i, q_point) *
-                                        rhs_values *
-                                        fe_values_face.JxW (q_point));
-                    }
-                }
-            }
-
-          cell->get_dof_indices (local_dof_indices);
-          constraints_dirichlet_hanging_nodes.distribute_local_to_global (cell_rhs,
-              local_dof_indices,
-              system_rhs_newton);
-
-          cell_number += 1;
-        }
-      else
-        {
-          cell_constitution (cell_number) = 0;
-          cell_number += 1;
-        };
-
-    cell_constitution /= n_q_points;
-    cell_constitution.compress (VectorOperation::add);
-    system_rhs_newton.compress (VectorOperation::add);
-
-    unsigned int sum_elast_points = Utilities::MPI::sum(elast_points, mpi_communicator);
-    unsigned int sum_plast_points = Utilities::MPI::sum(plast_points, mpi_communicator);
-    pcout << "      Number of elastic quadrature points: " << sum_elast_points
-          << " and plastic quadrature points: " << sum_plast_points << std::endl;
-  }
-
-  template <int dim>
-  void PlasticityContactProblem<dim>::assemble_mass_matrix_diagonal (TrilinosWrappers::SparseMatrix &mass_matrix)
-  {
-    QTrapez<dim-1>  face_quadrature_formula;
-
-    FEFaceValues<dim> fe_values_face (fe, face_quadrature_formula,
-                                      update_values   |
-                                      update_quadrature_points |
-                                      update_JxW_values);
-
-    const unsigned int   dofs_per_cell      = fe.dofs_per_cell;
-    const unsigned int   n_face_q_points    = face_quadrature_formula.size();
-
-    FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
-    Tensor<1,dim,double> ones (dim);
-    for (unsigned i=0; i<dim; i++)
-      ones[i] = 1.0;
-
-    std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
-
-    const FEValuesExtractors::Vector displacement (0);
-
-    typename DoFHandler<dim>::active_cell_iterator
-    cell = dof_handler.begin_active(),
-    endc = dof_handler.end();
-
-    for (; cell!=endc; ++cell)
-      if (cell->is_locally_owned())
-        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-          if (cell->face (face)->at_boundary()
-              && cell->face (face)->boundary_indicator () == 9)
-            {
-              fe_values_face.reinit (cell, face);
-              cell_matrix = 0;
-
-              for (unsigned int q_point=0; q_point<n_face_q_points; ++q_point)
-                for (unsigned int i=0; i<dofs_per_cell; ++i)
-                  cell_matrix(i,i) += (fe_values_face[displacement].value (i, q_point) *
-                                       ones *
-                                       fe_values_face.JxW (q_point));
-
-              cell->get_dof_indices (local_dof_indices);
-
-              constraints_dirichlet_hanging_nodes.distribute_local_to_global (cell_matrix,
-                  local_dof_indices,
-                  mass_matrix);
-            }
-
-    mass_matrix.compress (VectorOperation::add);
-  }
-
-  // @sect4{PlasticityContactProblem::update_solution_and_constraints}
-
-  // Projection and updating of the active set
-  // for the dofs which penetrates the obstacle.
-  template <int dim>
-  void PlasticityContactProblem<dim>::update_solution_and_constraints ()
-  {
-    computing_timer.enter_section("Update solution and constraints");
-
-    const EquationData::Obstacle<dim>     obstacle (input_obstacle, use_read_obstacle);
-    std::vector<bool>                     vertex_touched (dof_handler.n_dofs (), false);
-
-    typename DoFHandler<dim>::active_cell_iterator
-    cell = dof_handler.begin_active(),
-    endc = dof_handler.end();
-
-    TrilinosWrappers::MPI::Vector         distributed_solution (system_rhs_newton);
-    distributed_solution = solution;
-    TrilinosWrappers::MPI::Vector         lambda (solution);
-    lambda = resid_vector;
-    TrilinosWrappers::MPI::Vector         diag_mass_matrix_vector_relevant (solution);
-    diag_mass_matrix_vector_relevant = diag_mass_matrix_vector;
-
-    constraints.reinit(locally_relevant_dofs);
-    active_set.clear ();
-    IndexSet     active_set_locally_owned;
-    active_set_locally_owned.set_size (locally_owned_dofs.size ());
-    const double c = 100.0*e_modul;
-
-    for (; cell!=endc; ++cell)
-      if (cell->is_locally_owned())
-        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
-          if (cell->face (face)->at_boundary()
-              && cell->face (face)->boundary_indicator () == 9)
-            for (unsigned int v=0; v<GeometryInfo<dim-1>::vertices_per_cell; ++v)
-              {
-                unsigned int index_z = cell->face (face)->vertex_dof_index (v,2);
-
-                if (vertex_touched[cell->face (face)->vertex_index(v)] == false)
-                  vertex_touched[cell->face (face)->vertex_index(v)] = true;
-                else
-                  continue;
-
-                // the local row where
-                Point<dim> point (cell->face (face)->vertex (v)[0],
-                                  cell->face (face)->vertex (v)[1],
-                                  cell->face (face)->vertex (v)[2]);
-
-                double obstacle_value = obstacle.value (point, 2);
-                double solution_index_z = solution (index_z);
-                double gap = obstacle_value - point (2);
-
-
-//                std::cout << "lambda = " << lambda (index_z)
-//                          << ", solution_index_z - gap = " << solution_index_z - gap
-//                          << ", diag_mass_matrix_vector_relevant = " << diag_mass_matrix_vector_relevant (index_z)
-//                          << std::endl;
-
-                if (lambda (index_z) +
-                    c *
-                    diag_mass_matrix_vector_relevant (index_z) *
-                    (solution_index_z - gap)
-                    > 0 &&
-                    !(constraints_hanging_nodes.is_constrained(index_z)))
-                  {
-                    constraints.add_line (index_z);
-                    constraints.set_inhomogeneity (index_z, gap);
-
-                    distributed_solution (index_z) = gap;
-
-                    if (locally_relevant_dofs.is_element (index_z))
-                      active_set.add_index (index_z);
-
-                    if (locally_owned_dofs.is_element (index_z))
-                      active_set_locally_owned.add_index (index_z);
-                  }
-              }
-    distributed_solution.compress (VectorOperation::insert);
-
-    unsigned int sum_contact_constraints = Utilities::MPI::sum(active_set_locally_owned.n_elements (),
-                                                               mpi_communicator);
-    pcout << "         Size of active set: " << sum_contact_constraints <<std::endl;
-
-    solution = distributed_solution;
-
-    constraints.close ();
-
-    constraints.merge (constraints_dirichlet_hanging_nodes);
-
-    computing_timer.exit_section("Update solution and constraints");
-  }
-
-  // @sect4{PlasticityContactProblem::dirichlet_constraints}
-
-  // This function defines the new ConstraintMatrix
-  // constraints_dirichlet_hanging_nodes. It contains
-  // the dirichlet boundary values as well as the
-  // hanging nodes constraints.
-  template <int dim>
-  void PlasticityContactProblem<dim>::dirichlet_constraints ()
-  {
-    /* boundary_indicators:
-              _______
-             /  9    /|
-            /______ / |
-          8|       | 8|
-           |   8   | /
-           |_______|/
-               6
-     */
-
-    constraints_dirichlet_hanging_nodes.reinit (locally_relevant_dofs);
-    constraints_dirichlet_hanging_nodes.merge (constraints_hanging_nodes);
-
-    // interpolate all components of the solution
-    VectorTools::interpolate_boundary_values (dof_handler,
-                                              6,
-                                              EquationData::BoundaryValues<dim>(),
-                                              constraints_dirichlet_hanging_nodes,
-                                              ComponentMask());
-
-    // interpolate x- and y-components of the
-    // solution (this is a bit mask, so apply
-    // operator| )
-    FEValuesExtractors::Scalar x_displacement(0);
-    FEValuesExtractors::Scalar y_displacement(1);
-    VectorTools::interpolate_boundary_values (dof_handler,
-                                              8,
-                                              EquationData::BoundaryValues<dim>(),
-                                              constraints_dirichlet_hanging_nodes,
-                                              (fe.component_mask(x_displacement)
-                                               |
-                                               fe.component_mask(y_displacement)));
-    constraints_dirichlet_hanging_nodes.close ();
-  }
-
-  // @sect4{PlasticityContactProblem::solve}
-
-  // In addition to step-41 we have
-  // to deal with the hanging node
-  // constraints. Again we also consider
-  // the locally_owned_dofs only by
-  // creating the vector distributed_solution.
-  //
-  // For the hanging nodes we have to apply
-  // the set_zero function to system_rhs_newton.
-  // This is necessary if a hanging node value x_0
-  // has one neighbor which is in contact with
-  // value x_0 and one neighbor which is not with
-  // value x_1. This leads to an inhomogeneity
-  // constraint with value x_1/2 = gap/2 in the
-  // ConstraintMatrix.
-  // So the corresponding entries in the
-  // ride-hang-side are non-zero with a
-  // meaningless value. These values have to
-  // to set to zero.
-
-  // The rest of the function is similar to
-  // step-41 except that we use a FGMRES-solver
-  // instead of CG. For a very small hardening
-  // value gamma the linear system becomes
-  // almost semi definite but still symmetric.
-  template <int dim>
-  void PlasticityContactProblem<dim>::solve ()
-  {
-    computing_timer.enter_section ("Solve");
-
-    TrilinosWrappers::MPI::Vector    distributed_solution (system_rhs_newton);
-    distributed_solution = solution;
-
-    constraints_hanging_nodes.set_zero (distributed_solution);
-    constraints_hanging_nodes.set_zero (system_rhs_newton);
-    distributed_solution.compress(VectorOperation::insert);
-    system_rhs_newton.compress(VectorOperation::insert);
-
-    computing_timer.enter_section("Solve: setup preconditioner");
-
-    preconditioner_u.initialize (system_matrix_newton, additional_data);
-
-    computing_timer.exit_section("Solve: setup preconditioner");
-
-    computing_timer.enter_section("Solve: iterate");
-
-    PrimitiveVectorMemory<TrilinosWrappers::MPI::Vector> mem;
-    TrilinosWrappers::MPI::Vector    tmp (system_rhs_newton);
-    const double solver_tolerance = 1e-3 *
-                                    system_matrix_newton.residual (tmp, distributed_solution, system_rhs_newton);
-
-//    SolverControl solver_control (system_matrix_newton.m(), solver_tolerance);
-//    SolverFGMRES<TrilinosWrappers::MPI::Vector>
-//    solver(solver_control, mem,
-//           SolverFGMRES<TrilinosWrappers::MPI::Vector>::
-//           AdditionalData(30, true));
-//
-//    solver.solve(system_matrix_newton, distributed_solution, system_rhs_newton, preconditioner_u);
-//
-//    pcout << "         Error: " << solver_control.initial_value()
-//          << " -> " << solver_control.last_value()
-//          << " in " << solver_control.last_step()
-//          << " FGMRES iterations."
-//          << std::endl;
-
-    SolverControl solver_control (system_matrix_newton.m(), solver_tolerance);
-    SolverBicgstab<TrilinosWrappers::MPI::Vector>
-    solver(solver_control, mem,
-           SolverBicgstab<TrilinosWrappers::MPI::Vector>::
-           AdditionalData(false, 1.e-10));
-
-    solver.solve(system_matrix_newton, distributed_solution, system_rhs_newton, preconditioner_u);
-
-    pcout << "         Error: " << solver_control.initial_value()
-          << " -> " << solver_control.last_value()
-          << " in " << solver_control.last_step()
-          << " Bicgstab iterations."
-          << std::endl;
-
-    computing_timer.exit_section("Solve: iterate");
-
-    number_iterations += solver_control.last_step();
-
-    constraints.distribute (distributed_solution);
-
-    solution = distributed_solution;
-
-    computing_timer.exit_section("Solve");
-  }
-
-  // @sect4{PlasticityContactProblem::solve_newton}
-
-  // In this function the damped Newton method is implemented.
-  // That means two nested loops: the outer loop for the newton
-  // iteration and the inner loop for the damping steps which
-  // will be used only if necessary. To obtain a good and reasonable
-  // starting value we solve an elastic problem in very first step (j=1).
-  template <int dim>
-  void PlasticityContactProblem<dim>::solve_newton ()
-  {
-    double                         resid=0;
-    double                         resid_old=100000;
-    TrilinosWrappers::MPI::Vector  old_solution (system_rhs_newton);
-    TrilinosWrappers::MPI::Vector  res (system_rhs_newton);
-    TrilinosWrappers::MPI::Vector  tmp_vector (system_rhs_newton);
-
-    std::vector<std::vector<bool> > constant_modes;
-    DoFTools::extract_constant_modes (dof_handler,
-                                      ComponentMask(),
-                                      constant_modes);
-
-    double sigma_hlp = sigma_0;
-
-    additional_data.constant_modes = constant_modes;
-    additional_data.elliptic = true;
-    additional_data.n_cycles = 1;
-    additional_data.w_cycle = false;
-    additional_data.output_details = false;
-    additional_data.smoother_sweeps = 2;
-    additional_data.aggregation_threshold = 1e-2;
-
-    IndexSet                        active_set_old (active_set);
-    unsigned int j = 1;
-    unsigned int number_assemble_system = 0;
-    for (; j<=100; j++)
-      {
-        if (j == 1 && cycle == 0)
-          plast_lin_hard->set_sigma_0 (1e+10);
-        else if (j == 2 || cycle > 0)
-          plast_lin_hard->set_sigma_0 (sigma_hlp);
-
-        pcout << " " <<std::endl;
-        pcout << "   Newton iteration " << j << std::endl;
-        pcout << "      Updating active set..." << std::endl;
-
-        update_solution_and_constraints ();
-
-        pcout << "      Assembling system... " << std::endl;
-        system_matrix_newton = 0;
-        system_rhs_newton = 0;
-        assemble_nl_system (solution);  //compute Newton-Matrix
-
-        number_assemble_system += 1;
-
-        pcout << "      Solving system... " << std::endl;
-        solve ();
-
-        TrilinosWrappers::MPI::Vector distributed_solution (system_rhs_newton);
-        distributed_solution = solution;
-
-
-        // We handle a highly nonlinear problem so we have to damp
-        // the Newtons method. We refer that we iterate the new solution
-        // in each Newton step and not only the solution update.
-        // Since the solution set is a convex set and not a space we
-        // compute for the damping a linear combination of the
-        // previous and the current solution to guarantee that the
-        // damped solution is in our solution set again.
-        // At most we apply 10 damping steps.
-        bool damped = false;
-        tmp_vector = old_solution;
-        double a = 0;
-        for (unsigned int i=0; (i<10)&&(!damped); i++)
-          {
-            a=std::pow(0.5, static_cast<double>(i));
-            old_solution = tmp_vector;
-            old_solution.sadd(1-a,a, distributed_solution);
-            old_solution.compress (VectorOperation::add);
-
-            computing_timer.enter_section("Residual and lambda");
-
-            system_rhs_newton = 0;
-
-            solution = old_solution;
-            residual_nl_system (solution);
-            res = system_rhs_newton;
-
-            const unsigned int
-            start_res     = (res.local_range().first),
-            end_res       = (res.local_range().second);
-            for (unsigned int n=start_res; n<end_res; ++n)
-              if (constraints.is_inhomogeneously_constrained (n))
-                res(n) = 0;
-
-            res.compress(VectorOperation::insert);
-
-            resid = res.l2_norm ();
-
-            if (resid<resid_old)
-              damped=true;
-
-            computing_timer.exit_section("Residual and lambda");
-
-            pcout << "      Residual of the non-contact part of the system: " << resid
-                  << std::endl
-                  << "         with a damping parameter alpha = " << a
-                  << std::endl;
-
-            // The previous iteration of step 0 is the solution of an elastic problem.
-            // So a linear combination of a plastic and an elastic solution makes no sense
-            // since the elastic solution is not in the convex set of the plastic solution.
-            if (j == 2)
-              break;
-          }
-
-        resid_old=resid;
-
-        resid_vector = system_rhs_newton;
-        resid_vector.compress (VectorOperation::insert);
-
-        int is_my_set_changed = (active_set == active_set_old)?0:1;
-        int num_changed = Utilities::MPI::sum(is_my_set_changed, MPI_COMM_WORLD);
-        if (num_changed==0 && resid < 1e-8)
-          break;
-        active_set_old = active_set;
-      }
-
-    pcout << "" << std::endl
-          << "      Number of assembled systems = " << number_assemble_system
-          << std::endl
-          << "      Number of Solver-Iterations = " << number_iterations << std::endl;
-  }
-
-
-
-  template <int dim>
-  void PlasticityContactProblem<dim>::refine_grid ()
-  {
-    Vector<float> estimated_error_per_cell (triangulation.n_active_cells());
-    KellyErrorEstimator<dim>::estimate (dof_handler,
-                                        QGauss<dim-1>(3),
-                                        typename FunctionMap<dim>::type(),
-                                        solution,
-                                        estimated_error_per_cell);
-    parallel::distributed::GridRefinement::
-    refine_and_coarsen_fixed_number (triangulation,
-                                     estimated_error_per_cell,
-                                     0.3, 0.03);
-
-    triangulation.prepare_coarsening_and_refinement();
-    soltrans->prepare_for_coarsening_and_refinement(solution);
-
-    triangulation.execute_coarsening_and_refinement ();
-  }
-
-
-
-  template <int dim>
-  void PlasticityContactProblem<dim>::move_mesh (const TrilinosWrappers::MPI::Vector &_complete_displacement) const
-  {
-    std::vector<bool> vertex_touched (triangulation.n_vertices(),
-                                      false);
-
-    for (typename DoFHandler<dim>::active_cell_iterator
-         cell = dof_handler.begin_active ();
-         cell != dof_handler.end(); ++cell)
-      if (cell->is_locally_owned())
-        for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
-          {
-            if (vertex_touched[cell->vertex_index(v)] == false)
-              {
-                vertex_touched[cell->vertex_index(v)] = true;
-
-                Point<dim> vertex_displacement;
-                for (unsigned int d=0; d<dim; ++d)
-                  {
-                    if (_complete_displacement(cell->vertex_dof_index(v,d)) != 0)
-                      vertex_displacement[d]
-                        = _complete_displacement(cell->vertex_dof_index(v,d));
-                  }
-
-                cell->vertex(v) += vertex_displacement;
-              }
-          }
-  }
-
-
+}
 
-  template <int dim>
-  void PlasticityContactProblem<dim>::output_results (const std::string &title) const
-  {
-    move_mesh (solution);
-
-    TrilinosWrappers::MPI::Vector         lambda (solution);
-    lambda = resid_vector;
-
-    DataOut<dim> data_out;
-
-    data_out.attach_dof_handler (dof_handler);
-
-    const std::vector<DataComponentInterpretation::DataComponentInterpretation>
-    data_component_interpretation
-    (dim, DataComponentInterpretation::component_is_part_of_vector);
-    data_out.add_data_vector (solution, std::vector<std::string>(dim, "Displacement"),
-                              DataOut<dim>::type_dof_data,
-                              data_component_interpretation);
-    data_out.add_data_vector (lambda, std::vector<std::string>(dim, "Residual"),
-                              DataOut<dim>::type_dof_data,
-                              data_component_interpretation);
-    data_out.add_data_vector (active_set, std::vector<std::string>(dim, "ActiveSet"),
-                              DataOut<dim>::type_dof_data,
-                              data_component_interpretation);
-
-    Vector<float> subdomain (triangulation.n_active_cells());
-    for (unsigned int i=0; i<subdomain.size(); ++i)
-      subdomain(i) = triangulation.locally_owned_subdomain();
-    data_out.add_data_vector (subdomain, "subdomain");
-
-    data_out.add_data_vector (cell_constitution, "CellConstitution");
-
-    data_out.build_patches ();
-
-    const std::string filename = (title + "-" +
-                                  Utilities::int_to_string
-                                  (triangulation.locally_owned_subdomain(), 4));
-
-    std::ofstream output_vtu ((filename + ".vtu").c_str ());
-    data_out.write_vtu (output_vtu);
-
-    if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)
-      {
-        std::vector<std::string> filenames;
-        for (unsigned int i=0;
-             i<Utilities::MPI::n_mpi_processes(mpi_communicator);
-             ++i)
-          filenames.push_back (title + "-" +
-                               Utilities::int_to_string (i, 4) +
-                               ".vtu");
-
-        std::ofstream master_output ((filename + ".pvtu").c_str());
-        data_out.write_pvtu_record (master_output, filenames);
-      }
-
-    TrilinosWrappers::MPI::Vector  tmp (solution);
-    tmp *= -1;
-    move_mesh (tmp);
-  }
+// @sect3{The <code>move_mesh</code> function}
+
+template<int dim>
+void PlasticityContactProblem<dim>::move_mesh(
+               const TrilinosWrappers::MPI::Vector &_complete_displacement) const {
+       std::vector<bool> vertex_touched(triangulation.n_vertices(), false);
+
+       for (typename DoFHandler<dim>::active_cell_iterator cell =
+                       dof_handler.begin_active(); cell != dof_handler.end(); ++cell)
+               if (cell->is_locally_owned())
+                       for (unsigned int v = 0;
+                                       v < GeometryInfo < dim > ::vertices_per_cell; ++v) {
+                               if (vertex_touched[cell->vertex_index(v)] == false) {
+                                       vertex_touched[cell->vertex_index(v)] = true;
+
+                                       Point < dim > vertex_displacement;
+                                       for (unsigned int d = 0; d < dim; ++d) {
+                                               if (_complete_displacement(cell->vertex_dof_index(v, d))
+                                                               != 0)
+                                                       vertex_displacement[d] = _complete_displacement(
+                                                                       cell->vertex_dof_index(v, d));
+                                       }
+
+                                       cell->vertex(v) += vertex_displacement;
+                               }
+                       }
+}
 
+// @sect4{PlasticityContactProblem::output_results}
+
+template<int dim>
+void PlasticityContactProblem<dim>::output_results(
+               const std::string &title) {
+       move_mesh(solution);
+
+       // Calculation of the contact forces
+       TrilinosWrappers::MPI::Vector lambda(solution);
+       TrilinosWrappers::MPI::Vector distributed_lambda(system_rhs_newton);
+       const unsigned int start_res = (resid_vector.local_range().first), end_res =
+         (resid_vector.local_range().second);
+       for (unsigned int n = start_res; n < end_res; ++n)
+         if (constraints.is_inhomogeneously_constrained(n))
+           distributed_lambda(n) = resid_vector(n)/diag_mass_matrix_vector(n);
+       distributed_lambda.compress(VectorOperation::insert);
+       constraints_hanging_nodes.distribute(distributed_lambda);
+       lambda = distributed_lambda;
+       TrilinosWrappers::MPI::Vector resid_vector_relevant(solution);
+       TrilinosWrappers::MPI::Vector distributed_resid_vector(resid_vector);
+       constraints_hanging_nodes.distribute(distributed_resid_vector);
+       resid_vector_relevant = distributed_resid_vector;
+
+       DataOut < dim > data_out;
+
+       data_out.attach_dof_handler(dof_handler);
+
+       const std::vector<DataComponentInterpretation::DataComponentInterpretation> data_component_interpretation(
+                       dim, DataComponentInterpretation::component_is_part_of_vector);
+       data_out.add_data_vector(solution,
+                       std::vector < std::string > (dim, "Displacement"),
+                       DataOut < dim > ::type_dof_data, data_component_interpretation);
+       data_out.add_data_vector(lambda,
+                       std::vector < std::string > (dim, "ContactForce"),
+                       DataOut < dim > ::type_dof_data, data_component_interpretation);
+       data_out.add_data_vector(active_set,
+                       std::vector < std::string > (dim, "ActiveSet"),
+                       DataOut < dim > ::type_dof_data, data_component_interpretation);
+       data_out.add_data_vector(resid_vector_relevant,
+                       std::vector < std::string > (dim, "Residual"),
+                       DataOut < dim > ::type_dof_data, data_component_interpretation);
+
+       Vector<float> subdomain(triangulation.n_active_cells());
+       for (unsigned int i = 0; i < subdomain.size(); ++i)
+               subdomain(i) = triangulation.locally_owned_subdomain();
+       data_out.add_data_vector(subdomain, "subdomain");
+
+       data_out.add_data_vector(cell_constitution, "CellConstitution");
+
+       data_out.build_patches();
+
+       const std::string filename = (output_dir + title + "-"
+                       + Utilities::int_to_string(triangulation.locally_owned_subdomain(),
+                                       4));
+
+       std::ofstream output_vtu((filename + ".vtu").c_str());
+       data_out.write_vtu(output_vtu);
+        pcout << output_dir + title << ".pvtu" << std::endl;
+
+       if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0) {
+               std::vector<std::string> filenames;
+               for (unsigned int i = 0;
+                               i < Utilities::MPI::n_mpi_processes(mpi_communicator); ++i)
+                       filenames.push_back(
+                           title + "-" + Utilities::int_to_string(i, 4) + ".vtu");
+
+               std::ofstream master_output((output_dir + title + ".pvtu").c_str());
+               data_out.write_pvtu_record(master_output, filenames);
+       }
+
+       TrilinosWrappers::MPI::Vector tmp(solution);
+       tmp *= -1;
+       move_mesh(tmp);
+}
 
+// @sect4{PlasticityContactProblem::output_for_benchmark}
+
+template<int dim>
+void PlasticityContactProblem<dim>::output_for_benchmark(
+               const unsigned int cycle) {
+       Functions::FEFieldFunction<dim, DoFHandler<dim>,
+                       TrilinosWrappers::MPI::Vector> solution_function(dof_handler,
+                       solution);
+        std::cout.precision(10);
+
+        Vector<double> solution_p1(dim);
+       std::vector < Tensor<1, dim> > solution_gradient_p1(dim);
+
+       const Point<dim> p1_of_interest(0.5001, 0.5001, 0.9501);
+       bool point1_found = true;
+       bool point2_found = true;
+
+       // Calculation of the contact forces
+       TrilinosWrappers::MPI::Vector lambda(solution);
+       TrilinosWrappers::MPI::Vector distributed_lambda(system_rhs_newton);
+       const unsigned int start_res = (resid_vector.local_range().first), end_res =
+         (resid_vector.local_range().second);
+       for (unsigned int n = start_res; n < end_res; ++n)
+         if (constraints.is_inhomogeneously_constrained(n))
+           distributed_lambda(n) = resid_vector(n)/diag_mass_matrix_vector(n);
+         else
+           distributed_lambda(n) = 0;
+       distributed_lambda.compress(VectorOperation::insert);
+       constraints_hanging_nodes.distribute(distributed_lambda);
+       lambda = distributed_lambda;
+       Functions::FEFieldFunction<dim, DoFHandler<dim>,
+                       TrilinosWrappers::MPI::Vector> lambda_function(dof_handler,
+                       lambda);
+       const Point<dim> p2_of_interest(0.49, 0.5001, 1.0);
+       Vector<double> lambda_p2(dim);
+       
+       MPI_Barrier(MPI_COMM_WORLD);
+       try {
+         lambda_function.vector_value(p2_of_interest, lambda_p2);
+       } catch (const typename Functions::FEFieldFunction<dim, DoFHandler<dim>,
+                TrilinosWrappers::MPI::Vector>::ExcPointNotAvailableHere &) {
+         point2_found = false;
+       }
+       
+       if (point2_found == true) {
+         std::cout << "PoI lambda_z: " << lambda_p2(2) << std::endl;
+       }
+
+       // Integral of the contact force in z-direction over the whole contact area.
+       double contact_force = 0.0;
+       {
+               QGauss< dim - 1 > face_quadrature_formula(fe.degree + 1);
+
+               FEFaceValues < dim > fe_values_face(fe, face_quadrature_formula,
+                                               update_values | update_quadrature_points
+                                                               | update_JxW_values);
+
+               const unsigned int n_face_q_points = face_quadrature_formula.size();
+
+               const FEValuesExtractors::Vector displacement(0);
+
+               typename DoFHandler<dim>::active_cell_iterator cell =
+                               dof_handler.begin_active(), endc = dof_handler.end();
+               for (; cell != endc; ++cell)
+                       if (cell->is_locally_owned())
+                               for (unsigned int face = 0;
+                                               face < GeometryInfo < dim > ::faces_per_cell; ++face)
+                                       if (cell->face(face)->at_boundary()
+                                                       && cell->face(face)->boundary_indicator() == 1) {
+                                               fe_values_face.reinit(cell, face);
+
+                                               std::vector < Tensor<1, dim>
+                                                               > lambda_values(n_face_q_points);
+                                               fe_values_face[displacement].get_function_values(lambda,
+                                                               lambda_values);
+
+                                               for (unsigned int q_point = 0;
+                                                               q_point < n_face_q_points; ++q_point)
+                                               {
+                                                       contact_force += lambda_values[q_point][2]
+                                                                       * fe_values_face.JxW(q_point);
+                                               }
+                                       }
+               contact_force = Utilities::MPI::sum(contact_force,
+                               MPI_COMM_WORLD);
+               pcout << "Contact force = " << contact_force << std::endl;
+       }
+
+       // To calculate the contact area between deformable body and obstacle
+       double contact_area = 0.0;
+       {
+         move_mesh(solution);
+
+         QGaussLobatto < dim - 1 > face_quadrature_formula(fe.degree + 1);
+         
+         FEFaceValues < dim > fe_values_face(fe, face_quadrature_formula,
+                                             update_values | update_quadrature_points
+                                             | update_JxW_values);
+         
+         const unsigned int dofs_per_face = fe.dofs_per_face;
+         const unsigned int n_face_q_points = face_quadrature_formula.size();
+         
+         const FEValuesExtractors::Vector displacement(0);
+         typename DoFHandler<dim>::active_cell_iterator cell =
+           dof_handler.begin_active(), endc = dof_handler.end();
+         for (; cell != endc; ++cell)
+           if (cell->is_locally_owned())
+             for (unsigned int face = 0;
+                  face < GeometryInfo < dim > ::faces_per_cell; ++face){
+               if (cell->face(face)->at_boundary()
+                   && cell->face(face)->boundary_indicator() == 1) {
+                 fe_values_face.reinit(cell, face);
+
+                 unsigned int contact_counter = 0;
+                 std::vector<unsigned int> dof_indices (dofs_per_face);
+                 cell->face(face)->get_dof_indices (dof_indices);
+                 
+                 for (unsigned int q_point=0; q_point<n_face_q_points; ++q_point)
+                   {
+                     unsigned int component =
+                       fe.face_system_to_component_index (q_point).first;
+
+                     if (component == 2)
+                       {
+                         unsigned int index_z = dof_indices[q_point];
+
+                         if (constraints.is_inhomogeneously_constrained(index_z))
+                           contact_counter += 1;
+                       }
+                   }
+
+                 for (unsigned int q_point = 0;
+                      q_point < n_face_q_points; ++q_point)
+                   {
+                     contact_area += (double)(contact_counter)/n_face_q_points*3.0 * fe_values_face.JxW(q_point);
+                   }
+               }
+             }
+       
+         contact_area = Utilities::MPI::sum(contact_area,
+                                             MPI_COMM_WORLD);
+         pcout << "Contact area = " << contact_area << std::endl;
+
+         TrilinosWrappers::MPI::Vector tmp(solution);
+         tmp *= -1;
+         move_mesh(tmp);
+       }
+
+       MPI_Barrier(MPI_COMM_WORLD);
+       try {
+               solution_function.vector_value(p1_of_interest, solution_p1);
+       } catch (const typename Functions::FEFieldFunction<dim, DoFHandler<dim>,
+                       TrilinosWrappers::MPI::Vector>::ExcPointNotAvailableHere &) {
+               point1_found = false;
+       }
+
+       if (point1_found == true) {
+               solution_function.vector_gradient(p1_of_interest, solution_gradient_p1);
+
+               // Calculating strains tensor
+               SymmetricTensor < 2, dim > strain_tensor;
+               for (unsigned int i = 0; i < dim; i++) {
+                       strain_tensor[i][i] = solution_gradient_p1[i][i];
+                       for (unsigned int j = i; j < dim; j++)
+                               strain_tensor[i][j] = (solution_gradient_p1[i][j]
+                                               + solution_gradient_p1[j][i]) / 2.0;
+               }
+
+               // Calculating stress tensor
+               SymmetricTensor < 4, dim > stress_strain_tensor;
+               SymmetricTensor < 2, dim > stress_tensor;
+               unsigned int elast_points = 0;
+               unsigned int plast_points = 0;
+               double yield = 0.0;
+
+               plast_lin_hard->plast_linear_hardening(stress_strain_tensor,
+                               strain_tensor, elast_points, plast_points, yield);
+
+               stress_tensor = stress_strain_tensor * strain_tensor;
+
+               // Gnuplot file for point information
+               // output order: #dofs + displacement + stress tensor + contact_force + contact_area
+               // #dofs ux  uy  uz  sxx  syy  szz  sxy  sxz  syz contace_force contact_area
+               std::string filename = (output_dir + "Point_of_interest-"
+                               + Utilities::int_to_string(cycle, 2) + ".dat");
+               std::fstream file;
+               file.open(filename.c_str(), std::ios::out);
+               file.precision(10);
+
+               file << dof_handler.n_dofs() << " " << solution_p1(0) << " "
+                    << solution_p1(1) << " " << solution_p1(2) << " "
+                    << stress_tensor[0][0] << " " << stress_tensor[1][1] << " "
+                    << stress_tensor[2][2] << " " << stress_tensor[0][1] << " "
+                    << stress_tensor[1][2] << " " << stress_tensor[1][2] << " "
+                    << contact_force << " " << contact_area
+                    << std::endl;
+
+               file.close();
+
+               std::cout << "PoI u_z: " << solution_p1(2) << std::endl;
+               std::cout << "PoI s_xx: " << stress_tensor[0][0] << std::endl;
+               std::cout << "PoI s_zz: " << stress_tensor[2][2] << std::endl;
+       }
+
+       MPI_Barrier(MPI_COMM_WORLD);
+}
 
-  template <int dim>
-  void PlasticityContactProblem<dim>::run ()
-  {
-    use_read_obstacle = false;
-    if (use_read_obstacle)
-      {
-        pcout << "Read the obstacle from a file." << std::endl;
-        input_obstacle.reset (new Input<dim>("obstacle_file.pbm"));
-        pcout << "Obstacle is available now." << std::endl;
-      }
-
-    const unsigned int n_cycles = 6;
-    for (cycle=0; cycle<n_cycles; ++cycle)
-      {
-        computing_timer.enter_section("Setup");
-
-        pcout << std::endl;
-        pcout << "Cycle " << cycle << ':' << std::endl;
-
-        if (cycle == 0)
-          {
-            make_grid();
-          }
-        else
-          {
-            computing_timer.enter_section("Setup: refine mesh");
-            soltrans.reset (new parallel::distributed::SolutionTransfer<dim,TrilinosWrappers::MPI::Vector>(dof_handler));
-            refine_grid ();
-            computing_timer.exit_section("Setup: refine mesh");
-          }
+// @sect4{PlasticityContactProblem::run}
 
-        setup_system ();
+template<int dim>
+void PlasticityContactProblem<dim>::run() {
 
-        if (cycle > 0)
-          {
-            TrilinosWrappers::MPI::Vector    distributed_solution (system_rhs_newton);
-            distributed_solution = solution;
-            soltrans->interpolate(distributed_solution);
-            solution = distributed_solution;
+       if (obstacle_filename!="")
+         {
+                  pcout << "Read the obstacle from '" << obstacle_filename
+                      << "' ... " << std::flush;
+                  input_obstacle.reset(new Input<dim>(obstacle_filename.c_str()));
+                  pcout << "done." << std::endl;
           }
 
-        computing_timer.exit_section("Setup");
-
-        solve_newton ();
-
-        pcout << "      Writing graphical output..." << std::endl;
-        computing_timer.enter_section("Graphical output");
-
-        std::ostringstream filename_solution;
-        filename_solution << "solution-";
-        filename_solution << cycle;
-        output_results (filename_solution.str ());
-
-        computing_timer.exit_section("Graphical output");
-
-        computing_timer.print_summary();
-        computing_timer.reset();
-      }
-  }
+       computing_timer.reset();
+       for (cycle = 0; cycle < n_cycles; ++cycle) {
+               {
+                       TimerOutput::Scope t(computing_timer, "Setup");
+
+                       pcout << std::endl;
+                       pcout << "Cycle " << cycle << ':' << std::endl;
+
+                       if (cycle == 0) {
+                               make_grid();
+                       } else {
+                               TimerOutput::Scope t(computing_timer, "Setup: refine mesh");
+                               if (transfer_solution)
+                                 soltrans.reset (new parallel::distributed::SolutionTransfer<dim,TrilinosWrappers::MPI::Vector>(dof_handler));
+                               refine_grid();
+                       }
+
+                       setup_system();
+
+                       if (transfer_solution && cycle > 0)
+                       {
+                               TrilinosWrappers::MPI::Vector distributed_solution(
+                                               system_rhs_newton);
+                               distributed_solution = solution;
+                               soltrans->interpolate(distributed_solution);
+                               solution = distributed_solution;
+                               residual_nl_system(solution);
+                               resid_vector = system_rhs_lambda;
+                               resid_vector.compress(VectorOperation::insert);
+                       }
+
+               }
+
+               solve_newton();
+
+               if (true)    //Utilities::MPI::n_mpi_processes(mpi_communicator) <= 64)
+               {
+                       pcout << "      Writing graphical output... " << std::flush;
+
+                       TimerOutput::Scope t(computing_timer, "Graphical output");
+
+                       std::ostringstream filename_solution;
+                       filename_solution << "solution-";
+                       filename_solution << Utilities::int_to_string(cycle, 2);
+                       output_results(filename_solution.str());
+               }
+
+               computing_timer.print_summary();
+               computing_timer.reset();
+
+               Utilities::System::MemoryStats stats;
+               Utilities::System::get_memory_stats(stats);
+               pcout << "VMPEAK, Resident in kB: " << stats.VmSize << " "
+                               << stats.VmRSS << std::endl;
+
+               if (base_mesh=="box")
+                 output_for_benchmark(cycle);
+       }
+}
 }
 
 // @sect3{The <code>main</code> function}
 
-int main (int argc, char *argv[])
-{
-  using namespace dealii;
-  using namespace Step42;
-
-  deallog.depth_console (0);
-
-  Utilities::MPI::MPI_InitFinalize mpi_initialization (argc, argv);
-  {
-    int _n_refinements_global = 3;
-
-    if (argc == 2)
-      _n_refinements_global = atoi(argv[1]);
-
-    PlasticityContactProblem<3> laplace_problem_3d (_n_refinements_global);
-    laplace_problem_3d.run ();
-  }
-
-  return 0;
+int main(int argc, char *argv[]) {
+       using namespace dealii;
+       using namespace Step42;
+
+       deallog.depth_console(0);
+       ParameterHandler prm;
+       PlasticityContactProblem<3>::declare(prm);
+       if (argc!=2)
+       {
+           prm.print_parameters(std::cout, ParameterHandler::Text);
+           return 0;
+       }
+
+       prm.read_input(argv[1]);
+       Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv);
+       {
+         PlasticityContactProblem<3> problem(prm);
+         problem.run();
+       }
+
+       return 0;
 }
index 96f94caed02b1cd6f1e3ff5792cd870a63cb8d11..62b492245f6aab3c88726eb2933bd941f2043da3 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_TRILINOS)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index 0e32b6ef66b2425862439f23f5a4acb807747005..2c3477bc367d93ad64dfa96e25b40062d4380ef6 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2010 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2010 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Authors: Chih-Che Chueh, University of Victoria, 2010
  *          Wolfgang Bangerth, Texas A&M University, 2010
  */
index 18079d1da0ebd76ad282d038094e2b325c05b3c6..8983261329acc7159b60ebefbffea97cc620fa0e 100644 (file)
@@ -1,19 +1,19 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2010 - 2013 by the deal.II authors and
-//                              & Jean-Paul Pelteret and Andrew McBride
-//
-// 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.
-//
-// ---------------------------------------------------------------------
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2010 - 2013 by the deal.II authors and
+ *                              & Jean-Paul Pelteret and Andrew McBride
+ *
+ * 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.
+ *
+ * ---------------------------------------------------------------------
 
 /*
  * Authors: Jean-Paul Pelteret, University of Cape Town,
index 040d713eb6f09ea98093ada6c565b6f9fae36754..301a851e67a370364f056bc04f92049567bf26b5 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2010 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2010 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Markus Buerg, University of Karlsruhe, 2010
  */
 
index a2c8f5fbc53ea6815b9b3fd0fcd839855c47ae68..02ff830ab73de48351b67a880799f5f2ca2312a6 100644 (file)
@@ -33,7 +33,7 @@ IF(NOT DEAL_II_WITH_UMFPACK)
   MESSAGE(FATAL_ERROR "
 Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_UMFPACK = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index d3fb0d92bb03aa1194febfeb51d5e4959df087e5..8ccfd0e64d8b356ab41da3d59433b6a52c88bb87 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2011 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2011 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, Texas A&M University, 2011
  */
 
index fa212abae85ba45ce9fdc5822248266119fe327f..e607cb2d87178b32b54f9468728d439f08e83d59 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2011 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2011 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 2000
  */
 
index a37cc84d43531dd64fea97f55388e3d8d62256e1..953827c0e0c1c7b97b8185c9ee115e583f502051 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2011 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2011 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Katharina Kormann, Martin Kronbichler, Uppsala University, 2011-2012
  */
 
index f3042fd32b017ee13061e65524fabedce18a947d..a1139eb765b14f070a2d4dfcf5f894184c99de68 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Timo Heister, Texas A&M University, 2013
  */
 
index acaa49edd1ae9d5a4c79f9ca6180478a5841be71..f1d146935b83dec66687b652e1415de635e00913 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 1999 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 1999 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 1999
  */
 
index babcd817e0eca302889b0f5be9283a2033dffaf4..3a16b1326e33115cc945b3e06ca7012add887ad0 100644 (file)
@@ -11,9 +11,6 @@ SET(TARGET_SRC
   # You can specify additional files here!
   )
 
-# A custom command line to run the program
-SET(TARGET_RUN mpirun -np 2 ${TARGET})
-
 # Define the output that should be cleaned:
 SET(CLEAN_UP_FILES *.vtu *.pvtu *.visit)
 
@@ -43,7 +40,7 @@ Error! The deal.II library found at ${DEAL_II_PATH} was not configured with
     DEAL_II_WITH_MPI = ON
     DEAL_II_WITH_P4EST = ON
     DEAL_II_WITH_TRILINOS = ON
-which is required for this tutorial step."
+One or all of these are OFF in your installation but are required for this tutorial step."
     )
 ENDIF()
 
index b76f929eee3fc60a6fb8c0f070f05b7ba3533fa6..b1398c7362cc557b11c9870a34f7f732dfc87e8e 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2003 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2003 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Guido Kanschat, University of Heidelberg, 2003
  *         Baerbel Janssen, University of Heidelberg, 2010
  *         Wolfgang Bangerth, Texas A&M University, 2010
diff --git a/deal.II/examples/step-51/CMakeLists.txt b/deal.II/examples/step-51/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6d7622f
--- /dev/null
@@ -0,0 +1,31 @@
+##
+#  CMake script for the step-7 tutorial program:
+##
+
+# Set the name of the project and target:
+SET(TARGET "step-51")
+
+# Declare all source files the target consists of:
+SET(TARGET_SRC
+  ${TARGET}.cc
+  # You can specify additional files here!
+  )
+
+# Usually, you will not need to modify anything beyond this point...
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
+
+FIND_PACKAGE(deal.II 8.0 QUIET
+  HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR}
+  )
+IF(NOT ${deal.II_FOUND})
+  MESSAGE(FATAL_ERROR "\n"
+    "*** Could not locate deal.II. ***\n\n"
+    "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake\n"
+    "or set an environment variable \"DEAL_II_DIR\" that contains this path."
+    )
+ENDIF()
+
+DEAL_II_INITIALIZE_CACHED_VARIABLES()
+PROJECT(${TARGET})
+DEAL_II_INVOKE_AUTOPILOT()
diff --git a/deal.II/examples/step-51/doc/builds-on b/deal.II/examples/step-51/doc/builds-on
new file mode 100644 (file)
index 0000000..0946a61
--- /dev/null
@@ -0,0 +1 @@
+step-7 step-32 step-44
diff --git a/deal.II/examples/step-51/doc/intro.dox b/deal.II/examples/step-51/doc/intro.dox
new file mode 100644 (file)
index 0000000..d5ecfd4
--- /dev/null
@@ -0,0 +1,118 @@
+<a name="Intro"></a>
+<h1>Introduction</h1>
+
+This tutorial program presents the implementation of a hybridizable
+discontinuous Galkerin method for the convection-diffusion equation.
+
+<h3>  Hybridizable discontinuous Galerkin methods</h3>
+
+One common argument against the use of discontinuous Galerkin elements
+is the large number of globally coupled degrees of freedom that one
+must solve in an implicit system.  For the FE_DGP_Monomial basis, each 
+scalar solution component is represented by polynomials of degree p
+which yields $(1/dim!)*\prod_{i=1}^{dim}(k+i)$ degrees of freedom per
+element.  Typically, all degrees of freedom in an element are coupled
+to all of the degrees of freedom in the adjacent elements.  The resulting
+discrete equations yield very large linear systems very quickly, especially
+for systems of equations in dim=2 or dim=3.  
+
+To alleviate the computational cost of solving such large linear systems, 
+the hybridizable discontinuous Galerkin (HDG) methodology has recently been 
+developed by Cockburn and co-workers 
+(<b>
+   N.C. Nguyen and J. Peraire:
+   <i>Hybridizable discontinuous Galerkin methods for partial differential 
+   equations in continuum mechanics</i>, Journal of Computational Physics,
+   2012, 231:18, 5955-5988.
+   <a href="http://dx.doi.org/10.1016/j.jcp.2012.02.033">[DOI]</a>
+</b>).
+The HDG method achieves
+this goal by formulating the mathematical problem using Dirichlet-to-Neumann
+mappings.  The partial differential equations are first written as a first
+order system, and each field is then discretized via a DG method.  At this
+point the  single-valued ``trace'' values on the skeleton of the
+mesh, i.e. element edges, are taken to be independent unknown quantities.  
+The Dirichlet-to-Neumann map concept then permits the solution procedure:
+<ol>
+  <li> Solve a Dirichlet problem on each element individually, where the local/interior
+element solutions no longer couple to neighboring elements.  This is known as the
+'local solver', and is an <i>embarrissingly parallel</i> element-by-element 
+solution process.
+  <li>  Use the local element solutions to construct the global problem for the 
+trace values.  These are the only globally coupled unknowns.
+  <li>  Modify the local solutions from the computed trace values.
+</ol>
+
+Another criticism of traditional DG methods is that the approximate fluxes
+converge suboptimally.   The local HDG solutions can be shown to converge
+as $\mathcal{O}(h^{p+1})$.  Additionally, a super-convergence property can 
+be used to post-process a new approximate solution that converges at the 
+rate $\mathcal{O}(h^{p+2})$.
+
+
+
+<h3> HDG applied to the convection-diffusion problem </h3>
+
+The HDG formulation used for this example is taken from 
+<br>
+<b>
+  N.C. Nguyen, J. Peraire, B. Cockburn:
+  <i>An implicit high-order hybridizable discontinuous Galerkin method 
+  for linear convection–diffusion equations</i>, 
+  Journal of Computational Physics, 2009, 228:9, 3232-3254. 
+  <a href="http://dx.doi.org/10.1016/j.jcp.2009.01.030">[DOI]</a>
+</b>
+
+We consider the convection-diffusion equation:
+@f{eqnarray*}
+       \nabla \cdot (\mathbf{c} u) - \nabla \cdot (\kappa \nabla u) &=& f,
+       \quad \text{ in } \Omega, \\
+       u &=& g_D, \quad \text{ on } \partial \Omega_D, \\
+       (\mathbf{c} u - \kappa \nabla u)\cdot \mathbf{n} &=& g_N, 
+       \quad \text{ on }  \partial \Omega_D.
+@f}
+
+Introduce the auxiliary variable $\mathbf{q}=-\kappa \nabla u$ and rewrite
+the above equation as the first order system:
+@f{eqnarray*}
+  \mathbf{q} + \kappa \nabla u &=& 0, \quad \text{ in } \Omega, \\
+  \nabla \cdot (\mathbf{c} u + \mathbf{q}) &=& f, \quad \text{ in } \Omega, \\
+  u &=& g_D, \quad \text{ on } \partial \Omega_D, \\
+  (\mathbf{q} + \mathbf{c}u)\cdot\mathbf{n}  &=& g_N, 
+       \quad \text{ on }  \partial \Omega_D.
+@f}
+
+
+
+<h3> Problem specific data </h3>
+Example specific data:
+$\Omega := [-1,1]^d$
+
+\f[
+\mathbf{c} = \begin{cases}
+1, & \textrm{dim}=1 \\
+(y, -x), & \textrm{dim}=2 \\
+(y, -x, 1), & \textrm{dim}=3
+\end{cases}
+\f]
+
+the centers $x_i$ of the exponentials are 
+  $\{x_i\}_1^3 = \{ -\frac{1}{3}, 0, \frac{1}{3} \}$
+  $\{\mathbf{x}_i\}_1^3 = \{ (-\frac{1}{2},\frac{1}{2})
+                                                        (-\frac{1}{2},-\frac{1}{2})
+                                                        (\frac{1}{2},-\frac{1}{2})
+                                                 \}$
+  $\{\mathbf{x}_i\}_1^3 = \{ (-\frac{1}{2},\frac{1}{2}, \frac{1}{4})
+                                                        (-\frac{3}{5},-\frac{1}{2}, -\frac{1}{8})
+                                                        (\frac{1}{2},-\frac{1}{2}, \frac{1}{2})
+                                                 \}$
+   
+
+<h3> Implementation </h3>
+
+Implementation notes:
+
+- WorkStream to parallelize local solvers.  Workstream is already used in step-32, step-44.
+- Reconstructing the trace
+- Post-processing the solution for superconvergence
+- DataOutFaces:  direct output of the global solution
\ No newline at end of file
diff --git a/deal.II/examples/step-51/doc/kind b/deal.II/examples/step-51/doc/kind
new file mode 100644 (file)
index 0000000..c1d9154
--- /dev/null
@@ -0,0 +1 @@
+techniques
diff --git a/deal.II/examples/step-51/doc/results.dox b/deal.II/examples/step-51/doc/results.dox
new file mode 100644 (file)
index 0000000..ae6e002
--- /dev/null
@@ -0,0 +1,184 @@
+<h1>Results</h1>
+
+
+When the program is run, it outputs information about the respective steps and
+convergence tables with errors in the various components in the end. In 2D,
+the convergence tables look the following:
+
+@code
+Q1 elements, adaptive refinement:
+cells dofs   val L2    grad L2  val L2-post 
+    4    24 6.101e+00 1.065e+01   5.098e+00 
+   10    58 3.168e+00 9.223e+00   2.431e+00 
+   28   148 2.888e+00 9.368e+00   2.644e+00 
+   55   272 6.756e-01 4.088e+00   2.400e-01 
+  109   578 2.175e-01 1.529e+00   7.350e-02 
+  214  1072 9.783e-02 9.006e-01   2.219e-02 
+  409  2056 4.812e-02 5.193e-01   1.081e-02 
+  811  3880 2.714e-02 2.971e-01   4.669e-03 
+ 1555  7204 1.365e-02 1.789e-01   2.627e-03 
+ 2956 13198 7.919e-03 1.009e-01   1.006e-03 
+
+Q1 elements, global refinement:
+cells dofs      val L2        grad L2      val L2-post   
+   16    80 4.570e+00    - 1.221e+01    - 4.333e+00    -
+   36   168 1.869e+00 2.20 7.299e+00 1.27 1.734e+00 2.26
+   64   288 7.177e-01 3.33 4.218e+00 1.91 2.538e-01 6.68
+  144   624 2.729e-01 2.38 1.867e+00 2.01 6.110e-02 3.51
+  256  1088 1.493e-01 2.10 1.046e+00 2.01 2.878e-02 2.62
+  576  2400 6.964e-02 1.88 4.847e-01 1.90 9.202e-03 2.81
+ 1024  4224 4.018e-02 1.91 2.785e-01 1.93 4.027e-03 2.87
+ 2304  9408 1.831e-02 1.94 1.264e-01 1.95 1.236e-03 2.91
+ 4096 16640 1.043e-02 1.96 7.185e-02 1.96 5.306e-04 2.94
+ 9216 37248 4.690e-03 1.97 3.228e-02 1.97 1.600e-04 2.96
+
+Q3 elements, global refinement:
+cells dofs      val L2        grad L2      val L2-post   
+   16   160 2.398e-01    - 1.873e+00    - 1.354e-01    -
+   36   336 5.843e-02 3.48 5.075e-01 3.22 1.882e-02 4.87
+   64   576 3.466e-02 1.82 2.534e-01 2.41 4.326e-03 5.11
+  144  1248 8.297e-03 3.53 5.925e-02 3.58 6.330e-04 4.74
+  256  2176 2.254e-03 4.53 1.636e-02 4.47 1.403e-04 5.24
+  576  4800 4.558e-04 3.94 3.278e-03 3.96 1.844e-05 5.01
+ 1024  8448 1.471e-04 3.93 1.052e-03 3.95 4.378e-06 5.00
+ 2304 18816 2.956e-05 3.96 2.104e-04 3.97 5.751e-07 5.01
+ 4096 33280 9.428e-06 3.97 6.697e-05 3.98 1.362e-07 5.01
+ 9216 74496 1.876e-06 3.98 1.330e-05 3.99 1.817e-08 4.97
+@endcode
+
+
+One can see the error reduction upon grid refinement, and for the cases where
+global refinement was performed, also the convergence rates can be seen. The
+quadratic convergence rates of Q1 elements in the $L_2$ norm for both the
+scalar variable and the gradient variable can clearly be seen, as is the cubic
+rate for the postprocessed scalar variable in the $L_2$ norm. Likewise, the
+scalar variable and gradient for Q3 elements converge at fourth order and the
+postprocessed scalar variable at fifth order.
+
+The same convergence rates are observed in 3d.
+@code
+Q1 elements, adaptive refinement:
+cells   dofs    val L2    grad L2  val L2-post 
+     8     144 3.846e+00 1.519e+01   2.388e+00 
+    29     500 2.800e+00 9.885e+00   1.185e+00 
+   113    1792 1.772e+00 9.911e+00   1.423e+00 
+   379    5736 6.057e-01 5.011e+00   2.180e-01 
+  1317   19412 1.542e-01 1.465e+00   4.176e-02 
+  4579   64768 5.059e-02 5.615e-01   9.563e-03 
+ 14596  199552 2.128e-02 3.124e-01   4.599e-03 
+ 46180  611380 1.032e-02 1.623e-01   1.643e-03 
+144859 1864212 4.996e-03 8.376e-02   6.898e-04 
+451053 5684324 2.516e-03 4.559e-02   2.832e-04 
+
+Q1 elements, global refinement:
+cells   dofs       val L2          grad L2       val L2-post   
+     8     144 3.846e+00     - 1.519e+01     - 2.388e+00     - 
+    27     432 4.677e+00 -0.48 2.158e+01 -0.87 3.441e+00 -0.90 
+    64     960 2.366e+00  2.37 1.228e+01  1.96 1.831e+00  2.19 
+   216    3024 1.225e+00  1.62 8.396e+00  0.94 1.017e+00  1.45 
+   512    6912 6.870e-01  2.01 5.314e+00  1.59 2.421e-01  4.99 
+  1728   22464 2.912e-01  2.12 2.494e+00  1.87 8.593e-02  2.56 
+  4096   52224 1.683e-01  1.91 1.455e+00  1.87 4.056e-02  2.61 
+ 13824  172800 7.970e-02  1.84 6.866e-01  1.85 1.335e-02  2.74 
+ 32768  405504 4.637e-02  1.88 3.986e-01  1.89 5.932e-03  2.82 
+110592 1354752 2.133e-02  1.92 1.831e-01  1.92 1.851e-03  2.87 
+
+Q3 elements, global refinement:
+cells   dofs       val L2        grad L2      val L2-post   
+     8     576 3.845e+00    - 1.742e+01    - 3.550e+00    - 
+    27    1728 8.915e-01 3.60 6.939e+00 2.27 5.865e-01 4.44 
+    64    3840 2.807e-01 4.02 2.713e+00 3.26 1.326e-01 5.17 
+   216   12096 7.866e-02 3.14 7.727e-01 3.10 2.112e-02 4.53 
+   512   27648 3.640e-02 2.68 3.307e-01 2.95 5.224e-03 4.86 
+  1728   89856 8.545e-03 3.57 7.586e-02 3.63 7.642e-04 4.74 
+  4096  208896 2.598e-03 4.14 2.314e-02 4.13 1.783e-04 5.06 
+ 13824  691200 5.314e-04 3.91 4.699e-03 3.93 2.355e-05 4.99 
+ 32768 1622016 1.723e-04 3.91 1.518e-03 3.93 5.603e-06 4.99 
+110592 5419008 3.482e-05 3.94 3.057e-04 3.95 7.375e-07 5.00 
+@endcode
+
+
+<h3>Possibilities for improvements</h3>
+
+This tutorial program shows the a basic implementation of an HDG method
+without particular focus on a high performance implementation. Let us look at
+the computing time of the tutorial program and the share of the individual
+components:
+
+<table align="center" border="1">
+  <tr>
+    <th>&nbsp;</th>
+    <th>&nbsp;</th>
+    <th>Setup</th>
+    <th>Assemble</th>
+    <th>Solve</th>
+    <th>Trace reconstruct</th>
+    <th>Post-processing</th>
+    <th>Output</th>
+  </tr>
+  <tr>
+    <th>&nbsp;</th>
+    <th>Total time</th>
+    <th colspan="6">Relative share</th>
+  </tr>
+  <tr>
+    <td align="left">2D, Q1, cycle 9, 37,248 dofs</td>
+    <td align="center">5.34s</td>
+    <td align="center">0.7%</td>
+    <td align="center">1.2%</td>
+    <td align="center">89.5%</td>
+    <td align="center">0.9%</td>
+    <td align="center">2.3%</td>
+    <td align="center">5.4%</td>
+  </tr>
+  <tr>
+    <td align="left">2D, Q3, cycle 9, 74,496 dofs</td>
+    <td align="center">22.2s</td>
+    <td align="center">0.4%</td>
+    <td align="center">4.3%</td>
+    <td align="center">84.1%</td>
+    <td align="center">4.1%</td>
+    <td align="center">3.5%</td>
+    <td align="center">3.6%</td>
+  </tr>
+  <tr>
+    <td align="left">3D, Q1, cycle 7, 172,800 dofs</td>
+    <td align="center">9.06s</td>
+    <td align="center">3.1%</td>
+    <td align="center">8.9%</td>
+    <td align="center">42.7%</td>
+    <td align="center">7.0%</td>
+    <td align="center">20.6%</td>
+    <td align="center">17.7%</td>
+  </tr>
+  <tr>
+    <td align="left">3D, Q3, cycle 7, 691,200 dofs</td>
+    <td align="center">516s</td>
+    <td align="center">0.6%</td>
+    <td align="center">34.5%</td>
+    <td align="center">13.4%</td>
+    <td align="center">32.8%</td>
+    <td align="center">17.1%</td>
+    <td align="center">1.5%</td>
+  </tr>
+</table>
+
+As can be seen from the table, the solver and assembly calls dominate the
+runtime of the program. This also gives a clear indication of where an
+improvement makes most sense.
+
+<ol>
+  <li> Better linear solvers: We use a GMRES iterative solver without
+  preconditioner, where the number of iteration increases with increasing
+  problem size (the number of iterations for Q1 elements and global
+  refinements start at 8 for the small sizes but increase up to 2592 for the
+  largest size). To do better, one could for example use an algebraic
+  multigrid preconditioner from Trilinos. For diffusion-dominated problems as
+  the problem at hand with finer meshes, such a solver can be designed that
+  uses the matrix-vector products from the more efficient ChunkSparseMatrix on
+  the finest level, as long as we are not working in parallel with MPI.
+
+  <li> Speed up assembly by pre-assembling parts that do not change from one
+  cell to another (those that do neither contain variable coefficients nor
+  mapping-dependent terms.
+</ol>
diff --git a/deal.II/examples/step-51/doc/tooltip b/deal.II/examples/step-51/doc/tooltip
new file mode 100644 (file)
index 0000000..784e257
--- /dev/null
@@ -0,0 +1 @@
+Convection-diffusion equation. Hybridizable discontinuous Galerkin methods. Face elements.
diff --git a/deal.II/examples/step-51/step-51.cc b/deal.II/examples/step-51/step-51.cc
new file mode 100644 (file)
index 0000000..bc4778c
--- /dev/null
@@ -0,0 +1,1223 @@
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2013 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
+ * Author: Martin Kronbichler, Technische Universität München,
+ *         Scott T. Miller, The Pennsylvania State University, 2013
+ */
+
+// @sect3{Include files}
+//
+// Most of the deal.II include files have already been covered in previous
+// examples are are not commented on.
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/tensor_function.h>
+#include <deal.II/base/exceptions.h>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/work_stream.h>
+#include <deal.II/base/convergence_table.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/compressed_simple_sparsity_pattern.h>
+#include <deal.II/lac/solver_gmres.h>
+#include <deal.II/lac/precondition.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_accessor.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_refinement.h>
+#include <deal.II/grid/tria_iterator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_renumbering.h>
+#include <deal.II/dofs/dof_tools.h>
+#include <deal.II/fe/fe_dgq.h>
+#include <deal.II/fe/fe_system.h>
+#include <deal.II/fe/fe_values.h>
+#include <deal.II/numerics/vector_tools.h>
+#include <deal.II/numerics/error_estimator.h>
+#include <deal.II/numerics/matrix_tools.h>
+#include <deal.II/numerics/data_out.h>
+
+// However, we do have a few new includes for the example.
+// The first one defines finite element spaces on the faces
+// of the triangulation, which we refer to as the 'skeleton'.
+// These finite elements do not have any support on the element
+// interior, and they represent polynomials that have a single
+// value on each codimension-1 surface, but admit discontinuities
+// on codimension-2 surfaces.
+#include <deal.II/fe/fe_face.h>
+
+// The second new file we include defines a new type of sparse matrix.
+// The regular <code>SparseMatrix</code> type stores indices to all non-zero entries.
+// The <code>ChunkSparseMatrix</code> takes advantage of the coupled nature of
+// DG solutions.  It stores an index to a matrix sub-block of a specified
+// size.  In the HDG context, this sub-block-size is actually the number
+// of degrees of freedom per face defined by the skeleton solution field.
+#include <deal.II/lac/chunk_sparse_matrix.h>
+
+// The final new include for this example deals with data output.  Since
+// we have a finite element field defined on the skeleton of the mesh,
+// we would like to visualize what that solution actually is.
+// DataOutFaces does exactly this; the interface is the almost the same
+// as the familiar DataOut, but the output only has codimension-1 data for
+// the simulation.
+#include <deal.II/numerics/data_out_faces.h>
+
+using namespace dealii;
+
+// @sect3{Equation data}
+//
+// The structure of the analytic solution is the same as in step-7. There
+// are two exceptions. Firstly, we also create a solution for the 3d case,
+// and secondly, we take into account the convection velocity in the right
+// hand side that is variable in this case.
+template <int dim>
+class SolutionBase
+{
+protected:
+  static const unsigned int  n_source_centers = 3;
+  static const Point<dim>    source_centers[n_source_centers];
+  static const double        width;
+};
+
+
+template <>
+const Point<1>
+SolutionBase<1>::source_centers[SolutionBase<1>::n_source_centers]
+= { Point<1>(-1.0 / 3.0),
+    Point<1>(0.0),
+    Point<1>(+1.0 / 3.0)
+};
+
+
+template <>
+const Point<2>
+SolutionBase<2>::source_centers[SolutionBase<2>::n_source_centers]
+= { Point<2>(-0.5, +0.5),
+    Point<2>(-0.5, -0.5),
+    Point<2>(+0.5, -0.5)
+};
+
+template <>
+const Point<3>
+SolutionBase<3>::source_centers[SolutionBase<3>::n_source_centers]
+= { Point<3>(-0.5, +0.5, 0.25),
+    Point<3>(-0.6, -0.5, -0.125),
+    Point<3>(+0.5, -0.5, 0.5)   };
+
+template <int dim>
+const double SolutionBase<dim>::width = 1./5.;
+
+
+
+template <int dim>
+class ConvectionVelocity : public TensorFunction<1,dim>
+{
+public:
+  ConvectionVelocity() : TensorFunction<1,dim>() {}
+
+  virtual Tensor<1,dim> value (const Point<dim> &p) const;
+};
+
+
+
+template <int dim>
+Tensor<1,dim>
+ConvectionVelocity<dim>::value(const Point<dim> &p) const
+{
+  Tensor<1,dim> convection;
+  switch (dim)
+    {
+    case 1:
+      convection[0] = 1;
+      break;
+    case 2:
+      convection[0] = p[1];
+      convection[1] = -p[0];
+      break;
+    case 3:
+      convection[0] = p[1];
+      convection[1] = -p[0];
+      convection[2] = 1;
+      break;
+    default:
+      Assert(false, ExcNotImplemented());
+    }
+  return convection;
+}
+
+
+template <int dim>
+class Solution : public Function<dim>,
+                 protected SolutionBase<dim>
+{
+public:
+  Solution () : Function<dim>() {}
+
+  virtual double value (const Point<dim>   &p,
+                        const unsigned int  component = 0) const;
+
+  virtual Tensor<1,dim> gradient (const Point<dim>   &p,
+                                  const unsigned int  component = 0) const;
+};
+
+
+
+template <int dim>
+double Solution<dim>::value (const Point<dim>   &p,
+                             const unsigned int) const
+{
+  double return_value = 0;
+  for (unsigned int i=0; i<this->n_source_centers; ++i)
+    {
+      const Point<dim> x_minus_xi = p - this->source_centers[i];
+      return_value += std::exp(-x_minus_xi.square() /
+                               (this->width * this->width));
+    }
+
+  return return_value /
+    Utilities::fixed_power<dim>(std::sqrt(2. * numbers::PI) * this->width);
+}
+
+
+
+template <int dim>
+Tensor<1,dim> Solution<dim>::gradient (const Point<dim>   &p,
+                                       const unsigned int) const
+{
+  Tensor<1,dim> return_value;
+
+  for (unsigned int i=0; i<this->n_source_centers; ++i)
+    {
+      const Point<dim> x_minus_xi = p - this->source_centers[i];
+
+      return_value += (-2 / (this->width * this->width) *
+                       std::exp(-x_minus_xi.square() /
+                                (this->width * this->width)) *
+                       x_minus_xi);
+    }
+
+  return return_value / Utilities::fixed_power<dim>(std::sqrt(2 * numbers::PI) *
+                                                    this->width);
+}
+
+
+
+template <int dim>
+class SolutionAndGradient : public Function<dim>,
+                            protected SolutionBase<dim>
+{
+public:
+  SolutionAndGradient () : Function<dim>(dim) {}
+
+  virtual void vector_value (const Point<dim>   &p,
+                             Vector<double>     &v) const
+  {
+    AssertDimension(v.size(), dim+1);
+    Solution<dim> solution;
+    Tensor<1,dim> grad = solution.gradient(p);
+    for (unsigned int d=0; d<dim; ++d)
+      v[d] = -grad[d];
+    v[dim] = solution.value(p);
+  }
+};
+
+
+
+template <int dim>
+class RightHandSide : public Function<dim>,
+                      protected SolutionBase<dim>
+{
+public:
+  RightHandSide () : Function<dim>() {}
+
+  virtual double value (const Point<dim>   &p,
+                        const unsigned int  component = 0) const;
+
+private:
+  const ConvectionVelocity<dim> convection_velocity;
+};
+
+
+template <int dim>
+double RightHandSide<dim>::value (const Point<dim>   &p,
+                                  const unsigned int) const
+{
+  Tensor<1,dim> convection = convection_velocity.value(p);
+  double return_value = 0;
+  for (unsigned int i=0; i<this->n_source_centers; ++i)
+    {
+      const Point<dim> x_minus_xi = p - this->source_centers[i];
+
+      return_value +=
+        ((2*dim - 2*convection*x_minus_xi - 4*x_minus_xi.square()/
+          (this->width * this->width)) /
+         (this->width * this->width) *
+         std::exp(-x_minus_xi.square() /
+                  (this->width * this->width)));
+    }
+
+  return return_value / Utilities::fixed_power<dim>(std::sqrt(2 * numbers::PI)
+                                                    * this->width);
+}
+
+// @sect3{The Step51 HDG solver class}
+
+// The HDG solution procedure follows closely that of step-7.  The major
+// difference is the use of 3 different sets of <code>DoFHandler</code> and FE objects,
+// along with the <code>ChunkSparseMatrix</code> and the corresponding solutions vectors.
+// We also use WorkStream to enable a multi-threaded local solution process which exploits
+// the embarrassingly parallel nature of the local solver.
+
+template <int dim>
+class Step51
+{
+public:
+  enum RefinementMode
+    {
+      global_refinement, adaptive_refinement
+    };
+
+  Step51 (const unsigned int degree,
+          const RefinementMode refinement_mode);
+  void run ();
+
+private:
+    
+  struct PerTaskData;
+  struct ScratchData;
+  
+  struct EmptyData;
+  struct PostProcessScratchData;
+  void NullFunction(const EmptyData &data);
+    
+  void setup_system ();
+  void assemble_system (const bool reconstruct_trace = false);
+  void assemble_system_one_cell (const typename DoFHandler<dim>::active_cell_iterator &cell,
+                                   ScratchData &scratch,
+                                   PerTaskData &task_data);
+  void copy_local_to_global(const PerTaskData &data);
+  void solve ();
+  void postprocess ();
+  void postprocess_one_cell (const typename DoFHandler<dim>::active_cell_iterator &cell,
+                                   PostProcessScratchData &scratch,
+                                   EmptyData &task_data);
+  void refine_grid (const unsigned int cylce);
+  void output_results (const unsigned int cycle);
+
+  Triangulation<dim>   triangulation;
+  
+// The 'local' solutions are interior to each element.  These
+// represent the primal solution field $u$ as well as the auxiliary
+// field $\mathbf{q} = \nabla u$. 
+  FESystem<dim>        fe_local;
+  DoFHandler<dim>      dof_handler_local;
+
+// The new finite element type and corresponding <code>DoFHandler</code>
+// are used for the global solution that couples the element-level local
+// solution.
+  FE_FaceQ<dim>        fe;
+  DoFHandler<dim>      dof_handler;
+
+// As stated in the introduction, HDG solutions can be post-processed to
+// attain superconvegence rates of $\mathcal{O}(h^{p+2})$.
+// The post-processed solution is a discontinuous finite element solution
+// representing the primal variable on the interior of each cell.
+// We define a FE type to represent this post-processed solution, which we
+// only use for output after constructing it.
+  FE_DGQ<dim>          fe_u_post;
+  DoFHandler<dim>      dof_handler_u_post;
+
+// The degrees of freedom corresponding to the skeleton strongly enforce
+// Dirichlet boundary conditions, just as in a continuous Galerkin finite
+// element method.  We can enforce the boundary conditions in an analogous
+// manner through the use of <code>ConstrainMatrix</code> constructs.
+  ConstraintMatrix     constraints;
+  
+  // Comment on chunk.
+  ChunkSparsityPattern sparsity_pattern;
+  ChunkSparseMatrix<double> system_matrix;
+
+  // Global/skeleton solution/rhs
+  Vector<double>       solution;
+  Vector<double>       system_rhs;
+
+  // Local elementwise solution
+  Vector<double>       solution_local;
+  
+  // HDG solutions can be post-processed
+  // to gain one order of accuracy.
+  // <code>solution_u_post</code> will be
+  // our post-processed DG solution on the
+  // interior of cells represented by a 
+  // DG solution of order (degree+1)
+  Vector<double>       solution_u_post;
+
+  // Same as step-7:
+  const RefinementMode refinement_mode;
+
+  ConvergenceTable     convergence_table;
+};
+
+
+
+template <int dim>
+Step51<dim>::Step51 (const unsigned int degree,
+                     const RefinementMode refinement_mode) :
+  fe_local (FE_DGQ<dim>(degree), dim,
+            FE_DGQ<dim>(degree), 1),
+  dof_handler_local (triangulation),
+  fe (degree),
+  dof_handler (triangulation),
+  fe_u_post (degree+1),
+  dof_handler_u_post (triangulation),
+  refinement_mode (refinement_mode)
+{}
+
+template <int dim>
+struct Step51<dim>::PerTaskData
+{
+    FullMatrix<double> cell_matrix;
+    Vector<double>     cell_vector;
+    std::vector<types::global_dof_index> dof_indices;
+    
+    bool trace_reconstruct;
+    
+    PerTaskData(const unsigned int n_dofs, const bool trace_reconstruct)
+    : cell_matrix(n_dofs, n_dofs),
+      cell_vector(n_dofs),
+      dof_indices(n_dofs),
+      trace_reconstruct(trace_reconstruct)
+    {}
+    
+    void reset(){
+        cell_matrix = 0.0;
+        cell_vector = 0.0;
+    }
+};
+
+template <int dim>
+struct Step51<dim>::ScratchData
+{
+    FEValues<dim>     fe_values_local;
+    FEFaceValues<dim> fe_face_values_local;
+    FEFaceValues<dim> fe_face_values;
+    
+    FullMatrix<double> ll_matrix;
+    FullMatrix<double> lf_matrix;
+    FullMatrix<double> fl_matrix;
+    FullMatrix<double> tmp_matrix;
+    Vector<double>     l_rhs;
+    Vector<double>     tmp_rhs;
+    
+    std::vector<Tensor<1,dim> > q_phi;
+    std::vector<double>         q_phi_div;
+    std::vector<double>         u_phi;
+    std::vector<Tensor<1,dim> > u_phi_grad;
+    std::vector<double>         tr_phi;
+    std::vector<double>         trace_values;
+    
+    std::vector<std::vector<unsigned int> > fe_local_support_on_face;
+    std::vector<std::vector<unsigned int> > fe_support_on_face;
+    
+    ConvectionVelocity<dim> convection_velocity;
+    RightHandSide<dim> right_hand_side;
+    const Solution<dim> exact_solution;
+    
+        // Full constructor
+    ScratchData(const FiniteElement<dim> &fe,
+                const FiniteElement<dim> &fe_local,
+                const QGauss<dim>   &quadrature_formula,
+                const QGauss<dim-1> &face_quadrature_formula,
+                const UpdateFlags local_flags,
+                const UpdateFlags local_face_flags,
+                const UpdateFlags flags)
+      :
+      fe_values_local (fe_local, quadrature_formula, local_flags),
+      fe_face_values_local (fe_local, face_quadrature_formula, local_face_flags),
+      fe_face_values (fe, face_quadrature_formula, flags),
+      ll_matrix (fe_local.dofs_per_cell, fe_local.dofs_per_cell),
+      lf_matrix (fe_local.dofs_per_cell, fe.dofs_per_cell),
+      fl_matrix (fe.dofs_per_cell, fe_local.dofs_per_cell),
+      tmp_matrix (fe.dofs_per_cell, fe_local.dofs_per_cell),
+      l_rhs (fe_local.dofs_per_cell),
+      tmp_rhs (fe_local.dofs_per_cell),
+      q_phi (fe_local.dofs_per_cell),
+      q_phi_div (fe_local.dofs_per_cell),
+      u_phi (fe_local.dofs_per_cell),
+      u_phi_grad (fe_local.dofs_per_cell),
+      tr_phi (fe.dofs_per_cell),
+      trace_values(face_quadrature_formula.size()),
+      fe_local_support_on_face(GeometryInfo<dim>::faces_per_cell),
+      fe_support_on_face(GeometryInfo<dim>::faces_per_cell)
+    {
+        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            for (unsigned int i=0; i<fe_local.dofs_per_cell; ++i) {
+                if (fe_local.has_support_on_face(i,face))
+                    fe_local_support_on_face[face].push_back(i);
+            }
+        
+        for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            for (unsigned int i=0; i<fe.dofs_per_cell; ++i) {
+                if (fe.has_support_on_face(i,face))
+                    fe_support_on_face[face].push_back(i);
+            }
+    }
+    
+        // Copy constructor
+    ScratchData(const ScratchData &sd)
+      :
+      fe_values_local (sd.fe_values_local.get_fe(),
+                       sd.fe_values_local.get_quadrature(),
+                       sd.fe_values_local.get_update_flags()),
+      fe_face_values_local (sd.fe_face_values_local.get_fe(),
+                            sd.fe_face_values_local.get_quadrature(),
+                            sd.fe_face_values_local.get_update_flags()),
+      fe_face_values (sd.fe_face_values.get_fe(),
+                      sd.fe_face_values.get_quadrature(),
+                      sd.fe_face_values.get_update_flags()),
+      ll_matrix (sd.ll_matrix),
+      lf_matrix (sd.lf_matrix),
+      fl_matrix (sd.fl_matrix),
+      tmp_matrix (sd.tmp_matrix),
+      l_rhs (sd.l_rhs),
+      tmp_rhs (sd.tmp_rhs),
+      q_phi (sd.q_phi),
+      q_phi_div (sd.q_phi_div),
+      u_phi (sd.u_phi),
+      u_phi_grad (sd.u_phi_grad),
+      tr_phi (sd.tr_phi),
+      trace_values(sd.trace_values),
+      fe_local_support_on_face(sd.fe_local_support_on_face),
+      fe_support_on_face(sd.fe_support_on_face)
+    {}
+    
+// We manually reset our matrices to zero in the assembly process,
+// since certain matrices are only used in the reconstruction process.
+// We therefore do not implement an methods in <code>reset()</code>, but
+// need to have it for the WorkStream interface.   
+    void reset() {}
+    
+};
+
+template <int dim>
+struct Step51<dim>::EmptyData
+{
+    EmptyData(){}
+    void reset(){}
+};
+
+template <int dim>
+struct Step51<dim>::PostProcessScratchData
+{
+  FEValues<dim> fe_values_local;
+  FEValues<dim> fe_values;
+    
+  std::vector<double> u_values;
+  std::vector<Tensor<1,dim> > u_gradients;
+  FullMatrix<double> cell_matrix;
+  
+  Vector<double> cell_rhs;
+  Vector<double> cell_sol;
+    
+        // Full constructor
+  PostProcessScratchData(const FiniteElement<dim> &fe,
+                const FiniteElement<dim> &fe_local,
+                const QGauss<dim>   &quadrature_formula,
+                const UpdateFlags local_flags,
+                const UpdateFlags flags)
+      :
+      fe_values_local (fe_local, quadrature_formula, local_flags),
+      fe_values (fe, quadrature_formula, flags),
+      u_values (quadrature_formula.size()),
+      u_gradients (quadrature_formula.size()),
+      cell_matrix (fe.dofs_per_cell, fe.dofs_per_cell),
+      cell_rhs (fe.dofs_per_cell),
+      cell_sol (fe.dofs_per_cell)
+      {}
+    
+        // Copy constructor
+  PostProcessScratchData(const PostProcessScratchData &sd)
+      :
+      fe_values_local (sd.fe_values_local.get_fe(),
+                       sd.fe_values_local.get_quadrature(),
+                       sd.fe_values_local.get_update_flags()),
+      fe_values (sd.fe_values.get_fe(),
+                      sd.fe_values.get_quadrature(),
+                      sd.fe_values.get_update_flags()),
+      u_values (sd.u_values),
+      u_gradients (sd.u_gradients),
+      cell_matrix (sd.cell_matrix),
+      cell_rhs (sd.cell_rhs),
+      cell_sol (sd.cell_sol)
+    {}
+       
+    void reset() {
+      cell_matrix = 0.;
+      cell_rhs = 0.;
+      cell_sol = 0.;
+    }
+    
+};
+
+template <int dim>
+void Step51<dim>::NullFunction(const EmptyData &data){}
+
+template <int dim>
+void Step51<dim>::copy_local_to_global(const PerTaskData &data)
+{
+    if(data.trace_reconstruct == false)
+      constraints.distribute_local_to_global (data.cell_matrix,
+                                              data.cell_vector,
+                                              data.dof_indices,
+                                              system_matrix, system_rhs);
+}
+
+template <int dim>
+void
+Step51<dim>::setup_system ()
+{
+  dof_handler_local.distribute_dofs(fe_local);
+  dof_handler.distribute_dofs(fe);
+  dof_handler_u_post.distribute_dofs(fe_u_post);
+
+  std::cout << "   Number of degrees of freedom: "
+            << dof_handler.n_dofs()
+            << std::endl;
+
+  solution.reinit (dof_handler.n_dofs());
+  system_rhs.reinit (dof_handler.n_dofs());
+
+  solution_local.reinit (dof_handler_local.n_dofs());
+  solution_u_post.reinit (dof_handler_u_post.n_dofs());
+
+  constraints.clear ();
+  DoFTools::make_hanging_node_constraints (dof_handler, constraints);
+  typename FunctionMap<dim>::type boundary_functions;
+  Solution<dim> solution_function;
+  boundary_functions[0] = &solution_function;
+  VectorTools::project_boundary_values (dof_handler,
+                                        boundary_functions,
+                                        QGauss<dim-1>(fe.degree+1),
+                                        constraints);
+  constraints.close ();
+
+  {
+    CompressedSimpleSparsityPattern csp (dof_handler.n_dofs());
+    DoFTools::make_sparsity_pattern (dof_handler, csp,
+                                     constraints, false);
+    sparsity_pattern.copy_from(csp, fe.dofs_per_face);
+  }
+  system_matrix.reinit (sparsity_pattern);
+}
+
+
+
+template <int dim>
+void
+Step51<dim>::assemble_system (const bool trace_reconstruct)
+{
+    const QGauss<dim>   quadrature_formula(fe.degree+1);
+    const QGauss<dim-1> face_quadrature_formula(fe.degree+1);
+    
+    const UpdateFlags local_flags (update_values | update_gradients |
+                                   update_JxW_values | update_quadrature_points);
+    
+    const UpdateFlags local_face_flags (update_values);
+    
+    const UpdateFlags flags ( update_values | update_normal_vectors |
+                             update_quadrature_points |
+                             update_JxW_values);
+    
+    PerTaskData task_data (fe.dofs_per_cell,
+                           trace_reconstruct);
+    ScratchData scratch (fe, fe_local,
+                         quadrature_formula,
+                         face_quadrature_formula,
+                         local_flags,
+                         local_face_flags,
+                         flags);
+    
+    WorkStream::run(dof_handler.begin_active(),
+                    dof_handler.end(),
+                    *this,
+                    &Step51<dim>::assemble_system_one_cell,
+                    &Step51<dim>::copy_local_to_global,
+                    scratch,
+                    task_data);
+}
+
+
+template <int dim>
+void
+Step51<dim>::assemble_system_one_cell (const typename DoFHandler<dim>::active_cell_iterator &cell,
+                                       ScratchData &scratch,
+                                       PerTaskData &task_data)
+{
+        // Construct iterator for dof_handler_local
+  typename DoFHandler<dim>::active_cell_iterator
+    loc_cell (&triangulation,
+              cell->level(),
+              cell->index(),
+              &dof_handler_local);
+
+  const unsigned int n_q_points    = scratch.fe_values_local.get_quadrature().size();
+  const unsigned int n_face_q_points = scratch.fe_face_values_local.get_quadrature().size();
+
+        //  const unsigned int dofs_per_cell = scratch.fe_face_values.get_fe().dofs_per_cell;
+  const unsigned int loc_dofs_per_cell = scratch.fe_values_local.get_fe().dofs_per_cell;
+
+  // Choose stabilization parameter to be 5 * diffusion = 5
+  const double tau_stab_diffusion = 5.;
+
+  const FEValuesExtractors::Vector fluxes (0);
+  const FEValuesExtractors::Scalar scalar (dim);
+
+      scratch.ll_matrix = 0;
+      scratch.l_rhs = 0;
+      if (!task_data.trace_reconstruct)
+        {
+          scratch.lf_matrix = 0;
+          scratch.fl_matrix = 0;
+          task_data.reset();
+        }
+      scratch.fe_values_local.reinit (loc_cell);
+
+      for (unsigned int q=0; q<n_q_points; ++q)
+        {
+          const double rhs_value
+            = scratch.right_hand_side.value(scratch.fe_values_local.quadrature_point(q));
+          const Tensor<1,dim> convection
+            = scratch.convection_velocity.value(scratch.fe_values_local.quadrature_point(q));
+          const double JxW = scratch.fe_values_local.JxW(q);
+          for (unsigned int k=0; k<loc_dofs_per_cell; ++k)
+            {
+              scratch.q_phi[k] = scratch.fe_values_local[fluxes].value(k,q);
+              scratch.q_phi_div[k] = scratch.fe_values_local[fluxes].divergence(k,q);
+              scratch.u_phi[k] = scratch.fe_values_local[scalar].value(k,q);
+              scratch.u_phi_grad[k] = scratch.fe_values_local[scalar].gradient(k,q);
+            }
+          for (unsigned int i=0; i<loc_dofs_per_cell; ++i)
+            {
+              for (unsigned int j=0; j<loc_dofs_per_cell; ++j)
+                scratch.ll_matrix(i,j) += (
+                                   scratch.q_phi[i] * scratch.q_phi[j]
+                                   -
+                                   scratch.q_phi_div[i] * scratch.u_phi[j]
+                                   +
+                                   scratch.u_phi[i] * scratch.q_phi_div[j]
+                                   -
+                                   (scratch.u_phi_grad[i] * convection) * scratch.u_phi[j]
+                                   ) * JxW;
+              scratch.l_rhs(i) += scratch.u_phi[i] * rhs_value * JxW;
+            }
+        }
+
+      for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+        {
+          scratch.fe_face_values_local.reinit(loc_cell, face);
+          scratch.fe_face_values.reinit(cell, face);
+          if (task_data.trace_reconstruct)
+            scratch.fe_face_values.get_function_values (solution, scratch.trace_values);
+
+          for (unsigned int q=0; q<n_face_q_points; ++q)
+            {
+              const double JxW = scratch.fe_face_values.JxW(q);
+              const Point<dim> normal = scratch.fe_face_values.normal_vector(q);
+              const Tensor<1,dim> convection
+                = scratch.convection_velocity.value(scratch.fe_face_values.quadrature_point(q));
+              const double tau_stab = (tau_stab_diffusion +
+                                       std::abs(convection * normal));
+
+              for (unsigned int k=0; k<scratch.fe_local_support_on_face[face].size(); ++k)
+                {
+                  const unsigned int kk=scratch.fe_local_support_on_face[face][k];
+                  scratch.q_phi[k] = scratch.fe_face_values_local[fluxes].value(kk,q);
+                  scratch.u_phi[k] = scratch.fe_face_values_local[scalar].value(kk,q);
+                }
+
+              if (!task_data.trace_reconstruct)
+                {
+                  for (unsigned int k=0; k<scratch.fe_support_on_face[face].size(); ++k)
+                    scratch.tr_phi[k] =
+                      scratch.fe_face_values.shape_value(scratch.fe_support_on_face[face][k],q);
+                  for (unsigned int i=0; i<scratch.fe_local_support_on_face[face].size(); ++i)
+                    for (unsigned int j=0; j<scratch.fe_support_on_face[face].size(); ++j)
+                      {
+                        const unsigned int ii=scratch.fe_local_support_on_face[face][i];
+                        const unsigned int jj=scratch.fe_support_on_face[face][j];
+                        scratch.lf_matrix(ii,jj) += (
+                                             (scratch.q_phi[i] * normal
+                                              +
+                                              (convection * normal -
+                                               tau_stab) * scratch.u_phi[i])
+                                             * scratch.tr_phi[j]
+                                             ) * JxW;
+                        scratch.fl_matrix(jj,ii) -= (
+                                             (scratch.q_phi[i] * normal
+                                              +
+                                              tau_stab * scratch.u_phi[i])
+                                             * scratch.tr_phi[j]
+                                             ) * JxW;
+                      }
+
+                  for (unsigned int i=0; i<scratch.fe_support_on_face[face].size(); ++i)
+                    for (unsigned int j=0; j<scratch.fe_support_on_face[face].size(); ++j)
+                      {
+                        const unsigned int ii=scratch.fe_support_on_face[face][i];
+                        const unsigned int jj=scratch.fe_support_on_face[face][j];
+                        task_data.cell_matrix(ii,jj) += (
+                                             (convection * normal - tau_stab) *
+                                             scratch.tr_phi[i] * scratch.tr_phi[j]
+                                             ) * JxW;
+                      }
+
+                  if (cell->face(face)->at_boundary()
+                      &&
+                      (cell->face(face)->boundary_indicator() == 1))
+                    {
+                      const double neumann_value =
+                        scratch.exact_solution.value(scratch.fe_face_values.quadrature_point(q));
+                      for (unsigned int i=0; i<scratch.fe_support_on_face[face].size(); ++i)
+                        {
+                          const unsigned int ii=scratch.fe_support_on_face[face][i];
+                          task_data.cell_vector(ii) -= scratch.tr_phi[i] * neumann_value * JxW;
+                        }
+                    }
+                }
+
+              for (unsigned int i=0; i<scratch.fe_local_support_on_face[face].size(); ++i)
+                for (unsigned int j=0; j<scratch.fe_local_support_on_face[face].size(); ++j)
+                  {
+                    const unsigned int ii=scratch.fe_local_support_on_face[face][i];
+                    const unsigned int jj=scratch.fe_local_support_on_face[face][j];
+                    scratch.ll_matrix(ii,jj) += tau_stab * scratch.u_phi[i] * scratch.u_phi[j] * JxW;
+                  }
+
+              // compute the local right hand side contributions from trace
+              if (task_data.trace_reconstruct)
+                for (unsigned int i=0; i<scratch.fe_local_support_on_face[face].size(); ++i)
+                  {
+                    const unsigned int ii=scratch.fe_local_support_on_face[face][i];
+                    scratch.l_rhs(ii) -= (scratch.q_phi[i] * normal
+                                  +
+                                  scratch.u_phi[i] * (convection * normal - tau_stab)
+                                  ) * scratch.trace_values[q] * JxW;
+                  }
+            }
+        }
+
+      scratch.ll_matrix.gauss_jordan();
+      if (task_data.trace_reconstruct == false)
+        {
+          scratch.fl_matrix.mmult(scratch.tmp_matrix, scratch.ll_matrix);
+          scratch.tmp_matrix.vmult_add(task_data.cell_vector, scratch.l_rhs);
+          scratch.tmp_matrix.mmult(task_data.cell_matrix, scratch.lf_matrix, true);
+          cell->get_dof_indices(task_data.dof_indices);
+        }
+      else
+        {
+          scratch.ll_matrix.vmult(scratch.tmp_rhs, scratch.l_rhs);
+          loc_cell->set_dof_values(scratch.tmp_rhs, solution_local);
+        }
+}
+
+
+
+template <int dim>
+void Step51<dim>::solve ()
+{
+  SolverControl solver_control (system_matrix.m()*10,
+                                1e-10*system_rhs.l2_norm());
+  SolverGMRES<> solver (solver_control, 50);
+  solver.solve (system_matrix, solution, system_rhs,
+                PreconditionIdentity());
+
+  std::cout << "   Number of GMRES iterations: " << solver_control.last_step()
+            << std::endl;
+
+  system_matrix.clear();
+  sparsity_pattern.reinit(0,0,0,1);
+    
+  constraints.distribute(solution);
+
+  // update local values
+  assemble_system(true);
+}
+
+
+
+template <int dim>
+void
+Step51<dim>::postprocess()
+{
+  // construct post-processed solution with (hopefully) higher order of
+  // accuracy
+  {
+    const QGauss<dim>   quadrature_formula(fe_u_post.degree+1);
+    const UpdateFlags local_flags (update_values);
+    const UpdateFlags flags ( update_values | update_gradients |
+                             update_JxW_values);
+  
+    EmptyData task_data;
+    
+    PostProcessScratchData scratch (fe_u_post, fe_local,
+                         quadrature_formula,
+                         local_flags,
+                         flags);
+    
+    WorkStream::run(dof_handler_u_post.begin_active(),
+                    dof_handler_u_post.end(),
+                    *this,
+                    &Step51<dim>::postprocess_one_cell,
+                    &Step51<dim>::NullFunction,
+                    scratch,
+                    task_data);
+    }
+
+// Compute some convergence rates, etc., and add to a table
+  Vector<float> difference_per_cell (triangulation.n_active_cells());
+
+  ComponentSelectFunction<dim> value_select (dim, dim+1);
+  VectorTools::integrate_difference (dof_handler_local,
+                                     solution_local,
+                                     SolutionAndGradient<dim>(),
+                                     difference_per_cell,
+                                     QGauss<dim>(fe.degree+2),
+                                     VectorTools::L2_norm,
+                                     &value_select);
+  const double L2_error = difference_per_cell.l2_norm();
+
+  ComponentSelectFunction<dim> gradient_select (std::pair<unsigned int,unsigned int>(0, dim),
+                                                dim+1);
+  VectorTools::integrate_difference (dof_handler_local,
+                                     solution_local,
+                                     SolutionAndGradient<dim>(),
+                                     difference_per_cell,
+                                     QGauss<dim>(fe.degree+2),
+                                     VectorTools::L2_norm,
+                                     &gradient_select);
+  const double grad_error = difference_per_cell.l2_norm();
+
+  VectorTools::integrate_difference (dof_handler_u_post,
+                                     solution_u_post,
+                                     Solution<dim>(),
+                                     difference_per_cell,
+                                     QGauss<dim>(fe.degree+3),
+                                     VectorTools::L2_norm);
+  const double post_error = difference_per_cell.l2_norm();
+  
+  convergence_table.add_value("cells",                  triangulation.n_active_cells());
+  convergence_table.add_value("dofs",           dof_handler.n_dofs());
+  convergence_table.add_value("val L2",         L2_error);
+  convergence_table.add_value("grad L2",        grad_error);
+  convergence_table.add_value("val L2-post", post_error);  
+}
+
+template <int dim>
+void
+Step51<dim>::postprocess_one_cell (const typename DoFHandler<dim>::active_cell_iterator &cell,
+                                       PostProcessScratchData &scratch,
+                                       EmptyData &task_data)
+{
+  scratch.reset();
+
+  typename DoFHandler<dim>::active_cell_iterator
+    loc_cell (&triangulation,
+              cell->level(),
+              cell->index(),
+              &dof_handler_local);
+              
+  scratch.fe_values_local.reinit (loc_cell);
+  scratch.fe_values.reinit(cell);
+  
+  FEValuesExtractors::Vector fluxes(0);
+  FEValuesExtractors::Scalar scalar(dim);
+
+  const unsigned int n_q_points = scratch.fe_values.get_quadrature().size();
+  const unsigned int dofs_per_cell = scratch.fe_values.dofs_per_cell;
+
+  scratch.fe_values_local[scalar].get_function_values(solution_local, scratch.u_values);
+  scratch.fe_values_local[fluxes].get_function_values(solution_local, scratch.u_gradients);
+  
+  double sum = 0;
+  for (unsigned int i=1; i<dofs_per_cell; ++i)
+       {
+         for (unsigned int j=0; j<dofs_per_cell; ++j)
+               {
+                 sum = 0;
+                 for (unsigned int q=0; q<n_q_points; ++q)
+                       sum += (scratch.fe_values.shape_grad(i,q) *
+                                       scratch.fe_values.shape_grad(j,q)
+                                       ) * scratch.fe_values.JxW(q);
+                 scratch.cell_matrix(i,j) = sum;
+               }
+         
+         sum = 0;
+         for (unsigned int q=0; q<n_q_points; ++q)
+               sum -= (scratch.fe_values.shape_grad(i,q) * scratch.u_gradients[q]
+                               ) * scratch.fe_values.JxW(q);
+         scratch.cell_rhs(i) = sum;
+       }
+  for (unsigned int j=0; j<dofs_per_cell; ++j)
+       {
+         sum = 0;
+         for (unsigned int q=0; q<n_q_points; ++q)
+               sum += scratch.fe_values.shape_value(j,q) * scratch.fe_values.JxW(q);
+         scratch.cell_matrix(0,j) = sum;
+       }
+  {
+       sum = 0;
+       for (unsigned int q=0; q<n_q_points; ++q)
+         sum += scratch.u_values[q] * scratch.fe_values.JxW(q);
+       scratch.cell_rhs(0) = sum;
+  }
+
+  scratch.cell_matrix.gauss_jordan();
+  scratch.cell_matrix.vmult(scratch.cell_sol, scratch.cell_rhs);
+  cell->distribute_local_to_global(scratch.cell_sol, solution_u_post);
+}
+
+
+template <int dim>
+void Step51<dim>::output_results (const unsigned int cycle)
+{
+  std::string filename;
+  switch (refinement_mode)
+    {
+    case global_refinement:
+      filename = "solution-global";
+      break;
+    case adaptive_refinement:
+      filename = "solution-adaptive";
+      break;
+    default:
+      Assert (false, ExcNotImplemented());
+    }
+    
+  std::string face_out(filename);
+  face_out += "-face";
+
+  filename += "-q" + Utilities::int_to_string(fe.degree,1);
+  filename += "-" + Utilities::int_to_string(cycle,2);
+  filename += ".vtk";
+  std::ofstream output (filename.c_str());
+
+  DataOut<dim> data_out;
+  std::vector<std::string> names (dim, "gradient");
+  names.push_back ("solution");
+  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+    component_interpretation
+    (dim+1, DataComponentInterpretation::component_is_part_of_vector);
+  component_interpretation[dim]
+    = DataComponentInterpretation::component_is_scalar;
+  data_out.add_data_vector (dof_handler_local, solution_local,
+                            names, component_interpretation);
+                            
+  // Post-processed solution:  can now add more than 1 dof_handler to 
+  // the DataOut object!
+  std::vector<std::string> post_name(1,"u_post");
+  std::vector<DataComponentInterpretation::DataComponentInterpretation> 
+                        post_comp_type(1, DataComponentInterpretation::component_is_scalar);
+  data_out.add_data_vector (dof_handler_u_post, solution_u_post,
+                                                 post_name, post_comp_type);
+
+  data_out.build_patches (fe.degree);
+  data_out.write_vtk (output);
+    
+  face_out += "-q" + Utilities::int_to_string(fe.degree,1);
+  face_out += "-" + Utilities::int_to_string(cycle,2);
+  face_out += ".vtk";
+  std::ofstream face_output (face_out.c_str());
+
+  DataOutFaces<dim> data_out_face(false);
+  std::vector<std::string> face_name(1,"lambda");
+  std::vector<DataComponentInterpretation::DataComponentInterpretation> 
+                        face_component_type(1, DataComponentInterpretation::component_is_scalar);
+
+  data_out_face.add_data_vector (dof_handler, 
+                                                               solution, 
+                                                               face_name,
+                                                               face_component_type);
+                                                               
+  data_out_face.build_patches (fe.degree);
+  data_out_face.write_vtk (face_output);
+}
+
+
+
+template <int dim>
+void Step51<dim>::refine_grid (const unsigned int cycle)
+{
+  if (cycle == 0)
+    {
+      GridGenerator::subdivided_hyper_cube (triangulation, 2, -1, 1);
+    }
+  else
+    switch (refinement_mode)
+      {
+      case global_refinement:
+        {
+            triangulation.clear();
+            GridGenerator::subdivided_hyper_cube (triangulation, 2+(cycle%2), -1, 1);
+            triangulation.refine_global(3-dim+cycle/2);
+          break;
+        }
+
+      case adaptive_refinement:
+      {
+        Vector<float> estimated_error_per_cell (triangulation.n_active_cells());
+
+        FEValuesExtractors::Scalar scalar(dim);
+        typename FunctionMap<dim>::type neumann_boundary;
+        KellyErrorEstimator<dim>::estimate (dof_handler_local,
+                                            QGauss<dim-1>(3),
+                                            neumann_boundary,
+                                            solution_local,
+                                            estimated_error_per_cell,
+                                            fe_local.component_mask(scalar));
+
+        GridRefinement::refine_and_coarsen_fixed_number (triangulation,
+                                                         estimated_error_per_cell,
+                                                         0.3, 0.);
+
+        triangulation.execute_coarsening_and_refinement ();
+
+        break;
+      }
+
+      default:
+      {
+        Assert (false, ExcNotImplemented());
+      }
+      }
+  }
+
+
+
+
+
+template <int dim>
+void Step51<dim>::run ()
+{
+  for (unsigned int cycle=0; cycle<10; ++cycle)
+    {
+      std::cout << "Cycle " << cycle << ':' << std::endl;
+      
+      refine_grid (cycle);
+      setup_system ();
+      assemble_system (false);
+      solve ();
+      postprocess();
+      output_results (cycle);
+    }
+
+
+
+  convergence_table.set_precision("val L2", 3);
+  convergence_table.set_scientific("val L2", true);
+  convergence_table.set_precision("grad L2", 3);
+  convergence_table.set_scientific("grad L2", true);
+  convergence_table.set_precision("val L2-post", 3);
+  convergence_table.set_scientific("val L2-post", true);
+
+  if (refinement_mode == global_refinement)
+    {
+      convergence_table
+        .evaluate_convergence_rates("val L2", "cells", ConvergenceTable::reduction_rate_log2, dim);
+      convergence_table
+        .evaluate_convergence_rates("grad L2", "cells", ConvergenceTable::reduction_rate_log2, dim);
+      convergence_table
+        .evaluate_convergence_rates("val L2-post", "cells", ConvergenceTable::reduction_rate_log2, dim);
+    }
+  convergence_table.write_text(std::cout);
+}
+
+
+int main (int argc, char** argv)
+{
+  const unsigned int dim = 2;
+
+  try
+    {
+      using namespace dealii;
+
+      deallog.depth_console (0);
+
+      // Now for the three calls to the main class in complete analogy to
+      // step-7.
+      {
+        std::cout << "Solving with Q1 elements, adaptive refinement" << std::endl
+                  << "=============================================" << std::endl
+                  << std::endl;
+
+        Step51<dim> hdg_problem (1, Step51<dim>::adaptive_refinement);
+        hdg_problem.run ();
+
+        std::cout << std::endl;
+      }
+
+      {
+        std::cout << "Solving with Q1 elements, global refinement" << std::endl
+                  << "===========================================" << std::endl
+                  << std::endl;
+
+        Step51<dim> hdg_problem (1, Step51<dim>::global_refinement);
+        hdg_problem.run ();
+
+        std::cout << std::endl;
+      }
+
+      {
+        std::cout << "Solving with Q3 elements, global refinement" << std::endl
+                  << "===========================================" << std::endl
+                  << std::endl;
+
+        Step51<dim> hdg_problem (3, Step51<dim>::global_refinement);
+        hdg_problem.run ();
+
+        std::cout << std::endl;
+      }
+
+    }
+  catch (std::exception &exc)
+    {
+      std::cerr << std::endl << std::endl
+                << "----------------------------------------------------"
+                << std::endl;
+      std::cerr << "Exception on processing: " << std::endl
+                << exc.what() << std::endl
+                << "Aborting!" << std::endl
+                << "----------------------------------------------------"
+                << std::endl;
+      return 1;
+    }
+  catch (...)
+    {
+      std::cerr << std::endl << std::endl
+                << "----------------------------------------------------"
+                << std::endl;
+      std::cerr << "Unknown exception!" << std::endl
+                << "Aborting!" << std::endl
+                << "----------------------------------------------------"
+                << std::endl;
+      return 1;
+    }
+
+  return 0;
+}
index ea45447cb6d7a450d6e31c0ac0fc039bfceff3dd..681b9e4a34c900e7392b83bd7807b50e989baf75 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2000 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2000 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 2000
  */
 
index ff5a243964c683416aab4a814ca6a5107f985d64..058e7cf1cdc05da7cf7e0b254d910de74a075622 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2000 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2000 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth and Ralf Hartmann, University of Heidelberg, 2000
  */
 
@@ -950,7 +950,7 @@ namespace Step7
   //
   // For this, we will use the following convention: Faces belonging to Gamma1
   // will have the boundary indicator <code>0</code> (which is the default, so
-  // we don't have to set it explicitely), and faces belonging to Gamma2 will
+  // we don't have to set it explicitly), and faces belonging to Gamma2 will
   // use <code>1</code> as boundary indicator.  To set these values, we loop
   // over all cells, then over all faces of a given cell, check whether it is
   // part of the boundary that we want to denote by Gamma2, and if so set its
index b63fa0db1a39aa2d8f3165d792b101892d0789fe..da7eccfd573283f8913c15fe6bdb4f08c02ebb41 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2000 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2000 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 2000
  */
 
index 26df070fef7d25167bfaa4d96f804a9f3ad421bf..9f6883e273e02f56fefc0c1a82e6d15bf9d6ac08 100644 (file)
@@ -1,20 +1,20 @@
-// ---------------------------------------------------------------------
-// $Id$
-//
-// Copyright (C) 2000 - 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.
-//
-// ---------------------------------------------------------------------
-
-/*
+/* ---------------------------------------------------------------------
+ * $Id$
+ *
+ * Copyright (C) 2000 - 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.
+ *
+ * ---------------------------------------------------------------------
+
+ *
  * Author: Wolfgang Bangerth, University of Heidelberg, 2000
  */
 
index 43d43659069e330b10ffbda9a73f282362be2ab9..ca90c59df9e9c6414c01e9a6649a3dfa11151ca4 100644 (file)
@@ -1,14 +1,18 @@
-//----------------------------  config.h.in  ---------------------------
-//    $Id$
-//    Version: $Name$
+// ---------------------------------------------------------------------
+// $Id$
 //
-//    Copyright (C) 2012, 2013 by the deal.II authors
+// Copyright (C) 2012 - 2013 by the deal.II authors
 //
-//    TODO: Header
+// This file is part of the deal.II library.
 //
-//    Author: Matthias Maier <matthias.maier@iwr.uni-heidelberg.de>
+// 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.
 //
-//----------------------------  config.h.in  ---------------------------
+// ---------------------------------------------------------------------
 
 #ifndef __deal2__config_h
 #define __deal2__config_h
  * Configured in check_2_compiler_bugs: *
  ****************************************/
 
-/* Defined if we have to work around a bug where the compiler doesn't accept
- * an explicit destructor call. See the aclocal.m4 file in the top-level
- * directory for a description of this bug.
- */
-#cmakedefine DEAL_II_EXPLICIT_DESTRUCTOR_BUG
-
 /* Defined if we have to work around a bug with some compilers that will not
  * allow us to specify a fully specialized class of a template as a friend.
  * See the aclocal.m4 file in the top-level directory for a description of
index b054a3a822151596ec3a91bf1d646a6759c698b7..43e7e9a2944963cdf5a1bb7a9b47e05886035891 100644 (file)
@@ -1222,11 +1222,21 @@ public:
      */
     unsigned int cycle;
 
+   /**
+     * Flag to determine whether the current
+     * date and time shall be printed as a comment
+     * in the file's second line.
+     *
+     * Default is <tt>true</tt>.
+     */
+    bool print_date_and_time;
+
     /**
      * Default constructor.
      */
-    VtkFlags (const double       time  = std::numeric_limits<double>::min(),
-              const unsigned int cycle = std::numeric_limits<unsigned int>::min());
+    VtkFlags (const double       time   = std::numeric_limits<double>::min(),
+              const unsigned int cycle  = std::numeric_limits<unsigned int>::min(),
+              const bool print_date_and_time = true);
 
     /**
      * Declare the flags with name
@@ -1848,7 +1858,8 @@ public:
    * DataOutInterface::write_vtu_footer() and DataOutInterface::write_vtu_main()
    * by DataOutBase::write_vtu().
    */
-  static void write_vtu_header (std::ostream &out);
+  static void write_vtu_header (std::ostream &out,
+                                const VtkFlags &flags);
 
   /**
    * This writes the footer for the xml based vtu file format. This
index 313c3437591f08d649e202886eeab93605e467cb..87ef8c844dca74e32a8e276f9cd410677c943b99 100644 (file)
@@ -35,11 +35,8 @@ DEAL_II_NAMESPACE_OPEN
    In deal.II we represent these derivaties using objects of
    type DerivativeForm<1,dim,spacedim>, DerivativeForm<2,dim,spacedim> and so on.
 
-
    @author Sebastian Pauletti, 2011
-
 */
-
 template <int order, int dim, int spacedim>
 class DerivativeForm
 {
index 4704ebfdf63a78cf4d0b3bb8dd3d7699657b969a..22bfb276d2260550316baf08835030c7fac4b692 100644 (file)
@@ -2173,8 +2173,7 @@ struct GeometryInfo
   void
   alternating_form_at_vertices
   (const Point<spacedim> (&vertices)[vertices_per_cell],
-   Tensor<spacedim-dim,spacedim> (&forms)[vertices_per_cell])
-  ;
+   Tensor<spacedim-dim,spacedim> (&forms)[vertices_per_cell]);
 
   /**
    * For each face of the reference
index 977f40a3216fd768b4bb2dce280cd7f22521a236..9f573a98b6a3c5bf58af9a9387e52a28897663a7 100644 (file)
@@ -49,12 +49,12 @@ namespace Utilities
      * where other processors might require information from. In a
      * sense, these import indices form the dual of the ghost
      * indices. This information is gathered once when constructing the
-     * partitioner, which obviates subsequent global communcation steps
+     * partitioner, which obviates subsequent global communication steps
      * when exchanging data.
      *
-     * The partitioner includes a mechanism for converting global to
-     * local and local to global indices. The storage convention for the
-     * partitioner is as follows. The local range is associated with
+     * The partitioner includes a mechanism for converting global to local and
+     * local to global indices. Internally, this class stores vector elements
+     * using the convention as follows: The local range is associated with
      * local indices [0,@p local_size), and ghost indices are stored
      * consecutively in [@p local_size, @p local_size + @p
      * n_ghost_indices). The ghost indices are sorted according to their
index a6372e016eb7b7cd71a886465a61d0f7f41068be..44d425865c4bf61a6f85fff08b5a2a867efe580c 100644 (file)
@@ -49,7 +49,7 @@ DEAL_II_NAMESPACE_OPEN
  * same. The handling in SmartPointer will take care of this.
  *
  * @note Due to a problem with <tt>volatile</tt> declarations, this
- * additional feature is switched of if multithreading is used.
+ * additional feature is switched off if multithreading is used.
  *
  * @ingroup memory
  * @author Guido Kanschat, 1998 - 2005
index dd79b821d5082aba4c513966cce0d87e1c919820..93ffc6296a2c3e9b1f639e424da5ced3952fc312 100644 (file)
@@ -797,8 +797,8 @@ public:
    * one.
    *
    * If the present object is a
-   * rank-4 tensor, the the result
-   * is a rank-2 tensor, the
+   * rank-4 tensor, then the result
+   * is a rank-2 tensor, i.e., the
    * operation contracts over the
    * last two indices of the
    * present object and the indices
@@ -2842,8 +2842,68 @@ operator / (const SymmetricTensor<rank,dim> &t,
   return tt;
 }
 
+/**
+ * Compute the scalar product $a:b=\sum_{i,j} a_{ij}b_{ij}$ between two
+ * tensors $a,b$ of rank 2. In the current case where both arguments are
+ * symmetric tensors, this is equivalent to calling the expression
+ * <code>t1*t2</code> which uses the overloaded <code>operator*</code>
+ * between two symmetric tensors of rank 2.
+ *
+ * @relates SymmetricTensor
+ */
+template <int dim, typename Number>
+inline
+Number
+scalar_product (const SymmetricTensor<2,dim,Number> &t1,
+                const SymmetricTensor<2,dim,Number> &t2)
+{
+  return (t1*t2);
+}
+
+
+/**
+ * Compute the scalar product $a:b=\sum_{i,j} a_{ij}b_{ij}$ between two
+ * tensors $a,b$ of rank 2. We don't use <code>operator*</code> for this
+ * operation since the product between two tensors is usually assumed to be
+ * the contraction over the last index of the first tensor and the first index
+ * of the second tensor, for example $(a\cdot b)_{ij}=\sum_k a_{ik}b_{kj}$.
+ *
+ * @relates Tensor
+ * @relates SymmetricTensor
+ */
+template <int dim, typename Number>
+inline
+Number
+scalar_product (const SymmetricTensor<2,dim,Number> &t1,
+                const Tensor<2,dim,Number> &t2)
+{
+  Number s = 0;
+  for (unsigned int i=0; i<dim; ++i)
+    for (unsigned int j=0; j<dim; ++j)
+      s += t1[i][j] * t2[i][j];
+  return s;
+}
 
 
+/**
+ * Compute the scalar product $a:b=\sum_{i,j} a_{ij}b_{ij}$ between two
+ * tensors $a,b$ of rank 2. We don't use <code>operator*</code> for this
+ * operation since the product between two tensors is usually assumed to be
+ * the contraction over the last index of the first tensor and the first index
+ * of the second tensor, for example $(a\cdot b)_{ij}=\sum_k a_{ik}b_{kj}$.
+ *
+ * @relates Tensor
+ * @relates SymmetricTensor
+ */
+template <int dim, typename Number>
+inline
+Number
+scalar_product (const Tensor<2,dim,Number> &t1,
+                const SymmetricTensor<2,dim,Number> &t2)
+{
+  return scalar_product(t2, t1);
+}
+
 
 /**
  * Double contraction between a rank-4 and a rank-2 symmetric tensor,
index 0e2aebf0fe664e8448acb3083f66d63f6968545d..314a83a7b9a5c2e6b0d96c3e243d9ef04c539411 100644 (file)
@@ -311,13 +311,23 @@ public:
    *     2 13 a
    *     1 0 ""
    *   @endcode
-   *
-   **/
+   * - <code>org_mode_table</code>: Outputs to org-mode (http://orgmode.org/) table
+   *   format. It is easy to convert org-mode tables to HTML/LaTeX/csv.
+   *   Example output:
+   *   @code
+   *   | key1 | key2 | key3 |
+   *   | 0    | 0    | ""   |
+   *   | 1    | 0    | ""   |
+   *   | 2    | 13   | a    |
+   *   | 1    | 0    | ""   |
+   *   @endcode
+   */
   enum TextOutputFormat
   {
     table_with_headers,
     table_with_separate_column_description,
-    simple_table_with_separate_column_description
+    simple_table_with_separate_column_description,
+    org_mode_table
   };
 
   /**
index f77a552c71b2d1c7d3232d32138c7d0daf38c3df..b123fbe109e9ed17fd3925d9bac2373150130da2 100644 (file)
@@ -209,7 +209,7 @@ namespace internal
    *   template <>
    *   void X<dim>::f<0> () { ...operate on the vertices of a cell... }
    *
-   *   template <int dim, int subdim> void f(X<dim> &x) {
+   *   template <int dim, int subdim> void g(X<dim> &x) {
    *     x.f<subdim> ();
    *   }
    * @endcode
@@ -238,7 +238,7 @@ namespace internal
    *   template <int dim>
    *   void X<dim>::f (int2type<1>) { ...operate on the lines of a cell... }
    *
-   *   template <int dim, int subdim> void f(X<dim> &x) {
+   *   template <int dim, int subdim> void g(X<dim> &x) {
    *     x.f (int2type<subdim>());
    *   }
    * @endcode
index aab8d601134a82fbad72b7990244417144085095..c6da7af3aaf8f0a52236ac377dcbfadd74c22d28 100644 (file)
@@ -123,7 +123,7 @@ public:
 
 
 
-/*
+/**
  * Provide a tensor valued function which always returns a constant tensor
  * value. Obviously, all derivates of this function are zero.
  *
@@ -162,7 +162,7 @@ private:
 
 
 
-/*
+/**
  * Provide a tensor valued function which always returns zero.
  * Obviously, all derivates of this function are zero.
  *
index df17f8f976dfae82f123ee7b1495c1cc501d74b5..db5d8b435adf4cb86456ddb204f4eba476575368 100644 (file)
@@ -226,7 +226,7 @@ namespace Utilities
    * templates.
    *
    * Use this class as in
-   * <code>fixed_int_power@<5,2@>::value</code>
+   * <code>fixed_int_power@<5,2@>::%value</code>
    * to compute 5<sup>2</sup>.
    */
   template <int a, int N>
index 9e990e154e8538055504cc79ffae30ce64bd28cf..93d765a67071ac2145f96913c1ff29c77c897eca 100644 (file)
@@ -23,6 +23,7 @@
 #include <deal.II/base/exceptions.h>
 #include <deal.II/base/smartpointer.h>
 #include <deal.II/base/index_set.h>
+#include <deal.II/base/std_cxx1x/shared_ptr.h>
 #include <deal.II/dofs/block_info.h>
 #include <deal.II/dofs/dof_iterator_selector.h>
 #include <deal.II/dofs/number_cache.h>
index 8d52d8c9430f9e71f34c2f8b440089696beecfd8..31fb8c8cb7d0fd5bfe85246c8869e39c156175ba 100644 (file)
@@ -924,6 +924,65 @@ public:
   std::pair<unsigned int, unsigned int>
   face_system_to_component_index (const unsigned int index) const;
 
+  /**
+   * Given an index in the natural ordering of indices on a face, return the
+   * index of the same degree of freedom on the cell.
+   *
+   * To explain the concept, consider the case where we would like to know
+   * whether a degree of freedom on a face, for example as part of an FESystem
+   * element, is primitive. Unfortunately, the
+   * is_primitive() function in the FiniteElement class takes a cell index, so
+   * we would need to find the cell index of the shape function that
+   * corresponds to the present face index. This function does that.
+   *
+   * Code implementing this would then look like this:
+   * @code
+   * for (i=0; i<dofs_per_face; ++i)
+   *  if (fe.is_primitive(fe.face_to_equivalent_cell_index(i, some_face_no)))
+   *   ... do whatever
+   * @endcode
+   * The function takes additional arguments that account for the fact that
+   * actual faces can be in their standard ordering with respect to the cell
+   * under consideration, or can be flipped, oriented, etc.
+   *
+   * @param face_dof_index The index of the degree of freedom on a face.
+   *   This index must be between zero and dofs_per_face.
+   * @param face The number of the face this degree of freedom lives on.
+   *   This number must be between zero and GeometryInfo::faces_per_cell.
+   * @param face_orientation One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @param face_flip One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @param face_rotation One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @return The index of this degree of freedom within the set
+   *   of degrees of freedom on the entire cell. The returned value
+   *   will be between zero and dofs_per_cell.
+   *
+   * @note This function exists in this class because that is where it
+   * was first implemented. However, it can't really work in the most
+   * general case without knowing what element we have. The reason is that
+   * when a face is flipped or rotated, we also need to know whether we
+   * need to swap the degrees of freedom on this face, or whether they
+   * are immune from this. For this, consider the situation of a $Q_3$
+   * element in 2d. If face_flip is true, then we need to consider
+   * the two degrees of freedom on the edge in reverse order. On the other
+   * hand, if the element were a $Q_1^2$, then because the two degrees of
+   * freedom on this edge belong to different vector components, they
+   * should not be considered in reverse order. What all of this shows is
+   * that the function can't work if there are more than one degree of
+   * freedom per line or quad, and that in these cases the function will
+   * throw an exception pointing out that this functionality will need
+   * to be provided by a derived class that knows what degrees of freedom
+   * actually represent.
+   */
+  virtual
+  unsigned int face_to_cell_index (const unsigned int face_dof_index,
+                                   const unsigned int face,
+                                   const bool face_orientation = true,
+                                   const bool face_flip        = false,
+                                   const bool face_rotation    = false) const;
+
   /**
    * For faces with non-standard face_orientation in 3D, the dofs on faces
    * (quads) have to be permuted in order to be combined with the correct
index f7e0de1021eb3e81f392a7ded73d40d797304bbe..3cd065bb95eb54a54ad9c3a3aea146f95ad91e17 100644 (file)
@@ -409,54 +409,6 @@ public:
    */
   bool conforms (const Conformity) const;
 
-  /**
-   * Given an index in the natural ordering of indices on a face, return the
-   * index of the same degree of freedom on the cell.
-   *
-   * @param face_dof_index The index of the degree of freedom on a face.
-   *   This index must be between zero and dofs_per_face.
-   * @param face The number of the face this degree of freedom lives on.
-   *   This number must be between zero and GeometryInfo::faces_per_cell.
-   * @param face_orientation One part of the description of the orientation
-   *   of the face. See @ref GlossFaceOrientation .
-   * @param face_flip One part of the description of the orientation
-   *   of the face. See @ref GlossFaceOrientation .
-   * @param face_rotation One part of the description of the orientation
-   *   of the face. See @ref GlossFaceOrientation .
-   * @return The index of this degree of freedom within the set
-   *   of degrees of freedom on the entire cell. The returned value
-   *   will be between zero and dofs_per_cell.
-   */
-  unsigned int face_to_cell_index (const unsigned int face_dof_index,
-                                   const unsigned int face,
-                                   const bool face_orientation = true,
-                                   const bool face_flip        = false,
-                                   const bool face_rotation    = false) const;
-
-  /**
-   * @deprecated This function is just a special version of face_to_cell_index
-   * for the face zero. It is therefore of limited use in aplications and most
-   * of the time, the other function is what is required.
-   *
-   * Given an index in the natural ordering of indices on a face, return the
-   * index of an equivalent degree of freedom on the cell.
-   *
-   * To explain the concept, consider the case where we would like to know
-   * whether a degree of freedom on a face is primitive. Unfortunately, the
-   * is_primitive() function in the FiniteElement class takes a cell index, so
-   * we would need to find the cell index of the shape function that
-   * corresponds to the present face index. This function does that.
-   *
-   * Code implementing this would then look like this:
-   * @code
-   * for (i=0; i<dofs_per_face; ++i)
-   *  if (fe.is_primitive(fe.face_to_equivalent_cell_index(i)))
-   *   ... do whatever
-   * @endcode
-   *
-   */
-  unsigned int face_to_equivalent_cell_index (const unsigned int index) const DEAL_II_DEPRECATED;
-
   /**
    * Comparison operator.
    */
@@ -689,53 +641,6 @@ FiniteElementData<dim>::conforms (const Conformity space) const
 }
 
 
-
-template <>
-inline
-unsigned int
-FiniteElementData<1>::
-face_to_equivalent_cell_index (const unsigned int index) const
-{
-  Assert (index < dofs_per_face,
-          ExcIndexRange (index, 0, dofs_per_face));
-  return index;
-}
-
-
-
-template <>
-inline
-unsigned int
-FiniteElementData<2>::
-face_to_equivalent_cell_index (const unsigned int index) const
-{
-  Assert (index < dofs_per_face,
-          ExcIndexRange (index, 0, dofs_per_face));
-
-  // on face 0, the vertices are 0 and 2
-  if (index < this->dofs_per_vertex)
-    return index;
-  else if (index < 2*this->dofs_per_vertex)
-    return index + this->dofs_per_vertex;
-  else
-    // this is a dof on line 0, so on the cell there are now 4 vertices
-    // instead of only 2 ahead of this one
-    return index + 2*this->dofs_per_vertex;
-}
-
-
-
-
-template <>
-inline
-unsigned int
-FiniteElementData<3>::
-face_to_equivalent_cell_index (const unsigned int index) const
-{
-  // this case is just way too complicated. fall back to face_to_cell_index
-  return face_to_cell_index(index, 0, true);
-}
-
 #endif // DOXYGEN
 
 
index a091042adb7f7747f367d951ecec237756d8b567..3047f7a06afa4d2fc290183a12f3bd6daa7c862f 100644 (file)
@@ -25,9 +25,12 @@ DEAL_II_NAMESPACE_OPEN
 
 
 /**
- * A finite element, which is a tensor product polynomial on each face
- * and undefined in the interior of the cells. The basis functions on
- * the faces are from Polynomials::LagrangeEquidistant
+ * A finite element, which is a tensor product polynomial on each face and
+ * undefined in the interior of the cells. The basis functions on the faces
+ * are Lagrange polynomials based on the support points of the
+ * (dim-1)-dimensional Gauss--Lobatto quadrature rule. For element degree one
+ * and two, the polynomials hence correspond to the usual Lagrange polynomials
+ * on equidistant points.
  *
  * This finite element is the trace space of FE_RaviartThomas on the
  * faces and serves in hybridized methods.
@@ -39,13 +42,9 @@ DEAL_II_NAMESPACE_OPEN
  * element space, but all shape function values extracted will equal
  * to zero.
  *
- * @todo Polynomials::LagrangeEquidistant should be and will be
- * replaced by Polynomials::LagrangeGaussLobatto as soon as such a
- * polynomial set exists.
- *
  * @ingroup fe
- * @author Guido Kanschat
- * @date 2009, 2011
+ * @author Guido Kanschat, Martin Kronbichler
+ * @date 2009, 2011, 2013
  */
 template <int dim, int spacedim=dim>
 class FE_FaceQ : public FE_PolyFace<TensorProductPolynomials<dim-1>, dim, spacedim>
@@ -67,6 +66,31 @@ public:
    */
   virtual std::string get_name () const;
 
+  /**
+   * Return the matrix interpolating from a face of of one element to the face
+   * of the neighboring element.  The size of the matrix is then
+   * <tt>source.dofs_per_face</tt> times <tt>this->dofs_per_face</tt>. This
+   * element only provides interpolation matrices for elements of the same
+   * type and FE_Nothing. For all other elements, an exception of type
+   * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented is thrown.
+   */
+  virtual void
+  get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
+                                 FullMatrix<double>       &matrix) const;
+
+  /**
+   * Return the matrix interpolating from a face of of one element to the face
+   * of the neighboring element.  The size of the matrix is then
+   * <tt>source.dofs_per_face</tt> times <tt>this->dofs_per_face</tt>. This
+   * element only provides interpolation matrices for elements of the same
+   * type and FE_Nothing. For all other elements, an exception of type
+   * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented is thrown.
+   */
+  virtual void
+  get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
+                                    const unsigned int        subface,
+                                    FullMatrix<double>       &matrix) const;
+
   /**
    * Check for non-zero values on a face.
    *
@@ -78,6 +102,28 @@ public:
   virtual bool has_support_on_face (const unsigned int shape_index,
                                     const unsigned int face_index) const;
 
+  /**
+   * Return whether this element implements its hanging node constraints in
+   * the new way, which has to be used to make elements "hp compatible".
+   *
+   * For the FE_Q class the result is always true (independent of the degree
+   * of the element), as it implements the complete set of functions necessary
+   * for hp capability.
+   */
+  virtual bool hp_constraints_are_implemented () const;
+
+  /**
+   * Return whether this element dominates the one given as argument when they
+   * meet at a common face, whether it is the other way around, whether
+   * neither dominates, or if either could dominate.
+   *
+   * For a definition of domination, see FiniteElementBase::Domination and in
+   * particular the @ref hp_paper "hp paper".
+   */
+  virtual
+  FiniteElementDomination::Domination
+  compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
+
 private:
   /**
    * Return vector with dofs per vertex, line, quad, hex.
index 6f17bd38a4dfadf800549ffdd5c7c8a175aa0a87..15b6701171bd402597522306c8dc59159b7aa36a 100644 (file)
@@ -62,13 +62,11 @@ public:
   /**
    * Return the matrix interpolating from a face of of one element to the face
    * of the neighboring element.  The size of the matrix is then
-   * <tt>source.dofs_per_face</tt> times <tt>this->dofs_per_face</tt>.
-   *
-   * Derived elements will have to implement this function. They may only
-   * provide interpolation matrices for certain source finite elements, for
-   * example those from the same family. If they don't implement interpolation
-   * from a given element, then they must throw an exception of type
-   * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
+   * <tt>source.dofs_per_face</tt> times <tt>this->dofs_per_face</tt>. The
+   * FE_Q element family only provides interpolation matrices for elements of
+   * the same type and FE_Nothing. For all other elements, an exception of
+   * type FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented is
+   * thrown.
    */
   virtual void
   get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
@@ -77,13 +75,11 @@ public:
   /**
    * Return the matrix interpolating from a face of of one element to the face
    * of the neighboring element.  The size of the matrix is then
-   * <tt>source.dofs_per_face</tt> times <tt>this->dofs_per_face</tt>.
-   *
-   * Derived elements will have to implement this function. They may only
-   * provide interpolation matrices for certain source finite elements, for
-   * example those from the same family. If they don't implement interpolation
-   * from a given element, then they must throw an exception of type
-   * FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented.
+   * <tt>source.dofs_per_face</tt> times <tt>this->dofs_per_face</tt>. The
+   * FE_Q element family only provides interpolation matrices for elements of
+   * the same type and FE_Nothing. For all other elements, an exception of
+   * type FiniteElement<dim,spacedim>::ExcInterpolationNotImplemented is
+   * thrown.
    */
   virtual void
   get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &source,
@@ -157,6 +153,48 @@ public:
   get_prolongation_matrix (const unsigned int child,
                            const RefinementCase<dim> &refinement_case=RefinementCase<dim>::isotropic_refinement) const;
 
+  /**
+   * Given an index in the natural ordering of indices on a face, return the
+   * index of the same degree of freedom on the cell.
+   *
+   * To explain the concept, consider the case where we would like to know
+   * whether a degree of freedom on a face, for example as part of an FESystem
+   * element, is primitive. Unfortunately, the
+   * is_primitive() function in the FiniteElement class takes a cell index, so
+   * we would need to find the cell index of the shape function that
+   * corresponds to the present face index. This function does that.
+   *
+   * Code implementing this would then look like this:
+   * @code
+   * for (i=0; i<dofs_per_face; ++i)
+   *  if (fe.is_primitive(fe.face_to_equivalent_cell_index(i, some_face_no)))
+   *   ... do whatever
+   * @endcode
+   * The function takes additional arguments that account for the fact that
+   * actual faces can be in their standard ordering with respect to the cell
+   * under consideration, or can be flipped, oriented, etc.
+   *
+   * @param face_dof_index The index of the degree of freedom on a face.
+   *   This index must be between zero and dofs_per_face.
+   * @param face The number of the face this degree of freedom lives on.
+   *   This number must be between zero and GeometryInfo::faces_per_cell.
+   * @param face_orientation One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @param face_flip One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @param face_rotation One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @return The index of this degree of freedom within the set
+   *   of degrees of freedom on the entire cell. The returned value
+   *   will be between zero and dofs_per_cell.
+   */
+  virtual
+  unsigned int face_to_cell_index (const unsigned int face_dof_index,
+                                   const unsigned int face,
+                                   const bool face_orientation = true,
+                                   const bool face_flip        = false,
+                                   const bool face_rotation    = false) const;
+
   /**
    * @name Functions to support hp
    * @{
index 96a0d2dfbd80c2ad86d849a83b1ed751e273307d..0705632bacafc5d3818edb9e6f1921312e52ae22 100644 (file)
@@ -413,6 +413,48 @@ public:
   get_prolongation_matrix (const unsigned int child,
                            const RefinementCase<dim> &refinement_case=RefinementCase<dim>::isotropic_refinement) const;
 
+  /**
+   * Given an index in the natural ordering of indices on a face, return the
+   * index of the same degree of freedom on the cell.
+   *
+   * To explain the concept, consider the case where we would like to know
+   * whether a degree of freedom on a face, for example as part of an FESystem
+   * element, is primitive. Unfortunately, the
+   * is_primitive() function in the FiniteElement class takes a cell index, so
+   * we would need to find the cell index of the shape function that
+   * corresponds to the present face index. This function does that.
+   *
+   * Code implementing this would then look like this:
+   * @code
+   * for (i=0; i<dofs_per_face; ++i)
+   *  if (fe.is_primitive(fe.face_to_equivalent_cell_index(i, some_face_no)))
+   *   ... do whatever
+   * @endcode
+   * The function takes additional arguments that account for the fact that
+   * actual faces can be in their standard ordering with respect to the cell
+   * under consideration, or can be flipped, oriented, etc.
+   *
+   * @param face_dof_index The index of the degree of freedom on a face.
+   *   This index must be between zero and dofs_per_face.
+   * @param face The number of the face this degree of freedom lives on.
+   *   This number must be between zero and GeometryInfo::faces_per_cell.
+   * @param face_orientation One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @param face_flip One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @param face_rotation One part of the description of the orientation
+   *   of the face. See @ref GlossFaceOrientation .
+   * @return The index of this degree of freedom within the set
+   *   of degrees of freedom on the entire cell. The returned value
+   *   will be between zero and dofs_per_cell.
+   */
+  virtual
+  unsigned int face_to_cell_index (const unsigned int face_dof_index,
+                                   const unsigned int face,
+                                   const bool face_orientation = true,
+                                   const bool face_flip        = false,
+                                   const bool face_rotation    = false) const;
+
   /**
    * Implementation of the respective function in the base class.
    */
@@ -804,9 +846,11 @@ private:
   public:
     /**
      * Constructor. Is called by the @p get_data function. Sets the size of
-     * the @p base_fe_datas vector to @p n_base_elements.
+     * the @p base_fe_datas vector to @p n_base_elements and initializes
+     * the compute_hessians field.
      */
-    InternalData (const unsigned int n_base_elements);
+    InternalData (const unsigned int n_base_elements,
+                  const bool         compute_hessians);
 
     /**
      * Destructor. Deletes all @p InternalDatas whose pointers are stored by
@@ -817,7 +861,7 @@ private:
     /**
      * Flag indicating whether second derivatives shall be computed.
      */
-    bool compute_hessians;
+    const bool compute_hessians;
 
     /**
      * Gives write-access to the pointer to a @p InternalData of the @p
index f93a0cdf05650f392a7ff106881d7b7a06be4713..30ae94374310085f790da616278ce945492255c1 100644 (file)
@@ -52,6 +52,8 @@ template <int dim, int spacedim> class FESubfaceValues;
  * the transform() functions of
  * inheriting classes in order to
  * work.
+ *
+ * @ingroup mapping
  */
 enum MappingType
 {
index 39676698608ff92918e5df574b2d09817f0cf79f..a3f40212781bdb734438de9de6b8092d442fa9c2 100644 (file)
@@ -33,34 +33,25 @@ template <typename number> class SparseMatrix;
 
 
 /**
- * This class provides a collection of functions for generating basic
- * triangulations. Below, we try to provide some pictures in order to
- * illustrate at least the more complex ones.
+ * This namespace provides a collection of functions for generating
+ * triangulations for some basic geometries.
  *
  * Some of these functions receive a flag @p colorize. If this is
- * set, parts of the boundary receive different boundary numbers,
- * allowing them to be distinguished by application programs. See the
- * documentation of the functions for details.
- *
- * Additionally this class provides a function
- * (@p laplace_transformation) that smoothly transforms a grid
- * according to given new boundary points. This can be used to
- * transform (simple-shaped) grids to a more complicated ones, like a
- * shell onto a grid of an airfoil, for example.
- *
- * No meshes for the codimension one case are provided at the moment.
+ * set, parts of the boundary receive different boundary indicators
+ * (@ref GlossBoundaryIndicator),
+ * allowing them to be distinguished for the purpose of attaching geometry
+ * objects and evaluating different boundary conditions.
  *
+ * This namespace also provides a function
+ * GridGenerator::laplace_transformation that smoothly transforms a domain
+ * into another one. This can be used to
+ * transform basic geometries to more complicated ones, like a
+ * shell to a grid of an airfoil, for example.
  *
  * @ingroup grid
  */
-class GridGenerator
+namespace GridGenerator
 {
-public:
-  /**
-   * Declare type for number of cell.
-   */
-  typedef types::global_dof_index size_type;
-
   /**
    * Initialize the given triangulation with a hypercube (line in 1D, square
    * in 2D, etc) consisting of exactly one cell. The hypercube volume is the
@@ -79,9 +70,9 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim, int spacedim>
-  static void hyper_cube (Triangulation<dim,spacedim>  &tria,
-                          const double        left = 0.,
-                          const double        right= 1.);
+  void hyper_cube (Triangulation<dim,spacedim>  &tria,
+                   const double                  left = 0.,
+                   const double                  right= 1.);
 
   /**
    * Same as hyper_cube(), but with the difference that not only one cell is
@@ -97,10 +88,10 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void subdivided_hyper_cube (Triangulation<dim>  &tria,
-                                     const unsigned int  repetitions,
-                                     const double        left = 0.,
-                                     const double        right= 1.);
+  void subdivided_hyper_cube (Triangulation<dim>  &tria,
+                              const unsigned int   repetitions,
+                              const double         left = 0.,
+                              const double         right= 1.);
 
   /**
    * Create a coordinate-parallel brick from the two diagonally opposite
@@ -118,10 +109,10 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim, int spacedim>
-  static void hyper_rectangle (Triangulation<dim,spacedim> &tria,
-                               const Point<spacedim>       &p1,
-                               const Point<spacedim>       &p2,
-                               const bool                  colorize = false);
+  void hyper_rectangle (Triangulation<dim,spacedim> &tria,
+                        const Point<spacedim>       &p1,
+                        const Point<spacedim>       &p2,
+                        const bool                   colorize = false);
 
   /**
    * Create a coordinate-parallel parallelepiped from the two diagonally
@@ -155,13 +146,12 @@ public:
    * program.
    */
   template <int dim>
-  static
   void
   subdivided_hyper_rectangle (Triangulation<dim>              &tria,
                               const std::vector<unsigned int> &repetitions,
                               const Point<dim>                &p1,
                               const Point<dim>                &p2,
-                              const bool                      colorize=false);
+                              const bool                       colorize=false);
 
   /**
    * Like the previous function. However, here the second argument does not
@@ -179,13 +169,12 @@ public:
    * specified by the points @p p1 and @p p2.
    */
   template <int dim>
-  static
   void
-  subdivided_hyper_rectangle(Triangulation<dim>                      &tria,
-                             const std::vector<std::vector<double> > &step_sizes,
-                             const Point<dim>                        &p_1,
-                             const Point<dim>                        &p_2,
-                             const bool                              colorize);
+  subdivided_hyper_rectangle (Triangulation<dim>                      &tria,
+                              const std::vector<std::vector<double> > &step_sizes,
+                              const Point<dim>                        &p_1,
+                              const Point<dim>                        &p_2,
+                              const bool                               colorize);
 
   /**
    * Like the previous function, but with the following twist: the @p
@@ -196,13 +185,12 @@ public:
    * i.e. the domain will have a void there.
    */
   template <int dim>
-  static
   void
   subdivided_hyper_rectangle (Triangulation<dim>                       &tria,
                               const std::vector< std::vector<double> > &spacing,
                               const Point<dim>                         &p,
-                              const Table<dim,types::material_id>           &material_id,
-                              const bool                               colorize=false);
+                              const Table<dim,types::material_id>      &material_id,
+                              const bool                                colorize=false);
 
   /**
    * A parallelogram. The first corner point is the origin. The <tt>dim</tt>
@@ -215,21 +203,19 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static
   void
-  parallelogram(Triangulation<dim> &tria,
-                const Point<dim> (&corners)[dim],
-                const bool           colorize=false);
+  parallelogram (Triangulation<dim> &tria,
+                 const Point<dim>  (&corners) [dim],
+                 const bool          colorize=false);
 
   /**
    * @deprecated Use the other function of same name.
    */
   template <int dim>
-  static
   void
-  parallelogram(Triangulation<dim> &tria,
-                const Tensor<2,dim> &corners,
-                const bool           colorize=false) DEAL_II_DEPRECATED;
+  parallelogram (Triangulation<dim>  &tria,
+                 const Tensor<2,dim> &corners,
+                 const bool           colorize=false) DEAL_II_DEPRECATED;
 
   /**
    * A parallelepiped. The first corner point is the origin. The
@@ -249,11 +235,10 @@ public:
    * function.
    */
   template <int dim>
-  static
   void
-  parallelepiped (Triangulation<dim>  &tria,
-                  const Point<dim>   (&corners) [dim],
-                  const bool           colorize = false);
+  parallelepiped (Triangulation<dim> &tria,
+                  const Point<dim>  (&corners) [dim],
+                  const bool          colorize = false);
 
   /**
    * A subdivided parallelepiped. The first corner point is the
@@ -268,10 +253,9 @@ public:
    * function.
    */
   template <int dim>
-  static
   void
   subdivided_parallelepiped (Triangulation<dim>  &tria,
-                             const size_type     n_subdivisions,
+                             const unsigned int   n_subdivisions,
                              const Point<dim>   (&corners) [dim],
                              const bool           colorize = false);
 
@@ -284,10 +268,9 @@ public:
    * function.
    */
   template <int dim>
-  static
   void
   subdivided_parallelepiped (Triangulation<dim>  &tria,
-                             const size_type    ( n_subdivisions) [dim],
+                             const unsigned int  (n_subdivisions) [dim],
                              const Point<dim>   (&corners) [dim],
                              const bool           colorize = false);
 
@@ -307,11 +290,11 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void enclosed_hyper_cube (Triangulation<dim> &tria,
-                                   const double      left = 0.,
-                                   const double      right= 1.,
-                                   const double      thickness = 1.,
-                                   const bool        colorize = false);
+  void enclosed_hyper_cube (Triangulation<dim> &tria,
+                            const double        left = 0.,
+                            const double        right= 1.,
+                            const double        thickness = 1.,
+                            const bool          colorize = false);
 
   /**
    * Initialize the given triangulation with a hyperball, i.e. a circle or a
@@ -328,9 +311,9 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void hyper_ball (Triangulation<dim> &tria,
-                          const Point<dim>   &center = Point<dim>(),
-                          const double      radius = 1.);
+  void hyper_ball (Triangulation<dim> &tria,
+                   const Point<dim>   &center = Point<dim>(),
+                   const double        radius = 1.);
 
   /**
    * This class produces a half hyper-ball around <tt>center</tt>, which
@@ -346,9 +329,9 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void half_hyper_ball (Triangulation<dim> &tria,
-                               const Point<dim>   &center = Point<dim>(),
-                               const double      radius = 1.);
+  void half_hyper_ball (Triangulation<dim> &tria,
+                        const Point<dim>   &center = Point<dim>(),
+                        const double        radius = 1.);
 
   /**
    * Create a cylinder around the x-axis.  The cylinder extends from
@@ -366,9 +349,9 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void cylinder (Triangulation<dim> &tria,
-                        const double      radius = 1.,
-                        const double      half_length = 1.);
+  void cylinder (Triangulation<dim> &tria,
+                 const double        radius = 1.,
+                 const double        half_length = 1.);
 
   /**
    * Create a cutted cone around the x-axis.  The cone extends from
@@ -395,11 +378,11 @@ public:
    * @author Markus B&uuml;rg, 2009
    */
   template <int dim>
-  static void
+  void
   truncated_cone (Triangulation<dim> &tria,
-                  const double radius_0 = 1.0,
-                  const double radius_1 = 0.5,
-                  const double half_length = 1.0);
+                  const double        radius_0 = 1.0,
+                  const double        radius_1 = 0.5,
+                  const double        half_length = 1.0);
 
   /**
    * Initialize the given triangulation with a hyper-L consisting of exactly
@@ -417,9 +400,9 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void hyper_L (Triangulation<dim> &tria,
-                       const double      left = -1.,
-                       const double      right= 1.);
+  void hyper_L (Triangulation<dim> &tria,
+                const double        left = -1.,
+                const double        right= 1.);
 
   /**
    * Initialize the given Triangulation with a hypercube with a slit. In each
@@ -437,10 +420,10 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void hyper_cube_slit (Triangulation<dim> &tria,
-                               const double      left = 0.,
-                               const double      right= 1.,
-                               const bool colorize = false);
+  void hyper_cube_slit (Triangulation<dim> &tria,
+                        const double        left = 0.,
+                        const double        right = 1.,
+                        const bool          colorize = false);
 
   /**
    * Produce a hyper-shell, the region between two spheres around
@@ -491,12 +474,12 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void hyper_shell (Triangulation<dim>   &tria,
-                           const Point<dim>     &center,
-                           const double        inner_radius,
-                           const double        outer_radius,
-                           const size_type     n_cells = 0,
-                           bool colorize = false);
+  void hyper_shell (Triangulation<dim> &tria,
+                    const Point<dim>   &center,
+                    const double        inner_radius,
+                    const double        outer_radius,
+                    const unsigned int  n_cells = 0,
+                    bool                colorize = false);
 
   /**
    * Produce a half hyper-shell, i.e. the space between two circles in two
@@ -520,12 +503,12 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void half_hyper_shell (Triangulation<dim>   &tria,
-                                const Point<dim>     &center,
-                                const double        inner_radius,
-                                const double        outer_radius,
-                                const size_type     n_cells = 0,
-                                const bool colorize = false);
+  void half_hyper_shell (Triangulation<dim> &tria,
+                         const Point<dim>   &center,
+                         const double        inner_radius,
+                         const double        outer_radius,
+                         const unsigned int  n_cells = 0,
+                         const bool          colorize = false);
 
 
   /**
@@ -549,12 +532,12 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void quarter_hyper_shell (Triangulation<dim>   &tria,
-                                   const Point<dim>     &center,
-                                   const double        inner_radius,
-                                   const double        outer_radius,
-                                   const size_type     n_cells = 0,
-                                   const bool colorize = false);
+  void quarter_hyper_shell (Triangulation<dim> &tria,
+                            const Point<dim>   &center,
+                            const double        inner_radius,
+                            const double        outer_radius,
+                            const unsigned int  n_cells = 0,
+                            const bool          colorize = false);
 
   /**
    * Produce a domain that is the space between two cylinders in 3d, with
@@ -569,12 +552,12 @@ public:
    * @note The triangulation needs to be void upon calling this function.
    */
   template <int dim>
-  static void cylinder_shell (Triangulation<dim>   &tria,
-                              const double        length,
-                              const double        inner_radius,
-                              const double        outer_radius,
-                              const size_type     n_radial_cells = 0,
-                              const size_type     n_axial_cells = 0);
+  void cylinder_shell (Triangulation<dim> &tria,
+                       const double        length,
+                       const double        inner_radius,
+                       const double        outer_radius,
+                       const unsigned int  n_radial_cells = 0,
+                       const unsigned int  n_axial_cells = 0);
 
 
 
@@ -592,9 +575,9 @@ public:
    * torus.
    */
 
-  static void torus (Triangulation<2,3>  &tria,
-                     const double         R,
-                     const double         r);
+  void torus (Triangulation<2,3> &tria,
+              const double        R,
+              const double        r);
 
 
   /**
@@ -622,12 +605,13 @@ public:
    *    get the number 0 and the hole gets number 1.
    */
   template<int dim>
-  static void hyper_cube_with_cylindrical_hole (Triangulation<dim> &triangulation,
-                                                const double inner_radius = .25,
-                                                const double outer_radius = .5,
-                                                const double L = .5,
-                                                const size_type repetition = 1,
-                                                const bool colorize = false);
+  void hyper_cube_with_cylindrical_hole (
+      Triangulation<dim> &triangulation,
+      const double        inner_radius = .25,
+      const double        outer_radius = .5,
+      const double        L = .5,
+      const unsigned int  repetition = 1,
+      const bool          colorize = false);
 
   /**
    * Produce a ring of cells in 3D that is cut open, twisted and glued
@@ -639,11 +623,11 @@ public:
    * @param R           The radius of the circle, which forms the middle line of the torus containing the loop of cells. Must be greater than @p r.
    * @param r           The radius of the cylinder bend together as loop.
    */
-  static void moebius (Triangulation<3,3>  &tria,
-                       const size_type      n_cells,
-                       const unsigned int   n_rotations,
-                       const double         R,
-                       const double         r);
+  void moebius (Triangulation<3,3> &tria,
+                const unsigned int  n_cells,
+                const unsigned int  n_rotations,
+                const double        R,
+                const double        r);
 
   /**
    * Given the two triangulations specified as the first two arguments, create
@@ -676,7 +660,6 @@ public:
    * GridTools::create_union_triangulation .
    */
   template <int dim, int spacedim>
-  static
   void
   merge_triangulations (const Triangulation<dim, spacedim> &triangulation_1,
                         const Triangulation<dim, spacedim> &triangulation_2,
@@ -690,12 +673,11 @@ public:
    * to the corresponding side walls in z direction. The bottom and top
    * get the next two free boundary indicators.
    */
-  static
   void
-  extrude_triangulation(const Triangulation<2, 2> &input,
-                        const size_type n_slices,
-                        const double height,
-                        Triangulation<3,3> &result);
+  extrude_triangulation (const Triangulation<2, 2> &input,
+                         const unsigned int         n_slices,
+                         const double               height,
+                         Triangulation<3,3>        &result);
 
   /**
    * This function transformes the @p Triangulation @p tria smoothly to a
@@ -712,9 +694,8 @@ public:
    * @deprecated This function has been moved to GridTools::laplace_transform
    */
   template <int dim>
-  static
   void laplace_transformation (Triangulation<dim> &tria,
-                               const std::map<size_type,Point<dim> > &new_points) DEAL_II_DEPRECATED;
+                               const std::map<unsigned int,Point<dim> > &new_points) DEAL_II_DEPRECATED;
 
   /**
    * Exception
@@ -734,67 +715,7 @@ public:
                   int,
                   << "The vector of repetitions  must have "
                   << arg1 <<" elements.");
-
-private:
-  /**
-   * Perform the action specified by the @p colorize flag of the
-   * hyper_rectangle() function of this class.
-   */
-  template <int dim, int spacedim>
-  static
-  void
-  colorize_hyper_rectangle (Triangulation<dim,spacedim> &tria);
-
-  /**
-   * Perform the action specified by the @p colorize flag of the
-   * subdivided_hyper_rectangle() function of this class. This function is
-   * singled out because it is dimension specific.
-   */
-  template <int dim>
-  static
-  void
-  colorize_subdivided_hyper_rectangle (Triangulation<dim> &tria,
-                                       const Point<dim>   &p1,
-                                       const Point<dim>   &p2,
-                                       const double        epsilon);
-
-  /**
-   * Assign boundary number zero to the inner shell boundary and 1 to the
-   * outer.
-   */
-  template<int dim>
-  static
-  void
-  colorize_hyper_shell (Triangulation<dim> &tria,
-                        const Point<dim> &center,
-                        const double inner_radius,
-                        const double outer_radius);
-
-
-  /**
-   * Assign boundary number zero the inner shell boundary, one to the outer
-   * shell boundary, two to the face with x=0, three to the face with y=0,
-   * four to the face with z=0.
-   */
-  template<int dim>
-  static
-  void
-  colorize_quarter_hyper_shell(Triangulation<dim> &tria,
-                               const Point<dim> &center,
-                               const double inner_radius,
-                               const double outer_radius);
-
-  /**
-   * Solve the Laplace equation for @p laplace_transformation function for one
-   * of the @p dim space dimensions. Externalized into a function of its own
-   * in order to allow parallel execution.
-   */
-  static
-  void
-  laplace_solve (const SparseMatrix<double>          &S,
-                 const std::map<size_type,double> &m,
-                 Vector<double>                      &u);
-};
+}
 
 
 
index 1df740cff6064c19b3e378eb6dd820466074ccf0..bdbc8ab7929437f1c1a8da4e666d6f0f22433ac1 100644 (file)
@@ -237,16 +237,32 @@ namespace GridTools
                Triangulation<2> &triangulation);
 
   /**
-   * This function transformes the @p Triangulation @p tria smoothly to a
-   * domain that is described by the boundary points in the map @p
-   * new_points. This map maps the point indices to the boundary points in the
-   * transformed domain.
-   *
-   * Note, that the @p Triangulation is changed in-place, therefore you don't
-   * need to keep two triangulations, but the given triangulation is changed
-   * (overwritten).
-   *
-   * In 1d, this function is not currently implemented.
+   * Transform the given triangulation smoothly to a different domain where
+   * each of the vertices at the boundary of the triangulation is mapped to
+   * the corresponding points in the @p new_points map.
+   *
+   * The way this function works is that it solves a Laplace equation for each
+   * of the dim components of a displacement field that maps the current
+   * domain into one described by @p new_points . The @p new_points array
+   * therefore represents the boundary values of this displacement field.
+   * The function then evaluates this displacement field at each vertex in
+   * the interior and uses it to place the mapped vertex where the
+   * displacement field locates it. Because the solution of the Laplace
+   * equation is smooth, this guarantees a smooth mapping from the old
+   * domain to the new one.
+   *
+   * @param[in] new_points The locations where a subset of the existing vertices
+   * are to be placed. Typically, this would be a map from the vertex indices
+   * of all nodes on the boundary to their new locations, thus completely
+   * specifying the geometry of the mapped domain. However, it may also include
+   * interior points if necessary and it does not need to include all boundary
+   * vertices (although you then lose control over the exact shape of the mapped
+   * domain).
+   *
+   * @param[in,out] tria The Triangulation object. This object is changed in-place,
+   * i.e., the previous locations of vertices are overwritten.
+   *
+   * @note This function is not currently implemented for the 1d case.
    */
   template <int dim>
   void laplace_transform (const std::map<unsigned int,Point<dim> > &new_points,
index 6705f5ded335ad91b1b8df54d8998bfd9d0b74ad..984374f98f4242365221c2c58b4064beebbbd0d9 100644 (file)
 #include <deal.II/grid/tria_iterator_selector.h>
 #include <deal.II/grid/cell_id.h>
 
+#include <utility>
 
-namespace std
-{
-  template<class T1, class T2>
-  struct pair;
-}
 
 DEAL_II_NAMESPACE_OPEN
 
index fd02273faa2bd55c2dd2a510c3cd5a2993da8118..d077e4d8384ff4674b050d2e25816a5f9550cb51 100644 (file)
@@ -64,63 +64,45 @@ namespace internal
     {
     public:
       /**
-       * Constructor. Set the fields
-       * of this class to the values
-       * indicated by the parameters
-       * to the constructor.
+       * Constructor. Set the fields of this class to the values indicated by
+       * the parameters to the constructor.
        */
       FEValuesBase (const dealii::hp::MappingCollection<dim,FEValues::space_dimension> &mapping_collection,
                     const dealii::hp::FECollection<dim,FEValues::space_dimension>      &fe_collection,
                     const dealii::hp::QCollection<q_dim>     &q_collection,
                     const UpdateFlags             update_flags);
       /**
-       * Constructor. Set the fields
-       * of this class to the values
-       * indicated by the parameters
-       * to the constructor, and
-       * choose a @p MappingQ1
-       * object for the mapping
-       * object.
+       * Constructor. Set the fields of this class to the values indicated by
+       * the parameters to the constructor, and choose a @p MappingQ1 object
+       * for the mapping object.
        */
       FEValuesBase (const dealii::hp::FECollection<dim,FEValues::space_dimension> &fe_collection,
                     const dealii::hp::QCollection<q_dim> &q_collection,
                     const UpdateFlags         update_flags);
 
       /**
-       * Get a reference to the
-       * collection of finite
-       * element objects used here.
+       * Get a reference to the collection of finite element objects used
+       * here.
        */
       const dealii::hp::FECollection<dim,FEValues::space_dimension> &
       get_fe_collection () const;
 
       /**
-       * Return a reference to the @p
-       * FEValues object selected by the
-       * last call to
-       * select_fe_values(). select_fe_values()
-       * in turn is called when you called
-       * the @p reinit function of the
-       * <tt>hp::FE*Values</tt> class the
-       * last time.
+       * Return a reference to the @p FEValues object selected by the last
+       * call to select_fe_values(). select_fe_values() in turn is called when
+       * you called the @p reinit function of the <tt>hp::FE*Values</tt> class
+       * the last time.
        */
       const FEValues &get_present_fe_values () const;
 
     protected:
 
       /**
-       * Select a FEValues object
-       * suitable for the given FE,
-       * quadrature, and mapping
-       * indices. If such an object
-       * doesn't yet exist, create
-       * one.
+       * Select a FEValues object suitable for the given FE, quadrature, and
+       * mapping indices. If such an object doesn't yet exist, create one.
        *
-       * The function returns a
-       * writable reference so that
-       * derived classes can also
-       * reinit() the selected
-       * FEValues object.
+       * The function returns a writable reference so that derived classes can
+       * also reinit() the selected FEValues object.
        */
       FEValues &
       select_fe_values (const unsigned int fe_index,
@@ -129,68 +111,44 @@ namespace internal
 
     protected:
       /**
-       * A pointer to the
-       * collection of finite
-       * elements to be used.
+       * A pointer to the collection of finite elements to be used.
        */
       const SmartPointer<const dealii::hp::FECollection<dim,FEValues::space_dimension>,
             FEValuesBase<dim,q_dim,FEValues> > fe_collection;
 
       /**
-       * A pointer to the
-       * collection of mappings to
-       * be used.
+       * A pointer to the collection of mappings to be used.
        */
       const SmartPointer<const dealii::hp::MappingCollection<dim, FEValues::space_dimension>,
             FEValuesBase<dim,q_dim,FEValues> > mapping_collection;
 
       /**
-       * Copy of the quadrature
-       * collection object
-       * provided to the
-       * constructor.
+       * Copy of the quadrature collection object provided to the constructor.
        */
       const dealii::hp::QCollection<q_dim> q_collection;
 
     private:
       /**
-       * A table in which we store
-       * pointers to fe_values
-       * objects for different
-       * finite element, mapping,
-       * and quadrature objects
-       * from our collection. The
-       * first index indicates the
-       * index of the finite
-       * element within the
-       * fe_collection, the second
-       * the index of the mapping
-       * within the mapping
-       * collection, and the last
-       * one the index of the
-       * quadrature formula within
-       * the q_collection.
+       * A table in which we store pointers to fe_values objects for different
+       * finite element, mapping, and quadrature objects from our
+       * collection. The first index indicates the index of the finite element
+       * within the fe_collection, the second the index of the mapping within
+       * the mapping collection, and the last one the index of the quadrature
+       * formula within the q_collection.
        *
-       * Initially, all entries
-       * have zero pointers, and we
-       * will allocate them lazily
-       * as needed in
-       * select_fe_values().
+       * Initially, all entries have zero pointers, and we will allocate them
+       * lazily as needed in select_fe_values().
        */
       Table<3,std_cxx1x::shared_ptr<FEValues> > fe_values_table;
 
       /**
-       * Set of indices pointing at
-       * the fe_values object
-       * selected last time the
-       * select_fe_value() function
-       * was called.
+       * Set of indices pointing at the fe_values object selected last time
+       * the select_fe_value() function was called.
        */
       TableIndices<3> present_fe_values_index;
 
       /**
-       * Values of the update flags as
-       * given to the constructor.
+       * Values of the update flags as given to the constructor.
        */
       const UpdateFlags update_flags;
     };
@@ -259,24 +217,13 @@ namespace hp
     static const unsigned int space_dimension = spacedim;
 
     /**
-     * Constructor. Initialize this
-     * object with the given
-     * parameters.
+     * Constructor. Initialize this object with the given parameters.
      *
-     * The finite element
-     * collection parameter is
-     * actually ignored, but is in
-     * the signature of this
-     * function to make it
-     * compatible with the
-     * signature of the respective
-     * constructor of the usual
-     * FEValues object, with
-     * the respective parameter in
-     * that function also being the
-     * return value of the
-     * <tt>DoFHandler::get_fe()</tt>
-     * function.
+     * The finite element collection parameter is actually ignored, but is in
+     * the signature of this function to make it compatible with the signature
+     * of the respective constructor of the usual FEValues object, with the
+     * respective parameter in that function also being the return value of
+     * the <tt>DoFHandler::get_fe()</tt> function.
      */
     FEValues (const dealii::hp::MappingCollection<dim,spacedim> &mapping_collection,
               const dealii::hp::FECollection<dim,spacedim>  &fe_collection,
@@ -285,26 +232,14 @@ namespace hp
 
 
     /**
-     * Constructor. Initialize this
-     * object with the given
-     * parameters, and choose a
-     * @p MappingQ1 object for the
-     * mapping object.
+     * Constructor. Initialize this object with the given parameters, and
+     * choose a @p MappingQ1 object for the mapping object.
      *
-     * The finite element
-     * collection parameter is
-     * actually ignored, but is in
-     * the signature of this
-     * function to make it
-     * compatible with the
-     * signature of the respective
-     * constructor of the usual
-     * FEValues object, with
-     * the respective parameter in
-     * that function also being the
-     * return value of the
-     * <tt>DoFHandler::get_fe()</tt>
-     * function.
+     * The finite element collection parameter is actually ignored, but is in
+     * the signature of this function to make it compatible with the signature
+     * of the respective constructor of the usual FEValues object, with the
+     * respective parameter in that function also being the return value of
+     * the <tt>DoFHandler::get_fe()</tt> function.
      */
     FEValues (const hp::FECollection<dim,spacedim> &fe_collection,
               const hp::QCollection<dim>      &q_collection,
@@ -312,103 +247,50 @@ namespace hp
 
 
     /**
-     * Reinitialize the object for
-     * the given cell.
+     * Reinitialize the object for the given cell.
      *
-     * After the call, you can get
-     * an FEValues object using the
-     * get_present_fe_values()
-     * function that corresponds to
-     * the present cell. For this
-     * FEValues object, we use the
-     * additional arguments
-     * described below to determine
-     * which finite element,
-     * mapping, and quadrature
-     * formula to use. They are
-     * order in such a way that the
-     * arguments one may want to
-     * change most frequently come
-     * first. The rules for these
-     * arguments are as follows:
+     * After the call, you can get an FEValues object using the
+     * get_present_fe_values() function that corresponds to the present
+     * cell. For this FEValues object, we use the additional arguments
+     * described below to determine which finite element, mapping, and
+     * quadrature formula to use. They are order in such a way that the
+     * arguments one may want to change most frequently come first. The rules
+     * for these arguments are as follows:
      *
-     * If the @p fe_index argument
-     * to this function is left at
-     * its default value, then we
-     * use that finite element
-     * within the hp::FECollection
-     * passed to the constructor of
-     * this class with index given
-     * by
-     * <code>cell-@>active_fe_index()</code>. Consequently,
-     * the hp::FECollection
-     * argument given to this
-     * object should really be the
-     * same as that used in the
-     * construction of the
-     * hp::DofHandler associated
-     * with the present cell. On
-     * the other hand, if a value
-     * is given for this argument,
-     * it overrides the choice of
+     * If the @p fe_index argument to this function is left at its default
+     * value, then we use that finite element within the hp::FECollection
+     * passed to the constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>. Consequently, the
+     * hp::FECollection argument given to this object should really be the
+     * same as that used in the construction of the hp::DofHandler associated
+     * with the present cell. On the other hand, if a value is given for this
+     * argument, it overrides the choice of
      * <code>cell-@>active_fe_index()</code>.
      *
-     * If the @p q_index argument
-     * is left at its default
-     * value, then we use that
-     * quadrature formula within
-     * the hp::QCollection passed
-     * to the constructor of this
-     * class with index given by
-     * <code>cell-@>active_fe_index()</code>,
-     * i.e. the same index as that
-     * of the finite element. In
-     * this case, there should be a
-     * corresponding quadrature
-     * formula for each finite
-     * element in the
-     * hp::FECollection. As a
-     * special case, if the
-     * quadrature collection
-     * contains only a single
-     * element (a frequent case if
-     * one wants to use the same
-     * quadrature object for all
-     * finite elements in an hp
-     * discretization, even if that
-     * may not be the most
-     * efficient), then this single
-     * quadrature is used unless a
-     * different value for this
-     * argument is specified. On
-     * the other hand, if a value
-     * is given for this argument,
-     * it overrides the choice of
-     * <code>cell-@>active_fe_index()</code>
-     * or the choice for the single
+     * If the @p q_index argument is left at its default value, then we use
+     * that quadrature formula within the hp::QCollection passed to the
+     * constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>, i.e. the same index as that of
+     * the finite element. In this case, there should be a corresponding
+     * quadrature formula for each finite element in the hp::FECollection. As
+     * a special case, if the quadrature collection contains only a single
+     * element (a frequent case if one wants to use the same quadrature object
+     * for all finite elements in an hp discretization, even if that may not
+     * be the most efficient), then this single quadrature is used unless a
+     * different value for this argument is specified. On the other hand, if a
+     * value is given for this argument, it overrides the choice of
+     * <code>cell-@>active_fe_index()</code> or the choice for the single
      * quadrature.
      *
-     * If the @p mapping_index
-     * argument is left at its
-     * default value, then we use
-     * that mapping object within
-     * the hp::MappingCollection
-     * passed to the constructor of
-     * this class with index given
-     * by
-     * <code>cell-@>active_fe_index()</code>,
-     * i.e. the same index as that
-     * of the finite
-     * element. As above, if the
-     * mapping collection contains
-     * only a single element (a
-     * frequent case if one wants
-     * to use a MappingQ1 object
-     * for all finite elements in
-     * an hp discretization), then
-     * this single mapping is used
-     * unless a different value for
-     * this argument is specified.
+     * If the @p mapping_index argument is left at its default value, then we
+     * use that mapping object within the hp::MappingCollection passed to the
+     * constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>, i.e. the same index as that of
+     * the finite element. As above, if the mapping collection contains only a
+     * single element (a frequent case if one wants to use a MappingQ1 object
+     * for all finite elements in an hp discretization), then this single
+     * mapping is used unless a different value for this argument is
+     * specified.
      */
     template <class DH, bool lda>
     void
@@ -418,33 +300,17 @@ namespace hp
             const unsigned int fe_index = numbers::invalid_unsigned_int);
 
     /**
-     * Like the previous function,
-     * but for non-hp
-     * iterators. The reason this
-     * (and the other non-hp
-     * iterator) function exists is
-     * so that one can use
-     * hp::FEValues not only for
-     * hp::DoFhandler objects, but
-     * for all sorts of DoFHandler
-     * objects, and triangulations
-     * not associated with
-     * DoFHandlers in general.
+     * Like the previous function, but for non-hp iterators. The reason this
+     * (and the other non-hp iterator) function exists is so that one can use
+     * hp::FEValues not only for hp::DoFhandler objects, but for all sorts of
+     * DoFHandler objects, and triangulations not associated with DoFHandlers
+     * in general.
      *
-     * Since
-     * <code>cell-@>active_fe_index()</code>
-     * doesn't make sense for
-     * triangulation iterators,
-     * this function chooses the
-     * zero-th finite element,
-     * mapping, and quadrature
-     * object from the relevant
-     * constructions passed to the
-     * constructor of this
-     * object. The only exception
-     * is if you specify a value
-     * different from the default
-     * value for any of these last
+     * Since <code>cell-@>active_fe_index()</code> doesn't make sense for
+     * triangulation iterators, this function chooses the zero-th finite
+     * element, mapping, and quadrature object from the relevant constructions
+     * passed to the constructor of this object. The only exception is if you
+     * specify a value different from the default value for any of these last
      * three arguments.
      */
     void
@@ -486,24 +352,13 @@ namespace hp
   {
   public:
     /**
-     * Constructor. Initialize this
-     * object with the given
-     * parameters.
+     * Constructor. Initialize this object with the given parameters.
      *
-     * The finite element
-     * collection parameter is
-     * actually ignored, but is in
-     * the signature of this
-     * function to make it
-     * compatible with the
-     * signature of the respective
-     * constructor of the usual
-     * FEValues object, with
-     * the respective parameter in
-     * that function also being the
-     * return value of the
-     * <tt>DoFHandler::get_fe()</tt>
-     * function.
+     * The finite element collection parameter is actually ignored, but is in
+     * the signature of this function to make it compatible with the signature
+     * of the respective constructor of the usual FEValues object, with the
+     * respective parameter in that function also being the return value of
+     * the <tt>DoFHandler::get_fe()</tt> function.
      */
     FEFaceValues (const hp::MappingCollection<dim,spacedim> &mapping_collection,
                   const hp::FECollection<dim,spacedim>  &fe_collection,
@@ -512,129 +367,64 @@ namespace hp
 
 
     /**
-     * Constructor. Initialize this
-     * object with the given
-     * parameters, and choose a
-     * @p MappingQ1 object for the
-     * mapping object.
+     * Constructor. Initialize this object with the given parameters, and
+     * choose a @p MappingQ1 object for the mapping object.
      *
-     * The finite element
-     * collection parameter is
-     * actually ignored, but is in
-     * the signature of this
-     * function to make it
-     * compatible with the
-     * signature of the respective
-     * constructor of the usual
-     * FEValues object, with
-     * the respective parameter in
-     * that function also being the
-     * return value of the
-     * <tt>DoFHandler::get_fe()</tt>
-     * function.
+     * The finite element collection parameter is actually ignored, but is in
+     * the signature of this function to make it compatible with the signature
+     * of the respective constructor of the usual FEValues object, with the
+     * respective parameter in that function also being the return value of
+     * the <tt>DoFHandler::get_fe()</tt> function.
      */
     FEFaceValues (const hp::FECollection<dim,spacedim>  &fe_collection,
                   const hp::QCollection<dim-1> &q_collection,
                   const UpdateFlags             update_flags);
 
     /**
-     * Reinitialize the object for
-     * the given cell and face.
+     * Reinitialize the object for the given cell and face.
      *
-     * After the call, you can get
-     * an FEFaceValues object using the
-     * get_present_fe_values()
-     * function that corresponds to
-     * the present cell. For this
-     * FEFaceValues object, we use the
-     * additional arguments
-     * described below to determine
-     * which finite element,
-     * mapping, and quadrature
-     * formula to use. They are
-     * order in such a way that the
-     * arguments one may want to
-     * change most frequently come
-     * first. The rules for these
-     * arguments are as follows:
+     * After the call, you can get an FEFaceValues object using the
+     * get_present_fe_values() function that corresponds to the present
+     * cell. For this FEFaceValues object, we use the additional arguments
+     * described below to determine which finite element, mapping, and
+     * quadrature formula to use. They are order in such a way that the
+     * arguments one may want to change most frequently come first. The rules
+     * for these arguments are as follows:
      *
-     * If the @p fe_index argument
-     * to this function is left at
-     * its default value, then we
-     * use that finite element
-     * within the hp::FECollection
-     * passed to the constructor of
-     * this class with index given
-     * by
-     * <code>cell-@>active_fe_index()</code>. Consequently,
-     * the hp::FECollection
-     * argument given to this
-     * object should really be the
-     * same as that used in the
-     * construction of the
-     * hp::DofHandler associated
-     * with the present cell. On
-     * the other hand, if a value
-     * is given for this argument,
-     * it overrides the choice of
+     * If the @p fe_index argument to this function is left at its default
+     * value, then we use that finite element within the hp::FECollection
+     * passed to the constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>. Consequently, the
+     * hp::FECollection argument given to this object should really be the
+     * same as that used in the construction of the hp::DofHandler associated
+     * with the present cell. On the other hand, if a value is given for this
+     * argument, it overrides the choice of
      * <code>cell-@>active_fe_index()</code>.
      *
-     * If the @p q_index argument
-     * is left at its default
-     * value, then we use that
-     * quadrature formula within
-     * the hp::QCollection passed
-     * to the constructor of this
-     * class with index given by
-     * <code>cell-@>active_fe_index()</code>,
-     * i.e. the same index as that
-     * of the finite element. In
-     * this case, there should be a
-     * corresponding quadrature
-     * formula for each finite
-     * element in the
-     * hp::FECollection. As a
-     * special case, if the
-     * quadrature collection
-     * contains only a single
-     * element (a frequent case if
-     * one wants to use the same
-     * quadrature object for all
-     * finite elements in an hp
-     * discretization, even if that
-     * may not be the most
-     * efficient), then this single
-     * quadrature is used unless a
-     * different value for this
-     * argument is specified. On
-     * the other hand, if a value
-     * is given for this argument,
-     * it overrides the choice of
-     * <code>cell-@>active_fe_index()</code>
-     * or the choice for the single
+     * If the @p q_index argument is left at its default value, then we use
+     * that quadrature formula within the hp::QCollection passed to the
+     * constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>, i.e. the same index as that of
+     * the finite element. In this case, there should be a corresponding
+     * quadrature formula for each finite element in the hp::FECollection. As
+     * a special case, if the quadrature collection contains only a single
+     * element (a frequent case if one wants to use the same quadrature object
+     * for all finite elements in an hp discretization, even if that may not
+     * be the most efficient), then this single quadrature is used unless a
+     * different value for this argument is specified. On the other hand, if a
+     * value is given for this argument, it overrides the choice of
+     * <code>cell-@>active_fe_index()</code> or the choice for the single
      * quadrature.
      *
-     * If the @p mapping_index
-     * argument is left at its
-     * default value, then we use
-     * that mapping object within
-     * the hp::MappingCollection
-     * passed to the constructor of
-     * this class with index given
-     * by
-     * <code>cell-@>active_fe_index()</code>,
-     * i.e. the same index as that
-     * of the finite
-     * element. As above, if the
-     * mapping collection contains
-     * only a single element (a
-     * frequent case if one wants
-     * to use a MappingQ1 object
-     * for all finite elements in
-     * an hp discretization), then
-     * this single mapping is used
-     * unless a different value for
-     * this argument is specified.
+     * If the @p mapping_index argument is left at its default value, then we
+     * use that mapping object within the hp::MappingCollection passed to the
+     * constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>, i.e. the same index as that of
+     * the finite element. As above, if the mapping collection contains only a
+     * single element (a frequent case if one wants to use a MappingQ1 object
+     * for all finite elements in an hp discretization), then this single
+     * mapping is used unless a different value for this argument is
+     * specified.
      */
     template <class DH, bool lda>
     void
@@ -645,33 +435,17 @@ namespace hp
             const unsigned int fe_index = numbers::invalid_unsigned_int);
 
     /**
-     * Like the previous function,
-     * but for non-hp
-     * iterators. The reason this
-     * (and the other non-hp
-     * iterator) function exists is
-     * so that one can use
-     * hp::FEValues not only for
-     * hp::DoFhandler objects, but
-     * for all sorts of DoFHandler
-     * objects, and triangulations
-     * not associated with
-     * DoFHandlers in general.
+     * Like the previous function, but for non-hp iterators. The reason this
+     * (and the other non-hp iterator) function exists is so that one can use
+     * hp::FEValues not only for hp::DoFhandler objects, but for all sorts of
+     * DoFHandler objects, and triangulations not associated with DoFHandlers
+     * in general.
      *
-     * Since
-     * <code>cell-@>active_fe_index()</code>
-     * doesn't make sense for
-     * triangulation iterators,
-     * this function chooses the
-     * zero-th finite element,
-     * mapping, and quadrature
-     * object from the relevant
-     * constructions passed to the
-     * constructor of this
-     * object. The only exception
-     * is if you specify a value
-     * different from the default
-     * value for any of these last
+     * Since <code>cell-@>active_fe_index()</code> doesn't make sense for
+     * triangulation iterators, this function chooses the zero-th finite
+     * element, mapping, and quadrature object from the relevant constructions
+     * passed to the constructor of this object. The only exception is if you
+     * specify a value different from the default value for any of these last
      * three arguments.
      */
     void
@@ -696,24 +470,13 @@ namespace hp
   {
   public:
     /**
-     * Constructor. Initialize this
-     * object with the given
-     * parameters.
+     * Constructor. Initialize this object with the given parameters.
      *
-     * The finite element
-     * collection parameter is
-     * actually ignored, but is in
-     * the signature of this
-     * function to make it
-     * compatible with the
-     * signature of the respective
-     * constructor of the usual
-     * FEValues object, with
-     * the respective parameter in
-     * that function also being the
-     * return value of the
-     * <tt>DoFHandler::get_fe()</tt>
-     * function.
+     * The finite element collection parameter is actually ignored, but is in
+     * the signature of this function to make it compatible with the signature
+     * of the respective constructor of the usual FEValues object, with the
+     * respective parameter in that function also being the return value of
+     * the <tt>DoFHandler::get_fe()</tt> function.
      */
     FESubfaceValues (const hp::MappingCollection<dim,spacedim> &mapping_collection,
                      const hp::FECollection<dim,spacedim>  &fe_collection,
@@ -722,108 +485,54 @@ namespace hp
 
 
     /**
-     * Constructor. Initialize this
-     * object with the given
-     * parameters, and choose a
-     * @p MappingQ1 object for the
-     * mapping object.
+     * Constructor. Initialize this object with the given parameters, and
+     * choose a @p MappingQ1 object for the mapping object.
      *
-     * The finite element
-     * collection parameter is
-     * actually ignored, but is in
-     * the signature of this
-     * function to make it
-     * compatible with the
-     * signature of the respective
-     * constructor of the usual
-     * FEValues object, with
-     * the respective parameter in
-     * that function also being the
-     * return value of the
-     * <tt>DoFHandler::get_fe()</tt>
-     * function.
+     * The finite element collection parameter is actually ignored, but is in
+     * the signature of this function to make it compatible with the signature
+     * of the respective constructor of the usual FEValues object, with the
+     * respective parameter in that function also being the return value of
+     * the <tt>DoFHandler::get_fe()</tt> function.
      */
     FESubfaceValues (const hp::FECollection<dim,spacedim> &fe_collection,
                      const hp::QCollection<dim-1>    &q_collection,
                      const UpdateFlags            update_flags);
 
     /**
-     * Reinitialize the object for
-     * the given cell, face, and subface.
+     * Reinitialize the object for the given cell, face, and subface.
      *
-     * After the call, you can get
-     * an FESubfaceValues object using the
-     * get_present_fe_values()
-     * function that corresponds to
-     * the present cell. For this
-     * FESubfaceValues object, we use the
-     * additional arguments
-     * described below to determine
-     * which finite element,
-     * mapping, and quadrature
-     * formula to use. They are
-     * order in such a way that the
-     * arguments one may want to
-     * change most frequently come
-     * first. The rules for these
-     * arguments are as follows:
+     * After the call, you can get an FESubfaceValues object using the
+     * get_present_fe_values() function that corresponds to the present
+     * cell. For this FESubfaceValues object, we use the additional arguments
+     * described below to determine which finite element, mapping, and
+     * quadrature formula to use. They are order in such a way that the
+     * arguments one may want to change most frequently come first. The rules
+     * for these arguments are as follows:
      *
-     * If the @p q_index argument
-     * is left at its default
-     * value, then we use that
-     * quadrature formula within
-     * the hp::QCollection passed
-     * to the constructor of this
-     * class with index given by
-     * <code>cell-@>active_fe_index()</code>,
-     * i.e. the same index as that
-     * of the finite element. In
-     * this case, there should be a
-     * corresponding quadrature
-     * formula for each finite
-     * element in the
-     * hp::FECollection. As a
-     * special case, if the
-     * quadrature collection
-     * contains only a single
-     * element (a frequent case if
-     * one wants to use the same
-     * quadrature object for all
-     * finite elements in an hp
-     * discretization, even if that
-     * may not be the most
-     * efficient), then this single
-     * quadrature is used unless a
-     * different value for this
-     * argument is specified. On
-     * the other hand, if a value
-     * is given for this argument,
-     * it overrides the choice of
-     * <code>cell-@>active_fe_index()</code>
-     * or the choice for the single
+     * If the @p q_index argument is left at its default value, then we use
+     * that quadrature formula within the hp::QCollection passed to the
+     * constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>, i.e. the same index as that of
+     * the finite element. In this case, there should be a corresponding
+     * quadrature formula for each finite element in the hp::FECollection. As
+     * a special case, if the quadrature collection contains only a single
+     * element (a frequent case if one wants to use the same quadrature object
+     * for all finite elements in an hp discretization, even if that may not
+     * be the most efficient), then this single quadrature is used unless a
+     * different value for this argument is specified. On the other hand, if a
+     * value is given for this argument, it overrides the choice of
+     * <code>cell-@>active_fe_index()</code> or the choice for the single
      * quadrature.
      *
-     * If the @p mapping_index
-     * argument is left at its
-     * default value, then we use
-     * that mapping object within
-     * the hp::MappingCollection
-     * passed to the constructor of
-     * this class with index given
-     * by
-     * <code>cell-@>active_fe_index()</code>,
-     * i.e. the same index as that
-     * of the finite
-     * element. As above, if the
-     * mapping collection contains
-     * only a single element (a
-     * frequent case if one wants
-     * to use a MappingQ1 object
-     * for all finite elements in
-     * an hp discretization), then
-     * this single mapping is used
-     * unless a different value for
-     * this argument is specified.
+     * If the @p mapping_index argument is left at its default value, then we
+     * use that mapping object within the hp::MappingCollection passed to the
+     * constructor of this class with index given by
+     * <code>cell-@>active_fe_index()</code>, i.e. the same index as that of
+     * the finite element. As above, if the mapping collection contains only a
+     * single element (a frequent case if one wants to use a MappingQ1 object
+     * for all finite elements in an hp discretization), then this single
+     * mapping is used unless a different value for this argument is
+     * specified.
      */
     template <class DH, bool lda>
     void
@@ -835,33 +544,17 @@ namespace hp
             const unsigned int fe_index = numbers::invalid_unsigned_int);
 
     /**
-     * Like the previous function,
-     * but for non-hp
-     * iterators. The reason this
-     * (and the other non-hp
-     * iterator) function exists is
-     * so that one can use
-     * hp::FEValues not only for
-     * hp::DoFhandler objects, but
-     * for all sorts of DoFHandler
-     * objects, and triangulations
-     * not associated with
-     * DoFHandlers in general.
+     * Like the previous function, but for non-hp iterators. The reason this
+     * (and the other non-hp iterator) function exists is so that one can use
+     * hp::FEValues not only for hp::DoFhandler objects, but for all sorts of
+     * DoFHandler objects, and triangulations not associated with DoFHandlers
+     * in general.
      *
-     * Since
-     * <code>cell-@>active_fe_index()</code>
-     * doesn't make sense for
-     * triangulation iterators,
-     * this function chooses the
-     * zero-th finite element,
-     * mapping, and quadrature
-     * object from the relevant
-     * constructions passed to the
-     * constructor of this
-     * object. The only exception
-     * is if you specify a value
-     * different from the default
-     * value for any of these last
+     * Since <code>cell-@>active_fe_index()</code> doesn't make sense for
+     * triangulation iterators, this function chooses the zero-th finite
+     * element, mapping, and quadrature object from the relevant constructions
+     * passed to the constructor of this object. The only exception is if you
+     * specify a value different from the default value for any of these last
      * three arguments.
      */
     void
index 56d0067a63f3f2706498545e2bc486419ca6c0ee..df541b1ae8ac25147bbfdb36ea187084a7f36f07 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <deal.II/base/config.h>
 #include <deal.II/base/table.h>
+#include <deal.II/base/thread_management.h>
 #include <deal.II/base/utilities.h>
 #include <deal.II/base/smartpointer.h>
 #include <deal.II/base/memory_consumption.h>
@@ -412,6 +413,11 @@ public:
    */
   BlockMatrixBase ();
 
+  /**
+   * Destructor.
+   */
+  ~BlockMatrixBase ();
+
   /**
    * Copy the given matrix to this
    * one.  The operation throws an
@@ -936,7 +942,7 @@ public:
 
   /**
    * Return a reference to the underlying
-   * BlockIndices data of the rows.
+   * BlockIndices data of the columns.
    */
   const BlockIndices &get_column_indices () const;
 
@@ -1241,30 +1247,74 @@ protected:
 
 
 private:
-  /**
-   * Temporary vector for counting the
-   * elements written into the
-   * individual blocks when doing a
-   * collective add or set.
-   */
-  std::vector<size_type> counter_within_block;
 
   /**
-   * Temporary vector for column
-   * indices on each block when writing
-   * local to global data on each
-   * sparse matrix.
+   * A structure containing some fields used by the
+   * set() and add() functions that is used to pre-sort
+   * the input fields. Since one can reasonably expect
+   * to call set() and add() from multiple threads at once
+   * as long as the matrix indices that are touched are
+   * disjoint, these temporary data fields need to be
+   * guarded by a mutex; the structure therefore contains such
+   * a mutex as a member variable.
    */
-  std::vector<std::vector<size_type> > column_indices;
+  struct TemporaryData
+  {
+    /**
+     * Temporary vector for counting the
+     * elements written into the
+     * individual blocks when doing a
+     * collective add or set.
+     */
+    std::vector<size_type> counter_within_block;
+
+    /**
+     * Temporary vector for column
+     * indices on each block when writing
+     * local to global data on each
+     * sparse matrix.
+     */
+    std::vector<std::vector<size_type> > column_indices;
+
+    /**
+     * Temporary vector for storing the
+     * local values (they need to be
+     * reordered when writing local to
+     * global).
+     */
+    std::vector<std::vector<double> > column_values;
+
+    /**
+     * A mutex variable used to guard access to the member
+     * variables of this structure;
+     */
+    Threads::Mutex mutex;
+
+    /**
+     * Copy operator. This is needed because the default copy
+     * operator of this class is deleted (since Threads::Mutex is
+     * not copyable) and hence the default copy operator of the
+     * enclosing class is also deleted.
+     *
+     * The implementation here simply does nothing -- TemporaryData
+     * objects are just scratch objects that are resized at the
+     * beginning of their use, so there is no point actually copying
+     * anything.
+     */
+    TemporaryData & operator = (const TemporaryData &)
+    {
+      return *this;
+    }
+  };
 
   /**
-   * Temporary vector for storing the
-   * local values (they need to be
-   * reordered when writing local to
-   * global).
+   * A set of scratch arrays that can be used by the add()
+   * and set() functions that take pointers to data to
+   * pre-sort indices before use. Access from multiple threads
+   * is synchronized via the mutex variable that is part of the
+   * structure.
    */
-  std::vector<std::vector<double> > column_values;
-
+  TemporaryData temporary_data;
 
   /**
    * Make the iterator class a
@@ -1736,6 +1786,12 @@ inline
 BlockMatrixBase<MatrixType>::BlockMatrixBase ()
 {}
 
+template <typename MatrixType>
+inline
+BlockMatrixBase<MatrixType>::~BlockMatrixBase ()
+{
+  clear ();
+}
 
 
 template <class MatrixType>
@@ -1761,9 +1817,10 @@ BlockMatrixBase<MatrixType>::memory_consumption () const
     MemoryConsumption::memory_consumption(row_block_indices)+
     MemoryConsumption::memory_consumption(column_block_indices)+
     MemoryConsumption::memory_consumption(sub_objects)+
-    MemoryConsumption::memory_consumption(counter_within_block)+
-    MemoryConsumption::memory_consumption(column_indices)+
-    MemoryConsumption::memory_consumption(column_values);
+    MemoryConsumption::memory_consumption(temporary_data.counter_within_block)+
+    MemoryConsumption::memory_consumption(temporary_data.column_indices)+
+    MemoryConsumption::memory_consumption(temporary_data.column_values)+
+    sizeof(temporary_data.mutex);
 
   for (unsigned int r=0; r<n_block_rows(); ++r)
     for (unsigned int c=0; c<n_block_cols(); ++c)
@@ -1965,12 +2022,16 @@ BlockMatrixBase<MatrixType>::set (const size_type  row,
 {
   prepare_set_operation();
 
+  // lock access to the temporary data structure to
+  // allow multiple threads to call this function concurrently
+  Threads::Mutex::ScopedLock lock (temporary_data.mutex);
+
   // Resize scratch arrays
-  if (column_indices.size() < this->n_block_cols())
+  if (temporary_data.column_indices.size() < this->n_block_cols())
     {
-      column_indices.resize (this->n_block_cols());
-      column_values.resize (this->n_block_cols());
-      counter_within_block.resize (this->n_block_cols());
+      temporary_data.column_indices.resize (this->n_block_cols());
+      temporary_data.column_values.resize (this->n_block_cols());
+      temporary_data.counter_within_block.resize (this->n_block_cols());
     }
 
   // Resize sub-arrays to n_cols. This
@@ -1983,19 +2044,19 @@ BlockMatrixBase<MatrixType>::set (const size_type  row,
   // whether the size of one is large
   // enough before actually going
   // through all of them.
-  if (column_indices[0].size() < n_cols)
+  if (temporary_data.column_indices[0].size() < n_cols)
     {
       for (unsigned int i=0; i<this->n_block_cols(); ++i)
         {
-          column_indices[i].resize(n_cols);
-          column_values[i].resize(n_cols);
+          temporary_data.column_indices[i].resize(n_cols);
+          temporary_data.column_values[i].resize(n_cols);
         }
     }
 
   // Reset the number of added elements
   // in each block to zero.
   for (unsigned int i=0; i<this->n_block_cols(); ++i)
-    counter_within_block[i] = 0;
+    temporary_data.counter_within_block[i] = 0;
 
   // Go through the column indices to
   // find out which portions of the
@@ -2016,10 +2077,10 @@ BlockMatrixBase<MatrixType>::set (const size_type  row,
       const std::pair<unsigned int, size_type>
       col_index = this->column_block_indices.global_to_local(col_indices[j]);
 
-      const size_type local_index = counter_within_block[col_index.first]++;
+      const size_type local_index = temporary_data.counter_within_block[col_index.first]++;
 
-      column_indices[col_index.first][local_index] = col_index.second;
-      column_values[col_index.first][local_index] = value;
+      temporary_data.column_indices[col_index.first][local_index] = col_index.second;
+      temporary_data.column_values[col_index.first][local_index] = value;
     }
 
 #ifdef DEBUG
@@ -2027,7 +2088,7 @@ BlockMatrixBase<MatrixType>::set (const size_type  row,
   // the right length has been obtained.
   size_type length = 0;
   for (unsigned int i=0; i<this->n_block_cols(); ++i)
-    length += counter_within_block[i];
+    length += temporary_data.counter_within_block[i];
   Assert (length <= n_cols, ExcInternalError());
 #endif
 
@@ -2040,14 +2101,14 @@ BlockMatrixBase<MatrixType>::set (const size_type  row,
   row_index = this->row_block_indices.global_to_local (row);
   for (unsigned int block_col=0; block_col<n_block_cols(); ++block_col)
     {
-      if (counter_within_block[block_col] == 0)
+      if (temporary_data.counter_within_block[block_col] == 0)
         continue;
 
       block(row_index.first, block_col).set
       (row_index.second,
-       counter_within_block[block_col],
-       &column_indices[block_col][0],
-       &column_values[block_col][0],
+       temporary_data.counter_within_block[block_col],
+       &temporary_data.column_indices[block_col][0],
+       &temporary_data.column_values[block_col][0],
        false);
     }
 }
@@ -2210,12 +2271,14 @@ BlockMatrixBase<MatrixType>::add (const size_type  row,
       return;
     }
 
-  // Resize scratch arrays
-  if (column_indices.size() < this->n_block_cols())
+  // Lock scratch arrays, then resize them
+  Threads::Mutex::ScopedLock lock (temporary_data.mutex);
+
+  if (temporary_data.column_indices.size() < this->n_block_cols())
     {
-      column_indices.resize (this->n_block_cols());
-      column_values.resize (this->n_block_cols());
-      counter_within_block.resize (this->n_block_cols());
+      temporary_data.column_indices.resize (this->n_block_cols());
+      temporary_data.column_values.resize (this->n_block_cols());
+      temporary_data.counter_within_block.resize (this->n_block_cols());
     }
 
   // Resize sub-arrays to n_cols. This
@@ -2228,19 +2291,19 @@ BlockMatrixBase<MatrixType>::add (const size_type  row,
   // whether the size of one is large
   // enough before actually going
   // through all of them.
-  if (column_indices[0].size() < n_cols)
+  if (temporary_data.column_indices[0].size() < n_cols)
     {
       for (unsigned int i=0; i<this->n_block_cols(); ++i)
         {
-          column_indices[i].resize(n_cols);
-          column_values[i].resize(n_cols);
+          temporary_data.column_indices[i].resize(n_cols);
+          temporary_data.column_values[i].resize(n_cols);
         }
     }
 
   // Reset the number of added elements
   // in each block to zero.
   for (unsigned int i=0; i<this->n_block_cols(); ++i)
-    counter_within_block[i] = 0;
+    temporary_data.counter_within_block[i] = 0;
 
   // Go through the column indices to
   // find out which portions of the
@@ -2261,10 +2324,10 @@ BlockMatrixBase<MatrixType>::add (const size_type  row,
       const std::pair<unsigned int, size_type>
       col_index = this->column_block_indices.global_to_local(col_indices[j]);
 
-      const size_type local_index = counter_within_block[col_index.first]++;
+      const size_type local_index = temporary_data.counter_within_block[col_index.first]++;
 
-      column_indices[col_index.first][local_index] = col_index.second;
-      column_values[col_index.first][local_index] = value;
+      temporary_data.column_indices[col_index.first][local_index] = col_index.second;
+      temporary_data.column_values[col_index.first][local_index] = value;
     }
 
 #ifdef DEBUG
@@ -2272,7 +2335,7 @@ BlockMatrixBase<MatrixType>::add (const size_type  row,
   // the right length has been obtained.
   size_type length = 0;
   for (unsigned int i=0; i<this->n_block_cols(); ++i)
-    length += counter_within_block[i];
+    length += temporary_data.counter_within_block[i];
   Assert (length <= n_cols, ExcInternalError());
 #endif
 
@@ -2285,14 +2348,14 @@ BlockMatrixBase<MatrixType>::add (const size_type  row,
   row_index = this->row_block_indices.global_to_local (row);
   for (unsigned int block_col=0; block_col<n_block_cols(); ++block_col)
     {
-      if (counter_within_block[block_col] == 0)
+      if (temporary_data.counter_within_block[block_col] == 0)
         continue;
 
       block(row_index.first, block_col).add
       (row_index.second,
-       counter_within_block[block_col],
-       &column_indices[block_col][0],
-       &column_values[block_col][0],
+       temporary_data.counter_within_block[block_col],
+       &temporary_data.column_indices[block_col][0],
+       &temporary_data.column_values[block_col][0],
        false,
        col_indices_are_sorted);
     }
index 8237b943d99b9719bc86d7667d1fdf9c74dd1b76..6c623eef0ed0c17af3261de671b0a037c138f765 100644 (file)
@@ -548,6 +548,15 @@ public:
    */
   bool is_identity_constrained (const size_type index) const;
 
+  /**
+   * Return whether the two given degrees of freedom are linked by an
+   * equality constraint that either constrains index1 to be so that
+   * <code>index1=index2</code> or constrains index2 so that
+   * <code>index2=index1</code>.
+   */
+  bool are_identity_constrained (const size_type index1,
+                                     const size_type index2) const;
+
   /**
    * Return the maximum number of other
    * dofs that one dof is constrained
index 7d52ee379216f3843d6a890e18fb82b3cb4f548d..f55e61d5cc737bceb01d13d21e648bbfcee2742c 100644 (file)
@@ -313,6 +313,11 @@ namespace PETScWrappers
        */
       void reinit (const unsigned int num_blocks);
 
+      /**
+       * Returns if this vector is a ghosted vector (and thus read-only).
+       */
+      bool has_ghost_elements() const;
+
       /**
        * Return a reference to the MPI
        * communicator object in use with
@@ -436,17 +441,25 @@ namespace PETScWrappers
       return *this;
     }
 
-
-
     inline
     BlockVector &
     BlockVector::operator = (const BlockVector &v)
     {
-      BaseClass::operator = (v);
-      return *this;
-    }
+      // we only allow assignment to vectors with the same number of blocks
+      // or to an empty BlockVector
+      Assert (n_blocks() == 0 || n_blocks() == v.n_blocks(),
+          ExcDimensionMismatch(n_blocks(), v.n_blocks()));
+
+      if (this->n_blocks() != v.n_blocks())
+        reinit(v.n_blocks());
 
+      for (size_type i=0; i<this->n_blocks(); ++i)
+        this->components[i] = v.block(i);
 
+      collect_sizes();
+
+      return *this;
+    }
 
     inline
     BlockVector::~BlockVector ()
@@ -543,6 +556,17 @@ namespace PETScWrappers
       return block(0).get_mpi_communicator();
     }
 
+    inline
+    bool
+    BlockVector::has_ghost_elements() const
+    {
+      bool ghosted=block(0).has_ghost_elements();
+#ifdef DEBUG
+      for (unsigned int i=0; i<this->n_blocks(); ++i)
+        Assert(block(i).has_ghost_elements()==ghosted, ExcInternalError());
+#endif
+      return ghosted;
+    }
 
 
     inline
index 6bfa4df7dd3e8df3dc77bace4b5c1043d90ef185..115bb94bfce1522b00ca72461db933188eb16e06 100644 (file)
@@ -158,6 +158,11 @@ namespace PETScWrappers
        */
       SparseMatrix ();
 
+      /**
+       * Destructor to free the PETSc object.
+       */
+      ~SparseMatrix ();
+
       /**
        * Create a sparse matrix of
        * dimensions @p m times @p n, with
index 95cdddc2145cdd955649f50d3c831b1b7932c940..bc3ee07627c093a25ead661bcce5079a2f395327 100644 (file)
@@ -588,10 +588,38 @@ namespace PETScWrappers
     Vector &
     Vector::operator = (const Vector &v)
     {
+      if (v.size()==0)
+        {
+          // this happens if v has not been initialized to something useful:
+          // Vector x,v;x=v;
+          // we skip the code below and create a simple serial vector of
+          // length 0
+
+          int ierr;
+#if DEAL_II_PETSC_VERSION_LT(3,2,0)
+          ierr = VecDestroy (vector);
+#else
+          ierr = VecDestroy (&vector);
+#endif
+          AssertThrow (ierr == 0, ExcPETScError(ierr));
+
+          const int n = 0;
+          ierr = VecCreateSeq (PETSC_COMM_SELF, n, &vector);
+          AssertThrow (ierr == 0, ExcPETScError(ierr));
+          ghosted = false;
+          ghost_indices.clear();
+          return *this;
+        }
+
       // if the vectors have different sizes,
       // then first resize the present one
       if (size() != v.size())
-        reinit (v.communicator, v.size(), v.local_size(), true);
+        {
+          if (v.has_ghost_elements())
+            reinit( v.locally_owned_elements(), v.ghost_indices, v.communicator);
+          else
+            reinit (v.communicator, v.size(), v.local_size(), true);
+        }
 
       const int ierr = VecCopy (v.vector, vector);
       AssertThrow (ierr == 0, ExcPETScError(ierr));
index b5135d7403593c1c317807cb2c69932c51c9cd16..509297a5742a2c54add04acacfa850c47d7c504e 100644 (file)
@@ -297,7 +297,7 @@ namespace SLEPcWrappers
     EPS *get_eps ();
 
     /**
-     * Solve the linear system for </code>n_eigenpairs</code>
+     * Solve the linear system for <code>n_eigenpairs</code>
      * eigenstates. Parameter <code>n_converged</code> contains the
      * actual number of eigenstates that have .  converged; this can
      * be both fewer or more than n_eigenpairs, depending on the
index b327e5b9ab8fa70b52b51b80eb7ae9700153219f..ada6bbf528afb5021496fed09a18f8066f155d35 100644 (file)
@@ -1147,7 +1147,7 @@ public:
   /**
    * Write the data of this object en bloc to a file. This is done in a binary
    * mode, so the output is neither readable by humans nor (probably) by other
-   * computers using a different operating system of number format.
+   * computers using a different operating system or number format.
    *
    * The purpose of this function is that you can swap out matrices and
    * sparsity pattern if you are short of memory, want to communicate between
index 46b7d07308947b61d37cc22fff82f455c51c18ce..860eedfae76cdd2f3f9611c5e521e733902ddf63 100644 (file)
@@ -236,7 +236,9 @@ namespace SparsityTools
    * range of elements stored locally
    * and should be the one used in
    * the constructor of the
-   * CompressedSimpleSparsityPattern. Only
+   * CompressedSimpleSparsityPattern.
+   * This should be the locally relevant set.
+   * Only
    * rows contained in myrange are
    * checked in csp for transfer.
    * This function needs to be used
@@ -250,6 +252,19 @@ namespace SparsityTools
                                    const std::vector<size_type> &rows_per_cpu,
                                    const MPI_Comm &mpi_comm,
                                    const IndexSet &myrange);
+
+  /**
+   * similar to the function above, but includes support for
+   * BlockCompressedSimpleSparsityPattern.
+   * @p owned_set_per_cpu is typically DoFHandler::locally_owned_dofs_per_processor 
+   * and @p myrange are locally_relevant_dofs.
+   */
+  template <class CSP_t>
+  void distribute_sparsity_pattern(CSP_t &csp,
+                                   const std::vector<IndexSet> &owned_set_per_cpu,
+                                   const MPI_Comm &mpi_comm,
+                                   const IndexSet &myrange);
+
 #endif
 
 
index f35166b1c376716bd278bc234188a9f1739d03b2..d684216bdcd798d931f5822a30a37b7ef5292f73 100644 (file)
@@ -127,6 +127,16 @@ namespace TrilinosWrappers
       explicit BlockVector (const std::vector<IndexSet> &parallel_partitioning,
                             const MPI_Comm              &communicator = MPI_COMM_WORLD);
 
+      /**
+       * Creates a BlockVector with ghost elements. @p ghost_values
+       * may contain any elements in @p parallel_partitioning, they will
+       * be ignored.
+       */
+      BlockVector (const std::vector<IndexSet> &parallel_partitioning,
+          const std::vector<IndexSet> &ghost_values,
+          const MPI_Comm              &communicator);
+
+
       /**
        * Copy-Constructor. Set all the
        * properties of the parallel vector
@@ -353,6 +363,11 @@ namespace TrilinosWrappers
        */
       bool is_compressed () const;
 
+      /**
+       * Returns if this Vector contains ghost elements.
+       */
+      bool has_ghost_elements() const;
+
       /**
        * Swap the contents of this
        * vector and the other vector
@@ -431,6 +446,14 @@ namespace TrilinosWrappers
     }
 
 
+    inline
+    BlockVector::BlockVector (const std::vector<IndexSet> &parallel_partitioning,
+        const std::vector<IndexSet> &ghost_values,
+        const MPI_Comm              &communicator)
+    {
+      reinit(parallel_partitioning, ghost_values, communicator);
+    }
+
 
     inline
     BlockVector::BlockVector (const size_type num_blocks)
@@ -510,6 +533,18 @@ namespace TrilinosWrappers
     }
 
 
+    inline
+    bool
+    BlockVector::has_ghost_elements() const
+    {
+      bool ghosted=block(0).has_ghost_elements();
+#ifdef DEBUG
+      for (unsigned int i=0; i<this->n_blocks(); ++i)
+        Assert(block(i).has_ghost_elements()==ghosted, ExcInternalError());
+#endif
+      return ghosted;
+    }
+
     inline
     void
     BlockVector::swap (BlockVector &v)
index 34a6017f4f17b97e648d89b84b15e11a1bfdddd8..3936118d50082ba63ed9326329249e2159f5df69 100644 (file)
@@ -121,13 +121,13 @@ namespace TrilinosWrappers
     /**
      * Apply the preconditioner.
      */
-    void vmult (VectorBase       &dst,
-                const VectorBase &src) const;
+    virtual void vmult (VectorBase       &dst,
+                        const VectorBase &src) const;
 
     /**
      * Apply the transpose preconditioner.
      */
-    void Tvmult (VectorBase       &dst,
+    virtual void Tvmult (VectorBase       &dst,
                  const VectorBase &src) const;
 
     /**
@@ -137,8 +137,8 @@ namespace TrilinosWrappers
      * in the Trilinos wrapper
      * class.
      */
-    void vmult (dealii::Vector<double>       &dst,
-                const dealii::Vector<double> &src) const;
+    virtual void vmult (dealii::Vector<double>       &dst,
+                        const dealii::Vector<double> &src) const;
 
     /**
      * Apply the transpose preconditioner on
@@ -147,8 +147,8 @@ namespace TrilinosWrappers
      * in the Trilinos wrapper
      * class.
      */
-    void Tvmult (dealii::Vector<double>       &dst,
-                 const dealii::Vector<double> &src) const;
+    virtual void Tvmult (dealii::Vector<double>       &dst,
+                         const dealii::Vector<double> &src) const;
 
     /**
      * Apply the preconditioner on deal.II
@@ -156,8 +156,8 @@ namespace TrilinosWrappers
      * the ones provided in the Trilinos
      * wrapper class.
      */
-    void vmult (dealii::parallel::distributed::Vector<double>       &dst,
-                const dealii::parallel::distributed::Vector<double> &src) const;
+    virtual void vmult (dealii::parallel::distributed::Vector<double>       &dst,
+                        const dealii::parallel::distributed::Vector<double> &src) const;
 
     /**
      * Apply the transpose preconditioner on deal.II
@@ -165,8 +165,8 @@ namespace TrilinosWrappers
      * the ones provided in the Trilinos
      * wrapper class.
      */
-    void Tvmult (dealii::parallel::distributed::Vector<double>       &dst,
-                 const dealii::parallel::distributed::Vector<double> &src) const;
+    virtual void Tvmult (dealii::parallel::distributed::Vector<double>       &dst,
+                         const dealii::parallel::distributed::Vector<double> &src) const;
 
     /**
      * Exception.
@@ -1508,6 +1508,64 @@ namespace TrilinosWrappers
 
 
 
+  /**
+   * A wrapper class for an identity preconditioner for Trilinos matrices.
+   *
+   * @ingroup TrilinosWrappers
+   * @ingroup Preconditioners
+   * @author Bruno Turcksin, 2013
+   */
+  class PreconditionIdentity : public PreconditionBase
+  {
+  public:
+
+    /**
+     * Apply the preconditioner, i.e., dst = src.
+     */
+    void vmult (VectorBase       &dst,
+                const VectorBase &src) const;
+
+    /**
+     * Apply the transport conditioner, i.e., dst = src.
+     */
+    void Tvmult (VectorBase       &dst,
+                 const VectorBase &src) const;
+
+    /**
+     * Apply the preconditioner on deal.II data structures 
+     * instead of the ones provided in the Trilinos wrapper class, 
+     * i.e., dst = src.
+     */
+    void vmult (dealii::Vector<double>       &dst,
+                const dealii::Vector<double> &src) const;
+
+    /**
+     * Apply the transpose preconditioner on deal.II data structures 
+     * instead of the ones provided in the Trilinos wrapper class,
+     * i.e. dst = src.
+     */
+    void Tvmult (dealii::Vector<double>       &dst,
+                 const dealii::Vector<double> &src) const;
+
+    /**
+     * Apply the preconditioner on deal.II parallel data structures 
+     * instead of the ones provided in the Trilinos wrapper class,
+     * i.e., dst = src.
+     */
+    void vmult (parallel::distributed::Vector<double>       &dst,
+                const dealii::parallel::distributed::Vector<double> &src) const;
+
+    /**
+     * Apply the transpose preconditioner on deal.II parallel data structures 
+     * instead of the ones provided in the Trilinos wrapper class,
+     * i.e., dst = src.
+     */
+    void Tvmult (parallel::distributed::Vector<double>       &dst,
+                 const dealii::parallel::distributed::Vector<double> &src) const;
+  };
+
+
+
 // -------------------------- inline and template functions ----------------------
 
 
index 16c53c268d5b8b3493aa8c1afbe5c0ce794c5ba8..8ab56dcc92974e3c823509b3534a81ad53c8baf2 100644 (file)
@@ -1020,12 +1020,12 @@ no_constraint:
                k++)
             {
               unsigned int cell = partition_list[k];
-              unsigned int no_neighbors = connectivity.row_length(cell);
+              unsigned int n_neighbors = connectivity.row_length(cell);
 
               // In the worst case, each neighbor has a different color. So we
-              // find at least one available color between 0 and no_neighbors.
-              color_finder.resize(no_neighbors+1);
-              for (unsigned int j=0; j<=no_neighbors; ++j)
+              // find at least one available color between 0 and n_neighbors.
+              color_finder.resize(n_neighbors+1);
+              for (unsigned int j=0; j<=n_neighbors; ++j)
                 color_finder[j]=true;
               CompressedSimpleSparsityPattern::row_iterator
               neighbor = connectivity.row_begin(cell),
@@ -1035,7 +1035,7 @@ no_constraint:
                   // Mark the color that a neighbor within the partition has
                   // as taken
                   if (cell_partition[*neighbor] == part &&
-                      cell_color[*neighbor] <= no_neighbors)
+                      cell_color[*neighbor] <= n_neighbors)
                     color_finder[cell_color[*neighbor]] = false;
                 }
               // Choose the smallest color that is not taken for the block
index 40259aa4dd96a71da81df7a41fdbae85dc1b7804..305c82853246c9ed47dbd7e099315dd3392977c5 100644 (file)
 
 #include <deal.II/base/config.h>
 
+#include <deal.II/base/std_cxx1x/shared_ptr.h>
 #include <deal.II/lac/block_vector.h>
 #include <deal.II/lac/constraint_matrix.h>
 #include <deal.II/lac/sparsity_pattern.h>
 #include <deal.II/lac/block_sparsity_pattern.h>
 #include <deal.II/lac/vector_memory.h>
 
-#include <deal.II/multigrid/mg_base.h>
-#include <deal.II/fe/component_mask.h>
 #include <deal.II/base/mg_level_object.h>
-
-
-
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/fe/component_mask.h>
+#include <deal.II/multigrid/mg_base.h>
 
-#include <deal.II/base/std_cxx1x/shared_ptr.h>
 
 
 DEAL_II_NAMESPACE_OPEN
index 461a93fb56708f5160938c51c0ffd995bb77db75..0ef5bfdf4d5a8d0476157c17fce1ec95ea206652 100644 (file)
@@ -22,7 +22,6 @@
 #include <deal.II/base/subscriptor.h>
 #include <deal.II/base/smartpointer.h>
 #include <deal.II/dofs/dof_handler.h>
-#include <deal.II/numerics/data_out.h>
 #include <deal.II/lac/sparse_matrix.h>
 #include <deal.II/lac/vector.h>
 #include <deal.II/multigrid/mg_base.h>
index bb2d8f01f16b5c21018476656cf8eecfc35b5672..26cf9b1a5300e95ffdc3c6db59e3b442657016bb 100644 (file)
@@ -23,6 +23,7 @@
 #include <deal.II/base/smartpointer.h>
 #include <deal.II/base/data_out_base.h>
 #include <deal.II/dofs/dof_handler.h>
+#include <deal.II/grid/tria.h>
 #include <deal.II/fe/mapping.h>
 #include <deal.II/hp/q_collection.h>
 #include <deal.II/hp/fe_collection.h>
@@ -42,24 +43,15 @@ namespace internal
   namespace DataOut
   {
     /**
-     * For each vector that has been added
-     * through the add_data_vector()
-     * functions, we need to keep track of a
-     * pointer to it, and allow data
-     * extraction from it when we generate
-     * patches. Unfortunately, we need to do
-     * this for a number of different vector
-     * types. Fortunately, they all have the
-     * same interface. So the way we go is to
-     * have a base class that provides the
-     * functions to access the vector's
-     * information, and to have a derived
-     * template class that can be
-     * instantiated for each vector
-     * type. Since the vectors all have the
-     * same interface, this is no big
-     * problem, as they can all use the same
-     * general templatized code.
+     * For each vector that has been added through the add_data_vector()
+     * functions, we need to keep track of a pointer to it, and allow data
+     * extraction from it when we generate patches. Unfortunately, we need to
+     * do this for a number of different vector types. Fortunately, they all
+     * have the same interface. So the way we go is to have a base class that
+     * provides the functions to access the vector's information, and to have
+     * a derived template class that can be instantiated for each vector
+     * type. Since the vectors all have the same interface, this is no big
+     * problem, as they can all use the same general templatized code.
      *
      * @author Wolfgang Bangerth, 2004
      */
@@ -68,25 +60,21 @@ namespace internal
     {
     public:
       /**
-       * Constructor. Give a list of names
-       * for the individual components of
-       * the vector and their
-       * interpretation as scalar or vector
-       * data. This constructor assumes
-       * that no postprocessor is going to
-       * be used.
+       * Constructor. Give a list of names for the individual components of
+       * the vector and their interpretation as scalar or vector data. This
+       * constructor assumes that no postprocessor is going to be used.
        */
-      DataEntryBase (const std::vector<std::string> &names,
+      DataEntryBase (const DH                       *dofs,
+                     const std::vector<std::string> &names,
                      const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
 
       /**
-       * Constructor when a data
-       * postprocessor is going to be
-       * used. In that case, the names and
-       * vector declarations are going to
-       * be acquired from the postprocessor.
+       * Constructor when a data postprocessor is going to be used. In that
+       * case, the names and vector declarations are going to be acquired from
+       * the postprocessor.
        */
-      DataEntryBase (const DataPostprocessor<DH::space_dimension> *data_postprocessor);
+      DataEntryBase (const DH                       *dofs,
+                     const DataPostprocessor<DH::space_dimension> *data_postprocessor);
 
       /**
        * Destructor made virtual.
@@ -94,8 +82,7 @@ namespace internal
       virtual ~DataEntryBase ();
 
       /**
-       * Assuming that the stored vector is
-       * a cell vector, extract the given
+       * Assuming that the stored vector is a cell vector, extract the given
        * element from it.
        */
       virtual
@@ -103,10 +90,8 @@ namespace internal
       get_cell_data_value (const unsigned int cell_number) const = 0;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the values on the present
-       * cell from the vector we actually
-       * store.
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store.
        */
       virtual
       void
@@ -114,12 +99,9 @@ namespace internal
                            std::vector<double>             &patch_values) const = 0;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the values on the present
-       * cell from the vector we actually
-       * store. This function does the same
-       * as the one above but for
-       * vector-valued finite elements.
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store. This function does the same as the
+       * one above but for vector-valued finite elements.
        */
       virtual
       void
@@ -127,10 +109,8 @@ namespace internal
                            std::vector<dealii::Vector<double> >    &patch_values_system) const = 0;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the gradients on the present
-       * cell from the vector we actually
-       * store.
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store.
        */
       virtual
       void
@@ -138,12 +118,9 @@ namespace internal
                               std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const = 0;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the gradients on the present
-       * cell from the vector we actually
-       * store. This function does the same
-       * as the one above but for
-       * vector-valued finite elements.
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store. This function does the same
+       * as the one above but for vector-valued finite elements.
        */
       virtual
       void
@@ -151,10 +128,8 @@ namespace internal
                               std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const = 0;
 
       /**
-       * Given a FEValuesBase object, extract
-       * the second derivatives on the
-       * present cell from the vector we
-       * actually store.
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store.
        */
       virtual
       void
@@ -162,12 +137,9 @@ namespace internal
                              std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const = 0;
 
       /**
-       * Given a FEValuesBase object, extract
-       * the second derivatives on the
-       * present cell from the vector we
-       * actually store. This function does
-       * the same as the one above but for
-       * vector-valued finite elements.
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store. This function does
+       * the same as the one above but for vector-valued finite elements.
        */
       virtual
       void
@@ -175,100 +147,89 @@ namespace internal
                              std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const = 0;
 
       /**
-       * Clear all references to the
-       * vectors.
+       * Clear all references to the vectors.
        */
       virtual void clear () = 0;
 
       /**
-       * Determine an estimate for
-       * the memory consumption (in
-       * bytes) of this object.
+       * Determine an estimate for the memory consumption (in bytes) of this
+       * object.
        */
       virtual std::size_t memory_consumption () const = 0;
 
       /**
-       * Names of the components of this
-       * data vector.
+       * Pointer to the DoFHandler object that the vector is based on.
+       */
+      SmartPointer<const DH> dof_handler;
+
+      /**
+       * Names of the components of this data vector.
        */
       const std::vector<std::string> names;
 
       /**
-       * A vector that for each of the
-       * n_output_variables variables of
-       * the current data set indicates
-       * whether they are scalar fields,
-       * parts of a vector-field, or any of
-       * the other supported kinds of data.
+       * A vector that for each of the n_output_variables variables of the
+       * current data set indicates whether they are scalar fields, parts of a
+       * vector-field, or any of the other supported kinds of data.
        */
       const std::vector<DataComponentInterpretation::DataComponentInterpretation>
       data_component_interpretation;
 
       /**
-       * Pointer to a DataPostprocessing
-       * object which shall be applied to
-       * this data vector.
+       * Pointer to a DataPostprocessing object which shall be applied to this
+       * data vector.
        */
       SmartPointer<const dealii::DataPostprocessor<DH::space_dimension> > postprocessor;
 
       /**
-       * Number of output variables this
-       * dataset provides (either number of
-       * components in vector valued function
-       * / data vector or number of computed
-       * quantities, if DataPostprocessor is
-       * applied). This variable is
-       * determined via and thus equivalent
-       * to <tt>names.size()</tt>.
+       * Number of output variables this dataset provides (either number of
+       * components in vector valued function / data vector or number of
+       * computed quantities, if DataPostprocessor is applied). This variable
+       * is determined via and thus equivalent to <tt>names.size()</tt>.
        */
       unsigned int n_output_variables;
     };
 
 
     /**
-     * A data structure that holds
-     * all data needed in one thread
-     * when building patches in
-     * parallel.  These data
-     * structures are created
-     * globally rather than on each
-     * cell to avoid allocation of
-     * memory in the threads. This is
-     * a base class for the
-     * AdditionalData kind of data
-     * structure discussed in the
-     * documentation of the
-     * WorkStream class.
+     * A data structure that holds all data needed in one thread when building
+     * patches in parallel. These data structures are created globally rather
+     * than on each cell to avoid allocation of memory in the threads. This is
+     * a base class for the AdditionalData kind of data structure discussed in
+     * the documentation of the WorkStream class.
      *
-     * The
-     * <code>cell_to_patch_index_map</code>
-     * is an array that stores for index
-     * <tt>[i][j]</tt> the number of the
-     * patch that associated with the cell
-     * with index @p j on level @p i. This
-     * information is set up prior to
-     * generation of the patches, and is
-     * needed to generate neighborship
+     * The <code>cell_to_patch_index_map</code> is an array that stores for
+     * index <tt>[i][j]</tt> the number of the patch that associated with the
+     * cell with index @p j on level @p i. This information is set up prior to
+     * generation of the patches, and is needed to generate neighborship
      * information.
      *
-     * This structure is used by
-     * several of the DataOut*
-     * classes, which derived their
-     * own ParallelData classes from
-     * it for additional fields.
+     * This structure is used by several of the DataOut* classes, which
+     * derived their own ParallelData classes from it for additional fields.
      */
     template <int dim, int spacedim>
     struct ParallelDataBase
     {
-      template <class FE>
-      ParallelDataBase (const unsigned int n_components,
-                        const unsigned int n_datasets,
+      ParallelDataBase (const unsigned int n_datasets,
                         const unsigned int n_subdivisions,
-                        const unsigned int n_q_points,
                         const std::vector<unsigned int> &n_postprocessor_outputs,
-                        const FE &finite_elements);
+                        const Mapping<dim,spacedim> &mapping,
+                        const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
+                        const UpdateFlags update_flags,
+                        const bool        use_face_values);
+
+      ParallelDataBase (const ParallelDataBase &data);
+
+      template <typename DH>
+      void reinit_all_fe_values(std::vector<std_cxx1x::shared_ptr<DataEntryBase<DH> > > &dof_data,
+                                const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
+                                const unsigned int face = numbers::invalid_unsigned_int);
+
+      const FEValuesBase<dim,spacedim> &
+      get_present_fe_values(const unsigned int dataset) const;
+
+      void resize_system_vectors(const unsigned int n_components);
 
-      const unsigned int n_components;
       const unsigned int n_datasets;
       const unsigned int n_subdivisions;
 
@@ -280,36 +241,30 @@ namespace internal
       std::vector<std::vector<Tensor<2,spacedim> > >     patch_hessians_system;
       std::vector<std::vector<dealii::Vector<double> > > postprocessed_values;
 
-      const dealii::hp::FECollection<dim,spacedim>      fe_collection;
+      const dealii::hp::MappingCollection<dim,spacedim> mapping_collection;
+      const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > finite_elements;
+      const UpdateFlags update_flags;
+
+      std::vector<std_cxx1x::shared_ptr<dealii::hp::FEValues<dim,spacedim> > > x_fe_values;
+      std::vector<std_cxx1x::shared_ptr<dealii::hp::FEFaceValues<dim,spacedim> > > x_fe_face_values;
     };
 
 
     /**
-     * A derived class for use in the
-     * DataOut class. This is
-     * a class for the
-     * AdditionalData kind of data
-     * structure discussed in the
-     * documentation of the
-     * WorkStream context.
+     * A derived class for use in the DataOut class. This is a class for the
+     * AdditionalData kind of data structure discussed in the documentation of
+     * the WorkStream context.
      */
     template <int dim, int spacedim>
     struct ParallelData : public ParallelDataBase<dim,spacedim>
     {
-      template <class FE>
-      ParallelData (const Quadrature<dim> &quadrature,
-                    const unsigned int n_components,
-                    const unsigned int n_datasets,
+      ParallelData (const unsigned int n_datasets,
                     const unsigned int n_subdivisions,
                     const std::vector<unsigned int> &n_postprocessor_outputs,
                     const Mapping<dim,spacedim> &mapping,
-                    const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map,
-                    const FE &finite_elements,
-                    const UpdateFlags update_flags);
-
-      const dealii::hp::QCollection<dim> q_collection;
-      const dealii::hp::MappingCollection<dim,spacedim> mapping_collection;
-      dealii::hp::FEValues<dim,spacedim> x_fe_values;
+                    const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
+                    const UpdateFlags update_flags,
+                    const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map);
 
       std::vector<Point<spacedim> > patch_evaluation_points;
 
@@ -322,21 +277,24 @@ namespace internal
 //TODO: Most of the documentation of DataOut_DoFData applies to DataOut.
 
 /**
- * This is an abstract class which provides the functionality to
- * generate patches for output by base classes from data vectors on a
- * grid. It allows to store a pointer to a DoFHandler object and one
- * or more pointers to node and cell data denoting functions on the
- * grid which shall later be written in any of the implemented data
- * formats.
+ * This is an abstract class which provides the functionality to generate
+ * patches for output by base classes from data vectors on a grid. It allows
+ * to store one or more pointers to a DoFHandler and attached node and cell
+ * data denoting functions on the grid which shall later be written in any of
+ * the implemented data formats.
  *
  *
  * <h3>User visible interface</h3>
  *
- * The user visible interface of this class consists of functions which allow
- * a user to make a DoFHandler object known to this class and to add data
- * vectors which will later be written to a file in some format. Instead of
- * pondering about the different functions, an example is probably the best
- * way:
+ * The user visible interface of this class allows the user to specify data in
+ * two different ways. One is to make a DoFHandler object known to this class
+ * and to add data vectors that all correspond to this DoFHandler or the grid
+ * cells which will later be written to a file in some format. The second
+ * approach is to pass a DoFHandler object along with the vector. This allows
+ * setting data from different DoFHandlers in a neat way (of course, they both
+ * need to be based on the same triangulation). Instead of pondering about the
+ * different functions, an example for the first kind is probably the best
+ * explanation:
  * @code
  *   ...
  *   ...   // compute solution, which contains nodal values
@@ -399,7 +357,7 @@ namespace internal
  * function build_patches(). Finally, you write() the data in one format or other,
  * to a file.
  *
- * Please note, that in the example above, an object of type DataOut was
+ * Please note that in the example above, an object of type DataOut was
  * used, i.e. an object of a derived class. This is necessary since this
  * class does not provide means to actually generate the patches, only aids to
  * store and access data.
@@ -470,45 +428,31 @@ class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
 public:
 
   /**
-   * Typedef to the iterator type
-   * of the dof handler class under
+   * Typedef to the iterator type of the dof handler class under
    * consideration.
    */
-  typedef typename DH::cell_iterator cell_iterator;
-  typedef typename DH::active_cell_iterator active_cell_iterator;
+  typedef typename Triangulation<DH::dimension,DH::space_dimension>::cell_iterator cell_iterator;
+  typedef typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell_iterator;
 
 public:
 
   /**
-   * Type describing what the
-   * vector given to
-   * add_data_vector() is: a
-   * vector that has one entry per
-   * degree of freedom in a
-   * DoFHandler object (such
-   * as solution vectors), or one
-   * entry per cell in the
-   * triangulation underlying the
-   * DoFHandler object (such
-   * as error per cell data). The
-   * value #type_automatic tells
-   * add_data_vector() to find
-   * out itself (see the
-   * documentation of
-   * add_data_vector() for the
-   * method used).
+   * Type describing what the vector given to add_data_vector() is: a vector
+   * that has one entry per degree of freedom in a DoFHandler object (such as
+   * solution vectors), or one entry per cell in the triangulation underlying
+   * the DoFHandler object (such as error per cell data). The value
+   * #type_automatic tells add_data_vector() to find out itself (see the
+   * documentation of add_data_vector() for the method used).
    */
   enum DataVectorType
   {
     /**
-     * Data vector entries are
-     * associated to degrees of freedom
+     * Data vector entries are associated to degrees of freedom
      */
     type_dof_data,
 
     /**
-     * Data vector entries are one per
-     * grid cell
+     * Data vector entries are one per grid cell
      */
     type_cell_data,
 
@@ -529,140 +473,92 @@ public:
   virtual ~DataOut_DoFData ();
 
   /**
-   * Designate a dof handler to be
-   * used to extract geometry data
-   * and the mapping between nodes
-   * and node values.
+   * Designate a dof handler to be used to extract geometry data and the
+   * mapping between nodes and node values. This call is not necessary if all
+   * added data vectors are supplemented with a DoFHandler argument.
+   *
+   * This call is optional: If you add data vectors with specified DoFHandler
+   * object, then that contains all information needed to generate the output.
    */
   void attach_dof_handler (const DH &);
 
   /**
-   * Add a data vector together
-   * with its name.
+   * Designate a triangulation to be used to extract geometry data and the
+   * mapping between nodes and node values.
    *
-   * A pointer to the vector is
-   * stored, so you have to make
-   * sure the vector exists at that
-   * address at least as long as
-   * you call the <tt>write_*</tt>
+   * This call is optional: If you add data vectors with specified DoFHandler
+   * object, then that contains all information needed to generate the
+   * output. This call is useful when you only output cell vectors and no
+   * DoFHandler at all, in which case it provides the geometry.
+   */
+  void attach_triangulation (const Triangulation<DH::dimension,
+                             DH::space_dimension> &);
+
+  /**
+   * Add a data vector together with its name.
+   *
+   * A pointer to the vector is stored, so you have to make sure the vector
+   * exists at that address at least as long as you call the <tt>write_*</tt>
    * functions.
    *
-   * It is assumed that the vector
-   * has the same number of
-   * components as there are
-   * degrees of freedom in the dof
-   * handler, in which case it is
-   * assumed to be a vector storing
-   * nodal data; or the size may be
-   * the number of active cells on
-   * the present grid, in which
-   * case it is assumed to be a
-   * cell data vector. As the
-   * number of degrees of freedom
-   * and of cells is usually not
-   * equal, the function can
-   * determine itself which type of
-   * vector it is given. However,
-   * there are corner cases where
-   * this automatic determination
-   * does not work.  One example is
-   * if you compute with piecewise
-   * constant elements and have a
-   * scalar solution, then there
-   * are as many cells as there are
-   * degrees of freedom (though
-   * they may be numbered
-   * differently). Another
-   * possibility is if you have a
-   * 1d mesh embedded in 2d space
-   * and the mesh consists of a
-   * closed curve of cells; in this
-   * case, there are as many nodes
-   * as there are cells, and when
-   * using a Q1 element you will
-   * have as many degrees of
-   * freedom as there are cells.
-   * In these cases, you can change
-   * the last argument of the
-   * function from its default
-   * value #type_automatic to
-   * either #type_dof_data or
-   * #type_cell_data, depending on
-   * what the vector
-   * represents. Apart from such
-   * corner cases, you can leave
-   * the argument at its default
-   * value and let the function
-   * determine the type of the
-   * vector itself.
+   * It is assumed that the vector has the same number of components as there
+   * are degrees of freedom in the dof handler, in which case it is assumed to
+   * be a vector storing nodal data; or the size may be the number of active
+   * cells on the present grid, in which case it is assumed to be a cell data
+   * vector. As the number of degrees of freedom and of cells is usually not
+   * equal, the function can determine itself which type of vector it is
+   * given. However, there are corner cases where this automatic determination
+   * does not work.  One example is if you compute with piecewise constant
+   * elements and have a scalar solution, then there are as many cells as
+   * there are degrees of freedom (though they may be numbered
+   * differently). Another possibility is if you have a 1d mesh embedded in 2d
+   * space and the mesh consists of a closed curve of cells; in this case,
+   * there are as many nodes as there are cells, and when using a Q1 element
+   * you will have as many degrees of freedom as there are cells.  In these
+   * cases, you can change the last argument of the function from its default
+   * value #type_automatic to either #type_dof_data or #type_cell_data,
+   * depending on what the vector represents. Apart from such corner cases,
+   * you can leave the argument at its default value and let the function
+   * determine the type of the vector itself.
    *
-   * If it is a vector holding DoF
-   * data, the names given shall be
-   * one for each component of the
-   * underlying finite element.  If
-   * it is a finite element
-   * composed of only one
-   * subelement, then there is
-   * another function following
-   * which takes a single name
-   * instead of a vector of names.
+   * If it is a vector holding DoF data, the names given shall be one for each
+   * component of the underlying finite element.  If it is a finite element
+   * composed of only one subelement, then there is another function following
+   * which takes a single name instead of a vector of names.
    *
-   * The data_component_interpretation
-   * argument contains information about
-   * how the individual components of
-   * output files that consist of more than
-   * one data set are to be interpreted.
+   * The data_component_interpretation argument contains information about how
+   * the individual components of output files that consist of more than one
+   * data set are to be interpreted.
    *
-   * For example, if one has a finite
-   * element for the Stokes equations in
-   * 2d, representing components (u,v,p),
-   * one would like to indicate that the
-   * first two, u and v, represent a
-   * logical vector so that later on when
-   * we generate graphical output we can
-   * hand them off to a visualization
-   * program that will automatically know
-   * to render them as a vector field,
-   * rather than as two separate and
-   * independent scalar fields.
+   * For example, if one has a finite element for the Stokes equations in 2d,
+   * representing components (u,v,p), one would like to indicate that the
+   * first two, u and v, represent a logical vector so that later on when we
+   * generate graphical output we can hand them off to a visualization program
+   * that will automatically know to render them as a vector field, rather
+   * than as two separate and independent scalar fields.
    *
-   * The default value of this argument
-   * (i.e. an empty vector) corresponds is
+   * The default value of this argument (i.e. an empty vector) corresponds is
    * equivalent to a vector of values
-   * DataComponentInterpretation::component_is_scalar,
-   * indicating that all output components
-   * are independent scalar
-   * fields. However, if the given data
-   * vector represents logical vectors, you
-   * may pass a vector that contains values
-   * DataComponentInterpretation::component_is_part_of_vector. In
-   * the example above, one would pass in a
-   * vector with components
+   * DataComponentInterpretation::component_is_scalar, indicating that all
+   * output components are independent scalar fields. However, if the given
+   * data vector represents logical vectors, you may pass a vector that
+   * contains values
+   * DataComponentInterpretation::component_is_part_of_vector. In the example
+   * above, one would pass in a vector with components
    * (DataComponentInterpretation::component_is_part_of_vector,
    * DataComponentInterpretation::component_is_part_of_vector,
-   * DataComponentInterpretation::component_is_scalar)
-   * for (u,v,p).
+   * DataComponentInterpretation::component_is_scalar) for (u,v,p).
    *
-   * The names of a data vector
-   * shall only contain characters
-   * which are letters, underscore
-   * and a few other ones. Refer to
-   * the ExcInvalidCharacter
-   * exception declared in this
-   * class to see which characters
-   * are valid and which are not.
+   * The names of a data vector shall only contain characters which are
+   * letters, underscore and a few other ones. Refer to the
+   * ExcInvalidCharacter exception declared in this class to see which
+   * characters are valid and which are not.
    *
-   * @note The actual type for the
-   * vector argument may be any
-   * vector type from which
-   * FEValues can extract values on
-   * a cell using the
-   * FEValuesBase::get_function_values()
-   * function. In particular, this
-   * includes all of the usual
-   * vector types, but also
-   * IndexSet (see step-41 for a
-   * use of this).
+   * @note The actual type for the vector argument may be any vector type from
+   * which FEValues can extract values on a cell using the
+   * FEValuesBase::get_function_values() function. In particular, this
+   * includes all of the usual vector types, but also IndexSet (see step-41
+   * for a use of this).
    */
   template <class VECTOR>
   void add_data_vector (const VECTOR                   &data,
@@ -672,31 +568,19 @@ public:
                         = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
 
   /**
-   * This function is an abbreviation to
-   * the above one (see there for a
-   * discussion of the various arguments),
-   * intended for use with finite elements
-   * that are not composed of
-   * subelements. In this case, only one
-   * name per data vector needs to be
-   * given, which is what this function
-   * takes. It simply relays its arguments
-   * after a conversion of the @p name to a
-   * vector of strings, to the other
-   * add_data_vector() function above.
+   * This function is an abbreviation to the above one (see there for a
+   * discussion of the various arguments), intended for use with finite
+   * elements that are not composed of subelements. In this case, only one
+   * name per data vector needs to be given, which is what this function
+   * takes. It simply relays its arguments after a conversion of the @p name
+   * to a vector of strings, to the other add_data_vector() function above.
    *
-   * If @p data is a vector with
-   * multiple components this
-   * function will generate
-   * distinct names for all
-   * components by appending an
-   * underscore and the number of
-   * each component to @p name
+   * If @p data is a vector with multiple components this function will
+   * generate distinct names for all components by appending an underscore and
+   * the number of each component to @p name
    *
-   * The actual type for the template
-   * argument may be any vector type from
-   * which FEValues can extract values
-   * on a cell using the
+   * The actual type for the template argument may be any vector type from
+   * which FEValues can extract values on a cell using the
    * FEValuesBase::get_function_values() function.
    */
   template <class VECTOR>
@@ -707,158 +591,147 @@ public:
                         = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
 
   /**
-   * This function is an alternative to the
-   * above ones, allowing the output of
-   * derived quantities instead of the given
-   * data. This converison has to be done in
-   * a class derived from DataPostprocessor.
+   * This function is an extension of the above one (see there for a
+   * discussion of the arguments except the first one) and allows to set a
+   * vector with its own DoFHandler object. This DoFHandler needs to be
+   * compatible with the other DoFHandler objects assigned with calls to @p
+   * add_data_vector or @p attach_dof_handler, in the sense that the
+   * DoFHandler objects need to be based on the same triangulation. This
+   * function allows you to export data from multiple DoFHandlers that
+   * describe different solution components.
+   *
+   * Since this function takes a DoFHandler object and hence naturally
+   * represents dof data, the data vector type argument present in the other
+   * methods above is skipped.
+   */
+  template <class VECTOR>
+  void add_data_vector (const DH                       &dof_handler,
+                        const VECTOR                   &data,
+                        const std::vector<std::string> &names,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
+                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
+
+
+  /**
+   * This function is an abbreviation of the function above with only a scalar
+   * @p dof_handler given and a single data name.
+   */
+  template <class VECTOR>
+  void add_data_vector (const DH                       &dof_handler,
+                        const VECTOR                   &data,
+                        const std::string              &name,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation
+                        = std::vector<DataComponentInterpretation::DataComponentInterpretation>());
+
+  /**
+   * This function is an alternative to the above ones, allowing the output of
+   * derived quantities instead of the given data. This converison has to be
+   * done in a class derived from DataPostprocessor.
    *
-   * The names for these derived quantities
-   * are provided by the @p
-   * data_postprocessor argument. Likewise,
-   * the data_component_interpretation
-   * argument of the other
-   * add_data_vector() functions is
-   * provided by the data_postprocessor
-   * argument. As only data of type @p
-   * type_dof_data can be transformed, this
-   * type is also known implicitly and does
-   * not have to be given.
+   * The names for these derived quantities are provided by the @p
+   * data_postprocessor argument. Likewise, the data_component_interpretation
+   * argument of the other add_data_vector() functions is provided by the
+   * data_postprocessor argument. As only data of type @p type_dof_data can be
+   * transformed, this type is also known implicitly and does not have to be
+   * given.
    *
-   * @note The actual type for the
-   * vector argument may be any
-   * vector type from which
-   * FEValues can extract values on
-   * a cell using the
-   * FEValuesBase::get_function_values()
-   * function. In particular, this
-   * includes all of the usual
-   * vector types, but also
-   * IndexSet (see step-41 for a
-   * use of this).
+   * @note The actual type for the vector argument may be any vector type from
+   * which FEValues can extract values on a cell using the
+   * FEValuesBase::get_function_values() function. In particular, this
+   * includes all of the usual vector types, but also IndexSet (see step-41
+   * for a use of this).
    */
   template <class VECTOR>
   void add_data_vector (const VECTOR                           &data,
                         const DataPostprocessor<DH::space_dimension> &data_postprocessor);
 
   /**
-   * Release the pointers to the
-   * data vectors. This allows
-   * output of a new set of vectors
-   * without supplying the DoF
-   * handler again. Therefore, the
-   * DataOut object can be used
-   * in an algebraic context. Note
-   * that besides the data vectors
-   * also the patches already
-   * computed are deleted.
+   * Same function as above, but with a DoFHandler object that does not need
+   * to coincide with the DoFHandler initially set. Note that the
+   * postprocessor can only read data from the given DoFHandler and solution
+   * vector, not other solution vectors or DoFHandlers.
+   */
+  template <class VECTOR>
+  void add_data_vector (const DH                               &dof_handler,
+                        const VECTOR                           &data,
+                        const DataPostprocessor<DH::space_dimension> &data_postprocessor);
+
+  /**
+   * Release the pointers to the data vectors. This allows output of a new set
+   * of vectors without supplying the DoF handler again. Therefore, the
+   * DataOut object can be used in an algebraic context. Note that besides the
+   * data vectors also the patches already computed are deleted.
    */
   void clear_data_vectors ();
 
   /**
-   * Release pointers to all input
-   * data elements, i.e. pointers
-   * to data vectors and to the DoF
-   * handler object. This function
-   * may be useful when you have
-   * called the @p build_patches
-   * function of derived class,
-   * since then the patches are
-   * built and the input data is no
-   * more needed, nor is there a
-   * need to reference it. You can
-   * then output the patches
-   * detached from the main thread
-   * and need not make sure anymore
-   * that the DoF handler object
-   * and vectors must not be
-   * deleted before the output
-   * thread is finished.
+   * Release pointers to all input data elements, i.e. pointers to data
+   * vectors and to the DoF handler object. This function may be useful when
+   * you have called the @p build_patches function of derived class, since
+   * then the patches are built and the input data is no more needed, nor is
+   * there a need to reference it. You can then output the patches detached
+   * from the main thread and need not make sure anymore that the DoF handler
+   * object and vectors must not be deleted before the output thread is
+   * finished.
    */
   void clear_input_data_references ();
 
   /**
-   * This function can be used to
-   * merge the patches that were
-   * created using the
-   * @p build_patches function of
-   * the object given as argument
-   * into the list of patches
-   * created by this object. This
-   * is sometimes handy if one has,
-   * for example, a domain
-   * decomposition algorithm where
-   * each block is represented by a
-   * DoFHandler of its own,
-   * but one wants to output the
-   * solution on all the blocks at
-   * the same time.
+   * This function can be used to merge the patches that were created using
+   * the @p build_patches function of the object given as argument into the
+   * list of patches created by this object. This is sometimes handy if one
+   * has, for example, a domain decomposition algorithm where each block is
+   * represented by a DoFHandler of its own, but one wants to output the
+   * solution on all the blocks at the same time.
    *
-   * For this to work, the given
-   * argument and this object need
-   * to have the same number of
-   * output vectors, and they need
-   * to use the same number of
-   * subdivisions per patch. The
-   * output will probably look
-   * rather funny if patches in
-   * both objects overlap in space.
+   * For this to work, the given argument and this object need to have the
+   * same number of output vectors, and they need to use the same number of
+   * subdivisions per patch. The output will probably look rather funny if
+   * patches in both objects overlap in space.
    *
-   * If you call
-   * build_patches() for this
-   * object after merging in
-   * patches, the previous state is
-   * overwritten, and the merged-in
-   * patches are lost.
+   * If you call build_patches() for this object after merging in patches, the
+   * previous state is overwritten, and the merged-in patches are lost.
    *
-   * The second parameter allows to
-   * shift each node of the patches
-   * in the object passed in in the
-   * first parameter by a certain
-   * amount. This is sometimes
-   * useful to generate "exploded"
-   * views of a collection of
-   * blocks.
+   * The second parameter allows to shift each node of the patches in the
+   * object passed in in the first parameter by a certain amount. This is
+   * sometimes useful to generate "exploded" views of a collection of blocks.
    *
-   * This function will fail if
-   * either this or the other
-   * object did not yet set up any
-   * patches.
+   * This function will fail if either this or the other object did not yet
+   * set up any patches.
    */
   template <class DH2>
   void merge_patches (const DataOut_DoFData<DH2,patch_dim,patch_space_dim> &source,
                       const Point<patch_space_dim> &shift = Point<patch_space_dim>());
 
   /**
-   * Release the pointers to the
-   * data vectors and the DoF
-   * handler. You have to set all
-   * data entries again using the
-   * add_data_vector()
-   * function. The pointer to the
-   * dof handler is cleared as
-   * well, along with all other
-   * data. In effect, this function
-   * resets everything to a virgin
-   * state.
+   * Release the pointers to the data vectors and the DoF handler. You have to
+   * set all data entries again using the add_data_vector() function. The
+   * pointer to the dof handler is cleared as well, along with all other
+   * data. In effect, this function resets everything to a virgin state.
    */
   virtual void clear ();
 
   /**
-   * Determine an estimate for the
-   * memory consumption (in bytes)
-   * of this object.
+   * Determine an estimate for the memory consumption (in bytes) of this
+   * object.
    */
   std::size_t memory_consumption () const;
 
+  /**
+   * Exception
+   */
+  DeclException0 (ExcNoTriangulationSelected);
+
   /**
    * Exception
    */
   DeclException0 (ExcNoDoFHandlerSelected);
+
   /**
    * Exception
    */
   DeclException0 (ExcDataPostprocessingIsNotPossibleForCellData);
+
   /**
    * Exception
    */
@@ -917,69 +790,69 @@ public:
 
 protected:
   /**
-   * Abbreviate the somewhat lengthy
-   * name for the Patch class.
+   * Abbreviate the somewhat lengthy name for the Patch class.
    */
   typedef dealii::DataOutBase::Patch<patch_dim,patch_space_dim> Patch;
 
   /**
-   * Pointer to the dof handler object.
+   * Pointer to the triangulation object.
+   */
+  SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> > triangulation;
+
+  /**
+   * Pointer to the optional handler object.
    */
-  SmartPointer<const DH, DataOut_DoFData<DH,patch_dim,patch_space_dim> > dofs;
+  SmartPointer<const DH> dofs;
 
   /**
-   * List of data elements with vectors of
-   * values for each degree of freedom.
+   * List of data elements with vectors of values for each degree of freedom.
    */
   std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >  dof_data;
 
   /**
-   * List of data elements with vectors of
-   * values for each cell.
+   * List of data elements with vectors of values for each cell.
    */
   std::vector<std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> > >  cell_data;
 
   /**
-   * This is a list of patches that is
-   * created each time build_patches()
-   * is called. These patches are used
-   * in the output routines of the base
+   * This is a list of patches that is created each time build_patches() is
+   * called. These patches are used in the output routines of the base
    * classes.
    */
   std::vector<Patch> patches;
 
   /**
-   * Function by which the base
-   * class's functions get to know
-   * what patches they shall write
-   * to a file.
+   * Function by which the base class's functions get to know what patches
+   * they shall write to a file.
    */
   virtual
   const std::vector<Patch> &get_patches () const;
 
   /**
-   * Virtual function through
-   * which the names of data sets are
-   * obtained by the output functions
-   * of the base class.
+   * Virtual function through which the names of data sets are obtained by the
+   * output functions of the base class.
    */
   virtual
   std::vector<std::string> get_dataset_names () const;
 
   /**
-   * Overload of the respective
-   * DataOutInterface::get_vector_data_ranges()
-   * function. See there for a more
-   * extensive documentation.
+   * Extracts the finite elements stored in the dof_data object, including a
+   * dummy object of FE_DGQ<dim>(0) in case only the triangulation is used.
+   */
+  std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<DH::dimension,DH::space_dimension> > >
+  get_finite_elements() const;
+
+  /**
+   * Overload of the respective DataOutInterface::get_vector_data_ranges()
+   * function. See there for a more extensive documentation.
    */
   virtual
   std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> >
   get_vector_data_ranges () const;
 
   /**
-   * Make all template siblings
-   * friends. Needed for the
-   * merge_patches() function.
+   * Make all template siblings friends. Needed for the merge_patches()
+   * function.
    */
   template <class, int, int>
   friend class DataOut_DoFData;
@@ -988,6 +861,9 @@ protected:
 
 
 /**
+ * This class is the main class to provide output of data described by finite
+ * element fields defined on a collection of cells.
+ *
  * This class is an actual implementation of the functionality proposed by
  * the DataOut_DoFData class. It offers a function build_patches() that
  * generates the patches to be written in some graphics format from the data
@@ -1072,17 +948,15 @@ class DataOut : public DataOut_DoFData<DH, DH::dimension, DH::space_dimension>
 {
 public:
   /**
-   * Typedef to the iterator type
-   * of the dof handler class under
+   * Typedef to the iterator type of the dof handler class under
    * consideration.
    */
   typedef typename DataOut_DoFData<DH,DH::dimension,DH::space_dimension>::cell_iterator cell_iterator;
   typedef typename DataOut_DoFData<DH,DH::dimension,DH::space_dimension>::active_cell_iterator active_cell_iterator;
 
   /**
-   * Enumeration describing the region of the
-   * domain in which curved cells shall be
-   * created.
+   * Enumeration describing the region of the domain in which curved cells
+   * shall be created.
    */
   enum CurvedCellRegion
   {
@@ -1092,108 +966,61 @@ public:
   };
 
   /**
-   * This is the central function
-   * of this class since it builds
-   * the list of patches to be
-   * written by the low-level
-   * functions of the base
-   * class. See the general
-   * documentation of this class
-   * for further information.
+   * This is the central function of this class since it builds the list of
+   * patches to be written by the low-level functions of the base class. See
+   * the general documentation of this class for further information.
    *
-   * The default value <tt>0</tt>
-   * of <tt>n_subdivisions</tt>
-   * indicates that the value
-   * stored in
-   * DataOutInterface::default_subdivisions
-   * is to be used.
+   * The default value <tt>0</tt> of <tt>n_subdivisions</tt> indicates that
+   * the value stored in DataOutInterface::default_subdivisions is to be used.
    */
   virtual void build_patches (const unsigned int n_subdivisions = 0);
 
   /**
-   * Same as above, except that the
-   * additional first parameter
-   * defines a mapping that is to
-   * be used in the generation of
-   * output. If
-   * <tt>n_subdivisions>1</tt>, the
-   * points interior of subdivided
-   * patches which originate from
-   * cells at the boundary of the
-   * domain can be computed using the
-   * mapping, i.e. a higher order
-   * mapping leads to a
-   * representation of a curved
-   * boundary by using more
-   * subdivisions. Some mappings like
-   * MappingQEulerian result in curved cells
-   * in the interior of the domain. However,
-   * there is nor easy way to get this
-   * information from the Mapping. Thus the
-   * last argument @p curved_region take one
-   * of three values resulting in no curved
-   * cells at all, curved cells at the
-   * boundary (default) or curved cells in
-   * the whole domain.
+   * Same as above, except that the additional first parameter defines a
+   * mapping that is to be used in the generation of output. If
+   * <tt>n_subdivisions>1</tt>, the points interior of subdivided patches
+   * which originate from cells at the boundary of the domain can be computed
+   * using the mapping, i.e. a higher order mapping leads to a representation
+   * of a curved boundary by using more subdivisions. Some mappings like
+   * MappingQEulerian result in curved cells in the interior of the
+   * domain. However, there is nor easy way to get this information from the
+   * Mapping. Thus the last argument @p curved_region take one of three values
+   * resulting in no curved cells at all, curved cells at the boundary
+   * (default) or curved cells in the whole domain.
    *
-   * Even for non-curved cells the
-   * mapping argument can be used
-   * for the Eulerian mappings (see
-   * class MappingQ1Eulerian) where
-   * a mapping is used not only to
-   * determine the position of
-   * points interior to a cell, but
-   * also of the vertices.  It
-   * offers an opportunity to watch
-   * the solution on a deformed
-   * triangulation on which the
-   * computation was actually
-   * carried out, even if the mesh
-   * is internally stored in its
-   * undeformed configuration and
-   * the deformation is only
-   * tracked by an additional
-   * vector that holds the
+   * Even for non-curved cells the mapping argument can be used for the
+   * Eulerian mappings (see class MappingQ1Eulerian) where a mapping is used
+   * not only to determine the position of points interior to a cell, but also
+   * of the vertices.  It offers an opportunity to watch the solution on a
+   * deformed triangulation on which the computation was actually carried out,
+   * even if the mesh is internally stored in its undeformed configuration and
+   * the deformation is only tracked by an additional vector that holds the
    * deformation of each vertex.
    *
-   * @todo The @p mapping argument should be
-   * replaced by a hp::MappingCollection in
-   * case of a hp::DoFHandler.
+   * @todo The @p mapping argument should be replaced by a
+   * hp::MappingCollection in case of a hp::DoFHandler.
    */
   virtual void build_patches (const Mapping<DH::dimension,DH::space_dimension> &mapping,
                               const unsigned int n_subdivisions = 0,
                               const CurvedCellRegion curved_region = curved_boundary);
 
   /**
-   * Return the first cell which we
-   * want output for. The default
-   * implementation returns the
-   * first active cell, but you
-   * might want to return other
-   * cells in a derived class.
+   * Return the first cell which we want output for. The default
+   * implementation returns the first active cell, but you might want to
+   * return other cells in a derived class.
    */
   virtual cell_iterator first_cell ();
 
   /**
-   * Return the next cell after
-   * @p cell which we want output
-   * for.  If there are no more
-   * cells, <tt>#dofs->end()</tt> shall
-   * be returned.
+   * Return the next cell after @p cell which we want output for.  If there
+   * are no more cells, <tt>#dofs->end()</tt> shall be returned.
    *
-   * The default implementation
-   * returns the next active cell,
-   * but you might want to return
-   * other cells in a derived
-   * class. Note that the default
-   * implementation assumes that
-   * the given @p cell is active,
-   * which is guaranteed as long as
-   * first_cell() is also used
-   * from the default
-   * implementation. Overloading
-   * only one of the two functions
-   * might not be a good idea.
+   * The default implementation returns the next active cell, but you might
+   * want to return other cells in a derived class. Note that the default
+   * implementation assumes that the given @p cell is active, which is
+   * guaranteed as long as first_cell() is also used from the default
+   * implementation. Overloading only one of the two functions might not be a
+   * good idea.
    */
   virtual cell_iterator next_cell (const cell_iterator &cell);
 
@@ -1208,36 +1035,23 @@ public:
 private:
 
   /**
-   * Return the first cell produced
-   * by the
-   * first_cell()/next_cell()
-   * function pair that is locally
-   * owned. If this object operates
-   * on a non-distributed
-   * triangulation, the result
-   * equals what first_cell()
-   * returns.
+   * Return the first cell produced by the first_cell()/next_cell() function
+   * pair that is locally owned. If this object operates on a non-distributed
+   * triangulation, the result equals what first_cell() returns.
    */
   cell_iterator first_locally_owned_cell ();
 
   /**
-   * Return the next cell produced
-   * by the next_cell() function
-   * that is locally owned. If this
-   * object operates on a
-   * non-distributed triangulation,
-   * the result equals what
-   * first_cell() returns.
+   * Return the next cell produced by the next_cell() function that is locally
+   * owned. If this object operates on a non-distributed triangulation, the
+   * result equals what first_cell() returns.
    */
   cell_iterator next_locally_owned_cell (const cell_iterator &cell);
 
   /**
-   * Build one patch. This function
-   * is called in a WorkStream
-   * context.
+   * Build one patch. This function is called in a WorkStream context.
    *
-   * The result is written into the patch
-   * variable.
+   * The result is written into the patch variable.
    */
   void build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
                         internal::DataOut::ParallelData<DH::dimension, DH::space_dimension> &data,
@@ -1250,49 +1064,6 @@ private:
 // -------------------- template and inline functions ------------------------
 
 
-namespace internal
-{
-  namespace DataOut
-  {
-    template <int dim, int spacedim>
-    template <class FE>
-    ParallelDataBase<dim,spacedim>::
-    ParallelDataBase (const unsigned int n_components,
-                      const unsigned int n_datasets,
-                      const unsigned int n_subdivisions,
-                      const unsigned int n_q_points,
-                      const std::vector<unsigned int> &n_postprocessor_outputs,
-                      const FE &finite_elements)
-      :
-      n_components (n_components),
-      n_datasets (n_datasets),
-      n_subdivisions (n_subdivisions),
-      patch_values (n_q_points),
-      patch_values_system (n_q_points),
-      patch_gradients (n_q_points),
-      patch_gradients_system (n_q_points),
-      patch_hessians (n_q_points),
-      patch_hessians_system (n_q_points),
-      postprocessed_values (n_postprocessor_outputs.size()),
-      fe_collection (finite_elements)
-    {
-      for (unsigned int k=0; k<n_q_points; ++k)
-        {
-          patch_values_system[k].reinit(n_components);
-          patch_gradients_system[k].resize(n_components);
-          patch_hessians_system[k].resize(n_components);
-        }
-
-      for (unsigned int dataset=0; dataset<n_postprocessor_outputs.size(); ++dataset)
-        if (n_postprocessor_outputs[dataset] != 0)
-          postprocessed_values[dataset]
-          .resize(n_q_points,
-                  dealii::Vector<double>(n_postprocessor_outputs[dataset]));
-    }
-  }
-}
-
-
 template <class DH, int patch_dim, int patch_space_dim>
 template <class DH2>
 void
index 07c33fd26427a23e60d58ac9cb224fa2ef423c62..defebb091e7b49726ee615f4b953e86bcd632137 100644 (file)
@@ -43,20 +43,13 @@ namespace internal
     template <int dim, int spacedim>
     struct ParallelData : public internal::DataOut::ParallelDataBase<dim,spacedim>
     {
-      template <class FE>
-      ParallelData (const Quadrature<dim-1> &quadrature,
-                    const unsigned int n_components,
-                    const unsigned int n_datasets,
+      ParallelData (const unsigned int n_datasets,
                     const unsigned int n_subdivisions,
                     const std::vector<unsigned int> &n_postprocessor_outputs,
                     const Mapping<dim,spacedim> &mapping,
-                    const FE &finite_elements,
+                    const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
                     const UpdateFlags update_flags);
 
-      const dealii::hp::QCollection<dim-1> q_collection;
-      const dealii::hp::MappingCollection<dim,spacedim> mapping_collection;
-      dealii::hp::FEFaceValues<dim> x_fe_values;
-
       std::vector<Point<dim> > patch_normals;
       std::vector<Point<spacedim> > patch_evaluation_points;
     };
index 95f4f57378e35a04d435c307c12a9c6add8f11e6..1a45fd3fbb30dfb2d503e52ae699e6ff65a0d08c 100644 (file)
@@ -43,21 +43,16 @@ namespace internal
     template <int dim, int spacedim>
     struct ParallelData : public internal::DataOut::ParallelDataBase<dim,spacedim>
     {
-      template <class FE>
-      ParallelData (const Quadrature<dim> &quadrature,
-                    const unsigned int n_components,
-                    const unsigned int n_datasets,
+      ParallelData (const unsigned int n_datasets,
                     const unsigned int n_subdivisions,
                     const unsigned int n_patches_per_circle,
                     const std::vector<unsigned int> &n_postprocessor_outputs,
-                    const FE &finite_elements,
+                    const Mapping<dim,spacedim> &mapping,
+                    const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
                     const UpdateFlags update_flags);
 
       const unsigned int n_patches_per_circle;
 
-      const dealii::hp::QCollection<dim> q_collection;
-      dealii::hp::FEValues<dim,spacedim> x_fe_values;
-
       std::vector<Point<spacedim> > patch_evaluation_points;
     };
   }
index 0473525720c55ee76ab1c4fb3897aa4b5b8371d6..0260969acc44e808a04853fcdebead8e029a41de 100644 (file)
@@ -82,7 +82,7 @@ DEAL_II_NAMESPACE_OPEN
  * takes a solution that consists of velocity, pressure and temperature (dim+2
  * components) and computes a variety of output quantities, some of which
  * are vector valued and some of which are scalar. On the other hand,
- * in step-28 we implement a postprocessor that only computes the magnitude
+ * in step-29 we implement a postprocessor that only computes the magnitude
  * of a complex number given by a two-component finite element. It seems silly
  * to have to implement four virtual functions for this
  * (compute_derived_quantities_scalar() or compute_derived_quantities_vector(),
index 96fd9a1b7c7ddbac1a666e188cec8d4e5a06af3d..d7cf41a6ed1579e8da9a9571a938605043a830d6 100644 (file)
@@ -182,7 +182,7 @@ class ConstraintMatrix;
  *
  * <li> Creation of right hand side vectors for point sources:
  *   The create_point_source_vector() function computes the vector
- *   $f_i = \int_\Omega \delta_0(x-x_0) \phi_i(x) dx$.
+ *   $f_i = \int_\Omega \delta(x-x_0) \phi_i(x) dx$.
  *
  * <li> Creation of boundary right hand side vectors: The
  *   create_boundary_right_hand_side() function computes the vector
@@ -1785,7 +1785,9 @@ namespace VectorTools
 
   /**
    * Create a right hand side
-   * vector for a point source at point @p p.
+   * vector for a point source at point @p p. In other words, it creates
+   * a vector $F$ so that
+   * $F_i = \int_\Omega \delta(x-p) \phi_i(x) dx$.
    * Prior content of the
    * given @p rhs_vector vector is
    * deleted.
index 1638903344eea866ff185886b3121e59e3901d64..7277a8520d25fbe043e5c45de8b733b55019579b 100644 (file)
@@ -2194,10 +2194,12 @@ DataOutBase::TecplotFlags::memory_consumption () const
 
 
 DataOutBase::VtkFlags::VtkFlags (const double time,
-                                 const unsigned int cycle)
+                                 const unsigned int cycle,
+                                 const bool print_date_and_time)
   :
   time (time),
-  cycle (cycle)
+  cycle (cycle),
+  print_date_and_time (print_date_and_time)
 {}
 
 
@@ -4945,14 +4947,18 @@ DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
     std::tm     *time = std::localtime(&time1);
     out << "# vtk DataFile Version 3.0"
         << '\n'
-        << "#This file was generated by the deal.II library on "
-        << time->tm_year+1900 << "/"
-        << time->tm_mon+1 << "/"
-        << time->tm_mday << " at "
-        << time->tm_hour << ":"
-        << std::setw(2) << time->tm_min << ":"
-        << std::setw(2) << time->tm_sec
-        << '\n'
+        << "#This file was generated by the deal.II library";
+    if (flags.print_date_and_time)
+        out << " on "
+            << time->tm_year+1900 << "/"
+            << time->tm_mon+1 << "/"
+            << time->tm_mday << " at "
+            << time->tm_hour << ":"
+            << std::setw(2) << time->tm_min << ":"
+            << std::setw(2) << time->tm_sec;
+    else
+        out << ".";
+    out << '\n'
         << "ASCII"
         << '\n';
     // now output the data header
@@ -5162,7 +5168,8 @@ DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
 }
 
 
-void DataOutBase::write_vtu_header (std::ostream &out)
+void DataOutBase::write_vtu_header (std::ostream &out,
+                                    const VtkFlags &flags)
 {
   AssertThrow (out, ExcIO());
   std::time_t  time1= std::time (0);
@@ -5171,15 +5178,18 @@ void DataOutBase::write_vtu_header (std::ostream &out)
   out << "<!-- \n";
   out << "# vtk DataFile Version 3.0"
       << '\n'
-      << "#This file was generated by the deal.II library on "
-      << time->tm_year+1900 << "/"
-      << time->tm_mon+1 << "/"
-      << time->tm_mday << " at "
-      << time->tm_hour << ":"
-      << std::setw(2) << time->tm_min << ":"
-      << std::setw(2) << time->tm_sec
-      << "\n-->\n";
-
+      << "#This file was generated by the deal.II library";
+  if (flags.print_date_and_time)
+      out << " on "
+          << time->tm_year+1900 << "/"
+          << time->tm_mon+1 << "/"
+          << time->tm_mday << " at "
+          << time->tm_hour << ":"
+          << std::setw(2) << time->tm_min << ":"
+          << std::setw(2) << time->tm_sec;
+  else
+      out << ".";
+  out << "\n-->\n";
   out << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\"";
 #ifdef DEAL_II_WITH_ZLIB
   out << " compressor=\"vtkZLibDataCompressor\"";
@@ -5214,7 +5224,7 @@ DataOutBase::write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
                         const VtkFlags                          &flags,
                         std::ostream                            &out)
 {
-  write_vtu_header(out);
+  write_vtu_header(out, flags);
   write_vtu_main (patches, data_names, vector_data_ranges, flags, out);
   write_vtu_footer(out);
 
@@ -6498,7 +6508,7 @@ void DataOutInterface<dim,spacedim>::write_vtu_in_parallel (const char *filename
   if (myrank==0)
     {
       std::stringstream ss;
-      DataOutBase::write_vtu_header(ss);
+      DataOutBase::write_vtu_header(ss, vtk_flags);
       header_size = ss.str().size();
       MPI_File_write(fh, const_cast<char *>(ss.str().c_str()), header_size, MPI_CHAR, NULL);
     }
index b8223630f03b5cfe8521c3ddb99832e7f86ae6d2..6569451117892e39f132f8dbae4b30ad6a8dee47 100644 (file)
@@ -1101,7 +1101,9 @@ unsigned int
 GeometryInfo<2>::child_cell_on_face (const RefinementCase<2> &ref_case,
                                      const unsigned int face,
                                      const unsigned int subface,
-                                     const bool, const bool face_flip, const bool,
+                                     const bool /*face_orientation*/,
+                                     const bool face_flip,
+                                     const bool /*face_rotation*/,
                                      const RefinementCase<1> &)
 {
   Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
index bf373ddd5f163c3eee3a3da8e37a1236aeea9810..ce4b5bcfb716dfd71bc2f57b696fc20017fc77df 100644 (file)
@@ -271,6 +271,8 @@ IndexSet::block_read(std::istream &in)
   if (n_ranges)
     in.read(reinterpret_cast<char *>(&*ranges.begin()),
             ranges.size() * sizeof(Range));
+
+  do_compress(); // needed so that largest_range can be recomputed
 }
 
 
index ba7f8773f35290d9948b6518ba1cbf0d0c167966..447ff341100d3cb8eafb7f150695cbce42710141 100644 (file)
@@ -137,23 +137,65 @@ LogStream::operator<< (std::ostream& (*p) (std::ostream &))
   // Print to the internal stringstream:
   stream << p;
 
-  // Next check whether this is the <tt>flush</tt> or <tt>endl</tt>
-  // manipulator, and if so print out the message.
-  std::ostream & (* const p_flush) (std::ostream &) = &std::flush;
-  std::ostream & (* const p_endl) (std::ostream &) = &std::endl;
-  if (p == p_flush || p == p_endl)
+
+  // This is a bloody hack until LogStream got reimplemented as a proper
+  // child of std::streambuf (or similar).
+  //
+  // The problem is that at this point we would like to know whether an
+  // std::flush or std::endl has called us, however, there is no way to
+  // detect this in a sane manner.
+  //
+  // The obvious idea to compare function pointers,
+  //   std::ostream & (* const p_flush) (std::ostream &) = &std::flush;
+  //   p == p_flush ? ...,
+  // is wrong as there doesn't has to be a _single_ std::flush instance...
+  // there could be multiple of it. And in fact, LLVM's libc++ implements
+  // std::flush and std::endl in a way that every shared library and
+  // executable has its local copy... fun...
+  //
+  // - Maier, 2013
+
+  class QueryStreambuf : public std::streambuf
+  {
+    // Implement a minimalistic stream buffer that only stores the fact
+    // whether overflow or sync was called
+    public:
+      QueryStreambuf()
+        : flushed_(false), newline_written_(false)
+      {
+      }
+      bool flushed() { return flushed_; }
+      bool newline_written() { return newline_written_; }
+    private:
+      int_type overflow(int_type ch)
+        {
+          newline_written_ = true;
+          return ch;
+        }
+      int sync()
+        {
+          flushed_ = true;
+          return 0;
+        }
+      bool flushed_;
+      bool newline_written_;
+  } query_streambuf;
+
+  {
+    // and initialize an ostream with this streambuf:
+    std::ostream inject (&query_streambuf);
+    inject << p;
+  }
+
+  if (query_streambuf.flushed())
     {
       Threads::Mutex::ScopedLock lock(write_lock);
 
-      // Print the line head in case of a newline:
+      // Print the line head in case of a previous newline:
       if (at_newline)
         print_line_head();
 
-      if (p == p_flush)
-        at_newline = false;
-
-      if (p == p_endl)
-        at_newline = true;
+      at_newline = query_streambuf.newline_written();
 
       if (get_prefixes().size() <= std_depth)
         *std_out << stream.str();
@@ -161,7 +203,7 @@ LogStream::operator<< (std::ostream& (*p) (std::ostream &))
       if (file && (get_prefixes().size() <= file_depth))
         *file << stream.str() << std::flush;
 
-      // Start a new string
+      // Start a new string:
       stream.str("");
     }
 
index aed67bee637e93477d67317d8ec70181dcb5b30e..831434c98db2e2cb934b8fbe2502909a56f5eb64 100644 (file)
@@ -343,25 +343,62 @@ void TableHandler::write_text(std::ostream &out,
   const unsigned int nrows  = n_rows();
   const unsigned int n_cols = sel_columns.size();
 
-  // handle the simple format separately first
-  if (format==simple_table_with_separate_column_description)
+  // cache the columns and compute the widths of each column for alignment
+  std::vector<const Column *> cols;
+  std::vector<unsigned int> column_widths (n_cols, 0);
+  for (unsigned int j=0; j<n_cols; ++j)
+    {
+      std::string key=sel_columns[j];
+      const std::map<std::string, Column>::const_iterator
+      col_iter=columns.find(key);
+      Assert(col_iter!=columns.end(), ExcInternalError());
+      cols.push_back(&(col_iter->second));
+
+      column_widths[j] = col_iter->second.max_length;
+    }
+
+  switch (format)
+    {
+    case org_mode_table:
     {
       // write the captions
+      out << "| " << std::left;
       for (unsigned int j=0; j<n_cols; ++j)
         {
           const std::string &key = sel_columns[j];
-          out << "# " << j+1 << ": " << key << '\n';
+          column_widths[j] = std::max(column_widths[j],
+                                      (unsigned int)key.length());
+          out << std::setw(column_widths[j]);
+          out << key << " | ";
+        }
+      out << std::endl;
+
+      // write the body
+      for (unsigned int i=0; i<nrows; ++i)
+        {
+          out << "| ";
+          for (unsigned int j=0; j<n_cols; ++j)
+            {
+              const Column &column=*(cols[j]);
+
+              out << std::setw(column_widths[j]);
+              out << column.entries[i].get_cached_string();
+              out << " | ";
+            }
+          out << '\n';
         }
 
-      // cache the columns
-      std::vector<const Column *> cols;
+      out << std::flush;
+      return;
+    }
+    
+    case simple_table_with_separate_column_description:
+    {
+      // write the captions
       for (unsigned int j=0; j<n_cols; ++j)
         {
-          std::string key=sel_columns[j];
-          const std::map<std::string, Column>::const_iterator
-          col_iter=columns.find(key);
-          Assert(col_iter!=columns.end(), ExcInternalError());
-          cols.push_back(&(col_iter->second));
+          const std::string &key = sel_columns[j];
+          out << "# " << j+1 << ": " << key << '\n';
         }
 
       // write the body
@@ -380,33 +417,21 @@ void TableHandler::write_text(std::ostream &out,
       out << std::flush;
       return;
     }
-
-  // cache the columns and compute the widths of each column for alignment
-  std::vector<const Column *> cols;
-  std::vector<unsigned int> column_widths (n_cols, 0);
-  for (unsigned int j=0; j<n_cols; ++j)
-    {
-      std::string key=sel_columns[j];
-      const std::map<std::string, Column>::const_iterator
-      col_iter=columns.find(key);
-      Assert(col_iter!=columns.end(), ExcInternalError());
-      cols.push_back(&(col_iter->second));
-
-      column_widths[j] = col_iter->second.max_length;
-    }
-
-  // writing the captions for table_with_separate_column_description
-  // means that we ignore supercolumns and output the column
-  // header for each column. enumerate columns starting with 1
-  if (format == table_with_separate_column_description)
+    
+    case table_with_separate_column_description:
     {
+      // writing the captions for table_with_separate_column_description
+      // means that we ignore supercolumns and output the column
+      // header for each column. enumerate columns starting with 1
       for (unsigned int j=0; j<n_cols; ++j)
         {
           std::string key=sel_columns[j];
           out << "# " << j+1 << ": " << key << '\n';
         }
+      break;
     }
-  else if (format == table_with_headers)
+    
+    case table_with_headers:
     {
       // This format output supercolumn headers and aligns them centered
       // over all the columns that belong to it.
@@ -480,12 +505,16 @@ void TableHandler::write_text(std::ostream &out,
           out << ' ';
         }
       out << '\n';
+      break;
+    }
+    
+    default:
+      Assert (false, ExcInternalError());
     }
-  else
-    Assert (false, ExcInternalError());
-
 
-  // finally output the data itself
+  
+  // finally output the data itself for
+  // table_with_headers or table_with_separate_column_description:
   for (unsigned int i=0; i<nrows; ++i)
     {
       for (unsigned int j=0; j<n_cols; ++j)
index 10bf20eae2c76186d5702adcdec4d883719c0375..ad41b28892b8cbe4b89e6dfd75744a96bd03dee0 100644 (file)
@@ -2648,7 +2648,7 @@ namespace DoFTools
 
                         // break if the n_master_dofs == 0, because we are
                         // attempting to constrain to an element that has
-                        // has no face dofs
+                        // no face dofs
                         if (master_dofs.size() == 0) break;
 
                         // make sure the element constraints for this face
@@ -2692,39 +2692,15 @@ namespace DoFTools
                         // another possibility is what happens in crash_13.
                         // there, we have FESystem(FE_Q(1),FE_DGQ(0)) vs.
                         // FESystem(FE_Q(1),FE_DGQ(1)). neither of them
-                        // dominates the other. the point is that it
-                        // doesn't matter, since hopefully for this case,
-                        // both sides' dofs should have been unified.
-                        //
-                        // make sure this is actually true. this actually
-                        // only matters, of course, if either of the two
-                        // finite elements actually do have dofs on the
-                        // face
-                        if ((cell->get_fe().dofs_per_face != 0)
-                            ||
-                            (cell->neighbor(face)->get_fe().dofs_per_face != 0))
-                          {
-                            Assert (cell->get_fe().dofs_per_face
-                                    ==
-                                    cell->neighbor(face)->get_fe().dofs_per_face,
-                                    ExcNotImplemented());
-
-                            // (ab)use the master and slave dofs arrays for
-                            // a moment here
-                            master_dofs.resize (cell->get_fe().dofs_per_face);
-                            cell->face(face)
-                            ->get_dof_indices (master_dofs,
-                                               cell->active_fe_index ());
-
-                            slave_dofs.resize (cell->neighbor(face)->get_fe().dofs_per_face);
-                            cell->face(face)
-                            ->get_dof_indices (slave_dofs,
-                                               cell->neighbor(face)->active_fe_index ());
-
-                            for (unsigned int i=0; i<cell->get_fe().dofs_per_face; ++i)
-                              AssertDimension (master_dofs[i], slave_dofs[i]);
-                          }
-
+                        // dominates the other.
+                       //
+                       // a final possibility is that we have something like
+                       // FESystem(FE_Q(1),FE_Q(1)) vs
+                       // FESystem(FE_Q(1),FE_Nothing()), see
+                       // hp/fe_nothing_18/19.
+                       //
+                       // in any case, the point is that it doesn't
+                        // matter. there is nothing to do here.
                         break;
                       }
 
@@ -2792,6 +2768,12 @@ namespace DoFTools
     // to this particular child
     //
     // @precondition: face_1 is supposed to be active
+    //
+    // @note As bug #82 ((http://code.google.com/p/dealii/issues/detail?id=82) and the
+    // corresponding testcase bits/periodicity_05 demonstrate, we can occasionally
+    // get into trouble if we already have the constraint x1=x2 and want to insert
+    // x2=x1. we avoid this by skipping an identity constraint if the opposite
+    // constraint already exists
     template <typename FaceIterator>
     void
     set_periodicity_constraints (const FaceIterator                          &face_1,
@@ -2897,21 +2879,83 @@ namespace DoFTools
                   ||
                   component_mask[fe.face_system_to_component_index(i).first])
                 {
-                  constraint_matrix.add_line(dofs_2[i]);
+                  // as mentioned in the comment above this function, we need
+                  // to be careful about treating identity constraints differently.
+                  // consequently, find out whether this dof 'i' will be
+                  // identity constrained
+                  //
+                  // to check whether this is the case, first see whether there are
+                  // any weights other than 0 and 1, then in a first stage make sure
+                  // that if so there is only one weight equal to 1
+                  bool is_identity_constrained = true;
                   for (unsigned int jj=0; jj<dofs_per_face; ++jj)
+                    if (((transformation(i,jj) == 0) || (transformation(i,jj) == 1)) == false)
+                      {
+                        is_identity_constrained = false;
+                        break;
+                      }
+                  unsigned int identity_constraint_target = numbers::invalid_unsigned_int;
+                  if (is_identity_constrained == true)
+                    {
+                      bool one_identity_found = false;
+                      for (unsigned int jj=0; jj<dofs_per_face; ++jj)
+                        if (transformation(i,jj) == 1)
+                          {
+                            if (one_identity_found == false)
+                              {
+                                one_identity_found = true;
+                                identity_constraint_target = jj;
+                              }
+                            else
+                              {
+                                is_identity_constrained = false;
+                                identity_constraint_target = numbers::invalid_unsigned_int;
+                                break;
+                              }
+                          }
+                    }
+
+                  // now treat constraints, either as an equality constraint or
+                  // as a sequence of constraints
+                  if (is_identity_constrained == true)
                     {
                       // Query the correct face_index on face_2 respecting the given
                       // orientation:
                       const unsigned int j =
-                        cell_to_rotated_face_index[fe.face_to_cell_index(jj, 0, /* It doesn't really matter, just assume
+                        cell_to_rotated_face_index[fe.face_to_cell_index(identity_constraint_target,
+                            0, /* It doesn't really matter, just assume
                            * we're on the first face...
                            */
                                                                          face_orientation, face_flip, face_rotation)];
 
-                      // And finally constrain the two DoFs respecting component_mask:
-                      if (transformation(i,jj) != 0)
-                        constraint_matrix.add_entry(dofs_2[i], dofs_1[j],
-                                                    transformation(i,jj));
+                      // if the two aren't already identity constrained (whichever way
+                      // around, then enter the constraint. otherwise there is nothing
+                      // for us still to do
+                      if (constraint_matrix.are_identity_constrained(dofs_2[i], dofs_1[i]) == false)
+                        {
+                          constraint_matrix.add_line(dofs_2[i]);
+                          constraint_matrix.add_entry(dofs_2[i], dofs_1[j], 1);
+                        }
+                    }
+                  else
+                    {
+                      // this is just a regular constraint. enter it piece by piece
+                      constraint_matrix.add_line(dofs_2[i]);
+                      for (unsigned int jj=0; jj<dofs_per_face; ++jj)
+                        {
+                          // Query the correct face_index on face_2 respecting the given
+                          // orientation:
+                          const unsigned int j =
+                            cell_to_rotated_face_index[fe.face_to_cell_index(jj, 0, /* It doesn't really matter, just assume
+                               * we're on the first face...
+                               */
+                                                                             face_orientation, face_flip, face_rotation)];
+
+                          // And finally constrain the two DoFs respecting component_mask:
+                          if (transformation(i,jj) != 0)
+                            constraint_matrix.add_entry(dofs_2[i], dofs_1[j],
+                                                        transformation(i,jj));
+                        }
                     }
                 }
         }
index cdb97b5104b3bbd2dfa062be453fc04490006ee0..501e7e0d818874bfe071b15856a0bdcc6013b89f 100644 (file)
@@ -544,6 +544,96 @@ block_mask (const ComponentMask &component_mask) const
 
 
 
+template <int dim, int spacedim>
+unsigned int
+FiniteElement<dim,spacedim>::
+face_to_cell_index (const unsigned int face_index,
+                    const unsigned int face,
+                    const bool face_orientation,
+                    const bool face_flip,
+                    const bool face_rotation) const
+{
+  Assert (face_index < this->dofs_per_face,
+          ExcIndexRange(face_index, 0, this->dofs_per_face));
+  Assert (face < GeometryInfo<dim>::faces_per_cell,
+          ExcIndexRange(face, 0, GeometryInfo<dim>::faces_per_cell));
+
+//TODO: we could presumably solve the 3d case below using the
+// adjust_quad_dof_index_for_face_orientation_table field. for the
+// 2d case, we can't use adjust_line_dof_index_for_line_orientation_table
+// since that array is empty (presumably because we thought that
+// there are no flipped edges in 2d, but these can happen in
+// DoFTools::make_periodicity_constraints, for example). so we
+// would need to either fill this field, or rely on derived classes
+// implementing this function, as we currently do
+
+  // see the function's documentation for an explanation of this
+  // assertion -- in essence, derived classes have to implement
+  // an overloaded version of this function if we are to use any
+  // other than standard orientation
+  if ((face_orientation != true) || (face_flip != false) || (face_rotation != false))
+    Assert ((this->dofs_per_line <= 1) && (this->dofs_per_quad <= 1),
+            ExcMessage ("The function in this base class can not handle this case. "
+                        "Rather, the derived class you are using must provide "
+                        "an overloaded version but apparently hasn't done so. See "
+                        "the documentation of this function for more information."));
+
+  // we need to distinguish between DoFs on vertices, lines and in 3d quads.
+  // do so in a sequence of if-else statements
+  if (face_index < this->first_face_line_index)
+    // DoF is on a vertex
+    {
+      // get the number of the vertex on the face that corresponds to this DoF,
+      // along with the number of the DoF on this vertex
+      const unsigned int face_vertex         = face_index / this->dofs_per_vertex;
+      const unsigned int dof_index_on_vertex = face_index % this->dofs_per_vertex;
+
+      // then get the number of this vertex on the cell and translate
+      // this to a DoF number on the cell
+      return (GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
+                                                       face_orientation,
+                                                       face_flip,
+                                                       face_rotation)
+              * this->dofs_per_vertex
+              +
+              dof_index_on_vertex);
+    }
+  else if (face_index < this->first_face_quad_index)
+    // DoF is on a face
+    {
+      // do the same kind of translation as before. we need to only consider
+      // DoFs on the lines, i.e., ignoring those on the vertices
+      const unsigned int index = face_index - this->first_face_line_index;
+
+      const unsigned int face_line         = index / this->dofs_per_line;
+      const unsigned int dof_index_on_line = index % this->dofs_per_line;
+
+      return (this->first_line_index
+              + GeometryInfo<dim>::face_to_cell_lines(face, face_line,
+                                                      face_orientation,
+                                                      face_flip,
+                                                      face_rotation)
+              * this->dofs_per_line
+              +
+              dof_index_on_line);
+    }
+  else
+    // DoF is on a quad
+    {
+      Assert (dim >= 3, ExcInternalError());
+
+      // ignore vertex and line dofs
+      const unsigned int index = face_index - this->first_face_quad_index;
+
+      return (this->first_quad_index
+              + face * this->dofs_per_quad
+              + index);
+    }
+}
+
+
+
+
 template <int dim, int spacedim>
 unsigned int
 FiniteElement<dim,spacedim>::adjust_quad_dof_index_for_face_orientation (const unsigned int index,
index e0873d9ba3f6a6de3210041acf74a7796c600d76..894e3c3f1859fbeb10eb03059b481d6a415bb9b3 100644 (file)
@@ -99,54 +99,6 @@ bool FiniteElementData<dim>::operator== (const FiniteElementData<dim> &f) const
           (conforming_space == f.conforming_space));
 }
 
-template<int dim>
-unsigned int
-FiniteElementData<dim>::
-face_to_cell_index (const unsigned int face_index,
-                    const unsigned int face,
-                    const bool face_orientation,
-                    const bool face_flip,
-                    const bool face_rotation) const
-{
-  Assert (face_index < this->dofs_per_face,
-          ExcIndexRange(face_index, 0, this->dofs_per_face));
-  Assert (face < GeometryInfo<dim>::faces_per_cell,
-          ExcIndexRange(face, 0, GeometryInfo<dim>::faces_per_cell));
-
-  // DoF on a vertex
-  if (face_index < this->first_face_line_index)
-    {
-      // Vertex number on the face
-      const unsigned int face_vertex = face_index / this->dofs_per_vertex;
-      return face_index % this->dofs_per_vertex
-             + GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
-                                                        face_orientation,
-                                                        face_flip,
-                                                        face_rotation)
-             * this->dofs_per_vertex;
-    }
-  // Else, DoF on a line?
-  if (face_index < this->first_face_quad_index)
-    {
-      // Ignore vertex dofs
-      const unsigned int index = face_index - this->first_face_line_index;
-      // Line number on the face
-      const unsigned int face_line = index / this->dofs_per_line;
-      return this->first_line_index + index % this->dofs_per_line
-             + GeometryInfo<dim>::face_to_cell_lines(face, face_line,
-                                                     face_orientation,
-                                                     face_flip,
-                                                     face_rotation)
-             * this->dofs_per_line;
-    }
-  // Else, DoF is on a quad
-
-  // Ignore vertex and line dofs
-  const unsigned int index = face_index - this->first_face_quad_index;
-  return this->first_quad_index + index
-         + face * this->dofs_per_quad;
-}
-
 
 template class FiniteElementData<1>;
 template class FiniteElementData<2>;
index b8637568fc543241cb4d50e318bcf71ce6d79d64..bbf8124ada2958426bd7df76d54c7ff4078e9cf2 100644 (file)
 
 #include <deal.II/fe/fe_face.h>
 #include <deal.II/fe/fe_poly_face.templates.h>
+#include <deal.II/fe/fe_nothing.h>
+#include <deal.II/base/quadrature_lib.h>
 #include <sstream>
 
 DEAL_II_NAMESPACE_OPEN
 
+
+namespace
+{
+  std::vector<Point<1> >
+  get_QGaussLobatto_points (const unsigned int degree)
+  {
+    if (degree > 0)
+      return QGaussLobatto<1>(degree+1).get_points();
+    else
+      return std::vector<Point<1> >(1, Point<1>(0.5));
+  }
+}
+
 template <int dim, int spacedim>
 FE_FaceQ<dim,spacedim>::FE_FaceQ (const unsigned int degree)
   :
   FE_PolyFace<TensorProductPolynomials<dim-1>, dim, spacedim> (
-    TensorProductPolynomials<dim-1>(Polynomials::LagrangeEquidistant::generate_complete_basis(degree)),
+    TensorProductPolynomials<dim-1>(Polynomials::generate_complete_Lagrange_basis(get_QGaussLobatto_points(degree))),
     FiniteElementData<dim>(get_dpo_vector(degree), 1, degree, FiniteElementData<dim>::L2),
     std::vector<bool>(1,true))
 {
@@ -38,24 +53,44 @@ FE_FaceQ<dim,spacedim>::FE_FaceQ (const unsigned int degree)
       this->unit_face_support_points[0][d] = 0.5;
   else
     {
-      const double step = 1./this->degree;
-      Point<codim> p;
+      std::vector<Point<1> > points = get_QGaussLobatto_points(degree);
 
       unsigned int k=0;
       for (unsigned int iz=0; iz <= ((codim>2) ? this->degree : 0) ; ++iz)
         for (unsigned int iy=0; iy <= ((codim>1) ? this->degree : 0) ; ++iy)
           for (unsigned int ix=0; ix<=this->degree; ++ix)
             {
-              p(0) = ix * step;
+             Point<codim> p;
+             
+              p(0) = points[ix][0];
               if (codim>1)
-                p(1) = iy * step;
+                p(1) = points[iy][0];
               if (codim>2)
-                p(2) = iz * step;
+                p(2) = points[iz][0];
 
               this->unit_face_support_points[k++] = p;
             }
       AssertDimension (k, this->unit_face_support_points.size());
     }
+
+  // initialize unit support points
+  this->unit_support_points.resize(GeometryInfo<dim>::faces_per_cell*
+                                   this->unit_face_support_points.size());
+  const unsigned int n_face_dofs = this->unit_face_support_points.size();
+  for (unsigned int i=0; i<n_face_dofs; ++i)
+    for (unsigned int d=0; d<dim; ++d)
+      {
+        for (unsigned int e=0, c=0; e<dim; ++e)
+          if (d!=e)
+            {
+              this->unit_support_points[n_face_dofs*2*d+i][e] =
+                this->unit_face_support_points[i][c];
+              this->unit_support_points[n_face_dofs*(2*d+1)+i][e] =
+                this->unit_face_support_points[i][c];
+              this->unit_support_points[n_face_dofs*(2*d+1)+i][d] = 1;
+              ++c;
+            }
+      }
 }
 
 
@@ -86,6 +121,168 @@ FE_FaceQ<dim,spacedim>::get_name () const
 
 
 
+template <int dim, int spacedim>
+void
+FE_FaceQ<dim,spacedim>::
+get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
+                               FullMatrix<double>       &interpolation_matrix) const
+{
+  // this function is similar to the respective method in FE_Q
+
+  // this is only implemented, if the source FE is also a FE_FaceQ element
+  AssertThrow ((dynamic_cast<const FE_FaceQ<dim,spacedim> *>(&x_source_fe) != 0),
+               (typename FiniteElement<dim,spacedim>::
+                ExcInterpolationNotImplemented()));
+
+  Assert (interpolation_matrix.n() == this->dofs_per_face,
+          ExcDimensionMismatch (interpolation_matrix.n(),
+                                this->dofs_per_face));
+  Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
+          ExcDimensionMismatch (interpolation_matrix.m(),
+                                x_source_fe.dofs_per_face));
+
+  // ok, source is a FaceQ element, so we will be able to do the work
+  const FE_FaceQ<dim,spacedim> &source_fe
+    = dynamic_cast<const FE_FaceQ<dim,spacedim>&>(x_source_fe);
+
+  // Make sure that the element for which the DoFs should be constrained is
+  // the one with the higher polynomial degree.  Actually the procedure will
+  // work also if this assertion is not satisfied. But the matrices produced
+  // in that case might lead to problems in the hp procedures, which use this
+  // method.
+  Assert (this->dofs_per_face <= source_fe.dofs_per_face,
+          (typename FiniteElement<dim,spacedim>::
+           ExcInterpolationNotImplemented ()));
+
+  // generate a quadrature with the unit face support points. 
+  const Quadrature<dim-1> face_quadrature (source_fe.get_unit_face_support_points ());
+
+  // Rule of thumb for FP accuracy, that can be expected for a given
+  // polynomial degree.  This value is used to cut off values close to zero.
+  const double eps = 2e-13*(this->degree+1)*(dim-1);
+
+  // compute the interpolation matrix by simply taking the value at the
+  // support points.
+  for (unsigned int i=0; i<source_fe.dofs_per_face; ++i)
+    {
+      const Point<dim-1> &p = face_quadrature.point (i);
+
+      for (unsigned int j=0; j<this->dofs_per_face; ++j)
+        {
+          double matrix_entry = this->poly_space.compute_value (j, p);
+
+          // Correct the interpolated value. I.e. if it is close to 1 or 0,
+          // make it exactly 1 or 0. Unfortunately, this is required to avoid
+          // problems with higher order elements.
+          if (std::fabs (matrix_entry - 1.0) < eps)
+            matrix_entry = 1.0;
+          if (std::fabs (matrix_entry) < eps)
+            matrix_entry = 0.0;
+
+          interpolation_matrix(i,j) = matrix_entry;
+        }
+    }
+
+  // make sure that the row sum of each of the matrices is 1 at this
+  // point. this must be so since the shape functions sum up to 1
+  for (unsigned int j=0; j<source_fe.dofs_per_face; ++j)
+    {
+      double sum = 0.;
+
+      for (unsigned int i=0; i<this->dofs_per_face; ++i)
+        sum += interpolation_matrix(j,i);
+
+      Assert (std::fabs(sum-1) < eps, ExcInternalError());
+    }
+}
+
+
+
+template <int dim, int spacedim>
+void
+FE_FaceQ<dim,spacedim>::
+get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
+                                  const unsigned int        subface,
+                                  FullMatrix<double>       &interpolation_matrix) const
+{
+  // this function is similar to the respective method in FE_Q
+
+  Assert (interpolation_matrix.n() == this->dofs_per_face,
+          ExcDimensionMismatch (interpolation_matrix.n(),
+                                this->dofs_per_face));
+  Assert (interpolation_matrix.m() == x_source_fe.dofs_per_face,
+          ExcDimensionMismatch (interpolation_matrix.m(),
+                                x_source_fe.dofs_per_face));
+
+  // see if source is a FaceQ element
+  if (const FE_FaceQ<dim,spacedim> *source_fe
+      = dynamic_cast<const FE_FaceQ<dim,spacedim> *>(&x_source_fe))
+    {
+
+      // Make sure that the element for which the DoFs should be constrained
+      // is the one with the higher polynomial degree.  Actually the procedure
+      // will work also if this assertion is not satisfied. But the matrices
+      // produced in that case might lead to problems in the hp procedures,
+      // which use this method.
+      Assert (this->dofs_per_face <= source_fe->dofs_per_face,
+              (typename FiniteElement<dim,spacedim>::
+               ExcInterpolationNotImplemented ()));
+
+      // generate a quadrature with the unit face support points. 
+      const Quadrature<dim-1> face_quadrature (source_fe->get_unit_face_support_points ());
+
+      // Rule of thumb for FP accuracy, that can be expected for a given
+      // polynomial degree.  This value is used to cut off values close to
+      // zero.
+      const double eps = 2e-13*(this->degree+1)*(dim-1);
+
+      // compute the interpolation matrix by simply taking the value at the
+      // support points.
+      for (unsigned int i=0; i<source_fe->dofs_per_face; ++i)
+        {
+          const Point<dim-1> p =
+            GeometryInfo<dim-1>::child_to_cell_coordinates (face_quadrature.point(i),
+                                                            subface);
+
+          for (unsigned int j=0; j<this->dofs_per_face; ++j)
+            {
+              double matrix_entry = this->poly_space.compute_value (j, p);
+
+              // Correct the interpolated value. I.e. if it is close to 1 or 0,
+              // make it exactly 1 or 0. Unfortunately, this is required to avoid
+              // problems with higher order elements.
+              if (std::fabs (matrix_entry - 1.0) < eps)
+                matrix_entry = 1.0;
+              if (std::fabs (matrix_entry) < eps)
+                matrix_entry = 0.0;
+
+              interpolation_matrix(i,j) = matrix_entry;
+            }
+        }
+
+      // make sure that the row sum of each of the matrices is 1 at this
+      // point. this must be so since the shape functions sum up to 1
+      for (unsigned int j=0; j<source_fe->dofs_per_face; ++j)
+        {
+          double sum = 0.;
+
+          for (unsigned int i=0; i<this->dofs_per_face; ++i)
+            sum += interpolation_matrix(j,i);
+
+          Assert (std::fabs(sum-1) < eps, ExcInternalError());
+        }
+    }
+  else if (dynamic_cast<const FE_Nothing<dim> *>(&x_source_fe) != 0)
+    {
+      // nothing to do here, the FE_Nothing has no degrees of freedom anyway
+    }
+  else
+    AssertThrow (false,(typename FiniteElement<dim,spacedim>::
+                        ExcInterpolationNotImplemented()));
+}
+
+
+
 template <int dim, int spacedim>
 bool
 FE_FaceQ<dim,spacedim>::has_support_on_face (
@@ -96,6 +293,7 @@ FE_FaceQ<dim,spacedim>::has_support_on_face (
 }
 
 
+
 template <int dim, int spacedim>
 std::vector<unsigned int>
 FE_FaceQ<dim,spacedim>::get_dpo_vector (const unsigned int deg)
@@ -109,6 +307,41 @@ FE_FaceQ<dim,spacedim>::get_dpo_vector (const unsigned int deg)
 
 
 
+template <int dim, int spacedim>
+bool
+FE_FaceQ<dim,spacedim>::hp_constraints_are_implemented () const
+{
+  return true;
+}
+
+
+
+template <int dim, int spacedim>
+FiniteElementDomination::Domination
+FE_FaceQ<dim,spacedim>::
+compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const
+{
+  if (const FE_FaceQ<dim,spacedim> *fe_q_other
+      = dynamic_cast<const FE_FaceQ<dim,spacedim>*>(&fe_other))
+    {
+      if (this->degree < fe_q_other->degree)
+        return FiniteElementDomination::this_element_dominates;
+      else if (this->degree == fe_q_other->degree)
+        return FiniteElementDomination::either_element_can_dominate;
+      else
+        return FiniteElementDomination::other_element_dominates;
+    }
+  else if (dynamic_cast<const FE_Nothing<dim>*>(&fe_other) != 0)
+    {
+      // the FE_Nothing has no degrees of freedom and it is typically used in
+      // a context where we don't require any continuity along the interface
+      return FiniteElementDomination::no_requirements;
+    }
+
+  Assert (false, ExcNotImplemented());
+  return FiniteElementDomination::neither_element_dominates;
+}
+
 // explicit instantiations
 #include "fe_face.inst"
 
index 77aab44e1a89b79b4d393428da2e96086c4888c2..a43e3be528b3c054cf27988f54a2efea188ce3ec 100644 (file)
@@ -606,8 +606,7 @@ get_face_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe,
       for (unsigned int i=0; i<this->dofs_per_face; ++i)
         sum += interpolation_matrix(j,i);
 
-      Assert (std::fabs(sum-1) < 2e-13*this->degree*(dim-1),
-              ExcInternalError());
+      Assert (std::fabs(sum-1) < eps, ExcInternalError());
     }
 }
 
@@ -688,8 +687,7 @@ get_subface_interpolation_matrix (const FiniteElement<dim,spacedim> &x_source_fe
           for (unsigned int i=0; i<this->dofs_per_face; ++i)
             sum += interpolation_matrix(j,i);
 
-          Assert (std::fabs(sum-1) < 2e-13*this->degree*dim,
-                  ExcInternalError());
+          Assert (std::fabs(sum-1) < eps, ExcInternalError());
         }
     }
   else if (dynamic_cast<const FE_Nothing<dim> *>(&x_source_fe) != 0)
@@ -754,7 +752,7 @@ hp_line_dof_identities (const FiniteElement<dim,spacedim> &fe_other) const
     {
       // dofs are located along lines, so two dofs are identical if they are
       // located at identical positions. if we had only equidistant points, we
-      // could simple check for similarity like (i+1)*q == (j+1)*p, but we
+      // could simply check for similarity like (i+1)*q == (j+1)*p, but we
       // might have other support points (e.g. Gauss-Lobatto
       // points). Therefore, read the points in unit_support_points for the
       // first coordinate direction. We take the lexicographic ordering of the
@@ -988,11 +986,132 @@ FE_Q_Base<POLY,dim,spacedim>::initialize_quad_dof_index_permutation ()
 
 
 
+template <class POLY, int dim, int spacedim>
+unsigned int
+FE_Q_Base<POLY,dim,spacedim>::
+face_to_cell_index (const unsigned int face_index,
+                    const unsigned int face,
+                    const bool face_orientation,
+                    const bool face_flip,
+                    const bool face_rotation) const
+{
+  Assert (face_index < this->dofs_per_face,
+          ExcIndexRange(face_index, 0, this->dofs_per_face));
+  Assert (face < GeometryInfo<dim>::faces_per_cell,
+          ExcIndexRange(face, 0, GeometryInfo<dim>::faces_per_cell));
+
+//TODO: we could presumably solve the 3d case below using the
+// adjust_quad_dof_index_for_face_orientation_table field. for the
+// 2d case, we can't use adjust_line_dof_index_for_line_orientation_table
+// since that array is empty (presumably because we thought that
+// there are no flipped edges in 2d, but these can happen in
+// DoFTools::make_periodicity_constraints, for example). so we
+// would need to either fill this field, or rely on derived classes
+// implementing this function, as we currently do
+
+  // we need to distinguish between DoFs on vertices, lines and in 3d quads.
+  // do so in a sequence of if-else statements
+  if (face_index < this->first_face_line_index)
+    // DoF is on a vertex
+    {
+      // get the number of the vertex on the face that corresponds to this DoF,
+      // along with the number of the DoF on this vertex
+      const unsigned int face_vertex         = face_index / this->dofs_per_vertex;
+      const unsigned int dof_index_on_vertex = face_index % this->dofs_per_vertex;
+
+      // then get the number of this vertex on the cell and translate
+      // this to a DoF number on the cell
+      return (GeometryInfo<dim>::face_to_cell_vertices(face, face_vertex,
+                                                       face_orientation,
+                                                       face_flip,
+                                                       face_rotation)
+              * this->dofs_per_vertex
+              +
+              dof_index_on_vertex);
+    }
+  else if (face_index < this->first_face_quad_index)
+    // DoF is on a face
+    {
+      // do the same kind of translation as before. we need to only consider
+      // DoFs on the lines, i.e., ignoring those on the vertices
+      const unsigned int index = face_index - this->first_face_line_index;
+
+      const unsigned int face_line         = index / this->dofs_per_line;
+      const unsigned int dof_index_on_line = index % this->dofs_per_line;
+
+      // we now also need to adjust the line index for the case of
+      // face orientation, face flips, etc
+      unsigned int adjusted_dof_index_on_line;
+      switch (dim)
+      {
+      case 1:
+        Assert (false, ExcInternalError());
+
+      case 2:
+        // in 2d, only face_flip has a meaning. if it is set, consider
+        // dofs in reverse order
+        if (face_flip == false)
+          adjusted_dof_index_on_line = dof_index_on_line;
+        else
+          adjusted_dof_index_on_line = this->dofs_per_line - dof_index_on_line - 1;
+        break;
+
+      case 3:
+        // in 3d, things are difficult. someone will have to think
+        // about how this code here should look like, by drawing a bunch
+        // of pictures of how all the faces can look like with the various
+        // flips and rotations.
+        //
+        // that said, the Q2 case is easy enough to implement, as is the case
+        // where everything is in standard orientation
+        Assert ((this->dofs_per_line <= 1) ||
+                ((face_orientation == true) &&
+                 (face_flip == false) &&
+                 (face_rotation == false)),
+                ExcNotImplemented());
+        adjusted_dof_index_on_line = dof_index_on_line;
+        break;
+      }
+
+      return (this->first_line_index
+              + GeometryInfo<dim>::face_to_cell_lines(face, face_line,
+                                                      face_orientation,
+                                                      face_flip,
+                                                      face_rotation)
+              * this->dofs_per_line
+              +
+              adjusted_dof_index_on_line);
+    }
+  else
+    // DoF is on a quad
+    {
+      Assert (dim >= 3, ExcInternalError());
+
+      // ignore vertex and line dofs
+      const unsigned int index = face_index - this->first_face_quad_index;
+
+      // the same is true here as above for the 3d case -- someone will
+      // just have to draw a bunch of pictures. in the meantime,
+      // we can implement the Q2 case in which it is simple
+      Assert ((this->dofs_per_quad <= 1) ||
+              ((face_orientation == true) &&
+               (face_flip == false) &&
+               (face_rotation == false)),
+              ExcNotImplemented());
+      return (this->first_quad_index
+              + face * this->dofs_per_quad
+              + index);
+    }
+}
+
+
+
 
 template <class POLY, int dim, int spacedim>
 std::vector<unsigned int>
 FE_Q_Base<POLY,dim,spacedim>::get_dpo_vector(const unsigned int deg)
 {
+  AssertThrow(deg>0,ExcMessage("FE_Q needs to be of degree > 0."));
   std::vector<unsigned int> dpo(dim+1, 1U);
   for (unsigned int i=1; i<dpo.size(); ++i)
     dpo[i]=dpo[i-1]*(deg-1);
index 2f45064642d9fd443280e4f991af1864fedddb1f..2b5e504a5e0091aa56c9d686287f9a545c9432ac 100644 (file)
@@ -46,7 +46,10 @@ namespace
 
 
 template <int dim, int spacedim>
-FESystem<dim,spacedim>::InternalData::InternalData(const unsigned int n_base_elements):
+FESystem<dim,spacedim>::InternalData::InternalData(const unsigned int n_base_elements,
+                                                   const bool         compute_hessians)
+:
+  compute_hessians (compute_hessians),
   base_fe_datas(n_base_elements),
   base_fe_values_datas(n_base_elements)
 {}
@@ -745,6 +748,45 @@ FESystem<dim,spacedim>
 }
 
 
+template <int dim, int spacedim>
+unsigned int
+FESystem<dim,spacedim>::
+face_to_cell_index (const unsigned int face_dof_index,
+                    const unsigned int face,
+                    const bool face_orientation,
+                    const bool face_flip,
+                    const bool face_rotation) const
+{
+  // we need to ask the base elements how they want to translate
+  // the DoFs within their own numbering. thus, translate to
+  // the base element numbering and then back
+  const std::pair<std::pair<unsigned int, unsigned int>, unsigned int>
+  face_base_index = this->face_system_to_base_index(face_dof_index);
+
+  const unsigned int
+  base_face_to_cell_index
+  = this->base_element(face_base_index.first.first).face_to_cell_index (face_base_index.second,
+                                                                        face,
+                                                                        face_orientation,
+                                                                        face_flip,
+                                                                        face_rotation);
+
+  // it would be nice if we had a base_to_system_index function, but
+  // all that exists is a component_to_system_index function. we can't do
+  // this here because it won't work for non-primitive elements. consequently,
+  // simply do a loop over all dofs till we find whether it corresponds
+  // to the one we're interested in -- crude, maybe, but works for now
+  const std::pair<std::pair<unsigned int, unsigned int>, unsigned int>
+  target = std::make_pair (face_base_index.first, base_face_to_cell_index);
+  for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+    if (this->system_to_base_index(i) == target)
+      return i;
+
+  Assert (false, ExcInternalError());
+  return numbers::invalid_unsigned_int;
+}
+
+
 
 //---------------------------------------------------------------------------
 // Data field initialization
@@ -800,7 +842,8 @@ FESystem<dim,spacedim>::get_data (const UpdateFlags      flags_,
                                   const Quadrature<dim> &quadrature) const
 {
   UpdateFlags flags = flags_;
-  InternalData *data = new InternalData(this->n_base_elements());
+  InternalData *data = new InternalData(this->n_base_elements(),
+                                        flags & update_hessians);
 
   data->update_once = update_once (flags);
   data->update_each = update_each (flags);
@@ -811,7 +854,6 @@ FESystem<dim,spacedim>::get_data (const UpdateFlags      flags_,
   // finite differencing are required,
   // then initialize some objects for
   // that
-  data->compute_hessians = flags & update_hessians;
   if (data->compute_hessians)
     {
       // delete
@@ -887,14 +929,14 @@ FESystem<dim,spacedim>::get_face_data (
   const Quadrature<dim-1> &quadrature) const
 {
   UpdateFlags flags = flags_;
-  InternalData *data = new InternalData(this->n_base_elements());
+  InternalData *data = new InternalData(this->n_base_elements(),
+                                        flags & update_hessians);
 
   data->update_once = update_once (flags);
   data->update_each = update_each (flags);
   flags = data->update_once | data->update_each;
 
   UpdateFlags sub_flags = flags;
-  data->compute_hessians = flags & update_hessians;
   if (data->compute_hessians)
     {
       sub_flags = UpdateFlags (sub_flags ^ update_hessians);
@@ -939,14 +981,14 @@ FESystem<dim,spacedim>::get_subface_data (
   const Quadrature<dim-1> &quadrature) const
 {
   UpdateFlags flags = flags_;
-  InternalData *data = new InternalData(this->n_base_elements());
+  InternalData *data = new InternalData(this->n_base_elements(),
+                                        flags & update_hessians);
 
   data->update_once = update_once (flags);
   data->update_each = update_each (flags);
   flags = data->update_once | data->update_each;
 
   UpdateFlags sub_flags = flags;
-  data->compute_hessians = flags & update_hessians;
   if (data->compute_hessians)
     {
       sub_flags = UpdateFlags (sub_flags ^ update_hessians);
index 0602d5fd09a3a076ebc6cdb71c99a8aa0925bde4..a94336f66913db8c52b65fe0787968874e2d57db 100644 (file)
@@ -1641,12 +1641,10 @@ namespace internal
       scalars.resize (n_scalars);
       for (unsigned int component=0; component<n_scalars; ++component)
         {
-#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
-          scalars[component].dealii::FEValuesViews::Scalar<dim,spacedim>::~Scalar ();
-#else
+          // Use a typedef here to work around an issue with gcc-4.1:
           typedef dealii::FEValuesViews::Scalar<dim,spacedim> ScalarView;
           scalars[component].ScalarView::~ScalarView ();
-#endif
+
           new (&scalars[component])
           dealii::FEValuesViews::Scalar<dim,spacedim>(fe_values,
                                                       component);
@@ -1665,12 +1663,10 @@ namespace internal
       vectors.resize (n_vectors);
       for (unsigned int component=0; component<n_vectors; ++component)
         {
-#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
-          vectors[component].dealii::FEValuesViews::Vector<dim,spacedim>::~Vector ();
-#else
+          // Use a typedef here to work around an issue with gcc-4.1:
           typedef dealii::FEValuesViews::Vector<dim,spacedim> VectorView;
           vectors[component].VectorView::~VectorView ();
-#endif
+
           new (&vectors[component])
           dealii::FEValuesViews::Vector<dim,spacedim>(fe_values,
                                                       component);
@@ -1685,13 +1681,10 @@ namespace internal
       symmetric_second_order_tensors.resize(n_symmetric_second_order_tensors);
       for (unsigned int component = 0; component < n_symmetric_second_order_tensors; ++component)
         {
-#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
-          symmetric_second_order_tensors[component]
-          .dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim>::~SymmetricTensor();
-#else
+          // Use a typedef here to work around an issue with gcc-4.1:
           typedef dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim> SymmetricTensorView;
           symmetric_second_order_tensors[component].SymmetricTensorView::~SymmetricTensorView();
-#endif
+
           new (&symmetric_second_order_tensors[component])
           dealii::FEValuesViews::SymmetricTensor<2, dim, spacedim > (fe_values,
                                                                      component);
@@ -1707,13 +1700,10 @@ namespace internal
       second_order_tensors.resize(n_second_order_tensors);
       for (unsigned int component = 0; component < n_second_order_tensors; ++component)
         {
-#ifndef DEAL_II_EXPLICIT_DESTRUCTOR_BUG
-          second_order_tensors[component]
-          .dealii::FEValuesViews::Tensor<2, dim, spacedim>::~Tensor();
-#else
+          // Use a typedef here to work around an issue with gcc-4.1:
           typedef dealii::FEValuesViews::Tensor<2, dim, spacedim> TensorView;
           second_order_tensors[component].TensorView::~TensorView();
-#endif
+
           new (&second_order_tensors[component])
           dealii::FEValuesViews::Tensor<2, dim, spacedim > (fe_values,
                                                             component);
index 663d77482e3418f5a37b1f4ba7c2d2b01bf26f5d..18cb2b111045fd59d847b1ffcd54f81ffe349603 100644 (file)
@@ -696,7 +696,7 @@ MappingQ<dim,spacedim>::set_laplace_on_quad_vector(Table<2,double> &loqvs) const
   // one. check this
   for (unsigned int unit_point=0; unit_point<loqvs.n_rows(); ++unit_point)
     Assert(std::fabs(std::accumulate(loqvs[unit_point].begin(),
-                                     loqvs[unit_point].end(),0.)-1)<1e-13,
+                                     loqvs[unit_point].end(),0.)-1)<1e-12*this->degree*this->degree,
            ExcInternalError());
 }
 
index 4e005c2f8f2deca4614ea6ae997db9981e03b75c..c8ba7374746cc74fef9a4a8b1b01953d25fd7886 100644 (file)
@@ -18,6 +18,9 @@
 #include <deal.II/base/quadrature_lib.h>
 #include <deal.II/lac/vector.h>
 #include <deal.II/lac/petsc_vector.h>
+#include <deal.II/lac/trilinos_vector.h>
+#include <deal.II/lac/trilinos_block_vector.h>
+#include <deal.II/lac/trilinos_parallel_block_vector.h>
 #include <deal.II/grid/tria_iterator.h>
 #include <deal.II/dofs/dof_handler.h>
 #include <deal.II/dofs/dof_accessor.h>
index dd64c5497fdda71d773f7fa6d49d91992d2e8828..439ef92f5174050fc0b2e778f10408935be1e879 100644 (file)
@@ -25,6 +25,17 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
     template class MappingQEulerian<deal_II_dimension,
                                    PETScWrappers::MPI::Vector, deal_II_space_dimension>;
 #  endif   
+#  ifdef DEAL_II_WITH_TRILINOS
+    template class MappingQEulerian<deal_II_dimension,
+                                    TrilinosWrappers::Vector, deal_II_space_dimension>;
+    template class MappingQEulerian<deal_II_dimension,
+                                    TrilinosWrappers::MPI::Vector, deal_II_space_dimension>;
+    template class MappingQEulerian<deal_II_dimension,
+                                    TrilinosWrappers::BlockVector, deal_II_space_dimension>;
+    template class MappingQEulerian<deal_II_dimension,
+                                    TrilinosWrappers::MPI::BlockVector, deal_II_space_dimension>;
+#  endif
+
 #endif
   }
 
index e834ca633467cd8a19b156e2a6a46535d03e7bf9..298de0aac39b33d15ef1a9f547927869c2bd706c 100644 (file)
@@ -46,3784 +46,3794 @@ DEAL_II_NAMESPACE_OPEN
 
 
 
-namespace
+namespace GridGenerator
 {
-  // Corner points of the cube [-1,1]^3
-  const Point<3> hexahedron[8] =
+  namespace
   {
-    Point<3>(-1,-1,-1),
-    Point<3>(+1,-1,-1),
-    Point<3>(-1,+1,-1),
-    Point<3>(+1,+1,-1),
-    Point<3>(-1,-1,+1),
-    Point<3>(+1,-1,+1),
-    Point<3>(-1,+1,+1),
-    Point<3>(+1,+1,+1)
-  };
-
-  // Octahedron inscribed in the cube
-  // [-1,1]^3
-  const Point<3> octahedron[6] =
-  {
-    Point<3>(-1, 0, 0),
-    Point<3>( 1, 0, 0),
-    Point<3>( 0,-1, 0),
-    Point<3>( 0, 1, 0),
-    Point<3>( 0, 0,-1),
-    Point<3>( 0, 0, 1)
-  };
-}
-
+    // Corner points of the cube [-1,1]^3
+    const Point<3> hexahedron[8] =
+    {
+      Point<3>(-1,-1,-1),
+      Point<3>(+1,-1,-1),
+      Point<3>(-1,+1,-1),
+      Point<3>(+1,+1,-1),
+      Point<3>(-1,-1,+1),
+      Point<3>(+1,-1,+1),
+      Point<3>(-1,+1,+1),
+      Point<3>(+1,+1,+1)
+    };
 
-template <int dim, int spacedim>
-void
-GridGenerator::hyper_rectangle (Triangulation<dim,spacedim> &tria,
-                                const Point<spacedim>   &p_1,
-                                const Point<spacedim>   &p_2,
-                                const bool          colorize)
-{
-  // First, normalize input such that
-  // p1 is lower in all coordinate directions.
-  Point<spacedim> p1(p_1);
-  Point<spacedim> p2(p_2);
+    // Octahedron inscribed in the cube
+    // [-1,1]^3
+    const Point<3> octahedron[6] =
+    {
+      Point<3>(-1, 0, 0),
+      Point<3>( 1, 0, 0),
+      Point<3>( 0,-1, 0),
+      Point<3>( 0, 1, 0),
+      Point<3>( 0, 0,-1),
+      Point<3>( 0, 0, 1)
+    };
 
-  for (unsigned int i=0; i<spacedim; ++i)
-    if (p1(i) > p2(i))
-      std::swap (p1(i), p2(i));
 
-  std::vector<Point<spacedim> > vertices (GeometryInfo<dim>::vertices_per_cell);
-  switch (dim)
+    /**
+     * Perform the action specified by the @p colorize flag of the
+     * hyper_rectangle() function of this class.
+     */
+    template <int dim, int spacedim>
+    void
+    colorize_hyper_rectangle (Triangulation<dim,spacedim> &tria)
     {
-    case 1:
-      vertices[0] = p1;
-      vertices[1] = p2;
-      break;
-    case 2:
-      vertices[0] = vertices[1] = p1;
-      vertices[2] = vertices[3] = p2;
-
-      vertices[1](0) = p2(0);
-      vertices[2](0) = p1(0);
-      break;
-    case 3:
-      vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
-      vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
+      // there is nothing to do in 1d
+      if (dim > 1)
+        {
+          // there is only one cell, so
+          // simple task
+          const typename Triangulation<dim,spacedim>::cell_iterator
+          cell = tria.begin();
+          for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+            cell->face(f)->set_boundary_indicator (f);
+        }
+    }
 
-      vertices[1](0) = p2(0);
-      vertices[2](1) = p2(1);
-      vertices[3](0) = p2(0);
-      vertices[3](1) = p2(1);
 
-      vertices[4](0) = p1(0);
-      vertices[4](1) = p1(1);
-      vertices[5](1) = p1(1);
-      vertices[6](0) = p1(0);
 
-      break;
-    default:
-      Assert (false, ExcNotImplemented ());
+    void
+    colorize_subdivided_hyper_rectangle (Triangulation<1> &tria,
+                                         const Point<1> &,
+                                         const Point<1> &,
+                                         const double)
+    {
+      for (Triangulation<1>::cell_iterator cell = tria.begin();
+           cell != tria.end(); ++cell)
+        if (cell->center()(0) > 0)
+          cell->set_material_id(1);
+      // boundary indicators are set to
+      // 0 (left) and 1 (right) by default.
     }
 
-  // Prepare cell data
-  std::vector<CellData<dim> > cells (1);
-  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
-    cells[0].vertices[i] = i;
-  cells[0].material_id = 0;
 
-  tria.create_triangulation (vertices, cells, SubCellData());
 
-  // Assign boundary indicators
-  if (colorize)
-    colorize_hyper_rectangle (tria);
-}
+    template <int dim>
+    void
+    colorize_subdivided_hyper_rectangle (Triangulation<dim> &tria,
+                                         const Point<dim>   &p1,
+                                         const Point<dim>   &p2,
+                                         const double        epsilon)
+    {
 
+      // run through all faces and check
+      // if one of their center coordinates matches
+      // one of the corner points. Comparisons
+      // are made using an epsilon which
+      // should be smaller than the smallest cell
+      // diameter.
 
+      typename Triangulation<dim>::face_iterator face = tria.begin_face(),
+                                                 endface = tria.end_face();
+      for (; face!=endface; ++face)
+        {
+          if (face->boundary_indicator() == 0)
+            {
+              const Point<dim> center (face->center());
+              if (std::abs(center(0)-p1[0]) < epsilon)
+                face->set_boundary_indicator(0);
+              else if (std::abs(center(0) - p2[0]) < epsilon)
+                face->set_boundary_indicator(1);
+              else if (dim > 1 && std::abs(center(1) - p1[1]) < epsilon)
+                face->set_boundary_indicator(2);
+              else if (dim > 1 && std::abs(center(1) - p2[1]) < epsilon)
+                face->set_boundary_indicator(3);
+              else if (dim > 2 && std::abs(center(2) - p1[2]) < epsilon)
+                face->set_boundary_indicator(4);
+              else if (dim > 2 && std::abs(center(2) - p2[2]) < epsilon)
+                face->set_boundary_indicator(5);
+              else
+                // triangulation says it
+                // is on the boundary,
+                // but we could not find
+                // on which boundary.
+                Assert (false, ExcInternalError());
 
-template <int dim, int spacedim>
-void
-GridGenerator::colorize_hyper_rectangle (Triangulation<dim,spacedim> &tria)
-{
-  // there is nothing to do in 1d
-  if (dim > 1)
-    {
-      // there is only one cell, so
-      // simple task
-      const typename Triangulation<dim,spacedim>::cell_iterator
-      cell = tria.begin();
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-        cell->face(f)->set_boundary_indicator (f);
+            }
+        }
+      for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
+           cell != tria.end(); ++cell)
+        {
+          char id = 0;
+          for (unsigned int d=0; d<dim; ++d)
+            if (cell->center()(d) > 0) id += 1 << d;
+          cell->set_material_id(id);
+        }
     }
-}
-
 
 
-template <int dim, int spacedim>
-void GridGenerator::hyper_cube (Triangulation<dim,spacedim> &tria,
-                                const double                 left,
-                                const double                 right)
-{
-  Assert (left < right,
-          ExcMessage ("Invalid left-to-right bounds of hypercube"));
-
-  Point<spacedim> p1;
-  Point<spacedim> p2;
+    /**
+     * Assign boundary number zero to the inner shell boundary and 1 to the
+     * outer.
+     */
+    void colorize_hyper_shell (Triangulation<1> &,
+                               const Point<1> &,
+                               const double,
+                               const double)
+    {
+      Assert (false, ExcNotImplemented());
+    }
 
-  p1(spacedim-1) = 0;
-  p2(spacedim-1) = 0;
 
-  for (unsigned int i=0; i<dim; ++i)
+    /**
+     * Assign boundary number zero to the inner shell boundary and 1 to the
+     * outer.
+     */
+    void
+    colorize_hyper_shell (Triangulation<2> &tria,
+                          const Point<2> &,
+                          const double,
+                          const double)
     {
-      p1(i) = left;
-      p2(i) = right;
+      // In spite of receiving geometrical
+      // data, we do this only based on
+      // topology.
+
+      // For the mesh based on  cube,
+      // this is highly irregular
+      for (Triangulation<2>::cell_iterator cell = tria.begin ();
+           cell != tria.end (); ++cell)
+        {
+          Assert(cell->face(2)->at_boundary(), ExcInternalError());
+          cell->face (2)->set_boundary_indicator (1);
+        }
     }
-  hyper_rectangle (tria, p1, p2);
-}
 
 
+    /**
+     * Assign boundary number zero to the inner shell boundary and 1 to the
+     * outer.
+     */
+    void
+    colorize_hyper_shell (Triangulation<3> &tria,
+                          const Point<3> &,
+                          const double,
+                          const double)
+    {
+      // the following uses a good amount
+      // of knowledge about the
+      // orientation of cells. this is
+      // probably not good style...
+      if (tria.n_cells() == 6)
+        {
+          Triangulation<3>::cell_iterator cell = tria.begin();
 
-void
-GridGenerator::moebius (
-  Triangulation<3>  &tria,
-  const size_type      n_cells,
-  const unsigned int   n_rotations,
-  const double         R,
-  const double         r)
-{
-  const unsigned int dim=3;
-  Assert (n_cells>4, ExcMessage("More than 4 cells are needed to create a moebius grid."));
-  Assert (r>0 && R>0, ExcMessage("Outer and inner radius must be positive."));
-  Assert (R>r, ExcMessage("Outer radius must be greater than inner radius."));
+          cell->face(4)->set_boundary_indicator(1);
+          Assert (cell->face(4)->at_boundary(), ExcInternalError());
 
+          (++cell)->face(2)->set_boundary_indicator(1);
+          Assert (cell->face(2)->at_boundary(), ExcInternalError());
 
-  std::vector<Point<dim> > vertices (4*n_cells);
-  double beta_step=n_rotations*numbers::PI/2.0/n_cells;
-  double alpha_step=2.0*numbers::PI/n_cells;
+          (++cell)->face(2)->set_boundary_indicator(1);
+          Assert (cell->face(2)->at_boundary(), ExcInternalError());
 
-  for (size_type i=0; i<n_cells; ++i)
-    for (unsigned int j=0; j<4; ++j)
-      {
-        vertices[4*i+j][0]=R*std::cos(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::cos(i*alpha_step);
-        vertices[4*i+j][1]=R*std::sin(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::sin(i*alpha_step);
-        vertices[4*i+j][2]=r*std::sin(i*beta_step+j*numbers::PI/2.0);
-      }
+          (++cell)->face(0)->set_boundary_indicator(1);
+          Assert (cell->face(0)->at_boundary(), ExcInternalError());
 
-  size_type offset=0;
+          (++cell)->face(2)->set_boundary_indicator(1);
+          Assert (cell->face(2)->at_boundary(), ExcInternalError());
 
-  std::vector<CellData<dim> > cells (n_cells);
-  for (size_type i=0; i<n_cells; ++i)
-    {
-      for (unsigned int j=0; j<2; ++j)
+          (++cell)->face(0)->set_boundary_indicator(1);
+          Assert (cell->face(0)->at_boundary(), ExcInternalError());
+        }
+      else if (tria.n_cells() == 12)
         {
-          cells[i].vertices[0+4*j]=offset+0+4*j;
-          cells[i].vertices[1+4*j]=offset+3+4*j;
-          cells[i].vertices[2+4*j]=offset+2+4*j;
-          cells[i].vertices[3+4*j]=offset+1+4*j;
+          // again use some internal
+          // knowledge
+          for (Triangulation<3>::cell_iterator cell = tria.begin();
+               cell != tria.end(); ++cell)
+            {
+              Assert (cell->face(5)->at_boundary(), ExcInternalError());
+              cell->face(5)->set_boundary_indicator(1);
+            }
+        }
+      else if (tria.n_cells() == 96)
+        {
+          // the 96-cell hypershell is
+          // based on a once refined
+          // 12-cell mesh. consequently,
+          // since the outer faces all
+          // are face_no==5 above, so
+          // they are here (unless they
+          // are in the interior). Use
+          // this to assign boundary
+          // indicators, but also make
+          // sure that we encounter
+          // exactly 48 such faces
+          unsigned int count = 0;
+          for (Triangulation<3>::cell_iterator cell = tria.begin();
+               cell != tria.end(); ++cell)
+            if (cell->face(5)->at_boundary())
+              {
+                cell->face(5)->set_boundary_indicator(1);
+                ++count;
+              }
+          Assert (count == 48, ExcInternalError());
         }
-      offset+=4;
-      cells[i].material_id=0;
+      else
+        Assert (false, ExcNotImplemented());
     }
 
-  // now correct the last four vertices
-  cells[n_cells-1].vertices[4]=(0+n_rotations)%4;
-  cells[n_cells-1].vertices[5]=(3+n_rotations)%4;
-  cells[n_cells-1].vertices[6]=(2+n_rotations)%4;
-  cells[n_cells-1].vertices[7]=(1+n_rotations)%4;
 
-  GridReordering<dim>::invert_all_cells_of_negative_grid(vertices,cells);
-  tria.create_triangulation_compatibility (vertices, cells, SubCellData());
-}
 
+    /**
+     * Assign boundary number zero the inner shell boundary, one to the outer
+     * shell boundary, two to the face with x=0, three to the face with y=0,
+     * four to the face with z=0.
+     */
+    void
+    colorize_quarter_hyper_shell(Triangulation<3> &tria,
+                                 const Point<3> &center,
+                                 const double inner_radius,
+                                 const double outer_radius)
+    {
+      if (tria.n_cells() != 3)
+        AssertThrow (false, ExcNotImplemented());
 
+      double middle = (outer_radius-inner_radius)/2e0 + inner_radius;
+      double eps = 1e-3*middle;
+      Triangulation<3>::cell_iterator cell = tria.begin();
 
-void
-GridGenerator::torus (Triangulation<2,3>  &tria,
-                      const double         R,
-                      const double         r)
-{
-  Assert (R>r, ExcMessage("Outer radius must be greater than inner radius."));
-
-  const unsigned int dim=2;
-  const unsigned int spacedim=3;
-  std::vector<Point<spacedim> > vertices (16);
-
-  vertices[0]=Point<spacedim>(R-r,0,0);
-  vertices[1]=Point<spacedim>(R,-r,0);
-  vertices[2]=Point<spacedim>(R+r,0,0);
-  vertices[3]=Point<spacedim>(R, r,0);
-  vertices[4]=Point<spacedim>(0,0,R-r);
-  vertices[5]=Point<spacedim>(0,-r,R);
-  vertices[6]=Point<spacedim>(0,0,R+r);
-  vertices[7]=Point<spacedim>(0,r,R);
-  vertices[8]=Point<spacedim>(-(R-r),0,0);
-  vertices[9]=Point<spacedim>(-R,-r,0);
-  vertices[10]=Point<spacedim>(-(R+r),0,0);
-  vertices[11]=Point<spacedim>(-R, r,0);
-  vertices[12]=Point<spacedim>(0,0,-(R-r));
-  vertices[13]=Point<spacedim>(0,-r,-R);
-  vertices[14]=Point<spacedim>(0,0,-(R+r));
-  vertices[15]=Point<spacedim>(0,r,-R);
-
-  std::vector<CellData<dim> > cells (16);
-  //Right Hand Orientation
-  cells[0].vertices[0] =  0;
-  cells[0].vertices[1] =  4;
-  cells[0].vertices[2] =  7;
-  cells[0].vertices[3] =  3;
-  cells[0].material_id = 0;
-
-  cells[1].vertices[0] =  1;
-  cells[1].vertices[1] =  5;
-  cells[1].vertices[2] =  4;
-  cells[1].vertices[3] =  0;
-  cells[1].material_id = 0;
-
-  cells[2].vertices[0] =  2;
-  cells[2].vertices[1] =  6;
-  cells[2].vertices[2] =  5;
-  cells[2].vertices[3] =  1;
-  cells[2].material_id = 0;
-
-  cells[3].vertices[0] =  3;
-  cells[3].vertices[1] =  7;
-  cells[3].vertices[2] =  6;
-  cells[3].vertices[3] =  2;
-  cells[3].material_id = 0;
-
-  cells[4].vertices[0] =  4;
-  cells[4].vertices[1] =  8;
-  cells[4].vertices[2] =  11;
-  cells[4].vertices[3] =  7;
-  cells[4].material_id = 0;
-
-  cells[5].vertices[0] =  5;
-  cells[5].vertices[1] =  9;
-  cells[5].vertices[2] =  8;
-  cells[5].vertices[3] =  4;
-  cells[5].material_id = 0;
-
-  cells[6].vertices[0] =  6;
-  cells[6].vertices[1] =  10;
-  cells[6].vertices[2] =  9;
-  cells[6].vertices[3] =  5;
-  cells[6].material_id = 0;
-
-  cells[7].vertices[0] =  7;
-  cells[7].vertices[1] =  11;
-  cells[7].vertices[2] =  10;
-  cells[7].vertices[3] =  6;
-  cells[7].material_id = 0;
-
-  cells[8].vertices[0] =  8;
-  cells[8].vertices[1] =  12;
-  cells[8].vertices[2] =  15;
-  cells[8].vertices[3] =  11;
-  cells[8].material_id = 0;
-
-  cells[9].vertices[0] =  9;
-  cells[9].vertices[1] =  13;
-  cells[9].vertices[2] =  12;
-  cells[9].vertices[3] =  8;
-  cells[9].material_id = 0;
-
-  cells[10].vertices[0] =  10;
-  cells[10].vertices[1] =  14;
-  cells[10].vertices[2] =  13;
-  cells[10].vertices[3] =  9;
-  cells[10].material_id = 0;
-
-  cells[11].vertices[0] =  11;
-  cells[11].vertices[1] =  15;
-  cells[11].vertices[2] =  14;
-  cells[11].vertices[3] =  10;
-  cells[11].material_id = 0;
-
-  cells[12].vertices[0] =  12;
-  cells[12].vertices[1] =  0;
-  cells[12].vertices[2] =  3;
-  cells[12].vertices[3] =  15;
-  cells[12].material_id = 0;
-
-  cells[13].vertices[0] =  13;
-  cells[13].vertices[1] =  1;
-  cells[13].vertices[2] =  0;
-  cells[13].vertices[3] =  12;
-  cells[13].material_id = 0;
-
-  cells[14].vertices[0] =  14;
-  cells[14].vertices[1] =  2;
-  cells[14].vertices[2] =  1;
-  cells[14].vertices[3] =  13;
-  cells[14].material_id = 0;
-
-  cells[15].vertices[0] =  15;
-  cells[15].vertices[1] =  3;
-  cells[15].vertices[2] =  2;
-  cells[15].vertices[3] =  14;
-  cells[15].material_id = 0;
-
-  // Must call this to be able to create a
-  // correct triangulation in dealii, read
-  // GridReordering<> doc
-  GridReordering<dim,spacedim>::reorder_cells (cells);
-  tria.create_triangulation_compatibility (vertices, cells, SubCellData());
-}
+      for (; cell!=tria.end(); ++cell)
+        for (unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
+          {
+            if (!cell->face(f)->at_boundary())
+              continue;
 
+            double radius = cell->face(f)->center().norm() - center.norm();
+            if (std::fabs(cell->face(f)->center()(0)) < eps ) // x = 0 set boundary 2
+              {
+                cell->face(f)->set_boundary_indicator(2);
+                for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
+                  if (cell->face(f)->line(j)->at_boundary())
+                    if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
+                      cell->face(f)->line(j)->set_boundary_indicator(2);
+              }
+            else if (std::fabs(cell->face(f)->center()(1)) < eps) // y = 0 set boundary 3
+              {
+                cell->face(f)->set_boundary_indicator(3);
+                for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
+                  if (cell->face(f)->line(j)->at_boundary())
+                    if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
+                      cell->face(f)->line(j)->set_boundary_indicator(3);
+              }
+            else if (std::fabs(cell->face(f)->center()(2)) < eps ) // z = 0 set boundary 4
+              {
+                cell->face(f)->set_boundary_indicator(4);
+                for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
+                  if (cell->face(f)->line(j)->at_boundary())
+                    if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
+                      cell->face(f)->line(j)->set_boundary_indicator(4);
+              }
+            else if (radius < middle) // inner radius set boundary 0
+              {
+                cell->face(f)->set_boundary_indicator(0);
+                for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
+                  if (cell->face(f)->line(j)->at_boundary())
+                    if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) < eps)
+                      cell->face(f)->line(j)->set_boundary_indicator(0);
+              }
+            else if (radius > middle) // outer radius set boundary 1
+              {
+                cell->face(f)->set_boundary_indicator(1);
+                for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
+                  if (cell->face(f)->line(j)->at_boundary())
+                    if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) < eps)
+                      cell->face(f)->line(j)->set_boundary_indicator(1);
+              }
+            else
+              AssertThrow (false, ExcInternalError());
+          }
+    }
 
-// Implementation for 2D only
-template<>
-void
-GridGenerator::parallelogram (Triangulation<2>  &tria,
-                              const Point<2> (&corners)[2],
-                              const bool         colorize)
-{
-  std::vector<Point<2> > vertices (GeometryInfo<2>::vertices_per_cell);
-
-  vertices[1] = corners[0];
-  vertices[2] = corners[1];
-  vertices[3] = vertices[1] + vertices[2];
-  // Prepare cell data
-  std::vector<CellData<2> > cells (1);
-  for (unsigned int i=0; i<GeometryInfo<2>::vertices_per_cell; ++i)
-    cells[0].vertices[i] = i;
-  cells[0].material_id = 0;
-
-  tria.create_triangulation (vertices, cells, SubCellData());
-
-  // Assign boundary indicators
-  if (colorize)
-    colorize_hyper_rectangle (tria);
-}
+  }
 
 
-template<>
-void
-GridGenerator::parallelogram (Triangulation<2>  &tria,
-                              const Tensor<2,2> &corners,
-                              const bool         colorize)
-{
-  // simply pass everything to the other function of same name
-  const Point<2> x[2] = { corners[0], corners[1] };
-  parallelogram (tria, x, colorize);
-}
+  template <int dim, int spacedim>
+  void
+  hyper_rectangle (Triangulation<dim,spacedim> &tria,
+                   const Point<spacedim>   &p_1,
+                   const Point<spacedim>   &p_2,
+                   const bool          colorize)
+  {
+    // First, normalize input such that
+    // p1 is lower in all coordinate directions.
+    Point<spacedim> p1(p_1);
+    Point<spacedim> p2(p_2);
 
+    for (unsigned int i=0; i<spacedim; ++i)
+      if (p1(i) > p2(i))
+        std::swap (p1(i), p2(i));
 
+    std::vector<Point<spacedim> > vertices (GeometryInfo<dim>::vertices_per_cell);
+    switch (dim)
+      {
+      case 1:
+        vertices[0] = p1;
+        vertices[1] = p2;
+        break;
+      case 2:
+        vertices[0] = vertices[1] = p1;
+        vertices[2] = vertices[3] = p2;
+
+        vertices[1](0) = p2(0);
+        vertices[2](0) = p1(0);
+        break;
+      case 3:
+        vertices[0] = vertices[1] = vertices[2] = vertices[3] = p1;
+        vertices[4] = vertices[5] = vertices[6] = vertices[7] = p2;
+
+        vertices[1](0) = p2(0);
+        vertices[2](1) = p2(1);
+        vertices[3](0) = p2(0);
+        vertices[3](1) = p2(1);
+
+        vertices[4](0) = p1(0);
+        vertices[4](1) = p1(1);
+        vertices[5](1) = p1(1);
+        vertices[6](0) = p1(0);
+
+        break;
+      default:
+        Assert (false, ExcNotImplemented ());
+      }
 
-// Parallelepiped implementation in 1d, 2d, and 3d. @note The
-// implementation in 1d is similar to hyper_rectangle(), and in 2d is
-// similar to parallelogram().
-//
-// The GridReordering::reorder_grid is made use of towards the end of
-// this function. Thus the triangulation is explicitly constructed for
-// all dim here since it is slightly different in that respect
-// (cf. hyper_rectangle(), parallelogram()).
-template<int dim>
-void
-GridGenerator::parallelepiped (Triangulation<dim>  &tria,
-                               const Point<dim>   (&corners) [dim],
-                               const bool           colorize)
-{
-  // Check that none of the user defined vertices overlap
-  for (unsigned int i=0; i<dim; ++i)
-    for (unsigned int j=i+1; j<dim; ++j)
-      Assert ((corners[i]!=corners[j]),
-              ExcMessage ("Invalid distance between corner points of parallelepiped."));
+    // Prepare cell data
+    std::vector<CellData<dim> > cells (1);
+    for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+      cells[0].vertices[i] = i;
+    cells[0].material_id = 0;
 
-  // Note: vertex[0] is the origin and is initialised as so here:
-  std::vector<Point<dim> > vertices (GeometryInfo<dim>::vertices_per_cell);
+    tria.create_triangulation (vertices, cells, SubCellData());
 
-  switch (dim)
-    {
-      // A line (1d parallelepiped)
-    case 1:
-      vertices[1] = corners[0];
-      break;
+    // Assign boundary indicators
+    if (colorize)
+      colorize_hyper_rectangle (tria);
+  }
 
-      // A parallelogram (2d parallelepiped)
-    case 2:
-      // assign corners to vertices:
-      vertices[1] = corners[0];
-      vertices[2] = corners[1];
 
-      // compose the remaining vertex:
-      vertices[3] = vertices[1] + vertices[2];
-      break;
+  template <int dim, int spacedim>
+  void hyper_cube (Triangulation<dim,spacedim> &tria,
+                   const double                 left,
+                   const double                 right)
+  {
+    Assert (left < right,
+            ExcMessage ("Invalid left-to-right bounds of hypercube"));
 
-      // A parallelepiped (3d parallelepiped)
-    case 3:
-      // assign corners to vertices:
-      vertices[1] = corners[0];
-      vertices[2] = corners[1];
-      vertices[4] = corners[2];
-
-      // compose the remaining vertices:
-      vertices[3] = vertices[1] + vertices[2];
-      vertices[5] = vertices[1] + vertices[4];
-      vertices[6] = vertices[2] + vertices[4];
-      vertices[7] = vertices[1] + vertices[2] + vertices[4];
-      break;
+    Point<spacedim> p1;
+    Point<spacedim> p2;
 
-    default:
-      Assert (false, ExcNotImplemented());
-    }
+    p1(spacedim-1) = 0;
+    p2(spacedim-1) = 0;
 
-  // Prepare cell data and wipe material identity
-  std::vector<CellData<dim> > cells (1);
-  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
-    cells[0].vertices[i] = i;
-  cells[0].material_id = 0;
+    for (unsigned int i=0; i<dim; ++i)
+      {
+        p1(i) = left;
+        p2(i) = right;
+      }
+    hyper_rectangle (tria, p1, p2);
+  }
 
-  // Check ordering of vertices and create triangulation
-  GridReordering<dim>::reorder_cells (cells);
-  tria.create_triangulation (vertices, cells, SubCellData());
 
-  // Finally assign boundary indicators according to hyper_rectangle
-  if (colorize)
-    colorize_hyper_rectangle (tria);
-}
 
-template<int dim>
-void
-GridGenerator::subdivided_parallelepiped (Triangulation<dim>  &tria,
-                                          const size_type      n_subdivisions,
-                                          const Point<dim>   (&corners) [dim],
-                                          const bool           colorize)
-{
-  // Equalise number of subdivisions in each dim-direction, heir
-  // validity will be checked later
-  size_type (n_subdivisions_) [dim];
-  for (unsigned int i=0; i<dim; ++i)
-    n_subdivisions_[i] = n_subdivisions;
-
-  // and call the function below
-  GridGenerator::subdivided_parallelepiped (tria, n_subdivisions_,
-                                            corners,
-                                            colorize);
-}
+  void
+  moebius (Triangulation<3>  &tria,
+           const unsigned int      n_cells,
+           const unsigned int   n_rotations,
+           const double         R,
+           const double         r)
+  {
+    const unsigned int dim=3;
+    Assert (n_cells>4, ExcMessage("More than 4 cells are needed to create a moebius grid."));
+    Assert (r>0 && R>0, ExcMessage("Outer and inner radius must be positive."));
+    Assert (R>r, ExcMessage("Outer radius must be greater than inner radius."));
 
-template<int dim>
-void
-GridGenerator::subdivided_parallelepiped (Triangulation<dim>  &tria,
-                                          const size_type    ( n_subdivisions) [dim],
-                                          const Point<dim>   (&corners) [dim],
-                                          const bool           colorize)
-{
-  // Zero n_subdivisions is the origin only, which makes no sense
-  for (unsigned int i=0; i<dim; ++i)
-    Assert (n_subdivisions[i]>0, ExcInvalidRepetitions(n_subdivisions[i]));
 
-  // Check corners do not overlap (unique)
-  for (unsigned int i=0; i<dim; ++i)
-    for (unsigned int j=i+1; j<dim; ++j)
-      Assert ((corners[i]!=corners[j]),
-              ExcMessage ("Invalid distance between corner points of parallelepiped."));
+    std::vector<Point<dim> > vertices (4*n_cells);
+    double beta_step=n_rotations*numbers::PI/2.0/n_cells;
+    double alpha_step=2.0*numbers::PI/n_cells;
 
-  // Create a list of points
-  Point<dim> (delta) [dim];
+    for (unsigned int i=0; i<n_cells; ++i)
+      for (unsigned int j=0; j<4; ++j)
+        {
+          vertices[4*i+j][0]=R*std::cos(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::cos(i*alpha_step);
+          vertices[4*i+j][1]=R*std::sin(i*alpha_step)+r*std::cos(i*beta_step+j*numbers::PI/2.0)*std::sin(i*alpha_step);
+          vertices[4*i+j][2]=r*std::sin(i*beta_step+j*numbers::PI/2.0);
+        }
 
-  for (unsigned int i=0; i<dim; ++i)
-    delta[i] = corners[i]/n_subdivisions[i];
-  std::vector<Point<dim> > points;
+    unsigned int offset=0;
 
-  switch (dim)
-    {
-    case 1:
-      for (size_type x=0; x<=n_subdivisions[0]; ++x)
-        points.push_back (Point<dim> (x*delta[0]));
-      break;
+    std::vector<CellData<dim> > cells (n_cells);
+    for (unsigned int i=0; i<n_cells; ++i)
+      {
+        for (unsigned int j=0; j<2; ++j)
+          {
+            cells[i].vertices[0+4*j]=offset+0+4*j;
+            cells[i].vertices[1+4*j]=offset+3+4*j;
+            cells[i].vertices[2+4*j]=offset+2+4*j;
+            cells[i].vertices[3+4*j]=offset+1+4*j;
+          }
+        offset+=4;
+        cells[i].material_id=0;
+      }
 
-    case 2:
-      for (size_type y=0; y<=n_subdivisions[1]; ++y)
-        for (size_type x=0; x<=n_subdivisions[0]; ++x)
-          points.push_back (Point<dim> (x*delta[0] + y*delta[1]));
-      break;
+    // now correct the last four vertices
+    cells[n_cells-1].vertices[4]=(0+n_rotations)%4;
+    cells[n_cells-1].vertices[5]=(3+n_rotations)%4;
+    cells[n_cells-1].vertices[6]=(2+n_rotations)%4;
+    cells[n_cells-1].vertices[7]=(1+n_rotations)%4;
 
-    case 3:
-      for (size_type z=0; z<=n_subdivisions[2]; ++z)
-        for (size_type y=0; y<=n_subdivisions[1]; ++y)
-          for (size_type x=0; x<=n_subdivisions[0]; ++x)
-            points.push_back (Point<dim> (x*delta[0] + y*delta[1] + z*delta[2]));
-      break;
+    GridReordering<dim>::invert_all_cells_of_negative_grid(vertices,cells);
+    tria.create_triangulation_compatibility (vertices, cells, SubCellData());
+  }
 
-    default:
-      Assert (false, ExcNotImplemented());
-    }
 
-  // Prepare cell data
-  size_type n_cells = 1;
-  for (unsigned int i=0; i<dim; ++i)
-    n_cells *= n_subdivisions[i];
-  std::vector<CellData<dim> > cells (n_cells);
 
-  // Create fixed ordering of
-  switch (dim)
-    {
-    case 1:
-      for (size_type x=0; x<n_subdivisions[0]; ++x)
-        {
-          cells[x].vertices[0] = x;
-          cells[x].vertices[1] = x+1;
+  void
+  torus (Triangulation<2,3>  &tria,
+         const double         R,
+         const double         r)
+  {
+    Assert (R>r, ExcMessage("Outer radius must be greater than inner radius."));
+
+    const unsigned int dim=2;
+    const unsigned int spacedim=3;
+    std::vector<Point<spacedim> > vertices (16);
+
+    vertices[0]=Point<spacedim>(R-r,0,0);
+    vertices[1]=Point<spacedim>(R,-r,0);
+    vertices[2]=Point<spacedim>(R+r,0,0);
+    vertices[3]=Point<spacedim>(R, r,0);
+    vertices[4]=Point<spacedim>(0,0,R-r);
+    vertices[5]=Point<spacedim>(0,-r,R);
+    vertices[6]=Point<spacedim>(0,0,R+r);
+    vertices[7]=Point<spacedim>(0,r,R);
+    vertices[8]=Point<spacedim>(-(R-r),0,0);
+    vertices[9]=Point<spacedim>(-R,-r,0);
+    vertices[10]=Point<spacedim>(-(R+r),0,0);
+    vertices[11]=Point<spacedim>(-R, r,0);
+    vertices[12]=Point<spacedim>(0,0,-(R-r));
+    vertices[13]=Point<spacedim>(0,-r,-R);
+    vertices[14]=Point<spacedim>(0,0,-(R+r));
+    vertices[15]=Point<spacedim>(0,r,-R);
+
+    std::vector<CellData<dim> > cells (16);
+    //Right Hand Orientation
+    cells[0].vertices[0] =  0;
+    cells[0].vertices[1] =  4;
+    cells[0].vertices[2] =  7;
+    cells[0].vertices[3] =  3;
+    cells[0].material_id = 0;
+
+    cells[1].vertices[0] =  1;
+    cells[1].vertices[1] =  5;
+    cells[1].vertices[2] =  4;
+    cells[1].vertices[3] =  0;
+    cells[1].material_id = 0;
+
+    cells[2].vertices[0] =  2;
+    cells[2].vertices[1] =  6;
+    cells[2].vertices[2] =  5;
+    cells[2].vertices[3] =  1;
+    cells[2].material_id = 0;
+
+    cells[3].vertices[0] =  3;
+    cells[3].vertices[1] =  7;
+    cells[3].vertices[2] =  6;
+    cells[3].vertices[3] =  2;
+    cells[3].material_id = 0;
+
+    cells[4].vertices[0] =  4;
+    cells[4].vertices[1] =  8;
+    cells[4].vertices[2] =  11;
+    cells[4].vertices[3] =  7;
+    cells[4].material_id = 0;
+
+    cells[5].vertices[0] =  5;
+    cells[5].vertices[1] =  9;
+    cells[5].vertices[2] =  8;
+    cells[5].vertices[3] =  4;
+    cells[5].material_id = 0;
+
+    cells[6].vertices[0] =  6;
+    cells[6].vertices[1] =  10;
+    cells[6].vertices[2] =  9;
+    cells[6].vertices[3] =  5;
+    cells[6].material_id = 0;
+
+    cells[7].vertices[0] =  7;
+    cells[7].vertices[1] =  11;
+    cells[7].vertices[2] =  10;
+    cells[7].vertices[3] =  6;
+    cells[7].material_id = 0;
+
+    cells[8].vertices[0] =  8;
+    cells[8].vertices[1] =  12;
+    cells[8].vertices[2] =  15;
+    cells[8].vertices[3] =  11;
+    cells[8].material_id = 0;
+
+    cells[9].vertices[0] =  9;
+    cells[9].vertices[1] =  13;
+    cells[9].vertices[2] =  12;
+    cells[9].vertices[3] =  8;
+    cells[9].material_id = 0;
+
+    cells[10].vertices[0] =  10;
+    cells[10].vertices[1] =  14;
+    cells[10].vertices[2] =  13;
+    cells[10].vertices[3] =  9;
+    cells[10].material_id = 0;
+
+    cells[11].vertices[0] =  11;
+    cells[11].vertices[1] =  15;
+    cells[11].vertices[2] =  14;
+    cells[11].vertices[3] =  10;
+    cells[11].material_id = 0;
+
+    cells[12].vertices[0] =  12;
+    cells[12].vertices[1] =  0;
+    cells[12].vertices[2] =  3;
+    cells[12].vertices[3] =  15;
+    cells[12].material_id = 0;
+
+    cells[13].vertices[0] =  13;
+    cells[13].vertices[1] =  1;
+    cells[13].vertices[2] =  0;
+    cells[13].vertices[3] =  12;
+    cells[13].material_id = 0;
+
+    cells[14].vertices[0] =  14;
+    cells[14].vertices[1] =  2;
+    cells[14].vertices[2] =  1;
+    cells[14].vertices[3] =  13;
+    cells[14].material_id = 0;
+
+    cells[15].vertices[0] =  15;
+    cells[15].vertices[1] =  3;
+    cells[15].vertices[2] =  2;
+    cells[15].vertices[3] =  14;
+    cells[15].material_id = 0;
+
+    // Must call this to be able to create a
+    // correct triangulation in dealii, read
+    // GridReordering<> doc
+    GridReordering<dim,spacedim>::reorder_cells (cells);
+    tria.create_triangulation_compatibility (vertices, cells, SubCellData());
+  }
 
-          // wipe material id
-          cells[x].material_id = 0;
-        }
-      break;
 
-    case 2:
-    {
-      // Shorthand
-      const size_type n_dy = n_subdivisions[1];
-      const size_type n_dx = n_subdivisions[0];
+// Implementation for 2D only
+  template<>
+  void
+  parallelogram (Triangulation<2>  &tria,
+                 const Point<2> (&corners)[2],
+                 const bool         colorize)
+  {
+    std::vector<Point<2> > vertices (GeometryInfo<2>::vertices_per_cell);
+
+    vertices[1] = corners[0];
+    vertices[2] = corners[1];
+    vertices[3] = vertices[1] + vertices[2];
+    // Prepare cell data
+    std::vector<CellData<2> > cells (1);
+    for (unsigned int i=0; i<GeometryInfo<2>::vertices_per_cell; ++i)
+      cells[0].vertices[i] = i;
+    cells[0].material_id = 0;
+
+    tria.create_triangulation (vertices, cells, SubCellData());
+
+    // Assign boundary indicators
+    if (colorize)
+      colorize_hyper_rectangle (tria);
+  }
+
+
+  template<>
+  void
+  parallelogram (Triangulation<2>  &tria,
+                 const Tensor<2,2> &corners,
+                 const bool         colorize)
+  {
+    // simply pass everything to the other function of same name
+    const Point<2> x[2] = { corners[0], corners[1] };
+    parallelogram (tria, x, colorize);
+  }
+
+
+
+// Parallelepiped implementation in 1d, 2d, and 3d. @note The
+// implementation in 1d is similar to hyper_rectangle(), and in 2d is
+// similar to parallelogram().
+//
+// The GridReordering::reorder_grid is made use of towards the end of
+// this function. Thus the triangulation is explicitly constructed for
+// all dim here since it is slightly different in that respect
+// (cf. hyper_rectangle(), parallelogram()).
+  template<int dim>
+  void
+  parallelepiped (Triangulation<dim>  &tria,
+                  const Point<dim>   (&corners) [dim],
+                  const bool           colorize)
+  {
+    // Check that none of the user defined vertices overlap
+    for (unsigned int i=0; i<dim; ++i)
+      for (unsigned int j=i+1; j<dim; ++j)
+        Assert ((corners[i]!=corners[j]),
+                ExcMessage ("Invalid distance between corner points of parallelepiped."));
+
+    // Note: vertex[0] is the origin and is initialised as so here:
+    std::vector<Point<dim> > vertices (GeometryInfo<dim>::vertices_per_cell);
 
-      for (size_type y=0; y<n_dy; ++y)
-        for (size_type x=0; x<n_dx; ++x)
+    switch (dim)
+      {
+        // A line (1d parallelepiped)
+      case 1:
+        vertices[1] = corners[0];
+        break;
+
+        // A parallelogram (2d parallelepiped)
+      case 2:
+        // assign corners to vertices:
+        vertices[1] = corners[0];
+        vertices[2] = corners[1];
+
+        // compose the remaining vertex:
+        vertices[3] = vertices[1] + vertices[2];
+        break;
+
+        // A parallelepiped (3d parallelepiped)
+      case 3:
+        // assign corners to vertices:
+        vertices[1] = corners[0];
+        vertices[2] = corners[1];
+        vertices[4] = corners[2];
+
+        // compose the remaining vertices:
+        vertices[3] = vertices[1] + vertices[2];
+        vertices[5] = vertices[1] + vertices[4];
+        vertices[6] = vertices[2] + vertices[4];
+        vertices[7] = vertices[1] + vertices[2] + vertices[4];
+        break;
+
+      default:
+        Assert (false, ExcNotImplemented());
+      }
+
+    // Prepare cell data and wipe material identity
+    std::vector<CellData<dim> > cells (1);
+    for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+      cells[0].vertices[i] = i;
+    cells[0].material_id = 0;
+
+    // Check ordering of vertices and create triangulation
+    GridReordering<dim>::reorder_cells (cells);
+    tria.create_triangulation (vertices, cells, SubCellData());
+
+    // Finally assign boundary indicators according to hyper_rectangle
+    if (colorize)
+      colorize_hyper_rectangle (tria);
+  }
+
+  template<int dim>
+  void
+  subdivided_parallelepiped (Triangulation<dim>  &tria,
+                             const unsigned int      n_subdivisions,
+                             const Point<dim>   (&corners) [dim],
+                             const bool           colorize)
+  {
+    // Equalise number of subdivisions in each dim-direction, heir
+    // validity will be checked later
+    unsigned int (n_subdivisions_) [dim];
+    for (unsigned int i=0; i<dim; ++i)
+      n_subdivisions_[i] = n_subdivisions;
+
+    // and call the function below
+    subdivided_parallelepiped (tria, n_subdivisions_,
+                               corners,
+                               colorize);
+  }
+
+  template<int dim>
+  void
+  subdivided_parallelepiped (Triangulation<dim>  &tria,
+                             const unsigned int    ( n_subdivisions) [dim],
+                             const Point<dim>   (&corners) [dim],
+                             const bool           colorize)
+  {
+    // Zero n_subdivisions is the origin only, which makes no sense
+    for (unsigned int i=0; i<dim; ++i)
+      Assert (n_subdivisions[i]>0, ExcInvalidRepetitions(n_subdivisions[i]));
+
+    // Check corners do not overlap (unique)
+    for (unsigned int i=0; i<dim; ++i)
+      for (unsigned int j=i+1; j<dim; ++j)
+        Assert ((corners[i]!=corners[j]),
+                ExcMessage ("Invalid distance between corner points of parallelepiped."));
+
+    // Create a list of points
+    Point<dim> (delta) [dim];
+
+    for (unsigned int i=0; i<dim; ++i)
+      delta[i] = corners[i]/n_subdivisions[i];
+    std::vector<Point<dim> > points;
+
+    switch (dim)
+      {
+      case 1:
+        for (unsigned int x=0; x<=n_subdivisions[0]; ++x)
+          points.push_back (Point<dim> (x*delta[0]));
+        break;
+
+      case 2:
+        for (unsigned int y=0; y<=n_subdivisions[1]; ++y)
+          for (unsigned int x=0; x<=n_subdivisions[0]; ++x)
+            points.push_back (Point<dim> (x*delta[0] + y*delta[1]));
+        break;
+
+      case 3:
+        for (unsigned int z=0; z<=n_subdivisions[2]; ++z)
+          for (unsigned int y=0; y<=n_subdivisions[1]; ++y)
+            for (unsigned int x=0; x<=n_subdivisions[0]; ++x)
+              points.push_back (Point<dim> (x*delta[0] + y*delta[1] + z*delta[2]));
+        break;
+
+      default:
+        Assert (false, ExcNotImplemented());
+      }
+
+    // Prepare cell data
+    unsigned int n_cells = 1;
+    for (unsigned int i=0; i<dim; ++i)
+      n_cells *= n_subdivisions[i];
+    std::vector<CellData<dim> > cells (n_cells);
+
+    // Create fixed ordering of
+    switch (dim)
+      {
+      case 1:
+        for (unsigned int x=0; x<n_subdivisions[0]; ++x)
           {
-            const size_type    c = y*n_dx         + x;
-            cells[c].vertices[0] = y*(n_dx+1)     + x;
-            cells[c].vertices[1] = y*(n_dx+1)     + x+1;
-            cells[c].vertices[2] = (y+1)*(n_dx+1) + x;
-            cells[c].vertices[3] = (y+1)*(n_dx+1) + x+1;
+            cells[x].vertices[0] = x;
+            cells[x].vertices[1] = x+1;
 
             // wipe material id
-            cells[c].material_id = 0;
+            cells[x].material_id = 0;
           }
-    }
-    break;
+        break;
 
-    case 3:
-    {
-      // Shorthand
-      const size_type n_dz = n_subdivisions[2];
-      const size_type n_dy = n_subdivisions[1];
-      const size_type n_dx = n_subdivisions[0];
-
-      for (size_type z=0; z<n_dz; ++z)
-        for (size_type y=0; y<n_dy; ++y)
-          for (size_type x=0; x<n_dx; ++x)
-            {
-              const size_type    c = z*n_dy*n_dx             + y*n_dx         + x;
+      case 2:
+      {
+        // Shorthand
+        const unsigned int n_dy = n_subdivisions[1];
+        const unsigned int n_dx = n_subdivisions[0];
 
-              cells[c].vertices[0] = z*(n_dy+1)*(n_dx+1)     + y*(n_dx+1)     + x;
-              cells[c].vertices[1] = z*(n_dy+1)*(n_dx+1)     + y*(n_dx+1)     + x+1;
-              cells[c].vertices[2] = z*(n_dy+1)*(n_dx+1)     + (y+1)*(n_dx+1) + x;
-              cells[c].vertices[3] = z*(n_dy+1)*(n_dx+1)     + (y+1)*(n_dx+1) + x+1;
-              cells[c].vertices[4] = (z+1)*(n_dy+1)*(n_dx+1) + y*(n_dx+1)     + x;
-              cells[c].vertices[5] = (z+1)*(n_dy+1)*(n_dx+1) + y*(n_dx+1)     + x+1;
-              cells[c].vertices[6] = (z+1)*(n_dy+1)*(n_dx+1) + (y+1)*(n_dx+1) + x;
-              cells[c].vertices[7] = (z+1)*(n_dy+1)*(n_dx+1) + (y+1)*(n_dx+1) + x+1;
+        for (unsigned int y=0; y<n_dy; ++y)
+          for (unsigned int x=0; x<n_dx; ++x)
+            {
+              const unsigned int    c = y*n_dx         + x;
+              cells[c].vertices[0] = y*(n_dx+1)     + x;
+              cells[c].vertices[1] = y*(n_dx+1)     + x+1;
+              cells[c].vertices[2] = (y+1)*(n_dx+1) + x;
+              cells[c].vertices[3] = (y+1)*(n_dx+1) + x+1;
 
               // wipe material id
               cells[c].material_id = 0;
             }
+      }
       break;
-    }
 
-    default:
-      Assert (false, ExcNotImplemented());
-    }
+      case 3:
+      {
+        // Shorthand
+        const unsigned int n_dz = n_subdivisions[2];
+        const unsigned int n_dy = n_subdivisions[1];
+        const unsigned int n_dx = n_subdivisions[0];
+
+        for (unsigned int z=0; z<n_dz; ++z)
+          for (unsigned int y=0; y<n_dy; ++y)
+            for (unsigned int x=0; x<n_dx; ++x)
+              {
+                const unsigned int    c = z*n_dy*n_dx             + y*n_dx         + x;
+
+                cells[c].vertices[0] = z*(n_dy+1)*(n_dx+1)     + y*(n_dx+1)     + x;
+                cells[c].vertices[1] = z*(n_dy+1)*(n_dx+1)     + y*(n_dx+1)     + x+1;
+                cells[c].vertices[2] = z*(n_dy+1)*(n_dx+1)     + (y+1)*(n_dx+1) + x;
+                cells[c].vertices[3] = z*(n_dy+1)*(n_dx+1)     + (y+1)*(n_dx+1) + x+1;
+                cells[c].vertices[4] = (z+1)*(n_dy+1)*(n_dx+1) + y*(n_dx+1)     + x;
+                cells[c].vertices[5] = (z+1)*(n_dy+1)*(n_dx+1) + y*(n_dx+1)     + x+1;
+                cells[c].vertices[6] = (z+1)*(n_dy+1)*(n_dx+1) + (y+1)*(n_dx+1) + x;
+                cells[c].vertices[7] = (z+1)*(n_dy+1)*(n_dx+1) + (y+1)*(n_dx+1) + x+1;
+
+                // wipe material id
+                cells[c].material_id = 0;
+              }
+        break;
+      }
 
-  // Create triangulation
-  tria.create_triangulation (points, cells, SubCellData());
+      default:
+        Assert (false, ExcNotImplemented());
+      }
 
-  // Finally assign boundary indicators according to hyper_rectangle
-  if (colorize)
-    colorize_hyper_rectangle (tria);
-}
+    // Create triangulation
+    tria.create_triangulation (points, cells, SubCellData());
 
+    // Finally assign boundary indicators according to hyper_rectangle
+    if (colorize)
+      colorize_hyper_rectangle (tria);
+  }
 
-template <int dim>
-void
-GridGenerator::subdivided_hyper_cube (Triangulation<dim> &tria,
-                                      const unsigned int  repetitions,
-                                      const double        left,
-                                      const double        right)
-{
-  Assert (repetitions >= 1, ExcInvalidRepetitions(repetitions));
-  Assert (left < right,
-          ExcMessage ("Invalid left-to-right bounds of hypercube"));
-
-  // first generate the necessary
-  // points
-  const double delta = (right-left)/repetitions;
-  std::vector<Point<dim> > points;
-  switch (dim)
-    {
-    case 1:
-      for (unsigned int x=0; x<=repetitions; ++x)
-        points.push_back (Point<dim> (left+x*delta));
-      break;
 
-    case 2:
-      for (unsigned int y=0; y<=repetitions; ++y)
+  template <int dim>
+  void
+  subdivided_hyper_cube (Triangulation<dim> &tria,
+                         const unsigned int  repetitions,
+                         const double        left,
+                         const double        right)
+  {
+    Assert (repetitions >= 1, ExcInvalidRepetitions(repetitions));
+    Assert (left < right,
+            ExcMessage ("Invalid left-to-right bounds of hypercube"));
+
+    // first generate the necessary
+    // points
+    const double delta = (right-left)/repetitions;
+    std::vector<Point<dim> > points;
+    switch (dim)
+      {
+      case 1:
         for (unsigned int x=0; x<=repetitions; ++x)
-          points.push_back (Point<dim> (left+x*delta,
-                                        left+y*delta));
-      break;
+          points.push_back (Point<dim> (left+x*delta));
+        break;
 
-    case 3:
-      for (unsigned int z=0; z<=repetitions; ++z)
+      case 2:
         for (unsigned int y=0; y<=repetitions; ++y)
           for (unsigned int x=0; x<=repetitions; ++x)
             points.push_back (Point<dim> (left+x*delta,
-                                          left+y*delta,
-                                          left+z*delta));
-      break;
-
-    default:
-      Assert (false, ExcNotImplemented());
-    }
-
-  // next create the cells
-  // Prepare cell data
-  std::vector<CellData<dim> > cells;
-  // Define these as abbreviations
-  // for the step sizes below. The
-  // number of points in a single
-  // direction is repetitions+1
-  const unsigned int dy = repetitions+1;
-  const unsigned int dz = dy*dy;
-  switch (dim)
-    {
-    case 1:
-      cells.resize (repetitions);
-      for (unsigned int x=0; x<repetitions; ++x)
-        {
-          cells[x].vertices[0] = x;
-          cells[x].vertices[1] = x+1;
-          cells[x].material_id = 0;
-        }
-      break;
+                                          left+y*delta));
+        break;
+
+      case 3:
+        for (unsigned int z=0; z<=repetitions; ++z)
+          for (unsigned int y=0; y<=repetitions; ++y)
+            for (unsigned int x=0; x<=repetitions; ++x)
+              points.push_back (Point<dim> (left+x*delta,
+                                            left+y*delta,
+                                            left+z*delta));
+        break;
+
+      default:
+        Assert (false, ExcNotImplemented());
+      }
 
-    case 2:
-      cells.resize (repetitions*repetitions);
-      for (unsigned int y=0; y<repetitions; ++y)
+    // next create the cells
+    // Prepare cell data
+    std::vector<CellData<dim> > cells;
+    // Define these as abbreviations
+    // for the step sizes below. The
+    // number of points in a single
+    // direction is repetitions+1
+    const unsigned int dy = repetitions+1;
+    const unsigned int dz = dy*dy;
+    switch (dim)
+      {
+      case 1:
+        cells.resize (repetitions);
         for (unsigned int x=0; x<repetitions; ++x)
           {
-            const unsigned int c = x  +y*repetitions;
-            cells[c].vertices[0] = x  +y*dy;
-            cells[c].vertices[1] = x+1+y*dy;
-            cells[c].vertices[2] = x  +(y+1)*dy;
-            cells[c].vertices[3] = x+1+(y+1)*dy;
-            cells[c].material_id = 0;
+            cells[x].vertices[0] = x;
+            cells[x].vertices[1] = x+1;
+            cells[x].material_id = 0;
           }
-      break;
+        break;
 
-    case 3:
-      cells.resize (repetitions*repetitions*repetitions);
-      for (unsigned int z=0; z<repetitions; ++z)
+      case 2:
+        cells.resize (repetitions*repetitions);
         for (unsigned int y=0; y<repetitions; ++y)
           for (unsigned int x=0; x<repetitions; ++x)
             {
-              const unsigned int c = x+y*repetitions
-                                     +z*repetitions*repetitions;
-              cells[c].vertices[0] = x  +y*dy    +z*dz;
-              cells[c].vertices[1] = x+1+y*dy    +z*dz;
-              cells[c].vertices[2] = x  +(y+1)*dy+z*dz;
-              cells[c].vertices[3] = x+1+(y+1)*dy+z*dz;
-              cells[c].vertices[4] = x  +y*dy    +(z+1)*dz;
-              cells[c].vertices[5] = x+1+y*dy    +(z+1)*dz;
-              cells[c].vertices[6] = x  +(y+1)*dy+(z+1)*dz;
-              cells[c].vertices[7] = x+1+(y+1)*dy+(z+1)*dz;
+              const unsigned int c = x  +y*repetitions;
+              cells[c].vertices[0] = x  +y*dy;
+              cells[c].vertices[1] = x+1+y*dy;
+              cells[c].vertices[2] = x  +(y+1)*dy;
+              cells[c].vertices[3] = x+1+(y+1)*dy;
               cells[c].material_id = 0;
             }
-      break;
+        break;
 
-    default:
-      // should be trivial to
-      // do for 3d as well, but
-      // am too tired at this
-      // point of the night to
-      // do that...
-      //
-      // contributions are welcome!
-      Assert (false, ExcNotImplemented());
-    }
+      case 3:
+        cells.resize (repetitions*repetitions*repetitions);
+        for (unsigned int z=0; z<repetitions; ++z)
+          for (unsigned int y=0; y<repetitions; ++y)
+            for (unsigned int x=0; x<repetitions; ++x)
+              {
+                const unsigned int c = x+y*repetitions
+                                       +z*repetitions*repetitions;
+                cells[c].vertices[0] = x  +y*dy    +z*dz;
+                cells[c].vertices[1] = x+1+y*dy    +z*dz;
+                cells[c].vertices[2] = x  +(y+1)*dy+z*dz;
+                cells[c].vertices[3] = x+1+(y+1)*dy+z*dz;
+                cells[c].vertices[4] = x  +y*dy    +(z+1)*dz;
+                cells[c].vertices[5] = x+1+y*dy    +(z+1)*dz;
+                cells[c].vertices[6] = x  +(y+1)*dy+(z+1)*dz;
+                cells[c].vertices[7] = x+1+(y+1)*dy+(z+1)*dz;
+                cells[c].material_id = 0;
+              }
+        break;
+
+      default:
+        // should be trivial to
+        // do for 3d as well, but
+        // am too tired at this
+        // point of the night to
+        // do that...
+        //
+        // contributions are welcome!
+        Assert (false, ExcNotImplemented());
+      }
 
-  tria.create_triangulation (points, cells, SubCellData());
-}
+    tria.create_triangulation (points, cells, SubCellData());
+  }
 
 
 
-template <int dim>
-void
-GridGenerator::subdivided_hyper_rectangle (
-  Triangulation<dim>              &tria,
-  const std::vector<unsigned int> &repetitions,
-  const Point<dim>                &p_1,
-  const Point<dim>                &p_2,
-  const bool                       colorize)
-{
-  // contributed by Joerg R. Weimar
-  // (j.weimar@jweimar.de) 2003
-  Assert(repetitions.size() == dim,
-         ExcInvalidRepetitionsDimension(dim));
-  // First, normalize input such that
-  // p1 is lower in all coordinate
-  // directions.
-  Point<dim> p1(p_1);
-  Point<dim> p2(p_2);
-
-  for (unsigned int i=0; i<dim; ++i)
-    if (p1(i) > p2(i))
-      std::swap (p1(i), p2(i));
-
-  // then check that all repetitions
-  // are >= 1, and calculate deltas
-  // convert repetitions from double
-  // to int by taking the ceiling.
-  Point<dim> delta;
-
-  for (unsigned int i=0; i<dim; ++i)
-    {
-      Assert (repetitions[i] >= 1, ExcInvalidRepetitions(repetitions[i]));
+  template <int dim>
+  void
+  subdivided_hyper_rectangle (
+    Triangulation<dim>              &tria,
+    const std::vector<unsigned int> &repetitions,
+    const Point<dim>                &p_1,
+    const Point<dim>                &p_2,
+    const bool                       colorize)
+  {
+    // contributed by Joerg R. Weimar
+    // (j.weimar@jweimar.de) 2003
+    Assert(repetitions.size() == dim,
+           ExcInvalidRepetitionsDimension(dim));
+    // First, normalize input such that
+    // p1 is lower in all coordinate
+    // directions.
+    Point<dim> p1(p_1);
+    Point<dim> p2(p_2);
+
+    for (unsigned int i=0; i<dim; ++i)
+      if (p1(i) > p2(i))
+        std::swap (p1(i), p2(i));
 
-      delta[i] = (p2[i]-p1[i])/repetitions[i];
-    }
+    // then check that all repetitions
+    // are >= 1, and calculate deltas
+    // convert repetitions from double
+    // to int by taking the ceiling.
+    Point<dim> delta;
 
-  // then generate the necessary
-  // points
-  std::vector<Point<dim> > points;
-  switch (dim)
-    {
-    case 1:
-      for (unsigned int x=0; x<=repetitions[0]; ++x)
-        points.push_back (Point<dim> (p1[0]+x*delta[0]));
-      break;
+    for (unsigned int i=0; i<dim; ++i)
+      {
+        Assert (repetitions[i] >= 1, ExcInvalidRepetitions(repetitions[i]));
+
+        delta[i] = (p2[i]-p1[i])/repetitions[i];
+      }
 
-    case 2:
-      for (unsigned int y=0; y<=repetitions[1]; ++y)
+    // then generate the necessary
+    // points
+    std::vector<Point<dim> > points;
+    switch (dim)
+      {
+      case 1:
         for (unsigned int x=0; x<=repetitions[0]; ++x)
-          points.push_back (Point<dim> (p1[0]+x*delta[0],
-                                        p1[1]+y*delta[1]));
-      break;
+          points.push_back (Point<dim> (p1[0]+x*delta[0]));
+        break;
 
-    case 3:
-      for (unsigned int z=0; z<=repetitions[2]; ++z)
+      case 2:
         for (unsigned int y=0; y<=repetitions[1]; ++y)
           for (unsigned int x=0; x<=repetitions[0]; ++x)
             points.push_back (Point<dim> (p1[0]+x*delta[0],
-                                          p1[1]+y*delta[1],
-                                          p1[2]+z*delta[2]));
-      break;
-
-    default:
-      Assert (false, ExcNotImplemented());
-    }
-
-  // next create the cells
-  // Prepare cell data
-  std::vector<CellData<dim> > cells;
-  switch (dim)
-    {
-    case 1:
-    {
-      cells.resize (repetitions[0]);
-      for (unsigned int x=0; x<repetitions[0]; ++x)
-        {
-          cells[x].vertices[0] = x;
-          cells[x].vertices[1] = x+1;
-          cells[x].material_id = 0;
-        }
-      break;
-    }
+                                          p1[1]+y*delta[1]));
+        break;
+
+      case 3:
+        for (unsigned int z=0; z<=repetitions[2]; ++z)
+          for (unsigned int y=0; y<=repetitions[1]; ++y)
+            for (unsigned int x=0; x<=repetitions[0]; ++x)
+              points.push_back (Point<dim> (p1[0]+x*delta[0],
+                                            p1[1]+y*delta[1],
+                                            p1[2]+z*delta[2]));
+        break;
+
+      default:
+        Assert (false, ExcNotImplemented());
+      }
 
-    case 2:
-    {
-      cells.resize (repetitions[1]*repetitions[0]);
-      for (unsigned int y=0; y<repetitions[1]; ++y)
+    // next create the cells
+    // Prepare cell data
+    std::vector<CellData<dim> > cells;
+    switch (dim)
+      {
+      case 1:
+      {
+        cells.resize (repetitions[0]);
         for (unsigned int x=0; x<repetitions[0]; ++x)
           {
-            const unsigned int c = x+y*repetitions[0];
-            cells[c].vertices[0] = y*(repetitions[0]+1)+x;
-            cells[c].vertices[1] = y*(repetitions[0]+1)+x+1;
-            cells[c].vertices[2] = (y+1)*(repetitions[0]+1)+x;
-            cells[c].vertices[3] = (y+1)*(repetitions[0]+1)+x+1;
-            cells[c].material_id = 0;
+            cells[x].vertices[0] = x;
+            cells[x].vertices[1] = x+1;
+            cells[x].material_id = 0;
           }
-      break;
-    }
-
-    case 3:
-    {
-      const unsigned int n_x  = (repetitions[0]+1);
-      const unsigned int n_xy = (repetitions[0]+1)*(repetitions[1]+1);
+        break;
+      }
 
-      cells.resize (repetitions[2]*repetitions[1]*repetitions[0]);
-      for (unsigned int z=0; z<repetitions[2]; ++z)
+      case 2:
+      {
+        cells.resize (repetitions[1]*repetitions[0]);
         for (unsigned int y=0; y<repetitions[1]; ++y)
           for (unsigned int x=0; x<repetitions[0]; ++x)
             {
-              const unsigned int c = x+y*repetitions[0] +
-                                     z*repetitions[0]*repetitions[1];
-              cells[c].vertices[0] = z*n_xy + y*n_x + x;
-              cells[c].vertices[1] = z*n_xy + y*n_x + x+1;
-              cells[c].vertices[2] = z*n_xy + (y+1)*n_x + x;
-              cells[c].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
-              cells[c].vertices[4] = (z+1)*n_xy + y*n_x + x;
-              cells[c].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
-              cells[c].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
-              cells[c].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
+              const unsigned int c = x+y*repetitions[0];
+              cells[c].vertices[0] = y*(repetitions[0]+1)+x;
+              cells[c].vertices[1] = y*(repetitions[0]+1)+x+1;
+              cells[c].vertices[2] = (y+1)*(repetitions[0]+1)+x;
+              cells[c].vertices[3] = (y+1)*(repetitions[0]+1)+x+1;
               cells[c].material_id = 0;
             }
-      break;
-
-    }
+        break;
+      }
 
-    default:
-      Assert (false, ExcNotImplemented());
-    }
+      case 3:
+      {
+        const unsigned int n_x  = (repetitions[0]+1);
+        const unsigned int n_xy = (repetitions[0]+1)*(repetitions[1]+1);
 
-  tria.create_triangulation (points, cells, SubCellData());
+        cells.resize (repetitions[2]*repetitions[1]*repetitions[0]);
+        for (unsigned int z=0; z<repetitions[2]; ++z)
+          for (unsigned int y=0; y<repetitions[1]; ++y)
+            for (unsigned int x=0; x<repetitions[0]; ++x)
+              {
+                const unsigned int c = x+y*repetitions[0] +
+                                       z*repetitions[0]*repetitions[1];
+                cells[c].vertices[0] = z*n_xy + y*n_x + x;
+                cells[c].vertices[1] = z*n_xy + y*n_x + x+1;
+                cells[c].vertices[2] = z*n_xy + (y+1)*n_x + x;
+                cells[c].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
+                cells[c].vertices[4] = (z+1)*n_xy + y*n_x + x;
+                cells[c].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
+                cells[c].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
+                cells[c].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
+                cells[c].material_id = 0;
+              }
+        break;
 
-  if (colorize)
-    {
-      // to colorize, run through all
-      // faces of all cells and set
-      // boundary indicator to the
-      // correct value if it was 0.
-
-      // use a large epsilon to
-      // compare numbers to avoid
-      // roundoff problems.
-      const double epsilon
-        = 0.01 * *std::min_element (&delta[0], &delta[0]+dim);
-      Assert (epsilon > 0,
-              ExcMessage ("The distance between corner points must be positive."))
-
-      // actual code is external since
-      // 1-D is different from 2/3D.
-      colorize_subdivided_hyper_rectangle (tria, p1, p2, epsilon);
-    }
-}
+      }
 
+      default:
+        Assert (false, ExcNotImplemented());
+      }
 
+    tria.create_triangulation (points, cells, SubCellData());
 
-template <int dim>
-void
-GridGenerator::subdivided_hyper_rectangle(
-  Triangulation<dim>              &tria,
-  const std::vector<std::vector<double> > &step_sz,
-  const Point<dim>                &p_1,
-  const Point<dim>                &p_2,
-  const bool                       colorize)
-{
-  // contributed by Joerg R. Weimar
-  // (j.weimar@jweimar.de) 2003
-  // modified by Yaqi Wang 2006
-  Assert(step_sz.size() == dim,
-         ExcInvalidRepetitionsDimension(dim));
-
-
-  // First, normalize input such that
-  // p1 is lower in all coordinate
-  // directions.
-
-  // and check the consistency of
-  // step sizes, i.e. that they all
-  // add up to the sizes specified by
-  // p_1 and p_2
-  Point<dim> p1(p_1);
-  Point<dim> p2(p_2);
-  std::vector< std::vector<double> > step_sizes(step_sz);
-
-  for (unsigned int i=0; i<dim; ++i)
-    {
-      if (p1(i) > p2(i))
-        {
-          std::swap (p1(i), p2(i));
-          std::reverse (step_sizes[i].begin(), step_sizes[i].end());
-        }
+    if (colorize)
+      {
+        // to colorize, run through all
+        // faces of all cells and set
+        // boundary indicator to the
+        // correct value if it was 0.
+
+        // use a large epsilon to
+        // compare numbers to avoid
+        // roundoff problems.
+        const double epsilon
+          = 0.01 * *std::min_element (&delta[0], &delta[0]+dim);
+        Assert (epsilon > 0,
+                ExcMessage ("The distance between corner points must be positive."))
+
+        // actual code is external since
+        // 1-D is different from 2/3D.
+        colorize_subdivided_hyper_rectangle (tria, p1, p2, epsilon);
+      }
+  }
 
-      double x = 0;
-      for (size_type j=0; j<step_sizes.at(i).size(); j++)
-        x += step_sizes[i][j];
-      Assert(std::fabs(x - (p2(i)-p1(i))) <= 1e-12*std::fabs(x),
-             ExcInvalidRepetitions (i) );
-    }
 
 
-  // then generate the necessary
-  // points
-  std::vector<Point<dim> > points;
-  switch (dim)
-    {
-    case 1:
-    {
-      double x=0;
-      for (size_type i=0; ; ++i)
-        {
-          points.push_back (Point<dim> (p1[0]+x));
-
-          // form partial sums. in
-          // the last run through
-          // avoid accessing
-          // non-existent values
-          // and exit early instead
-          if (i == step_sizes[0].size())
-            break;
+  template <int dim>
+  void
+  subdivided_hyper_rectangle(
+    Triangulation<dim>              &tria,
+    const std::vector<std::vector<double> > &step_sz,
+    const Point<dim>                &p_1,
+    const Point<dim>                &p_2,
+    const bool                       colorize)
+  {
+    // contributed by Joerg R. Weimar
+    // (j.weimar@jweimar.de) 2003
+    // modified by Yaqi Wang 2006
+    Assert(step_sz.size() == dim,
+           ExcInvalidRepetitionsDimension(dim));
+
+
+    // First, normalize input such that
+    // p1 is lower in all coordinate
+    // directions.
+
+    // and check the consistency of
+    // step sizes, i.e. that they all
+    // add up to the sizes specified by
+    // p_1 and p_2
+    Point<dim> p1(p_1);
+    Point<dim> p2(p_2);
+    std::vector< std::vector<double> > step_sizes(step_sz);
+
+    for (unsigned int i=0; i<dim; ++i)
+      {
+        if (p1(i) > p2(i))
+          {
+            std::swap (p1(i), p2(i));
+            std::reverse (step_sizes[i].begin(), step_sizes[i].end());
+          }
 
-          x += step_sizes[0][i];
-        }
-      break;
-    }
+        double x = 0;
+        for (unsigned int j=0; j<step_sizes.at(i).size(); j++)
+          x += step_sizes[i][j];
+        Assert(std::fabs(x - (p2(i)-p1(i))) <= 1e-12*std::fabs(x),
+               ExcInvalidRepetitions (i) );
+      }
 
-    case 2:
-    {
-      double y=0;
-      for (size_type j=0; ; ++j)
-        {
-          double x=0;
-          for (size_type i=0; ; ++i)
-            {
-              points.push_back (Point<dim> (p1[0]+x,
-                                            p1[1]+y));
-              if (i == step_sizes[0].size())
-                break;
 
-              x += step_sizes[0][i];
-            }
+    // then generate the necessary
+    // points
+    std::vector<Point<dim> > points;
+    switch (dim)
+      {
+      case 1:
+      {
+        double x=0;
+        for (unsigned int i=0; ; ++i)
+          {
+            points.push_back (Point<dim> (p1[0]+x));
 
-          if (j == step_sizes[1].size())
-            break;
+            // form partial sums. in
+            // the last run through
+            // avoid accessing
+            // non-existent values
+            // and exit early instead
+            if (i == step_sizes[0].size())
+              break;
 
-          y += step_sizes[1][j];
-        }
-      break;
+            x += step_sizes[0][i];
+          }
+        break;
+      }
 
-    }
-    case 3:
-    {
-      double z=0;
-      for (size_type k=0; ; ++k)
-        {
-          double y=0;
-          for (size_type j=0; ; ++j)
-            {
-              double x=0;
-              for (size_type i=0; ; ++i)
-                {
-                  points.push_back (Point<dim> (p1[0]+x,
-                                                p1[1]+y,
-                                                p1[2]+z));
-                  if (i == step_sizes[0].size())
-                    break;
+      case 2:
+      {
+        double y=0;
+        for (unsigned int j=0; ; ++j)
+          {
+            double x=0;
+            for (unsigned int i=0; ; ++i)
+              {
+                points.push_back (Point<dim> (p1[0]+x,
+                                              p1[1]+y));
+                if (i == step_sizes[0].size())
+                  break;
 
-                  x += step_sizes[0][i];
-                }
+                x += step_sizes[0][i];
+              }
 
-              if (j == step_sizes[1].size())
-                break;
+            if (j == step_sizes[1].size())
+              break;
 
-              y += step_sizes[1][j];
-            }
+            y += step_sizes[1][j];
+          }
+        break;
 
-          if (k == step_sizes[2].size())
-            break;
+      }
+      case 3:
+      {
+        double z=0;
+        for (unsigned int k=0; ; ++k)
+          {
+            double y=0;
+            for (unsigned int j=0; ; ++j)
+              {
+                double x=0;
+                for (unsigned int i=0; ; ++i)
+                  {
+                    points.push_back (Point<dim> (p1[0]+x,
+                                                  p1[1]+y,
+                                                  p1[2]+z));
+                    if (i == step_sizes[0].size())
+                      break;
 
-          z += step_sizes[2][k];
-        }
-      break;
-    }
+                    x += step_sizes[0][i];
+                  }
 
-    default:
-      Assert (false, ExcNotImplemented());
-    }
+                if (j == step_sizes[1].size())
+                  break;
 
-  // next create the cells
-  // Prepare cell data
-  std::vector<CellData<dim> > cells;
-  switch (dim)
-    {
-    case 1:
-    {
-      cells.resize (step_sizes[0].size());
-      for (size_type x=0; x<step_sizes[0].size(); ++x)
-        {
-          cells[x].vertices[0] = x;
-          cells[x].vertices[1] = x+1;
-          cells[x].material_id = 0;
-        }
-      break;
-    }
+                y += step_sizes[1][j];
+              }
 
-    case 2:
-    {
-      cells.resize (step_sizes[1].size()*step_sizes[0].size());
-      for (size_type y=0; y<step_sizes[1].size(); ++y)
-        for (size_type x=0; x<step_sizes[0].size(); ++x)
-          {
-            const size_type c = x+y*step_sizes[0].size();
-            cells[c].vertices[0] = y*(step_sizes[0].size()+1)+x;
-            cells[c].vertices[1] = y*(step_sizes[0].size()+1)+x+1;
-            cells[c].vertices[2] = (y+1)*(step_sizes[0].size()+1)+x;
-            cells[c].vertices[3] = (y+1)*(step_sizes[0].size()+1)+x+1;
-            cells[c].material_id = 0;
+            if (k == step_sizes[2].size())
+              break;
+
+            z += step_sizes[2][k];
           }
-      break;
-    }
+        break;
+      }
 
-    case 3:
-    {
-      const size_type n_x  = (step_sizes[0].size()+1);
-      const size_type n_xy = (step_sizes[0].size()+1)*(step_sizes[1].size()+1);
+      default:
+        Assert (false, ExcNotImplemented());
+      }
+
+    // next create the cells
+    // Prepare cell data
+    std::vector<CellData<dim> > cells;
+    switch (dim)
+      {
+      case 1:
+      {
+        cells.resize (step_sizes[0].size());
+        for (unsigned int x=0; x<step_sizes[0].size(); ++x)
+          {
+            cells[x].vertices[0] = x;
+            cells[x].vertices[1] = x+1;
+            cells[x].material_id = 0;
+          }
+        break;
+      }
 
-      cells.resize (step_sizes[2].size()*step_sizes[1].size()*step_sizes[0].size());
-      for (size_type z=0; z<step_sizes[2].size(); ++z)
-        for (size_type y=0; y<step_sizes[1].size(); ++y)
-          for (size_type x=0; x<step_sizes[0].size(); ++x)
+      case 2:
+      {
+        cells.resize (step_sizes[1].size()*step_sizes[0].size());
+        for (unsigned int y=0; y<step_sizes[1].size(); ++y)
+          for (unsigned int x=0; x<step_sizes[0].size(); ++x)
             {
-              const size_type    c = x+y*step_sizes[0].size() +
-                                     z*step_sizes[0].size()*step_sizes[1].size();
-              cells[c].vertices[0] = z*n_xy + y*n_x + x;
-              cells[c].vertices[1] = z*n_xy + y*n_x + x+1;
-              cells[c].vertices[2] = z*n_xy + (y+1)*n_x + x;
-              cells[c].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
-              cells[c].vertices[4] = (z+1)*n_xy + y*n_x + x;
-              cells[c].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
-              cells[c].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
-              cells[c].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
+              const unsigned int c = x+y*step_sizes[0].size();
+              cells[c].vertices[0] = y*(step_sizes[0].size()+1)+x;
+              cells[c].vertices[1] = y*(step_sizes[0].size()+1)+x+1;
+              cells[c].vertices[2] = (y+1)*(step_sizes[0].size()+1)+x;
+              cells[c].vertices[3] = (y+1)*(step_sizes[0].size()+1)+x+1;
               cells[c].material_id = 0;
             }
-      break;
+        break;
+      }
 
-    }
+      case 3:
+      {
+        const unsigned int n_x  = (step_sizes[0].size()+1);
+        const unsigned int n_xy = (step_sizes[0].size()+1)*(step_sizes[1].size()+1);
 
-    default:
-      Assert (false, ExcNotImplemented());
-    }
+        cells.resize (step_sizes[2].size()*step_sizes[1].size()*step_sizes[0].size());
+        for (unsigned int z=0; z<step_sizes[2].size(); ++z)
+          for (unsigned int y=0; y<step_sizes[1].size(); ++y)
+            for (unsigned int x=0; x<step_sizes[0].size(); ++x)
+              {
+                const unsigned int    c = x+y*step_sizes[0].size() +
+                                          z*step_sizes[0].size()*step_sizes[1].size();
+                cells[c].vertices[0] = z*n_xy + y*n_x + x;
+                cells[c].vertices[1] = z*n_xy + y*n_x + x+1;
+                cells[c].vertices[2] = z*n_xy + (y+1)*n_x + x;
+                cells[c].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
+                cells[c].vertices[4] = (z+1)*n_xy + y*n_x + x;
+                cells[c].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
+                cells[c].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
+                cells[c].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
+                cells[c].material_id = 0;
+              }
+        break;
 
-  tria.create_triangulation (points, cells, SubCellData());
+      }
 
-  if (colorize)
-    {
-      // to colorize, run through all
-      // faces of all cells and set
-      // boundary indicator to the
-      // correct value if it was 0.
-
-      // use a large epsilon to
-      // compare numbers to avoid
-      // roundoff problems.
-      double min_size = *std::min_element (step_sizes[0].begin(),
-                                           step_sizes[0].end());
-      for (unsigned int i=1; i<dim; ++i)
-        min_size = std::min (min_size,
-                             *std::min_element (step_sizes[i].begin(),
-                                                step_sizes[i].end()));
-      const double epsilon = 0.01 * min_size;
-
-      // actual code is external since
-      // 1-D is different from 2/3D.
-      colorize_subdivided_hyper_rectangle (tria, p1, p2, epsilon);
-    }
-}
+      default:
+        Assert (false, ExcNotImplemented());
+      }
 
+    tria.create_triangulation (points, cells, SubCellData());
 
+    if (colorize)
+      {
+        // to colorize, run through all
+        // faces of all cells and set
+        // boundary indicator to the
+        // correct value if it was 0.
+
+        // use a large epsilon to
+        // compare numbers to avoid
+        // roundoff problems.
+        double min_size = *std::min_element (step_sizes[0].begin(),
+                                             step_sizes[0].end());
+        for (unsigned int i=1; i<dim; ++i)
+          min_size = std::min (min_size,
+                               *std::min_element (step_sizes[i].begin(),
+                                                  step_sizes[i].end()));
+        const double epsilon = 0.01 * min_size;
+
+        // actual code is external since
+        // 1-D is different from 2/3D.
+        colorize_subdivided_hyper_rectangle (tria, p1, p2, epsilon);
+      }
+  }
 
-template <>
-void
-GridGenerator::subdivided_hyper_rectangle (
-  Triangulation<1>                             &tria,
-  const std::vector< std::vector<double> >     &spacing,
-  const Point<1>                               &p,
-  const Table<1,types::material_id>                 &material_id,
-  const bool                                    colorize)
-{
-  // contributed by Yaqi Wang 2006
-  Assert(spacing.size() == 1,
-         ExcInvalidRepetitionsDimension(1));
 
-  const size_type n_cells = material_id.size(0);
 
-  Assert(spacing[0].size() == n_cells,
-         ExcInvalidRepetitionsDimension(1));
+  template <>
+  void
+  subdivided_hyper_rectangle (
+    Triangulation<1>                             &tria,
+    const std::vector< std::vector<double> >     &spacing,
+    const Point<1>                               &p,
+    const Table<1,types::material_id>                 &material_id,
+    const bool                                    colorize)
+  {
+    // contributed by Yaqi Wang 2006
+    Assert(spacing.size() == 1,
+           ExcInvalidRepetitionsDimension(1));
 
-  double delta = std::numeric_limits<double>::max();
-  for (size_type i=0; i<n_cells; i++)
-    {
-      Assert (spacing[0][i] >= 0, ExcInvalidRepetitions(-1));
-      delta = std::min (delta, spacing[0][i]);
-    }
+    const unsigned int n_cells = material_id.size(0);
 
-  // generate the necessary points
-  std::vector<Point<1> > points;
-  double ax = p[0];
-  for (size_type x=0; x<=n_cells; ++x)
-    {
-      points.push_back (Point<1> (ax));
-      if (x<n_cells)
-        ax += spacing[0][x];
-    }
-  // create the cells
-  size_type n_val_cells = 0;
-  for (size_type i=0; i<n_cells; i++)
-    if (material_id[i]!=numbers::invalid_material_id) n_val_cells++;
+    Assert(spacing[0].size() == n_cells,
+           ExcInvalidRepetitionsDimension(1));
 
-  std::vector<CellData<1> > cells(n_val_cells);
-  size_type id = 0;
-  for (size_type x=0; x<n_cells; ++x)
-    if (material_id[x] != numbers::invalid_material_id)
+    double delta = std::numeric_limits<double>::max();
+    for (unsigned int i=0; i<n_cells; i++)
       {
-        cells[id].vertices[0] = x;
-        cells[id].vertices[1] = x+1;
-        cells[id].material_id = material_id[x];
-        id++;
+        Assert (spacing[0][i] >= 0, ExcInvalidRepetitions(-1));
+        delta = std::min (delta, spacing[0][i]);
       }
-  // create triangulation
-  SubCellData t;
-  GridTools::delete_unused_vertices (points, cells, t);
 
-  tria.create_triangulation (points, cells, t);
+    // generate the necessary points
+    std::vector<Point<1> > points;
+    double ax = p[0];
+    for (unsigned int x=0; x<=n_cells; ++x)
+      {
+        points.push_back (Point<1> (ax));
+        if (x<n_cells)
+          ax += spacing[0][x];
+      }
+    // create the cells
+    unsigned int n_val_cells = 0;
+    for (unsigned int i=0; i<n_cells; i++)
+      if (material_id[i]!=numbers::invalid_material_id) n_val_cells++;
+
+    std::vector<CellData<1> > cells(n_val_cells);
+    unsigned int id = 0;
+    for (unsigned int x=0; x<n_cells; ++x)
+      if (material_id[x] != numbers::invalid_material_id)
+        {
+          cells[id].vertices[0] = x;
+          cells[id].vertices[1] = x+1;
+          cells[id].material_id = material_id[x];
+          id++;
+        }
+    // create triangulation
+    SubCellData t;
+    GridTools::delete_unused_vertices (points, cells, t);
 
-  // set boundary indicator
-  if (colorize)
-    Assert (false, ExcNotImplemented());
-}
+    tria.create_triangulation (points, cells, t);
 
+    // set boundary indicator
+    if (colorize)
+      Assert (false, ExcNotImplemented());
+  }
 
-template <>
-void
-GridGenerator::subdivided_hyper_rectangle (
-  Triangulation<2>                         &tria,
-  const std::vector< std::vector<double> >     &spacing,
-  const Point<2>                               &p,
-  const Table<2,types::material_id>          &material_id,
-  const bool                                    colorize)
-{
-  // contributed by Yaqi Wang 2006
-  Assert(spacing.size() == 2,
-         ExcInvalidRepetitionsDimension(2));
-
-  std::vector<size_type> repetitions(2);
-  size_type n_cells = 1;
-  double delta = std::numeric_limits<double>::max();
-  for (unsigned int i=0; i<2; i++)
-    {
-      repetitions[i] = spacing[i].size();
-      n_cells *= repetitions[i];
-      for (size_type j=0; j<repetitions[i]; j++)
-        {
-          Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
-          delta = std::min (delta, spacing[i][j]);
-        }
-      Assert(material_id.size(i) == repetitions[i],
-             ExcInvalidRepetitionsDimension(i));
-    }
 
-  // generate the necessary points
-  std::vector<Point<2> > points;
-  double ay = p[1];
-  for (size_type y=0; y<=repetitions[1]; ++y)
-    {
-      double ax = p[0];
-      for (size_type x=0; x<=repetitions[0]; ++x)
-        {
-          points.push_back (Point<2> (ax,ay));
-          if (x<repetitions[0])
-            ax += spacing[0][x];
-        }
-      if (y<repetitions[1])
-        ay += spacing[1][y];
-    }
+  template <>
+  void
+  subdivided_hyper_rectangle (
+    Triangulation<2>                         &tria,
+    const std::vector< std::vector<double> >     &spacing,
+    const Point<2>                               &p,
+    const Table<2,types::material_id>          &material_id,
+    const bool                                    colorize)
+  {
+    // contributed by Yaqi Wang 2006
+    Assert(spacing.size() == 2,
+           ExcInvalidRepetitionsDimension(2));
+
+    std::vector<unsigned int> repetitions(2);
+    unsigned int n_cells = 1;
+    double delta = std::numeric_limits<double>::max();
+    for (unsigned int i=0; i<2; i++)
+      {
+        repetitions[i] = spacing[i].size();
+        n_cells *= repetitions[i];
+        for (unsigned int j=0; j<repetitions[i]; j++)
+          {
+            Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
+            delta = std::min (delta, spacing[i][j]);
+          }
+        Assert(material_id.size(i) == repetitions[i],
+               ExcInvalidRepetitionsDimension(i));
+      }
 
-  // create the cells
-  size_type n_val_cells = 0;
-  for (size_type i=0; i<material_id.size(0); i++)
-    for (size_type j=0; j<material_id.size(1); j++)
-      if (material_id[i][j] != numbers::invalid_material_id)
-        n_val_cells++;
-
-  std::vector<CellData<2> > cells(n_val_cells);
-  size_type id = 0;
-  for (size_type y=0; y<repetitions[1]; ++y)
-    for (size_type x=0; x<repetitions[0]; ++x)
-      if (material_id[x][y]!=numbers::invalid_material_id)
-        {
-          cells[id].vertices[0] = y*(repetitions[0]+1)+x;
-          cells[id].vertices[1] = y*(repetitions[0]+1)+x+1;
-          cells[id].vertices[2] = (y+1)*(repetitions[0]+1)+x;
-          cells[id].vertices[3] = (y+1)*(repetitions[0]+1)+x+1;
-          cells[id].material_id = material_id[x][y];
-          id++;
-        }
+    // generate the necessary points
+    std::vector<Point<2> > points;
+    double ay = p[1];
+    for (unsigned int y=0; y<=repetitions[1]; ++y)
+      {
+        double ax = p[0];
+        for (unsigned int x=0; x<=repetitions[0]; ++x)
+          {
+            points.push_back (Point<2> (ax,ay));
+            if (x<repetitions[0])
+              ax += spacing[0][x];
+          }
+        if (y<repetitions[1])
+          ay += spacing[1][y];
+      }
 
-  // create triangulation
-  SubCellData t;
-  GridTools::delete_unused_vertices (points, cells, t);
+    // create the cells
+    unsigned int n_val_cells = 0;
+    for (unsigned int i=0; i<material_id.size(0); i++)
+      for (unsigned int j=0; j<material_id.size(1); j++)
+        if (material_id[i][j] != numbers::invalid_material_id)
+          n_val_cells++;
 
-  tria.create_triangulation (points, cells, t);
+    std::vector<CellData<2> > cells(n_val_cells);
+    unsigned int id = 0;
+    for (unsigned int y=0; y<repetitions[1]; ++y)
+      for (unsigned int x=0; x<repetitions[0]; ++x)
+        if (material_id[x][y]!=numbers::invalid_material_id)
+          {
+            cells[id].vertices[0] = y*(repetitions[0]+1)+x;
+            cells[id].vertices[1] = y*(repetitions[0]+1)+x+1;
+            cells[id].vertices[2] = (y+1)*(repetitions[0]+1)+x;
+            cells[id].vertices[3] = (y+1)*(repetitions[0]+1)+x+1;
+            cells[id].material_id = material_id[x][y];
+            id++;
+          }
 
-  // set boundary indicator
-  if (colorize)
-    {
-      double eps = 0.01 * delta;
-      Triangulation<2>::cell_iterator cell = tria.begin(),
-                                      endc = tria.end();
-      for (; cell !=endc; ++cell)
-        {
-          Point<2> cell_center = cell->center();
-          for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
-            if (cell->face(f)->boundary_indicator() == 0)
-              {
-                Point<2> face_center = cell->face(f)->center();
-                for (unsigned int i=0; i<2; ++i)
-                  {
-                    if (face_center[i]<cell_center[i]-eps)
-                      cell->face(f)->set_boundary_indicator(i*2);
-                    if (face_center[i]>cell_center[i]+eps)
-                      cell->face(f)->set_boundary_indicator(i*2+1);
-                  }
-              }
-        }
-    }
-}
+    // create triangulation
+    SubCellData t;
+    GridTools::delete_unused_vertices (points, cells, t);
 
+    tria.create_triangulation (points, cells, t);
 
-template <>
-void
-GridGenerator::subdivided_hyper_rectangle (
-  Triangulation<3>                           &tria,
-  const std::vector< std::vector<double> >     &spacing,
-  const Point<3>                             &p,
-  const Table<3,types::material_id>               &material_id,
-  const bool                                    colorize)
-{
-  // contributed by Yaqi Wang 2006
-  const unsigned int dim = 3;
+    // set boundary indicator
+    if (colorize)
+      {
+        double eps = 0.01 * delta;
+        Triangulation<2>::cell_iterator cell = tria.begin(),
+                                        endc = tria.end();
+        for (; cell !=endc; ++cell)
+          {
+            Point<2> cell_center = cell->center();
+            for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
+              if (cell->face(f)->boundary_indicator() == 0)
+                {
+                  Point<2> face_center = cell->face(f)->center();
+                  for (unsigned int i=0; i<2; ++i)
+                    {
+                      if (face_center[i]<cell_center[i]-eps)
+                        cell->face(f)->set_boundary_indicator(i*2);
+                      if (face_center[i]>cell_center[i]+eps)
+                        cell->face(f)->set_boundary_indicator(i*2+1);
+                    }
+                }
+          }
+      }
+  }
 
-  Assert(spacing.size() == dim,
-         ExcInvalidRepetitionsDimension(dim));
 
-  std::vector<size_type > repetitions(dim);
-  size_type n_cells = 1;
-  double delta = std::numeric_limits<double>::max();
-  for (unsigned int i=0; i<dim; i++)
-    {
-      repetitions[i] = spacing[i].size();
-      n_cells *= repetitions[i];
-      for (size_type j=0; j<repetitions[i]; j++)
-        {
-          Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
-          delta = std::min (delta, spacing[i][j]);
-        }
-      Assert(material_id.size(i) == repetitions[i],
-             ExcInvalidRepetitionsDimension(i));
-    }
+  template <>
+  void
+  subdivided_hyper_rectangle (
+    Triangulation<3>                           &tria,
+    const std::vector< std::vector<double> >     &spacing,
+    const Point<3>                             &p,
+    const Table<3,types::material_id>               &material_id,
+    const bool                                    colorize)
+  {
+    // contributed by Yaqi Wang 2006
+    const unsigned int dim = 3;
 
-  // generate the necessary points
-  std::vector<Point<dim> > points;
-  double az = p[2];
-  for (size_type z=0; z<=repetitions[2]; ++z)
-    {
-      double ay = p[1];
-      for (size_type y=0; y<=repetitions[1]; ++y)
-        {
-          double ax = p[0];
-          for (size_type x=0; x<=repetitions[0]; ++x)
+    Assert(spacing.size() == dim,
+           ExcInvalidRepetitionsDimension(dim));
+
+    std::vector<unsigned int > repetitions(dim);
+    unsigned int n_cells = 1;
+    double delta = std::numeric_limits<double>::max();
+    for (unsigned int i=0; i<dim; i++)
+      {
+        repetitions[i] = spacing[i].size();
+        n_cells *= repetitions[i];
+        for (unsigned int j=0; j<repetitions[i]; j++)
+          {
+            Assert (spacing[i][j] >= 0, ExcInvalidRepetitions(-1));
+            delta = std::min (delta, spacing[i][j]);
+          }
+        Assert(material_id.size(i) == repetitions[i],
+               ExcInvalidRepetitionsDimension(i));
+      }
+
+    // generate the necessary points
+    std::vector<Point<dim> > points;
+    double az = p[2];
+    for (unsigned int z=0; z<=repetitions[2]; ++z)
+      {
+        double ay = p[1];
+        for (unsigned int y=0; y<=repetitions[1]; ++y)
+          {
+            double ax = p[0];
+            for (unsigned int x=0; x<=repetitions[0]; ++x)
+              {
+                points.push_back (Point<dim> (ax,ay,az));
+                if (x<repetitions[0])
+                  ax += spacing[0][x];
+              }
+            if (y<repetitions[1])
+              ay += spacing[1][y];
+          }
+        if (z<repetitions[2])
+          az += spacing[2][z];
+      }
+
+    // create the cells
+    unsigned int n_val_cells = 0;
+    for (unsigned int i=0; i<material_id.size(0); i++)
+      for (unsigned int j=0; j<material_id.size(1); j++)
+        for (unsigned int k=0; k<material_id.size(2); k++)
+          if (material_id[i][j][k]!=numbers::invalid_material_id)
+            n_val_cells++;
+
+    std::vector<CellData<dim> > cells(n_val_cells);
+    unsigned int id = 0;
+    const unsigned int n_x  = (repetitions[0]+1);
+    const unsigned int n_xy = (repetitions[0]+1)*(repetitions[1]+1);
+    for (unsigned int z=0; z<repetitions[2]; ++z)
+      for (unsigned int y=0; y<repetitions[1]; ++y)
+        for (unsigned int x=0; x<repetitions[0]; ++x)
+          if (material_id[x][y][z]!=numbers::invalid_material_id)
             {
-              points.push_back (Point<dim> (ax,ay,az));
-              if (x<repetitions[0])
-                ax += spacing[0][x];
+              cells[id].vertices[0] = z*n_xy + y*n_x + x;
+              cells[id].vertices[1] = z*n_xy + y*n_x + x+1;
+              cells[id].vertices[2] = z*n_xy + (y+1)*n_x + x;
+              cells[id].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
+              cells[id].vertices[4] = (z+1)*n_xy + y*n_x + x;
+              cells[id].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
+              cells[id].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
+              cells[id].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
+              cells[id].material_id = material_id[x][y][z];
+              id++;
             }
-          if (y<repetitions[1])
-            ay += spacing[1][y];
-        }
-      if (z<repetitions[2])
-        az += spacing[2][z];
-    }
 
-  // create the cells
-  size_type n_val_cells = 0;
-  for (size_type i=0; i<material_id.size(0); i++)
-    for (size_type j=0; j<material_id.size(1); j++)
-      for (size_type k=0; k<material_id.size(2); k++)
-        if (material_id[i][j][k]!=numbers::invalid_material_id)
-          n_val_cells++;
+    // create triangulation
+    SubCellData t;
+    GridTools::delete_unused_vertices (points, cells, t);
 
-  std::vector<CellData<dim> > cells(n_val_cells);
-  size_type id = 0;
-  const size_type n_x  = (repetitions[0]+1);
-  const size_type n_xy = (repetitions[0]+1)*(repetitions[1]+1);
-  for (size_type z=0; z<repetitions[2]; ++z)
-    for (size_type y=0; y<repetitions[1]; ++y)
-      for (size_type x=0; x<repetitions[0]; ++x)
-        if (material_id[x][y][z]!=numbers::invalid_material_id)
+    tria.create_triangulation (points, cells, t);
+
+    // set boundary indicator
+    if (colorize && dim>1)
+      {
+        double eps = 0.01 * delta;
+        Triangulation<dim>::cell_iterator cell = tria.begin(),
+                                          endc = tria.end();
+        for (; cell !=endc; ++cell)
           {
-            cells[id].vertices[0] = z*n_xy + y*n_x + x;
-            cells[id].vertices[1] = z*n_xy + y*n_x + x+1;
-            cells[id].vertices[2] = z*n_xy + (y+1)*n_x + x;
-            cells[id].vertices[3] = z*n_xy + (y+1)*n_x + x+1;
-            cells[id].vertices[4] = (z+1)*n_xy + y*n_x + x;
-            cells[id].vertices[5] = (z+1)*n_xy + y*n_x + x+1;
-            cells[id].vertices[6] = (z+1)*n_xy + (y+1)*n_x + x;
-            cells[id].vertices[7] = (z+1)*n_xy + (y+1)*n_x + x+1;
-            cells[id].material_id = material_id[x][y][z];
-            id++;
+            Point<dim> cell_center = cell->center();
+            for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+              if (cell->face(f)->boundary_indicator() == 0)
+                {
+                  Point<dim> face_center = cell->face(f)->center();
+                  for (unsigned int i=0; i<dim; ++i)
+                    {
+                      if (face_center[i]<cell_center[i]-eps)
+                        cell->face(f)->set_boundary_indicator(i*2);
+                      if (face_center[i]>cell_center[i]+eps)
+                        cell->face(f)->set_boundary_indicator(i*2+1);
+                    }
+                }
           }
+      }
+  }
 
-  // create triangulation
-  SubCellData t;
-  GridTools::delete_unused_vertices (points, cells, t);
 
-  tria.create_triangulation (points, cells, t);
 
-  // set boundary indicator
-  if (colorize && dim>1)
-    {
-      double eps = 0.01 * delta;
-      Triangulation<dim>::cell_iterator cell = tria.begin(),
-                                        endc = tria.end();
-      for (; cell !=endc; ++cell)
-        {
-          Point<dim> cell_center = cell->center();
-          for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-            if (cell->face(f)->boundary_indicator() == 0)
-              {
-                Point<dim> face_center = cell->face(f)->center();
-                for (unsigned int i=0; i<dim; ++i)
-                  {
-                    if (face_center[i]<cell_center[i]-eps)
-                      cell->face(f)->set_boundary_indicator(i*2);
-                    if (face_center[i]>cell_center[i]+eps)
-                      cell->face(f)->set_boundary_indicator(i*2+1);
-                  }
-              }
-        }
-    }
-}
+  template <>
+  void hyper_cube_slit (Triangulation<1> &,
+                        const double,
+                        const double,
+                        const bool)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
 
-template <>
-void
-GridGenerator::colorize_subdivided_hyper_rectangle (
-  Triangulation<1> &tria,
-  const Point<1> &,
-  const Point<1> &,
-  const double)
-{
-  for (Triangulation<1>::cell_iterator cell = tria.begin();
-       cell != tria.end(); ++cell)
-    if (cell->center()(0) > 0)
-      cell->set_material_id(1);
-  // boundary indicators are set to
-  // 0 (left) and 1 (right) by default.
-}
+  template <>
+  void enclosed_hyper_cube (Triangulation<1> &,
+                            const double,
+                            const double,
+                            const double,
+                            const bool)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
 
-template <int dim>
-void
-GridGenerator::colorize_subdivided_hyper_rectangle (Triangulation<dim> &tria,
-                                                    const Point<dim>   &p1,
-                                                    const Point<dim>   &p2,
-                                                    const double        epsilon)
-{
+  template <>
+  void hyper_L (Triangulation<1> &,
+                const double,
+                const double)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
-  // run through all faces and check
-  // if one of their center coordinates matches
-  // one of the corner points. Comparisons
-  // are made using an epsilon which
-  // should be smaller than the smallest cell
-  // diameter.
 
-  typename Triangulation<dim>::face_iterator face = tria.begin_face(),
-                                             endface = tria.end_face();
-  for (; face!=endface; ++face)
-    {
-      if (face->boundary_indicator() == 0)
-        {
-          const Point<dim> center (face->center());
-          if (std::abs(center(0)-p1[0]) < epsilon)
-            face->set_boundary_indicator(0);
-          else if (std::abs(center(0) - p2[0]) < epsilon)
-            face->set_boundary_indicator(1);
-          else if (dim > 1 && std::abs(center(1) - p1[1]) < epsilon)
-            face->set_boundary_indicator(2);
-          else if (dim > 1 && std::abs(center(1) - p2[1]) < epsilon)
-            face->set_boundary_indicator(3);
-          else if (dim > 2 && std::abs(center(2) - p1[2]) < epsilon)
-            face->set_boundary_indicator(4);
-          else if (dim > 2 && std::abs(center(2) - p2[2]) < epsilon)
-            face->set_boundary_indicator(5);
-          else
-            // triangulation says it
-            // is on the boundary,
-            // but we could not find
-            // on which boundary.
-            Assert (false, ExcInternalError());
 
-        }
-    }
-  for (typename Triangulation<dim>::cell_iterator cell = tria.begin();
-       cell != tria.end(); ++cell)
-    {
-      char id = 0;
-      for (unsigned int d=0; d<dim; ++d)
-        if (cell->center()(d) > 0) id += 1 << d;
-      cell->set_material_id(id);
-    }
-}
+  template <>
+  void hyper_ball (Triangulation<1> &,
+                   const Point<1> &,
+                   const double)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
-template <>
-void GridGenerator::hyper_cube_slit (Triangulation<1> &,
-                                     const double,
-                                     const double,
-                                     const bool)
-{
-  Assert (false, ExcNotImplemented());
-}
 
+  template <>
+  void cylinder (Triangulation<1> &,
+                 const double,
+                 const double)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
-template <>
-void GridGenerator::enclosed_hyper_cube (Triangulation<1> &,
-                                         const double,
-                                         const double,
-                                         const double,
-                                         const bool)
-{
-  Assert (false, ExcNotImplemented());
-}
 
+  template <>
+  void truncated_cone (Triangulation<1> &,
+                       const double,
+                       const double,
+                       const double)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
-template <>
-void GridGenerator::hyper_L (Triangulation<1> &,
-                             const double,
-                             const double)
-{
-  Assert (false, ExcNotImplemented());
-}
 
+  template <>
+  void hyper_shell (Triangulation<1> &,
+                    const Point<1> &,
+                    const double,
+                    const double,
+                    const unsigned int ,
+                    const bool)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
-template <>
-void GridGenerator::hyper_ball (Triangulation<1> &,
-                                const Point<1> &,
-                                const double)
-{
-  Assert (false, ExcNotImplemented());
-}
+  template <>
+  void cylinder_shell (Triangulation<1> &,
+                       const double,
+                       const double,
+                       const double,
+                       const unsigned int ,
+                       const unsigned int )
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
 
+  template <>
+  void
+  half_hyper_ball (Triangulation<1> &,
+                   const Point<1> &,
+                   const double)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
-template <>
-void GridGenerator::cylinder (Triangulation<1> &,
-                              const double,
-                              const double)
-{
-  Assert (false, ExcNotImplemented());
-}
 
+  template <>
+  void
+  half_hyper_shell (Triangulation<1> &,
+                    const Point<1> &,
+                    const double,
+                    const double,
+                    const unsigned int ,
+                    const bool)
+  {
+    Assert (false, ExcNotImplemented());
+  }
+
+  template <>
+  void quarter_hyper_shell (Triangulation<1> &,
+                            const Point<1> &,
+                            const double,
+                            const double,
+                            const unsigned int ,
+                            const bool)
+  {
+    Assert (false, ExcNotImplemented());
+  }
+
+  template <>
+  void enclosed_hyper_cube (Triangulation<2> &tria,
+                            const double        left,
+                            const double        right,
+                            const double        thickness,
+                            const bool          colorize)
+  {
+    Assert(left<right,
+           ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
+
+    std::vector<Point<2> > vertices(16);
+    double coords[4];
+    coords[0] = left-thickness;
+    coords[1] = left;
+    coords[2] = right;
+    coords[3] = right+thickness;
+
+    unsigned int k=0;
+    for (unsigned int i0=0; i0<4; ++i0)
+      for (unsigned int i1=0; i1<4; ++i1)
+        vertices[k++] = Point<2>(coords[i1], coords[i0]);
+
+    const types::material_id materials[9] = { 5, 4, 6,
+                                              1, 0, 2,
+                                              9, 8,10
+                                            };
+
+    std::vector<CellData<2> > cells(9);
+    k = 0;
+    for (unsigned int i0=0; i0<3; ++i0)
+      for (unsigned int i1=0; i1<3; ++i1)
+        {
+          cells[k].vertices[0] = i1+4*i0;
+          cells[k].vertices[1] = i1+4*i0+1;
+          cells[k].vertices[2] = i1+4*i0+4;
+          cells[k].vertices[3] = i1+4*i0+5;
+          if (colorize)
+            cells[k].material_id = materials[k];
+          ++k;
+        }
+    tria.create_triangulation (vertices,
+                               cells,
+                               SubCellData());       // no boundary information
+  }
 
 
-template <>
-void GridGenerator::truncated_cone (Triangulation<1> &,
-                                    const double,
-                                    const double,
-                                    const double)
-{
-  Assert (false, ExcNotImplemented());
-}
 
+// Implementation for 2D only
+  template <>
+  void
+  hyper_cube_slit (Triangulation<2> &tria,
+                   const double left,
+                   const double right,
+                   const bool colorize)
+  {
+    const double rl2=(right+left)/2;
+    const Point<2> vertices[10] = { Point<2>(left, left ),
+                                    Point<2>(rl2,  left ),
+                                    Point<2>(rl2,  rl2  ),
+                                    Point<2>(left, rl2  ),
+                                    Point<2>(right,left ),
+                                    Point<2>(right,rl2  ),
+                                    Point<2>(rl2,  right),
+                                    Point<2>(left, right),
+                                    Point<2>(right,right),
+                                    Point<2>(rl2,  left )
+                                  };
+    const int cell_vertices[4][4] = { { 0,1,3,2 },
+      { 9,4,2,5 },
+      { 3,2,7,6 },
+      { 2,5,6,8 }
+    };
+    std::vector<CellData<2> > cells (4, CellData<2>());
+    for (unsigned int i=0; i<4; ++i)
+      {
+        for (unsigned int j=0; j<4; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
+    tria.create_triangulation (
+      std::vector<Point<2> >(&vertices[0], &vertices[10]),
+      cells,
+      SubCellData());       // no boundary information
 
+    if (colorize)
+      {
+        Triangulation<2>::cell_iterator cell = tria.begin();
+        cell->face(1)->set_boundary_indicator(1);
+        ++cell;
+        cell->face(3)->set_boundary_indicator(2);
+      }
+  }
 
-template <>
-void GridGenerator::hyper_shell (Triangulation<1> &,
-                                 const Point<1> &,
-                                 const double,
-                                 const double,
-                                 const size_type ,
-                                 const bool)
-{
-  Assert (false, ExcNotImplemented());
-}
 
 
-template <>
-void GridGenerator::colorize_hyper_shell (Triangulation<1> &,
-                                          const Point<1> &,
-                                          const double,
-                                          const double)
-{
-  Assert (false, ExcNotImplemented());
-}
+  template <>
+  void truncated_cone (Triangulation<2> &triangulation,
+                       const double radius_0,
+                       const double radius_1,
+                       const double half_length)
+  {
+    Point<2> vertices_tmp[4];
 
+    vertices_tmp[0] = Point<2> (-half_length, -radius_0);
+    vertices_tmp[1] = Point<2> (half_length, -radius_1);
+    vertices_tmp[2] = Point<2> (-half_length, radius_0);
+    vertices_tmp[3] = Point<2> (half_length, radius_1);
 
-template <>
-void GridGenerator::cylinder_shell (Triangulation<1> &,
-                                    const double,
-                                    const double,
-                                    const double,
-                                    const size_type ,
-                                    const size_type )
-{
-  Assert (false, ExcNotImplemented());
-}
+    const std::vector<Point<2> > vertices (&vertices_tmp[0], &vertices_tmp[4]);
+    unsigned int cell_vertices[1][GeometryInfo<2>::vertices_per_cell];
 
+    for (unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
+      cell_vertices[0][i] = i;
 
-template <>
-void
-GridGenerator::half_hyper_ball (Triangulation<1> &,
-                                const Point<1> &,
-                                const double)
-{
-  Assert (false, ExcNotImplemented());
-}
+    std::vector<CellData<2> > cells (1, CellData<2> ());
 
+    for (unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
+      cells[0].vertices[i] = cell_vertices[0][i];
 
-template <>
-void
-GridGenerator::half_hyper_shell (Triangulation<1> &,
-                                 const Point<1> &,
-                                 const double,
-                                 const double,
-                                 const size_type ,
-                                 const bool)
-{
-  Assert (false, ExcNotImplemented());
-}
+    cells[0].material_id = 0;
+    triangulation.create_triangulation (vertices, cells, SubCellData ());
 
-template <>
-void GridGenerator::quarter_hyper_shell (Triangulation<1> &,
-                                         const Point<1> &,
-                                         const double,
-                                         const double,
-                                         const size_type ,
-                                         const bool)
-{
-  Assert (false, ExcNotImplemented());
-}
+    Triangulation<2>::cell_iterator cell = triangulation.begin ();
 
-template <>
-void GridGenerator::enclosed_hyper_cube (Triangulation<2> &tria,
-                                         const double        left,
-                                         const double        right,
-                                         const double        thickness,
-                                         const bool          colorize)
-{
-  Assert(left<right,
-         ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
-
-  std::vector<Point<2> > vertices(16);
-  double coords[4];
-  coords[0] = left-thickness;
-  coords[1] = left;
-  coords[2] = right;
-  coords[3] = right+thickness;
-
-  unsigned int k=0;
-  for (unsigned int i0=0; i0<4; ++i0)
-    for (unsigned int i1=0; i1<4; ++i1)
-      vertices[k++] = Point<2>(coords[i1], coords[i0]);
-
-  const types::material_id materials[9] = { 5, 4, 6,
-                                            1, 0, 2,
-                                            9, 8,10
-                                          };
-
-  std::vector<CellData<2> > cells(9);
-  k = 0;
-  for (unsigned int i0=0; i0<3; ++i0)
-    for (unsigned int i1=0; i1<3; ++i1)
-      {
-        cells[k].vertices[0] = i1+4*i0;
-        cells[k].vertices[1] = i1+4*i0+1;
-        cells[k].vertices[2] = i1+4*i0+4;
-        cells[k].vertices[3] = i1+4*i0+5;
-        if (colorize)
-          cells[k].material_id = materials[k];
-        ++k;
-      }
-  tria.create_triangulation (vertices,
-                             cells,
-                             SubCellData());       // no boundary information
-}
+    cell->face (0)->set_boundary_indicator (1);
+    cell->face (1)->set_boundary_indicator (2);
+
+    for (unsigned int i = 2; i < 4; ++i)
+      cell->face (i)->set_boundary_indicator (0);
+  }
 
 
 
+//TODO: Colorize edges as circumference, left and right radius
 // Implementation for 2D only
-template <>
-void
-GridGenerator::hyper_cube_slit (Triangulation<2> &tria,
-                                const double left,
-                                const double right,
-                                const bool colorize)
-{
-  const double rl2=(right+left)/2;
-  const Point<2> vertices[10] = { Point<2>(left, left ),
-                                  Point<2>(rl2,  left ),
-                                  Point<2>(rl2,  rl2  ),
-                                  Point<2>(left, rl2  ),
-                                  Point<2>(right,left ),
-                                  Point<2>(right,rl2  ),
-                                  Point<2>(rl2,  right),
-                                  Point<2>(left, right),
-                                  Point<2>(right,right),
-                                  Point<2>(rl2,  left )
-                                };
-  const int cell_vertices[4][4] = { { 0,1,3,2 },
-    { 9,4,2,5 },
-    { 3,2,7,6 },
-    { 2,5,6,8 }
-  };
-  std::vector<CellData<2> > cells (4, CellData<2>());
-  for (unsigned int i=0; i<4; ++i)
-    {
-      for (unsigned int j=0; j<4; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
+  template <>
+  void
+  hyper_L (Triangulation<2> &tria,
+           const double a,
+           const double b)
+  {
+    const Point<2> vertices[8] = { Point<2> (a,a),
+                                   Point<2> ((a+b)/2,a),
+                                   Point<2> (b,a),
+                                   Point<2> (a,(a+b)/2),
+                                   Point<2> ((a+b)/2,(a+b)/2),
+                                   Point<2> (b,(a+b)/2),
+                                   Point<2> (a,b),
+                                   Point<2> ((a+b)/2,b)
+                                 };
+    const int cell_vertices[3][4] = {{0, 1, 3, 4},
+      {1, 2, 4, 5},
+      {3, 4, 6, 7}
     };
-  tria.create_triangulation (
-    std::vector<Point<2> >(&vertices[0], &vertices[10]),
-    cells,
-    SubCellData());       // no boundary information
 
-  if (colorize)
-    {
-      Triangulation<2>::cell_iterator cell = tria.begin();
-      cell->face(1)->set_boundary_indicator(1);
-      ++cell;
-      cell->face(3)->set_boundary_indicator(2);
-    }
-}
+    std::vector<CellData<2> > cells (3, CellData<2>());
 
+    for (unsigned int i=0; i<3; ++i)
+      {
+        for (unsigned int j=0; j<4; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
+    tria.create_triangulation (
+      std::vector<Point<2> >(&vertices[0], &vertices[8]),
+      cells,
+      SubCellData());       // no boundary information
+  }
 
-template <>
-void GridGenerator::truncated_cone (Triangulation<2> &triangulation,
-                                    const double radius_0,
-                                    const double radius_1,
-                                    const double half_length)
-{
-  Point<2> vertices_tmp[4];
 
-  vertices_tmp[0] = Point<2> (-half_length, -radius_0);
-  vertices_tmp[1] = Point<2> (half_length, -radius_1);
-  vertices_tmp[2] = Point<2> (-half_length, radius_0);
-  vertices_tmp[3] = Point<2> (half_length, radius_1);
 
-  const std::vector<Point<2> > vertices (&vertices_tmp[0], &vertices_tmp[4]);
-  unsigned int cell_vertices[1][GeometryInfo<2>::vertices_per_cell];
+// Implementation for 2D only
+  template <>
+  void
+  hyper_ball (Triangulation<2> &tria,
+              const Point<2>   &p,
+              const double      radius)
+  {
+    // equilibrate cell sizes at
+    // transition from the inner part
+    // to the radial cells
+    const double a = 1./(1+std::sqrt(2.0));
+    const Point<2> vertices[8] = { p+Point<2>(-1,-1) *(radius/std::sqrt(2.0)),
+                                   p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)),
+                                   p+Point<2>(-1,-1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(-1,+1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(+1,+1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(-1,+1) *(radius/std::sqrt(2.0)),
+                                   p+Point<2>(+1,+1) *(radius/std::sqrt(2.0))
+                                 };
+
+    const int cell_vertices[5][4] = {{0, 1, 2, 3},
+      {0, 2, 6, 4},
+      {2, 3, 4, 5},
+      {1, 7, 3, 5},
+      {6, 4, 7, 5}
+    };
 
-  for (unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
-    cell_vertices[0][i] = i;
+    std::vector<CellData<2> > cells (5, CellData<2>());
 
-  std::vector<CellData<2> > cells (1, CellData<2> ());
+    for (unsigned int i=0; i<5; ++i)
+      {
+        for (unsigned int j=0; j<4; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
-  for (unsigned int i = 0; i < GeometryInfo<2>::vertices_per_cell; ++i)
-    cells[0].vertices[i] = cell_vertices[0][i];
+    tria.create_triangulation (
+      std::vector<Point<2> >(&vertices[0], &vertices[8]),
+      cells,
+      SubCellData());       // no boundary information
+  }
 
-  cells[0].material_id = 0;
-  triangulation.create_triangulation (vertices, cells, SubCellData ());
 
-  Triangulation<2>::cell_iterator cell = triangulation.begin ();
 
-  cell->face (0)->set_boundary_indicator (1);
-  cell->face (1)->set_boundary_indicator (2);
+  template <>
+  void hyper_shell (Triangulation<2> &tria,
+                    const Point<2>   &center,
+                    const double      inner_radius,
+                    const double      outer_radius,
+                    const unsigned int   n_cells,
+                    const bool colorize)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
+
+    const double pi = numbers::PI;
+
+    // determine the number of cells
+    // for the grid. if not provided by
+    // the user determine it such that
+    // the length of each cell on the
+    // median (in the middle between
+    // the two circles) is equal to its
+    // radial extent (which is the
+    // difference between the two
+    // radii)
+    const unsigned int N = (n_cells == 0 ?
+                            static_cast<unsigned int>
+                            (std::ceil((2*pi* (outer_radius + inner_radius)/2) /
+                                       (outer_radius - inner_radius))) :
+                            n_cells);
+
+    // set up N vertices on the
+    // outer and N vertices on
+    // the inner circle. the
+    // first N ones are on the
+    // outer one, and all are
+    // numbered counter-clockwise
+    std::vector<Point<2> > vertices(2*N);
+    for (unsigned int i=0; i<N; ++i)
+      {
+        vertices[i] = Point<2>( std::cos(2*pi * i/N),
+                                std::sin(2*pi * i/N)) * outer_radius;
+        vertices[i+N] = vertices[i] * (inner_radius/outer_radius);
 
-  for (unsigned int i = 2; i < 4; ++i)
-    cell->face (i)->set_boundary_indicator (0);
-}
+        vertices[i]   += center;
+        vertices[i+N] += center;
+      };
 
+    std::vector<CellData<2> > cells (N, CellData<2>());
 
+    for (unsigned int i=0; i<N; ++i)
+      {
+        cells[i].vertices[0] = i;
+        cells[i].vertices[1] = (i+1)%N;
+        cells[i].vertices[2] = N+i;
+        cells[i].vertices[3] = N+((i+1)%N);
 
-//TODO: Colorize edges as circumference, left and right radius
-// Implementation for 2D only
-template <>
-void
-GridGenerator::hyper_L (Triangulation<2> &tria,
-                        const double a,
-                        const double b)
-{
-  const Point<2> vertices[8] = { Point<2> (a,a),
-                                 Point<2> ((a+b)/2,a),
-                                 Point<2> (b,a),
-                                 Point<2> (a,(a+b)/2),
-                                 Point<2> ((a+b)/2,(a+b)/2),
-                                 Point<2> (b,(a+b)/2),
-                                 Point<2> (a,b),
-                                 Point<2> ((a+b)/2,b)
-                               };
-  const int cell_vertices[3][4] = {{0, 1, 3, 4},
-    {1, 2, 4, 5},
-    {3, 4, 6, 7}
-  };
-
-  std::vector<CellData<2> > cells (3, CellData<2>());
-
-  for (unsigned int i=0; i<3; ++i)
-    {
-      for (unsigned int j=0; j<4; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
-    };
+        cells[i].material_id = 0;
+      };
 
-  tria.create_triangulation (
-    std::vector<Point<2> >(&vertices[0], &vertices[8]),
-    cells,
-    SubCellData());       // no boundary information
-}
+    tria.create_triangulation (
+      vertices, cells, SubCellData());
 
+    if (colorize)
+      colorize_hyper_shell(tria, center, inner_radius, outer_radius);
+  }
 
 
 // Implementation for 2D only
-template <>
-void
-GridGenerator::hyper_ball (Triangulation<2> &tria,
-                           const Point<2>   &p,
-                           const double      radius)
-{
-  // equilibrate cell sizes at
-  // transition from the inner part
-  // to the radial cells
-  const double a = 1./(1+std::sqrt(2.0));
-  const Point<2> vertices[8] = { p+Point<2>(-1,-1) *(radius/std::sqrt(2.0)),
-                                 p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)),
-                                 p+Point<2>(-1,-1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(-1,+1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(+1,+1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(-1,+1) *(radius/std::sqrt(2.0)),
-                                 p+Point<2>(+1,+1) *(radius/std::sqrt(2.0))
-                               };
-
-  const int cell_vertices[5][4] = {{0, 1, 2, 3},
-    {0, 2, 6, 4},
-    {2, 3, 4, 5},
-    {1, 7, 3, 5},
-    {6, 4, 7, 5}
-  };
-
-  std::vector<CellData<2> > cells (5, CellData<2>());
-
-  for (unsigned int i=0; i<5; ++i)
-    {
-      for (unsigned int j=0; j<4; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
-    };
+  template <>
+  void
+  cylinder (Triangulation<2> &tria,
+            const double radius,
+            const double half_length)
+  {
+    Point<2> p1 (-half_length, -radius);
+    Point<2> p2 (half_length, radius);
 
-  tria.create_triangulation (
-    std::vector<Point<2> >(&vertices[0], &vertices[8]),
-    cells,
-    SubCellData());       // no boundary information
-}
+    hyper_rectangle(tria, p1, p2, true);
+
+    Triangulation<2>::face_iterator f = tria.begin_face();
+    Triangulation<2>::face_iterator end = tria.end_face();
+    while (f != end)
+      {
+        switch (f->boundary_indicator())
+          {
+          case 0:
+            f->set_boundary_indicator(1);
+            break;
+          case 1:
+            f->set_boundary_indicator(2);
+            break;
+          default:
+            f->set_boundary_indicator(0);
+            break;
+          }
+        ++f;
+      }
+  }
 
 
 
 // Implementation for 2D only
-template<>
-void
-GridGenerator::colorize_hyper_shell (
-  Triangulation<2> &tria,
-  const Point<2> &, const double, const double)
-{
-  // In spite of receiving geometrical
-  // data, we do this only based on
-  // topology.
-
-  // For the mesh based on  cube,
-  // this is highly irregular
-  for (Triangulation<2>::cell_iterator cell = tria.begin();
-       cell != tria.end(); ++cell)
-    {
-      Assert (cell->face(2)->at_boundary(), ExcInternalError());
-      cell->face(2)->set_boundary_indicator(1);
-    }
-}
-
+  template <>
+  void cylinder_shell (Triangulation<2> &,
+                       const double,
+                       const double,
+                       const double,
+                       const unsigned int,
+                       const unsigned int)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
-template <>
-void GridGenerator::hyper_shell (Triangulation<2> &tria,
-                                 const Point<2>   &center,
-                                 const double      inner_radius,
-                                 const double      outer_radius,
-                                 const size_type   n_cells,
-                                 const bool colorize)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
-
-  const double pi = numbers::PI;
-
-  // determine the number of cells
-  // for the grid. if not provided by
-  // the user determine it such that
-  // the length of each cell on the
-  // median (in the middle between
-  // the two circles) is equal to its
-  // radial extent (which is the
-  // difference between the two
-  // radii)
-  const size_type N = (n_cells == 0 ?
-                       static_cast<size_type>
-                       (std::ceil((2*pi* (outer_radius + inner_radius)/2) /
-                                  (outer_radius - inner_radius))) :
-                       n_cells);
-
-  // set up N vertices on the
-  // outer and N vertices on
-  // the inner circle. the
-  // first N ones are on the
-  // outer one, and all are
-  // numbered counter-clockwise
-  std::vector<Point<2> > vertices(2*N);
-  for (size_type i=0; i<N; ++i)
-    {
-      vertices[i] = Point<2>( std::cos(2*pi * i/N),
-                              std::sin(2*pi * i/N)) * outer_radius;
-      vertices[i+N] = vertices[i] * (inner_radius/outer_radius);
 
-      vertices[i]   += center;
-      vertices[i+N] += center;
+  template <>
+  void
+  half_hyper_ball (Triangulation<2> &tria,
+                   const Point<2>   &p,
+                   const double      radius)
+  {
+    // equilibrate cell sizes at
+    // transition from the inner part
+    // to the radial cells
+    const double a = 1./(1+std::sqrt(2.0));
+    const Point<2> vertices[8] = { p+Point<2>(0,-1) *radius,
+                                   p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)),
+                                   p+Point<2>(0,-1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(0,+1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(+1,+1) *(radius/std::sqrt(2.0)*a),
+                                   p+Point<2>(0,+1) *radius,
+                                   p+Point<2>(+1,+1) *(radius/std::sqrt(2.0))
+                                 };
+
+    const int cell_vertices[5][4] = {{0, 1, 2, 3},
+      {2, 3, 4, 5},
+      {1, 7, 3, 5},
+      {6, 4, 7, 5}
     };
 
-  std::vector<CellData<2> > cells (N, CellData<2>());
-
-  for (size_type i=0; i<N; ++i)
-    {
-      cells[i].vertices[0] = i;
-      cells[i].vertices[1] = (i+1)%N;
-      cells[i].vertices[2] = N+i;
-      cells[i].vertices[3] = N+((i+1)%N);
-
-      cells[i].material_id = 0;
-    };
+    std::vector<CellData<2> > cells (4, CellData<2>());
 
-  tria.create_triangulation (
-    vertices, cells, SubCellData());
+    for (unsigned int i=0; i<4; ++i)
+      {
+        for (unsigned int j=0; j<4; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
-  if (colorize)
-    colorize_hyper_shell(tria, center, inner_radius, outer_radius);
-}
+    tria.create_triangulation (
+      std::vector<Point<2> >(&vertices[0], &vertices[8]),
+      cells,
+      SubCellData());       // no boundary information
 
+    Triangulation<2>::cell_iterator cell = tria.begin();
+    Triangulation<2>::cell_iterator end = tria.end();
 
-// Implementation for 2D only
-template <>
-void
-GridGenerator::cylinder (Triangulation<2> &tria,
-                         const double radius,
-                         const double half_length)
-{
-  Point<2> p1 (-half_length, -radius);
-  Point<2> p2 (half_length, radius);
 
-  hyper_rectangle(tria, p1, p2, true);
+    while (cell != end)
+      {
+        for (unsigned int i=0; i<GeometryInfo<2>::faces_per_cell; ++i)
+          {
+            if (cell->face(i)->boundary_indicator() == numbers::internal_face_boundary_id)
+              continue;
 
-  Triangulation<2>::face_iterator f = tria.begin_face();
-  Triangulation<2>::face_iterator end = tria.end_face();
-  while (f != end)
-    {
-      switch (f->boundary_indicator())
-        {
-        case 0:
-          f->set_boundary_indicator(1);
-          break;
-        case 1:
-          f->set_boundary_indicator(2);
-          break;
-        default:
-          f->set_boundary_indicator(0);
-          break;
-        }
-      ++f;
-    }
-}
+            // If x is zero, then this is part of the plane
+            if (cell->face(i)->center()(0) < p(0)+1.e-5)
+              cell->face(i)->set_boundary_indicator(1);
+          }
+        ++cell;
+      }
+  }
 
 
 
 // Implementation for 2D only
-template <>
-void GridGenerator::cylinder_shell (Triangulation<2> &,
-                                    const double,
-                                    const double,
-                                    const double,
-                                    const size_type,
-                                    const size_type)
-{
-  Assert (false, ExcNotImplemented());
-}
+  template <>
+  void
+  half_hyper_shell (Triangulation<2> &tria,
+                    const Point<2>   &center,
+                    const double      inner_radius,
+                    const double      outer_radius,
+                    const unsigned int   n_cells,
+                    const bool colorize)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
+
+    const double pi     = numbers::PI;
+    // determine the number of cells
+    // for the grid. if not provided by
+    // the user determine it such that
+    // the length of each cell on the
+    // median (in the middle between
+    // the two circles) is equal to its
+    // radial extent (which is the
+    // difference between the two
+    // radii)
+    const unsigned int N = (n_cells == 0 ?
+                            static_cast<unsigned int>
+                            (std::ceil((pi* (outer_radius + inner_radius)/2) /
+                                       (outer_radius - inner_radius))) :
+                            n_cells);
+
+    // set up N+1 vertices on the
+    // outer and N+1 vertices on
+    // the inner circle. the
+    // first N+1 ones are on the
+    // outer one, and all are
+    // numbered counter-clockwise
+    std::vector<Point<2> > vertices(2*(N+1));
+    for (unsigned int i=0; i<=N; ++i)
+      {
+        // enforce that the x-coordinates
+        // of the first and last point of
+        // each half-circle are exactly
+        // zero (contrary to what we may
+        // compute using the imprecise
+        // value of pi)
+        vertices[i] =  Point<2>( ( (i==0) || (i==N) ?
+                                   0 :
+                                   std::cos(pi * i/N - pi/2) ),
+                                 std::sin(pi * i/N - pi/2)) * outer_radius;
+        vertices[i+N+1] = vertices[i] * (inner_radius/outer_radius);
+
+        vertices[i]     += center;
+        vertices[i+N+1] += center;
+      };
 
 
-template <>
-void
-GridGenerator::half_hyper_ball (Triangulation<2> &tria,
-                                const Point<2>   &p,
-                                const double      radius)
-{
-  // equilibrate cell sizes at
-  // transition from the inner part
-  // to the radial cells
-  const double a = 1./(1+std::sqrt(2.0));
-  const Point<2> vertices[8] = { p+Point<2>(0,-1) *radius,
-                                 p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)),
-                                 p+Point<2>(0,-1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(+1,-1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(0,+1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(+1,+1) *(radius/std::sqrt(2.0)*a),
-                                 p+Point<2>(0,+1) *radius,
-                                 p+Point<2>(+1,+1) *(radius/std::sqrt(2.0))
-                               };
-
-  const int cell_vertices[5][4] = {{0, 1, 2, 3},
-    {2, 3, 4, 5},
-    {1, 7, 3, 5},
-    {6, 4, 7, 5}
-  };
-
-  std::vector<CellData<2> > cells (4, CellData<2>());
-
-  for (unsigned int i=0; i<4; ++i)
-    {
-      for (unsigned int j=0; j<4; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
-    };
+    std::vector<CellData<2> > cells (N, CellData<2>());
 
-  tria.create_triangulation (
-    std::vector<Point<2> >(&vertices[0], &vertices[8]),
-    cells,
-    SubCellData());       // no boundary information
+    for (unsigned int i=0; i<N; ++i)
+      {
+        cells[i].vertices[0] = i;
+        cells[i].vertices[1] = (i+1)%(N+1);
+        cells[i].vertices[2] = N+1+i;
+        cells[i].vertices[3] = N+1+((i+1)%(N+1));
 
-  Triangulation<2>::cell_iterator cell = tria.begin();
-  Triangulation<2>::cell_iterator end = tria.end();
+        cells[i].material_id = 0;
+      };
 
+    tria.create_triangulation (vertices, cells, SubCellData());
 
-  while (cell != end)
-    {
-      for (unsigned int i=0; i<GeometryInfo<2>::faces_per_cell; ++i)
-        {
-          if (cell->face(i)->boundary_indicator() == numbers::internal_face_boundary_id)
-            continue;
+    if (colorize)
+      {
+        Triangulation<2>::cell_iterator cell = tria.begin();
+        for (; cell!=tria.end(); ++cell)
+          {
+            cell->face(2)->set_boundary_indicator(1);
+          }
+        tria.begin()->face(0)->set_boundary_indicator(3);
 
-          // If x is zero, then this is part of the plane
-          if (cell->face(i)->center()(0) < p(0)+1.e-5)
-            cell->face(i)->set_boundary_indicator(1);
-        }
-      ++cell;
-    }
-}
+        tria.last()->face(1)->set_boundary_indicator(2);
+      }
+  }
 
 
+  template <>
+  void quarter_hyper_shell (Triangulation<2> &tria,
+                            const Point<2>   &center,
+                            const double      inner_radius,
+                            const double      outer_radius,
+                            const unsigned int   n_cells,
+                            const bool colorize)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
+
+    const double pi     = numbers::PI;
+    // determine the number of cells
+    // for the grid. if not provided by
+    // the user determine it such that
+    // the length of each cell on the
+    // median (in the middle between
+    // the two circles) is equal to its
+    // radial extent (which is the
+    // difference between the two
+    // radii)
+    const unsigned int N = (n_cells == 0 ?
+                            static_cast<unsigned int>
+                            (std::ceil((pi* (outer_radius + inner_radius)/4) /
+                                       (outer_radius - inner_radius))) :
+                            n_cells);
+
+    // set up N+1 vertices on the
+    // outer and N+1 vertices on
+    // the inner circle. the
+    // first N+1 ones are on the
+    // outer one, and all are
+    // numbered counter-clockwise
+    std::vector<Point<2> > vertices(2*(N+1));
+    for (unsigned int i=0; i<=N; ++i)
+      {
+        // enforce that the x-coordinates
+        // of the last point is exactly
+        // zero (contrary to what we may
+        // compute using the imprecise
+        // value of pi)
+        vertices[i] =  Point<2>( ( (i==N) ?
+                                   0 :
+                                   std::cos(pi * i/N/2) ),
+                                 std::sin(pi * i/N/2)) * outer_radius;
+        vertices[i+N+1] = vertices[i] * (inner_radius/outer_radius);
+
+        vertices[i]     += center;
+        vertices[i+N+1] += center;
+      };
 
-// Implementation for 2D only
-template <>
-void
-GridGenerator::half_hyper_shell (Triangulation<2> &tria,
-                                 const Point<2>   &center,
-                                 const double      inner_radius,
-                                 const double      outer_radius,
-                                 const size_type   n_cells,
-                                 const bool colorize)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
-
-  const double pi     = numbers::PI;
-  // determine the number of cells
-  // for the grid. if not provided by
-  // the user determine it such that
-  // the length of each cell on the
-  // median (in the middle between
-  // the two circles) is equal to its
-  // radial extent (which is the
-  // difference between the two
-  // radii)
-  const size_type N = (n_cells == 0 ?
-                       static_cast<size_type>
-                       (std::ceil((pi* (outer_radius + inner_radius)/2) /
-                                  (outer_radius - inner_radius))) :
-                       n_cells);
-
-  // set up N+1 vertices on the
-  // outer and N+1 vertices on
-  // the inner circle. the
-  // first N+1 ones are on the
-  // outer one, and all are
-  // numbered counter-clockwise
-  std::vector<Point<2> > vertices(2*(N+1));
-  for (size_type i=0; i<=N; ++i)
-    {
-      // enforce that the x-coordinates
-      // of the first and last point of
-      // each half-circle are exactly
-      // zero (contrary to what we may
-      // compute using the imprecise
-      // value of pi)
-      vertices[i] =  Point<2>( ( (i==0) || (i==N) ?
-                                 0 :
-                                 std::cos(pi * i/N - pi/2) ),
-                               std::sin(pi * i/N - pi/2)) * outer_radius;
-      vertices[i+N+1] = vertices[i] * (inner_radius/outer_radius);
-
-      vertices[i]     += center;
-      vertices[i+N+1] += center;
-    };
 
+    std::vector<CellData<2> > cells (N, CellData<2>());
 
-  std::vector<CellData<2> > cells (N, CellData<2>());
+    for (unsigned int i=0; i<N; ++i)
+      {
+        cells[i].vertices[0] = i;
+        cells[i].vertices[1] = (i+1)%(N+1);
+        cells[i].vertices[2] = N+1+i;
+        cells[i].vertices[3] = N+1+((i+1)%(N+1));
 
-  for (size_type i=0; i<N; ++i)
-    {
-      cells[i].vertices[0] = i;
-      cells[i].vertices[1] = (i+1)%(N+1);
-      cells[i].vertices[2] = N+1+i;
-      cells[i].vertices[3] = N+1+((i+1)%(N+1));
+        cells[i].material_id = 0;
+      };
 
-      cells[i].material_id = 0;
-    };
+    tria.create_triangulation (vertices, cells, SubCellData());
 
-  tria.create_triangulation (vertices, cells, SubCellData());
+    if (colorize)
+      {
+        Triangulation<2>::cell_iterator cell = tria.begin();
+        for (; cell!=tria.end(); ++cell)
+          {
+            cell->face(2)->set_boundary_indicator(1);
+          }
+        tria.begin()->face(0)->set_boundary_indicator(3);
 
-  if (colorize)
-    {
-      Triangulation<2>::cell_iterator cell = tria.begin();
-      for (; cell!=tria.end(); ++cell)
-        {
-          cell->face(2)->set_boundary_indicator(1);
-        }
-      tria.begin()->face(0)->set_boundary_indicator(3);
+        tria.last()->face(1)->set_boundary_indicator(2);
+      }
+  }
 
-      tria.last()->face(1)->set_boundary_indicator(2);
-    }
-}
 
 
-template <>
-void GridGenerator::quarter_hyper_shell (Triangulation<2> &tria,
-                                         const Point<2>   &center,
-                                         const double      inner_radius,
-                                         const double      outer_radius,
-                                         const size_type   n_cells,
-                                         const bool colorize)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
-
-  const double pi     = numbers::PI;
-  // determine the number of cells
-  // for the grid. if not provided by
-  // the user determine it such that
-  // the length of each cell on the
-  // median (in the middle between
-  // the two circles) is equal to its
-  // radial extent (which is the
-  // difference between the two
-  // radii)
-  const size_type N = (n_cells == 0 ?
-                       static_cast<size_type>
-                       (std::ceil((pi* (outer_radius + inner_radius)/4) /
-                                  (outer_radius - inner_radius))) :
-                       n_cells);
-
-  // set up N+1 vertices on the
-  // outer and N+1 vertices on
-  // the inner circle. the
-  // first N+1 ones are on the
-  // outer one, and all are
-  // numbered counter-clockwise
-  std::vector<Point<2> > vertices(2*(N+1));
-  for (size_type i=0; i<=N; ++i)
-    {
-      // enforce that the x-coordinates
-      // of the last point is exactly
-      // zero (contrary to what we may
-      // compute using the imprecise
-      // value of pi)
-      vertices[i] =  Point<2>( ( (i==N) ?
-                                 0 :
-                                 std::cos(pi * i/N/2) ),
-                               std::sin(pi * i/N/2)) * outer_radius;
-      vertices[i+N+1] = vertices[i] * (inner_radius/outer_radius);
-
-      vertices[i]     += center;
-      vertices[i+N+1] += center;
+// Implementation for 3D only
+  template <>
+  void hyper_cube_slit (Triangulation<3> &tria,
+                        const double left,
+                        const double right,
+                        const bool colorize)
+  {
+    const double rl2=(right+left)/2;
+    const double len = (right-left)/2.;
+
+    const Point<3> vertices[20] =
+    {
+      Point<3>(left, left , -len/2.),
+      Point<3>(rl2,  left , -len/2.),
+      Point<3>(rl2,  rl2  , -len/2.),
+      Point<3>(left, rl2  , -len/2.),
+      Point<3>(right,left , -len/2.),
+      Point<3>(right,rl2  , -len/2.),
+      Point<3>(rl2,  right, -len/2.),
+      Point<3>(left, right, -len/2.),
+      Point<3>(right,right, -len/2.),
+      Point<3>(rl2,  left , -len/2.),
+      Point<3>(left, left , len/2.),
+      Point<3>(rl2,  left , len/2.),
+      Point<3>(rl2,  rl2  , len/2.),
+      Point<3>(left, rl2  , len/2.),
+      Point<3>(right,left , len/2.),
+      Point<3>(right,rl2  , len/2.),
+      Point<3>(rl2,  right, len/2.),
+      Point<3>(left, right, len/2.),
+      Point<3>(right,right, len/2.),
+      Point<3>(rl2,  left , len/2.)
     };
-
-
-  std::vector<CellData<2> > cells (N, CellData<2>());
-
-  for (size_type i=0; i<N; ++i)
-    {
-      cells[i].vertices[0] = i;
-      cells[i].vertices[1] = (i+1)%(N+1);
-      cells[i].vertices[2] = N+1+i;
-      cells[i].vertices[3] = N+1+((i+1)%(N+1));
-
-      cells[i].material_id = 0;
+    const int cell_vertices[4][8] = { { 0,1,3,2, 10, 11, 13, 12 },
+      { 9,4,2,5, 19,14, 12, 15 },
+      { 3,2,7,6,13,12,17,16 },
+      { 2,5,6,8,12,15,16,18 }
     };
+    std::vector<CellData<3> > cells (4, CellData<3>());
+    for (unsigned int i=0; i<4; ++i)
+      {
+        for (unsigned int j=0; j<8; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
+    tria.create_triangulation (
+      std::vector<Point<3> >(&vertices[0], &vertices[20]),
+      cells,
+      SubCellData());       // no boundary information
 
-  tria.create_triangulation (vertices, cells, SubCellData());
-
-  if (colorize)
-    {
-      Triangulation<2>::cell_iterator cell = tria.begin();
-      for (; cell!=tria.end(); ++cell)
-        {
-          cell->face(2)->set_boundary_indicator(1);
-        }
-      tria.begin()->face(0)->set_boundary_indicator(3);
-
-      tria.last()->face(1)->set_boundary_indicator(2);
-    }
-}
+    if (colorize)
+      {
+        Assert(false, ExcNotImplemented());
+        Triangulation<3>::cell_iterator cell = tria.begin();
+        cell->face(1)->set_boundary_indicator(1);
+        ++cell;
+        cell->face(3)->set_boundary_indicator(2);
+      }
+  }
 
 
 
 // Implementation for 3D only
-template <>
-void GridGenerator::hyper_cube_slit (Triangulation<3> &tria,
-                                     const double left,
-                                     const double right,
-                                     const bool colorize)
-{
-  const double rl2=(right+left)/2;
-  const double len = (right-left)/2.;
-
-  const Point<3> vertices[20] =
+  template <>
+  void enclosed_hyper_cube (Triangulation<3> &tria,
+                            const double        left,
+                            const double        right,
+                            const double        thickness,
+                            const bool          colorize)
   {
-    Point<3>(left, left , -len/2.),
-    Point<3>(rl2,  left , -len/2.),
-    Point<3>(rl2,  rl2  , -len/2.),
-    Point<3>(left, rl2  , -len/2.),
-    Point<3>(right,left , -len/2.),
-    Point<3>(right,rl2  , -len/2.),
-    Point<3>(rl2,  right, -len/2.),
-    Point<3>(left, right, -len/2.),
-    Point<3>(right,right, -len/2.),
-    Point<3>(rl2,  left , -len/2.),
-    Point<3>(left, left , len/2.),
-    Point<3>(rl2,  left , len/2.),
-    Point<3>(rl2,  rl2  , len/2.),
-    Point<3>(left, rl2  , len/2.),
-    Point<3>(right,left , len/2.),
-    Point<3>(right,rl2  , len/2.),
-    Point<3>(rl2,  right, len/2.),
-    Point<3>(left, right, len/2.),
-    Point<3>(right,right, len/2.),
-    Point<3>(rl2,  left , len/2.)
-  };
-  const int cell_vertices[4][8] = { { 0,1,3,2, 10, 11, 13, 12 },
-    { 9,4,2,5, 19,14, 12, 15 },
-    { 3,2,7,6,13,12,17,16 },
-    { 2,5,6,8,12,15,16,18 }
-  };
-  std::vector<CellData<3> > cells (4, CellData<3>());
-  for (unsigned int i=0; i<4; ++i)
-    {
-      for (unsigned int j=0; j<8; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
+    Assert(left<right,
+           ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
+
+    std::vector<Point<3> > vertices(64);
+    double coords[4];
+    coords[0] = left-thickness;
+    coords[1] = left;
+    coords[2] = right;
+    coords[3] = right+thickness;
+
+    unsigned int k=0;
+    for (unsigned int z=0; z<4; ++z)
+      for (unsigned int y=0; y<4; ++y)
+        for (unsigned int x=0; x<4; ++x)
+          vertices[k++] = Point<3>(coords[x], coords[y], coords[z]);
+
+    const types::material_id materials[27] =
+    {
+      21,20,22,
+      17,16,18,
+      25,24,26,
+      5 , 4, 6,
+      1 , 0, 2,
+      9 , 8,10,
+      37,36,38,
+      33,32,34,
+      41,40,42
     };
-  tria.create_triangulation (
-    std::vector<Point<3> >(&vertices[0], &vertices[20]),
-    cells,
-    SubCellData());       // no boundary information
 
-  if (colorize)
-    {
-      Assert(false, ExcNotImplemented());
-      Triangulation<3>::cell_iterator cell = tria.begin();
-      cell->face(1)->set_boundary_indicator(1);
-      ++cell;
-      cell->face(3)->set_boundary_indicator(2);
-    }
-}
+    std::vector<CellData<3> > cells(27);
+    k = 0;
+    for (unsigned int z=0; z<3; ++z)
+      for (unsigned int y=0; y<3; ++y)
+        for (unsigned int x=0; x<3; ++x)
+          {
+            cells[k].vertices[0] = x+4*y+16*z;
+            cells[k].vertices[1] = x+4*y+16*z+1;
+            cells[k].vertices[2] = x+4*y+16*z+4;
+            cells[k].vertices[3] = x+4*y+16*z+5;
+            cells[k].vertices[4] = x+4*y+16*z+16;
+            cells[k].vertices[5] = x+4*y+16*z+17;
+            cells[k].vertices[6] = x+4*y+16*z+20;
+            cells[k].vertices[7] = x+4*y+16*z+21;
+            if (colorize)
+              cells[k].material_id = materials[k];
+            ++k;
+          }
+    tria.create_triangulation (
+      vertices,
+      cells,
+      SubCellData());       // no boundary information
+  }
 
 
 
-// Implementation for 3D only
-template <>
-void GridGenerator::enclosed_hyper_cube (Triangulation<3> &tria,
-                                         const double        left,
-                                         const double        right,
-                                         const double        thickness,
-                                         const bool          colorize)
-{
-  Assert(left<right,
-         ExcMessage ("Invalid left-to-right bounds of enclosed hypercube"));
-
-  std::vector<Point<3> > vertices(64);
-  double coords[4];
-  coords[0] = left-thickness;
-  coords[1] = left;
-  coords[2] = right;
-  coords[3] = right+thickness;
-
-  unsigned int k=0;
-  for (unsigned int z=0; z<4; ++z)
-    for (unsigned int y=0; y<4; ++y)
-      for (unsigned int x=0; x<4; ++x)
-        vertices[k++] = Point<3>(coords[x], coords[y], coords[z]);
-
-  const types::material_id materials[27] =
+  template <>
+  void truncated_cone (Triangulation<3> &triangulation,
+                       const double radius_0,
+                       const double radius_1,
+                       const double half_length)
   {
-    21,20,22,
-    17,16,18,
-    25,24,26,
-    5 , 4, 6,
-    1 , 0, 2,
-    9 , 8,10,
-    37,36,38,
-    33,32,34,
-    41,40,42
-  };
-
-  std::vector<CellData<3> > cells(27);
-  k = 0;
-  for (unsigned int z=0; z<3; ++z)
-    for (unsigned int y=0; y<3; ++y)
-      for (unsigned int x=0; x<3; ++x)
-        {
-          cells[k].vertices[0] = x+4*y+16*z;
-          cells[k].vertices[1] = x+4*y+16*z+1;
-          cells[k].vertices[2] = x+4*y+16*z+4;
-          cells[k].vertices[3] = x+4*y+16*z+5;
-          cells[k].vertices[4] = x+4*y+16*z+16;
-          cells[k].vertices[5] = x+4*y+16*z+17;
-          cells[k].vertices[6] = x+4*y+16*z+20;
-          cells[k].vertices[7] = x+4*y+16*z+21;
-          if (colorize)
-            cells[k].material_id = materials[k];
-          ++k;
-        }
-  tria.create_triangulation (
-    vertices,
-    cells,
-    SubCellData());       // no boundary information
-}
-
-
-
-template <>
-void GridGenerator::truncated_cone (Triangulation<3> &triangulation,
-                                    const double radius_0,
-                                    const double radius_1,
-                                    const double half_length)
-{
-  // Determine number of cells and vertices
-  const size_type
-  n_cells = static_cast<size_type>(std::floor (half_length /
-                                               std::max (radius_0,
-                                                         radius_1) +
-                                               0.5));
-  const size_type n_vertices = 4 * (n_cells + 1);
-  std::vector<Point<3> > vertices_tmp(n_vertices);
-
-  vertices_tmp[0] = Point<3> (-half_length, 0, -radius_0);
-  vertices_tmp[1] = Point<3> (-half_length, radius_0, 0);
-  vertices_tmp[2] = Point<3> (-half_length, -radius_0, 0);
-  vertices_tmp[3] = Point<3> (-half_length, 0, radius_0);
-
-  const double dx = 2 * half_length / n_cells;
-
-  for (size_type i = 0; i < n_cells; ++i)
-    {
-      vertices_tmp[4 * (i + 1)]
-        = vertices_tmp[4 * i] +
-          Point<3> (dx, 0, 0.5 * (radius_0 - radius_1) * dx / half_length);
-      vertices_tmp[4 * i + 5]
-        = vertices_tmp[4 * i + 1] +
-          Point<3> (dx, 0.5 * (radius_1 - radius_0) * dx / half_length, 0);
-      vertices_tmp[4 * i + 6]
-        = vertices_tmp[4 * i + 2] +
-          Point<3> (dx, 0.5 * (radius_0 - radius_1) * dx / half_length, 0);
-      vertices_tmp[4 * i + 7]
-        = vertices_tmp[4 * i + 3] +
-          Point<3> (dx, 0, 0.5 * (radius_1 - radius_0) * dx / half_length);
-    }
+    // Determine number of cells and vertices
+    const unsigned int
+    n_cells = static_cast<unsigned int>(std::floor (half_length /
+                                                    std::max (radius_0,
+                                                              radius_1) +
+                                                    0.5));
+    const unsigned int n_vertices = 4 * (n_cells + 1);
+    std::vector<Point<3> > vertices_tmp(n_vertices);
+
+    vertices_tmp[0] = Point<3> (-half_length, 0, -radius_0);
+    vertices_tmp[1] = Point<3> (-half_length, radius_0, 0);
+    vertices_tmp[2] = Point<3> (-half_length, -radius_0, 0);
+    vertices_tmp[3] = Point<3> (-half_length, 0, radius_0);
+
+    const double dx = 2 * half_length / n_cells;
+
+    for (unsigned int i = 0; i < n_cells; ++i)
+      {
+        vertices_tmp[4 * (i + 1)]
+          = vertices_tmp[4 * i] +
+            Point<3> (dx, 0, 0.5 * (radius_0 - radius_1) * dx / half_length);
+        vertices_tmp[4 * i + 5]
+          = vertices_tmp[4 * i + 1] +
+            Point<3> (dx, 0.5 * (radius_1 - radius_0) * dx / half_length, 0);
+        vertices_tmp[4 * i + 6]
+          = vertices_tmp[4 * i + 2] +
+            Point<3> (dx, 0.5 * (radius_0 - radius_1) * dx / half_length, 0);
+        vertices_tmp[4 * i + 7]
+          = vertices_tmp[4 * i + 3] +
+            Point<3> (dx, 0, 0.5 * (radius_1 - radius_0) * dx / half_length);
+      }
 
-  const std::vector<Point<3> > vertices (vertices_tmp.begin(),
-                                         vertices_tmp.end());
-  Table<2,unsigned int> cell_vertices(n_cells,GeometryInfo<3>::vertices_per_cell);
+    const std::vector<Point<3> > vertices (vertices_tmp.begin(),
+                                           vertices_tmp.end());
+    Table<2,unsigned int> cell_vertices(n_cells,GeometryInfo<3>::vertices_per_cell);
 
-  for (size_type i = 0; i < n_cells; ++i)
-    for (unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
-      cell_vertices[i][j] = 4 * i + j;
+    for (unsigned int i = 0; i < n_cells; ++i)
+      for (unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
+        cell_vertices[i][j] = 4 * i + j;
 
-  std::vector<CellData<3> > cells (n_cells, CellData<3> ());
+    std::vector<CellData<3> > cells (n_cells, CellData<3> ());
 
-  for (size_type i = 0; i < n_cells; ++i)
-    {
-      for (unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
+    for (unsigned int i = 0; i < n_cells; ++i)
+      {
+        for (unsigned int j = 0; j < GeometryInfo<3>::vertices_per_cell; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
 
-      cells[i].material_id = 0;
-    }
+        cells[i].material_id = 0;
+      }
 
-  triangulation.create_triangulation (vertices, cells, SubCellData ());
+    triangulation.create_triangulation (vertices, cells, SubCellData ());
 
-  for (Triangulation<3>::cell_iterator cell = triangulation.begin ();
-       cell != triangulation.end (); ++cell)
-    {
-      if (cell->vertex (0) (0) == -half_length)
-        {
-          cell->face (4)->set_boundary_indicator (1);
+    for (Triangulation<3>::cell_iterator cell = triangulation.begin ();
+         cell != triangulation.end (); ++cell)
+      {
+        if (cell->vertex (0) (0) == -half_length)
+          {
+            cell->face (4)->set_boundary_indicator (1);
 
-          for (unsigned int i = 0; i < 4; ++i)
-            cell->line (i)->set_boundary_indicator (0);
-        }
+            for (unsigned int i = 0; i < 4; ++i)
+              cell->line (i)->set_boundary_indicator (0);
+          }
 
-      if (cell->vertex (4) (0) == half_length)
-        {
-          cell->face (5)->set_boundary_indicator (2);
+        if (cell->vertex (4) (0) == half_length)
+          {
+            cell->face (5)->set_boundary_indicator (2);
 
-          for (unsigned int i = 4; i < 8; ++i)
-            cell->line (i)->set_boundary_indicator (0);
-        }
+            for (unsigned int i = 4; i < 8; ++i)
+              cell->line (i)->set_boundary_indicator (0);
+          }
 
-      for (unsigned int i = 0; i < 4; ++i)
-        cell->face (i)->set_boundary_indicator (0);
-    }
-}
+        for (unsigned int i = 0; i < 4; ++i)
+          cell->face (i)->set_boundary_indicator (0);
+      }
+  }
 
 
 // Implementation for 3D only
-template <>
-void
-GridGenerator::hyper_L (Triangulation<3> &tria,
-                        const double      a,
-                        const double      b)
-{
-  // we slice out the top back right
-  // part of the cube
-  const Point<3> vertices[26]
-  =
+  template <>
+  void
+  hyper_L (Triangulation<3> &tria,
+           const double      a,
+           const double      b)
   {
-    // front face of the big cube
-    Point<3> (a,      a,a),
-    Point<3> ((a+b)/2,a,a),
-    Point<3> (b,      a,a),
-    Point<3> (a,      a,(a+b)/2),
-    Point<3> ((a+b)/2,a,(a+b)/2),
-    Point<3> (b,      a,(a+b)/2),
-    Point<3> (a,      a,b),
-    Point<3> ((a+b)/2,a,b),
-    Point<3> (b,      a,b),
-    // middle face of the big cube
-    Point<3> (a,      (a+b)/2,a),
-    Point<3> ((a+b)/2,(a+b)/2,a),
-    Point<3> (b,      (a+b)/2,a),
-    Point<3> (a,      (a+b)/2,(a+b)/2),
-    Point<3> ((a+b)/2,(a+b)/2,(a+b)/2),
-    Point<3> (b,      (a+b)/2,(a+b)/2),
-    Point<3> (a,      (a+b)/2,b),
-    Point<3> ((a+b)/2,(a+b)/2,b),
-    Point<3> (b,      (a+b)/2,b),
-    // back face of the big cube
-    // last (top right) point is missing
-    Point<3> (a,      b,a),
-    Point<3> ((a+b)/2,b,a),
-    Point<3> (b,      b,a),
-    Point<3> (a,      b,(a+b)/2),
-    Point<3> ((a+b)/2,b,(a+b)/2),
-    Point<3> (b,      b,(a+b)/2),
-    Point<3> (a,      b,b),
-    Point<3> ((a+b)/2,b,b)
-  };
-  const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
-    {1, 2, 10, 11, 4, 5, 13, 14},
-    {3, 4, 12, 13, 6, 7, 15, 16},
-    {4, 5, 13, 14, 7, 8, 16, 17},
-    {9, 10, 18, 19, 12, 13, 21, 22},
-    {10, 11, 19, 20, 13, 14, 22, 23},
-    {12, 13, 21, 22, 15, 16, 24, 25}
-  };
-
-  std::vector<CellData<3> > cells (7, CellData<3>());
-
-  for (unsigned int i=0; i<7; ++i)
-    {
-      for (unsigned int j=0; j<8; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
+    // we slice out the top back right
+    // part of the cube
+    const Point<3> vertices[26]
+    =
+    {
+      // front face of the big cube
+      Point<3> (a,      a,a),
+      Point<3> ((a+b)/2,a,a),
+      Point<3> (b,      a,a),
+      Point<3> (a,      a,(a+b)/2),
+      Point<3> ((a+b)/2,a,(a+b)/2),
+      Point<3> (b,      a,(a+b)/2),
+      Point<3> (a,      a,b),
+      Point<3> ((a+b)/2,a,b),
+      Point<3> (b,      a,b),
+      // middle face of the big cube
+      Point<3> (a,      (a+b)/2,a),
+      Point<3> ((a+b)/2,(a+b)/2,a),
+      Point<3> (b,      (a+b)/2,a),
+      Point<3> (a,      (a+b)/2,(a+b)/2),
+      Point<3> ((a+b)/2,(a+b)/2,(a+b)/2),
+      Point<3> (b,      (a+b)/2,(a+b)/2),
+      Point<3> (a,      (a+b)/2,b),
+      Point<3> ((a+b)/2,(a+b)/2,b),
+      Point<3> (b,      (a+b)/2,b),
+      // back face of the big cube
+      // last (top right) point is missing
+      Point<3> (a,      b,a),
+      Point<3> ((a+b)/2,b,a),
+      Point<3> (b,      b,a),
+      Point<3> (a,      b,(a+b)/2),
+      Point<3> ((a+b)/2,b,(a+b)/2),
+      Point<3> (b,      b,(a+b)/2),
+      Point<3> (a,      b,b),
+      Point<3> ((a+b)/2,b,b)
+    };
+    const int cell_vertices[7][8] = {{0, 1, 9, 10, 3, 4, 12, 13},
+      {1, 2, 10, 11, 4, 5, 13, 14},
+      {3, 4, 12, 13, 6, 7, 15, 16},
+      {4, 5, 13, 14, 7, 8, 16, 17},
+      {9, 10, 18, 19, 12, 13, 21, 22},
+      {10, 11, 19, 20, 13, 14, 22, 23},
+      {12, 13, 21, 22, 15, 16, 24, 25}
     };
 
-  tria.create_triangulation (
-    std::vector<Point<3> >(&vertices[0], &vertices[26]),
-    cells,
-    SubCellData());       // no boundary information
-}
-
-
+    std::vector<CellData<3> > cells (7, CellData<3>());
 
-// Implementation for 3D only
-template <>
-void
-GridGenerator::hyper_ball (Triangulation<3> &tria,
-                           const Point<3>   &p,
-                           const double radius)
-{
-  const double a = 1./(1+std::sqrt(3.0)); // equilibrate cell sizes at transition
-  // from the inner part to the radial
-  // cells
-  const unsigned int n_vertices = 16;
-  const Point<3> vertices[n_vertices]
-  =
-  {
-    // first the vertices of the inner
-    // cell
-    p+Point<3>(-1,-1,-1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(+1,-1,-1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(+1,-1,+1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(-1,-1,+1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(-1,+1,-1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(+1,+1,-1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(+1,+1,+1) *(radius/std::sqrt(3.0)*a),
-    p+Point<3>(-1,+1,+1) *(radius/std::sqrt(3.0)*a),
-    // now the eight vertices at
-    // the outer sphere
-    p+Point<3>(-1,-1,-1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(+1,-1,-1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(+1,-1,+1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(-1,-1,+1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(-1,+1,-1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(+1,+1,-1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(+1,+1,+1) *(radius/std::sqrt(3.0)),
-    p+Point<3>(-1,+1,+1) *(radius/std::sqrt(3.0)),
-  };
-
-  // one needs to draw the seven cubes to
-  // understand what's going on here
-  const unsigned int n_cells = 7;
-  const int cell_vertices[n_cells][8] = {{0, 1, 4, 5, 3, 2, 7, 6}, // center
-    {8, 9, 12, 13, 0, 1, 4, 5}, // bottom
-    {9, 13, 1, 5, 10, 14, 2, 6}, // right
-    {11, 10, 3, 2, 15, 14, 7, 6}, // top
-    {8, 0, 12, 4, 11, 3, 15, 7}, // left
-    {8, 9, 0, 1, 11, 10, 3, 2}, // front
-    {12, 4, 13, 5, 15, 7, 14, 6}
-  }; // back
-
-  std::vector<CellData<3> > cells (n_cells, CellData<3>());
-
-  for (unsigned int i=0; i<n_cells; ++i)
-    {
-      for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
-    };
+    for (unsigned int i=0; i<7; ++i)
+      {
+        for (unsigned int j=0; j<8; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
-  tria.create_triangulation (
-    std::vector<Point<3> >(&vertices[0], &vertices[n_vertices]),
-    cells,
-    SubCellData());       // no boundary information
-}
+    tria.create_triangulation (
+      std::vector<Point<3> >(&vertices[0], &vertices[26]),
+      cells,
+      SubCellData());       // no boundary information
+  }
 
 
 
 // Implementation for 3D only
-template <>
-void
-GridGenerator::cylinder (Triangulation<3> &tria,
-                         const double radius,
-                         const double half_length)
-{
-  // Copy the base from hyper_ball<3>
-  // and transform it to yz
-  const double d = radius/std::sqrt(2.0);
-  const double a = d/(1+std::sqrt(2.0));
-  Point<3> vertices[24] =
-  {
-    Point<3>(-d, -half_length,-d),
-    Point<3>( d, -half_length,-d),
-    Point<3>(-a, -half_length,-a),
-    Point<3>( a, -half_length,-a),
-    Point<3>(-a, -half_length, a),
-    Point<3>( a, -half_length, a),
-    Point<3>(-d, -half_length, d),
-    Point<3>( d, -half_length, d),
-    Point<3>(-d, 0,-d),
-    Point<3>( d, 0,-d),
-    Point<3>(-a, 0,-a),
-    Point<3>( a, 0,-a),
-    Point<3>(-a, 0, a),
-    Point<3>( a, 0, a),
-    Point<3>(-d, 0, d),
-    Point<3>( d, 0, d),
-    Point<3>(-d, half_length,-d),
-    Point<3>( d, half_length,-d),
-    Point<3>(-a, half_length,-a),
-    Point<3>( a, half_length,-a),
-    Point<3>(-a, half_length, a),
-    Point<3>( a, half_length, a),
-    Point<3>(-d, half_length, d),
-    Point<3>( d, half_length, d),
-  };
-  // Turn cylinder such that y->x
-  for (unsigned int i=0; i<24; ++i)
-    {
-      const double h = vertices[i](1);
-      vertices[i](1) = -vertices[i](0);
-      vertices[i](0) = h;
-    }
-
-  int cell_vertices[10][8] =
+  template <>
+  void
+  hyper_ball (Triangulation<3> &tria,
+              const Point<3>   &p,
+              const double radius)
   {
-    {0, 1, 8, 9, 2, 3, 10, 11},
-    {0, 2, 8, 10, 6, 4, 14, 12},
-    {2, 3, 10, 11, 4, 5, 12, 13},
-    {1, 7, 9, 15, 3, 5, 11, 13},
-    {6, 4, 14, 12, 7, 5, 15, 13}
-  };
-  for (unsigned int i=0; i<5; ++i)
-    for (unsigned int j=0; j<8; ++j)
-      cell_vertices[i+5][j] = cell_vertices[i][j]+8;
-
-  std::vector<CellData<3> > cells (10, CellData<3>());
-
-  for (unsigned int i=0; i<10; ++i)
-    {
-      for (unsigned int j=0; j<8; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
+    const double a = 1./(1+std::sqrt(3.0)); // equilibrate cell sizes at transition
+    // from the inner part to the radial
+    // cells
+    const unsigned int n_vertices = 16;
+    const Point<3> vertices[n_vertices]
+    =
+    {
+      // first the vertices of the inner
+      // cell
+      p+Point<3>(-1,-1,-1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(+1,-1,-1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(+1,-1,+1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(-1,-1,+1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(-1,+1,-1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(+1,+1,-1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(+1,+1,+1) *(radius/std::sqrt(3.0)*a),
+      p+Point<3>(-1,+1,+1) *(radius/std::sqrt(3.0)*a),
+      // now the eight vertices at
+      // the outer sphere
+      p+Point<3>(-1,-1,-1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(+1,-1,-1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(+1,-1,+1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(-1,-1,+1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(-1,+1,-1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(+1,+1,-1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(+1,+1,+1) *(radius/std::sqrt(3.0)),
+      p+Point<3>(-1,+1,+1) *(radius/std::sqrt(3.0)),
     };
 
-  tria.create_triangulation (
-    std::vector<Point<3> >(&vertices[0], &vertices[24]),
-    cells,
-    SubCellData());       // no boundary information
-
-  // set boundary indicators for the
-  // faces at the ends to 1 and 2,
-  // respectively. note that we also
-  // have to deal with those lines
-  // that are purely in the interior
-  // of the ends. we determine whether
-  // an edge is purely in the
-  // interior if one of its vertices
-  // is at coordinates '+-a' as set
-  // above
-  Triangulation<3>::cell_iterator cell = tria.begin();
-  Triangulation<3>::cell_iterator end = tria.end();
-
-  for (; cell != end; ++cell)
-    for (unsigned int i=0; i<GeometryInfo<3>::faces_per_cell; ++i)
-      if (cell->at_boundary(i))
-        {
-          if (cell->face(i)->center()(0) > half_length-1.e-5)
-            {
-              cell->face(i)->set_boundary_indicator(2);
-
-              for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
-                if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
-                    (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
-                    (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
-                    (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
-                  cell->face(i)->line(e)->set_boundary_indicator(2);
-            }
-          else if (cell->face(i)->center()(0) < -half_length+1.e-5)
-            {
-              cell->face(i)->set_boundary_indicator(1);
+    // one needs to draw the seven cubes to
+    // understand what's going on here
+    const unsigned int n_cells = 7;
+    const int cell_vertices[n_cells][8] = {{0, 1, 4, 5, 3, 2, 7, 6}, // center
+      {8, 9, 12, 13, 0, 1, 4, 5}, // bottom
+      {9, 13, 1, 5, 10, 14, 2, 6}, // right
+      {11, 10, 3, 2, 15, 14, 7, 6}, // top
+      {8, 0, 12, 4, 11, 3, 15, 7}, // left
+      {8, 9, 0, 1, 11, 10, 3, 2}, // front
+      {12, 4, 13, 5, 15, 7, 14, 6}
+    }; // back
+
+    std::vector<CellData<3> > cells (n_cells, CellData<3>());
+
+    for (unsigned int i=0; i<n_cells; ++i)
+      {
+        for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
-              for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
-                if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
-                    (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
-                    (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
-                    (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
-                  cell->face(i)->line(e)->set_boundary_indicator(1);
-            }
-        }
-}
+    tria.create_triangulation (
+      std::vector<Point<3> >(&vertices[0], &vertices[n_vertices]),
+      cells,
+      SubCellData());       // no boundary information
+  }
 
 
 
 // Implementation for 3D only
-template <>
-void
-GridGenerator::half_hyper_ball (Triangulation<3> &tria,
-                                const Point<3> &center,
-                                const double radius)
-{
-  // These are for the two lower squares
-  const double d = radius/std::sqrt(2.0);
-  const double a = d/(1+std::sqrt(2.0));
-  // These are for the two upper square
-  const double b = a/2.0;
-  const double c = d/2.0;
-  // And so are these
-  const double hb = radius*std::sqrt(3.0)/4.0;
-  const double hc = radius*std::sqrt(3.0)/2.0;
-
-  Point<3> vertices[16] =
+  template <>
+  void
+  cylinder (Triangulation<3> &tria,
+            const double radius,
+            const double half_length)
   {
-    center+Point<3>( 0,  d, -d),
-    center+Point<3>( 0, -d, -d),
-    center+Point<3>( 0,  a, -a),
-    center+Point<3>( 0, -a, -a),
-    center+Point<3>( 0,  a,  a),
-    center+Point<3>( 0, -a,  a),
-    center+Point<3>( 0,  d,  d),
-    center+Point<3>( 0, -d,  d),
-
-    center+Point<3>(hc,  c, -c),
-    center+Point<3>(hc, -c, -c),
-    center+Point<3>(hb,  b, -b),
-    center+Point<3>(hb, -b, -b),
-    center+Point<3>(hb,  b,  b),
-    center+Point<3>(hb, -b,  b),
-    center+Point<3>(hc,  c,  c),
-    center+Point<3>(hc, -c,  c),
-  };
-
-  int cell_vertices[6][8] =
-  {
-    {0, 1, 8, 9, 2, 3, 10, 11},
-    {0, 2, 8, 10, 6, 4, 14, 12},
-    {2, 3, 10, 11, 4, 5, 12, 13},
-    {1, 7, 9, 15, 3, 5, 11, 13},
-    {6, 4, 14, 12, 7, 5, 15, 13},
-    {8, 10, 9, 11, 14, 12, 15, 13}
-  };
-
-  std::vector<CellData<3> > cells (6, CellData<3>());
+    // Copy the base from hyper_ball<3>
+    // and transform it to yz
+    const double d = radius/std::sqrt(2.0);
+    const double a = d/(1+std::sqrt(2.0));
+    Point<3> vertices[24] =
+    {
+      Point<3>(-d, -half_length,-d),
+      Point<3>( d, -half_length,-d),
+      Point<3>(-a, -half_length,-a),
+      Point<3>( a, -half_length,-a),
+      Point<3>(-a, -half_length, a),
+      Point<3>( a, -half_length, a),
+      Point<3>(-d, -half_length, d),
+      Point<3>( d, -half_length, d),
+      Point<3>(-d, 0,-d),
+      Point<3>( d, 0,-d),
+      Point<3>(-a, 0,-a),
+      Point<3>( a, 0,-a),
+      Point<3>(-a, 0, a),
+      Point<3>( a, 0, a),
+      Point<3>(-d, 0, d),
+      Point<3>( d, 0, d),
+      Point<3>(-d, half_length,-d),
+      Point<3>( d, half_length,-d),
+      Point<3>(-a, half_length,-a),
+      Point<3>( a, half_length,-a),
+      Point<3>(-a, half_length, a),
+      Point<3>( a, half_length, a),
+      Point<3>(-d, half_length, d),
+      Point<3>( d, half_length, d),
+    };
+    // Turn cylinder such that y->x
+    for (unsigned int i=0; i<24; ++i)
+      {
+        const double h = vertices[i](1);
+        vertices[i](1) = -vertices[i](0);
+        vertices[i](0) = h;
+      }
 
-  for (unsigned int i=0; i<6; ++i)
+    int cell_vertices[10][8] =
     {
-      for (unsigned int j=0; j<8; ++j)
-        cells[i].vertices[j] = cell_vertices[i][j];
-      cells[i].material_id = 0;
+      {0, 1, 8, 9, 2, 3, 10, 11},
+      {0, 2, 8, 10, 6, 4, 14, 12},
+      {2, 3, 10, 11, 4, 5, 12, 13},
+      {1, 7, 9, 15, 3, 5, 11, 13},
+      {6, 4, 14, 12, 7, 5, 15, 13}
     };
+    for (unsigned int i=0; i<5; ++i)
+      for (unsigned int j=0; j<8; ++j)
+        cell_vertices[i+5][j] = cell_vertices[i][j]+8;
 
-  tria.create_triangulation (
-    std::vector<Point<3> >(&vertices[0], &vertices[16]),
-    cells,
-    SubCellData());       // no boundary information
+    std::vector<CellData<3> > cells (10, CellData<3>());
 
-  Triangulation<3>::cell_iterator cell = tria.begin();
-  Triangulation<3>::cell_iterator end = tria.end();
+    for (unsigned int i=0; i<10; ++i)
+      {
+        for (unsigned int j=0; j<8; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
-  // go over all faces. for the ones on the flat face, set boundary
-  // indicator for face and edges to one; the rest will remain at
-  // zero but we have to pay attention to those edges that are
-  // at the perimeter of the flat face since they should not be
-  // set to one
-  while (cell != end)
-    {
+    tria.create_triangulation (
+      std::vector<Point<3> >(&vertices[0], &vertices[24]),
+      cells,
+      SubCellData());       // no boundary information
+
+    // set boundary indicators for the
+    // faces at the ends to 1 and 2,
+    // respectively. note that we also
+    // have to deal with those lines
+    // that are purely in the interior
+    // of the ends. we determine whether
+    // an edge is purely in the
+    // interior if one of its vertices
+    // is at coordinates '+-a' as set
+    // above
+    Triangulation<3>::cell_iterator cell = tria.begin();
+    Triangulation<3>::cell_iterator end = tria.end();
+
+    for (; cell != end; ++cell)
       for (unsigned int i=0; i<GeometryInfo<3>::faces_per_cell; ++i)
-        {
-          if (!cell->at_boundary(i))
-            continue;
+        if (cell->at_boundary(i))
+          {
+            if (cell->face(i)->center()(0) > half_length-1.e-5)
+              {
+                cell->face(i)->set_boundary_indicator(2);
+
+                for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
+                  if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
+                    cell->face(i)->line(e)->set_boundary_indicator(2);
+              }
+            else if (cell->face(i)->center()(0) < -half_length+1.e-5)
+              {
+                cell->face(i)->set_boundary_indicator(1);
+
+                for (unsigned int e=0; e<GeometryInfo<3>::lines_per_face; ++e)
+                  if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
+                    cell->face(i)->line(e)->set_boundary_indicator(1);
+              }
+          }
+  }
+
 
-          // If the center is on the plane x=0, this is a planar element. set
-          // its boundary indicator. also set the boundary indicators of the
-          // bounding faces unless both vertices are on the perimeter
-          if (cell->face(i)->center()(0) < center(0)+1.e-5*radius)
-            {
-              cell->face(i)->set_boundary_indicator(1);
-              for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
-                {
-                  const Point<3> vertices[2]
-                    = { cell->face(i)->line(j)->vertex(0),
-                        cell->face(i)->line(j)->vertex(1)
-                      };
-                  if ((std::fabs(vertices[0].distance(center)-radius) >
-                       1e-5*radius)
-                      ||
-                      (std::fabs(vertices[1].distance(center)-radius) >
-                       1e-5*radius))
-                    cell->face(i)->line(j)->set_boundary_indicator(1);
-                }
-            }
-        }
-      ++cell;
-    }
-}
 
 // Implementation for 3D only
-template<>
-void
-GridGenerator::
-colorize_hyper_shell (Triangulation<3> &tria,
-                      const Point<3> &,
-                      const double,
-                      const double)
-{
-  // the following uses a good amount
-  // of knowledge about the
-  // orientation of cells. this is
-  // probably not good style...
-  if (tria.n_cells() == 6)
+  template <>
+  void
+  half_hyper_ball (Triangulation<3> &tria,
+                   const Point<3> &center,
+                   const double radius)
+  {
+    // These are for the two lower squares
+    const double d = radius/std::sqrt(2.0);
+    const double a = d/(1+std::sqrt(2.0));
+    // These are for the two upper square
+    const double b = a/2.0;
+    const double c = d/2.0;
+    // And so are these
+    const double hb = radius*std::sqrt(3.0)/4.0;
+    const double hc = radius*std::sqrt(3.0)/2.0;
+
+    Point<3> vertices[16] =
+    {
+      center+Point<3>( 0,  d, -d),
+      center+Point<3>( 0, -d, -d),
+      center+Point<3>( 0,  a, -a),
+      center+Point<3>( 0, -a, -a),
+      center+Point<3>( 0,  a,  a),
+      center+Point<3>( 0, -a,  a),
+      center+Point<3>( 0,  d,  d),
+      center+Point<3>( 0, -d,  d),
+
+      center+Point<3>(hc,  c, -c),
+      center+Point<3>(hc, -c, -c),
+      center+Point<3>(hb,  b, -b),
+      center+Point<3>(hb, -b, -b),
+      center+Point<3>(hb,  b,  b),
+      center+Point<3>(hb, -b,  b),
+      center+Point<3>(hc,  c,  c),
+      center+Point<3>(hc, -c,  c),
+    };
+
+    int cell_vertices[6][8] =
     {
-      Triangulation<3>::cell_iterator cell = tria.begin();
+      {0, 1, 8, 9, 2, 3, 10, 11},
+      {0, 2, 8, 10, 6, 4, 14, 12},
+      {2, 3, 10, 11, 4, 5, 12, 13},
+      {1, 7, 9, 15, 3, 5, 11, 13},
+      {6, 4, 14, 12, 7, 5, 15, 13},
+      {8, 10, 9, 11, 14, 12, 15, 13}
+    };
 
-      cell->face(4)->set_boundary_indicator(1);
-      Assert (cell->face(4)->at_boundary(), ExcInternalError());
+    std::vector<CellData<3> > cells (6, CellData<3>());
 
-      (++cell)->face(2)->set_boundary_indicator(1);
-      Assert (cell->face(2)->at_boundary(), ExcInternalError());
+    for (unsigned int i=0; i<6; ++i)
+      {
+        for (unsigned int j=0; j<8; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      };
 
-      (++cell)->face(2)->set_boundary_indicator(1);
-      Assert (cell->face(2)->at_boundary(), ExcInternalError());
+    tria.create_triangulation (
+      std::vector<Point<3> >(&vertices[0], &vertices[16]),
+      cells,
+      SubCellData());       // no boundary information
 
-      (++cell)->face(0)->set_boundary_indicator(1);
-      Assert (cell->face(0)->at_boundary(), ExcInternalError());
+    Triangulation<3>::cell_iterator cell = tria.begin();
+    Triangulation<3>::cell_iterator end = tria.end();
 
-      (++cell)->face(2)->set_boundary_indicator(1);
-      Assert (cell->face(2)->at_boundary(), ExcInternalError());
-
-      (++cell)->face(0)->set_boundary_indicator(1);
-      Assert (cell->face(0)->at_boundary(), ExcInternalError());
-    }
-  else if (tria.n_cells() == 12)
-    {
-      // again use some internal
-      // knowledge
-      for (Triangulation<3>::cell_iterator cell = tria.begin();
-           cell != tria.end(); ++cell)
-        {
-          Assert (cell->face(5)->at_boundary(), ExcInternalError());
-          cell->face(5)->set_boundary_indicator(1);
-        }
-    }
-  else if (tria.n_cells() == 96)
-    {
-      // the 96-cell hypershell is
-      // based on a once refined
-      // 12-cell mesh. consequently,
-      // since the outer faces all
-      // are face_no==5 above, so
-      // they are here (unless they
-      // are in the interior). Use
-      // this to assign boundary
-      // indicators, but also make
-      // sure that we encounter
-      // exactly 48 such faces
-      unsigned int count = 0;
-      for (Triangulation<3>::cell_iterator cell = tria.begin();
-           cell != tria.end(); ++cell)
-        if (cell->face(5)->at_boundary())
+    // go over all faces. for the ones on the flat face, set boundary
+    // indicator for face and edges to one; the rest will remain at
+    // zero but we have to pay attention to those edges that are
+    // at the perimeter of the flat face since they should not be
+    // set to one
+    while (cell != end)
+      {
+        for (unsigned int i=0; i<GeometryInfo<3>::faces_per_cell; ++i)
           {
-            cell->face(5)->set_boundary_indicator(1);
-            ++count;
-          }
-      Assert (count == 48, ExcInternalError());
-    }
-  else
-    Assert (false, ExcNotImplemented());
-}
-
+            if (!cell->at_boundary(i))
+              continue;
 
+            // If the center is on the plane x=0, this is a planar element. set
+            // its boundary indicator. also set the boundary indicators of the
+            // bounding faces unless both vertices are on the perimeter
+            if (cell->face(i)->center()(0) < center(0)+1.e-5*radius)
+              {
+                cell->face(i)->set_boundary_indicator(1);
+                for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
+                  {
+                    const Point<3> vertices[2]
+                      = { cell->face(i)->line(j)->vertex(0),
+                          cell->face(i)->line(j)->vertex(1)
+                        };
+                    if ((std::fabs(vertices[0].distance(center)-radius) >
+                         1e-5*radius)
+                        ||
+                        (std::fabs(vertices[1].distance(center)-radius) >
+                         1e-5*radius))
+                      cell->face(i)->line(j)->set_boundary_indicator(1);
+                  }
+              }
+          }
+        ++cell;
+      }
+  }
 
-template <>
-void
-GridGenerator::hyper_shell (Triangulation<3> &tria,
-                            const Point<3> &p,
-                            const double inner_radius,
-                            const double outer_radius,
-                            const size_type n,
-                            const bool colorize)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
 
-  const double irad = inner_radius/std::sqrt(3.0);
-  const double orad = outer_radius/std::sqrt(3.0);
-  std::vector<Point<3> > vertices;
-  std::vector<CellData<3> > cells;
+  template <>
+  void
+  hyper_shell (Triangulation<3> &tria,
+               const Point<3> &p,
+               const double inner_radius,
+               const double outer_radius,
+               const unsigned int n,
+               const bool colorize)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
 
-  // Start with the shell bounded by
-  // two nested cubes
-  if (n == 6)
-    {
-      for (unsigned int i=0; i<8; ++i)
-        vertices.push_back(p+hexahedron[i]*irad);
-      for (unsigned int i=0; i<8; ++i)
-        vertices.push_back(p+hexahedron[i]*orad);
+    const double irad = inner_radius/std::sqrt(3.0);
+    const double orad = outer_radius/std::sqrt(3.0);
+    std::vector<Point<3> > vertices;
+    std::vector<CellData<3> > cells;
 
-      const unsigned int n_cells = 6;
-      const int cell_vertices[n_cells][8] =
+    // Start with the shell bounded by
+    // two nested cubes
+    if (n == 6)
       {
-        {8, 9, 10, 11, 0, 1, 2, 3}, // bottom
-        {9, 11, 1, 3, 13, 15, 5, 7}, // right
-        {12, 13, 4, 5, 14, 15, 6, 7}, // top
-        {8, 0, 10, 2, 12, 4, 14, 6}, // left
-        {8, 9, 0, 1, 12, 13, 4, 5}, // front
-        {10, 2, 11, 3, 14, 6, 15, 7}
-      }; // back
+        for (unsigned int i=0; i<8; ++i)
+          vertices.push_back(p+hexahedron[i]*irad);
+        for (unsigned int i=0; i<8; ++i)
+          vertices.push_back(p+hexahedron[i]*orad);
 
-      cells.resize(n_cells, CellData<3>());
-
-      for (unsigned int i=0; i<n_cells; ++i)
+        const unsigned int n_cells = 6;
+        const int cell_vertices[n_cells][8] =
         {
-          for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
-            cells[i].vertices[j] = cell_vertices[i][j];
-          cells[i].material_id = 0;
-        }
+          {8, 9, 10, 11, 0, 1, 2, 3}, // bottom
+          {9, 11, 1, 3, 13, 15, 5, 7}, // right
+          {12, 13, 4, 5, 14, 15, 6, 7}, // top
+          {8, 0, 10, 2, 12, 4, 14, 6}, // left
+          {8, 9, 0, 1, 12, 13, 4, 5}, // front
+          {10, 2, 11, 3, 14, 6, 15, 7}
+        }; // back
 
-      tria.create_triangulation (vertices, cells, SubCellData());
-    }
-  // A more regular subdivision can
-  // be obtained by two nested
-  // rhombic dodecahedra
-  else if (n == 12)
-    {
-      for (unsigned int i=0; i<8; ++i)
-        vertices.push_back(p+hexahedron[i]*irad);
-      for (unsigned int i=0; i<6; ++i)
-        vertices.push_back(p+octahedron[i]*inner_radius);
-      for (unsigned int i=0; i<8; ++i)
-        vertices.push_back(p+hexahedron[i]*orad);
-      for (unsigned int i=0; i<6; ++i)
-        vertices.push_back(p+octahedron[i]*outer_radius);
-
-      const unsigned int n_cells = 12;
-      const unsigned int rhombi[n_cells][4] =
-      {
-        { 10,  4,  0,  8},
-        {  4, 13,  8,  6},
-        { 10,  5,  4, 13},
-        {  1,  9, 10,  5},
-        {  9,  7,  5, 13},
-        {  7, 11, 13,  6},
-        {  9,  3,  7, 11},
-        {  1, 12,  9,  3},
-        { 12,  2,  3, 11},
-        {  2,  8, 11,  6},
-        { 12,  0,  2,  8},
-        {  1, 10, 12,  0}
-      };
+        cells.resize(n_cells, CellData<3>());
 
-      cells.resize(n_cells, CellData<3>());
+        for (unsigned int i=0; i<n_cells; ++i)
+          {
+            for (unsigned int j=0; j<GeometryInfo<3>::vertices_per_cell; ++j)
+              cells[i].vertices[j] = cell_vertices[i][j];
+            cells[i].material_id = 0;
+          }
 
-      for (unsigned int i=0; i<n_cells; ++i)
+        tria.create_triangulation (vertices, cells, SubCellData());
+      }
+    // A more regular subdivision can
+    // be obtained by two nested
+    // rhombic dodecahedra
+    else if (n == 12)
+      {
+        for (unsigned int i=0; i<8; ++i)
+          vertices.push_back(p+hexahedron[i]*irad);
+        for (unsigned int i=0; i<6; ++i)
+          vertices.push_back(p+octahedron[i]*inner_radius);
+        for (unsigned int i=0; i<8; ++i)
+          vertices.push_back(p+hexahedron[i]*orad);
+        for (unsigned int i=0; i<6; ++i)
+          vertices.push_back(p+octahedron[i]*outer_radius);
+
+        const unsigned int n_cells = 12;
+        const unsigned int rhombi[n_cells][4] =
         {
-          for (unsigned int j=0; j<4; ++j)
-            {
-              cells[i].vertices[j  ] = rhombi[i][j];
-              cells[i].vertices[j+4] = rhombi[i][j] + 14;
-            }
-          cells[i].material_id = 0;
-        }
+          { 10,  4,  0,  8},
+          {  4, 13,  8,  6},
+          { 10,  5,  4, 13},
+          {  1,  9, 10,  5},
+          {  9,  7,  5, 13},
+          {  7, 11, 13,  6},
+          {  9,  3,  7, 11},
+          {  1, 12,  9,  3},
+          { 12,  2,  3, 11},
+          {  2,  8, 11,  6},
+          { 12,  0,  2,  8},
+          {  1, 10, 12,  0}
+        };
 
-      tria.create_triangulation (vertices, cells, SubCellData());
-    }
-  else if (n == 96)
-    {
-      // create a triangulation based on the
-      // 12-cell one where we refine the mesh
-      // once and then re-arrange all
-      // interior nodes so that the mesh is
-      // the least distorted
-      HyperShellBoundary<3> boundary (p);
-      Triangulation<3> tmp;
-      GridGenerator::hyper_shell (tmp, p, inner_radius, outer_radius, 12);
-      tmp.set_boundary(0, boundary);
-      tmp.set_boundary(1, boundary);
-      tmp.refine_global (1);
-
-      // let's determine the distance at
-      // which the interior nodes should be
-      // from the center. let's say we
-      // measure distances in multiples of
-      // outer_radius and call
-      // r=inner_radius.
-      //
-      // then note
-      // that we now have 48 faces on the
-      // inner and 48 on the outer sphere,
-      // each with an area of approximately
-      // 4*pi/48*r^2 and 4*pi/48, for
-      // a face edge length of approximately
-      // sqrt(pi/12)*r and sqrt(pi/12)
-      //
-      // let's say we put the interior nodes
-      // at a distance rho, then a measure of
-      // deformation for the inner cells
-      // would be
-      //   di=max(sqrt(pi/12)*r/(rho-r),
-      //          (rho-r)/sqrt(pi/12)/r)
-      // and for the outer cells
-      //   do=max(sqrt(pi/12)/(1-rho),
-      //          (1-rho)/sqrt(pi/12))
-      //
-      // we now seek a rho so that the
-      // deformation of cells on the inside
-      // and outside is equal. there are in
-      // principle four possibilities for one
-      // of the branches of do== one of the
-      // branches of di, though not all of
-      // them satisfy do==di, of
-      // course. however, we are not
-      // interested in cases where the inner
-      // cell is long and skinny and the
-      // outer one tall -- yes, they have the
-      // same aspect ratio, but in different
-      // space directions.
-      //
-      // so it only boils down to the
-      // following two possibilities: the
-      // first branch of each max(.,.)
-      // functions are equal, or the second
-      // one are. on the other hand, since
-      // they two branches are reciprocals of
-      // each other, if one pair of branches
-      // is equal, so is the other
-      //
-      // this yields the following equation
-      // for rho:
-      //   sqrt(pi/12)*r/(rho-r)
-      //   == sqrt(pi/12)/(1-rho)
-      // with solution rho=2r/(1+r)
-      const double r = inner_radius / outer_radius;
-      const double rho = 2*r/(1+r);
-
-      // then this is the distance of the
-      // interior nodes from the center:
-      const double middle_radius = rho * outer_radius;
-
-      // mark vertices we've already moved or
-      // that we want to ignore: we don't
-      // want to move vertices at the inner
-      // or outer boundaries
-      std::vector<bool> vertex_already_treated (tmp.n_vertices(), false);
-      for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
-           cell != tmp.end(); ++cell)
-        for (unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
-          if (cell->at_boundary(f))
-            for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_face; ++v)
-              vertex_already_treated[cell->face(f)->vertex_index(v)] = true;
-
-      // now move the remaining vertices
-      for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
-           cell != tmp.end(); ++cell)
-        for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
-          if (vertex_already_treated[cell->vertex_index(v)] == false)
-            {
-              // this is a new interior
-              // vertex. mesh refinement may
-              // have placed it at a number
-              // of places in radial
-              // direction and oftentimes not
-              // in a particularly good
-              // one. move it to halfway
-              // between inner and outer
-              // sphere
-              const Point<3> old_distance = cell->vertex(v) - p;
-              const double old_radius = cell->vertex(v).distance(p);
-              cell->vertex(v) = p + old_distance * (middle_radius / old_radius);
-
-              vertex_already_treated[cell->vertex_index(v)] = true;
-            }
+        cells.resize(n_cells, CellData<3>());
 
-      // now copy the resulting level 1 cells
-      // into the new triangulation,
-      cells.resize(tmp.n_active_cells(), CellData<3>());
+        for (unsigned int i=0; i<n_cells; ++i)
+          {
+            for (unsigned int j=0; j<4; ++j)
+              {
+                cells[i].vertices[j  ] = rhombi[i][j];
+                cells[i].vertices[j+4] = rhombi[i][j] + 14;
+              }
+            cells[i].material_id = 0;
+          }
 
-      unsigned int index = 0;
-      for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
-           cell != tmp.end(); ++cell, ++index)
-        {
+        tria.create_triangulation (vertices, cells, SubCellData());
+      }
+    else if (n == 96)
+      {
+        // create a triangulation based on the
+        // 12-cell one where we refine the mesh
+        // once and then re-arrange all
+        // interior nodes so that the mesh is
+        // the least distorted
+        HyperShellBoundary<3> boundary (p);
+        Triangulation<3> tmp;
+        hyper_shell (tmp, p, inner_radius, outer_radius, 12);
+        tmp.set_boundary(0, boundary);
+        tmp.set_boundary(1, boundary);
+        tmp.refine_global (1);
+
+        // let's determine the distance at
+        // which the interior nodes should be
+        // from the center. let's say we
+        // measure distances in multiples of
+        // outer_radius and call
+        // r=inner_radius.
+        //
+        // then note
+        // that we now have 48 faces on the
+        // inner and 48 on the outer sphere,
+        // each with an area of approximately
+        // 4*pi/48*r^2 and 4*pi/48, for
+        // a face edge length of approximately
+        // sqrt(pi/12)*r and sqrt(pi/12)
+        //
+        // let's say we put the interior nodes
+        // at a distance rho, then a measure of
+        // deformation for the inner cells
+        // would be
+        //   di=max(sqrt(pi/12)*r/(rho-r),
+        //          (rho-r)/sqrt(pi/12)/r)
+        // and for the outer cells
+        //   do=max(sqrt(pi/12)/(1-rho),
+        //          (1-rho)/sqrt(pi/12))
+        //
+        // we now seek a rho so that the
+        // deformation of cells on the inside
+        // and outside is equal. there are in
+        // principle four possibilities for one
+        // of the branches of do== one of the
+        // branches of di, though not all of
+        // them satisfy do==di, of
+        // course. however, we are not
+        // interested in cases where the inner
+        // cell is long and skinny and the
+        // outer one tall -- yes, they have the
+        // same aspect ratio, but in different
+        // space directions.
+        //
+        // so it only boils down to the
+        // following two possibilities: the
+        // first branch of each max(.,.)
+        // functions are equal, or the second
+        // one are. on the other hand, since
+        // they two branches are reciprocals of
+        // each other, if one pair of branches
+        // is equal, so is the other
+        //
+        // this yields the following equation
+        // for rho:
+        //   sqrt(pi/12)*r/(rho-r)
+        //   == sqrt(pi/12)/(1-rho)
+        // with solution rho=2r/(1+r)
+        const double r = inner_radius / outer_radius;
+        const double rho = 2*r/(1+r);
+
+        // then this is the distance of the
+        // interior nodes from the center:
+        const double middle_radius = rho * outer_radius;
+
+        // mark vertices we've already moved or
+        // that we want to ignore: we don't
+        // want to move vertices at the inner
+        // or outer boundaries
+        std::vector<bool> vertex_already_treated (tmp.n_vertices(), false);
+        for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
+             cell != tmp.end(); ++cell)
+          for (unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
+            if (cell->at_boundary(f))
+              for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_face; ++v)
+                vertex_already_treated[cell->face(f)->vertex_index(v)] = true;
+
+        // now move the remaining vertices
+        for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
+             cell != tmp.end(); ++cell)
           for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
-            cells[index].vertices[v] = cell->vertex_index(v);
-          cells[index].material_id = 0;
-        }
-
-      tria.create_triangulation (tmp.get_vertices(), cells, SubCellData());
-    }
-  else
-    {
-      Assert(false, ExcMessage ("Invalid number of coarse mesh cells."));
-    }
+            if (vertex_already_treated[cell->vertex_index(v)] == false)
+              {
+                // this is a new interior
+                // vertex. mesh refinement may
+                // have placed it at a number
+                // of places in radial
+                // direction and oftentimes not
+                // in a particularly good
+                // one. move it to halfway
+                // between inner and outer
+                // sphere
+                const Point<3> old_distance = cell->vertex(v) - p;
+                const double old_radius = cell->vertex(v).distance(p);
+                cell->vertex(v) = p + old_distance * (middle_radius / old_radius);
+
+                vertex_already_treated[cell->vertex_index(v)] = true;
+              }
 
-  if (colorize)
-    colorize_hyper_shell(tria, p, inner_radius, outer_radius);
-}
+        // now copy the resulting level 1 cells
+        // into the new triangulation,
+        cells.resize(tmp.n_active_cells(), CellData<3>());
 
+        unsigned int index = 0;
+        for (Triangulation<3>::active_cell_iterator cell = tmp.begin_active();
+             cell != tmp.end(); ++cell, ++index)
+          {
+            for (unsigned int v=0; v<GeometryInfo<3>::vertices_per_cell; ++v)
+              cells[index].vertices[v] = cell->vertex_index(v);
+            cells[index].material_id = 0;
+          }
 
+        tria.create_triangulation (tmp.get_vertices(), cells, SubCellData());
+      }
+    else
+      {
+        Assert(false, ExcMessage ("Invalid number of coarse mesh cells."));
+      }
 
+    if (colorize)
+      colorize_hyper_shell(tria, p, inner_radius, outer_radius);
+  }
 
-// Implementation for 3D only
-template <>
-void
-GridGenerator::half_hyper_shell (Triangulation<3> &tria,
-                                 const Point<3> &center,
-                                 const double inner_radius,
-                                 const double outer_radius,
-                                 const size_type n,
-                                 const bool colorize)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
-  Assert(colorize == false, ExcNotImplemented());
 
-  if (n <= 5)
-    {
-      // These are for the two lower squares
-      const double d = outer_radius/std::sqrt(2.0);
-      const double a = inner_radius/std::sqrt(2.0);
-      // These are for the two upper square
-      const double b = a/2.0;
-      const double c = d/2.0;
-      // And so are these
-      const double hb = inner_radius*std::sqrt(3.0)/2.0;
-      const double hc = outer_radius*std::sqrt(3.0)/2.0;
-
-      Point<3> vertices[16] =
-      {
-        center+Point<3>( 0,  d, -d),
-        center+Point<3>( 0, -d, -d),
-        center+Point<3>( 0,  a, -a),
-        center+Point<3>( 0, -a, -a),
-        center+Point<3>( 0,  a,  a),
-        center+Point<3>( 0, -a,  a),
-        center+Point<3>( 0,  d,  d),
-        center+Point<3>( 0, -d,  d),
-
-        center+Point<3>(hc,  c, -c),
-        center+Point<3>(hc, -c, -c),
-        center+Point<3>(hb,  b, -b),
-        center+Point<3>(hb, -b, -b),
-        center+Point<3>(hb,  b,  b),
-        center+Point<3>(hb, -b,  b),
-        center+Point<3>(hc,  c,  c),
-        center+Point<3>(hc, -c,  c),
-      };
 
-      int cell_vertices[5][8] =
-      {
-        {0, 1, 8, 9, 2, 3, 10, 11},
-        {0, 2, 8, 10, 6, 4, 14, 12},
-        {1, 7, 9, 15, 3, 5, 11, 13},
-        {6, 4, 14, 12, 7, 5, 15, 13},
-        {8, 10, 9, 11, 14, 12, 15, 13}
-      };
 
-      std::vector<CellData<3> > cells (5, CellData<3>());
+// Implementation for 3D only
+  template <>
+  void
+  half_hyper_shell (Triangulation<3> &tria,
+                    const Point<3> &center,
+                    const double inner_radius,
+                    const double outer_radius,
+                    const unsigned int n,
+                    const bool colorize)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
+    Assert(colorize == false, ExcNotImplemented());
 
-      for (unsigned int i=0; i<5; ++i)
+    if (n <= 5)
+      {
+        // These are for the two lower squares
+        const double d = outer_radius/std::sqrt(2.0);
+        const double a = inner_radius/std::sqrt(2.0);
+        // These are for the two upper square
+        const double b = a/2.0;
+        const double c = d/2.0;
+        // And so are these
+        const double hb = inner_radius*std::sqrt(3.0)/2.0;
+        const double hc = outer_radius*std::sqrt(3.0)/2.0;
+
+        Point<3> vertices[16] =
         {
-          for (unsigned int j=0; j<8; ++j)
-            cells[i].vertices[j] = cell_vertices[i][j];
-          cells[i].material_id = 0;
+          center+Point<3>( 0,  d, -d),
+          center+Point<3>( 0, -d, -d),
+          center+Point<3>( 0,  a, -a),
+          center+Point<3>( 0, -a, -a),
+          center+Point<3>( 0,  a,  a),
+          center+Point<3>( 0, -a,  a),
+          center+Point<3>( 0,  d,  d),
+          center+Point<3>( 0, -d,  d),
+
+          center+Point<3>(hc,  c, -c),
+          center+Point<3>(hc, -c, -c),
+          center+Point<3>(hb,  b, -b),
+          center+Point<3>(hb, -b, -b),
+          center+Point<3>(hb,  b,  b),
+          center+Point<3>(hb, -b,  b),
+          center+Point<3>(hc,  c,  c),
+          center+Point<3>(hc, -c,  c),
         };
 
-      tria.create_triangulation (
-        std::vector<Point<3> >(&vertices[0], &vertices[16]),
-        cells,
-        SubCellData());       // no boundary information
-    }
-  else
-    {
-      Assert(false, ExcIndexRange(n, 0, 5));
-    }
+        int cell_vertices[5][8] =
+        {
+          {0, 1, 8, 9, 2, 3, 10, 11},
+          {0, 2, 8, 10, 6, 4, 14, 12},
+          {1, 7, 9, 15, 3, 5, 11, 13},
+          {6, 4, 14, 12, 7, 5, 15, 13},
+          {8, 10, 9, 11, 14, 12, 15, 13}
+        };
 
-}
+        std::vector<CellData<3> > cells (5, CellData<3>());
 
-// Implementation for 3D only
-template <>
-void
-GridGenerator::colorize_quarter_hyper_shell(Triangulation<3> &tria,
-                                            const Point<3> &center,
-                                            const double inner_radius,
-                                            const double outer_radius)
-{
+        for (unsigned int i=0; i<5; ++i)
+          {
+            for (unsigned int j=0; j<8; ++j)
+              cells[i].vertices[j] = cell_vertices[i][j];
+            cells[i].material_id = 0;
+          };
+
+        tria.create_triangulation (
+          std::vector<Point<3> >(&vertices[0], &vertices[16]),
+          cells,
+          SubCellData());       // no boundary information
+      }
+    else
+      {
+        Assert(false, ExcIndexRange(n, 0, 5));
+      }
 
-  if (tria.n_cells() != 3)
-    AssertThrow (false, ExcNotImplemented());
+  }
 
-  double middle = (outer_radius-inner_radius)/2e0 + inner_radius;
-  double eps = 1e-3*middle;
-  Triangulation<3>::cell_iterator cell = tria.begin();
 
-  for (; cell!=tria.end(); ++cell)
-    for (unsigned int f=0; f<GeometryInfo<3>::faces_per_cell; ++f)
+// Implementation for 3D only
+  template <>
+  void quarter_hyper_shell (Triangulation<3> &tria,
+                            const Point<3> &center,
+                            const double inner_radius,
+                            const double outer_radius,
+                            const unsigned int n,
+                            const bool colorize)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
+    if (n == 0 || n == 3)
       {
-        if (!cell->face(f)->at_boundary())
-          continue;
+        const double a = inner_radius*std::sqrt(2.0)/2e0;
+        const double b = outer_radius*std::sqrt(2.0)/2e0;
+        const double c = a*std::sqrt(3.0)/2e0;
+        const double d = b*std::sqrt(3.0)/2e0;
+        const double e = outer_radius/2e0;
+        const double h = inner_radius/2e0;
+
+        std::vector<Point<3> > vertices;
+
+        vertices.push_back (center+Point<3>( 0,  inner_radius, 0)); //0
+        vertices.push_back (center+Point<3>( a,  a, 0));                  //1
+        vertices.push_back (center+Point<3>( b,  b, 0));                  //2
+        vertices.push_back (center+Point<3>( 0, outer_radius, 0));        //3
+        vertices.push_back (center+Point<3>( 0, a , a));                  //4
+        vertices.push_back (center+Point<3>( c, c , h));                  //5
+        vertices.push_back (center+Point<3>( d, d , e));                  //6
+        vertices.push_back (center+Point<3>( 0, b , b));                  //7
+        vertices.push_back (center+Point<3>( inner_radius, 0 , 0));       //8
+        vertices.push_back (center+Point<3>( outer_radius, 0 , 0));       //9
+        vertices.push_back (center+Point<3>( a, 0 , a));  //10
+        vertices.push_back (center+Point<3>( b, 0 , b));  //11
+        vertices.push_back (center+Point<3>( 0, 0 , inner_radius));       //12
+        vertices.push_back (center+Point<3>( 0, 0 , outer_radius));       //13
+
+        const int cell_vertices[3][8] =
+        {
+          {0, 1, 3, 2, 4, 5, 7, 6},
+          {1, 8, 2, 9, 5, 10, 6, 11},
+          {4, 5, 7, 6, 12, 10, 13, 11},
+        };
+        std::vector<CellData<3> > cells(3);
 
-        double radius = cell->face(f)->center().norm() - center.norm();
-        if (std::fabs(cell->face(f)->center()(0)) < eps ) // x = 0 set boundary 2
-          {
-            cell->face(f)->set_boundary_indicator(2);
-            for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
-              if (cell->face(f)->line(j)->at_boundary())
-                if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
-                  cell->face(f)->line(j)->set_boundary_indicator(2);
-          }
-        else if (std::fabs(cell->face(f)->center()(1)) < eps) // y = 0 set boundary 3
-          {
-            cell->face(f)->set_boundary_indicator(3);
-            for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
-              if (cell->face(f)->line(j)->at_boundary())
-                if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
-                  cell->face(f)->line(j)->set_boundary_indicator(3);
-          }
-        else if (std::fabs(cell->face(f)->center()(2)) < eps ) // z = 0 set boundary 4
-          {
-            cell->face(f)->set_boundary_indicator(4);
-            for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
-              if (cell->face(f)->line(j)->at_boundary())
-                if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) > eps)
-                  cell->face(f)->line(j)->set_boundary_indicator(4);
-          }
-        else if (radius < middle) // inner radius set boundary 0
-          {
-            cell->face(f)->set_boundary_indicator(0);
-            for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
-              if (cell->face(f)->line(j)->at_boundary())
-                if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) < eps)
-                  cell->face(f)->line(j)->set_boundary_indicator(0);
-          }
-        else if (radius > middle) // outer radius set boundary 1
+        for (unsigned int i=0; i<3; ++i)
           {
-            cell->face(f)->set_boundary_indicator(1);
-            for (unsigned int j=0; j<GeometryInfo<3>::lines_per_face; ++j)
-              if (cell->face(f)->line(j)->at_boundary())
-                if (std::fabs(cell->face(f)->line(j)->vertex(0).norm() - cell->face(f)->line(j)->vertex(1).norm()) < eps)
-                  cell->face(f)->line(j)->set_boundary_indicator(1);
+            for (unsigned int j=0; j<8; ++j)
+              cells[i].vertices[j] = cell_vertices[i][j];
+            cells[i].material_id = 0;
           }
-        else
-          AssertThrow (false, ExcInternalError());
+
+        tria.create_triangulation ( vertices, cells, SubCellData());       // no boundary information
+      }
+    else
+      {
+        AssertThrow(false, ExcNotImplemented());
       }
-}
 
+    if (colorize)
+      colorize_quarter_hyper_shell(tria, center, inner_radius, outer_radius);
+  }
 
 
 // Implementation for 3D only
-template <>
-void GridGenerator::quarter_hyper_shell (Triangulation<3> &tria,
-                                         const Point<3> &center,
-                                         const double inner_radius,
-                                         const double outer_radius,
-                                         const size_type n,
-                                         const bool colorize)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
-  if (n == 0 || n == 3)
-    {
-      const double a = inner_radius*std::sqrt(2.0)/2e0;
-      const double b = outer_radius*std::sqrt(2.0)/2e0;
-      const double c = a*std::sqrt(3.0)/2e0;
-      const double d = b*std::sqrt(3.0)/2e0;
-      const double e = outer_radius/2e0;
-      const double h = inner_radius/2e0;
-
-      std::vector<Point<3> > vertices;
-
-      vertices.push_back (center+Point<3>( 0,  inner_radius, 0)); //0
-      vertices.push_back (center+Point<3>( a,  a, 0));                  //1
-      vertices.push_back (center+Point<3>( b,  b, 0));                  //2
-      vertices.push_back (center+Point<3>( 0, outer_radius, 0));        //3
-      vertices.push_back (center+Point<3>( 0, a , a));                  //4
-      vertices.push_back (center+Point<3>( c, c , h));                  //5
-      vertices.push_back (center+Point<3>( d, d , e));                  //6
-      vertices.push_back (center+Point<3>( 0, b , b));                  //7
-      vertices.push_back (center+Point<3>( inner_radius, 0 , 0));       //8
-      vertices.push_back (center+Point<3>( outer_radius, 0 , 0));       //9
-      vertices.push_back (center+Point<3>( a, 0 , a));  //10
-      vertices.push_back (center+Point<3>( b, 0 , b));  //11
-      vertices.push_back (center+Point<3>( 0, 0 , inner_radius));       //12
-      vertices.push_back (center+Point<3>( 0, 0 , outer_radius));       //13
-
-      const int cell_vertices[3][8] =
-      {
-        {0, 1, 3, 2, 4, 5, 7, 6},
-        {1, 8, 2, 9, 5, 10, 6, 11},
-        {4, 5, 7, 6, 12, 10, 13, 11},
+  template <>
+  void cylinder_shell (Triangulation<3> &tria,
+                       const double      length,
+                       const double      inner_radius,
+                       const double      outer_radius,
+                       const unsigned int   n_radial_cells,
+                       const unsigned int   n_axial_cells)
+  {
+    Assert ((inner_radius > 0) && (inner_radius < outer_radius),
+            ExcInvalidRadii ());
+
+    const double pi = numbers::PI;
+
+    // determine the number of cells
+    // for the grid. if not provided by
+    // the user determine it such that
+    // the length of each cell on the
+    // median (in the middle between
+    // the two circles) is equal to its
+    // radial extent (which is the
+    // difference between the two
+    // radii)
+    const unsigned int N_r = (n_radial_cells == 0 ?
+                              static_cast<unsigned int>
+                              (std::ceil((2*pi* (outer_radius + inner_radius)/2) /
+                                         (outer_radius - inner_radius))) :
+                              n_radial_cells);
+    const unsigned int N_z = (n_axial_cells == 0 ?
+                              static_cast<unsigned int>
+                              (std::ceil (length /
+                                          (2*pi*(outer_radius + inner_radius)/2/N_r))) :
+                              n_axial_cells);
+
+    // set up N vertices on the
+    // outer and N vertices on
+    // the inner circle. the
+    // first N ones are on the
+    // outer one, and all are
+    // numbered counter-clockwise
+    std::vector<Point<2> > vertices_2d(2*N_r);
+    for (unsigned int i=0; i<N_r; ++i)
+      {
+        vertices_2d[i] = Point<2>( std::cos(2*pi * i/N_r),
+                                   std::sin(2*pi * i/N_r)) * outer_radius;
+        vertices_2d[i+N_r] = vertices_2d[i] * (inner_radius/outer_radius);
       };
-      std::vector<CellData<3> > cells(3);
 
-      for (unsigned int i=0; i<3; ++i)
+    std::vector<Point<3> > vertices_3d;
+    vertices_3d.reserve (2*N_r*(N_z+1));
+    for (unsigned int j=0; j<=N_z; ++j)
+      for (unsigned int i=0; i<2*N_r; ++i)
         {
-          for (unsigned int j=0; j<8; ++j)
-            cells[i].vertices[j] = cell_vertices[i][j];
-          cells[i].material_id = 0;
+          const Point<3> v (vertices_2d[i][0],
+                            vertices_2d[i][1],
+                            j*length/N_z);
+          vertices_3d.push_back (v);
         }
 
-      tria.create_triangulation ( vertices, cells, SubCellData());       // no boundary information
-    }
-  else
-    {
-      AssertThrow(false, ExcNotImplemented());
-    }
-
-  if (colorize)
-    colorize_quarter_hyper_shell(tria, center, inner_radius, outer_radius);
-}
+    std::vector<CellData<3> > cells (N_r*N_z, CellData<3>());
 
+    for (unsigned int j=0; j<N_z; ++j)
+      for (unsigned int i=0; i<N_r; ++i)
+        {
+          cells[i+j*N_r].vertices[0] = i + (j+1)*2*N_r;
+          cells[i+j*N_r].vertices[1] = (i+1)%N_r + (j+1)*2*N_r;
+          cells[i+j*N_r].vertices[2] = i + j*2*N_r;
+          cells[i+j*N_r].vertices[3] = (i+1)%N_r + j*2*N_r;
 
-// Implementation for 3D only
-template <>
-void GridGenerator::cylinder_shell (Triangulation<3> &tria,
-                                    const double      length,
-                                    const double      inner_radius,
-                                    const double      outer_radius,
-                                    const size_type   n_radial_cells,
-                                    const size_type   n_axial_cells)
-{
-  Assert ((inner_radius > 0) && (inner_radius < outer_radius),
-          ExcInvalidRadii ());
-
-  const double pi = numbers::PI;
-
-  // determine the number of cells
-  // for the grid. if not provided by
-  // the user determine it such that
-  // the length of each cell on the
-  // median (in the middle between
-  // the two circles) is equal to its
-  // radial extent (which is the
-  // difference between the two
-  // radii)
-  const size_type N_r = (n_radial_cells == 0 ?
-                         static_cast<size_type>
-                         (std::ceil((2*pi* (outer_radius + inner_radius)/2) /
-                                    (outer_radius - inner_radius))) :
-                         n_radial_cells);
-  const size_type N_z = (n_axial_cells == 0 ?
-                         static_cast<size_type>
-                         (std::ceil (length /
-                                     (2*pi*(outer_radius + inner_radius)/2/N_r))) :
-                         n_axial_cells);
-
-  // set up N vertices on the
-  // outer and N vertices on
-  // the inner circle. the
-  // first N ones are on the
-  // outer one, and all are
-  // numbered counter-clockwise
-  std::vector<Point<2> > vertices_2d(2*N_r);
-  for (size_type i=0; i<N_r; ++i)
-    {
-      vertices_2d[i] = Point<2>( std::cos(2*pi * i/N_r),
-                                 std::sin(2*pi * i/N_r)) * outer_radius;
-      vertices_2d[i+N_r] = vertices_2d[i] * (inner_radius/outer_radius);
-    };
+          cells[i+j*N_r].vertices[4] = N_r+i + (j+1)*2*N_r;
+          cells[i+j*N_r].vertices[5] = N_r+((i+1)%N_r) + (j+1)*2*N_r;
+          cells[i+j*N_r].vertices[6] = N_r+i + j*2*N_r;
+          cells[i+j*N_r].vertices[7] = N_r+((i+1)%N_r) + j*2*N_r;
 
-  std::vector<Point<3> > vertices_3d;
-  vertices_3d.reserve (2*N_r*(N_z+1));
-  for (size_type j=0; j<=N_z; ++j)
-    for (size_type i=0; i<2*N_r; ++i)
-      {
-        const Point<3> v (vertices_2d[i][0],
-                          vertices_2d[i][1],
-                          j*length/N_z);
-        vertices_3d.push_back (v);
-      }
+          cells[i+j*N_r].material_id = 0;
+        }
 
-  std::vector<CellData<3> > cells (N_r*N_z, CellData<3>());
+    tria.create_triangulation (
+      vertices_3d, cells, SubCellData());
+  }
 
-  for (size_type j=0; j<N_z; ++j)
-    for (size_type i=0; i<N_r; ++i)
-      {
-        cells[i+j*N_r].vertices[0] = i + (j+1)*2*N_r;
-        cells[i+j*N_r].vertices[1] = (i+1)%N_r + (j+1)*2*N_r;
-        cells[i+j*N_r].vertices[2] = i + j*2*N_r;
-        cells[i+j*N_r].vertices[3] = (i+1)%N_r + j*2*N_r;
 
-        cells[i+j*N_r].vertices[4] = N_r+i + (j+1)*2*N_r;
-        cells[i+j*N_r].vertices[5] = N_r+((i+1)%N_r) + (j+1)*2*N_r;
-        cells[i+j*N_r].vertices[6] = N_r+i + j*2*N_r;
-        cells[i+j*N_r].vertices[7] = N_r+((i+1)%N_r) + j*2*N_r;
 
-        cells[i+j*N_r].material_id = 0;
+  template <int dim, int spacedim>
+  void
+  merge_triangulations (const Triangulation<dim, spacedim> &triangulation_1,
+                        const Triangulation<dim, spacedim> &triangulation_2,
+                        Triangulation<dim, spacedim>       &result)
+  {
+    Assert (triangulation_1.n_levels() == 1,
+            ExcMessage ("The input triangulations must be coarse meshes."));
+    Assert (triangulation_2.n_levels() == 1,
+            ExcMessage ("The input triangulations must be coarse meshes."));
+
+    // get the union of the set of vertices
+    std::vector<Point<spacedim> > vertices = triangulation_1.get_vertices();
+    vertices.insert (vertices.end(),
+                     triangulation_2.get_vertices().begin(),
+                     triangulation_2.get_vertices().end());
+
+    // now form the union of the set of cells
+    std::vector<CellData<dim> > cells;
+    cells.reserve (triangulation_1.n_cells() + triangulation_2.n_cells());
+    for (typename Triangulation<dim,spacedim>::cell_iterator
+         cell = triangulation_1.begin(); cell != triangulation_1.end(); ++cell)
+      {
+        CellData<dim> this_cell;
+        for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+          this_cell.vertices[v] = cell->vertex_index(v);
+        this_cell.material_id = cell->material_id();
+        cells.push_back (this_cell);
       }
 
-  tria.create_triangulation (
-    vertices_3d, cells, SubCellData());
-}
-
-
-
-template <int dim, int spacedim>
-void
-GridGenerator::
-merge_triangulations (const Triangulation<dim, spacedim> &triangulation_1,
-                      const Triangulation<dim, spacedim> &triangulation_2,
-                      Triangulation<dim, spacedim>       &result)
-{
-  Assert (triangulation_1.n_levels() == 1,
-          ExcMessage ("The input triangulations must be coarse meshes."));
-  Assert (triangulation_2.n_levels() == 1,
-          ExcMessage ("The input triangulations must be coarse meshes."));
-
-  // get the union of the set of vertices
-  std::vector<Point<spacedim> > vertices = triangulation_1.get_vertices();
-  vertices.insert (vertices.end(),
-                   triangulation_2.get_vertices().begin(),
-                   triangulation_2.get_vertices().end());
-
-  // now form the union of the set of cells
-  std::vector<CellData<dim> > cells;
-  cells.reserve (triangulation_1.n_cells() + triangulation_2.n_cells());
-  for (typename Triangulation<dim,spacedim>::cell_iterator
-       cell = triangulation_1.begin(); cell != triangulation_1.end(); ++cell)
-    {
-      CellData<dim> this_cell;
-      for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
-        this_cell.vertices[v] = cell->vertex_index(v);
-      this_cell.material_id = cell->material_id();
-      cells.push_back (this_cell);
-    }
-
-  // now do the same for the other other mesh. note that we have to
-  // translate the vertex indices
-  for (typename Triangulation<dim,spacedim>::cell_iterator
-       cell = triangulation_2.begin(); cell != triangulation_2.end(); ++cell)
-    {
-      CellData<dim> this_cell;
-      for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
-        this_cell.vertices[v] = cell->vertex_index(v) + triangulation_1.n_vertices();
-      this_cell.material_id = cell->material_id();
-      cells.push_back (this_cell);
-    }
-
-  // throw out duplicated vertices from the two meshes
-  // and create the triangulation
-  SubCellData subcell_data;
-  std::vector<unsigned int> considered_vertices;
-  GridTools::delete_duplicated_vertices (vertices, cells, subcell_data, considered_vertices);
-  result.clear ();
-  result.create_triangulation (vertices, cells, subcell_data);
-}
-
-void
-GridGenerator::
-extrude_triangulation(const Triangulation<2, 2> &input,
-                      const size_type n_slices,
-                      const double height,
-                      Triangulation<3,3> &result)
-{
-  Assert (input.n_levels() == 1,
-          ExcMessage ("The input triangulations must be coarse meshes."));
-  Assert(result.n_cells()==0, ExcMessage("resultin Triangulation need to be empty upon calling extrude_triangulation."));
-  Assert(height>0, ExcMessage("The height in extrude_triangulation needs to be positive."));
-  Assert(n_slices>=2, ExcMessage("The number of slices in extrude_triangulation needs to be at least 2."));
-
-  std::vector<Point<3> > points(n_slices*input.n_vertices());
-  std::vector<CellData<3> > cells;
-  cells.reserve((n_slices-1)*input.n_active_cells());
+    // now do the same for the other other mesh. note that we have to
+    // translate the vertex indices
+    for (typename Triangulation<dim,spacedim>::cell_iterator
+         cell = triangulation_2.begin(); cell != triangulation_2.end(); ++cell)
+      {
+        CellData<dim> this_cell;
+        for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
+          this_cell.vertices[v] = cell->vertex_index(v) + triangulation_1.n_vertices();
+        this_cell.material_id = cell->material_id();
+        cells.push_back (this_cell);
+      }
 
-  for (size_type slice=0; slice<n_slices; ++slice)
-    {
-      for (size_type i=0; i<input.n_vertices(); ++i)
+    // throw out duplicated vertices from the two meshes
+    // and create the triangulation
+    SubCellData subcell_data;
+    std::vector<unsigned int> considered_vertices;
+    GridTools::delete_duplicated_vertices (vertices, cells, subcell_data, considered_vertices);
+    result.clear ();
+    result.create_triangulation (vertices, cells, subcell_data);
+  }
+
+
+  void
+  extrude_triangulation(const Triangulation<2, 2> &input,
+                        const unsigned int n_slices,
+                        const double height,
+                        Triangulation<3,3> &result)
+  {
+    Assert (input.n_levels() == 1,
+            ExcMessage ("The input triangulations must be coarse meshes."));
+    Assert(result.n_cells()==0, ExcMessage("resultin Triangulation need to be empty upon calling extrude_triangulation."));
+    Assert(height>0, ExcMessage("The height in extrude_triangulation needs to be positive."));
+    Assert(n_slices>=2, ExcMessage("The number of slices in extrude_triangulation needs to be at least 2."));
 
-        {
-          const Point<2> &v = input.get_vertices()[i];
-          points[i+slice*input.n_vertices()](0) = v(0);
-          points[i+slice*input.n_vertices()](1) = v(1);
-          points[i+slice*input.n_vertices()](2) = height * slice / (n_slices-1);
-        }
-    }
+    std::vector<Point<3> > points(n_slices*input.n_vertices());
+    std::vector<CellData<3> > cells;
+    cells.reserve((n_slices-1)*input.n_active_cells());
 
-  for (Triangulation<2,2>::cell_iterator
-       cell = input.begin(); cell != input.end(); ++cell)
-    {
-      for (size_type slice=0; slice<n_slices-1; ++slice)
-        {
-          CellData<3> this_cell;
-          for (unsigned int v=0; v<GeometryInfo<2>::vertices_per_cell; ++v)
-            {
-              this_cell.vertices[v]
-                = cell->vertex_index(v)+slice*input.n_vertices();
-              this_cell.vertices[v+GeometryInfo<2>::vertices_per_cell]
-                = cell->vertex_index(v)+(slice+1)*input.n_vertices();
-            }
+    for (unsigned int slice=0; slice<n_slices; ++slice)
+      {
+        for (unsigned int i=0; i<input.n_vertices(); ++i)
 
-          this_cell.material_id = cell->material_id();
-          cells.push_back(this_cell);
-        }
-    }
+          {
+            const Point<2> &v = input.get_vertices()[i];
+            points[i+slice*input.n_vertices()](0) = v(0);
+            points[i+slice*input.n_vertices()](1) = v(1);
+            points[i+slice*input.n_vertices()](2) = height * slice / (n_slices-1);
+          }
+      }
 
-  SubCellData s;
-  types::boundary_id bid=0;
-  s.boundary_quads.reserve(input.n_active_lines()*(n_slices-1) + input.n_active_cells()*2);
-  for (Triangulation<2,2>::cell_iterator
-       cell = input.begin(); cell != input.end(); ++cell)
-    {
-      CellData<2> quad;
-      for (unsigned int f=0; f<4; ++f)
-        if (cell->at_boundary(f))
+    for (Triangulation<2,2>::cell_iterator
+         cell = input.begin(); cell != input.end(); ++cell)
+      {
+        for (unsigned int slice=0; slice<n_slices-1; ++slice)
           {
-            quad.boundary_id = cell->face(f)->boundary_indicator();
-            bid = std::max(bid, quad.boundary_id);
-            for (size_type slice=0; slice<n_slices-1; ++slice)
+            CellData<3> this_cell;
+            for (unsigned int v=0; v<GeometryInfo<2>::vertices_per_cell; ++v)
               {
-                quad.vertices[0] = cell->face(f)->vertex_index(0)+slice*input.n_vertices();
-                quad.vertices[1] = cell->face(f)->vertex_index(1)+slice*input.n_vertices();
-                quad.vertices[2] = cell->face(f)->vertex_index(0)+(slice+1)*input.n_vertices();
-                quad.vertices[3] = cell->face(f)->vertex_index(1)+(slice+1)*input.n_vertices();
-                s.boundary_quads.push_back(quad);
+                this_cell.vertices[v]
+                  = cell->vertex_index(v)+slice*input.n_vertices();
+                this_cell.vertices[v+GeometryInfo<2>::vertices_per_cell]
+                  = cell->vertex_index(v)+(slice+1)*input.n_vertices();
               }
-          }
-    }
 
-  for (Triangulation<2,2>::cell_iterator
-       cell = input.begin(); cell != input.end(); ++cell)
-    {
-      CellData<2> quad;
-      quad.boundary_id = bid + 1;
-      quad.vertices[0] = cell->vertex_index(0);
-      quad.vertices[1] = cell->vertex_index(1);
-      quad.vertices[2] = cell->vertex_index(2);
-      quad.vertices[3] = cell->vertex_index(3);
-      s.boundary_quads.push_back(quad);
-
-      quad.boundary_id = bid + 2;
-      for (int i=0; i<4; ++i)
-        quad.vertices[i] += (n_slices-1)*input.n_vertices();
-      s.boundary_quads.push_back(quad);
-    }
+            this_cell.material_id = cell->material_id();
+            cells.push_back(this_cell);
+          }
+      }
 
+    SubCellData s;
+    types::boundary_id bid=0;
+    s.boundary_quads.reserve(input.n_active_lines()*(n_slices-1) + input.n_active_cells()*2);
+    for (Triangulation<2,2>::cell_iterator
+         cell = input.begin(); cell != input.end(); ++cell)
+      {
+        CellData<2> quad;
+        for (unsigned int f=0; f<4; ++f)
+          if (cell->at_boundary(f))
+            {
+              quad.boundary_id = cell->face(f)->boundary_indicator();
+              bid = std::max(bid, quad.boundary_id);
+              for (unsigned int slice=0; slice<n_slices-1; ++slice)
+                {
+                  quad.vertices[0] = cell->face(f)->vertex_index(0)+slice*input.n_vertices();
+                  quad.vertices[1] = cell->face(f)->vertex_index(1)+slice*input.n_vertices();
+                  quad.vertices[2] = cell->face(f)->vertex_index(0)+(slice+1)*input.n_vertices();
+                  quad.vertices[3] = cell->face(f)->vertex_index(1)+(slice+1)*input.n_vertices();
+                  s.boundary_quads.push_back(quad);
+                }
+            }
+      }
 
+    for (Triangulation<2,2>::cell_iterator
+         cell = input.begin(); cell != input.end(); ++cell)
+      {
+        CellData<2> quad;
+        quad.boundary_id = bid + 1;
+        quad.vertices[0] = cell->vertex_index(0);
+        quad.vertices[1] = cell->vertex_index(1);
+        quad.vertices[2] = cell->vertex_index(2);
+        quad.vertices[3] = cell->vertex_index(3);
+        s.boundary_quads.push_back(quad);
+
+        quad.boundary_id = bid + 2;
+        for (int i=0; i<4; ++i)
+          quad.vertices[i] += (n_slices-1)*input.n_vertices();
+        s.boundary_quads.push_back(quad);
+      }
 
-  result.create_triangulation (
-    points,
-    cells,
-    s);
-}
+    result.create_triangulation (points,
+                                 cells,
+                                 s);
+  }
 
 
-// make the following function inline. this is so that it becomes marked
-// internal/weak for the linker and we don't get multiply defined errors
-// when linking with more than one dimension at a time. Usually we used
-// the trick of putting these functions in a .all_dimensions.cc file, but
-// this is not necessary here as this is an internal only function.
-inline
-void GridGenerator::laplace_solve (const SparseMatrix<double> &S,
-                                   const std::map<size_type,double> &m,
-                                   Vector<double> &u)
-{
-  const size_type n_dofs=S.n();
-  FilteredMatrix<Vector<double> > SF (S);
-  PreconditionJacobi<SparseMatrix<double> > prec;
-  prec.initialize(S, 1.2);
-  FilteredMatrix<Vector<double> > PF (prec);
+  /**
+   * Solve the Laplace equation for @p laplace_transformation function for one
+   * of the @p dim space dimensions. Factorized into a function of its own
+   * in order to allow parallel execution.
+   */
+  void laplace_solve (const SparseMatrix<double> &S,
+                      const std::map<unsigned int,double> &m,
+                      Vector<double> &u)
+  {
+    const unsigned int n_dofs=S.n();
+    FilteredMatrix<Vector<double> > SF (S);
+    PreconditionJacobi<SparseMatrix<double> > prec;
+    prec.initialize(S, 1.2);
+    FilteredMatrix<Vector<double> > PF (prec);
 
-  SolverControl control (n_dofs, 1.e-10, false, false);
-  GrowingVectorMemory<Vector<double> > mem;
-  SolverCG<Vector<double> > solver (control, mem);
+    SolverControl control (n_dofs, 1.e-10, false, false);
+    GrowingVectorMemory<Vector<double> > mem;
+    SolverCG<Vector<double> > solver (control, mem);
 
-  Vector<double> f(n_dofs);
+    Vector<double> f(n_dofs);
 
-  SF.add_constraints(m);
-  SF.apply_constraints (f, true);
-  solver.solve(SF, u, f, PF);
-}
+    SF.add_constraints(m);
+    SF.apply_constraints (f, true);
+    solver.solve(SF, u, f, PF);
+  }
 
 
 // Implementation for 1D only
-template <>
-void GridGenerator::laplace_transformation (Triangulation<1> &,
-                                            const std::map<size_type,Point<1> > &)
-{
-  Assert(false, ExcNotImplemented());
-}
+  template <>
+  void laplace_transformation (Triangulation<1> &,
+                               const std::map<unsigned int,Point<1> > &)
+  {
+    Assert(false, ExcNotImplemented());
+  }
 
 
 // Implementation for dimensions except 1
-template <int dim>
-void GridGenerator::laplace_transformation (Triangulation<dim> &tria,
-                                            const std::map<size_type,Point<dim> > &new_points)
-{
-  // first provide everything that is
-  // needed for solving a Laplace
-  // equation.
-  MappingQ1<dim> mapping_q1;
-  FE_Q<dim> q1(1);
-
-  DoFHandler<dim> dof_handler(tria);
-  dof_handler.distribute_dofs(q1);
-
-  CompressedSparsityPattern c_sparsity_pattern (dof_handler.n_dofs (),
-                                                dof_handler.n_dofs ());
-  DoFTools::make_sparsity_pattern (dof_handler, c_sparsity_pattern);
-  c_sparsity_pattern.compress ();
-
-  SparsityPattern sparsity_pattern;
-  sparsity_pattern.copy_from (c_sparsity_pattern);
-  sparsity_pattern.compress ();
-
-  SparseMatrix<double> S(sparsity_pattern);
-
-  QGauss<dim> quadrature(4);
-
-  MatrixCreator::create_laplace_matrix(mapping_q1, dof_handler, quadrature, S);
-
-  // set up the boundary values for
-  // the laplace problem
-  std::vector<std::map<size_type,double> > m(dim);
-  typename std::map<size_type,Point<dim> >::const_iterator map_iter;
-  typename std::map<size_type,Point<dim> >::const_iterator map_end=new_points.end();
-
-  // fill these maps using the data
-  // given by new_points
-  typename DoFHandler<dim>::cell_iterator cell=dof_handler.begin_active(),
-                                          endc=dof_handler.end();
-  typename DoFHandler<dim>::face_iterator face;
-  for (; cell!=endc; ++cell)
-    {
-      if (cell->at_boundary())
-        for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
-          {
-            face=cell->face(face_no);
-            if (face->at_boundary())
-              for (unsigned int vertex_no=0;
-                   vertex_no<GeometryInfo<dim>::vertices_per_face; ++vertex_no)
-                {
-                  const size_type vertex_index=face->vertex_index(vertex_no);
-                  map_iter=new_points.find(vertex_index);
-
-                  if (map_iter!=map_end)
-                    for (unsigned int i=0; i<dim; ++i)
-                      m[i].insert(std::pair<size_type,double> (
-                                    face->vertex_dof_index(vertex_no, 0), map_iter->second(i)));
-                }
-          }
-    }
+  template <int dim>
+  void laplace_transformation (Triangulation<dim> &tria,
+                               const std::map<unsigned int,Point<dim> > &new_points)
+  {
+    // first provide everything that is
+    // needed for solving a Laplace
+    // equation.
+    MappingQ1<dim> mapping_q1;
+    FE_Q<dim> q1(1);
+
+    DoFHandler<dim> dof_handler(tria);
+    dof_handler.distribute_dofs(q1);
+
+    CompressedSparsityPattern c_sparsity_pattern (dof_handler.n_dofs (),
+                                                  dof_handler.n_dofs ());
+    DoFTools::make_sparsity_pattern (dof_handler, c_sparsity_pattern);
+    c_sparsity_pattern.compress ();
+
+    SparsityPattern sparsity_pattern;
+    sparsity_pattern.copy_from (c_sparsity_pattern);
+    sparsity_pattern.compress ();
+
+    SparseMatrix<double> S(sparsity_pattern);
+
+    QGauss<dim> quadrature(4);
+
+    MatrixCreator::create_laplace_matrix(mapping_q1, dof_handler, quadrature, S);
+
+    // set up the boundary values for
+    // the laplace problem
+    std::vector<std::map<unsigned int,double> > m(dim);
+    typename std::map<unsigned int,Point<dim> >::const_iterator map_iter;
+    typename std::map<unsigned int,Point<dim> >::const_iterator map_end=new_points.end();
+
+    // fill these maps using the data
+    // given by new_points
+    typename DoFHandler<dim>::cell_iterator cell=dof_handler.begin_active(),
+                                            endc=dof_handler.end();
+    typename DoFHandler<dim>::face_iterator face;
+    for (; cell!=endc; ++cell)
+      {
+        if (cell->at_boundary())
+          for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
+            {
+              face=cell->face(face_no);
+              if (face->at_boundary())
+                for (unsigned int vertex_no=0;
+                     vertex_no<GeometryInfo<dim>::vertices_per_face; ++vertex_no)
+                  {
+                    const unsigned int vertex_index=face->vertex_index(vertex_no);
+                    map_iter=new_points.find(vertex_index);
 
-  // solve the dim problems with
-  // different right hand sides.
-  Vector<double> us[dim];
-  for (unsigned int i=0; i<dim; ++i)
-    us[i].reinit (dof_handler.n_dofs());
-
-  // solve linear systems in parallel
-  Threads::TaskGroup<> tasks;
-  for (unsigned int i=0; i<dim; ++i)
-    tasks += Threads::new_task (&GridGenerator::laplace_solve,
-                                S, m[i], us[i]);
-  tasks.join_all ();
-
-  // change the coordinates of the
-  // points of the triangulation
-  // according to the computed values
-  for (cell=dof_handler.begin_active(); cell!=endc; ++cell)
-    for (size_type vertex_no=0;
-         vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
-      {
-        Point<dim> &v=cell->vertex(vertex_no);
-        const size_type dof_index=cell->vertex_dof_index(vertex_no, 0);
-        for (unsigned int i=0; i<dim; ++i)
-          v(i)=us[i](dof_index);
+                    if (map_iter!=map_end)
+                      for (unsigned int i=0; i<dim; ++i)
+                        m[i].insert(std::pair<unsigned int,double> (
+                                      face->vertex_dof_index(vertex_no, 0), map_iter->second(i)));
+                  }
+            }
       }
-}
 
+    // solve the dim problems with
+    // different right hand sides.
+    Vector<double> us[dim];
+    for (unsigned int i=0; i<dim; ++i)
+      us[i].reinit (dof_handler.n_dofs());
+
+    // solve linear systems in parallel
+    Threads::TaskGroup<> tasks;
+    for (unsigned int i=0; i<dim; ++i)
+      tasks += Threads::new_task (&laplace_solve,
+                                  S, m[i], us[i]);
+    tasks.join_all ();
+
+    // change the coordinates of the
+    // points of the triangulation
+    // according to the computed values
+    for (cell=dof_handler.begin_active(); cell!=endc; ++cell)
+      for (unsigned int vertex_no=0;
+           vertex_no<GeometryInfo<dim>::vertices_per_cell; ++vertex_no)
+        {
+          Point<dim> &v=cell->vertex(vertex_no);
+          const unsigned int dof_index=cell->vertex_dof_index(vertex_no, 0);
+          for (unsigned int i=0; i<dim; ++i)
+            v(i)=us[i](dof_index);
+        }
+  }
 
 
-template <>
-void GridGenerator::hyper_cube_with_cylindrical_hole (Triangulation<1> &,
-                                                      const double,
-                                                      const double,
-                                                      const double,
-                                                      const size_type,
-                                                      bool)
-{
-  Assert(false, ExcNotImplemented());
-}
 
+  template <>
+  void hyper_cube_with_cylindrical_hole (Triangulation<1> &,
+                                         const double,
+                                         const double,
+                                         const double,
+                                         const unsigned int,
+                                         bool)
+  {
+    Assert(false, ExcNotImplemented());
+  }
 
 
-template <>
-void
-GridGenerator::hyper_cube_with_cylindrical_hole (Triangulation<2> &triangulation,
-                                                 const double inner_radius,
-                                                 const double outer_radius,
-                                                 const double, // width,
-                                                 const size_type, // width_repetition,
-                                                 bool colorize)
-{
-  const int dim = 2;
-
-  Assert(inner_radius < outer_radius,
-         ExcMessage("outer_radius has to be bigger than inner_radius."));
-
-  Point<dim> center;
-  // We create an hyper_shell in two dimensions, and then we modify it.
-  GridGenerator::hyper_shell (triangulation,
-                              center, inner_radius, outer_radius,
-                              8);
-  Triangulation<dim>::active_cell_iterator
-  cell = triangulation.begin_active(),
-  endc = triangulation.end();
-  std::vector<bool> treated_vertices(triangulation.n_vertices(), false);
-  for (; cell != endc; ++cell)
-    {
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-        if (cell->face(f)->at_boundary())
-          {
-            for (unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v)
-              {
-                size_type vv = cell->face(f)->vertex_index(v);
-                if (treated_vertices[vv] == false)
-                  {
-                    treated_vertices[vv] = true;
-                    switch (vv)
-                      {
-                      case 1:
-                        cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,outer_radius);
-                        break;
-                      case 3:
-                        cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,outer_radius);
-                        break;
-                      case 5:
-                        cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,-outer_radius);
-                        break;
-                      case 7:
-                        cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,-outer_radius);
-                      default:
-                        break;
-                      }
-                  }
-              }
-          }
-    }
-  double eps = 1e-3 * outer_radius;
-  cell = triangulation.begin_active();
-  for (; cell != endc; ++cell)
-    {
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-        if (cell->face(f)->at_boundary())
-          {
-            double dx = cell->face(f)->center()(0) - center(0);
-            double dy = cell->face(f)->center()(1) - center(1);
-            if (colorize)
-              {
-                if (std::abs(dx + outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(0);
-                else if (std::abs(dx - outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(1);
-                else if (std::abs(dy + outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(2);
-                else if (std::abs(dy - outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(3);
-                else
-                  cell->face(f)->set_boundary_indicator(4);
-              }
-            else
-              {
-                double d = (cell->face(f)->center() - center).norm();
-                if (d-inner_radius < 0)
-                  cell->face(f)->set_boundary_indicator(1);
-                else
-                  cell->face(f)->set_boundary_indicator(0);
-              }
-          }
-    }
-}
 
-template <>
-void GridGenerator::hyper_cube_with_cylindrical_hole(Triangulation<3> &triangulation,
-                                                     const double inner_radius,
-                                                     const double outer_radius,
-                                                     const double L,
-                                                     const size_type Nz,
-                                                     bool colorize)
-{
-  const int dim = 3;
-
-  Assert(inner_radius < outer_radius,
-         ExcMessage("outer_radius has to be bigger than inner_radius."));
-  Assert(L > 0,
-         ExcMessage("Must give positive extension L"));
-  Assert(Nz >= 1, ExcLowerRange(1, Nz));
-
-  GridGenerator::cylinder_shell (triangulation,
-                                 L, inner_radius, outer_radius,
-                                 8,
-                                 Nz);
-
-  Triangulation<dim>::active_cell_iterator
-  cell = triangulation.begin_active(),
-  endc = triangulation.end();
-  std::vector<bool> treated_vertices(triangulation.n_vertices(), false);
-  for (; cell != endc; ++cell)
-    {
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-        if (cell->face(f)->at_boundary())
-          {
-            for (unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v)
-              {
-                size_type vv = cell->face(f)->vertex_index(v);
-                if (treated_vertices[vv] == false)
-                  {
-                    treated_vertices[vv] = true;
-                    for (size_type i=0; i<=Nz; ++i)
-                      {
-                        double d = ((double) i)*L/((double) Nz);
-                        switch (vv-i*16)
-                          {
-                          case 1:
-                            cell->face(f)->vertex(v) = Point<dim>(outer_radius,outer_radius,d);
-                            break;
-                          case 3:
-                            cell->face(f)->vertex(v) = Point<dim>(-outer_radius,outer_radius,d);
-                            break;
-                          case 5:
-                            cell->face(f)->vertex(v) = Point<dim>(-outer_radius,-outer_radius,d);
-                            break;
-                          case 7:
-                            cell->face(f)->vertex(v) = Point<dim>(outer_radius,-outer_radius,d);
-                            break;
-                          default:
-                            break;
-                          }
-                      }
-                  }
-              }
-          }
-    }
-  double eps = 1e-3 * outer_radius;
-  cell = triangulation.begin_active();
-  for (; cell != endc; ++cell)
-    {
-      for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
-        if (cell->face(f)->at_boundary())
-          {
-            double dx = cell->face(f)->center()(0);
-            double dy = cell->face(f)->center()(1);
-            double dz = cell->face(f)->center()(2);
+  template <>
+  void
+  hyper_cube_with_cylindrical_hole (Triangulation<2> &triangulation,
+                                    const double inner_radius,
+                                    const double outer_radius,
+                                    const double, // width,
+                                    const unsigned int, // width_repetition,
+                                    bool colorize)
+  {
+    const int dim = 2;
+
+    Assert(inner_radius < outer_radius,
+           ExcMessage("outer_radius has to be bigger than inner_radius."));
+
+    Point<dim> center;
+    // We create an hyper_shell in two dimensions, and then we modify it.
+    hyper_shell (triangulation,
+                 center, inner_radius, outer_radius,
+                 8);
+    Triangulation<dim>::active_cell_iterator
+    cell = triangulation.begin_active(),
+    endc = triangulation.end();
+    std::vector<bool> treated_vertices(triangulation.n_vertices(), false);
+    for (; cell != endc; ++cell)
+      {
+        for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+          if (cell->face(f)->at_boundary())
+            {
+              for (unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v)
+                {
+                  unsigned int vv = cell->face(f)->vertex_index(v);
+                  if (treated_vertices[vv] == false)
+                    {
+                      treated_vertices[vv] = true;
+                      switch (vv)
+                        {
+                        case 1:
+                          cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,outer_radius);
+                          break;
+                        case 3:
+                          cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,outer_radius);
+                          break;
+                        case 5:
+                          cell->face(f)->vertex(v) = center+Point<dim>(-outer_radius,-outer_radius);
+                          break;
+                        case 7:
+                          cell->face(f)->vertex(v) = center+Point<dim>(outer_radius,-outer_radius);
+                        default:
+                          break;
+                        }
+                    }
+                }
+            }
+      }
+    double eps = 1e-3 * outer_radius;
+    cell = triangulation.begin_active();
+    for (; cell != endc; ++cell)
+      {
+        for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+          if (cell->face(f)->at_boundary())
+            {
+              double dx = cell->face(f)->center()(0) - center(0);
+              double dy = cell->face(f)->center()(1) - center(1);
+              if (colorize)
+                {
+                  if (std::abs(dx + outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(0);
+                  else if (std::abs(dx - outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(1);
+                  else if (std::abs(dy + outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(2);
+                  else if (std::abs(dy - outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(3);
+                  else
+                    cell->face(f)->set_boundary_indicator(4);
+                }
+              else
+                {
+                  double d = (cell->face(f)->center() - center).norm();
+                  if (d-inner_radius < 0)
+                    cell->face(f)->set_boundary_indicator(1);
+                  else
+                    cell->face(f)->set_boundary_indicator(0);
+                }
+            }
+      }
+  }
 
-            if (colorize)
-              {
-                if (std::abs(dx + outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(0);
 
-                else if (std::abs(dx - outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(1);
 
-                else if (std::abs(dy + outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(2);
+  template <>
+  void hyper_cube_with_cylindrical_hole(Triangulation<3> &triangulation,
+                                        const double inner_radius,
+                                        const double outer_radius,
+                                        const double L,
+                                        const unsigned int Nz,
+                                        bool colorize)
+  {
+    const int dim = 3;
+
+    Assert(inner_radius < outer_radius,
+           ExcMessage("outer_radius has to be bigger than inner_radius."));
+    Assert(L > 0,
+           ExcMessage("Must give positive extension L"));
+    Assert(Nz >= 1, ExcLowerRange(1, Nz));
+
+    cylinder_shell (triangulation,
+                    L, inner_radius, outer_radius,
+                    8,
+                    Nz);
+
+    Triangulation<dim>::active_cell_iterator
+    cell = triangulation.begin_active(),
+    endc = triangulation.end();
+    std::vector<bool> treated_vertices(triangulation.n_vertices(), false);
+    for (; cell != endc; ++cell)
+      {
+        for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+          if (cell->face(f)->at_boundary())
+            {
+              for (unsigned int v=0; v < GeometryInfo<dim>::vertices_per_face; ++v)
+                {
+                  unsigned int vv = cell->face(f)->vertex_index(v);
+                  if (treated_vertices[vv] == false)
+                    {
+                      treated_vertices[vv] = true;
+                      for (unsigned int i=0; i<=Nz; ++i)
+                        {
+                          double d = ((double) i)*L/((double) Nz);
+                          switch (vv-i*16)
+                            {
+                            case 1:
+                              cell->face(f)->vertex(v) = Point<dim>(outer_radius,outer_radius,d);
+                              break;
+                            case 3:
+                              cell->face(f)->vertex(v) = Point<dim>(-outer_radius,outer_radius,d);
+                              break;
+                            case 5:
+                              cell->face(f)->vertex(v) = Point<dim>(-outer_radius,-outer_radius,d);
+                              break;
+                            case 7:
+                              cell->face(f)->vertex(v) = Point<dim>(outer_radius,-outer_radius,d);
+                              break;
+                            default:
+                              break;
+                            }
+                        }
+                    }
+                }
+            }
+      }
+    double eps = 1e-3 * outer_radius;
+    cell = triangulation.begin_active();
+    for (; cell != endc; ++cell)
+      {
+        for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+          if (cell->face(f)->at_boundary())
+            {
+              double dx = cell->face(f)->center()(0);
+              double dy = cell->face(f)->center()(1);
+              double dz = cell->face(f)->center()(2);
 
-                else if (std::abs(dy - outer_radius) < eps)
-                  cell->face(f)->set_boundary_indicator(3);
+              if (colorize)
+                {
+                  if (std::abs(dx + outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(0);
 
-                else if (std::abs(dz) < eps)
-                  cell->face(f)->set_boundary_indicator(4);
+                  else if (std::abs(dx - outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(1);
 
-                else if (std::abs(dz - L) < eps)
-                  cell->face(f)->set_boundary_indicator(5);
+                  else if (std::abs(dy + outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(2);
 
-                else
-                  {
-                    cell->face(f)->set_boundary_indicator(6);
-                    for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
-                      cell->face(f)->line(l)->set_boundary_indicator(6);
-                  }
+                  else if (std::abs(dy - outer_radius) < eps)
+                    cell->face(f)->set_boundary_indicator(3);
 
-              }
-            else
-              {
-                Point<dim> c = cell->face(f)->center();
-                c(2) = 0;
-                double d = c.norm();
-                if (d-inner_radius < 0)
-                  {
-                    cell->face(f)->set_boundary_indicator(1);
-                    for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
-                      cell->face(f)->line(l)->set_boundary_indicator(1);
-                  }
-                else
-                  cell->face(f)->set_boundary_indicator(0);
-              }
-          }
-    }
-}
+                  else if (std::abs(dz) < eps)
+                    cell->face(f)->set_boundary_indicator(4);
+
+                  else if (std::abs(dz - L) < eps)
+                    cell->face(f)->set_boundary_indicator(5);
+
+                  else
+                    {
+                      cell->face(f)->set_boundary_indicator(6);
+                      for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+                        cell->face(f)->line(l)->set_boundary_indicator(6);
+                    }
 
+                }
+              else
+                {
+                  Point<dim> c = cell->face(f)->center();
+                  c(2) = 0;
+                  double d = c.norm();
+                  if (d-inner_radius < 0)
+                    {
+                      cell->face(f)->set_boundary_indicator(1);
+                      for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_face; ++l)
+                        cell->face(f)->line(l)->set_boundary_indicator(1);
+                    }
+                  else
+                    cell->face(f)->set_boundary_indicator(0);
+                }
+            }
+      }
+  }
+}
 
 // explicit instantiations
 #include "grid_generator.inst"
index fadcea0bc79024596630f0fb46e782b97f07c0ff..5ce5fcc0f475bec12cadfb927bfc9466a8ad6254 100644 (file)
 
 for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS)
   {
+namespace GridGenerator 
+\{
 #if deal_II_dimension <= deal_II_space_dimension
     template void
-      GridGenerator::hyper_rectangle<deal_II_dimension, deal_II_space_dimension> (
+      hyper_rectangle<deal_II_dimension, deal_II_space_dimension> (
        Triangulation<deal_II_dimension, deal_II_space_dimension> &,
        const Point<deal_II_space_dimension>&, const Point<deal_II_space_dimension>&,
        const bool);
     
     template void
-      GridGenerator::colorize_hyper_rectangle<deal_II_dimension, deal_II_space_dimension> (
-       Triangulation<deal_II_dimension, deal_II_space_dimension> &);
-    
-    template void
-      GridGenerator::hyper_cube<deal_II_dimension, deal_II_space_dimension> (
+      hyper_cube<deal_II_dimension, deal_II_space_dimension> (
        Triangulation<deal_II_dimension, deal_II_space_dimension> &, const double, const double);
     
     template
       void
-      GridGenerator::merge_triangulations
+      merge_triangulations
       (const Triangulation<deal_II_dimension,deal_II_space_dimension> &triangulation_1,
        const Triangulation<deal_II_dimension,deal_II_space_dimension> &triangulation_2,
        Triangulation<deal_II_dimension,deal_II_space_dimension>       &result);
       
 #endif
+\}  
   }
 
 
 for (deal_II_dimension : DIMENSIONS)
 {
-  
+namespace GridGenerator \{  
   template void
-    GridGenerator::subdivided_hyper_cube<deal_II_dimension> (
+    subdivided_hyper_cube<deal_II_dimension> (
       Triangulation<deal_II_dimension> &,
       const unsigned int, const double, const double);
   
   template void
-    GridGenerator::subdivided_hyper_rectangle<deal_II_dimension>
+    subdivided_hyper_rectangle<deal_II_dimension>
     (Triangulation<deal_II_dimension> &,
      const std::vector<unsigned int>&,
      const Point<deal_II_dimension>&,
@@ -61,7 +60,7 @@ for (deal_II_dimension : DIMENSIONS)
   
   template
     void
-    GridGenerator::subdivided_hyper_rectangle(
+    subdivided_hyper_rectangle(
       Triangulation<deal_II_dimension>              &,
       const std::vector<std::vector<double> > &,
       const Point<deal_II_dimension>                &,
@@ -69,32 +68,31 @@ for (deal_II_dimension : DIMENSIONS)
       const bool                       );
   
     template void
-      GridGenerator::parallelepiped<deal_II_dimension> (
+      parallelepiped<deal_II_dimension> (
        Triangulation<deal_II_dimension>&,
        const Point<deal_II_dimension> (&) [deal_II_dimension], 
        const bool);  
   
     template void
-      GridGenerator::subdivided_parallelepiped<deal_II_dimension> (
+      subdivided_parallelepiped<deal_II_dimension> (
        Triangulation<deal_II_dimension>&,
-       const size_type,
+       const unsigned int,
        const Point<deal_II_dimension> (&) [deal_II_dimension], 
        const bool);  
 
     template void
-      GridGenerator::subdivided_parallelepiped<deal_II_dimension> (
+      subdivided_parallelepiped<deal_II_dimension> (
        Triangulation<deal_II_dimension>&,
-       const size_type [deal_II_dimension], 
+       const unsigned int [deal_II_dimension], 
        const Point<deal_II_dimension> (&) [deal_II_dimension], 
        const bool);  
   
 #if deal_II_dimension > 1
   template void
-    GridGenerator::
     laplace_transformation<deal_II_dimension> (Triangulation<deal_II_dimension> &,
-                                              const std::map<types::global_dof_index,Point<deal_II_dimension> > &);
+                                              const std::map<unsigned int,Point<deal_II_dimension> > &);
 #endif
   
-  
+\}  
  }
 
index ed2325f2b1b3d731c11535acad745685ed489c48..a49ede55e228e84b3553f528dfb1b5d28cec9930 100644 (file)
@@ -607,7 +607,7 @@ namespace GridTools
 
   template <int dim>
   void
-  laplace_transform (const std::map<types::global_dof_index,Point<dim> > &new_points,
+  laplace_transform (const std::map<unsigned int,Point<dim> > &new_points,
                      Triangulation<dim> &triangulation)
   {
     //TODO: Move implementation of this function into the current
index 9087a8e74f8f2b41c6f7d5c586eae45086707dc7..44118972249c7376db16733070a17bf3d41a7212 100644 (file)
@@ -161,7 +161,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 #if deal_II_dimension == deal_II_space_dimension  
     template
     void
-    laplace_transform (const std::map<types::global_dof_index,Point<deal_II_dimension> > &new_points,
+    laplace_transform (const std::map<unsigned int,Point<deal_II_dimension> > &new_points,
                        Triangulation<deal_II_dimension> &triangulation);
 
     template
index a9e5b9de0b1603e00c4d6051040cafca90349b9a..021d90b89b8d0831170f179ecec51ba570855828 100644 (file)
@@ -265,22 +265,26 @@ namespace internal
     // distinguish between compressed sparsity types that define row_begin()
     // and SparsityPattern that uses begin() as iterator type
     template <typename Sparsity>
-    void copy_row (const Sparsity       &csp,
-                   const size_type       row,
-                   ChunkSparsityPattern &dst)
+    void copy_row (const Sparsity                  &csp,
+                   const size_type                  row,
+                   const unsigned int               chunk_size,
+                   CompressedSimpleSparsityPattern &dst)
     {
       typename Sparsity::row_iterator col_num = csp.row_begin (row);
+      const size_type reduced_row = row/chunk_size;
       for (; col_num != csp.row_end (row); ++col_num)
-        dst.add (row, *col_num);
+        dst.add (reduced_row, *col_num/chunk_size);
     }
 
-    void copy_row (const SparsityPattern &csp,
-                   const size_type        row,
-                   ChunkSparsityPattern  &dst)
+    void copy_row (const SparsityPattern           &csp,
+                   const size_type                  row,
+                   const unsigned int               chunk_size,
+                   CompressedSimpleSparsityPattern &dst)
     {
       SparsityPattern::iterator col_num = csp.begin (row);
+      const size_type reduced_row = row/chunk_size;
       for (; col_num != csp.end (row); ++col_num)
-        dst.add (row, col_num->column());
+        dst.add (reduced_row, col_num->column()/chunk_size);
     }
   }
 }
@@ -292,23 +296,28 @@ ChunkSparsityPattern::copy_from (const SparsityType &csp,
                                  const size_type     chunk_size)
 {
   Assert (chunk_size > 0, ExcInvalidNumber (chunk_size));
+  this->chunk_size = chunk_size;
+  rows = csp.n_rows();
+  cols = csp.n_cols();
 
-  // count number of entries per row, then initialize the underlying sparsity
-  // pattern
-  std::vector<size_type> entries_per_row (csp.n_rows(), 0);
-  for (size_type row = 0; row<csp.n_rows(); ++row)
-    entries_per_row[row] = csp.row_length(row);
+  // simple case: just use the other sparsity pattern
+  if (chunk_size == 1)
+    {
+      sparsity_pattern.copy_from (csp);
+      return;
+    }
 
-  reinit (csp.n_rows(), csp.n_cols(),
-          entries_per_row,
-          chunk_size);
+  // create a temporary compressed sparsity pattern that collects all entries
+  // from the input sparsity pattern and then initialize the underlying small
+  // sparsity pattern
+  const size_type m_chunks = (csp.n_rows()+chunk_size-1) / chunk_size,
+                  n_chunks = (csp.n_cols()+chunk_size-1) / chunk_size;
+  CompressedSimpleSparsityPattern temporary_sp(m_chunks, n_chunks);
 
-  // then actually fill it
   for (size_type row = 0; row<csp.n_rows(); ++row)
-    internal::copy_row(csp, row, *this);
+    internal::copy_row(csp, row, chunk_size, temporary_sp);
 
-  // finally compress
-  compress ();
+  sparsity_pattern.copy_from (temporary_sp);
 }
 
 
index 099e3703d6925fad293116dbedd2d02ac07c507a..79f46bad9c46c5b1b6a7f6e6b74797a448443197 100644 (file)
@@ -1542,6 +1542,36 @@ bool ConstraintMatrix::is_identity_constrained (const size_type index) const
 }
 
 
+bool ConstraintMatrix::are_identity_constrained (const size_type index1,
+                                                       const size_type index2) const
+{
+  if (is_constrained(index1) == true)
+    {
+      const ConstraintLine &p = lines[lines_cache[calculate_line_index(index1)]];
+      Assert (p.line == index1, ExcInternalError());
+
+      // return if an entry for this line was found and if it has only one
+      // entry equal to 1.0 and that one is index2
+      return ((p.entries.size() == 1) &&
+          (p.entries[0].first == index2) &&
+          (p.entries[0].second == 1.0));
+    }
+  else if (is_constrained(index2) == true)
+    {
+      const ConstraintLine &p = lines[lines_cache[calculate_line_index(index2)]];
+      Assert (p.line == index2, ExcInternalError());
+
+      // return if an entry for this line was found and if it has only one
+      // entry equal to 1.0 and that one is index1
+      return ((p.entries.size() == 1) &&
+          (p.entries[0].first == index1) &&
+          (p.entries[0].second == 1.0));
+    }
+  else
+    return false;
+}
+
+
 
 ConstraintMatrix::size_type
 ConstraintMatrix::max_constraint_indirections () const
index 9295ce6146bbedf2cbbba2b2149dd730f05b99aa..b169d1260a3a3702fdacc73617dd871976a7271b 100644 (file)
@@ -234,7 +234,7 @@ namespace PETScWrappers
     vmult (*y, *x);
 
     // copy the result back to dst
-    ierr = VecCopy (&(*(*y)), dst);
+    ierr = VecCopy (static_cast<const Vec &>(*y), dst);
     AssertThrow (ierr == 0, ExcPETScError(ierr));
 
     delete (x);
index e366b66458b53cd427ad0b2fa3528a3a5d6973ea..6e91035df75019f0ac27841dedef8dd4243e1129 100644 (file)
@@ -43,6 +43,14 @@ namespace PETScWrappers
     }
 
 
+    SparseMatrix::~SparseMatrix ()
+    {
+#if DEAL_II_PETSC_VERSION_LT(3,2,0)
+      const int ierr = MatDestroy (matrix);
+#else
+      const int ierr = MatDestroy (&matrix);
+#endif
+    }
 
     SparseMatrix::SparseMatrix (const MPI_Comm  &communicator,
                                 const size_type  m,
index 7c4cc997ee4aadc034b73de53cde899cc936ba9c..848ba3eec1eb0dfd0a7c9db2b2f677783abf6e01 100644 (file)
@@ -39,6 +39,7 @@ namespace PETScWrappers
       const int ierr
         = VecCreateSeq (PETSC_COMM_SELF, n, &vector);
       AssertThrow (ierr == 0, ExcPETScError(ierr));
+      ghosted = false;
     }
 
 
@@ -130,7 +131,7 @@ namespace PETScWrappers
       MPI_Allreduce (&k, &k_global, 1,
                      MPI_INT, MPI_LOR, communicator);
 
-      if (k_global)
+      if (k_global || has_ghost_elements())
         {
           // FIXME: I'd like to use this here,
           // but somehow it leads to odd errors
@@ -165,9 +166,17 @@ namespace PETScWrappers
     Vector::reinit (const Vector &v,
                     const bool    fast)
     {
-      communicator = v.communicator;
-
-      reinit (communicator, v.size(), v.local_size(), fast);
+      if (v.has_ghost_elements())
+        {
+          reinit (v.locally_owned_elements(), v.ghost_indices, v.communicator);
+          if (!fast)
+            {
+              int ierr = VecSet(vector, 0.0);
+              AssertThrow (ierr == 0, ExcPETScError(ierr));
+            }
+        }
+      else
+        reinit (v.communicator, v.size(), v.local_size(), fast);
     }
 
 
@@ -185,6 +194,14 @@ namespace PETScWrappers
                     const IndexSet &ghost,
                     const MPI_Comm     &comm)
     {
+      int ierr;
+#if DEAL_II_PETSC_VERSION_LT(3,2,0)
+      ierr = VecDestroy (vector);
+#else
+      ierr = VecDestroy (&vector);
+#endif
+      AssertThrow (ierr == 0, ExcPETScError(ierr));
+
       communicator = comm;
 
       Assert(local.is_contiguous(), ExcNotImplemented());
@@ -206,6 +223,14 @@ namespace PETScWrappers
     Vector::reinit (const IndexSet &local,
                     const MPI_Comm &comm)
     {
+      int ierr;
+#if DEAL_II_PETSC_VERSION_LT(3,2,0)
+      ierr = VecDestroy (vector);
+#else
+      ierr = VecDestroy (&vector);
+#endif
+      AssertThrow (ierr == 0, ExcPETScError(ierr));
+
       communicator = comm;
 
       Assert(local.is_contiguous(), ExcNotImplemented());
index b821a61c7106352f05cb107340ab523f65653d38..e436edf79ea2321d7e520abfa5f506033fae3cce 100644 (file)
@@ -531,13 +531,5 @@ namespace SLEPcWrappers
 
 DEAL_II_NAMESPACE_CLOSE
 
-#else
-
-// On gcc2.95 on Alpha OSF1, the native assembler does not like empty
-// files, so provide some dummy code
-namespace
-{
-  void dummy () {}
-}
 #endif // DEAL_II_WITH_SLEPC
 
index ff64e5d87dad8fabf5dd9a61cf8926b975335185..fdd6eb5ae763e01f283d17f9275b69747e2e67c2 100644 (file)
@@ -164,12 +164,5 @@ namespace SLEPcWrappers
 
 DEAL_II_NAMESPACE_CLOSE
 
-#else
-// On gcc2.95 on Alpha OSF1, the native assembler does not like empty
-// files, so provide some dummy code
-namespace
-{
-  void dummy () {}
-}
 #endif // DEAL_II_WITH_SLEPC
 
index 18f2c1b0de777fd14dcc87c734eb9b9e5fcbf45c..edef0ca4efcb1db7beabdf8d57370af5db40c475 100644 (file)
@@ -1195,6 +1195,7 @@ template void SparsityPattern::copy_from<CompressedSimpleSparsityPattern> (const
 template void SparsityPattern::copy_from<float> (const FullMatrix<float> &, bool);
 template void SparsityPattern::copy_from<double> (const FullMatrix<double> &, bool);
 
+template void SparsityPattern::copy_from<SparsityPattern> (const SparsityPattern &);
 template void SparsityPattern::copy_from<CompressedSparsityPattern> (const CompressedSparsityPattern &);
 template void SparsityPattern::copy_from<CompressedSetSparsityPattern> (const CompressedSetSparsityPattern &);
 template void SparsityPattern::copy_from<CompressedSimpleSparsityPattern> (const CompressedSimpleSparsityPattern &);
index f88015c32b643b517b66d1653ab0b957f5415012..066aa09a9b8aae7a339762b7f9a8ea3125075e7d 100644 (file)
@@ -505,6 +505,132 @@ namespace SparsityTools
     MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
 
   }
+
+template <class CSP_t>
+void distribute_sparsity_pattern(CSP_t &csp,
+                                   const std::vector<IndexSet> &owned_set_per_cpu,
+                                   const MPI_Comm &mpi_comm,
+                                   const IndexSet &myrange)
+{
+  size_type myid = Utilities::MPI::this_mpi_process(mpi_comm);
+
+  typedef std::map<size_type, std::vector<size_type> > map_vec_t;
+  map_vec_t send_data;
+
+  {
+    unsigned int dest_cpu=0;
+
+    size_type n_local_rel_rows = myrange.n_elements();
+    for (size_type row_idx=0; row_idx<n_local_rel_rows; ++row_idx)
+      {
+        size_type row=myrange.nth_index_in_set(row_idx);
+
+        // calculate destination CPU, note that we start the search
+        // at last destination cpu, because even if the owned ranges
+        // are not contiguous, they hopefully consist of large blocks
+        while (!owned_set_per_cpu[dest_cpu].is_element(row))
+          {
+            ++dest_cpu;
+            if (dest_cpu==owned_set_per_cpu.size()) // wrap around
+                dest_cpu=0;
+          }
+
+        //skip myself
+        if (dest_cpu==myid)
+          continue;
+
+        size_type rlen = csp.row_length(row);
+
+        //skip empty lines
+        if (!rlen)
+          continue;
+
+        //save entries
+        std::vector<size_type> &dst = send_data[dest_cpu];
+
+        dst.push_back(rlen); // number of entries
+        dst.push_back(row); // row index
+        for (size_type c=0; c<rlen; ++c)
+          {
+            //columns
+            size_type column = csp.column_number(row, c);
+            dst.push_back(column);
+          }
+      }
+
+  }
+
+  unsigned int num_receive=0;
+  {
+    std::vector<unsigned int> send_to;
+    send_to.reserve(send_data.size());
+    for (map_vec_t::iterator it=send_data.begin(); it!=send_data.end(); ++it)
+      send_to.push_back(it->first);
+
+    num_receive =
+      Utilities::MPI::
+      compute_point_to_point_communication_pattern(mpi_comm, send_to).size();
+  }
+
+  std::vector<MPI_Request> requests(send_data.size());
+
+
+  // send data
+  {
+    unsigned int idx=0;
+    for (map_vec_t::iterator it=send_data.begin(); it!=send_data.end(); ++it, ++idx)
+      MPI_Isend(&(it->second[0]),
+                it->second.size(),
+                DEAL_II_DOF_INDEX_MPI_TYPE,
+                it->first,
+                124,
+                mpi_comm,
+                &requests[idx]);
+  }
+
+//TODO: In the following, we read individual bytes and then reinterpret them
+//    as size_type objects. this is error prone. use properly typed reads that
+//    match the write above
+  {
+    //receive
+    std::vector<size_type> recv_buf;
+    for (unsigned int index=0; index<num_receive; ++index)
+      {
+        MPI_Status status;
+        int len;
+        MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, mpi_comm, &status);
+        Assert (status.MPI_TAG==124, ExcInternalError());
+
+        MPI_Get_count(&status, MPI_BYTE, &len);
+        Assert( len%sizeof(unsigned int)==0, ExcInternalError());
+
+        recv_buf.resize(len/sizeof(size_type));
+
+        MPI_Recv(&recv_buf[0], len, MPI_BYTE, status.MPI_SOURCE,
+                 status.MPI_TAG, mpi_comm, &status);
+
+        std::vector<size_type>::const_iterator ptr = recv_buf.begin();
+        std::vector<size_type>::const_iterator end = recv_buf.end();
+        while (ptr+1<end)
+          {
+            size_type num=*(ptr++);
+            size_type row=*(ptr++);
+            for (unsigned int c=0; c<num; ++c)
+              {
+                csp.add(row, *ptr);
+                ptr++;
+              }
+          }
+        Assert(ptr==end, ExcInternalError());
+      }
+  }
+
+  // complete all sends, so that we can
+  // safely destroy the buffers.
+  MPI_Waitall(requests.size(), &requests[0], MPI_STATUSES_IGNORE);
+}
+
+
 #endif
 }
 
@@ -520,7 +646,14 @@ namespace SparsityTools
 #ifdef DEAL_II_WITH_MPI
 SPARSITY_FUNCTIONS(CompressedSparsityPattern);
 SPARSITY_FUNCTIONS(CompressedSimpleSparsityPattern);
-SPARSITY_FUNCTIONS(BlockCompressedSimpleSparsityPattern);
+
+template void SparsityTools::distribute_sparsity_pattern
+<BlockCompressedSimpleSparsityPattern>
+(BlockCompressedSimpleSparsityPattern &csp,
+                                   const std::vector<IndexSet> &owned_set_per_cpu,
+                                   const MPI_Comm &mpi_comm,
+                                   const IndexSet &myrange);
+
 #endif
 
 #undef SPARSITY_FUNCTIONS
index b09660c23687e21e1fccd75363a4eab775f42346..7344ec1199ef9fab238dbe8ce28703d1f9e7a1f3 100644 (file)
@@ -59,6 +59,11 @@ namespace TrilinosWrappers
     BlockVector &
     BlockVector::operator = (const BlockVector &v)
     {
+      // we only allow assignment to vectors with the same number of blocks
+      // or to an empty BlockVector
+      Assert (n_blocks() == 0 || n_blocks() == v.n_blocks(),
+                    ExcDimensionMismatch(n_blocks(), v.n_blocks()));
+
       if (this->n_blocks() != v.n_blocks())
         reinit(v.n_blocks());
 
index d8342f04d2e7bd9153996b4e68cea27baacfded5..a014bdd2f346c56ffc6ab0f8d8484ff1c6fa3d33 100644 (file)
@@ -745,6 +745,52 @@ namespace TrilinosWrappers
                                              const AdditionalData &, const double,
                                              const ::dealii::SparsityPattern *);
 
+
+
+
+  /* -------------------------- PreconditionAMG -------------------------- */
+
+  void 
+  PreconditionIdentity::vmult(VectorBase       &dst,
+                              const VectorBase &src) const
+  {
+    dst = src;
+  }
+
+  void
+  PreconditionIdentity::Tvmult(VectorBase       &dst,
+                               const VectorBase &src) const
+  {
+    dst = src;
+  }
+
+  void 
+  PreconditionIdentity::vmult(dealii::Vector<double>       &dst,
+                              const dealii::Vector<double> &src) const
+  {
+    dst = src;
+  }
+
+  void
+  PreconditionIdentity::Tvmult(dealii::Vector<double>       &dst,
+                               const dealii::Vector<double> &src) const
+  {
+    dst = src;
+  }
+
+  void
+  PreconditionIdentity::vmult(parallel::distributed::Vector<double>       &dst,
+                              const parallel::distributed::Vector<double> &src) const
+  {
+    dst = src;
+  }
+
+  void
+  PreconditionIdentity::Tvmult(parallel::distributed::Vector<double>       &dst,
+                               const parallel::distributed::Vector<double> &src) const
+  {
+    dst = src;
+  }
 }
 
 DEAL_II_NAMESPACE_CLOSE
index f04ca39f85986d85602ee4d8ad41d2f9ffd9a8f8..25edefb025e2ce29c8dd747a258e43aead1e2e2c 100644 (file)
@@ -208,11 +208,17 @@ namespace TrilinosWrappers
         Assert (false, ExcNotImplemented());
       }
 
-    // Introduce the
-    // preconditioner, ...
-    ierr = solver.SetPrecOperator (const_cast<Epetra_Operator *>
-                                   (preconditioner.preconditioner.get()));
-    AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+    // Introduce the preconditioner, 
+    // if the identity preconditioner is used,
+    // the precondioner is set to none, ...
+    if (preconditioner.preconditioner.use_count()!=0)
+    {
+      ierr = solver.SetPrecOperator (const_cast<Epetra_Operator *>
+                                     (preconditioner.preconditioner.get()));
+      AssertThrow (ierr == 0, ExcTrilinosError(ierr));
+    }
+    else
+      solver.SetAztecOption(AZ_precond,AZ_none);
 
     // ... set some options, ...
     solver.SetAztecOption (AZ_output, additional_data.output_solver_details ?
index 51d7a560bc8475a52291be7c052c7f0b42f18113..79fd402ccb69d02239a713a1ff56e9febfb2ad1c 100644 (file)
@@ -32,6 +32,7 @@
 #include <deal.II/hp/dof_handler.h>
 #include <deal.II/grid/tria_iterator.h>
 #include <deal.II/fe/fe.h>
+#include <deal.II/fe/fe_dgq.h>
 #include <deal.II/fe/fe_values.h>
 #include <deal.II/hp/fe_values.h>
 #include <deal.II/fe/mapping_q1.h>
@@ -46,30 +47,263 @@ namespace internal
   namespace DataOut
   {
     template <int dim, int spacedim>
-    template <class FE>
+    ParallelDataBase<dim,spacedim>::
+    ParallelDataBase (const unsigned int n_datasets,
+                      const unsigned int n_subdivisions,
+                      const std::vector<unsigned int> &n_postprocessor_outputs,
+                      const Mapping<dim,spacedim> &mapping,
+                      const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
+                      const UpdateFlags update_flags,
+                      const bool        use_face_values)
+      :
+      n_datasets (n_datasets),
+      n_subdivisions (n_subdivisions),
+      postprocessed_values (n_postprocessor_outputs.size()),
+      mapping_collection (mapping),
+      finite_elements (finite_elements),
+      update_flags (update_flags)
+    {
+      unsigned int n_q_points = 0;
+      if (use_face_values == false)
+        {
+          dealii::hp::QCollection<dim>
+            quadrature(QIterated<dim>(QTrapez<1>(), n_subdivisions));
+          n_q_points = quadrature[0].size();
+          x_fe_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_values[i] = x_fe_values[j];
+                    break;
+                  }
+              if (x_fe_values[i].get() == 0)
+                x_fe_values[i].reset(new dealii::hp::FEValues<dim,spacedim>
+                                     (this->mapping_collection,
+                                      *this->finite_elements[i],
+                                      quadrature,
+                                      this->update_flags));
+            }
+        }
+      else
+        {
+          dealii::hp::QCollection<dim-1>
+            quadrature(QIterated<dim-1>(QTrapez<1>(), n_subdivisions));
+          n_q_points = quadrature[0].size();
+          x_fe_face_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_face_values[i] = x_fe_face_values[j];
+                    break;
+                  }
+              if (x_fe_face_values[i].get() == 0)
+                x_fe_face_values[i].reset(new dealii::hp::FEFaceValues<dim,spacedim>
+                                          (this->mapping_collection,
+                                           *this->finite_elements[i],
+                                           quadrature,
+                                           this->update_flags));
+            }
+        }
+
+      patch_values.resize (n_q_points);
+      patch_values_system.resize (n_q_points);
+      patch_gradients.resize (n_q_points);
+      patch_gradients_system.resize (n_q_points);
+      patch_hessians.resize (n_q_points);
+      patch_hessians_system.resize (n_q_points);
+
+      for (unsigned int dataset=0; dataset<n_postprocessor_outputs.size(); ++dataset)
+        if (n_postprocessor_outputs[dataset] != 0)
+          postprocessed_values[dataset]
+          .resize(n_q_points,
+                  dealii::Vector<double>(n_postprocessor_outputs[dataset]));
+    }
+
+
+
+
+
+    // implement copy constructor to create a thread's own version of
+    // x_fe_values
+    template <int dim, int spacedim>
+    ParallelDataBase<dim,spacedim>::
+    ParallelDataBase (const ParallelDataBase<dim,spacedim> &data)
+      :
+      n_datasets (data.n_datasets),
+      n_subdivisions (data.n_subdivisions),
+      patch_values (data.patch_values),
+      patch_values_system (data.patch_values_system),
+      patch_gradients (data.patch_gradients),
+      patch_gradients_system (data.patch_gradients_system),
+      patch_hessians (data.patch_hessians),
+      patch_hessians_system (data.patch_hessians_system),
+      postprocessed_values (data.postprocessed_values),
+      mapping_collection (data.mapping_collection),
+      finite_elements (data.finite_elements),
+      update_flags (data.update_flags)
+    {
+      if (data.x_fe_values.empty() == false)
+        {
+          Assert(data.x_fe_face_values.empty() == true, ExcInternalError());
+          dealii::hp::QCollection<dim>
+            quadrature(QIterated<dim>(QTrapez<1>(), n_subdivisions));
+          x_fe_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_values[i] = x_fe_values[j];
+                    break;
+                  }
+              if (x_fe_values[i].get() == 0)
+                x_fe_values[i].reset(new dealii::hp::FEValues<dim,spacedim>
+                                     (this->mapping_collection,
+                                      *this->finite_elements[i],
+                                      quadrature,
+                                      this->update_flags));
+            }
+        }
+      else
+        {
+          dealii::hp::QCollection<dim-1>
+            quadrature(QIterated<dim-1>(QTrapez<1>(), n_subdivisions));
+          x_fe_face_values.resize(this->finite_elements.size());
+          for (unsigned int i=0; i<this->finite_elements.size(); ++i)
+            {
+              // check if there is a finite element that is equal to the
+              // present one, then we can re-use the FEValues object
+              for (unsigned int j=0; j<i; ++j)
+                if (this->finite_elements[i].get() ==
+                    this->finite_elements[j].get())
+                  {
+                    x_fe_face_values[i] = x_fe_face_values[j];
+                    break;
+                  }
+              if (x_fe_face_values[i].get() == 0)
+                x_fe_face_values[i].reset(new dealii::hp::FEFaceValues<dim,spacedim>
+                                          (this->mapping_collection,
+                                           *this->finite_elements[i],
+                                           quadrature,
+                                           this->update_flags));
+            }
+        }
+    }
+
+
+
+    template <int dim, int spacedim>
+    template <typename DH>
+    void
+    ParallelDataBase<dim,spacedim>::
+    reinit_all_fe_values(std::vector<std_cxx1x::shared_ptr<DataEntryBase<DH> > > &dof_data,
+                         const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell,
+                         const unsigned int face)
+    {
+      for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
+        {
+          bool duplicate = false;
+          for (unsigned int j=0; j<dataset; ++j)
+            if (finite_elements[dataset].get() == finite_elements[j].get())
+              duplicate = true;
+          if (duplicate == false)
+            {
+              typename DH::active_cell_iterator dh_cell(&cell->get_triangulation(),
+                                                        cell->level(),
+                                                        cell->index(),
+                                                        dof_data[dataset]->dof_handler);
+              if (x_fe_values.empty())
+                {
+                  AssertIndexRange(face,
+                                   GeometryInfo<dim>::faces_per_cell);
+                  x_fe_face_values[dataset]->reinit(dh_cell, face);
+                }
+              else
+                x_fe_values[dataset]->reinit (dh_cell);
+            }
+        }
+      if (dof_data.empty())
+        {
+          if (x_fe_values.empty())
+            {
+              AssertIndexRange(face,
+                               GeometryInfo<dim>::faces_per_cell);
+              x_fe_face_values[0]->reinit(cell, face);
+            }
+          else
+            x_fe_values[0]->reinit (cell);
+        }
+    }
+
+
+
+    template <int dim, int spacedim>
+    const FEValuesBase<dim,spacedim> &
+    ParallelDataBase<dim,spacedim>::
+    get_present_fe_values(const unsigned int dataset) const
+    {
+      AssertIndexRange(dataset, finite_elements.size());
+      if (x_fe_values.empty())
+        return x_fe_face_values[dataset]->get_present_fe_values();
+      else
+        return x_fe_values[dataset]->get_present_fe_values();
+    }
+
+
+
+    template <int dim, int spacedim>
+    void
+    ParallelDataBase<dim,spacedim>::
+    resize_system_vectors(const unsigned int n_components)
+    {
+      Assert(patch_values_system.size() > 0, ExcInternalError());
+      AssertDimension(patch_values_system.size(),
+                      patch_gradients_system.size());
+      AssertDimension(patch_values_system.size(),
+                      patch_hessians_system.size());
+      if (patch_values_system[0].size() == n_components)
+        return;
+      for (unsigned int k=0; k<patch_values_system.size(); ++k)
+        {
+          patch_values_system[k].reinit(n_components);
+          patch_gradients_system[k].resize(n_components);
+          patch_hessians_system[k].resize(n_components);
+        }
+    }
+
+
+
+
+    template <int dim, int spacedim>
     ParallelData<dim,spacedim>::
-    ParallelData (const Quadrature<dim> &quadrature,
-                  const unsigned int n_components,
-                  const unsigned int n_datasets,
+    ParallelData (const unsigned int n_datasets,
                   const unsigned int n_subdivisions,
                   const std::vector<unsigned int> &n_postprocessor_outputs,
                   const Mapping<dim,spacedim> &mapping,
-                  const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map,
-                  const FE &finite_elements,
-                  const UpdateFlags update_flags)
+                  const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
+                  const UpdateFlags update_flags,
+                  const std::vector<std::vector<unsigned int> > &cell_to_patch_index_map)
       :
-      ParallelDataBase<dim,spacedim> (n_components,
-                                      n_datasets,
+      ParallelDataBase<dim,spacedim> (n_datasets,
                                       n_subdivisions,
-                                      quadrature.size(),
                                       n_postprocessor_outputs,
-                                      finite_elements),
-      q_collection (quadrature),
-      mapping_collection (mapping),
-      x_fe_values (this->mapping_collection,
-                   this->fe_collection,
-                   q_collection,
-                   update_flags),
+                                      mapping,
+                                      finite_elements,
+                                      update_flags,
+                                      false),
       cell_to_patch_index_map (&cell_to_patch_index_map)
     {}
 
@@ -77,10 +311,8 @@ namespace internal
 
 
     /**
-     * In a WorkStream context, use
-     * this function to append the
-     * patch computed by the parallel
-     * stage to the array of patches.
+     * In a WorkStream context, use this function to append the patch computed
+     * by the parallel stage to the array of patches.
      */
     template <int dim, int spacedim>
     void
@@ -99,9 +331,11 @@ namespace internal
   namespace DataOut
   {
     template <class DH>
-    DataEntryBase<DH>::DataEntryBase (const std::vector<std::string> &names_in,
+    DataEntryBase<DH>::DataEntryBase (const DH                       *dofs,
+                                      const std::vector<std::string> &names_in,
                                       const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
       :
+      dof_handler (dofs, typeid(dealii::DataOut_DoFData<DH,DH::dimension,DH::space_dimension>).name()),
       names(names_in),
       data_component_interpretation (data_component_interpretation),
       postprocessor(0, typeid(*this).name()),
@@ -111,9 +345,7 @@ namespace internal
               ExcDimensionMismatch(data_component_interpretation.size(),
                                    names.size()));
 
-      // check that the names use only allowed
-      // characters
-      // check names for invalid characters
+      // check that the names use only allowed characters
       for (unsigned int i=0; i<names.size(); ++i)
         Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
                                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -128,8 +360,10 @@ namespace internal
 
 
     template <class DH>
-    DataEntryBase<DH>::DataEntryBase (const DataPostprocessor<DH::space_dimension> *data_postprocessor)
+    DataEntryBase<DH>::DataEntryBase (const DH *dofs,
+                                      const DataPostprocessor<DH::space_dimension> *data_postprocessor)
       :
+      dof_handler (dofs, typeid(dealii::DataOut_DoFData<DH,DH::dimension,DH::space_dimension>).name()),
       names(data_postprocessor->get_names()),
       data_component_interpretation (data_postprocessor->get_data_component_interpretation()),
       postprocessor(data_postprocessor, typeid(*this).name()),
@@ -141,8 +375,7 @@ namespace internal
               ExcDimensionMismatch (data_postprocessor->get_names().size(),
                                     data_postprocessor->get_data_component_interpretation().size()));
 
-      // check that the names use only allowed
-      // characters
+      // check that the names use only allowed characters
       for (unsigned int i=0; i<names.size(); ++i)
         Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
                                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -163,10 +396,8 @@ namespace internal
 
 
     /**
-     * Class that stores a pointer to a
-     * vector of type equal to the template
-     * argument, and provides the functions
-     * to extract data from it.
+     * Class that stores a pointer to a vector of type equal to the template
+     * argument, and provides the functions to extract data from it.
      *
      * @author Wolfgang Bangerth, 2004
      */
@@ -175,31 +406,26 @@ namespace internal
     {
     public:
       /**
-       * Constructor. Give a list of names
-       * for the individual components of
-       * the vector and their
-       * interpretation as scalar or vector
-       * data. This constructor assumes
-       * that no postprocessor is going to
-       * be used.
+       * Constructor. Give a list of names for the individual components of
+       * the vector and their interpretation as scalar or vector data. This
+       * constructor assumes that no postprocessor is going to be used.
        */
-      DataEntry (const VectorType               *data,
+      DataEntry (const DH                       *dofs,
+                 const VectorType               *data,
                  const std::vector<std::string> &names,
                  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation);
 
       /**
-       * Constructor when a data
-       * postprocessor is going to be
-       * used. In that case, the names and
-       * vector declarations are going to
-       * be acquired from the postprocessor.
+       * Constructor when a data postprocessor is going to be used. In that
+       * case, the names and vector declarations are going to be acquired from
+       * the postprocessor.
        */
-      DataEntry (const VectorType                       *data,
+      DataEntry (const DH                                     *dofs,
+                 const VectorType                             *data,
                  const DataPostprocessor<DH::space_dimension> *data_postprocessor);
 
       /**
-       * Assuming that the stored vector is
-       * a cell vector, extract the given
+       * Assuming that the stored vector is a cell vector, extract the given
        * element from it.
        */
       virtual
@@ -207,10 +433,8 @@ namespace internal
       get_cell_data_value (const unsigned int cell_number) const;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the values on the present
-       * cell from the vector we actually
-       * store.
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store.
        */
       virtual
       void
@@ -218,12 +442,9 @@ namespace internal
                            std::vector<double>             &patch_values) const;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the values on the present
-       * cell from the vector we actually
-       * store. This function does the same
-       * as the one above but for
-       * vector-valued finite elements.
+       * Given a FEValuesBase object, extract the values on the present cell
+       * from the vector we actually store. This function does the same as the
+       * one above but for vector-valued finite elements.
        */
       virtual
       void
@@ -231,10 +452,8 @@ namespace internal
                            std::vector<dealii::Vector<double> >    &patch_values_system) const;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the gradients on the present
-       * cell from the vector we actually
-       * store.
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store.
        */
       virtual
       void
@@ -242,12 +461,9 @@ namespace internal
                               std::vector<Tensor<1,DH::space_dimension> >       &patch_gradients) const;
 
       /**
-       * Given a FEValuesBase object,
-       * extract the gradients on the present
-       * cell from the vector we actually
-       * store. This function does the same
-       * as the one above but for
-       * vector-valued finite elements.
+       * Given a FEValuesBase object, extract the gradients on the present
+       * cell from the vector we actually store. This function does the same
+       * as the one above but for vector-valued finite elements.
        */
       virtual
       void
@@ -255,10 +471,8 @@ namespace internal
                               std::vector<std::vector<Tensor<1,DH::space_dimension> > > &patch_gradients_system) const;
 
       /**
-       * Given a FEValuesBase object, extract
-       * the second derivatives on the
-       * present cell from the vector we
-       * actually store.
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store.
        */
       virtual
       void
@@ -266,12 +480,9 @@ namespace internal
                              std::vector<Tensor<2,DH::space_dimension> >       &patch_hessians) const;
 
       /**
-       * Given a FEValuesBase object, extract
-       * the second derivatives on the
-       * present cell from the vector we
-       * actually store. This function does
-       * the same as the one above but for
-       * vector-valued finite elements.
+       * Given a FEValuesBase object, extract the second derivatives on the
+       * present cell from the vector we actually store. This function does
+       * the same as the one above but for vector-valued finite elements.
        */
       virtual
       void
@@ -279,25 +490,20 @@ namespace internal
                              std::vector<std::vector< Tensor<2,DH::space_dimension> > > &patch_hessians_system) const;
 
       /**
-       * Clear all references to the
-       * vectors.
+       * Clear all references to the vectors.
        */
       virtual void clear ();
 
       /**
-       * Determine an estimate for
-       * the memory consumption (in
-       * bytes) of this object.
+       * Determine an estimate for the memory consumption (in bytes) of this
+       * object.
        */
       virtual std::size_t memory_consumption () const;
 
     private:
       /**
-       * Pointer to the data
-       * vector. Note that
-       * ownership of the vector
-       * pointed to remains with
-       * the caller of this class.
+       * Pointer to the data vector. Note that ownership of the vector pointed
+       * to remains with the caller of this class.
        */
       const VectorType *vector;
     };
@@ -306,11 +512,12 @@ namespace internal
 
     template <class DH, class VectorType>
     DataEntry<DH,VectorType>::
-    DataEntry (const VectorType                       *data,
+    DataEntry (const DH                               *dofs,
+               const VectorType                       *data,
                const std::vector<std::string>         &names,
                const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
       :
-      DataEntryBase<DH> (names, data_component_interpretation),
+      DataEntryBase<DH> (dofs, names, data_component_interpretation),
       vector (data)
     {}
 
@@ -318,10 +525,11 @@ namespace internal
 
     template <class DH, class VectorType>
     DataEntry<DH,VectorType>::
-    DataEntry (const VectorType                       *data,
+    DataEntry (const DH                                     *dofs,
+               const VectorType                             *data,
                const DataPostprocessor<DH::space_dimension> *data_postprocessor)
       :
-      DataEntryBase<DH> (data_postprocessor),
+      DataEntryBase<DH> (dofs, data_postprocessor),
       vector (data)
     {}
 
@@ -438,6 +646,7 @@ namespace internal
     DataEntry<DH,VectorType>::clear ()
     {
       vector = 0;
+      this->dof_handler = 0;
     }
   }
 }
@@ -448,6 +657,7 @@ template <class DH,
          int patch_dim, int patch_space_dim>
 DataOut_DoFData<DH,patch_dim,patch_space_dim>::DataOut_DoFData ()
   :
+  triangulation(0,typeid(*this).name()),
   dofs(0,typeid(*this).name())
 {}
 
@@ -469,7 +679,21 @@ attach_dof_handler (const DH &d)
   Assert (dof_data.size() == 0, ExcOldDataStillPresent());
   Assert (cell_data.size() == 0, ExcOldDataStillPresent());
 
-  dofs = &d;
+  triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&d.get_tria(), typeid(*this).name());
+  dofs = SmartPointer<const DH>(&d, typeid(*this).name());
+}
+
+
+
+template <class DH, int patch_dim, int patch_space_dim>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+attach_triangulation (const Triangulation<DH::dimension,DH::space_dimension> &tria)
+{
+  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
+  Assert (cell_data.size() == 0, ExcOldDataStillPresent());
+
+  triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&tria, typeid(*this).name());
 }
 
 
@@ -485,21 +709,19 @@ add_data_vector (const VECTOR                             &vec,
                  const DataVectorType                      type,
                  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
 {
-  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
-  const unsigned int n_components = dofs->get_fe().n_components ();
+  Assert (triangulation != 0, ExcNoTriangulationSelected ());
+  const unsigned int n_components =
+    dofs != 0 ? dofs->get_fe().n_components () : 1;
 
   std::vector<std::string> names;
-  // if only one component or vector
-  // is cell vector: we only need one
-  // name
+  // if only one component or vector is cell vector: we only need one name
   if ((n_components == 1) ||
-      (vec.size() == dofs->get_tria().n_active_cells()))
+      (vec.size() == triangulation->n_active_cells()))
     {
       names.resize (1, name);
     }
   else
-    // otherwise append _i to the
-    // given name
+    // otherwise append _i to the given name
     {
       names.resize (n_components);
       for (unsigned int i=0; i<n_components; ++i)
@@ -525,7 +747,7 @@ add_data_vector (const VECTOR                             &vec,
                  const DataVectorType                      type,
                  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
 {
-  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
+  Assert (triangulation != 0, ExcNoTriangulationSelected ());
 
   const std::vector<DataComponentInterpretation::DataComponentInterpretation> &
   data_component_interpretation
@@ -541,7 +763,7 @@ add_data_vector (const VECTOR                             &vec,
   DataVectorType actual_type = type;
   if (type == type_automatic)
     {
-      if (vec.size() == dofs->get_tria().n_active_cells())
+      if (vec.size() == triangulation->n_active_cells())
         actual_type = type_cell_data;
       else
         actual_type = type_dof_data;
@@ -550,31 +772,30 @@ add_data_vector (const VECTOR                             &vec,
   switch (actual_type)
     {
     case type_cell_data:
-      Assert (vec.size() == dofs->get_tria().n_active_cells(),
-              ExcInvalidVectorSize (vec.size(),
-                                    dofs->n_dofs(),
-                                    dofs->get_tria().n_active_cells()));
+      Assert (vec.size() == triangulation->n_active_cells(),
+              ExcDimensionMismatch (vec.size(),
+                                    triangulation->n_active_cells()));
       Assert (names.size() == 1,
               ExcInvalidNumberOfNames (names.size(), 1));
       break;
 
     case type_dof_data:
+      Assert (dofs != 0, ExcNoDoFHandlerSelected ());
       Assert (vec.size() == dofs->n_dofs(),
               ExcInvalidVectorSize (vec.size(),
                                     dofs->n_dofs(),
-                                    dofs->get_tria().n_active_cells()));
+                                    triangulation->n_active_cells()));
       Assert (names.size() == dofs->get_fe().n_components(),
               ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
       break;
 
     case type_automatic:
-      // this case should have
-      // been handled above...
+      // this case should have been handled above...
       Assert (false, ExcInternalError());
     }
 
   internal::DataOut::DataEntryBase<DH> *new_entry
-    = new internal::DataOut::DataEntry<DH,VECTOR>(&vec, names,
+    = new internal::DataOut::DataEntry<DH,VECTOR>(dofs, &vec, names,
                                                   data_component_interpretation);
   if (actual_type == type_dof_data)
     dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
@@ -592,13 +813,10 @@ DataOut_DoFData<DH,patch_dim,patch_space_dim>::
 add_data_vector (const VECTOR                           &vec,
                  const DataPostprocessor<DH::space_dimension> &data_postprocessor)
 {
-  // this is a specialized version of the
-  // other function where we have a
-  // postprocessor. if we do, we know that we
-  // have type_dof_data, which makes things a
-  // bit simpler, we also don't need to deal
-  // with some of the other stuff and use a
-  // different constructor of DataEntry
+  // this is a specialized version of the other function where we have a
+  // postprocessor. if we do, we know that we have type_dof_data, which makes
+  // things a bit simpler, we also don't need to deal with some of the other
+  // stuff and use a different constructor of DataEntry
 
   Assert (dofs != 0, ExcNoDoFHandlerSelected ());
 
@@ -608,7 +826,103 @@ add_data_vector (const VECTOR                           &vec,
                                 dofs->get_tria().n_active_cells()));
 
   internal::DataOut::DataEntryBase<DH> *new_entry
-    = new internal::DataOut::DataEntry<DH,VECTOR>(&vec, &data_postprocessor);
+    = new internal::DataOut::DataEntry<DH,VECTOR>(dofs, &vec, &data_postprocessor);
+  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const DH                               &dof_handler,
+                 const VECTOR                           &vec,
+                 const DataPostprocessor<DH::space_dimension> &data_postprocessor)
+{
+  // this is a specialized version of the other function where we have a
+  // postprocessor. if we do, we know that we have type_dof_data, which makes
+  // things a bit simpler, we also don't need to deal with some of the other
+  // stuff and use a different constructor of DataEntry
+
+  AssertDimension (vec.size(), dof_handler.n_dofs());
+
+  internal::DataOut::DataEntryBase<DH> *new_entry
+    = new internal::DataOut::DataEntry<DH,VECTOR>(&dof_handler, &vec, &data_postprocessor);
+  dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const DH                       &dof_handler,
+                 const VECTOR                   &data,
+                 const std::string              &name,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation)
+{
+  const unsigned int n_components = dof_handler.get_fe().n_components ();
+
+  std::vector<std::string> names;
+  // if only one component: we only need one name
+  if (n_components == 1)
+    names.resize (1, name);
+  else
+    // otherwise append _i to the given name
+    {
+      names.resize (n_components);
+      for (unsigned int i=0; i<n_components; ++i)
+        {
+          std::ostringstream namebuf;
+          namebuf << '_' << i;
+          names[i] = name + namebuf.str();
+        }
+    }
+
+  add_data_vector (dof_handler, data, names, data_component_interpretation);
+}
+
+
+
+template <class DH,
+         int patch_dim, int patch_space_dim>
+template <class VECTOR>
+void
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::
+add_data_vector (const DH                       &dof_handler,
+                 const VECTOR                   &data,
+                 const std::vector<std::string> &names,
+                 const std::vector<DataComponentInterpretation::DataComponentInterpretation> &data_component_interpretation_)
+{
+  // this is an extended version of the other functions where we pass a vector
+  // together with its DoFHandler. if we do, we know that we have
+  // type_dof_data, which makes things a bit simpler
+  if (triangulation == 0)
+    triangulation = SmartPointer<const Triangulation<DH::dimension,DH::space_dimension> >(&dof_handler.get_tria(), typeid(*this).name());
+
+  Assert (&dof_handler.get_tria() == triangulation,
+          ExcMessage("The triangulation attached to the DoFHandler does not "
+                     "match with the one set previously"));
+
+  Assert (data.size() == dof_handler.n_dofs(),
+          ExcDimensionMismatch (data.size(), dof_handler.n_dofs()));
+
+  const std::vector<DataComponentInterpretation::DataComponentInterpretation> &
+  data_component_interpretation
+    = (data_component_interpretation_.size() != 0
+       ?
+       data_component_interpretation_
+       :
+       std::vector<DataComponentInterpretation::DataComponentInterpretation>
+       (names.size(), DataComponentInterpretation::component_is_scalar));
+
+  internal::DataOut::DataEntryBase<DH> *new_entry
+    = new internal::DataOut::DataEntry<DH,VECTOR>(&dof_handler, &data, names,
+                                                  data_component_interpretation);
   dof_data.push_back (std_cxx1x::shared_ptr<internal::DataOut::DataEntryBase<DH> >(new_entry));
 }
 
@@ -796,6 +1110,47 @@ DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_patches () const
 
 
 
+template <class DH,
+         int patch_dim, int patch_space_dim>
+std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<DH::dimension,DH::space_dimension> > >
+DataOut_DoFData<DH,patch_dim,patch_space_dim>::get_finite_elements() const
+{
+  const unsigned int dhdim = DH::dimension;
+  const unsigned int dhspacedim = DH::space_dimension;
+  std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dhdim,dhspacedim> > >
+    finite_elements(this->dof_data.size());
+  for (unsigned int i=0; i<this->dof_data.size(); ++i)
+    {
+      Assert (dof_data[i]->dof_handler != 0, ExcNoDoFHandlerSelected ());
+
+      // avoid creating too many finite elements and doing a lot of work on
+      // initializing FEValues downstream: if two DoFHandlers are the same
+      // (checked by pointer comparison), we can re-use the shared_ptr object
+      // for the second one. We cannot check for finite element equalities
+      // because we need different FEValues objects for different dof
+      // handlers.
+      bool duplicate = false;
+      for (unsigned int j=0; j<i; ++j)
+        if (dof_data[i]->dof_handler == dof_data[j]->dof_handler)
+          {
+            finite_elements[i] = finite_elements[j];
+            duplicate = true;
+          }
+      if (duplicate == false)
+        finite_elements[i].reset(new dealii::hp::FECollection<dhdim,dhspacedim>
+                                 (this->dof_data[i]->dof_handler->get_fe()));
+    }
+  if (this->dof_data.empty())
+    {
+      finite_elements.resize(1);
+      finite_elements[0].reset(new dealii::hp::FECollection<dhdim,dhspacedim>
+                               (FE_DGQ<dhdim,dhspacedim>(0)));
+    }
+  return finite_elements;
+}
+
+
+
 template <class DH,
          int patch_dim, int patch_space_dim>
 std::size_t
@@ -819,13 +1174,10 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
                  DataOutBase::Patch<DH::dimension, DH::space_dimension> &patch,
                  const CurvedCellRegion curved_cell_region)
 {
-  // use ucd_to_deal map as patch vertices
-  // are in the old, unnatural ordering. if
-  // the mapping does not preserve locations
-  // (e.g. MappingQEulerian), we need to
-  // compute the offset of the vertex for the
-  // graphical output. Otherwise, we can just
-  // use the vertex info.
+  // use ucd_to_deal map as patch vertices are in the old, unnatural
+  // ordering. if the mapping does not preserve locations
+  // (e.g. MappingQEulerian), we need to compute the offset of the vertex for
+  // the graphical output. Otherwise, we can just use the vertex info.
   for (unsigned int vertex=0; vertex<GeometryInfo<DH::dimension>::vertices_per_cell; ++vertex)
     if (data.mapping_collection[0].preserves_vertex_locations())
       patch.vertices[vertex] = cell_and_index->first->vertex(vertex);
@@ -836,25 +1188,21 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
 
   if (data.n_datasets > 0)
     {
-      data.x_fe_values.reinit (cell_and_index->first);
-      const FEValues<DH::dimension,DH::space_dimension> &fe_patch_values
-        = data.x_fe_values.get_present_fe_values ();
+      // create DH::active_cell_iterator and initialize FEValues
+      data.reinit_all_fe_values(this->dof_data, cell_and_index->first);
+
+      const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values
+        = data.get_present_fe_values (0);
 
       const unsigned int n_q_points = fe_patch_values.n_quadrature_points;
 
-      // depending on the requested output
-      // of curved cells, if necessary
-      // append the quadrature points to
-      // the last rows of the patch.data
-      // member. This is the case if we
-      // want to produce curved cells at
-      // the boundary and this cell
-      // actually is at the boundary, or
-      // else if we want to produce curved
-      // cells everywhere
+      // depending on the requested output of curved cells, if necessary
+      // append the quadrature points to the last rows of the patch.data
+      // member. This is the case if we want to produce curved cells at the
+      // boundary and this cell actually is at the boundary, or else if we
+      // want to produce curved cells everywhere
       //
-      // note: a cell is *always* at
-      // the boundary if dim<spacedim
+      // note: a cell is *always* at the boundary if dim<spacedim
       if (curved_cell_region==curved_inner_cells
           ||
           (curved_cell_region==curved_boundary
@@ -865,13 +1213,10 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
         {
           Assert(patch.space_dim==DH::space_dimension, ExcInternalError());
           const std::vector<Point<DH::space_dimension> > &q_points=fe_patch_values.get_quadrature_points();
-          // resize the patch.data member
-          // in order to have enough memory
-          // for the quadrature points as
-          // well
+          // resize the patch.data member in order to have enough memory for
+          // the quadrature points as well
           patch.data.reinit (data.n_datasets+DH::space_dimension, n_q_points);
-          // set the flag indicating that
-          // for this cell the points are
+          // set the flag indicating that for this cell the points are
           // explicitly given
           patch.points_are_available=true;
           // copy points to patch.data
@@ -892,19 +1237,22 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
       // first fill dof_data
       for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
         {
+          const FEValuesBase<DH::dimension,DH::space_dimension> &fe_patch_values
+            = data.get_present_fe_values (dataset);
+          const unsigned int n_components =
+            fe_patch_values.get_fe().n_components();
+
           const DataPostprocessor<DH::space_dimension> *postprocessor=this->dof_data[dataset]->postprocessor;
 
           if (postprocessor != 0)
             {
-              // we have to postprocess the
-              // data, so determine, which
-              // fields have to be updated
+              // we have to postprocess the data, so determine, which fields
+              // have to be updated
               const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
-              if (data.n_components == 1)
+              if (n_components == 1)
                 {
-                  // at each point there is
-                  // only one component of
-                  // value, gradient etc.
+                  // at each point there is only one component of value,
+                  // gradient etc.
                   if (update_flags & update_values)
                     this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                   data.patch_values);
@@ -930,9 +1278,9 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
                 }
               else
                 {
-                  // at each point there is
-                  // a vector valued
-                  // function and its
+                  data.resize_system_vectors (n_components);
+
+                  // at each point there is a vector valued function and its
                   // derivative...
                   if (update_flags & update_values)
                     this->dof_data[dataset]->get_function_values (fe_patch_values,
@@ -966,13 +1314,10 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
                     = data.postprocessed_values[dataset][q](component);
             }
           else
-            // now we use the given data
-            // vector without
-            // modifications. again, we
-            // treat single component
-            // functions separately for
-            // efficiency reasons.
-            if (data.n_components == 1)
+            // now we use the given data vector without modifications. again,
+            // we treat single component functions separately for efficiency
+            // reasons.
+            if (n_components == 1)
               {
                 this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                               data.patch_values);
@@ -981,25 +1326,22 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
               }
             else
               {
+                data.resize_system_vectors(n_components);
                 this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                               data.patch_values_system);
-                for (unsigned int component=0; component<data.n_components;
+                for (unsigned int component=0; component<n_components;
                      ++component)
                   for (unsigned int q=0; q<n_q_points; ++q)
                     patch.data(offset+component,q) =
                       data.patch_values_system[q](component);
               }
-          // increment the counter for the
-          // actual data record
+          // increment the counter for the actual data record
           offset+=this->dof_data[dataset]->n_output_variables;
         }
 
-      // then do the cell data. only
-      // compute the number of a cell if
-      // needed; also make sure that we
-      // only access cell data if the
-      // first_cell/next_cell functions
-      // only return active cells
+      // then do the cell data. only compute the number of a cell if needed;
+      // also make sure that we only access cell data if the
+      // first_cell/next_cell functions only return active cells
       if (this->cell_data.size() != 0)
         {
           Assert (!cell_and_index->first->has_children(), ExcNotImplemented());
@@ -1017,32 +1359,15 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
 
   for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
     {
-      // let's look up whether
-      // the neighbor behind that
-      // face is noted in the
-      // table of cells which we
-      // treat. this can only
-      // happen if the neighbor
-      // exists, and is on the
-      // same level as this cell,
-      // but it may also happen
-      // that the neighbor is not
-      // a member of the range of
-      // cells over which we
-      // loop, in which case the
-      // respective entry in the
-      // cell_to_patch_index_map
-      // will have the value
-      // no_neighbor. (note that
-      // since we allocated only
-      // as much space in this
-      // array as the maximum
-      // index of the cells we
-      // loop over, not every
-      // neighbor may have its
-      // space in it, so we have
-      // to assume that it is
-      // extended by values
+      // let's look up whether the neighbor behind that face is noted in the
+      // table of cells which we treat. this can only happen if the neighbor
+      // exists, and is on the same level as this cell, but it may also happen
+      // that the neighbor is not a member of the range of cells over which we
+      // loop, in which case the respective entry in the
+      // cell_to_patch_index_map will have the value no_neighbor. (note that
+      // since we allocated only as much space in this array as the maximum
+      // index of the cells we loop over, not every neighbor may have its
+      // space in it, so we have to assume that it is extended by values
       // no_neighbor)
       if (cell_and_index->first->at_boundary(f)
           ||
@@ -1067,10 +1392,8 @@ build_one_patch (const std::pair<cell_iterator, unsigned int> *cell_and_index,
           continue;
         }
 
-      // now, there is a
-      // neighbor, so get its
-      // patch number and set it
-      // for the neighbor index
+      // now, there is a neighbor, so get its patch number and set it for the
+      // neighbor index
       patch.neighbors[f]
         = (*data.cell_to_patch_index_map)[neighbor->level()][neighbor->index()];
     }
@@ -1086,17 +1409,18 @@ void DataOut<dim,DH>::build_patches (const unsigned int n_subdivisions)
 }
 
 
+
 template <int dim, class DH>
 void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimension> &mapping,
                                      const unsigned int nnnn_subdivisions,
                                      const CurvedCellRegion curved_region)
 {
-  // Check consistency of redundant
-  // template parameter
+  // Check consistency of redundant template parameter
   Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
 
   typedef DataOut_DoFData<DH, DH::dimension, DH::space_dimension> BaseClass;
-  Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
+  Assert (this->triangulation != 0,
+          typename BaseClass::ExcNoTriangulationSelected());
 
   const unsigned int n_subdivisions = (nnnn_subdivisions != 0)
                                       ? nnnn_subdivisions
@@ -1104,19 +1428,15 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimen
   Assert (n_subdivisions >= 1,
           ExcInvalidNumberOfSubdivisions(n_subdivisions));
 
-  // first count the cells we want to
-  // create patches of. also fill the
-  // object that maps the cell
-  // indices to the patch numbers, as
-  // this will be needed for
-  // generation of neighborship
-  // information
+  // first count the cells we want to create patches of. also fill the object
+  // that maps the cell indices to the patch numbers, as this will be needed
+  // for generation of neighborship information
   std::vector<std::vector<unsigned int> > cell_to_patch_index_map;
-  cell_to_patch_index_map.resize (this->dofs->get_tria().n_levels());
-  for (unsigned int l=0; l<this->dofs->get_tria().n_levels(); ++l)
+  cell_to_patch_index_map.resize (this->triangulation->n_levels());
+  for (unsigned int l=0; l<this->triangulation->n_levels(); ++l)
     {
       unsigned int max_index = 0;
-      for (cell_iterator cell=first_locally_owned_cell(); cell != this->dofs->end();
+      for (cell_iterator cell=first_locally_owned_cell(); cell != this->triangulation->end();
            cell = next_locally_owned_cell(cell))
         if (static_cast<unsigned int>(cell->level()) == l)
           max_index = std::max (max_index,
@@ -1128,24 +1448,19 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimen
 
   std::vector<std::pair<cell_iterator, unsigned int> > all_cells;
   {
-    // set the index of the first
-    // cell. if
-    // first_locally_owned_cell /
-    // next_locally_owned_cell
-    // returns non-active cells, then
-    // the index is not usable
-    // anyway, but otherwise we
-    // should keep track where we are
+    // set the index of the first cell. if first_locally_owned_cell /
+    // next_locally_owned_cell returns non-active cells, then the index is not
+    // usable anyway, but otherwise we should keep track where we are
     unsigned int index;
-    if ((first_locally_owned_cell() == this->dofs->end())
+    cell_iterator cell = first_locally_owned_cell();
+    if ((cell == this->triangulation->end())
         ||
-        (first_locally_owned_cell()->has_children()))
+        (cell->has_children()))
       index = 0;
     else
-      index = std::distance (this->dofs->begin_active(),
-                             active_cell_iterator(first_locally_owned_cell()));
-    for (cell_iterator cell=first_locally_owned_cell(); cell != this->dofs->end();
-         cell = next_locally_owned_cell(cell))
+      index = std::distance (this->triangulation->begin_active(),
+                             active_cell_iterator(cell));
+    for ( ; cell != this->triangulation->end(); )
       {
         Assert (static_cast<unsigned int>(cell->level()) <
                 cell_to_patch_index_map.size(),
@@ -1158,22 +1473,18 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimen
 
         all_cells.push_back (std::make_pair(cell, index));
 
-        // if both this and the next
-        // cell are active, then
-        // increment the index that
-        // keeps track on which
-        // active cell we are sitting
-        // correctly. if one of the
-        // cells is not active, then
-        // this index doesn't mean
-        // anything anyway, so just
-        // ignore it. same if we are
-        // at the end of the range
+        // if both this and the next cell are active, then increment the index
+        // that keeps track on which active cell we are sitting correctly. if
+        // one of the cells is not active, then this index doesn't mean
+        // anything anyway, so just ignore it. same if we are at the end of
+        // the range
+        cell_iterator next = next_locally_owned_cell(cell);
         if (!cell->has_children() &&
-            next_locally_owned_cell(cell) != this->dofs->end() &&
-            !next_locally_owned_cell(cell)->has_children())
+            next != this->triangulation->end() &&
+            !next->has_children())
           index += std::distance (active_cell_iterator(cell),
-                                  active_cell_iterator(next_locally_owned_cell(cell)));
+                                  active_cell_iterator(next));
+        cell = next;
       }
   }
 
@@ -1181,13 +1492,7 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimen
   this->patches.reserve (all_cells.size());
   Assert (this->patches.size() == 0, ExcInternalError());
 
-  // now create a default patch and a
-  // default object for the
-  // WorkStream object to work with
-  const QTrapez<1>     q_trapez;
-  const QIterated<DH::dimension> patch_points (q_trapez, n_subdivisions);
-
-  const unsigned int n_components   = this->dofs->get_fe().n_components();
+  // now create a default object for the WorkStream object to work with
   unsigned int n_datasets=this->cell_data.size();
   for (unsigned int i=0; i<this->dof_data.size(); ++i)
     n_datasets += this->dof_data[i]->n_output_variables;
@@ -1209,26 +1514,24 @@ void DataOut<dim,DH>::build_patches (const Mapping<DH::dimension,DH::space_dimen
   for (unsigned int i=0; i<this->dof_data.size(); ++i)
     if (this->dof_data[i]->postprocessor)
       update_flags |= this->dof_data[i]->postprocessor->get_needed_update_flags();
-  // perhaps update_normal_vectors is present,
-  // which would only be useful on faces, but
-  // we may not use it here.
+  // perhaps update_normal_vectors is present, which would only be useful on
+  // faces, but we may not use it here.
   Assert (!(update_flags & update_normal_vectors),
           ExcMessage("The update of normal vectors may not be requested for evaluation of "
                      "data on cells via DataPostprocessor."));
 
   internal::DataOut::ParallelData<DH::dimension, DH::space_dimension>
-  thread_data (patch_points,
-               n_components, n_datasets, n_subdivisions,
+  thread_data (n_datasets, n_subdivisions,
                n_postprocessor_outputs,
                mapping,
-               cell_to_patch_index_map,
-               this->dofs->get_fe(),
-               update_flags);
+               this->get_finite_elements(),
+               update_flags,
+               cell_to_patch_index_map);
 
   ::dealii::DataOutBase::Patch<DH::dimension, DH::space_dimension> sample_patch;
   sample_patch.n_subdivisions = n_subdivisions;
-  sample_patch.data.reinit (n_datasets, patch_points.size());
-
+  sample_patch.data.reinit (n_datasets,
+                            Utilities::fixed_power<DH::dimension>(n_subdivisions+1));
 
 
   // now build the patches in parallel
@@ -1250,7 +1553,7 @@ template <int dim, class DH>
 typename DataOut<dim,DH>::cell_iterator
 DataOut<dim,DH>::first_cell ()
 {
-  return this->dofs->begin_active ();
+  return this->triangulation->begin_active ();
 }
 
 
@@ -1259,10 +1562,10 @@ template <int dim, class DH>
 typename DataOut<dim,DH>::cell_iterator
 DataOut<dim,DH>::next_cell (const typename DataOut<dim,DH>::cell_iterator &cell)
 {
-  // convert the iterator to an
-  // active_iterator and advance
-  // this to the next active cell
-  typename DH::active_cell_iterator active_cell = cell;
+  // convert the iterator to an active_iterator and advance this to the next
+  // active cell
+  typename Triangulation<DH::dimension,DH::space_dimension>::
+    active_cell_iterator active_cell = cell;
   ++active_cell;
   return active_cell;
 }
@@ -1274,12 +1577,11 @@ typename DataOut<dim,DH>::cell_iterator
 DataOut<dim,DH>::first_locally_owned_cell ()
 {
   typename DataOut<dim,DH>::cell_iterator
-  cell = this->dofs->begin_active ();
+  cell = this->triangulation->begin_active ();
 
-  // skip cells if the current one
-  // has no children (is active) and
-  // is a ghost or artificial cell
-  while ((cell != this->dofs->end()) &&
+  // skip cells if the current one has no children (is active) and is a ghost
+  // or artificial cell
+  while ((cell != this->triangulation->end()) &&
          (cell->has_children() == false) &&
          !cell->is_locally_owned())
     cell = next_cell(cell);
@@ -1295,7 +1597,7 @@ DataOut<dim,DH>::next_locally_owned_cell (const typename DataOut<dim,DH>::cell_i
 {
   typename DataOut<dim,DH>::cell_iterator
   cell = next_cell(old_cell);
-  while ((cell != this->dofs->end()) &&
+  while ((cell != this->triangulation->end()) &&
          (cell->has_children() == false) &&
          !cell->is_locally_owned())
     cell = next_cell(cell);
index 55fc70143326514c7b0854b4f2c487c46987a749..aa157920a15b9e3e973b18a45785b8191d40d485 100644 (file)
@@ -38,6 +38,28 @@ for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENS
   add_data_vector<VEC> (const VEC                 &,
                       const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
 
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
 // stuff needed for face data
 
   template void
@@ -59,6 +81,28 @@ for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENS
   add_data_vector<VEC> (const VEC                 &,
                       const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
 
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension-1,deal_II_dimension>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
 // things for DataOutRotation
 
   template void
@@ -80,6 +124,28 @@ for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENS
   add_data_vector<VEC> (const VEC                 &,
                       const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
 
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension>,deal_II_dimension+1,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension>::space_dimension> &);
+
+
+
 // codim 1
 
   #if deal_II_dimension < 3
@@ -101,6 +167,26 @@ for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENS
   DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
   add_data_vector<VEC> (const VEC                 &,
                       const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<deal_II_dimension,deal_II_dimension+1>,deal_II_dimension,deal_II_dimension+1>::
+  add_data_vector<VEC> (const DH<deal_II_dimension,deal_II_dimension+1> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<deal_II_dimension,deal_II_dimension+1>::space_dimension> &);
   #endif
 
 
@@ -126,6 +212,26 @@ for (VEC : SERIAL_VECTORS; DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENS
   DataOut_DoFData<DH<1,3>,1,3>::
   add_data_vector<VEC> (const VEC                 &,
                       const DataPostprocessor<DH<1,3>::space_dimension> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const DH<1,3> &,
+                        const VEC            &,
+                        const std::string   &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const DH<1,3> &,
+                        const VEC                       &,
+                        const std::vector<std::string> &,
+                        const std::vector<DataComponentInterpretation::DataComponentInterpretation> &);
+
+  template void
+  DataOut_DoFData<DH<1,3>,1,3>::
+  add_data_vector<VEC> (const DH<1,3> &,
+                        const VEC                 &,
+                        const DataPostprocessor<DH<1,3>::space_dimension> &);
   #endif
 
 }
@@ -250,3 +356,34 @@ for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS)
   #endif
 
 }
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
+{
+  namespace internal \{
+    namespace DataOut \{
+#if deal_II_dimension <= deal_II_space_dimension
+      template struct ParallelDataBase<deal_II_dimension,deal_II_space_dimension>;
+      template struct ParallelData<deal_II_dimension,deal_II_space_dimension>;
+#endif
+    \}
+  \}
+}
+
+
+for (DH : DOFHANDLER_TEMPLATES; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
+{
+  namespace internal \{
+    namespace DataOut \{
+#if deal_II_dimension <= deal_II_space_dimension
+      template
+      void 
+      ParallelDataBase<deal_II_dimension,deal_II_space_dimension>::
+      reinit_all_fe_values<dealii::DH<deal_II_dimension,deal_II_space_dimension> >
+      (std::vector<std_cxx1x::shared_ptr<DataEntryBase<dealii::DH<deal_II_dimension,deal_II_space_dimension> > > > &dof_data,
+       const dealii::Triangulation<deal_II_dimension,deal_II_space_dimension>::cell_iterator &cell,
+       const unsigned int face);
+#endif
+    \}
+  \}
+}
index 9d282370ae82be90132e621877c469685ef3934f..4dd1ccec43c1030a05b4575b792bb4f6c3af4e9f 100644 (file)
@@ -36,38 +36,29 @@ namespace internal
   namespace DataOutFaces
   {
     template <int dim, int spacedim>
-    template <class FE>
     ParallelData<dim,spacedim>::
-    ParallelData (const Quadrature<dim-1> &quadrature,
-                  const unsigned int n_components,
-                  const unsigned int n_datasets,
+    ParallelData (const unsigned int n_datasets,
                   const unsigned int n_subdivisions,
                   const std::vector<unsigned int> &n_postprocessor_outputs,
                   const Mapping<dim,spacedim> &mapping,
-                  const FE &finite_elements,
+                  const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
                   const UpdateFlags update_flags)
       :
       internal::DataOut::
-      ParallelDataBase<dim,spacedim> (n_components,
-                                      n_datasets,
+      ParallelDataBase<dim,spacedim> (n_datasets,
                                       n_subdivisions,
-                                      quadrature.size(),
                                       n_postprocessor_outputs,
-                                      finite_elements),
-      q_collection (quadrature),
-      mapping_collection (mapping),
-      x_fe_values (this->mapping_collection,
-                   this->fe_collection,
-                   q_collection,
-                   update_flags)
+                                      mapping,
+                                      finite_elements,
+                                      update_flags,
+                                      true)
     {}
 
 
+
     /**
-     * In a WorkStream context, use
-     * this function to append the
-     * patch computed by the parallel
-     * stage to the array of patches.
+     * In a WorkStream context, use this function to append the patch computed
+     * by the parallel stage to the array of patches.
      */
     template <int dim, int spacedim>
     void
@@ -81,6 +72,7 @@ namespace internal
 }
 
 
+
 template <int dim, class DH>
 DataOutFaces<dim,DH>::DataOutFaces(const bool so)
   :
@@ -88,6 +80,7 @@ DataOutFaces<dim,DH>::DataOutFaces(const bool so)
 {}
 
 
+
 template <int dim, class DH>
 void
 DataOutFaces<dim,DH>::
@@ -98,14 +91,10 @@ build_one_patch (const FaceDescriptor *cell_and_face,
   Assert (cell_and_face->first->is_locally_owned(),
           ExcNotImplemented());
 
-  // we use the mapping to transform the
-  // vertices. However, the mapping works on
-  // cells, not faces, so transform the face
-  // vertex to a cell vertex, that to a unit
-  // cell vertex and then, finally, that to
-  // the mapped vertex. In most cases this
-  // complicated procedure will be the
-  // identity.
+  // we use the mapping to transform the vertices. However, the mapping works
+  // on cells, not faces, so transform the face vertex to a cell vertex, that
+  // to a unit cell vertex and then, finally, that to the mapped vertex. In
+  // most cases this complicated procedure will be the identity.
   for (unsigned int vertex=0; vertex<GeometryInfo<DH::dimension-1>::vertices_per_cell; ++vertex)
     patch.vertices[vertex] = data.mapping_collection[0].transform_unit_to_real_cell
                              (cell_and_face->first,
@@ -119,24 +108,22 @@ build_one_patch (const FaceDescriptor *cell_and_face,
 
   if (data.n_datasets > 0)
     {
-      data.x_fe_values.reinit (cell_and_face->first, cell_and_face->second);
-      const FEFaceValues<DH::dimension> &fe_patch_values
-        = data.x_fe_values.get_present_fe_values ();
+      data.reinit_all_fe_values(this->dof_data, cell_and_face->first,
+                                cell_and_face->second);
+      const FEValuesBase<DH::dimension> &fe_patch_values
+        = data.get_present_fe_values (0);
 
       const unsigned int n_q_points = fe_patch_values.n_quadrature_points;
 
       // store the intermediate points
       Assert(patch.space_dim==DH::dimension, ExcInternalError());
       const std::vector<Point<DH::dimension> > &q_points=fe_patch_values.get_quadrature_points();
-      // resize the patch.data member
-      // in order to have enough memory
-      // for the quadrature points as
-      // well
+      // resize the patch.data member in order to have enough memory for the
+      // quadrature points as well
       patch.data.reinit(data.n_datasets+DH::dimension,
                         patch.data.size(1));
-      // set the flag indicating that
-      // for this cell the points are
-      // explicitly given
+      // set the flag indicating that for this cell the points are explicitly
+      // given
       patch.points_are_available=true;
       // copy points to patch.data
       for (unsigned int i=0; i<DH::dimension; ++i)
@@ -149,29 +136,27 @@ build_one_patch (const FaceDescriptor *cell_and_face,
       // first fill dof_data
       for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
         {
+          const FEValuesBase<DH::dimension> &fe_patch_values
+            = data.get_present_fe_values (dataset);
+          const unsigned int n_components
+            = fe_patch_values.get_fe().n_components();
           const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
           if (postprocessor != 0)
             {
-              // we have to postprocess the
-              // data, so determine, which
-              // fields have to be updated
+              // we have to postprocess the data, so determine, which fields
+              // have to be updated
               const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
 
-              // get normals, if
-              // needed. this is a
-              // geometrical information
-              // and thus does not depend
-              // on the number of
-              // components of the data
+              // get normals, if needed. this is a geometrical information and
+              // thus does not depend on the number of components of the data
               // vector
               if (update_flags & update_normal_vectors)
                 data.patch_normals=fe_patch_values.get_normal_vectors();
 
-              if (data.n_components == 1)
+              if (n_components == 1)
                 {
-                  // at each point there is
-                  // only one component of
-                  // value, gradient etc.
+                  // at each point there is only one component of value,
+                  // gradient etc.
                   if (update_flags & update_values)
                     this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                   data.patch_values);
@@ -195,10 +180,9 @@ build_one_patch (const FaceDescriptor *cell_and_face,
                 }
               else
                 {
-                  // at each point there is
-                  // a vector valued
-                  // function and its
+                  // at each point there is a vector valued function and its
                   // derivative...
+                  data.resize_system_vectors(n_components);
                   if (update_flags & update_values)
                     this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                   data.patch_values_system);
@@ -228,13 +212,10 @@ build_one_patch (const FaceDescriptor *cell_and_face,
                     = data.postprocessed_values[dataset][q](component);
             }
           else
-            // now we use the given data
-            // vector without
-            // modifications. again, we
-            // treat single component
-            // functions separately for
-            // efficiency reasons.
-            if (data.n_components == 1)
+            // now we use the given data vector without modifications. again,
+            // we treat single component functions separately for efficiency
+            // reasons.
+            if (n_components == 1)
               {
                 this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                               data.patch_values);
@@ -243,36 +224,29 @@ build_one_patch (const FaceDescriptor *cell_and_face,
               }
             else
               {
+                data.resize_system_vectors(n_components);
                 this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                               data.patch_values_system);
-                for (unsigned int component=0; component<data.n_components;
+                for (unsigned int component=0; component<n_components;
                      ++component)
                   for (unsigned int q=0; q<n_q_points; ++q)
                     patch.data(offset+component,q) =
                       data.patch_values_system[q](component);
               }
-          // increment the counter for the
-          // actual data record
+          // increment the counter for the actual data record
           offset+=this->dof_data[dataset]->n_output_variables;
         }
 
       // then do the cell data
       for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
         {
-          // we need to get at
-          // the number of the
-          // cell to which this
-          // face belongs in
-          // order to access the
-          // cell data. this is
-          // not readily
-          // available, so choose
-          // the following rather
-          // inefficient way:
+          // we need to get at the number of the cell to which this face
+          // belongs in order to access the cell data. this is not readily
+          // available, so choose the following rather inefficient way:
           Assert (cell_and_face->first->active(), ExcCellNotActiveForCellData());
           const unsigned int cell_number
-            = std::distance (this->dofs->begin_active(),
-                             typename DH::active_cell_iterator(cell_and_face->first));
+            = std::distance (this->triangulation->begin_active(),
+                             typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator(cell_and_face->first));
 
           const double value
             = this->cell_data[dataset]->get_cell_data_value (cell_number);
@@ -297,8 +271,7 @@ template <int dim, class DH>
 void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
                                           const unsigned int n_subdivisions_)
 {
-  // Check consistency of redundant
-  // template parameter
+  // Check consistency of redundant template parameter
   Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
 
   const unsigned int n_subdivisions = (n_subdivisions_ != 0)
@@ -309,33 +282,22 @@ void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
           ExcInvalidNumberOfSubdivisions(n_subdivisions));
 
   typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
-  Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
-
-  // before we start the loop:
-  // create a quadrature rule that
-  // actually has the points on this
-  // patch
-  const QTrapez<1>       q_trapez;
-  const QIterated<DH::dimension-1> patch_points (q_trapez, n_subdivisions);
-
-  const unsigned int n_components   = this->dofs->get_fe().n_components();
+  Assert (this->triangulation != 0,
+          typename BaseClass::ExcNoTriangulationSelected());
 
   unsigned int n_datasets     = this->cell_data.size();
   for (unsigned int i=0; i<this->dof_data.size(); ++i)
     n_datasets += this->dof_data[i]->n_output_variables;
 
-  // first count the cells we want to
-  // create patches of and make sure
-  // there is enough memory for that
+  // first count the cells we want to create patches of and make sure there is
+  // enough memory for that
   std::vector<FaceDescriptor> all_faces;
   for (FaceDescriptor face=first_face();
-       face.first != this->dofs->end();
+       face.first != this->triangulation->end();
        face = next_face(face))
     all_faces.push_back (face);
 
-  // clear the patches array and
-  // allocate the right number of
-  // elements
+  // clear the patches array and allocate the right number of elements
   this->patches.clear ();
   this->patches.reserve (all_faces.size());
   Assert (this->patches.size() == 0, ExcInternalError());
@@ -354,17 +316,17 @@ void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
       update_flags |= this->dof_data[i]->postprocessor->get_needed_update_flags();
   update_flags |= update_quadrature_points;
 
-  internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension>
-  thread_data (patch_points, n_components, n_datasets,
+  internal::DataOutFaces::ParallelData<DH::dimension, DH::space_dimension>
+  thread_data (n_datasets,
                n_subdivisions,
                n_postprocessor_outputs,
                mapping,
-               this->dofs->get_fe(),
+               this->get_finite_elements(),
                update_flags);
   DataOutBase::Patch<DH::dimension-1,DH::space_dimension> sample_patch;
   sample_patch.n_subdivisions = n_subdivisions;
   sample_patch.data.reinit (n_datasets,
-                            patch_points.size());
+                            Utilities::fixed_power<DH::dimension-1>(n_subdivisions+1));
 
   // now build the patches in parallel
   WorkStream::run (&all_faces[0],
@@ -386,8 +348,8 @@ DataOutFaces<dim,DH>::first_face ()
 {
   // simply find first active cell
   // with a face on the boundary
-  typename DH::active_cell_iterator cell = this->dofs->begin_active();
-  for (; cell != this->dofs->end(); ++cell)
+  typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator cell = this->triangulation->begin_active();
+  for (; cell != this->triangulation->end(); ++cell)
     for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
       if (!surface_only || cell->face(f)->at_boundary())
         return FaceDescriptor(cell, f);
@@ -407,9 +369,7 @@ DataOutFaces<dim,DH>::next_face (const FaceDescriptor &old_face)
 {
   FaceDescriptor face = old_face;
 
-  // first check whether the present
-  // cell has more faces on the
-  // boundary
+  // first check whether the present cell has more faces on the boundary
   for (unsigned int f=face.second+1; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
     if (!surface_only || face.first->face(f)->at_boundary())
       // yup, that is so, so return it
@@ -418,23 +378,19 @@ DataOutFaces<dim,DH>::next_face (const FaceDescriptor &old_face)
         return face;
       };
 
-  // otherwise find the next active
-  // cell that has a face on the
-  // boundary
+  // otherwise find the next active cell that has a face on the boundary
 
-  // convert the iterator to an
-  // active_iterator and advance
-  // this to the next active cell
-  typename DH::active_cell_iterator active_cell = face.first;
+  // convert the iterator to an active_iterator and advance this to the next
+  // active cell
+  typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell = face.first;
 
   // increase face pointer by one
   ++active_cell;
 
   // while there are active cells
-  while (active_cell != this->dofs->end())
+  while (active_cell != this->triangulation->end())
     {
-      // check all the faces of this
-      // active cell
+      // check all the faces of this active cell
       for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
         if (!surface_only || active_cell->face(f)->at_boundary())
           {
@@ -442,15 +398,12 @@ DataOutFaces<dim,DH>::next_face (const FaceDescriptor &old_face)
             face.second = f;
             return face;
           };
-      // the present cell had no
-      // faces on the boundary, so
-      // check next cell
+      // the present cell had no faces on the boundary, so check next cell
       ++active_cell;
     };
 
-  // we fell off the edge, so return
-  // with invalid pointer
-  face.first  = this->dofs->end();
+  // we fell off the edge, so return with invalid pointer
+  face.first  = this->triangulation->end();
   face.second = 0;
   return face;
 }
index a78854ada675e9daf810d21891091456782d60ed..5593d7a792004466a36531dece787cc44378f95b 100644 (file)
@@ -49,37 +49,31 @@ namespace internal
   namespace DataOutRotation
   {
     template <int dim, int spacedim>
-    template <class FE>
     ParallelData<dim,spacedim>::
-    ParallelData (const Quadrature<dim> &quadrature,
-                  const unsigned int n_components,
-                  const unsigned int n_datasets,
+    ParallelData (const unsigned int n_datasets,
                   const unsigned int n_subdivisions,
                   const unsigned int n_patches_per_circle,
                   const std::vector<unsigned int> &n_postprocessor_outputs,
-                  const FE &finite_elements,
+                  const Mapping<dim,spacedim> &mapping,
+                  const std::vector<std_cxx1x::shared_ptr<dealii::hp::FECollection<dim,spacedim> > > &finite_elements,
                   const UpdateFlags update_flags)
       :
       internal::DataOut::
-      ParallelDataBase<dim,spacedim> (n_components,
-                                      n_datasets,
+      ParallelDataBase<dim,spacedim> (n_datasets,
                                       n_subdivisions,
-                                      quadrature.size(),
                                       n_postprocessor_outputs,
-                                      finite_elements),
-      n_patches_per_circle (n_patches_per_circle),
-      q_collection (quadrature),
-      x_fe_values (this->fe_collection,
-                   q_collection,
-                   update_flags)
+                                      mapping,
+                                      finite_elements,
+                                      update_flags,
+                                      false),
+      n_patches_per_circle (n_patches_per_circle)
     {}
 
 
+
     /**
-     * In a WorkStream context, use
-     * this function to append the
-     * patch computed by the parallel
-     * stage to the array of patches.
+     * In a WorkStream context, use this function to append the patch computed
+     * by the parallel stage to the array of patches.
      */
     template <int dim, int spacedim>
     void
@@ -106,10 +100,8 @@ build_one_patch (const cell_iterator *cell,
 {
   if (dim == 3)
     {
-      // would this function make any
-      // sense after all? who would want
-      // to output/compute in four space
-      // dimensions?
+      // would this function make any sense after all? who would want to
+      // output/compute in four space dimensions?
       Assert (false, ExcNotImplemented());
       return;
     }
@@ -119,20 +111,13 @@ build_one_patch (const cell_iterator *cell,
 
   const unsigned int n_patches_per_circle = data.n_patches_per_circle;
 
-  // another abbreviation denoting
-  // the number of q_points in each
-  // direction
+  // another abbreviation denoting the number of q_points in each direction
   const unsigned int n_points = data.n_subdivisions+1;
 
-  // set up an array that holds the
-  // directions in the plane of
-  // rotation in which we will put
-  // points in the whole domain (not
-  // the rotationally reduced one in
-  // which the computation took
-  // place. for simplicity add the
-  // initial direction at the end
-  // again
+  // set up an array that holds the directions in the plane of rotation in
+  // which we will put points in the whole domain (not the rotationally
+  // reduced one in which the computation took place. for simplicity add the
+  // initial direction at the end again
   std::vector<Point<DH::dimension+1> > angle_directions (n_patches_per_circle+1);
   for (unsigned int i=0; i<=n_patches_per_circle; ++i)
     {
@@ -144,13 +129,9 @@ build_one_patch (const cell_iterator *cell,
 
   for (unsigned int angle=0; angle<n_patches_per_circle; ++angle)
     {
-      // first compute the
-      // vertices of the
-      // patch. note that they
-      // will have to be computed
-      // from the vertices of the
-      // cell, which has one
-      // dimension less, however.
+      // first compute the vertices of the patch. note that they will have to
+      // be computed from the vertices of the cell, which has one dimension
+      // less, however.
       switch (DH::dimension)
         {
         case 1:
@@ -176,14 +157,11 @@ build_one_patch (const cell_iterator *cell,
             {
               const Point<DH::dimension> v = (*cell)->vertex(vertex);
 
-              // make sure that the
-              // radial variable does
-              // attain negative
+              // make sure that the radial variable does attain negative
               // values
               Assert (v(0) >= 0, ExcRadialVariableHasNegativeValues(v(0)));
 
-              // now set the vertices
-              // of the patch
+              // now set the vertices of the patch
               patches[angle].vertices[vertex] = v(0) * angle_directions[angle];
               patches[angle].vertices[vertex][0] = v(1);
 
@@ -205,13 +183,14 @@ build_one_patch (const cell_iterator *cell,
       // then fill in data
       if (data.n_datasets > 0)
         {
-          data.x_fe_values.reinit (*cell);
-          const FEValues<DH::dimension> &fe_patch_values
-            = data.x_fe_values.get_present_fe_values ();
-
+          data.reinit_all_fe_values(this->dof_data, *cell);
           // first fill dof_data
           for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
             {
+              const FEValuesBase<DH::dimension> & fe_patch_values
+                = data.get_present_fe_values(dataset);
+              const unsigned int n_components
+                = fe_patch_values.get_fe().n_components();
               const DataPostprocessor<dim> *postprocessor=this->dof_data[dataset]->postprocessor;
               if (postprocessor != 0)
                 {
@@ -220,7 +199,7 @@ build_one_patch (const cell_iterator *cell,
                   // fields have to be updated
                   const UpdateFlags update_flags=postprocessor->get_needed_update_flags();
 
-                  if (data.n_components == 1)
+                  if (n_components == 1)
                     {
                       // at each point there is
                       // only one component of
@@ -249,10 +228,10 @@ build_one_patch (const cell_iterator *cell,
                     }
                   else
                     {
-                      // at each point there is
-                      // a vector valued
-                      // function and its
-                      // derivative...
+                      data.resize_system_vectors(n_components);
+
+                      // at each point there is a vector valued function and
+                      // its derivative...
                       if (update_flags & update_values)
                         this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                       data.patch_values_system);
@@ -306,7 +285,7 @@ build_one_patch (const cell_iterator *cell,
                         }
                     }
                 }
-              else if (data.n_components == 1)
+              else if (n_components == 1)
                 {
                   this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                 data.patch_values);
@@ -339,10 +318,11 @@ build_one_patch (const cell_iterator *cell,
               else
                 // system of components
                 {
+                  data.resize_system_vectors(n_components);
                   this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                 data.patch_values_system);
 
-                  for (unsigned int component=0; component<data.n_components;
+                  for (unsigned int component=0; component<n_components;
                        ++component)
                     {
                       switch (DH::dimension)
@@ -377,21 +357,14 @@ build_one_patch (const cell_iterator *cell,
           // then do the cell data
           for (unsigned int dataset=0; dataset<this->cell_data.size(); ++dataset)
             {
-              // we need to get at
-              // the number of the
-              // cell to which this
-              // face belongs in
-              // order to access the
-              // cell data. this is
-              // not readily
-              // available, so choose
-              // the following rather
-              // inefficient way:
+              // we need to get at the number of the cell to which this face
+              // belongs in order to access the cell data. this is not readily
+              // available, so choose the following rather inefficient way:
               Assert ((*cell)->active(),
                       ExcMessage("Cell must be active for cell data"));
               const unsigned int cell_number
-                = std::distance (this->dofs->begin_active(),
-                                 typename DH::active_cell_iterator(*cell));
+                = std::distance (this->triangulation->begin_active(),
+                                 typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator(*cell));
               const double value
                 = this->cell_data[dataset]->get_cell_data_value (cell_number);
               switch (DH::dimension)
@@ -434,7 +407,8 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
   // template parameter
   Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
   typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
-  Assert (this->dofs != 0, typename BaseClass::ExcNoDoFHandlerSelected());
+  Assert (this->triangulation != 0,
+          typename BaseClass::ExcNoTriangulationSelected());
 
   const unsigned int n_subdivisions = (nnnn_subdivisions != 0)
                                       ? nnnn_subdivisions
@@ -442,10 +416,6 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
   Assert (n_subdivisions >= 1,
           ExcInvalidNumberOfSubdivisions(n_subdivisions));
 
-  const QTrapez<1>     q_trapez;
-  const QIterated<DH::dimension> patch_points (q_trapez, n_subdivisions);
-
-  const unsigned int n_components   = this->dofs->get_fe().n_components();
   unsigned int n_datasets=this->cell_data.size();
   for (unsigned int i=0; i<this->dof_data.size(); ++i)
     n_datasets+= this->dof_data[i]->n_output_variables;
@@ -465,7 +435,7 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
   // create patches of and make sure
   // there is enough memory for that
   std::vector<cell_iterator> all_cells;
-  for (cell_iterator cell=first_cell(); cell != this->dofs->end();
+  for (cell_iterator cell=first_cell(); cell != this->triangulation->end();
        cell = next_cell(cell))
     all_cells.push_back (cell);
 
@@ -485,10 +455,11 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
     else
       n_postprocessor_outputs[dataset] = 0;
 
+  const MappingQ1<DH::dimension, DH::space_dimension> mapping;
   internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension>
-  thread_data (patch_points, n_components, n_datasets,
+  thread_data (n_datasets,
                n_subdivisions, n_patches_per_circle,
-               n_postprocessor_outputs, this->dofs->get_fe(),
+               n_postprocessor_outputs, mapping, this->get_finite_elements(),
                update_flags);
   std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> >
   new_patches (n_patches_per_circle);
@@ -496,8 +467,7 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
     {
       new_patches[i].n_subdivisions = n_subdivisions;
       new_patches[i].data.reinit (n_datasets,
-                                  patch_points.size()
-                                  * (n_subdivisions+1));
+                                  Utilities::fixed_power<DH::dimension+1>(n_subdivisions+1));
     }
 
   // now build the patches in parallel
@@ -518,7 +488,7 @@ template <int dim, class DH>
 typename DataOutRotation<dim,DH>::cell_iterator
 DataOutRotation<dim,DH>::first_cell ()
 {
-  return this->dofs->begin_active ();
+  return this->triangulation->begin_active ();
 }
 
 
@@ -529,7 +499,7 @@ DataOutRotation<dim,DH>::next_cell (const cell_iterator &cell)
   // convert the iterator to an
   // active_iterator and advance
   // this to the next active cell
-  typename DH::active_cell_iterator active_cell = cell;
+  typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell = cell;
   ++active_cell;
   return active_cell;
 }
index 7d0327b86645ffbea5a538091547d7b7e1ad6f9f..f7bbff340ecceb50f3f74fc09ddd2e93adc61904 100644 (file)
@@ -577,6 +577,22 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
          std::map<types::global_dof_index,double>&, 
          std::vector<unsigned int>);
 
+      template
+        void project_boundary_values<deal_II_dimension>
+        (const Mapping<deal_II_dimension>     &,
+         const DoFHandler<deal_II_dimension>  &,
+         const FunctionMap<deal_II_dimension>::type &,
+         const Quadrature<deal_II_dimension-1>&,
+         ConstraintMatrix&, std::vector<unsigned int>);
+
+      template
+        void project_boundary_values<deal_II_dimension>
+        (const DoFHandler<deal_II_dimension>  &,
+         const FunctionMap<deal_II_dimension>::type &,
+         const Quadrature<deal_II_dimension-1>&,
+         ConstraintMatrix&, 
+         std::vector<unsigned int>);
+
 
 
 #if deal_II_dimension != 1

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.