]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Merged from trunk r32366 through r32443.
authorheltai <heltai@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 10 Feb 2014 13:21:33 +0000 (13:21 +0000)
committerheltai <heltai@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 10 Feb 2014 13:21:33 +0000 (13:21 +0000)
git-svn-id: https://svn.dealii.org/branches/branch_manifold_id@32444 0785d39b-7218-0410-832d-ea1e28bc413d

122 files changed:
deal.II/CMakeLists.txt
deal.II/bundled/CMakeLists.txt
deal.II/bundled/boost-1.49.0/libs/iostreams/src/CMakeLists.txt
deal.II/bundled/boost-1.49.0/libs/serialization/src/CMakeLists.txt
deal.II/bundled/boost-1.49.0/libs/thread/src/CMakeLists.txt
deal.II/bundled/tbb41_20130401oss/src/CMakeLists.txt
deal.II/bundled/umfpack/AMD/Source/CMakeLists.txt
deal.II/bundled/umfpack/UMFPACK/Source/CMakeLists.txt
deal.II/cmake/checks/check_02_system_features.cmake
deal.II/cmake/config/CMakeLists.txt
deal.II/cmake/configure/configure_1_bzip2.cmake
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_2_umfpack.cmake
deal.II/cmake/configure/configure_3_petsc.cmake
deal.II/cmake/configure/configure_boost.cmake
deal.II/cmake/configure/configure_functionparser.cmake
deal.II/cmake/configure/configure_hdf5.cmake
deal.II/cmake/configure/configure_mumps.cmake
deal.II/cmake/configure/configure_p4est.cmake
deal.II/cmake/configure/configure_slepc.cmake
deal.II/cmake/macros/macro_configure_feature.cmake
deal.II/cmake/macros/macro_deal_ii_add_library.cmake
deal.II/cmake/macros/macro_filter_system_libraries.cmake [new file with mode: 0644]
deal.II/cmake/macros/macro_find_system_library.cmake [new file with mode: 0644]
deal.II/cmake/macros/macro_register_feature.cmake
deal.II/cmake/modules/FindDEALII_LAPACK.cmake
deal.II/cmake/modules/FindPETSC.cmake
deal.II/cmake/modules/FindTRILINOS.cmake
deal.II/cmake/modules/FindUMFPACK.cmake
deal.II/cmake/setup_compiler_flags.cmake
deal.II/cmake/setup_finalize.cmake
deal.II/cmake/setup_sanity_checks.cmake [new file with mode: 0644]
deal.II/cmake/setup_write_config.cmake
deal.II/doc/developers/cmake-internals.html
deal.II/doc/doxygen/headers/glossary.h
deal.II/doc/news/changes.h
deal.II/doc/publications/index.html
deal.II/examples/step-13/step-13.cc
deal.II/examples/step-14/step-14.cc
deal.II/examples/step-2/doc/intro.dox
deal.II/examples/step-6/step-6.cc
deal.II/include/deal.II/algorithms/newton.templates.h
deal.II/include/deal.II/base/data_out_base.h
deal.II/include/deal.II/base/function.h
deal.II/include/deal.II/base/function_parser.h
deal.II/include/deal.II/base/smartpointer.h
deal.II/include/deal.II/base/thread_local_storage.h
deal.II/include/deal.II/dofs/dof_accessor.h
deal.II/include/deal.II/dofs/dof_accessor.templates.h
deal.II/include/deal.II/grid/grid_generator.h
deal.II/include/deal.II/grid/grid_tools.h
deal.II/include/deal.II/integrators/l2.h
deal.II/include/deal.II/lac/constraint_matrix.h
deal.II/include/deal.II/lac/full_matrix.h
deal.II/include/deal.II/lac/full_matrix.templates.h
deal.II/include/deal.II/lac/lapack_full_matrix.h
deal.II/include/deal.II/lac/matrix_block.h
deal.II/include/deal.II/matrix_free/fe_evaluation.h
deal.II/include/deal.II/matrix_free/mapping_info.h
deal.II/include/deal.II/matrix_free/mapping_info.templates.h
deal.II/include/deal.II/multigrid/mg_transfer.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/derivative_approximation.h
deal.II/include/deal.II/numerics/vector_tools.templates.h
deal.II/source/CMakeLists.txt
deal.II/source/base/data_out_base.cc
deal.II/source/base/data_out_base.inst.in
deal.II/source/base/mpi.cc
deal.II/source/base/quadrature_lib.cc
deal.II/source/fe/fe_values.cc
deal.II/source/grid/grid_generator.cc
deal.II/source/grid/grid_tools.cc
deal.II/source/grid/grid_tools.inst.in
deal.II/source/hp/dof_handler.cc
deal.II/source/lac/lapack_full_matrix.cc
deal.II/source/lac/petsc_full_matrix.cc
deal.II/source/multigrid/mg_transfer_prebuilt.cc
deal.II/source/numerics/data_out_faces.cc
deal.II/source/numerics/data_out_rotation.cc
deal.II/source/numerics/derivative_approximation.cc
deal.II/source/numerics/derivative_approximation.inst.in
deal.II/source/numerics/error_estimator.cc
deal.II/tests/quick_tests/CMakeLists.txt
deal.II/tests/quick_tests/affinity.cc
deal.II/tests/quick_tests/tbb.cc
tests/base/function_parser_03.cc [new file with mode: 0644]
tests/base/function_parser_03.with_functionparser=true.output [new file with mode: 0644]
tests/base/function_parser_04.cc [new file with mode: 0644]
tests/base/function_parser_04.with_functionparser=true.with_threads=true.output [new file with mode: 0644]
tests/base/functions_04.cc
tests/base/functions_singularity.cc
tests/base/thread_local_storage_05.cc [new file with mode: 0644]
tests/base/thread_local_storage_05.with_threads=on.output [new file with mode: 0644]
tests/base/thread_local_storage_06.cc [new file with mode: 0644]
tests/base/thread_local_storage_06.with_threads=on.output [new file with mode: 0644]
tests/bits/step-13.cc
tests/bits/step-14.cc
tests/deal.II/fe_values_view_28.cc
tests/deal.II/fe_values_view_28.output
tests/deal.II/fe_values_view_29.cc [new file with mode: 0644]
tests/deal.II/fe_values_view_29.output [new file with mode: 0644]
tests/deal.II/grid_tools_transform_01.cc [new file with mode: 0644]
tests/deal.II/grid_tools_transform_01.output [new file with mode: 0644]
tests/hp/step-13.cc
tests/lapack/full_matrix_08.cc [new file with mode: 0644]
tests/lapack/full_matrix_08.output [new file with mode: 0644]
tests/lapack/full_matrix_09.cc [new file with mode: 0644]
tests/lapack/full_matrix_09.output [new file with mode: 0644]
tests/lapack/full_matrix_10.cc [new file with mode: 0644]
tests/lapack/full_matrix_10.output [new file with mode: 0644]
tests/lapack/full_matrix_11.cc [new file with mode: 0644]
tests/lapack/full_matrix_11.output [new file with mode: 0644]
tests/lapack/full_matrix_12.cc [new file with mode: 0644]
tests/lapack/full_matrix_12.output [new file with mode: 0644]
tests/petsc/full_matrix_00.cc [new file with mode: 0644]
tests/petsc/full_matrix_00.output [new file with mode: 0644]

index ad2a8cacd4ed2736d765fdf6cd6a5d9de819aa83..3b5c72425849d707ae0aeb9e04afd7a1ed5f33ee 100644 (file)
@@ -124,6 +124,7 @@ ENDFOREACH()
 INCLUDE(setup_custom_targets)
 INCLUDE(setup_finalize)
 INCLUDE(setup_write_config)
+#INCLUDE(setup_sanity_checks)
 
 
 ########################################################################
index b4ff8c8bf6e05e0267b62f7fd68308de8b6b1b85..68855752ccaa0c2d1c8013a0ab6da2f9935fadc6 100644 (file)
@@ -28,10 +28,6 @@ IF(FEATURE_BOOST_BUNDLED_CONFIGURED)
     PATTERN ".svn" EXCLUDE
     )
 
-  FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
-    "${BOOST_FOLDER}/include\n"
-    )
-
   ADD_SUBDIRECTORY(${BOOST_FOLDER}/libs/serialization/src)
 
   IF(DEAL_II_WITH_ZLIB)
@@ -59,10 +55,6 @@ IF(FEATURE_THREADS_BUNDLED_CONFIGURED)
     PATTERN ".svn" EXCLUDE
     )
 
-  FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
-    "${TBB_FOLDER}/include\n"
-    )
-
   ADD_SUBDIRECTORY(${TBB_FOLDER}/src)
 ENDIF()
 
index ef8f84838ce349ad5cf61a70e00073d49fbe9514..0e7daafd8fcda9ce143f8882be1227518a2e2223 100644 (file)
@@ -14,6 +14,8 @@
 ##
 ## ---------------------------------------------------------------------
 
+INCLUDE_DIRECTORIES(${BOOST_BUNDLED_INCLUDE_DIRS})
+
 SET(src_boost_iostreams
     file_descriptor.cpp
     gzip.cpp
index b06ba8bd6e6daced561fbb15a0dd6c8336b09b80..4f35a0e7de566880f57ee394961e24c2c77932c8 100644 (file)
@@ -14,6 +14,8 @@
 ##
 ## ---------------------------------------------------------------------
 
+INCLUDE_DIRECTORIES(${BOOST_BUNDLED_INCLUDE_DIRS})
+
 SET(src_boost_serialization
   basic_archive.cpp
   basic_iarchive.cpp
index 2e3eb8839f5ce1cdf1fda7a7c4029575656e49c7..c1229bb8a94016af5e57fcd842cee084cdb28da0 100644 (file)
@@ -14,6 +14,8 @@
 ##
 ## ---------------------------------------------------------------------
 
+INCLUDE_DIRECTORIES(${BOOST_BUNDLED_INCLUDE_DIRS})
+
 IF(DEAL_II_USE_MT_POSIX)
   SET(src_boost_thread
     pthread/once.cpp
index 8e764b44f3273570b39e806ac86e3c3553b0c8f1..fa9b0faa97824fc875578dfebb60a49a9f50dcce 100644 (file)
@@ -23,6 +23,7 @@ STRIP_FLAG(DEAL_II_CXX_FLAGS "-pedantic")
 
 SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
 INCLUDE_DIRECTORIES(
+  ${THREADS_BUNDLED_INCLUDE_DIRS}
   ${CMAKE_CURRENT_SOURCE_DIR}/rml/include
   )
 
index 5f3231de0111d484fc4f624af747f3c89e2e9f06..df569bf230775f268b14d23a441233cb3b9de9b4 100644 (file)
@@ -14,6 +14,8 @@
 ##
 ## ---------------------------------------------------------------------
 
+INCLUDE_DIRECTORIES(${UMFPACK_BUNDLED_INCLUDE_DIRS})
+
 SET(src_amd
   amd_1.cc
   amd_2.cc
index 16f03377d4e0528f39164982f67210e2bb2043d1..5029fc65f708d9473b33d535770e3ff8cbeb7866 100644 (file)
 # (... where everything is explained contrary to this... mess)
 #
 
+INCLUDE_DIRECTORIES(${UMFPACK_BUNDLED_INCLUDE_DIRS})
+
 #
 # *Shush!*
+# (Remove locally in this subdirectory)
 #
 STRIP_FLAG(DEAL_II_CXX_FLAGS "-pedantic")
 STRIP_FLAG(DEAL_II_CXX_FLAGS "-Wall")
index 20c158c6361c6f52a20857440ec35f32c7f73054..259465b9f93ebf1636a8c458ac453cf3fbeb9019 100644 (file)
@@ -58,13 +58,7 @@ CHECK_CXX_SYMBOL_EXISTS("rand_r" "stdlib.h" HAVE_RAND_R)
 #
 # Do we have the Bessel function jn?
 #
-# 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()
-FIND_LIBRARY(m_LIBRARY NAMES m)
-SWITCH_LIBRARY_PREFERENCE()
+FIND_SYSTEM_LIBRARY(m_LIBRARY NAMES m)
 MARK_AS_ADVANCED(m_LIBRARY)
 
 IF(NOT m_LIBRARY MATCHES "-NOTFOUND")
@@ -72,7 +66,7 @@ IF(NOT m_LIBRARY MATCHES "-NOTFOUND")
   CHECK_CXX_SYMBOL_EXISTS("jn" "math.h" HAVE_JN)
   RESET_CMAKE_REQUIRED()
   IF(HAVE_JN)
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${m_LIBRARY})
+    LIST(APPEND DEAL_II_LIBRARIES ${m_LIBRARY})
   ENDIF()
 ENDIF()
 
index 4ade81d2b2f00244685269d107ed2b8b293edae3..465d18de1fef7c049b812fca9d525067cc14b572 100644 (file)
 
 MESSAGE(STATUS "Setting up project configuration")
 
-#
-# Read in auxiliary include directories for the build directory
-# configuration:
-#
-FILE(STRINGS
-  ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
-  deal_ii_source_includes
-  )
-
 #
 # Configure the template-arguments file
 #
@@ -113,8 +104,8 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
   ENDIF()
 
   LIST(APPEND CONFIG_LIBRARIES_${_build}
-    ${DEAL_II_EXTERNAL_LIBRARIES_${_build}}
-    ${DEAL_II_EXTERNAL_LIBRARIES}
+    ${DEAL_II_LIBRARIES_${_build}}
+    ${DEAL_II_LIBRARIES}
     )
   LIST(APPEND CONFIG_LIBRARIES
     ${_keyword}
@@ -140,7 +131,7 @@ SET(CONFIG_INCLUDE_DIRS
   \${DEAL_II_PATH}/include/deal.II
   ${CMAKE_SOURCE_DIR}/include/
   ${CMAKE_SOURCE_DIR}/include/deal.II
-  ${deal_ii_source_includes}
+  ${DEAL_II_BUNDLED_INCLUDE_DIRS}
   ${DEAL_II_USER_INCLUDE_DIRS}
   )
 CONFIGURE_FILE(
@@ -236,8 +227,8 @@ IF(DEAL_II_COMPONENT_COMPAT_FILES)
 
     SET(_libs)
     FOREACH(_lib
-        ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
-        ${DEAL_II_EXTERNAL_LIBRARIES}
+        ${DEAL_II_LIBRARIES_${build}}
+        ${DEAL_II_LIBRARIES}
         )
       IF(_lib MATCHES "^\\s*\\/" AND NOT _lib MATCHES "\\.framework$")
         LIST(APPEND _libs "${_lib}")
@@ -252,8 +243,8 @@ IF(DEAL_II_COMPONENT_COMPAT_FILES)
     SET(_paths)
     FOREACH(_lib
         $(D)/${DEAL_II_LIBRARY_RELDIR}/${CONFIG_LIBRARY_${build}}
-        ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
-        ${DEAL_II_EXTERNAL_LIBRARIES}
+        ${DEAL_II_LIBRARIES_${build}}
+        ${DEAL_II_LIBRARIES}
         )
 
       #
@@ -351,7 +342,7 @@ IF(DEAL_II_COMPONENT_COMPAT_FILES)
     $(D)/install/deal.II
     ${CMAKE_SOURCE_DIR}/include/
     ${CMAKE_SOURCE_DIR}/include/deal.II
-    ${deal_ii_source_includes}
+    ${DEAL_II_BUNDLED_INCLUDE_DIRS}
     ${DEAL_II_USER_INCLUDE_DIRS}
     )
   CONFIGURE_FILE(
index 61fd319e7ed3c281f89ed447c6a25bd53f751c76..a905aad144d8b5e07a0b41245f65ea234b55b7fe 100644 (file)
 #
 
 MACRO(FEATURE_BZIP2_FIND_EXTERNAL var)
-
   FIND_PACKAGE(BZip2)
 
   IF(BZIP2_FOUND)
     #
-    # Rename some variables:
+    # Rename variables:
     #
     SET(BZIP2_VERSION ${BZIP2_VERSION_STRING})
     SET(BZIP2_INCLUDE_DIRS ${BZIP2_INCLUDE_DIR})
index ede31c24ba7fc2445ea38b585d5ab44be565dc3a..258af871f23cd4b9416bb89337aa875a6cb8f4bc 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -80,7 +80,6 @@ ENDMACRO()
 
 
 MACRO(FEATURE_LAPACK_CONFIGURE_EXTERNAL)
-  REGISTER_FEATURE(LAPACK)
   CHECK_FOR_LAPACK_FUNCTIONS()
 ENDMACRO()
 
index 1927e8ecbdb92a2ab2c01a33074855480d0081bd..a73e27d962eab0c0599e3970196059bd0e546e8c 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -18,7 +18,7 @@
 # Configuration for mpi support:
 #
 # We look for the C and Fortran libraries as well because they are needed
-# by some external libraries:
+# by some external libraries for the link interface:
 #
 
 MACRO(FEATURE_MPI_FIND_EXTERNAL var)
@@ -137,6 +137,9 @@ MACRO(FEATURE_MPI_FIND_EXTERNAL var)
     SET(${var} TRUE)
   ENDIF()
 
+  # Hide some variables:
+  MARK_AS_ADVANCED(MPI_EXTRA_LIBRARY MPI_LIBRARY MPI_MPI_H)
+
   #
   # Populate correct variables:
   #
@@ -145,19 +148,6 @@ MACRO(FEATURE_MPI_FIND_EXTERNAL var)
   SET(MPI_CXX_FLAGS ${MPI_CXX_COMPILE_FLAGS})
   SET(MPI_LINKER_FLAGS "${MPI_CXX_LINK_FLAGS}")
 
-  # Hide some variables:
-  MARK_AS_ADVANCED(MPI_EXTRA_LIBRARY MPI_LIBRARY MPI_MPI_H)
-
-ENDMACRO()
-
-
-MACRO(FEATURE_MPI_CONFIGURE_EXTERNAL)
-  #
-  # The user has to know the location of the mpi headers as well:
-  #
-  SET(MPI_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-  REGISTER_FEATURE(MPI)
 ENDMACRO()
 
 
@@ -179,3 +169,8 @@ ENDMACRO()
 
 
 CONFIGURE_FEATURE(MPI)
+
+#
+# The user has to know the location of the mpi headers as well:
+#
+SET(MPI_USER_INCLUDE_DIRS ${MPI_INCLUDE_DIRS})
index c7265653bb70dbcdee547acd5dc13676c1d492eb..1d712c04b7618e254b735c69272a8d8f387cae2a 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -30,22 +30,16 @@ MACRO(SETUP_THREADING)
   # Unfortunately the FindThreads macro needs a working C compiler
   #
   IF(CMAKE_C_COMPILER_WORKS)
-    #
-    # 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()
-
     #
     # Clear the test flags because FindThreads.cmake will use a C compiler:
     #
     CLEAR_CMAKE_REQUIRED()
 
+    SWITCH_LIBRARY_PREFERENCE()
     FIND_PACKAGE(Threads)
+    SWITCH_LIBRARY_PREFERENCE()
 
     RESET_CMAKE_REQUIRED()
-    SWITCH_LIBRARY_PREFERENCE()
 
   ELSE()
 
@@ -63,7 +57,7 @@ MACRO(SETUP_THREADING)
 
   IF(NOT Threads_FOUND)
     #
-    # TODO: This is a dead end. Threading might be setup with internal TBB
+    # TODO: This is a dead end. Threading might be set up with internal TBB
     # so we have no way of returning unsuccessfully...
     #
     MESSAGE(FATAL_ERROR
@@ -88,7 +82,7 @@ MACRO(SETUP_THREADING)
     ENDIF()
   ENDIF()
 
-  ADD_FLAGS(DEAL_II_LINKER_FLAGS "${CMAKE_THREAD_LIBS_INIT}")
+  ADD_FLAGS(THREADS_LINKER_FLAGS "${CMAKE_THREAD_LIBS_INIT}")
 
   #
   # Set up some posix thread specific configuration toggles:
@@ -152,13 +146,10 @@ ENDMACRO()
 
 MACRO(FEATURE_THREADS_CONFIGURE_EXTERNAL)
 
-  REGISTER_FEATURE(TBB)
-
-  # TODO: Refactor
   IF(CMAKE_BUILD_TYPE MATCHES "Debug")
     IF(TBB_WITH_DEBUG_LIB)
-      LIST(APPEND DEAL_II_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
-      LIST(APPEND DEAL_II_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+      LIST(APPEND THREADS_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+      LIST(APPEND THREADS_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
     ENDIF()
   ENDIF()
 
@@ -169,15 +160,14 @@ MACRO(FEATURE_THREADS_CONFIGURE_EXTERNAL)
   IF( DEAL_II_WITH_CXX11 AND
       NOT DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE AND
       NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
-    LIST(APPEND DEAL_II_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
-    LIST(APPEND DEAL_II_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+    LIST(APPEND THREADS_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+    LIST(APPEND THREADS_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
   ENDIF()
 
   SETUP_THREADING()
 
-  # TODO: Refactor this mess of a configure file...
-  SET(THREADS_LIBRARIES ${TBB_LIBRARIES})
-  SET(THREADS_INCLUDE_DIRS ${TBB_INCLUDE_DIRS})
+  LIST(APPEND THREADS_LIBRARIES ${TBB_LIBRARIES})
+  LIST(APPEND THREADS_INCLUDE_DIRS ${TBB_INCLUDE_DIRS})
 
 ENDMACRO()
 
@@ -191,15 +181,15 @@ MACRO(FEATURE_THREADS_CONFIGURE_BUNDLED)
   #
   # We have to disable a bunch of warnings:
   #
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-parentheses")
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-long-long")
+  ENABLE_IF_SUPPORTED(THREADS_CXX_FLAGS "-Wno-parentheses")
+  ENABLE_IF_SUPPORTED(THREADS_CXX_FLAGS "-Wno-long-long")
 
   #
   # Add some definitions to use the header files in debug mode:
   #
   IF (CMAKE_BUILD_TYPE MATCHES "Debug")
-    LIST(APPEND DEAL_II_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
-    LIST(APPEND DEAL_II_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+    LIST(APPEND THREADS_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
+    LIST(APPEND THREADS_USER_DEFINITIONS_DEBUG "TBB_USE_DEBUG" "TBB_DO_ASSERT=1")
   ENDIF()
 
   #
@@ -209,20 +199,22 @@ MACRO(FEATURE_THREADS_CONFIGURE_BUNDLED)
   IF( DEAL_II_WITH_CXX11 AND
       NOT DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE AND
       NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU" )
-    LIST(APPEND DEAL_II_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
-    LIST(APPEND DEAL_II_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+    LIST(APPEND THREADS_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
+    LIST(APPEND THREADS_USER_DEFINITIONS "TBB_IMPLEMENT_CPP0X=1")
   ENDIF()
 
   #
   # tbb uses dlopen/dlclose, so link against libdl.so as well:
   #
-  FIND_LIBRARY(dl_LIBRARY NAMES dl)
+  # TODO: Also necessary for external lib, use preference toggle
+  #
+  FIND_SYSTEM_LIBRARY(dl_LIBRARY NAMES dl)
   MARK_AS_ADVANCED(dl_LIBRARY)
   IF(NOT dl_LIBRARY MATCHES "-NOTFOUND")
-    LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${dl_LIBRARY})
+    LIST(APPEND THREADS_LIBRARIES ${dl_LIBRARY})
   ENDIF()
 
-  INCLUDE_DIRECTORIES(${TBB_FOLDER}/include)
+  LIST(APPEND THREADS_BUNDLED_INCLUDE_DIRS ${TBB_FOLDER}/include)
 ENDMACRO()
 
 
index 1a49a2c7c2bebd8bbfcab618e94a2e14c98d4f18..739c7a62749372c5916b0f12c0b281ecc46eca24 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
index e04bbfac4149d743dda3b0c7822de52e26e45782..b7b000621152424734416a97fae8f5d233c80a4b 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -163,8 +163,8 @@ MACRO(FEATURE_TRILINOS_FIND_EXTERNAL var)
     IF(DEAL_II_WITH_CXX11 AND NOT TRILINOS_SUPPORTS_CPP11)
 
       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")
+        LIST(APPEND TRILINOS_DEFINITIONS "HAS_C99_TR1_CMATH")
+        LIST(APPEND TRILINOS_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 "
@@ -195,8 +195,7 @@ ENDMACRO()
 
 MACRO(FEATURE_TRILINOS_CONFIGURE_EXTERNAL)
 
-  SET(TRILINOS_ADD_TO_USER_INCLUDE_DIRS TRUE)
-  REGISTER_FEATURE(TRILINOS)
+  SET(TRILINOS_USER_INCLUDE_DIRS ${TRILINOS_INCLUDE_DIRS})
 
   SET(DEAL_II_EXPAND_TRILINOS_VECTOR "TrilinosWrappers::Vector")
   SET(DEAL_II_EXPAND_TRILINOS_BLOCKVECTOR "TrilinosWrappers::BlockVector")
@@ -208,9 +207,9 @@ MACRO(FEATURE_TRILINOS_CONFIGURE_EXTERNAL)
   #
   # Disable a bunch of warnings caused by Trilinos headers:
   #
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-unused")
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-extra")
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-overloaded-virtual")
+  ENABLE_IF_SUPPORTED(TRILINOS_CXX_FLAGS "-Wno-unused")
+  ENABLE_IF_SUPPORTED(TRILINOS_CXX_FLAGS "-Wno-extra")
+  ENABLE_IF_SUPPORTED(TRILINOS_CXX_FLAGS "-Wno-overloaded-virtual")
 
 ENDMACRO()
 
index 56ac7e323d648fd83fe9671aa145903caaf85d05..f1d0d7451351799f7f7cbc0f28939af4730349b4 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -21,7 +21,7 @@
 SET(FEATURE_UMFPACK_DEPENDS DEAL_II_WITH_LAPACK)
 
 MACRO(FEATURE_UMFPACK_CONFIGURE_BUNDLED)
-  INCLUDE_DIRECTORIES(
+  SET(UMFPACK_BUNDLED_INCLUDE_DIRS
     ${UMFPACK_FOLDER}/UMFPACK/Include
     ${UMFPACK_FOLDER}/AMD/Include
     )
index 6ed8f62c24e4e592dabb81007dda802e0ecd4e4a..81cdd69e30149ae60a32cb0b57ea8f602969cf86 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -112,15 +112,13 @@ ENDMACRO()
 
 
 MACRO(FEATURE_PETSC_CONFIGURE_EXTERNAL)
-  INCLUDE_DIRECTORIES(${PETSC_INCLUDE_DIRS})
 
-  SET(PETSC_ADD_TO_USER_INCLUDE_DIRS TRUE)
-  REGISTER_FEATURE(PETSC)
+  SET(PETSC_USER_INCLUDE_DIRS ${PETSC_INCLUDE_DIRS})
 
   #
   # Disable a bunch of warnings when compiling with petsc:
   #
-  ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS "-Wno-long-long")
+  ENABLE_IF_SUPPORTED(PETSC_CXX_FLAGS "-Wno-long-long")
 
   SET(DEAL_II_EXPAND_PETSC_VECTOR "PETScWrappers::Vector")
   SET(DEAL_II_EXPAND_PETSC_BLOCKVECTOR "PETScWrappers::BlockVector")
index de29304bbf61942974fbc691c55ba723f2359ffe..ec72b800a282ef096e56e0c65873c59386712718 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -105,19 +105,18 @@ MACRO(FEATURE_BOOST_FIND_EXTERNAL var)
 ENDMACRO()
 
 
-#
-# The user has to know the location of the boost headers as well:
-#
-SET(BOOST_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
 MACRO(FEATURE_BOOST_CONFIGURE_BUNDLED)
-  INCLUDE_DIRECTORIES(${BOOST_FOLDER}/include)
+  SET(BOOST_BUNDLED_INCLUDE_DIRS ${BOOST_FOLDER}/include)
 ENDMACRO()
 
 
 CONFIGURE_FEATURE(BOOST)
 
+#
+# The user has to know the location of the boost headers as well:
+#
+SET(BOOST_USER_INCLUDE_DIRS ${BOOST_INCLUDE_DIRS})
+
 #
 # DEAL_II_WITH_BOOST is always required.
 #
index c9abde129dc68f5ff79d86f56c78e455c262ec16..4794106652ed52c33a7a13940b7704fe283e03bb 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -26,7 +26,7 @@ ENDMACRO()
 
 
 MACRO(FEATURE_FUNCTIONPARSER_CONFIGURE_BUNDLED)
-  INCLUDE_DIRECTORIES(${FUNCTIONPARSER_FOLDER})
+  SET(FUNCTIONPARSER_BUNDLED_INCLUDE_DIRS ${FUNCTIONPARSER_FOLDER})
 ENDMACRO()
 
 
index 81e71ceffa7bf9b83ce5166fd3c8abbe3c5288a7..5dd027d482929c502f76e73fcd242dd18d55b1ec 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -47,10 +47,10 @@ MACRO(FEATURE_HDF5_FIND_EXTERNAL var)
 ENDMACRO()
 
 
+CONFIGURE_FEATURE(HDF5)
+
+
 #
 # The user has to know the location of the hdf5 headers as well:
 #
-SET(HDF5_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
-CONFIGURE_FEATURE(HDF5)
+SET(HDF5_USER_INCLUDE_DIRS ${HDF5_INCLUDE_DIRS})
index 4022f98026856d9e501ce4a5827f408042cfec91..a02e94d0b97d6e5856ac254e580a622e494d74e3 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
 SET(FEATURE_MUMPS_DEPENDS DEAL_II_WITH_MPI DEAL_II_WITH_LAPACK)
 
 
+CONFIGURE_FEATURE(MUMPS)
+
 #
 # The user has to know the location of the MUMPS headers as well:
 #
-SET(MUMPS_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
-CONFIGURE_FEATURE(MUMPS)
+SET(MUMPS_USER_INCLUDE_DIRS ${MUMPS_INCLUDE_DIRS})
index 4055c0f30cf494a5ca73e930b73fbec2fac8a737..a54643b60cd34f3566206f6d882e87037742e985 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -75,10 +75,9 @@ MACRO(FEATURE_P4EST_FIND_EXTERNAL var)
 ENDMACRO()
 
 
+CONFIGURE_FEATURE(P4EST)
+
 #
 # The user has to know the location of the P4est headers as well:
 #
-SET(P4EST_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
-CONFIGURE_FEATURE(P4EST)
+SET(P4EST_USER_INCLUDE_DIRS ${P4EST_INCLUDE_DIRS})
index fdb87649d01d34fe8a763dd928739d71e41df61c..a4b97958fc6323c706107c04a5171efad9035513 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -58,12 +58,6 @@ MACRO(FEATURE_SLEPC_FIND_EXTERNAL var)
 ENDMACRO()
 
 
-#
-# The user has to know the location of the SLEPC headers as well:
-#
-SET(SLEPC_ADD_TO_USER_INCLUDE_DIRS TRUE)
-
-
 MACRO(FEATURE_SLEPC_ERROR_MESSAGE)
   MESSAGE(FATAL_ERROR "\n"
     "Could not find the SLEPc library!\n"
@@ -84,3 +78,8 @@ ENDMACRO()
 
 
 CONFIGURE_FEATURE(SLEPC)
+
+#
+# The user has to know the location of the SLEPC headers as well:
+#
+SET(SLEPC_USER_INCLUDE_DIRS ${SLEPC_INCLUDE_DIRS})
index 240e2bfa0d8f5a215832fd1089c7f1eb5273f372..219ab2f40586488d2832a9a5bab6203ff71cb5c6 100644 (file)
@@ -209,6 +209,7 @@ MACRO(CONFIGURE_FEATURE _feature)
         IF(FEATURE_${_feature}_HAVE_BUNDLED)
           RUN_COMMAND("FEATURE_${_feature}_CONFIGURE_BUNDLED()")
           MESSAGE(STATUS "DEAL_II_WITH_${_feature} successfully set up with bundled packages.")
+          LIST(APPEND DEAL_II_FEATURES ${_feature})
           SET(FEATURE_${_feature}_BUNDLED_CONFIGURED TRUE)
           SET_CACHED_OPTION(${_feature} ON)
         ELSE()
@@ -233,11 +234,10 @@ MACRO(CONFIGURE_FEATURE _feature)
 
           IF(COMMAND FEATURE_${_feature}_CONFIGURE_EXTERNAL)
             RUN_COMMAND("FEATURE_${_feature}_CONFIGURE_EXTERNAL()")
-          ELSE()
-            REGISTER_FEATURE(${_feature})
           ENDIF()
 
           MESSAGE(STATUS "DEAL_II_WITH_${_feature} successfully set up with external dependencies.")
+          LIST(APPEND DEAL_II_FEATURES ${_feature})
           SET(FEATURE_${_feature}_EXTERNAL_CONFIGURED TRUE)
           SET_CACHED_OPTION(${_feature} ON)
 
@@ -247,9 +247,12 @@ MACRO(CONFIGURE_FEATURE _feature)
 
           IF(FEATURE_${_feature}_HAVE_BUNDLED AND DEAL_II_ALLOW_BUNDLED)
             RUN_COMMAND("FEATURE_${_feature}_CONFIGURE_BUNDLED()")
+
             MESSAGE(STATUS "DEAL_II_WITH_${_feature} successfully set up with bundled packages.")
+            LIST(APPEND DEAL_II_FEATURES ${_feature})
             SET(FEATURE_${_feature}_BUNDLED_CONFIGURED TRUE)
             SET_CACHED_OPTION(${_feature} ON)
+
           ELSE()
             IF(DEAL_II_WITH_${_feature})
               IF(COMMAND FEATURE_${_feature}_ERROR_MESSAGE)
index 8efacf6dfe5b3c91c08a5348fd9ee1d8e244230c..19d4883aaeb4713583e1e5787c0aacd1f9e83862 100644 (file)
@@ -39,7 +39,7 @@ MACRO(DEAL_II_ADD_LIBRARY _library)
       )
 
     SET_TARGET_PROPERTIES(${_library}.${_build_lowercase} PROPERTIES
-      LINK_FLAGS "${DEAL_II_LINKER_FLAGS};${DEAL_II_LINKER_FLAGS_${_build}}"
+      LINK_FLAGS "${DEAL_II_LINKER_FLAGS} ${DEAL_II_LINKER_FLAGS_${_build}}"
       COMPILE_DEFINITIONS "${DEAL_II_DEFINITIONS};${DEAL_II_DEFINITIONS_${_build}}"
       COMPILE_FLAGS "${DEAL_II_CXX_FLAGS} ${DEAL_II_CXX_FLAGS_${_build}}"
       LINKER_LANGUAGE "CXX"
diff --git a/deal.II/cmake/macros/macro_filter_system_libraries.cmake b/deal.II/cmake/macros/macro_filter_system_libraries.cmake
new file mode 100644 (file)
index 0000000..49b4e75
--- /dev/null
@@ -0,0 +1,43 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2014 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# This macro replaces absolute paths to system libraries with the
+# corresponding short name within the FEATURE_LIBRARIES(|_DEBUG|_RELEASE)
+# variables
+#
+# Usage:
+#     FILTER_SYSTEM_LIBRARIES(feature)
+#
+
+MACRO(FILTER_SYSTEM_LIBRARIES _feature)
+  FOREACH(_variable
+    ${_feature}_LIBRARIES
+    ${_feature}_LIBRARIES_DEBUG
+    ${_feature}_LIBRARIES_RELEASE
+    )
+    IF(DEFINED ${_variable})
+      SET(_tmp_${_variable} ${${_variable}})
+      SET(${_variable} "")
+      FOREACH(_lib ${_tmp_${_variable}})
+        IF(_lib MATCHES "lib(c|quadmath|gfortran|m|rt|nsl|dl|pthread).so$")
+          string(REGEX REPLACE ".*lib([a-z]+).so$" "\\1" _lib ${_lib})
+        ENDIF()
+        LIST(APPEND ${_variable} ${_lib})
+      ENDFOREACH()
+    ENDIF()
+  ENDFOREACH()
+ENDMACRO()
diff --git a/deal.II/cmake/macros/macro_find_system_library.cmake b/deal.II/cmake/macros/macro_find_system_library.cmake
new file mode 100644 (file)
index 0000000..eda5e4a
--- /dev/null
@@ -0,0 +1,50 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2013 - 2014 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Search for a system library. In contrast to normal libraries we do this
+# purely via "-l<library name>" instead of selecting a full library path..
+#
+# USAGE:
+#   FIND_SYSTEM_LIBRARY(variable NAMES [list of possible names])
+#
+
+MACRO(FIND_SYSTEM_LIBRARY)
+  SET(_argn ${ARGN})
+  LIST(GET _argn 0 _variable)
+  LIST(REMOVE_AT _argn 0 1)
+
+  if("${_variable}" MATCHES "^${_variable}$")
+    FOREACH(_arg ${_argn})
+      LIST(APPEND CMAKE_REQUIRED_LIBRARIES "-l${_arg}")
+      CHECK_CXX_COMPILER_FLAG("" ${_variable})
+      RESET_CMAKE_REQUIRED()
+
+      IF(${_variable})
+        UNSET(${_variable} CACHE)
+        SET(${_variable} ${_arg} CACHE STRING "A system library.")
+        SET(${_variable} ${_arg})
+        BREAK()
+      ELSE()
+        UNSET(${_variable} CACHE)
+      ENDIF()
+    ENDFOREACH()
+
+    IF(NOT _variable)
+      SET(${_variable} "${_variable}-NOTFOUND")
+    ENDIF()
+  ENDIF()
+ENDMACRO()
index 5c590280ee058f379a1cdd164a12271e7addf5ed..1f6ed329a0c612bae2f15972b3155174ee738ce2 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2013 by the deal.II authors
+## Copyright (C) 2013 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -24,9 +24,9 @@
 #
 # This macro will add
 #
-#   <FEATURE>_LIBRARIES
-#   <FEATURE>_INCLUDE_DIRS(|_DEBUG|_RELEASE)
-#   <FEATURE>_USER_INCLUDE_DIRS(|_DEBUG|_RELEASE)
+#   <FEATURE>_LIBRARIES (respecting general, optimized, debug keyword)
+#   <FEATURE>_LIBRARIES(_DEBUG|_RELEASE)
+#   <FEATURE>_(|BUNDLED_|USER_)INCLUDE_DIRS
 #   <FEATURE>_DEFINITIONS(|_DEBUG|_RELEASE)
 #   <FEATURE>_USER_DEFINITIONS(|_DEBUG|_RELEASE)
 #   <FEATURE>_CXX_FLAGS(|_DEBUG|_RELEASE)
 # to the corresponding DEAL_II_* variables
 #
 
-
 MACRO(REGISTER_FEATURE _feature)
-  # variables for include directories:
-  FOREACH(_var ${_feature}_INCLUDE_DIRS ${_feature}_INCLUDE_PATH)
-    IF(DEFINED ${_var})
-      INCLUDE_DIRECTORIES(${${_var}})
-      IF(${_feature}_ADD_TO_USER_INCLUDE_DIRS)
-        LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${${_var}})
-      ENDIF()
-    ENDIF()
-  ENDFOREACH()
-
-  # variables for linker flags:
-  FOREACH(_var ${_feature}_LINKER_FLAGS ${_feature}_LINK_FLAGS)
-    IF(DEFINED ${_var})
-      ADD_FLAGS(DEAL_II_LINKER_FLAGS "${${_var}}")
-    ENDIF()
-  ENDFOREACH()
-
-  # variables for compiler flags:
-  FOREACH(_var ${_feature}_CXX_FLAGS ${_feature}_COMPILE_FLAGS)
-    IF(DEFINED ${_var})
-      ADD_FLAGS(DEAL_II_CXX_FLAGS "${${_var}}")
-    ENDIF()
-  ENDFOREACH()
 
   IF(DEFINED ${_feature}_LIBRARIES)
     #
     # Add ${_feature}_LIBRARIES to
-    #   DEAL_II_EXTERNAL_LIBRARIES
-    #   DEAL_II_EXTERNAL_LIBRARIES_DEBUG
-    #   DEAL_II_EXTERNAL_LIBRARIES_RELEASE
+    #   DEAL_II_LIBRARIES
+    #   DEAL_II_LIBRARIES_DEBUG
+    #   DEAL_II_LIBRARIES_RELEASE
     # depending on the "optmized", "debug" or "general" keyword
     #
     SET(_toggle "general")
@@ -77,14 +53,34 @@ MACRO(REGISTER_FEATURE _feature)
         SET(_toggle "${_tmp}")
       ELSE()
         IF("${_toggle}" STREQUAL "general")
-          LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES ${_tmp})
+          LIST(APPEND DEAL_II_LIBRARIES ${_tmp})
         ELSEIF("${_toggle}" STREQUAL "debug")
-          LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_DEBUG ${_tmp})
+          LIST(APPEND DEAL_II_LIBRARIES_DEBUG ${_tmp})
         ELSEIF("${_toggle}" STREQUAL "optimized")
-          LIST(APPEND DEAL_II_EXTERNAL_LIBRARIES_RELEASE ${_tmp})
+          LIST(APPEND DEAL_II_LIBRARIES_RELEASE ${_tmp})
         ENDIF()
       ENDIF()
     ENDFOREACH()
   ENDIF()
 
+  FOREACH(_var
+    LIBRARIES_DEBUG LIBRARIES_RELEASE
+    INCLUDE_DIRS BUNDLED_INCLUDE_DIRS USER_INCLUDE_DIRS
+    DEFINITIONS DEFINITIONS_DEBUG DEFINITIONS_RELEASE
+    USER_DEFINITIONS USER_DEFINITIONS_DEBUG USER_DEFINITIONS_RELEASE
+    )
+    IF(DEFINED ${_feature}_${_var})
+      LIST(APPEND DEAL_II_${_var} ${${_feature}_${_var}})
+    ENDIF()
+  ENDFOREACH()
+
+  FOREACH(_var
+    CXX_FLAGS CXX_FLAGS_DEBUG CXX_FLAGS_RELEASE
+    LINKER_FLAGS LINKER_FLAGS_DEBUG LINKER_FLAGS_RELEASE
+    )
+    IF(DEFINED ${_feature}_${_var})
+      ADD_FLAGS(DEAL_II_${_var} "${${_feature}_${_var}}")
+    ENDIF()
+  ENDFOREACH()
+
 ENDMACRO()
index 378851f71cfb5c35635711555746d343fba478da..b16cf25b137de1a19cb884de7abad7686b1a3a14 100644 (file)
@@ -50,18 +50,9 @@ FIND_PACKAGE(LAPACK)
 SET(CMAKE_PREFIX_PATH ${_cmake_prefix_path_backup})
 
 MARK_AS_ADVANCED(
-  atlas_LIBRARY
-  atlcblas_LIBRARY
-  atllapack_LIBRARY
-  blas_LIBRARY
-  eigen_blas_LIBRARY
-  f77blas_LIBRARY
-  gslcblas_LIBRARY
-  lapack_LIBRARY
-  m_LIBRARY
-  ptf77blas_LIBRARY
-  ptlapack_LIBRARY
-  refblas_LIBRARY
+  atlas_LIBRARY atlcblas_LIBRARY atllapack_LIBRARY blas_LIBRARY
+  eigen_blas_LIBRARY f77blas_LIBRARY gslcblas_LIBRARY lapack_LIBRARY
+  m_LIBRARY ptf77blas_LIBRARY ptlapack_LIBRARY refblas_LIBRARY
   reflapack_LIBRARY
   )
 
@@ -94,28 +85,19 @@ IF(LAPACK_FOUND)
   # If CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES is not available, do it
   # unconditionally for the most common case (gfortran).
   #
-  # 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.
-  #
   SET(_fortran_libs ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES})
   SET_IF_EMPTY(_fortran_libs gfortran m quadmath c)
 
-  SWITCH_LIBRARY_PREFERENCE()
   FOREACH(_lib ${_fortran_libs})
-    FIND_LIBRARY(${_lib}_LIBRARY
-      NAMES ${_lib}
-      HINTS
-        ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES}
-        ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
+    FIND_SYSTEM_LIBRARY(${_lib}_LIBRARY NAMES ${_lib})
     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()
 
   #
   # Filter out spurious "FALSE" in the library lists:
index 1a4f3122c4f2759dc9fcc5826536e222b9ea6d5c..df83255e4d98371a2608545a69317b454924452f 100644 (file)
@@ -123,13 +123,18 @@ IF(NOT PETSC_PETSCVARIABLES MATCHES "-NOTFOUND")
   # Link line:
   #
 
-  FILE(STRINGS "${PETSC_PETSCVARIABLES}" _external_link_line
+  FILE(STRINGS "${PETSC_PETSCVARIABLES}" PETSC_EXTERNAL_LINK_LINE
     REGEX "^PETSC_WITH_EXTERNAL_LIB =.*")
-  SEPARATE_ARGUMENTS(_external_link_line)
+  SEPARATE_ARGUMENTS(PETSC_EXTERNAL_LINK_LINE)
+
+  IF(NOT "${PETSC_EXTERNAL_LINK_LINE}" STREQUAL "${PETSC_EXTERNAL_LINK_LINE_SAVED}")
+    SET(_new_petsc_external_link_line TRUE)
+  ENDIF()
+  SET(PETSC_EXTERNAL_LINK_LINE_SAVED "${PETSC_EXTERNAL_LINK_LINE}" CACHE INTERNAL "" FORCE)
 
   SET(_hints)
   SET(_petsc_libraries)
-  FOREACH(_token ${_external_link_line}})
+  FOREACH(_token ${PETSC_EXTERNAL_LINK_LINE}})
     IF(_token MATCHES "^-L")
       # Build up hints with the help of all tokens passed with -L:
       STRING(REGEX REPLACE "^-L" "" _token "${_token}")
@@ -137,7 +142,17 @@ IF(NOT PETSC_PETSCVARIABLES MATCHES "-NOTFOUND")
     ELSEIF(_token MATCHES "^-l")
       # Search for every library that was specified with -l:
       STRING(REGEX REPLACE "^-l" "" _token "${_token}")
-      IF(NOT _token MATCHES "(petsc|stdc\\+\\+|gcc_s)")
+
+      IF(_new_petsc_external_link_line)
+        UNSET(PETSC_LIBRARY_${_token} CACHE)
+      ENDIF()
+
+      IF(_token MATCHES "^(c|quadmath|gfortran|m|rt|nsl|dl|pthread)$")
+        FIND_SYSTEM_LIBRARY(PETSC_LIBRARY_${_token} NAMES ${_token})
+        IF(NOT PETSC_LIBRARY_${_token} MATCHES "-NOTFOUND")
+          LIST(APPEND _petsc_libraries ${PETSC_LIBRARY_${_token}})
+        ENDIF()
+      ELSEIF(NOT _token MATCHES "(petsc|stdc\\+\\+|gcc_s)")
         FIND_LIBRARY(PETSC_LIBRARY_${_token}
           NAMES ${_token}
           HINTS ${_hints}
@@ -145,19 +160,13 @@ IF(NOT PETSC_PETSCVARIABLES MATCHES "-NOTFOUND")
         IF(NOT PETSC_LIBRARY_${_token} MATCHES "-NOTFOUND")
           LIST(APPEND _petsc_libraries ${PETSC_LIBRARY_${_token}})
         ENDIF()
-        #
-        # Remove from cache, so that updating PETSC search paths will
-        # find a (possibly) new link interface
-        #
-        UNSET(PETSC_LIBRARY_${_token} CACHE)
       ENDIF()
+
     ENDIF()
   ENDFOREACH()
 
 ENDIF()
 
-
-
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PETSC DEFAULT_MSG
   PETSC_LIBRARY
   PETSC_INCLUDE_DIR_ARCH
index 877e550f65487b6326f5af1d759ae5d5f3979b78..b6526cf4a3afc9834f1288107c60c78284b675d8 100644 (file)
@@ -51,10 +51,10 @@ FIND_PACKAGE(TRILINOS_CONFIG
   NO_SYSTEM_ENVIRONMENT_PATH
   )
 
-IF(NOT "${TRILINOS_CONFIG}" STREQUAL "${TRILINOS_CONFIG_SAVED}")
+IF(NOT "${TRILINOS_CONFIG_DIR}" STREQUAL "${TRILINOS_CONFIG_DIR_SAVED}")
   SET(_new_trilinos_config TRUE)
 ENDIF()
-SET(TRILINOS_CONFIG_SAVED "${TRILINOS_CONFIG}" CACHE INTERNAL "" FORCE)
+SET(TRILINOS_CONFIG_DIR_SAVED "${TRILINOS_CONFIG_DIR}" CACHE INTERNAL "" FORCE)
 
 
 #
@@ -204,17 +204,15 @@ IF(TRILINOS_FOUND)
     "
     TRILINOS_HAS_C99_TR1_WORKAROUND
     )
-
   RESET_CMAKE_REQUIRED()
 
-
   MARK_AS_ADVANCED(TRILINOS_DIR)
 
 ELSE()
 
   SET(TRILINOS_LIBRARIES)
   SET(TRILINOS_INCLUDE_DIRS)
-  SET(TRILINOS_CONFIG_SAVED "" CACHE INTERNAL "" FORCE)
+  UNSET(TRILINOS_CONFIG_DIR_SAVED CACHE)
 
   SET(TRILINOS_DIR "" CACHE PATH
     "An optional hint to a Trilinos installation"
index 71f9361e1ad0245ed135e38d759eda0a456b3918..b4048cf40d015ae015bb643b419f4c708c95fca1 100644 (file)
@@ -105,6 +105,20 @@ FIND_UMFPACK_LIBRARY(CCOLAMD ccolamd)
 FIND_UMFPACK_LIBRARY(CAMD camd)
 FIND_UMFPACK_LIBRARY(SuiteSparse_config suitesparseconfig)
 
+#
+# Test whether libsuitesparseconfig.xxx can be used for shared library
+# linkage. If not, exclude it from the command line.
+#
+LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+  "-shared"
+  ${SuiteSparse_config_LIBRARY}
+  )
+CHECK_CXX_SOURCE_COMPILES("extern int SuiteSparse_version (int[3]);
+  void foo(int bar[3]) { SuiteSparse_version(bar);}"
+  LAPACK_SUITESPARSECONFIG_WITH_PIC
+  )
+RESET_CMAKE_REQUIRED()
+
 IF(EXISTS ${UMFPACK_INCLUDE_DIR}/umfpack.h)
   FILE(STRINGS "${UMFPACK_INCLUDE_DIR}/umfpack.h" UMFPACK_VERSION_MAJOR_STRING
     REGEX "#define.*UMFPACK_MAIN_VERSION")
@@ -161,8 +175,10 @@ IF(UMFPACK_FOUND)
     ${COLAMD_LIBRARY}
     ${CAMD_LIBRARY}
     ${AMD_LIBRARY}
-    ${SuiteSparse_config_LIBRARY}
     )
+  IF(LAPACK_SUITESPARSECONFIG_WITH_PIC OR NOT BUILD_SHARED_LIBS)
+    LIST(APPEND UMFPACK_LIBRARIES ${SuiteSparse_config_LIBRARY})
+  ENDIF()
 
   #
   # For good measure:
@@ -179,9 +195,7 @@ IF(UMFPACK_FOUND)
   # lib does not record its dependence on librt.so as evidenced
   # by ldd :-( ):
   #
-  SWITCH_LIBRARY_PREFERENCE()
-  FIND_LIBRARY(rt_LIBRARY NAMES rt)
-  SWITCH_LIBRARY_PREFERENCE()
+  FIND_SYSTEM_LIBRARY(rt_LIBRARY NAMES rt)
   MARK_AS_ADVANCED(rt_LIBRARY)
   IF(NOT rt_LIBRARY MATCHES "-NOTFOUND")
     LIST(APPEND UMFPACK_LIBRARIES ${rt_LIBRARY})
index d8eb42447c764bd98f3f0d76be0c11405581dbac..0514c8f62484aeb307ba1c9601699bcec8e67ca1 100644 (file)
 # Check the user provided CXX flags:
 #
 
-IF( NOT "${DEAL_II_CXX_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_CXX_FLAGS_SAVED}"
-    OR NOT "${DEAL_II_LINKER_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_LINKER_FLAGS_SAVED}")
+IF(NOT "${DEAL_II_CXX_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_CXX_FLAGS_SAVED}"
+   OR NOT "${DEAL_II_LINKER_FLAGS_SAVED}" STREQUAL "${CACHED_DEAL_II_LINKER_FLAGS_SAVED}")
   MESSAGE(STATUS "")
   # Rerun this test if cxx flags changed:
   UNSET(DEAL_II_HAVE_USABLE_CXX_FLAGS CACHE)
+ELSE()
+  SET(DEAL_II_HAVE_USABLE_CXX_FLAGS TRUE CACHE INTERNAL "")
 ENDIF()
 SET(CACHED_DEAL_II_CXX_FLAGS_SAVED "${DEAL_II_CXX_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
 SET(CACHED_DEAL_II_LINKER_FLAGS_SAVED "${DEAL_II_LINKER_FLAGS_SAVED}" CACHE INTERNAL "" FORCE)
index 4baa99b615ce32d0fb6ea961ca692a2f566937d3..22e0d65c08dc0b4db41a7089cbcde1a8cb283857 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2012 - 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -38,7 +38,7 @@ ENDFOREACH()
 
 #
 # Sanity check: The variables defined in DEAL_II_REMOVED_FLAGS must not be
-# used during the comfiguration stage:
+# used during the configuration stage:
 #
 FOREACH(_flag ${DEAL_II_REMOVED_FLAGS})
   IF(NOT "${_flag}" STREQUAL "")
@@ -52,18 +52,48 @@ FOREACH(_flag ${DEAL_II_REMOVED_FLAGS})
 ENDFOREACH()
 
 #
-# Deduplicate entries in DEAL_II_USER_INCLUDE_DIRS
+# Deduplicate entries in *_INCLUDE_DIRS and *_LIBRARIES
 #
-REMOVE_DUPLICATES(DEAL_II_USER_INCLUDE_DIRS)
+FOREACH(_feature DEAL_II ${DEAL_II_FEATURES})
+  FOREACH(_suffix INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS)
+    REMOVE_DUPLICATES(${_feature}_${_suffix})
+  ENDFOREACH()
+  FOREACH(_suffix LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG)
+    REMOVE_DUPLICATES(${_feature}_${_suffix} REVERSE)
+  ENDFOREACH()
+ENDFOREACH()
 
 #
-# Deduplicate entries in DEAL_II_EXTERNAL_LIBRARIES(_...)
-# in reverse order:
+# Save base configuration into variables BASE_* for later use in
+# setup_write_config.cmake:
 #
-REMOVE_DUPLICATES(DEAL_II_EXTERNAL_LIBRARIES REVERSE)
+FOREACH(_suffix
+  CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG
+  DEFINITIONS DEFINITIONS_RELEASE DEFINITIONS_DEBUG
+  USER_DEFINITIONS USER_DEFINITIONS_RELEASE USER_DEFINITIONS_DEBUG
+  LINKER_FLAGS LINKER_FLAGS_RELEASE LINKER_FLAGS_DEBUG
+  INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS
+  LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG
+  )
+  SET(BASE_${_suffix} ${DEAL_II_${_suffix}})
+ENDFOREACH()
 
-FOREACH(_build ${DEAL_II_BUILD_TYPES})
-  REMOVE_DUPLICATES(DEAL_II_EXTERNAL_LIBRARIES_${_build} REVERSE)
+#
+# Register features:
+#
+FOREACH(_feature ${DEAL_II_FEATURES})
+  FILTER_SYSTEM_LIBRARIES(${_feature})
+  REGISTER_FEATURE(${_feature})
+ENDFOREACH()
+
+#
+# Deduplicate entries one more time :-]
+#
+FOREACH(_suffix INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS)
+  REMOVE_DUPLICATES(DEAL_II_${_suffix})
+ENDFOREACH()
+FOREACH(_suffix LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG)
+  REMOVE_DUPLICATES(DEAL_II_${_suffix} REVERSE)
 ENDFOREACH()
 
 #
@@ -78,15 +108,10 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
     ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_${_build_lowercase}
     )
 ENDFOREACH()
-FILE(WRITE
-  ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_source_includes
-  ""
-  )
 
 #
 # Cleanup deal.IITargets.cmake in the build directory:
 #
-FILE(WRITE
+FILE(REMOVE
   ${CMAKE_BINARY_DIR}/${DEAL_II_PROJECT_CONFIG_RELDIR}/${DEAL_II_PROJECT_CONFIG_NAME}Targets.cmake
-  ""
   )
diff --git a/deal.II/cmake/setup_sanity_checks.cmake b/deal.II/cmake/setup_sanity_checks.cmake
new file mode 100644 (file)
index 0000000..f8091b7
--- /dev/null
@@ -0,0 +1,72 @@
+## ---------------------------------------------------------------------
+## $Id$
+##
+## Copyright (C) 2014 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+
+########################################################################
+#                                                                      #
+#                            Sanity checks:                            #
+#                                                                      #
+########################################################################
+
+#
+# A quick test whether we're able to successfully link with the given
+# compiler and linker flags and the given library link interface:
+#
+
+MESSAGE(STATUS "")
+MESSAGE(STATUS "Sanity checks.")
+
+FOREACH(_build ${DEAL_II_BUILD_TYPES})
+
+  FOREACH(_var
+    CXX_FLAGS CXX_FLAGS_${_build}
+    LINKER_FLAGS LINKER_FLAGS_${_build}
+    LIBRARIES LIBRARIES_${_build}
+    )
+    IF(NOT "${DEAL_II_${_var}}" STREQUAL "${CACHED_DEAL_II_${_var}_${_build}}")
+      UNSET(DEAL_II_SANITY_CHECK_${_build} CACHE)
+      SET(CACHED_DEAL_II_${_var}_${_build} "${DEAL_II_${_var}}" CACHE INTERNAL "" FORCE)
+    ENDIF()
+  ENDFOREACH()
+
+  RESET_CMAKE_REQUIRED()
+  ADD_FLAGS(CMAKE_REQUIRED_FLAGS
+    "${DEAL_II_CXX_FLAGS} ${DEAL_II_CXX_FLAGS_${_build}}"
+    )
+  LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+    "${DEAL_II_LINKER_FLAGS} ${DEAL_II_CXX_LINKER_${_build}}"
+    )
+  LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+    ${DEAL_II_LIBRARIES}
+    ${DEAL_II_LIBRARIES_${_build}}
+    )
+  CHECK_CXX_SOURCE_COMPILES("int main(){ return 0; }"
+    DEAL_II_SANITY_CHECK_${_build}
+    )
+  RESET_CMAKE_REQUIRED()
+
+  IF(NOT DEAL_II_SANITY_CHECK_${_build})
+    UNSET(DEAL_II_SANITY_CHECK_${_build} CACHE)
+    MESSAGE(FATAL_ERROR "
+  Configuration error: Cannot compile and link with the current set of
+  compiler flags, linker flags and libraries!
+
+  Please check the test output given at the end of
+  CMakeFiles/CMakeError.log and consult detailed.log for the current
+  configuration.\n\n"
+    )
+  ENDIF()
+ENDFOREACH()
index f3062a3907d2013bef518e9ed44ccc5ab2a7eee2..1afca5ff200c8780d04d343661f0e20799d92e4b 100644 (file)
@@ -1,7 +1,7 @@
 ## ---------------------------------------------------------------------
 ## $Id$
 ##
-## Copyright (C) 2012 - 2013 by the deal.II authors
+## Copyright (C) 2014 by the deal.II authors
 ##
 ## This file is part of the deal.II library.
 ##
@@ -76,31 +76,51 @@ ENDIF()
 _both("#\n")
 
 _detailed(
-"#  Compiler flags used for this build:
-#        DEAL_II_CXX_FLAGS:            ${DEAL_II_CXX_FLAGS}
+"#  Base configuration (prior to feature configuration):
+#        DEAL_II_CXX_FLAGS:            ${BASE_CXX_FLAGS}
 "
   )
 IF(CMAKE_BUILD_TYPE MATCHES "Release")
-  _detailed("#        DEAL_II_CXX_FLAGS_RELEASE:    ${DEAL_II_CXX_FLAGS_RELEASE}\n")
+  _detailed("#        DEAL_II_CXX_FLAGS_RELEASE:    ${BASE_CXX_FLAGS_RELEASE}\n")
 ENDIF()
 IF(CMAKE_BUILD_TYPE MATCHES "Debug")
-  _detailed("#        DEAL_II_CXX_FLAGS_DEBUG:      ${DEAL_II_CXX_FLAGS_DEBUG}\n")
+  _detailed("#        DEAL_II_CXX_FLAGS_DEBUG:      ${BASE_CXX_FLAGS_DEBUG}\n")
 ENDIF()
 
-_detailed("#        DEAL_II_LINKER_FLAGS:         ${DEAL_II_LINKER_FLAGS}\n")
+_detailed("#        DEAL_II_LINKER_FLAGS:         ${BASE_LINKER_FLAGS}\n")
 IF(CMAKE_BUILD_TYPE MATCHES "Release")
-  _detailed("#        DEAL_II_LINKER_FLAGS_RELEASE: ${DEAL_II_LINKER_FLAGS_RELEASE}\n")
+  _detailed("#        DEAL_II_LINKER_FLAGS_RELEASE: ${BASE_LINKER_FLAGS_RELEASE}\n")
 ENDIF()
 IF(CMAKE_BUILD_TYPE MATCHES "Debug")
-  _detailed("#        DEAL_II_LINKER_FLAGS_DEBUG:   ${DEAL_II_LINKER_FLAGS_DEBUG}\n")
+  _detailed("#        DEAL_II_LINKER_FLAGS_DEBUG:   ${BASE_LINKER_FLAGS_DEBUG}\n")
 ENDIF()
 
-_detailed("#        DEAL_II_DEFINITIONS:          ${DEAL_II_DEFINITIONS}\n")
+_detailed("#        DEAL_II_DEFINITIONS:          ${BASE_DEFINITIONS}\n")
 IF(CMAKE_BUILD_TYPE MATCHES "Release")
-  _detailed("#        DEAL_II_DEFINITIONS_RELEASE:  ${DEAL_II_DEFINITIONS_RELEASE}\n")
+  _detailed("#        DEAL_II_DEFINITIONS_RELEASE:  ${BASE_DEFINITIONS_RELEASE}\n")
 ENDIF()
 IF(CMAKE_BUILD_TYPE MATCHES "Debug")
-  _detailed("#        DEAL_II_DEFINITIONS_DEBUG:    ${DEAL_II_DEFINITIONS_DEBUG}\n")
+  _detailed("#        DEAL_II_DEFINITIONS_DEBUG:    ${BASE_DEFINITIONS_DEBUG}\n")
+ENDIF()
+
+_detailed("#        DEAL_II_USER_DEFINITIONS:     ${BASE_DEFINITIONS}\n")
+IF(CMAKE_BUILD_TYPE MATCHES "Release")
+  _detailed("#        DEAL_II_USER_DEFINITIONS_REL: ${BASE_DEFINITIONS_RELEASE}\n")
+ENDIF()
+IF(CMAKE_BUILD_TYPE MATCHES "Debug")
+  _detailed("#        DEAL_II_USER_DEFINITIONS_DEB: ${BASE_DEFINITIONS_DEBUG}\n")
+ENDIF()
+
+_detailed("#        DEAL_II_INCLUDE_DIRS          ${BASE_INCLUDE_DIRS}\n")
+_detailed("#        DEAL_II_USER_INCLUDE_DIRS:    ${BASE_USER_INCLUDE_DIRS}\n")
+_detailed("#        DEAL_II_BUNDLED_INCLUDE_DIRS: ${BASE_BUNDLED_INCLUDE_DIRS}\n")
+
+_detailed("#        DEAL_II_LIBRARIES:            ${BASE_LIBRARIES}\n")
+IF(CMAKE_BUILD_TYPE MATCHES "Release")
+  _detailed("#        DEAL_II_LIBRARIES_RELEASE:    ${BASE_LIBRARIES_RELEASE}\n")
+ENDIF()
+IF(CMAKE_BUILD_TYPE MATCHES "Debug")
+  _detailed("#        DEAL_II_LIBRARIES_DEBUG:      ${BASE_LIBRARIES_DEBUG}\n")
 ENDIF()
 
 _detailed("#\n")
@@ -134,50 +154,14 @@ ENDFOREACH()
 
 FOREACH(_var ${_features})
   IF(${${_var}})
-    # FEATURE is enabled
+
+    #
+    # The feature is enabled:
+    #
     STRING(REGEX REPLACE "^DEAL_II_WITH_" "" _feature ${_var})
     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()
-
-      #
-      # Special version numbers:
-      #
-      IF(_feature MATCHES "THREADS" AND DEFINED TBB_VERSION)
-        _detailed("#            TBB_VERSION = ${TBB_VERSION}\n")
-      ENDIF()
-      IF(_feature MATCHES "MPI" AND DEFINED OMPI_VERSION)
-        _detailed("#            OMPI_VERSION = ${OMPI_VERSION}\n")
-      ENDIF()
-
-      #
-      # Print out ${_feature}_DIR:
-      #
-      IF(NOT "${${_feature}_DIR}" STREQUAL "")
-        _detailed("#            ${_feature}_DIR = ${${_feature}_DIR}\n")
-      ENDIF()
-
-      #
-      # Print the feature configuration:
-      #
-      FOREACH(_var2
-          CXX_COMPILER C_COMPILER Fortran_COMPILER LIBRARIES INCLUDE_DIRS
-          USER_INCLUDE_DIRS DEFINITIONS USER_DEFINITIONS CXX_FLAGS
-          LINKER_FLAGS
-        )
-        IF(DEFINED ${_feature}_${_var2})
-          _detailed("#            ${_feature}_${_var2} = ${${_feature}_${_var2}}\n")
-        ENDIF()
-      ENDFOREACH()
-
     ELSEIF(FEATURE_${_feature}_BUNDLED_CONFIGURED)
-
       IF(DEAL_II_FORCE_BUNDLED_${_feature})
         _both("#        ${_var} set up with bundled packages (forced)\n")
       ELSE()
@@ -186,6 +170,47 @@ FOREACH(_var ${_features})
     ELSE()
      _both("#        ${_var} = ${${_var}}\n")
     ENDIF()
+
+    #
+    # Print out version number:
+    #
+    IF(DEFINED ${_feature}_VERSION)
+      _detailed("#            ${_feature}_VERSION = ${${_feature}_VERSION}\n")
+    ENDIF()
+
+    #
+    # Special version numbers:
+    #
+    IF(_feature MATCHES "THREADS" AND DEFINED TBB_VERSION)
+      _detailed("#            TBB_VERSION = ${TBB_VERSION}\n")
+    ENDIF()
+    IF(_feature MATCHES "MPI" AND DEFINED OMPI_VERSION)
+      _detailed("#            OMPI_VERSION = ${OMPI_VERSION}\n")
+    ENDIF()
+
+    #
+    # Print out ${_feature}_DIR:
+    #
+    IF(NOT "${${_feature}_DIR}" STREQUAL "")
+      _detailed("#            ${_feature}_DIR = ${${_feature}_DIR}\n")
+    ENDIF()
+
+    #
+    # Print the feature configuration:
+    #
+    FOREACH(_var2
+        C_COMPILER CXX_COMPILER Fortran_COMPILER
+        CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG
+        DEFINITIONS DEFINITIONS_RELEASE DEFINITIONS_DEBUG
+        USER_DEFINITIONS USER_DEFINITIONS_RELEASE USER_DEFINITIONS_DEBUG
+        LINKER_FLAGS LINKER_FLAGS_RELEASE LINKER_FLAGS_DEBUG
+        INCLUDE_DIRS USER_INCLUDE_DIRS BUNDLED_INCLUDE_DIRS
+        LIBRARIES LIBRARIES_RELEASE LIBRARIES_DEBUG
+      )
+      IF(DEFINED ${_feature}_${_var2})
+        _detailed("#            ${_feature}_${_var2} = ${${_feature}_${_var2}}\n")
+      ENDIF()
+    ENDFOREACH()
   ELSE()
     # FEATURE is disabled
     _both("#      ( ${_var} = ${${_var}} )\n")
index 3517b168bb8868ad7903d2a031a4a847f62aba40..48146dc0c2f60dda763d62427389d3f8f7570ca3 100644 (file)
@@ -343,18 +343,19 @@ RESET_CMAKE_REQUIRED()
       <code>FATAL_ERROR</code> must be avoided (the only exception is
       the <code>REQUIRED</code> keyword).
     <li>
-      If successful, the following uncached variables might be set:
-
+      If the feature is successfully found, a subset of the following
+      <b>uncached</b> variables might be set:
 <pre>
 FEATURE_FOUND
-FEATURE_LIBRARIES
+FEATURE_LIBRARIES (with optimized, debug, release keywords)
+FEATURE_LIBRARIES(_DEBUG|_RELEASE)
 FEATURE_INCLUDE_DIRS
-FEATURE_LINKER_FLAGS
+FEATURE_LINKER_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_CXX_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_DEFINITIONS(|_DEBUG|_RELEASE)
 
 FEATURE_VERSION
-FEATURE_VERSION_MAJOR
-FEATURE_VERSION_MINOR
-FEATURE_VERSION_SUBMINOR
+FEATURE_VERSION(_MAJOR|_MINOR|_SUBMINOR)
 </pre>
 
 There are obviously valid exceptions from this rule, though.
@@ -363,6 +364,11 @@ There are obviously valid exceptions from this rule, though.
       "global" variables prefixed by <code>FEATURE_</code> may be
       altered. Do not set <code>DEAL_II_*</code> or <code>CMAKE_*</code>
       variables directly!
+
+    <li>
+      The find module must define a macro <code>FEATURE_CLEAR</code> that
+      unsets all cached variables, so that a subsequent call to the find
+      module starts a completely fresh features search.
     <li>
       A hint with <code>FEATURE_DIR</code> can be set up for
       convenience. It is best to start the <code>Find</code> module by
@@ -400,11 +406,15 @@ SET(FEATURE_DIR "" CACHE PATH "An optional hint to a FEATURE directory")
   module is used to determine whether an external dependency can be
   resolved or not. Depending on the current state of
   <code>DEAL_II_WITH_&lt;FEATURE&gt;</code> (see
-  <a href="../users/cmake.html#configurefeature">here</a>) the variables
+  <a href="../users/cmake.html#configurefeature">here</a>) the
+  configuration variables
 <pre>
 FEATURE_LIBRARIES
-FEATURE_INCLUDE_DIRS
-FEATURE_LINKER_FLAGS
+FEATURE_LIBRARIES(|_DEBUG|_RELEASE)
+FEATURE_(|USER_|BUNDLED_)INCLUDE_DIRS
+FEATURE_LINKER_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_CXX_FLAGS(|_DEBUG|_RELEASE)
+FEATURE_DEFINITIONS(|_DEBUG|_RELEASE)
 </pre>
   are appended to the set of <a href="#variables">global variables</a>
   and <code>DEAL_II_WITH_&lt;FEATURE&gt;</code> is set to
@@ -458,7 +468,7 @@ FEATURE_&lt;FEATURE&gt;_ERROR_MESSAGE()      (macro)
 </pre>
 
     <li>
-      In <code>./bundled/CMakeLists.txt</code>:
+      In <code>./bundled/configure_bundled.cmake</code>:
 <pre>
 FEATURE_&lt;FEATURE&gt;_HAVE_BUNDLED         (a boolean)
   - which should either be set to TRUE if all necessary libraries of the
@@ -492,6 +502,15 @@ DEAL_II_FORCE_BUNDLED_&lt;FEATURE&gt;        (an option)
   <code>LIST(APPEND ...)</code>, flags with <code>ADD_FLAGS(...)</code>
   (or if it is necessary to guard them with
   <code>ENABLE_IF_SUPPORTED(...)</code>.)
+</p>
+<p>
+  <b>Feature configuration must not be added directly to this variables but
+    to corresponding <code>&lt;FEATURE&gt;_*</code> variables, instead.
+  Feature configuration variables get appended to the below list of global
+  configuration variables automatically.</b>
+</p>
+
+
   <ul>
     <li>
       The general (internal) logic for variables applies:
@@ -503,27 +522,32 @@ DEAL_II_FORCE_BUNDLED_&lt;FEATURE&gt;        (an option)
       </ul>
 
     <li>
-      For internal use, for setting necessary linker flags for the deal.II library:
+      For internal and external use, used to keep track of external
+      libraries, the <acronym>deal.II</acronym> library and user
+      programs have to be linked against:
       <ul>
-        <li> <code>DEAL_II_LINKER_FLAGS</code>
-        <li> <code>DEAL_II_LINKER_FLAGS_DEBUG</code>
-        <li> <code>DEAL_II_LINKER_FLAGS_RELEASE</code>
+        <li> <code>DEAL_II_LIBRARIES</code>
+        <li> <code>DEAL_II_LIBRARIES_DEBUG</code>
+        <li> <code>DEAL_II_LIBRARIES_RELEASE</code>
       </ul>
 
     <li>
-      For internal use, for setting necessary compiler flags, e.g.
-      <code>-std=c++11</code> (if available):
+      For internal use, for setting necessary include dirs for the compilation of the
+      <acronym>deal.II</acronym> library:
       <ul>
-        <li> <code>DEAL_II_CXX_FLAGS</code>
-        <li> <code>DEAL_II_CXX_FLAGS_DEBUG</code>
-        <li> <code>DEAL_II_CXX_FLAGS_RELEASE</code>
+        <li> <code>DEAL_II_INCLUDE_DIRS</code>
       </ul>
-
     <li>
-      For internal use, for setting necessary include dirs for the compilation of the
-      <acronym>deal.II</acronym> library:
+      Used to keep track of external include dirs, necessary for the
+      compilation of user programs:
       <ul>
-        <li> <code>INCLUDE_DIRECTORIES(...)</code>
+        <li> <code>DEAL_II_USER_INCLUDE_DIRS</code>
+      </ul>
+    <li>
+      Include dirs from bundled packages necessary for the compilation fo
+      the library and user projects out of the build directory:
+      <ul>
+        <li> <code>DEAL_II_BUNDLED_INCLUDE_DIRS</code>
       </ul>
 
     <li>
@@ -535,17 +559,6 @@ DEAL_II_FORCE_BUNDLED_&lt;FEATURE&gt;        (an option)
         <li> <code>DEAL_II_DEFINITIONS_DEBUG</code>
         <li> <code>DEAL_II_DEFINITIONS_RELEASE</code>
       </ul>
-
-    <li>
-      For internal and external use, used to keep track of external
-      libraries, the <acronym>deal.II</acronym> library and user
-      programs have to be linked against:
-      <ul>
-        <li> <code>DEAL_II_EXTERNAL_LIBRARIES</code>
-        <li> <code>DEAL_II_EXTERNAL_LIBRARIES_DEBUG</code>
-        <li> <code>DEAL_II_EXTERNAL_LIBRARIES_RELEASE</code>
-      </ul>
-
     <li>
       For external use, used to keep track of external preprocessor
       definitions, necessary for the compilation of user programs:
@@ -556,11 +569,22 @@ DEAL_II_FORCE_BUNDLED_&lt;FEATURE&gt;        (an option)
       </ul>
 
     <li>
-      Used to keep track of external include dirs, necessary for the
-      compilation of user programs:
+      For internal and external use, for setting necessary compiler flags,
+      e.g. <code>-std=c++11</code> (if available):
       <ul>
-        <li> <code>DEAL_II_USER_INCLUDE_DIRS</code>
+        <li> <code>DEAL_II_CXX_FLAGS</code>
+        <li> <code>DEAL_II_CXX_FLAGS_DEBUG</code>
+        <li> <code>DEAL_II_CXX_FLAGS_RELEASE</code>
       </ul>
+
+    <li>
+      For internal use, for setting necessary linker flags for the deal.II library:
+      <ul>
+        <li> <code>DEAL_II_LINKER_FLAGS</code>
+        <li> <code>DEAL_II_LINKER_FLAGS_DEBUG</code>
+        <li> <code>DEAL_II_LINKER_FLAGS_RELEASE</code>
+      </ul>
+
   </ul>
 </p>
 
index 2e3fda1ce79a7e79c8ca051f55fcb86dd19463ee..a110179809921a85e56bb3ddfe34942808d83d8b 100644 (file)
  * is a vector of expension coefficients. Because we don't know their values
  * yet (we will compute them as the solution of a linear or nonlinear system),
  * they are called "unknowns" or "degrees of freedom". The second meaning of
- * the term con be explained as follows: A mathematical description of finite
+ * the term can be explained as follows: A mathematical description of finite
  * element problem is often to say that we are looking for a finite
  * dimensional function $u_h \in V_h$ that satisfies some set of equations
  * (e.g. $a(u_h,\varphi_h)=(f,\varphi_h)$ for all test functions $\varphi_h\in
index 73d5cb20e9a546ab3dd2d592d057d52c347633b1..6a1402798326ec3a90981f293ca1e30aa571bfbb 100644 (file)
@@ -15,7 +15,7 @@
 // ---------------------------------------------------------------------
 
 /**
-// * @page changes_after_8_1 Changes after Version 8.1
+@page changes_after_8_1 Changes after Version 8.1
 
 <p>
 This is the list of changes made after the release of
@@ -40,6 +40,28 @@ inconvenience this causes.
 </p>
 
 <ol>
+  <li> Changed: The various classes generating graphical output, such
+  as DataOut or DataOutStack, are all derived from a common interface
+  class DataOutInterface which, in turn was derived from DataOutBase
+  through <i>private</i> inheritance. Because we frequently also
+  access the (public) members of this private base class this has tripped
+  up most every compiler we know of at one point or another. Furthermore,
+  because DataOutBase was a class that only defined static member functions
+  and had not member variables, there was really no reason for this
+  construct.
+  <br>
+  For these reasons, DataOutBase is now just a regular namespace and the
+  inheritance is gone. For the most part, this should not lead to any
+  incompatibilities except in cases where you accessed members of
+  DataOutBase through their derived classes. For example, it was possible
+  to write <code>DataOut@<2@>::Patch@<2,2@></code> even though the
+  <code>Patch</code> class is actually declared in DataOutBase. Since
+  the inheritance is now gone, this is no longer possible and one
+  actually has to write DataOutBase::Patch instead. Using this form
+  turns out to be compatible also with older versions of deal.II.
+  <br>
+  (Wolfgang Bangerth, 2014/02/01)
+  </li>
 </ol>
 
 
@@ -102,8 +124,60 @@ inconvenience this causes.
 <h3>Specific improvements</h3>
 
 <ol>
+  <li>Changed: DerivativeApproximation used to be a class that only had
+  static members. It is now a namespace.
+  <br>
+  (Wolfgang Bangerth, 2014/02/08)
+
+  <li>New: ThreadLocalStorage::clear() clears out all objects allocated on the
+  current and all other threads.
+  <br>
+  (Wolfgang Bangerth, 2014/02/06)
+
+  <li>Fixed: A configuration error on Debian Testing where accidentally a
+  non-pic libSuiteSparse_config.a was picked up when building a shared
+  library up resulting in a link error.
+  <br>
+  (Matthias Maier, 2014/02/04)
+
+  <li> Changed: GridTools::transform() can now deal with meshes with hanging nodes.
+  <br>
+  (Timo Heister, 2014/02/04)
+  </li>
+
+  <li>Fixed: Calling FEValuesViews::Vector::get_function_curls() computed
+  wrong results in some cases (see https://code.google.com/p/dealii/issues/detail?id=182).
+  This is now fixed.
+  <br>
+  (Christoph Heiniger, Wolfgang Bangerth, 2014/02/03)
+
+  <li>Added: The class LAPACKFullMatrix now implements interfaces to
+  matrix-matrix multiplication. Also, LAPACKFullMatrix::apply_lu_factorization
+  now also operates on multiple right hand sides in form of another
+  LAPACKFullMatrix.
+  <br>
+  (Martin Kronbichler, 2014/02/03)
+
+  <li>Added: A sanity check for the full link interface at configure time.
+  Hopefully this prevents some people from compiling the whole library just
+  to hit a link error.
+  <br>
+  (Matthias Maier, 2014/02/01)
+
+  <li>Fixed: The build system does no longer record full paths to system
+  libraries but uses the appropriate short names instead.
+  <br>
+  (Matthias Maier, 2014/02/01)
+
+  <li>Reworked: External feature setup. Disabling a feature now cleans up
+  associated internal, cached variables. A per-feature linkage test now spots
+  common linking inconsistencies early in the configuration stage (and not
+  just after a complete compilation).
+  <br>
+  (Matthias Maier, 2014/02/01)
+
   <li>New/fixed: The ParameterHandler::print_parameters_section
-  method not worked for XML output. There is now a flag
+  method did not work for XML output. There is now a flag
   include_top_level_elements which prints all higher
   subsection elements, default is false.
   For XML output setting this flag to true is required
index f33462423a746605d8ffee5963f3f026578d0f6c..3dc872d59ab7e4e3bdd94cc5c899078c3db1ce9d 100644 (file)
@@ -315,6 +315,15 @@ Pressurized Fractures
          <br>
          Comput. Methods Appl. Mech. Engrg., vol. 271, pp. 69-85, 2014.
         </li>
+
+       <li> J. Willems
+         <br>
+         <strong>Robust Multilevel Methods for General Symmetric Positive Definite Operators
+         </strong>
+         <br>
+         SIAM J. Numer. Anal.  52  (2014),  no. 1, 103-124.
+        </li>
+
       </ol>
 
 
@@ -417,7 +426,7 @@ Pressurized Fractures
          <br>
          <strong>Adaptive Finite Element Methods for Elliptic Problems with Discontinuous Coefficients</strong>
          <br>
-         SIAM J. Numer. Anal.  51  (2013),  no. 6, 3106--3134.
+         SIAM J. Numer. Anal.  51  (2013),  no. 6, 3106-3134.
        </li>
 
        <li> A. Bonito, R. Glowinski
@@ -454,7 +463,7 @@ Pressurized Fractures
          <br>
          <strong>Time-discrete higher order ALE formulations: Stability</strong>
          <br>
-         SIAM J. Numer. Anal., 51(1), 577--608, 2013.
+         SIAM J. Numer. Anal., 51(1), 577-608, 2013.
        </li>
 
        <li> A. Bonito, J. E. Pasciak
index cd1f9525b769b4510208bd8e4f70286673e885d2..189f1f70770ea5992ae9cc8f27b6e84f7cc13c0e 100644 (file)
@@ -1,7 +1,7 @@
 /* ---------------------------------------------------------------------
  * $Id$
  *
- * Copyright (C) 2001 - 2013 by the deal.II authors
+ * Copyright (C) 2001 - 2014 by the deal.II authors
  *
  * This file is part of the deal.II library.
  *
@@ -343,15 +343,14 @@ namespace Step13
     // program we shall generate output (from this we will then also generate
     // the suffix of the filename to which we write).
     //
-    // Regarding the output format, the <code>DataOutInterface</code> class
-    // (which is a base class of <code>DataOut</code> through which we will
-    // access its fields) provides an enumeration field
-    // <code>OutputFormat</code>, which lists names for all supported output
+    // Regarding the output format, the DataOutBase namespace
+    // provides an enumeration field
+    // DataOutBase::OutputFormat which lists names for all supported output
     // formats. At the time of writing of this program, the supported graphics
     // formats are represented by the enum values <code>ucd</code>,
     // <code>gnuplot</code>, <code>povray</code>, <code>eps</code>,
     // <code>gmv</code>, <code>tecplot</code>, <code>tecplot_binary</code>,
-    // <code>dx</code>, and <code>vtk</code>, but this list will certainly
+    // <code>dx</code>, <code>vtk</code>, etc, but this list will certainly
     // grow over time. Now, within various functions of that base class, you
     // can use values of this type to get information about these graphics
     // formats (for example the default suffix used for files of each format),
@@ -372,21 +371,21 @@ namespace Step13
     class SolutionOutput : public EvaluationBase<dim>
     {
     public:
-      SolutionOutput (const std::string                         &output_name_base,
-                      const typename DataOut<dim>::OutputFormat  output_format);
+      SolutionOutput (const std::string               &output_name_base,
+                      const DataOutBase::OutputFormat  output_format);
 
       virtual void operator () (const DoFHandler<dim> &dof_handler,
                                 const Vector<double>  &solution) const;
     private:
-      const std::string                         output_name_base;
-      const typename DataOut<dim>::OutputFormat output_format;
+      const std::string               output_name_base;
+      const DataOutBase::OutputFormat output_format;
     };
 
 
     template <int dim>
     SolutionOutput<dim>::
-    SolutionOutput (const std::string                         &output_name_base,
-                    const typename DataOut<dim>::OutputFormat  output_format)
+    SolutionOutput (const std::string               &output_name_base,
+                    const DataOutBase::OutputFormat  output_format)
       :
       output_name_base (output_name_base),
       output_format (output_format)
@@ -396,7 +395,7 @@ namespace Step13
     // After the description above, the function generating the actual output
     // is now relatively straightforward. The only particularly interesting
     // feature over previous example programs is the use of the
-    // <code>DataOut::default_suffix</code> function, returning the usual
+    // DataOutBase::default_suffix function, returning the usual
     // suffix for files of a given format (e.g. ".eps" for encapsulated
     // postscript files, ".gnuplot" for Gnuplot files), and of the generic
     // <code>DataOut::write</code> function with a second argument, which
@@ -1489,7 +1488,7 @@ namespace Step13
     // Also generate an evaluator which writes out the solution:
     Evaluation::SolutionOutput<dim>
     postprocessor2 (std::string("solution-")+solver_name,
-                    DataOut<dim>::gnuplot);
+                    DataOutBase::gnuplot);
 
     // Take these two evaluation objects and put them in a list...
     std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
index 23590f9d8bd5f4a7102dc91a8a5e1e3b6f2e9be2..bcb7d493edd80de2fd906bf000325d44f4b7d50d 100644 (file)
@@ -1,7 +1,7 @@
 /* ---------------------------------------------------------------------
  * $Id$
  *
- * Copyright (C) 2002 - 2013 by the deal.II authors
+ * Copyright (C) 2002 - 2014 by the deal.II authors
  *
  * This file is part of the deal.II library.
  *
@@ -875,7 +875,7 @@ namespace Step14
                << std::ends;
 
       std::ofstream out (filename.str().c_str());
-      data_out.write (out, DataOut<dim>::gnuplot);
+      data_out.write (out, DataOutBase::gnuplot);
     }
 
 
@@ -2399,7 +2399,7 @@ namespace Step14
                << std::ends;
 
       std::ofstream out (filename.str().c_str());
-      data_out.write (out, DataOut<dim>::gnuplot);
+      data_out.write (out, DataOutBase::gnuplot);
     }
 
 
index 3c2412609ab7b5b2473d9df0848e638465ad301a..61b5a33244acb250022cb79b6b2a8c86c49f4522 100644 (file)
@@ -16,7 +16,7 @@ function, in the form $u_h(\mathbf x) = \sum_{j=0}^{N-1} U_j \varphi_j(\mathbf
 x)$. Here, $U_j$ is a vector of expansion coefficients. Because we don't know
 their values yet (we will compute them as the solution of a linear or
 nonlinear system), they are called "unknowns" or "degrees of freedom". The
-second meaning of the term con be explained as follows: A mathematical
+second meaning of the term can be explained as follows: A mathematical
 description of finite element problem is often to say that we are looking for
 a finite dimensional function $u_h \in V_h$ that satisfies some set of equations
 (e.g. $a(u_h,\varphi_h)=(f,\varphi_h)$ for all test functions $\varphi_h\in
index e3fca00b1e95487f764a1f658fe07b43d8eb709b..52dda1eb453ab2250fae4de3d96de1ca73e4c68c 100644 (file)
@@ -273,7 +273,7 @@ Step6<dim>::~Step6 ()
 // The next function is setting up all the variables that describe the linear
 // finite element problem, such as the DoF handler, the matrices, and
 // vectors. The difference to what we did in step-5 is only that we now also
-// have to take care of handing node constraints. These constraints are
+// have to take care of hanging node constraints. These constraints are
 // handled almost transparently by the library, i.e. you only need to know
 // that they exist and how to get them, but you do not have to know how they
 // are formed or what exactly is done with them.
index b1380d6e4e2c706b0f2a4f63c02b3c91e99873a2..16c6b74483064e8d6ec7dc145632f496fbd01d63 100644 (file)
@@ -80,7 +80,17 @@ namespace Algorithms
     inverse_derivative->notify(e);
   }
 
-
+  
+  template <class VECTOR>
+  double
+  Newton<VECTOR>::threshold(const double thr)
+  {
+    const double t = assemble_threshold;
+    assemble_threshold = thr;
+    return t;
+  }
+  
+  
   template <class VECTOR>
   void
   Newton<VECTOR>::operator() (NamedData<VECTOR *> &out, const NamedData<VECTOR *> &in)
index 0d9ee2bbf387e735a1a46b8e6b486ca7b2ffd61e..ea0a249a98553fe4fa12344f4e5c0ab7c0f94277 100644 (file)
@@ -44,7 +44,6 @@ DEAL_II_NAMESPACE_OPEN
 
 class ParameterHandler;
 class XDMFEntry;
-class DataOutFilter;
 
 /**
  * This is a base class for output of data on meshes of very general
@@ -142,11 +141,9 @@ class DataOutFilter;
  *
  * <h3>DataOutBaseInterface</h3>
  *
- * This class has an interface that is not usually called by a user
- * directly; also, it consists of <tt>static</tt> functions
- * only. Usually, derived classes will inherit this class
- * <tt>protected</tt> to hide this interface to the users of thes
- * classes.
+ * The members of this namespace are not usually called from user code
+ * directly. Rather, classes that use the functions declared here
+ * are typically derived from DataOutInterface.
  *
  * The interface of this class basically consists of the declaration of a data
  * type describing a patch and a bunch of functions taking a list of patches
@@ -216,9 +213,8 @@ class DataOutFilter;
  * @ingroup output
  * @author Wolfgang Bangerth, Guido Kanschat 1999, 2000, 2001, 2002, 2005, 2006.
  */
-class DataOutBase
+namespace DataOutBase
 {
-public:
   /**
    * Data structure describing a patch of data in <tt>dim</tt> space
    * dimensions.
@@ -1108,7 +1104,7 @@ public:
      * understand.
      */
     static const unsigned int format_version = 3;
-    
+
   private:
     /**
      * Dummy entry to suppress compiler warnings when copying an empty
@@ -1461,11 +1457,11 @@ public:
    * <tt>contrib/dx</tt>.
    */
   template <int dim, int spacedim>
-  static void write_dx (const std::vector<Patch<dim,spacedim> > &patches,
-                        const std::vector<std::string>          &data_names,
-                        const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                        const DXFlags                           &flags,
-                        std::ostream                            &out);
+  void write_dx (const std::vector<Patch<dim,spacedim> > &patches,
+                 const std::vector<std::string>          &data_names,
+                 const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                 const DXFlags                           &flags,
+                 std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in eps format.
@@ -1513,11 +1509,11 @@ public:
    * class. See there for more and detailed information.
    */
   template <int dim, int spacedim>
-  static void write_eps (const std::vector<Patch<dim,spacedim> > &patches,
-                         const std::vector<std::string>          &data_names,
-                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                         const EpsFlags                          &flags,
-                         std::ostream                            &out);
+  void write_eps (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const EpsFlags                          &flags,
+                  std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in
@@ -1530,11 +1526,11 @@ public:
    * space is interpolated to (bi-,tri-)linear elements.
    */
   template <int dim, int spacedim>
-  static void write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
-                         const std::vector<std::string>          &data_names,
-                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                         const GmvFlags                          &flags,
-                         std::ostream                            &out);
+  void write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const GmvFlags                          &flags,
+                  std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in gnuplot
@@ -1597,11 +1593,11 @@ public:
    * cut-surface are plotted.
    */
   template <int dim, int spacedim>
-  static void write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
-                             const std::vector<std::string>          &data_names,
-                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                             const GnuplotFlags                      &flags,
-                             std::ostream                            &out);
+  void write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
+                      const std::vector<std::string>          &data_names,
+                      const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                      const GnuplotFlags                      &flags,
+                      std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream for the
@@ -1651,11 +1647,11 @@ public:
    * included in the povray options.
    */
   template <int dim, int spacedim>
-  static void write_povray (const std::vector<Patch<dim,spacedim> > &patches,
-                            const std::vector<std::string>          &data_names,
-                            const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                            const PovrayFlags                       &flags,
-                            std::ostream                            &out);
+  void write_povray (const std::vector<Patch<dim,spacedim> > &patches,
+                     const std::vector<std::string>          &data_names,
+                     const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                     const PovrayFlags                       &flags,
+                     std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in
@@ -1665,11 +1661,11 @@ public:
    * manuals.
    */
   template <int dim, int spacedim>
-  static void write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
-                             const std::vector<std::string>          &data_names,
-                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                             const TecplotFlags                      &flags,
-                             std::ostream                            &out);
+  void write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
+                      const std::vector<std::string>          &data_names,
+                      const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                      const TecplotFlags                      &flags,
+                      std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in
@@ -1693,7 +1689,7 @@ public:
    * manuals.
    */
   template <int dim, int spacedim>
-  static void write_tecplot_binary (
+  void write_tecplot_binary (
     const std::vector<Patch<dim,spacedim> > &patches,
     const std::vector<std::string>          &data_names,
     const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
@@ -1716,11 +1712,11 @@ public:
    * patch to the same value.
    */
   template <int dim, int spacedim>
-  static void write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
-                         const std::vector<std::string>          &data_names,
-                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                         const UcdFlags                          &flags,
-                         std::ostream                            &out);
+  void write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const UcdFlags                          &flags,
+                  std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in VTK
@@ -1742,11 +1738,11 @@ public:
    * latter file format instead, by using the write_vtu() function.
    */
   template <int dim, int spacedim>
-  static void write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
-                         const std::vector<std::string>          &data_names,
-                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                         const VtkFlags                          &flags,
-                         std::ostream                            &out);
+  void write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const VtkFlags                          &flags,
+                  std::ostream                            &out);
 
 
   /**
@@ -1773,11 +1769,11 @@ public:
    * The use of this function is explained in step-40.
    */
   template <int dim, int spacedim>
-  static void write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
-                         const std::vector<std::string>          &data_names,
-                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                         const VtkFlags                          &flags,
-                         std::ostream                            &out);
+  void write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const VtkFlags                          &flags,
+                  std::ostream                            &out);
 
   /**
    * This writes the header for the xml based vtu file format. This
@@ -1785,8 +1781,8 @@ public:
    * DataOutInterface::write_vtu_footer() and DataOutInterface::write_vtu_main()
    * by DataOutBase::write_vtu().
    */
-  static void write_vtu_header (std::ostream &out,
-                                const VtkFlags &flags);
+  void write_vtu_header (std::ostream &out,
+                         const VtkFlags &flags);
 
   /**
    * This writes the footer for the xml based vtu file format. This
@@ -1794,7 +1790,7 @@ public:
    * DataOutInterface::write_vtu_header() and DataOutInterface::write_vtu_main()
    * by DataOutBase::write_vtu().
    */
-  static void write_vtu_footer (std::ostream &out);
+  void write_vtu_footer (std::ostream &out);
 
   /**
    * This writes the main part for the xml based vtu file format. This
@@ -1803,11 +1799,11 @@ public:
    * by DataOutBase::write_vtu().
    */
   template <int dim, int spacedim>
-  static void write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
-                              const std::vector<std::string>          &data_names,
-                              const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                              const VtkFlags                          &flags,
-                              std::ostream                            &out);
+  void write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
+                       const std::vector<std::string>          &data_names,
+                       const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                       const VtkFlags                          &flags,
+                       std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in SVG format.
@@ -1827,15 +1823,15 @@ public:
    * the data values at the vertices taken from the specified data
    * vector. A colorbar can be drawn to encode the coloring.
    *
-   * @note Yet only implemented for two dimensions with an additional
-   * dimension reserved for data information.
+   * @note This function is so far only implemented for two dimensions
+   * with an additional dimension reserved for data information.
    */
-  template <int dim, int spacedim>
-  static void write_svg (const std::vector<Patch<dim,spacedim> > &patches,
-                         const std::vector<std::string>          &data_names,
-                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                         const SvgFlags                          &flags,
-                         std::ostream                            &out);
+  template <int spacedim>
+  void write_svg (const std::vector<Patch<2,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const SvgFlags                          &flags,
+                  std::ostream                            &out);
 
   /**
    * Write the given list of patches to the output stream in deal.II
@@ -1878,7 +1874,7 @@ public:
    * the ending <tt>.d2</tt>.
    */
   template <int dim, int spacedim>
-  static void write_deal_II_intermediate (
+  void write_deal_II_intermediate (
     const std::vector<Patch<dim,spacedim> > &patches,
     const std::vector<std::string>          &data_names,
     const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
@@ -1890,10 +1886,10 @@ public:
    * the mesh and solution values.
    */
   template <int dim, int spacedim>
-  static void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
-                                   const DataOutFilter &data_filter,
-                                   const std::string &filename,
-                                   MPI_Comm comm);
+  void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
+                            const DataOutFilter &data_filter,
+                            const std::string &filename,
+                            MPI_Comm comm);
 
   /**
    * Write the data in data_filter to HDF5 file(s). If write_mesh_file
@@ -1903,12 +1899,12 @@ public:
    * contain both mesh data and solution values.
    */
   template <int dim, int spacedim>
-  static void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
-                                   const DataOutFilter &data_filter,
-                                   const bool write_mesh_file,
-                                   const std::string &mesh_filename,
-                                   const std::string &solution_filename,
-                                   MPI_Comm comm);
+  void write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
+                            const DataOutFilter &data_filter,
+                            const bool write_mesh_file,
+                            const std::string &mesh_filename,
+                            const std::string &solution_filename,
+                            MPI_Comm comm);
 
   /**
    * DataOutFilter is an intermediate data format that reduces the amount of
@@ -1917,10 +1913,10 @@ public:
    * see, for example, DataOutBase::write_hdf5_parallel().
    */
   template <int dim, int spacedim>
-  static void write_filtered_data (const std::vector<Patch<dim,spacedim> > &patches,
-                                   const std::vector<std::string>          &data_names,
-                                   const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                                   DataOutFilter &filtered_data);
+  void write_filtered_data (const std::vector<Patch<dim,spacedim> > &patches,
+                            const std::vector<std::string>          &data_names,
+                            const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                            DataOutFilter &filtered_data);
 
   /**
    * Given an input stream that contains data written by
@@ -1934,7 +1930,6 @@ public:
    * to either reset the stream to its previous position, or close and
    * reopen it.
    */
-  static
   std::pair<unsigned int, unsigned int>
   determine_intermediate_format_dimensions (std::istream &input);
 
@@ -1943,9 +1938,7 @@ public:
    * string. If the string does not match any known format, an
    * exception is thrown.
    *
-   * Since this function does not need data from this object, it is
-   * static and can thus be called without creating an object of this
-   * class. Its main purpose is to allow a program to use any
+   * The main purpose of this function is to allow a program to use any
    * implemented output format without the need to extend the
    * program's parser each time a new format is implemented.
    *
@@ -1953,14 +1946,14 @@ public:
    * it to the ParameterHandler class, use the function
    * get_output_format_names().
    */
-  static OutputFormat parse_output_format (const std::string &format_name);
+  OutputFormat parse_output_format (const std::string &format_name);
 
   /**
    * Return a list of implemented output formats. The different names
    * are separated by vertical bar signs (<tt>`|'</tt>) as used by the
    * ParameterHandler classes.
    */
-  static std::string get_output_format_names ();
+  std::string get_output_format_names ();
 
   /**
    * Provide a function which tells us which suffix a file with a
@@ -1981,17 +1974,7 @@ public:
    * <li> <tt>deal_II_intermediate</tt>: <tt>.d2</tt>.
    * </ul>
    */
-  static std::string default_suffix (const OutputFormat output_format);
-
-  /**
-   * Determine an estimate for the memory consumption (in bytes) of
-   * this object. Since sometimes the size of objects can not be
-   * determined exactly (for example: what is the memory consumption
-   * of an STL <tt>std::map</tt> type with a certain number of
-   * elements?), this is only an estimate. however often quite close
-   * to the true value.
-   */
-  static std::size_t memory_consumption ();
+  std::string default_suffix (const OutputFormat output_format);
 
   /** @addtogroup Exceptions
    * @{ */
@@ -2020,151 +2003,13 @@ public:
                   << " for output");
 
   //@}
-private:
-  /**
-   * Write the coordinates of nodes in the desired format.
-   */
-  template <int dim, int spacedim, typename STREAM>
-  static void write_nodes (const std::vector<Patch<dim,spacedim> > &patches,
-                           STREAM &out);
-
-  /**
-   * Write the node numbers of a cell in the desired format.
-   */
-  template <int dim, int spacedim, typename STREAM>
-  static void write_cells (const std::vector<Patch<dim,spacedim> > &patches,
-                           STREAM &out);
-
-  /**
-   * Write data in the desired format.
-   */
-  template <int dim, int spacedim, class STREAM>
-  static void write_data (const std::vector<Patch<dim,spacedim> > &patches,
-                          const unsigned int n_data_sets,
-                          const bool double_precision,
-                          STREAM &out);
-
-
-  /**
-   * This function projects a three-dimensional point (Point<3> point)
-   * onto a two-dimensional image plane, specified by the position of
-   * the camera viewing system (Point<3> camera_position), camera
-   * direction (Point<3> camera_position), camera horizontal (Point<3>
-   * camera_horizontal, necessary for the correct alignment of the
-   * later images), and the focus of the camera (float camera_focus).
-   *
-   * For SVG output.
-   */
-  static Point<2> svg_project_point(Point<3> point,
-                                    Point<3> camera_position,
-                                    Point<3> camera_direction,
-                                    Point<3> camera_horizontal,
-                                    float camera_focus);
-  /**
-   * Function to compute the gradient parameters for a triangle with
-   * given values for the vertices.
-   *
-   * Used for svg output.
-   */
-  static Point<6> svg_get_gradient_parameters(Point<3> points[]);
-
-  /**
-   * Class holding the data of one cell of a patch in two space
-   * dimensions for output. It is the projection of a cell in
-   * three-dimensional space (two coordinates, one height value) to
-   * the direction of sight.
-   */
-  class SvgCell
-  {
-  public:
-
-    // Center of the cell (three-dimensional)
-    Point<3> center;
-
-    /**
-     * Vector of vertices of this cell (three-dimensional)
-     */
-    Point<3> vertices[4];
-
-    /**
-     * Depth into the picture, which is defined as the distance from
-     * an observer at an the origin in direction of the line of sight.
-     */
-    float depth;
-
-    /**
-     * Vector of vertices of this cell (projected, two-dimensional).
-     */
-    Point<2> projected_vertices[4];
-
-    // Center of the cell (projected, two-dimensional)
-    Point<2> projected_center;
-
-    /**
-     * Comparison operator for sorting.
-     */
-    bool operator < (const SvgCell &) const;
-  };
-
-
-  /**
-   * Class holding the data of one cell of a patch in two space
-   * dimensions for output. It is the projection of a cell in
-   * three-dimensional space (two coordinates, one height value) to
-   * the direction of sight.
-   */
-  class EpsCell2d
-  {
-  public:
-
-    /**
-     * Vector of vertices of this cell.
-     */
-    Point<2> vertices[4];
-
-    /**
-     * Data value from which the actual colors will be computed by the
-     * colorization function stated in the <tt>EpsFlags</tt> class.
-     */
-    float color_value;
-
-    /**
-     * Depth into the picture, which is defined as the distance from
-     * an observer at an the origin in direction of the line of sight.
-     */
-    float depth;
-
-    /**
-     * Comparison operator for sorting.
-     */
-    bool operator < (const EpsCell2d &) const;
-  };
-
-
-  /**
-   * This is a helper function for the write_gmv() function. There,
-   * the data in the patches needs to be copied around as output is
-   * one variable globally at a time, rather than all data on each
-   * vertex at a time. This copying around can be done detached from
-   * the main thread, and is thus moved into this separate function.
-   *
-   * Note that because of the similarity of the formats, this function
-   * is also used by the Vtk and Tecplot output functions.
-   */
-  template <int dim, int spacedim>
-  static void
-  write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
-                                  Table<2,double>                         &data_vectors);
-
-
-
-};
+}
 
 
 
 
 /**
- * This class is the interface to the <tt>DataOutBase</tt> class, as already its name
+ * This class is the interface to the functions in the DataOutBase namespace, as already its name
  * might suggest. It does not offer much functionality apart from a way to
  * access the implemented formats and a way to dynamically dispatch what output
  * format to chose.
@@ -2278,36 +2123,9 @@ private:
  * @author Wolfgang Bangerth, 1999
  */
 template <int dim, int spacedim=dim>
-class DataOutInterface : private DataOutBase
+class DataOutInterface
 {
 public:
-  /*
-   * Import a few names that were
-   * previously in this class and have then
-   * moved to the base class. Since the
-   * base class is inherited from
-   * privately, we need to re-import these
-   * symbols to make sure that references
-   * to DataOutInterface<dim,spacedim>::XXX
-   * remain valid.
-   */
-  using DataOutBase::OutputFormat;
-  using DataOutBase::default_format;
-  using DataOutBase::dx;
-  using DataOutBase::gnuplot;
-  using DataOutBase::povray;
-  using DataOutBase::eps;
-  using DataOutBase::tecplot;
-  using DataOutBase::tecplot_binary;
-  using DataOutBase::vtk;
-  using DataOutBase::vtu;
-  using DataOutBase::deal_II_intermediate;
-  using DataOutBase::parse_output_format;
-  using DataOutBase::get_output_format_names;
-  using DataOutBase::determine_intermediate_format_dimensions;
-
-  using DataOutBase::Patch;
-  
   /**
    * Constructor.
    */
@@ -2630,7 +2448,7 @@ public:
    * the mesh and solution data were written to a single file. See
    * write_xdmf_file() for an example of usage.
    */
-  XDMFEntry create_xdmf_entry (const DataOutFilter &data_filter,
+  XDMFEntry create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
                                const std::string &h5_filename,
                                const double cur_time,
                                MPI_Comm comm) const;
@@ -2640,7 +2458,7 @@ public:
    * the mesh and solution data were written to separate files. See
    * write_xdmf_file() for an example of usage.
    */
-  XDMFEntry create_xdmf_entry (const DataOutFilter &data_filter,
+  XDMFEntry create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
                                const std::string &h5_mesh_filename,
                                const std::string &h5_solution_filename,
                                const double cur_time,
@@ -2674,7 +2492,8 @@ public:
    * single HDF5 file containing both the mesh and solution values.
   @deprecated: use write_hdf5_parallel(DataOutFilter, ...) instead
    */
-  void write_hdf5_parallel (const std::string &filename, MPI_Comm comm) const DEAL_II_DEPRECATED;
+  void write_hdf5_parallel (const std::string &filename,
+                            MPI_Comm comm) const DEAL_II_DEPRECATED;
 
   /**
    * Write the data in data_filter to a single HDF5 file containing both
@@ -2689,7 +2508,8 @@ public:
    * data_out.write_hdf5_parallel(data_filter, "solution.h5", MPI_COMM_WORLD);
    * @endcode
    */
-  void write_hdf5_parallel (const DataOutFilter &data_filter, const std::string &filename, MPI_Comm comm) const;
+  void write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+                            const std::string &filename, MPI_Comm comm) const;
 
   /**
    * Write the data in data_filter to HDF5 file(s). If write_mesh_file
@@ -2698,7 +2518,8 @@ public:
    * is true and the filenames are the same, the resulting file will
    * contain both mesh data and solution values.
    */
-  void write_hdf5_parallel (const DataOutFilter &data_filter, const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const;
+  void write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+                            const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const;
 
   /**
    * DataOutFilter is an intermediate data format that reduces the amount of
@@ -2706,7 +2527,7 @@ public:
    * can then later be used again to write data in a concrete file format;
    * see, for example, DataOutBase::write_hdf5_parallel().
    */
-  void write_filtered_data (DataOutFilter &filtered_data) const;
+  void write_filtered_data (DataOutBase::DataOutFilter &filtered_data) const;
 
 
   /**
@@ -2724,64 +2545,64 @@ public:
    * format is <tt>default_format</tt>.
    */
   void write (std::ostream       &out,
-              const OutputFormat  output_format = default_format) const;
+              const DataOutBase::OutputFormat  output_format = DataOutBase::default_format) const;
 
   /**
    * Set the default format. The value set here is used anytime,
    * output for format <tt>default_format</tt> is requested.
    */
-  void set_default_format (const OutputFormat default_format);
+  void set_default_format (const DataOutBase::OutputFormat default_format);
 
   /**
    * Set the flags to be used for output in OpenDX format.
    */
-  void set_flags (const DXFlags &dx_flags);
+  void set_flags (const DataOutBase::DXFlags &dx_flags);
 
   /**
    * Set the flags to be used for output in UCD format.
    */
-  void set_flags (const UcdFlags &ucd_flags);
+  void set_flags (const DataOutBase::UcdFlags &ucd_flags);
 
   /**
    * Set the flags to be used for output in GNUPLOT format.
    */
-  void set_flags (const GnuplotFlags &gnuplot_flags);
+  void set_flags (const DataOutBase::GnuplotFlags &gnuplot_flags);
 
   /**
    * Set the flags to be used for output in POVRAY format.
    */
-  void set_flags (const PovrayFlags &povray_flags);
+  void set_flags (const DataOutBase::PovrayFlags &povray_flags);
 
   /**
    * Set the flags to be used for output in EPS output.
    */
-  void set_flags (const EpsFlags &eps_flags);
+  void set_flags (const DataOutBase::EpsFlags &eps_flags);
 
   /**
    * Set the flags to be used for output in GMV format.
    */
-  void set_flags (const GmvFlags &gmv_flags);
+  void set_flags (const DataOutBase::GmvFlags &gmv_flags);
 
   /**
    * Set the flags to be used for output in Tecplot format.
    */
-  void set_flags (const TecplotFlags &tecplot_flags);
+  void set_flags (const DataOutBase::TecplotFlags &tecplot_flags);
 
   /**
    * Set the flags to be used for output in VTK format.
    */
-  void set_flags (const VtkFlags &vtk_flags);
+  void set_flags (const DataOutBase::VtkFlags &vtk_flags);
 
   /**
    * Set the flags to be used for output in SVG format.
    */
-  void set_flags (const SvgFlags &svg_flags);
+  void set_flags (const DataOutBase::SvgFlags &svg_flags);
 
   /**
    * Set the flags to be used for output in deal.II intermediate
    * format.
    */
-  void set_flags (const Deal_II_IntermediateFlags &deal_II_intermediate_flags);
+  void set_flags (const DataOutBase::Deal_II_IntermediateFlags &deal_II_intermediate_flags);
 
   /**
    * A function that returns the same string as the respective
@@ -2792,7 +2613,7 @@ public:
    * calling this function.
    */
   std::string
-  default_suffix (const OutputFormat output_format = default_format) const;
+  default_suffix (const DataOutBase::OutputFormat output_format = DataOutBase::default_format) const;
 
   /**
    * Declare parameters for all output formats by declaring
@@ -2840,7 +2661,7 @@ protected:
    * functions to know what they shall print.
    */
   virtual
-  const std::vector<typename DataOutBase::Patch<dim,spacedim> > &
+  const std::vector<DataOutBase::Patch<dim,spacedim> > &
   get_patches () const = 0;
 
   /**
@@ -2887,73 +2708,73 @@ private:
    * default_format is requested. It can be changed by the
    * <tt>set_format</tt> function or in a parameter file.
    */
-  OutputFormat default_fmt;
+  DataOutBase::OutputFormat default_fmt;
 
   /**
    * Flags to be used upon output of OpenDX data. Can be changed by
    * using the <tt>set_flags</tt> function.
    */
-  DXFlags     dx_flags;
+  DataOutBase::DXFlags     dx_flags;
 
   /**
    * Flags to be used upon output of UCD data. Can be changed by using
    * the <tt>set_flags</tt> function.
    */
-  UcdFlags     ucd_flags;
+  DataOutBase::UcdFlags     ucd_flags;
 
   /**
    * Flags to be used upon output of GNUPLOT data. Can be changed by
    * using the <tt>set_flags</tt> function.
    */
-  GnuplotFlags gnuplot_flags;
+  DataOutBase::GnuplotFlags gnuplot_flags;
 
   /**
    * Flags to be used upon output of POVRAY data. Can be changed by
    * using the <tt>set_flags</tt> function.
    */
-  PovrayFlags povray_flags;
+  DataOutBase::PovrayFlags povray_flags;
 
   /**
    * Flags to be used upon output of EPS data in one space
    * dimension. Can be changed by using the <tt>set_flags</tt>
    * function.
    */
-  EpsFlags     eps_flags;
+  DataOutBase::EpsFlags     eps_flags;
 
   /**
    * Flags to be used upon output of gmv data in one space
    * dimension. Can be changed by using the <tt>set_flags</tt>
    * function.
    */
-  GmvFlags     gmv_flags;
+  DataOutBase::GmvFlags     gmv_flags;
 
   /**
    * Flags to be used upon output of Tecplot data in one space
    * dimension. Can be changed by using the <tt>set_flags</tt>
    * function.
    */
-  TecplotFlags tecplot_flags;
+  DataOutBase::TecplotFlags tecplot_flags;
 
   /**
    * Flags to be used upon output of vtk data in one space
    * dimension. Can be changed by using the <tt>set_flags</tt>
    * function.
    */
-  VtkFlags     vtk_flags;
+  DataOutBase::VtkFlags     vtk_flags;
 
   /**
    * Flags to be used upon output of svg data in one space
    * dimension. Can be changed by using the <tt>set_flags</tt>
    * function.
    */
-  SvgFlags     svg_flags;
+  DataOutBase::SvgFlags     svg_flags;
 
   /**
    * Flags to be used upon output of deal.II intermediate data in one
    * space dimension. Can be changed by using the <tt>set_flags</tt>
    * function.
    */
-  Deal_II_IntermediateFlags     deal_II_intermediate_flags;
+  DataOutBase::Deal_II_IntermediateFlags     deal_II_intermediate_flags;
 };
 
 
@@ -3077,7 +2898,7 @@ protected:
    * It returns the patches as read the last time a stream was given
    * to the read() function.
    */
-  virtual const std::vector<typename dealii::DataOutBase::Patch<dim,spacedim> > &
+  virtual const std::vector<dealii::DataOutBase::Patch<dim,spacedim> > &
   get_patches () const;
 
   /**
@@ -3117,7 +2938,7 @@ private:
    * Arrays holding the set of patches as well as the names of output
    * variables, all of which we read from an input stream.
    */
-  std::vector<typename dealii::DataOutBase::Patch<dim,spacedim> > patches;
+  std::vector<dealii::DataOutBase::Patch<dim,spacedim> > patches;
   std::vector<std::string> dataset_names;
 
   /**
@@ -3200,45 +3021,47 @@ public:
 
 /* -------------------- inline functions ------------------- */
 
-inline
-bool
-DataOutBase::EpsFlags::RgbValues::is_grey () const
+namespace DataOutBase
 {
-  return (red == green) && (red == blue);
-}
-
+  inline
+  bool
+  EpsFlags::RgbValues::is_grey () const
+  {
+    return (red == green) && (red == blue);
+  }
 
-/* -------------------- template functions ------------------- */
 
-/**
- * Output operator for an object of type
- * <tt>DataOutBase::Patch</tt>. This operator dumps the intermediate
- * graphics format represented by the patch data structure. It may
- * later be converted into regular formats for a number of graphics
- * programs.
- *
- * @author Wolfgang Bangerth, 2005
- */
-template <int dim, int spacedim>
-std::ostream &
-operator << (std::ostream                           &out,
-             const DataOutBase::Patch<dim,spacedim> &patch);
+  /* -------------------- template functions ------------------- */
 
+  /**
+   * Output operator for an object of type
+   * <tt>DataOutBase::Patch</tt>. This operator dumps the intermediate
+   * graphics format represented by the patch data structure. It may
+   * later be converted into regular formats for a number of graphics
+   * programs.
+   *
+   * @author Wolfgang Bangerth, 2005
+   */
+  template <int dim, int spacedim>
+  std::ostream &
+  operator << (std::ostream                           &out,
+               const Patch<dim,spacedim> &patch);
 
 
-/**
- * Input operator for an object of type
- * <tt>DataOutBase::Patch</tt>. This operator reads the intermediate
- * graphics format represented by the patch data structure, using the
- * format in which it was written using the operator<<.
- *
- * @author Wolfgang Bangerth, 2005
- */
-template <int dim, int spacedim>
-std::istream &
-operator >> (std::istream                     &in,
-             DataOutBase::Patch<dim,spacedim> &patch);
 
+  /**
+   * Input operator for an object of type
+   * <tt>DataOutBase::Patch</tt>. This operator reads the intermediate
+   * graphics format represented by the patch data structure, using the
+   * format in which it was written using the operator<<.
+   *
+   * @author Wolfgang Bangerth, 2005
+   */
+  template <int dim, int spacedim>
+  std::istream &
+  operator >> (std::istream                     &in,
+               Patch<dim,spacedim> &patch);
+}
 
 
 DEAL_II_NAMESPACE_CLOSE
index 616f6de210deb93dc2691556cf60af8ecbd35280..19ddcd716d2fc9dbf9be9b0149179c2ce012cfa7 100644 (file)
@@ -193,7 +193,7 @@ public:
    * <tt>values</tt> already has the right size, i.e.  the same size as the
    * <tt>points</tt> array.
    *
-   * Be default, this function repeatedly calls value() for each point
+   * By default, this function repeatedly calls value() for each point
    * separately, to fill the output array.
    */
   virtual void value_list (const std::vector<Point<dim> > &points,
@@ -207,7 +207,7 @@ public:
    * all elements be vectors with the same number of components as this
    * function has.
    *
-   * Be default, this function repeatedly calls vector_value() for each
+   * By default, this function repeatedly calls vector_value() for each
    * point separately, to fill the output array.
    */
   virtual void vector_value_list (const std::vector<Point<dim> > &points,
index 7f1429eae4031b9067ec9037c00634a051a57570..eab0bbea856138a6e5c505dad2326f35ec4c4ae0 100644 (file)
@@ -94,7 +94,7 @@ template <typename> class Vector;
   // Define the expressions of the individual components of a
   // vector valued function with two components:
   std::vector<std::string> expressions(1);
-  expressions[0] = "x cm + y m + PI cm;
+  expressions[0] = "x cm + y m + PI cm";
 
   // Generate an empty function for these two components.
   FunctionParser<2> vector_function;
index f61e2b3681c31875138ed95bd4056916ed536076..d2435f1883d9de2f1ead35ee4bc3c35f4e170709 100644 (file)
@@ -472,7 +472,15 @@ SmartPointer<T,P>::memory_consumption () const
 
 
 
-
+// The following function is not strictly necessary but is an optimization
+// for places where you call swap(p1,p2) with SmartPointer objects p1, p2.
+// Unfortunately, MS Visual Studio (at least up to the 2013 edition) trips
+// over it when calling std::swap(v1,v2) where v1,v2 are std::vectors of
+// SmartPointer objects: it can't determine whether it should call std::swap
+// or dealii::swap on the individual elements (see bug #184 on our Google Code
+// site. Consequently, just take this function out of the competition for this
+// compiler.
+#ifndef _MSC_VER
 /**
  * Global function to swap the contents of two smart pointers. As both
  * objects to which the pointers point retain to be subscribed to, we
@@ -484,7 +492,7 @@ void swap (SmartPointer<T,P> &t1, SmartPointer<T,Q> &t2)
 {
   t1.swap (t2);
 }
-
+#endif
 
 
 /**
index dccaa2f61fc7f72c6dca4ace185b87408c464eef..70d71b75ed53564e1ab9d34eb6684e85ecfd9425 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2011 - 2013 by the deal.II authors
+// Copyright (C) 2011 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -84,7 +84,7 @@ namespace Threads
     /**
      * Copy constructor. Initialize each thread local object
      * with the corresponding object of the given object.
-     **/
+     */
     ThreadLocalStorage (const ThreadLocalStorage<T> &t);
 
     /**
@@ -132,17 +132,37 @@ namespace Threads
     ThreadLocalStorage<T> &operator = (const T &t);
 
     /**
-     * Returns a reference to the internal implementation.
+     * Remove the thread-local objects stored for all threads that have
+     * created one with this object (i.e., that have called get()
+     * at least once on this thread. This includes the current thread. If you
+     * call get() subsequently on this or any other thread, new objects will
+     * again be created.
+     *
+     * If deal.II has been configured to not use multithreading, then this function
+     * does not do anything at all. Note that this of course has different semantics
+     * as in the multithreading context the objects are deleted and created again
+     * (possible by copying from a sample object, if the appropriate constructor
+     * of this class was called), whereas in the multithreaded context the object
+     * is simply not touched at all. At the same time, the purpose of this function
+     * is to release memory other threads may have allocated for their own thread
+     * local objects after which every use of this object will require some kind
+     * of initialization. This is necessary both in the multithreaded or
+     * non-multithreaded case.
+     */
+    void clear ();
+
+    /**
+     * Returns a reference to the internal Threading Building Blocks
+     * implementation. This function is really only useful if deal.II
+     * has been configured with multithreading and has no useful
+     * purpose otherwise.
      */
 #ifdef DEAL_II_WITH_THREADS
     tbb::enumerable_thread_specific<T> &
 #else
     T &
 #endif
-    get_implementation()
-    {
-      return data;
-    }
+    get_implementation();
 
   private:
 #ifdef DEAL_II_WITH_THREADS
@@ -225,6 +245,31 @@ namespace Threads
     get() = t;
     return *this;
   }
+
+
+  template <typename T>
+  inline
+#ifdef DEAL_II_WITH_THREADS
+  tbb::enumerable_thread_specific<T> &
+#else
+  T &
+#endif
+  ThreadLocalStorage<T>::get_implementation()
+  {
+    return data;
+  }
+
+
+
+  template <typename T>
+  inline
+  void
+  ThreadLocalStorage<T>::clear ()
+  {
+#ifdef DEAL_II_WITH_THREADS
+    data.clear ();
+#endif
+  }
 }   // end of implementation of namespace Threads
 
 /**
index 038443436efce3762fc55c575e7d4ccdb6e5cc91..1c56c862d52c3bd5b4e26377f1d6091d427203ec 100644 (file)
@@ -1208,6 +1208,14 @@ public:
    */
   typedef DH Container;
 
+  /**
+   * A type for an iterator over the faces of a cell. This is
+   * what the face() function returns.
+   */
+  typedef
+  TriaIterator<DoFAccessor<DH::dimension-1, DH, level_dof_access> >
+  face_iterator;
+
   /**
    * @name Constructors and initialization
    */
@@ -1284,10 +1292,10 @@ public:
   /**
    * Return an iterator to the @p ith face of this cell.
    *
-   * This function is not implemented in 1D, and maps to
-   * DoFAccessor::line in 2D.
+   * This function is not implemented in 1D, and returns
+   * DoFAccessor::line in 2D and DoFAccessor::quad in 3d.
    */
-  TriaIterator<DoFAccessor<DH::dimension-1,DH, level_dof_access> >
+  face_iterator
   face (const unsigned int i) const;
 
   /**
@@ -1748,12 +1756,12 @@ private:
 };
 
 
-template <int sd, class DH, bool lda>
+template <int sd, class DH, bool level_dof_access>
 inline
 bool
-DoFAccessor<sd, DH, lda>::is_level_cell()
+DoFAccessor<sd, DH, level_dof_access>::is_level_cell()
 {
-  return lda;
+  return level_dof_access;
 }
 
 
index 9b689af2ab7525359d5649edee4355e4e78e0b65..ec4b9754424cfd9a6b481d92073d97418f8c6c09 100644 (file)
@@ -38,18 +38,18 @@ DEAL_II_NAMESPACE_OPEN
 /*------------------------- Functions: DoFAccessor ---------------------------*/
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor ()
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor ()
 {
   Assert (false, ExcInvalidObject());
 }
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor (
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (
   const Triangulation<DH::dimension,DH::space_dimension> *tria,
   const int                 level,
   const int                 index,
@@ -64,19 +64,19 @@ DoFAccessor<structdim,DH,lda>::DoFAccessor (
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 template <int structdim2, int dim2, int spacedim2>
-DoFAccessor<structdim,DH,lda>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
 {
   Assert (false, ExcInvalidObject());
 }
 
 
 
-template <int structdim, class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor (const DoFAccessor<dim2, DH2, lda2> &other)
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (const DoFAccessor<dim2, DH2, level_dof_access2> &other)
   : BaseClass(other),
     dof_handler(0)
 {
@@ -90,10 +90,10 @@ DoFAccessor<structdim,DH,lda>::DoFAccessor (const DoFAccessor<dim2, DH2, lda2> &
 
 
 
-template <int structdim, class DH, bool lda>
-template <bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <bool level_dof_access2>
 inline
-DoFAccessor<structdim,DH,lda>::DoFAccessor (const DoFAccessor<structdim, DH, lda2> &other)
+DoFAccessor<structdim,DH,level_dof_access>::DoFAccessor (const DoFAccessor<structdim, DH, level_dof_access2> &other)
   : BaseClass(other),
     dof_handler(const_cast<DH *>(other.dof_handler))
 {
@@ -101,10 +101,10 @@ DoFAccessor<structdim,DH,lda>::DoFAccessor (const DoFAccessor<structdim, DH, lda
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<structdim,DH,lda>::set_dof_handler (DH *dh)
+DoFAccessor<structdim,DH,level_dof_access>::set_dof_handler (DH *dh)
 {
   Assert (dh != 0, ExcInvalidObject());
   this->dof_handler = dh;
@@ -112,20 +112,20 @@ DoFAccessor<structdim,DH,lda>::set_dof_handler (DH *dh)
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
 const DH &
-DoFAccessor<structdim,DH,lda>::get_dof_handler () const
+DoFAccessor<structdim,DH,level_dof_access>::get_dof_handler () const
 {
   return *this->dof_handler;
 }
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<structdim,DH,lda>::copy_from (
+DoFAccessor<structdim,DH,level_dof_access>::copy_from (
   const TriaAccessorBase<structdim, DH::dimension, DH::space_dimension> &da)
 {
   Assert (this->dof_handler != 0, ExcInvalidObject());
@@ -134,11 +134,11 @@ DoFAccessor<structdim,DH,lda>::copy_from (
 
 
 
-template <int structdim, class DH, bool lda>
-template <bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <bool level_dof_access2>
 inline
 void
-DoFAccessor<structdim,DH,lda>::copy_from (const DoFAccessor<structdim,DH,lda2> &a)
+DoFAccessor<structdim,DH,level_dof_access>::copy_from (const DoFAccessor<structdim,DH,level_dof_access2> &a)
 {
   BaseClass::copy_from (a);
   set_dof_handler (a.dof_handler);
@@ -146,11 +146,11 @@ DoFAccessor<structdim,DH,lda>::copy_from (const DoFAccessor<structdim,DH,lda2> &
 
 
 
-template <int structdim, class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
 bool
-DoFAccessor<structdim,DH,lda>::operator == (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<structdim,DH,level_dof_access>::operator == (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
 {
   Assert (structdim == dim2, ExcCantCompareIterators());
   Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
@@ -159,11 +159,11 @@ DoFAccessor<structdim,DH,lda>::operator == (const DoFAccessor<dim2,DH2,lda2> &a)
 
 
 
-template <int structdim, class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <int structdim, class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
 bool
-DoFAccessor<structdim,DH,lda>::operator != (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<structdim,DH,level_dof_access>::operator != (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
 {
   Assert (structdim == dim2, ExcCantCompareIterators());
   Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
@@ -172,10 +172,10 @@ DoFAccessor<structdim,DH,lda>::operator != (const DoFAccessor<dim2,DH2,lda2> &a)
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
-TriaIterator<DoFAccessor<structdim,DH,lda> >
-DoFAccessor<structdim,DH,lda>::child (const unsigned int i) const
+TriaIterator<DoFAccessor<structdim,DH,level_dof_access> >
+DoFAccessor<structdim,DH,level_dof_access>::child (const unsigned int i) const
 {
   Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
           ExcMessage ("DoFHandler not initialized"));
@@ -183,15 +183,15 @@ DoFAccessor<structdim,DH,lda>::child (const unsigned int i) const
   TriaIterator<TriaAccessor<structdim,DH::dimension,DH::space_dimension> >
   t = TriaAccessor<structdim,DH::dimension,DH::space_dimension>::child(i);
 
-  TriaIterator<DoFAccessor<structdim,DH,lda> > q (*t, this->dof_handler);
+  TriaIterator<DoFAccessor<structdim,DH,level_dof_access> > q (*t, this->dof_handler);
   return q;
 }
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
-TriaIterator<DoFAccessor<structdim,DH,lda> >
-DoFAccessor<structdim,DH,lda>::parent () const
+TriaIterator<DoFAccessor<structdim,DH,level_dof_access> >
+DoFAccessor<structdim,DH,level_dof_access>::parent () const
 {
   Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
           ExcMessage ("DoFHandler not initialized"));
@@ -206,7 +206,7 @@ DoFAccessor<structdim,DH,lda>::parent () const
   else
     previous_level = 0;
 
-  TriaIterator<DoFAccessor<structdim,DH,lda> > q (this->tria,
+  TriaIterator<DoFAccessor<structdim,DH,level_dof_access> > q (this->tria,
                                                   previous_level,
                                                   this->parent_index (),
                                                   this->dof_handler);
@@ -1421,9 +1421,9 @@ namespace internal
           }
       }
 
-      template<class DH, bool lda>
+      template<class DH, bool level_dof_access>
       static
-      void set_mg_dof_indices (const dealii::DoFAccessor<1,DH,lda> &,
+      void set_mg_dof_indices (const dealii::DoFAccessor<1,DH,level_dof_access> &,
                                const int,
                                const std::vector<types::global_dof_index> &,
                                const unsigned int)
@@ -1433,9 +1433,9 @@ namespace internal
 
 
 
-      template<class DH, bool lda>
+      template<class DH, bool level_dof_access>
       static
-      void set_mg_dof_indices (dealii::DoFAccessor<2, DH,lda> &accessor,
+      void set_mg_dof_indices (dealii::DoFAccessor<2, DH,level_dof_access> &accessor,
                                const int level,
                                const std::vector<types::global_dof_index> &dof_indices,
                                const unsigned int fe_index)
@@ -1459,9 +1459,9 @@ namespace internal
 
 
 
-      template<class DH, bool lda>
+      template<class DH, bool level_dof_access>
       static
-      void set_mg_dof_indices (const dealii::DoFAccessor<3, DH,lda> &,
+      void set_mg_dof_indices (const dealii::DoFAccessor<3, DH,level_dof_access> &,
                                const int,
                                const std::vector<types::global_dof_index> &,
                                const unsigned int)
@@ -1475,10 +1475,10 @@ namespace internal
 
 
 
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
 inline
 types::global_dof_index
-DoFAccessor<dim,DH,lda>::dof_index (const unsigned int i,
+DoFAccessor<dim,DH,level_dof_access>::dof_index (const unsigned int i,
                                     const unsigned int fe_index) const
 {
   // access the respective DoF
@@ -1491,20 +1491,20 @@ DoFAccessor<dim,DH,lda>::dof_index (const unsigned int i,
 }
 
 
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
 inline
 types::global_dof_index
-DoFAccessor<structdim, DH,lda>::mg_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::mg_dof_index (const int level,
                                               const unsigned int i) const
 {
   return this->dof_handler->template get_dof_index<structdim> (level, this->present_index, 0, i);
 }
 
 
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<dim,DH,lda>::set_dof_index (const unsigned int i,
+DoFAccessor<dim,DH,level_dof_access>::set_dof_index (const unsigned int i,
                                         const types::global_dof_index index,
                                         const unsigned int fe_index) const
 {
@@ -1520,10 +1520,10 @@ DoFAccessor<dim,DH,lda>::set_dof_index (const unsigned int i,
 
 
 
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
 inline
 unsigned int
-DoFAccessor<dim,DH,lda>::n_active_fe_indices () const
+DoFAccessor<dim,DH,level_dof_access>::n_active_fe_indices () const
 {
   // access the respective DoF
   return
@@ -1536,10 +1536,10 @@ DoFAccessor<dim,DH,lda>::n_active_fe_indices () const
 
 
 
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
 inline
 unsigned int
-DoFAccessor<dim,DH,lda>::nth_active_fe_index (const unsigned int n) const
+DoFAccessor<dim,DH,level_dof_access>::nth_active_fe_index (const unsigned int n) const
 {
   // access the respective DoF
   return
@@ -1553,10 +1553,10 @@ DoFAccessor<dim,DH,lda>::nth_active_fe_index (const unsigned int n) const
 
 
 
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
 inline
 bool
-DoFAccessor<dim,DH,lda>::fe_index_is_active (const unsigned int fe_index) const
+DoFAccessor<dim,DH,level_dof_access>::fe_index_is_active (const unsigned int fe_index) const
 {
   // access the respective DoF
   return
@@ -1570,10 +1570,10 @@ DoFAccessor<dim,DH,lda>::fe_index_is_active (const unsigned int fe_index) const
 
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
 types::global_dof_index
-DoFAccessor<structdim, DH,lda>::vertex_dof_index (const unsigned int vertex,
+DoFAccessor<structdim, DH,level_dof_access>::vertex_dof_index (const unsigned int vertex,
                                                   const unsigned int i,
                                                   const unsigned int fe_index) const
 {
@@ -1586,10 +1586,10 @@ DoFAccessor<structdim, DH,lda>::vertex_dof_index (const unsigned int vertex,
 }
 
 
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
 inline
 types::global_dof_index
-DoFAccessor<structdim, DH,lda>::mg_vertex_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::mg_vertex_dof_index (const int level,
                                                      const unsigned int vertex,
                                                      const unsigned int i,
                                                      const unsigned int fe_index) const
@@ -1602,10 +1602,10 @@ DoFAccessor<structdim, DH,lda>::mg_vertex_dof_index (const int level,
 }
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<structdim, DH,lda>::set_vertex_dof_index (const unsigned int vertex,
+DoFAccessor<structdim, DH,level_dof_access>::set_vertex_dof_index (const unsigned int vertex,
                                                       const unsigned int i,
                                                       const types::global_dof_index index,
                                                       const unsigned int fe_index) const
@@ -1619,10 +1619,10 @@ DoFAccessor<structdim, DH,lda>::set_vertex_dof_index (const unsigned int vertex,
 }
 
 
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<structdim, DH,lda>::set_mg_vertex_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::set_mg_vertex_dof_index (const int level,
                                                          const unsigned int vertex,
                                                          const unsigned int i,
                                                          const types::global_dof_index index,
@@ -1636,10 +1636,10 @@ DoFAccessor<structdim, DH,lda>::set_mg_vertex_dof_index (const int level,
 }
 
 
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<structdim, DH,lda>::set_mg_dof_index (const int level,
+DoFAccessor<structdim, DH,level_dof_access>::set_mg_dof_index (const int level,
                                                   const unsigned int i,
                                                   const types::global_dof_index index) const
 {
@@ -1674,10 +1674,10 @@ namespace internal
 }
 
 
-template <int dim, class DH, bool lda>
+template <int dim, class DH, bool level_dof_access>
 inline
 const FiniteElement<DH::dimension,DH::space_dimension> &
-DoFAccessor<dim,DH,lda>::get_fe (const unsigned int fe_index) const
+DoFAccessor<dim,DH,level_dof_access>::get_fe (const unsigned int fe_index) const
 {
   Assert (fe_index_is_active (fe_index) == true,
           ExcMessage ("This function can only be called for active fe indices"));
@@ -1691,8 +1691,8 @@ namespace internal
 {
   namespace DoFAccessor
   {
-    template <class DH, bool lda>
-    void get_dof_indices (const dealii::DoFAccessor<1,DH,lda>   &accessor,
+    template <class DH, bool level_dof_access>
+    void get_dof_indices (const dealii::DoFAccessor<1,DH,level_dof_access>   &accessor,
                           std::vector<types::global_dof_index> &dof_indices,
                           const unsigned int         fe_index)
     {
@@ -1708,8 +1708,8 @@ namespace internal
 
 
 
-    template <class DH, bool lda>
-    void get_dof_indices (const dealii::DoFAccessor<2,DH,lda>   &accessor,
+    template <class DH, bool level_dof_access>
+    void get_dof_indices (const dealii::DoFAccessor<2,DH,level_dof_access>   &accessor,
                           std::vector<types::global_dof_index> &dof_indices,
                           const unsigned int         fe_index)
     {
@@ -1743,8 +1743,8 @@ namespace internal
 
 
 
-    template <class DH, bool lda>
-    void get_dof_indices (const dealii::DoFAccessor<3,DH,lda>   &accessor,
+    template <class DH, bool level_dof_access>
+    void get_dof_indices (const dealii::DoFAccessor<3,DH,level_dof_access>   &accessor,
                           std::vector<types::global_dof_index> &dof_indices,
                           const unsigned int         fe_index)
     {
@@ -1799,8 +1799,8 @@ namespace internal
 
 
 
-    template<class DH, bool lda>
-    void get_mg_dof_indices (const dealii::DoFAccessor<1, DH,lda> &accessor,
+    template<class DH, bool level_dof_access>
+    void get_mg_dof_indices (const dealii::DoFAccessor<1, DH,level_dof_access> &accessor,
                              const int level,
                              std::vector<types::global_dof_index> &dof_indices,
                              const unsigned int fe_index)
@@ -1825,8 +1825,8 @@ namespace internal
 
 
 
-    template<class DH, bool lda>
-    void get_mg_dof_indices (const dealii::DoFAccessor<2, DH,lda> &accessor,
+    template<class DH, bool level_dof_access>
+    void get_mg_dof_indices (const dealii::DoFAccessor<2, DH,level_dof_access> &accessor,
                              const int level,
                              std::vector<types::global_dof_index> &dof_indices,
                              const unsigned int fe_index)
@@ -1854,8 +1854,8 @@ namespace internal
 
 
 
-    template<class DH, bool lda>
-    void get_mg_dof_indices (const dealii::DoFAccessor<3, DH,lda> &accessor,
+    template<class DH, bool level_dof_access>
+    void get_mg_dof_indices (const dealii::DoFAccessor<3, DH,level_dof_access> &accessor,
                              const int level,
                              std::vector<types::global_dof_index> &dof_indices,
                              const unsigned int fe_index)
@@ -1890,10 +1890,10 @@ namespace internal
 }
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
 void
-DoFAccessor<structdim,DH,lda>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices,
+DoFAccessor<structdim,DH,level_dof_access>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices,
                                                 const unsigned int         fe_index) const
 {
   Assert (this->dof_handler != 0, ExcNotInitialized());
@@ -1953,9 +1953,9 @@ DoFAccessor<structdim,DH,lda>::get_dof_indices (std::vector<types::global_dof_in
 
 
 
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
 inline
-void DoFAccessor<structdim, DH,lda>::get_mg_dof_indices (const int level,
+void DoFAccessor<structdim, DH,level_dof_access>::get_mg_dof_indices (const int level,
                                                          std::vector<types::global_dof_index> &dof_indices,
                                                          const unsigned int fe_index) const
 {
@@ -2005,9 +2005,9 @@ void DoFAccessor<structdim, DH,lda>::get_mg_dof_indices (const int level,
 }
 
 
-template<int structdim, class DH, bool lda>
+template<int structdim, class DH, bool level_dof_access>
 inline
-void DoFAccessor<structdim, DH,lda>::set_mg_dof_indices (const int level,
+void DoFAccessor<structdim, DH,level_dof_access>::set_mg_dof_indices (const int level,
                                                          const std::vector<types::global_dof_index> &dof_indices,
                                                          const unsigned int fe_index)
 {
@@ -2061,9 +2061,9 @@ namespace internal
 {
   namespace DoFAccessor
   {
-    template <bool lda, class DH>
+    template <bool level_dof_access, class DH>
     inline
-    typename dealii::internal::DoFHandler::Iterators<DH, lda>::quad_iterator
+    typename dealii::internal::DoFHandler::Iterators<DH, level_dof_access>::quad_iterator
     get_quad(const dealii::Triangulation<DH::dimension, DH::space_dimension> *tria,
              unsigned int index,
              DH *dof_handler)
@@ -2071,57 +2071,57 @@ namespace internal
     }
 
 
-    template<bool lda>
+    template<bool level_dof_access>
     inline
-    typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, lda>::quad_iterator
+    typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, level_dof_access>::quad_iterator
     get_quad(const dealii::Triangulation<2,2> *,
              unsigned int,
              dealii::DoFHandler<2,2> *)
     {
       Assert(false, ExcNotImplemented());
-      return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, lda>::line_iterator();
+      return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,2>, level_dof_access>::line_iterator();
     }
 
-    template<bool lda>
+    template<bool level_dof_access>
     inline
-    typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, lda>::quad_iterator
+    typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, level_dof_access>::quad_iterator
     get_quad(const dealii::Triangulation<2,3> *,
              unsigned int,
              dealii::DoFHandler<2,3> *)
     {
       Assert(false, ExcNotImplemented());
-      return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, lda>::line_iterator();
+      return typename dealii::internal::DoFHandler::Iterators<dealii::DoFHandler<2,3>, level_dof_access>::line_iterator();
     }
 
-    template<bool lda>
+    template<bool level_dof_access>
     inline
-    typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, lda>::quad_iterator
+    typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, level_dof_access>::quad_iterator
     get_quad(const dealii::Triangulation<2,2> *,
              unsigned int,
              dealii::hp::DoFHandler<2,2> *)
     {
       Assert(false, ExcNotImplemented());
-      return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, lda>::line_iterator();
+      return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,2>, level_dof_access>::line_iterator();
     }
 
-    template<bool lda>
+    template<bool level_dof_access>
     inline
-    typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, lda>::quad_iterator
+    typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, level_dof_access>::quad_iterator
     get_quad(const dealii::Triangulation<2,3> *,
              unsigned int,
              dealii::hp::DoFHandler<2,3> *)
     {
       Assert(false, ExcNotImplemented());
-      return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, lda>::line_iterator();
+      return typename dealii::internal::DoFHandler::Iterators<dealii::hp::DoFHandler<2,3>, level_dof_access>::line_iterator();
     }
   }
 }
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
-typename dealii::internal::DoFHandler::Iterators<DH,lda>::line_iterator
-DoFAccessor<structdim,DH,lda>::line (const unsigned int i) const
+typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::line_iterator
+DoFAccessor<structdim,DH,level_dof_access>::line (const unsigned int i) const
 {
   // if we are asking for a particular line and this object refers to
   // a line, then the only valid index is i==0 and we should return
@@ -2131,7 +2131,7 @@ DoFAccessor<structdim,DH,lda>::line (const unsigned int i) const
       Assert (i==0, ExcMessage ("You can only ask for line zero if the "
                                 "current object is a line itself."));
       return
-        typename dealii::internal::DoFHandler::Iterators<DH,lda>::cell_iterator
+        typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::cell_iterator
         (&this->get_triangulation(),
          this->level(),
          this->index(),
@@ -2143,7 +2143,7 @@ DoFAccessor<structdim,DH,lda>::line (const unsigned int i) const
   Assert (DH::dimension > 1, ExcImpossibleInDim(DH::dimension));
 
   // checking of 'i' happens in line_index(i)
-  return typename dealii::internal::DoFHandler::Iterators<DH,lda>::line_iterator
+  return typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::line_iterator
          (this->tria,
           0,  // only sub-objects are allowed, which have no level
           this->line_index(i),
@@ -2151,10 +2151,10 @@ DoFAccessor<structdim,DH,lda>::line (const unsigned int i) const
 }
 
 
-template <int structdim, class DH, bool lda>
+template <int structdim, class DH, bool level_dof_access>
 inline
-typename dealii::internal::DoFHandler::Iterators<DH,lda>::quad_iterator
-DoFAccessor<structdim,DH,lda>::quad (const unsigned int i) const
+typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::quad_iterator
+DoFAccessor<structdim,DH,level_dof_access>::quad (const unsigned int i) const
 {
   // if we are asking for a
   // particular quad and this object
@@ -2178,7 +2178,7 @@ DoFAccessor<structdim,DH,lda>::quad (const unsigned int i) const
   Assert (DH::dimension > 2, ExcImpossibleInDim(DH::dimension));
 
   // checking of 'i' happens in quad_index(i)
-  return typename dealii::internal::DoFHandler::Iterators<DH,lda>::quad_iterator
+  return typename dealii::internal::DoFHandler::Iterators<DH,level_dof_access>::quad_iterator
          (this->tria,
           0,  // only sub-objects are allowed, which have no level
           this->quad_index(i),
@@ -2189,18 +2189,18 @@ DoFAccessor<structdim,DH,lda>::quad (const unsigned int i) const
 /*------------------------- Functions: DoFAccessor<0,1,spacedim> ---------------------------*/
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
-DoFAccessor<0,DH<1,spacedim>, lda>::DoFAccessor ()
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::DoFAccessor ()
 {
   Assert (false, ExcInvalidObject());
 }
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
-DoFAccessor<0,DH<1,spacedim>, lda>::
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::
 DoFAccessor (const Triangulation<1,spacedim> *tria,
              const typename TriaAccessor<0,1,spacedim>::VertexKind vertex_kind,
              const unsigned int    vertex_index,
@@ -2214,9 +2214,9 @@ DoFAccessor (const Triangulation<1,spacedim> *tria,
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
-DoFAccessor<0,DH<1,spacedim>, lda>::
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::
 DoFAccessor (const Triangulation<1,spacedim> *,
              const int                 ,
              const int                 ,
@@ -2230,29 +2230,29 @@ DoFAccessor (const Triangulation<1,spacedim> *,
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 template <int structdim2, int dim2, int spacedim2>
-DoFAccessor<0,DH<1,spacedim>, lda>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::DoFAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
 {
   Assert (false, ExcInvalidObject());
 }
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
-DoFAccessor<0,DH<1,spacedim>, lda>::DoFAccessor (const DoFAccessor<dim2, DH2, lda2> &)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::DoFAccessor (const DoFAccessor<dim2, DH2, level_dof_access2> &)
 {
   Assert (false, ExcInvalidObject());
 }
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
 void
-DoFAccessor<0,DH<1,spacedim>, lda>::set_dof_handler (DH<1,spacedim> *dh)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::set_dof_handler (DH<1,spacedim> *dh)
 {
   Assert (dh != 0, ExcInvalidObject());
   this->dof_handler = dh;
@@ -2260,20 +2260,20 @@ DoFAccessor<0,DH<1,spacedim>, lda>::set_dof_handler (DH<1,spacedim> *dh)
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
 const DH<1,spacedim> &
-DoFAccessor<0,DH<1,spacedim>, lda>::get_dof_handler () const
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::get_dof_handler () const
 {
   return *this->dof_handler;
 }
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
 void
-DoFAccessor<0,DH<1,spacedim>, lda>::get_dof_indices (
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::get_dof_indices (
   std::vector<types::global_dof_index> &dof_indices,
   const unsigned int fe_index) const
 {
@@ -2288,10 +2288,10 @@ DoFAccessor<0,DH<1,spacedim>, lda>::get_dof_indices (
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
 types::global_dof_index
-DoFAccessor<0,DH<1,spacedim>, lda>::
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::
 vertex_dof_index (const unsigned int vertex,
                   const unsigned int i,
                   const unsigned int fe_index) const
@@ -2306,10 +2306,10 @@ vertex_dof_index (const unsigned int vertex,
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
 inline
 void
-DoFAccessor<0,DH<1,spacedim>, lda>::copy_from (const TriaAccessorBase<0,1,spacedim> &da)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::copy_from (const TriaAccessorBase<0,1,spacedim> &da)
 {
   Assert (this->dof_handler != 0, ExcInvalidObject());
   BaseClass::copy_from(da);
@@ -2317,11 +2317,11 @@ DoFAccessor<0,DH<1,spacedim>, lda>::copy_from (const TriaAccessorBase<0,1,spaced
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
-template <bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <bool level_dof_access2>
 inline
 void
-DoFAccessor<0,DH<1,spacedim>, lda>::copy_from (const DoFAccessor<0,DH<1,spacedim>, lda2> &a)
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::copy_from (const DoFAccessor<0,DH<1,spacedim>, level_dof_access2> &a)
 {
   BaseClass::copy_from (a);
   set_dof_handler (a.dof_handler);
@@ -2329,11 +2329,11 @@ DoFAccessor<0,DH<1,spacedim>, lda>::copy_from (const DoFAccessor<0,DH<1,spacedim
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
 bool
-DoFAccessor<0,DH<1,spacedim>, lda>::operator == (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::operator == (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
 {
   Assert (dim2 == 0, ExcCantCompareIterators());
   Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
@@ -2342,11 +2342,11 @@ DoFAccessor<0,DH<1,spacedim>, lda>::operator == (const DoFAccessor<dim2,DH2,lda2
 
 
 
-template <template <int, int> class DH, int spacedim, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <template <int, int> class DH, int spacedim, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
 bool
-DoFAccessor<0,DH<1,spacedim>, lda>::operator != (const DoFAccessor<dim2,DH2,lda2> &a) const
+DoFAccessor<0,DH<1,spacedim>, level_dof_access>::operator != (const DoFAccessor<dim2,DH2,level_dof_access2> &a) const
 {
   Assert (dim2 == 0, ExcCantCompareIterators());
   Assert (this->dof_handler == a.dof_handler, ExcCantCompareIterators());
@@ -2381,10 +2381,10 @@ namespace internal
        * implemented for hp::DoFHandler
        * objects.
        */
-      template <int spacedim, bool lda>
+      template <int spacedim, bool level_dof_access>
       static
       void
-      update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<1,spacedim>, lda> &accessor)
+      update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<1,spacedim>, level_dof_access> &accessor)
       {
         // check as in documentation that
         // cell is either active, or dofs
@@ -2426,10 +2426,10 @@ namespace internal
 
 
 
-      template <int spacedim, bool lda>
+      template <int spacedim, bool level_dof_access>
       static
       void
-      update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<2,spacedim>, lda> &accessor)
+      update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<2,spacedim>, level_dof_access> &accessor)
       {
         // check as in documentation that
         // cell is either active, or dofs
@@ -2474,10 +2474,10 @@ namespace internal
       }
 
 
-      template <int spacedim, bool lda>
+      template <int spacedim, bool level_dof_access>
       static
       void
-      update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<3,spacedim>, lda> &accessor)
+      update_cell_dof_indices_cache (const DoFCellAccessor<DoFHandler<3,spacedim>, level_dof_access> &accessor)
       {
         // check as in documentation that
         // cell is either active, or dofs
@@ -2560,10 +2560,10 @@ namespace internal
       // hp::DoFHandler objects. it's
       // not implemented there, for no
       // space dimension
-      template <int dim, int spacedim, bool lda>
+      template <int dim, int spacedim, bool level_dof_access>
       static
       void
-      update_cell_dof_indices_cache (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor)
+      update_cell_dof_indices_cache (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor)
       {
         // caches are only for cells with DoFs, i.e., for active ones
         if (accessor.has_children())
@@ -2588,7 +2588,7 @@ namespace internal
                 ExcInternalError());
 
         std::vector<types::global_dof_index> dof_indices (dofs_per_cell);
-        static_cast<const dealii::DoFAccessor<dim,dealii::hp::DoFHandler<dim,spacedim>,lda> &>
+        static_cast<const dealii::DoFAccessor<dim,dealii::hp::DoFHandler<dim,spacedim>,level_dof_access> &>
         (accessor).get_dof_indices (dof_indices, accessor.active_fe_index());
 
         types::global_dof_index *next_dof_index
@@ -2608,10 +2608,10 @@ namespace internal
        * implemented for
        * hp::DoFHandler objects.
        */
-      template <int spacedim, bool lda>
+      template <int spacedim, bool level_dof_access>
       static
       void
-      set_dof_indices (DoFCellAccessor<DoFHandler<1,spacedim>, lda> &accessor,
+      set_dof_indices (DoFCellAccessor<DoFHandler<1,spacedim>, level_dof_access> &accessor,
                        const std::vector<types::global_dof_index>          &local_dof_indices)
       {
         Assert (accessor.has_children() == false,
@@ -2640,10 +2640,10 @@ namespace internal
 
 
 
-      template <int spacedim, bool lda>
+      template <int spacedim, bool level_dof_access>
       static
       void
-      set_dof_indices (DoFCellAccessor<DoFHandler<2,spacedim>, lda> &accessor,
+      set_dof_indices (DoFCellAccessor<DoFHandler<2,spacedim>, level_dof_access> &accessor,
                        const std::vector<types::global_dof_index>          &local_dof_indices)
       {
         Assert (accessor.has_children() == false,
@@ -2676,10 +2676,10 @@ namespace internal
 
 
 
-      template <int spacedim, bool lda>
+      template <int spacedim, bool level_dof_access>
       static
       void
-      set_dof_indices (DoFCellAccessor<DoFHandler<3,spacedim>, lda> &accessor,
+      set_dof_indices (DoFCellAccessor<DoFHandler<3,spacedim>, level_dof_access> &accessor,
                        const std::vector<types::global_dof_index>          &local_dof_indices)
       {
         Assert (accessor.has_children() == false,
@@ -2750,10 +2750,10 @@ namespace internal
       // hp::DoFHandler objects. it's
       // not implemented there, for no
       // space dimension
-      template <int dim, int spacedim, bool lda>
+      template <int dim, int spacedim, bool level_dof_access>
       static
       void
-      set_dof_indices (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &,
+      set_dof_indices (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &,
                        const std::vector<types::global_dof_index> &)
       {
         Assert (false, ExcNotImplemented());
@@ -2766,10 +2766,10 @@ namespace internal
        * function in the parent class
        * is supposed to do.
        */
-      template <int dim, int spacedim, bool lda>
+      template <int dim, int spacedim, bool level_dof_access>
       static
       unsigned int
-      active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, lda> &)
+      active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, level_dof_access> &)
       {
         // ::DoFHandler only supports a
         // single active fe with index
@@ -2779,10 +2779,10 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda>
+      template <int dim, int spacedim, bool level_dof_access>
       static
       unsigned int
-      active_fe_index (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor)
+      active_fe_index (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor)
       {
         Assert (static_cast<unsigned int>(accessor.level()) < accessor.dof_handler->levels.size(),
                 ExcMessage ("DoFHandler not initialized"));
@@ -2799,28 +2799,28 @@ namespace internal
        * in the parent class is
        * supposed to do.
        */
-      template <int dim, int spacedim, bool lda>
+      template <int dim, int spacedim, bool level_dof_access>
       static
       void
-      set_active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, lda> &,
+      set_active_fe_index (const DoFCellAccessor<DoFHandler<dim,spacedim>, level_dof_access> &,
                            const unsigned int                                i)
       {
         // ::DoFHandler only supports a
         // single active fe with index
         // zero
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (i == 0, typename BaseClass::ExcInvalidObject());
       }
 
 
 
-      template <int dim, int spacedim, bool lda>
+      template <int dim, int spacedim, bool level_dof_access>
       static
       void
-      set_active_fe_index (DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+      set_active_fe_index (DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                            const unsigned int                                      i)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (static_cast<unsigned int>(accessor.level()) <
@@ -2833,15 +2833,15 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+      template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   ForwardIterator local_source_begin,
                                   ForwardIterator local_source_end,
                                   OutputVector   &global_destination)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -2867,15 +2867,15 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+      template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   ForwardIterator local_source_begin,
                                   ForwardIterator local_source_end,
                                   OutputVector   &global_destination)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -2899,16 +2899,16 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+      template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   const ConstraintMatrix &constraints,
                                   ForwardIterator         local_source_begin,
                                   ForwardIterator         local_source_end,
                                   OutputVector           &global_destination)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -2933,16 +2933,16 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename ForwardIterator, class OutputVector>
+      template <int dim, int spacedim, bool level_dof_access, typename ForwardIterator, class OutputVector>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   const ConstraintMatrix &constraints,
                                   ForwardIterator         local_source_begin,
                                   ForwardIterator         local_source_end,
                                   OutputVector           &global_destination)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -2967,14 +2967,14 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename number, class OutputMatrix>
+      template <int dim, int spacedim, bool level_dof_access, typename number, class OutputMatrix>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   const dealii::FullMatrix<number> &local_source,
                                   OutputMatrix                     &global_destination)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -3004,14 +3004,14 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename number, class OutputMatrix>
+      template <int dim, int spacedim, bool level_dof_access, typename number, class OutputMatrix>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   const dealii::FullMatrix<number> &local_source,
                                   OutputMatrix                     &global_destination)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -3039,17 +3039,17 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename number,
+      template <int dim, int spacedim, bool level_dof_access, typename number,
                 class OutputMatrix, typename OutputVector>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   const dealii::FullMatrix<number> &local_matrix,
                                   const dealii::Vector<number>     &local_vector,
                                   OutputMatrix                     &global_matrix,
                                   OutputVector                     &global_vector)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -3084,17 +3084,17 @@ namespace internal
 
 
 
-      template <int dim, int spacedim, bool lda, typename number,
+      template <int dim, int spacedim, bool level_dof_access, typename number,
                 class OutputMatrix, typename OutputVector>
       static
       void
-      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, lda> &accessor,
+      distribute_local_to_global (const DoFCellAccessor<dealii::hp::DoFHandler<dim,spacedim>, level_dof_access> &accessor,
                                   const dealii::FullMatrix<number> &local_matrix,
                                   const dealii::Vector<number>     &local_vector,
                                   OutputMatrix                     &global_matrix,
                                   OutputVector                     &global_vector)
       {
-        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, lda> BaseClass;
+        typedef dealii::DoFAccessor<dim,DoFHandler<dim,spacedim>, level_dof_access> BaseClass;
         Assert (accessor.dof_handler != 0,
                 typename BaseClass::ExcInvalidObject());
         Assert (&accessor.get_fe() != 0,
@@ -3132,43 +3132,43 @@ namespace internal
 }
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
-DoFCellAccessor<DH,lda>::DoFCellAccessor (
+DoFCellAccessor<DH,level_dof_access>::DoFCellAccessor (
   const Triangulation<DH::dimension,DH::space_dimension> *tria,
   const int                 level,
   const int                 index,
   const AccessorData       *local_data)
   :
-  DoFAccessor<DH::dimension,DH,lda> (tria,level,index, local_data)
+  DoFAccessor<DH::dimension,DH,level_dof_access> (tria,level,index, local_data)
 {}
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <int structdim2, int dim2, int spacedim2>
 inline
-DoFCellAccessor<DH,lda>::DoFCellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
+DoFCellAccessor<DH,level_dof_access>::DoFCellAccessor (const InvalidAccessor<structdim2,dim2,spacedim2> &)
 {
   Assert (false, typename BaseClass::ExcInvalidObject());
 }
 
 
 
-template <class DH, bool lda>
-template <int dim2, class DH2, bool lda2>
+template <class DH, bool level_dof_access>
+template <int dim2, class DH2, bool level_dof_access2>
 inline
-DoFCellAccessor<DH,lda>::DoFCellAccessor (const DoFAccessor<dim2,DH2,lda2> &other)
+DoFCellAccessor<DH,level_dof_access>::DoFCellAccessor (const DoFAccessor<dim2,DH2,level_dof_access2> &other)
   :
   BaseClass(other)
 {}
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
-TriaIterator<DoFCellAccessor<DH,lda> >
-DoFCellAccessor<DH,lda>::neighbor (const unsigned int i) const
+TriaIterator<DoFCellAccessor<DH,level_dof_access> >
+DoFCellAccessor<DH,level_dof_access>::neighbor (const unsigned int i) const
 {
-  TriaIterator<DoFCellAccessor<DH,lda> >
+  TriaIterator<DoFCellAccessor<DH,level_dof_access> >
   q (this->tria,
      this->neighbor_level (i),
      this->neighbor_index (i),
@@ -3182,12 +3182,12 @@ DoFCellAccessor<DH,lda>::neighbor (const unsigned int i) const
 }
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
-TriaIterator<DoFCellAccessor<DH,lda> >
-DoFCellAccessor<DH,lda>::child (const unsigned int i) const
+TriaIterator<DoFCellAccessor<DH,level_dof_access> >
+DoFCellAccessor<DH,level_dof_access>::child (const unsigned int i) const
 {
-  TriaIterator<DoFCellAccessor<DH,lda> >
+  TriaIterator<DoFCellAccessor<DH,level_dof_access> >
   q (this->tria,
      this->level()+1,
      this->child_index (i),
@@ -3201,12 +3201,12 @@ DoFCellAccessor<DH,lda>::child (const unsigned int i) const
 }
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
-TriaIterator<DoFCellAccessor<DH,lda> >
-DoFCellAccessor<DH,lda>::parent () const
+TriaIterator<DoFCellAccessor<DH,level_dof_access> >
+DoFCellAccessor<DH,level_dof_access>::parent () const
 {
-  TriaIterator<DoFCellAccessor<DH,lda> >
+  TriaIterator<DoFCellAccessor<DH,level_dof_access> >
   q (this->tria,
      this->level() - 1,
      this->parent_index (),
@@ -3220,14 +3220,14 @@ namespace internal
 {
   namespace DoFCellAccessor
   {
-    template <class DH, bool lda>
+    template <class DH, bool level_dof_access>
     inline
-    TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,lda> >
-    get_face (const dealii::DoFCellAccessor<DH,lda> &cell,
+    TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,level_dof_access> >
+    get_face (const dealii::DoFCellAccessor<DH,level_dof_access> &cell,
               const unsigned int i,
               const dealii::internal::int2type<1>)
     {
-      dealii::DoFAccessor<0, DH,lda>
+      dealii::DoFAccessor<0, DH,level_dof_access>
       a (&cell.get_triangulation(),
          ((i == 0) && cell.at_boundary(0)
           ?
@@ -3240,14 +3240,14 @@ namespace internal
            dealii::TriaAccessor<0, 1, DH::space_dimension>::interior_vertex)),
          cell.vertex_index(i),
          &cell.get_dof_handler());
-      return dealii::TriaIterator<dealii::DoFAccessor<0,DH,lda> > (a);
+      return dealii::TriaIterator<dealii::DoFAccessor<0,DH,level_dof_access> > (a);
     }
 
 
-    template <class DH, bool lda>
+    template <class DH, bool level_dof_access>
     inline
-    TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,lda> >
-    get_face (const dealii::DoFCellAccessor<DH,lda> &cell,
+    TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,level_dof_access> >
+    get_face (const dealii::DoFCellAccessor<DH,level_dof_access> &cell,
               const unsigned int i,
               const dealii::internal::int2type<2>)
     {
@@ -3255,10 +3255,10 @@ namespace internal
     }
 
 
-    template <class DH, bool lda>
+    template <class DH, bool level_dof_access>
     inline
-    TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,lda> >
-    get_face (const dealii::DoFCellAccessor<DH,lda> &cell,
+    TriaIterator<dealii::DoFAccessor<DH::dimension-1,DH,level_dof_access> >
+    get_face (const dealii::DoFCellAccessor<DH,level_dof_access> &cell,
               const unsigned int i,
               const dealii::internal::int2type<3>)
     {
@@ -3268,10 +3268,10 @@ namespace internal
 }
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
-TriaIterator<DoFAccessor<DH::dimension-1,DH,lda> >
-DoFCellAccessor<DH,lda>::face (const unsigned int i) const
+typename DoFCellAccessor<DH,level_dof_access>::face_iterator
+DoFCellAccessor<DH,level_dof_access>::face (const unsigned int i) const
 {
   Assert (i<GeometryInfo<dim>::faces_per_cell, ExcIndexRange (i, 0, GeometryInfo<dim>::faces_per_cell));
   Assert (static_cast<unsigned int>(this->level()) < this->dof_handler->levels.size(),
@@ -3283,10 +3283,10 @@ DoFCellAccessor<DH,lda>::face (const unsigned int i) const
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
 void
-DoFCellAccessor<DH,lda>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
+DoFCellAccessor<DH,level_dof_access>::get_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
 {
   Assert (this->active(), ExcMessage ("get_dof_indices() only works on active cells."));
   Assert (this->is_artificial() == false,
@@ -3302,29 +3302,29 @@ DoFCellAccessor<DH,lda>::get_dof_indices (std::vector<types::global_dof_index> &
 
 
 
-template<class DH, bool lda>
+template<class DH, bool level_dof_access>
 inline
-void DoFCellAccessor<DH,lda>::get_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
+void DoFCellAccessor<DH,level_dof_access>::get_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
 {
-  DoFAccessor<dim, DH,lda>::get_mg_dof_indices (this->level (), dof_indices);
+  DoFAccessor<dim, DH,level_dof_access>::get_mg_dof_indices (this->level (), dof_indices);
 }
 
 
 
-template<class DH, bool lda>
+template<class DH, bool level_dof_access>
 inline
-void DoFCellAccessor<DH,lda>::set_mg_dof_indices (const std::vector<types::global_dof_index> &dof_indices)
+void DoFCellAccessor<DH,level_dof_access>::set_mg_dof_indices (const std::vector<types::global_dof_index> &dof_indices)
 {
-  DoFAccessor<dim, DH,lda>::set_mg_dof_indices (this->level (), dof_indices);
+  DoFAccessor<dim, DH,level_dof_access>::set_mg_dof_indices (this->level (), dof_indices);
 }
 
 
 
-template<class DH, bool lda>
+template<class DH, bool level_dof_access>
 inline
-void DoFCellAccessor<DH,lda>::get_active_or_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
+void DoFCellAccessor<DH,level_dof_access>::get_active_or_mg_dof_indices (std::vector<types::global_dof_index> &dof_indices) const
 {
-  if (lda)
+  if (level_dof_access)
     get_mg_dof_indices (dof_indices);
   else
     get_dof_indices (dof_indices);
@@ -3332,11 +3332,11 @@ void DoFCellAccessor<DH,lda>::get_active_or_mg_dof_indices (std::vector<types::g
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <class InputVector, typename number>
 inline
 void
-DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
+DoFCellAccessor<DH,level_dof_access>::get_dof_values (const InputVector &values,
                                          Vector<number>    &local_values) const
 {
   get_dof_values (values, local_values.begin(), local_values.end());
@@ -3344,11 +3344,11 @@ DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <class InputVector, typename ForwardIterator>
 inline
 void
-DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
+DoFCellAccessor<DH,level_dof_access>::get_dof_values (const InputVector &values,
                                          ForwardIterator    local_values_begin,
                                          ForwardIterator    local_values_end) const
 {
@@ -3374,11 +3374,11 @@ DoFCellAccessor<DH,lda>::get_dof_values (const InputVector &values,
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <class InputVector, typename ForwardIterator>
 inline
 void
-DoFCellAccessor<DH,lda>::get_dof_values (const ConstraintMatrix &constraints,
+DoFCellAccessor<DH,level_dof_access>::get_dof_values (const ConstraintMatrix &constraints,
                                          const InputVector      &values,
                                          ForwardIterator         local_values_begin,
                                          ForwardIterator         local_values_end) const
@@ -3405,11 +3405,11 @@ DoFCellAccessor<DH,lda>::get_dof_values (const ConstraintMatrix &constraints,
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <class OutputVector, typename number>
 inline
 void
-DoFCellAccessor<DH,lda>::set_dof_values (const Vector<number> &local_values,
+DoFCellAccessor<DH,level_dof_access>::set_dof_values (const Vector<number> &local_values,
                                          OutputVector         &values) const
 {
   Assert (this->is_artificial() == false,
@@ -3434,10 +3434,10 @@ DoFCellAccessor<DH,lda>::set_dof_values (const Vector<number> &local_values,
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
 const FiniteElement<DH::dimension,DH::space_dimension> &
-DoFCellAccessor<DH,lda>::get_fe () const
+DoFCellAccessor<DH,level_dof_access>::get_fe () const
 {
   Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
           (this->dof_handler) != 0)
@@ -3451,10 +3451,10 @@ DoFCellAccessor<DH,lda>::get_fe () const
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
 unsigned int
-DoFCellAccessor<DH,lda>::active_fe_index () const
+DoFCellAccessor<DH,level_dof_access>::active_fe_index () const
 {
   Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
           (this->dof_handler) != 0)
@@ -3469,10 +3469,10 @@ DoFCellAccessor<DH,lda>::active_fe_index () const
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 inline
 void
-DoFCellAccessor<DH,lda>::set_active_fe_index (const unsigned int i)
+DoFCellAccessor<DH,level_dof_access>::set_active_fe_index (const unsigned int i)
 {
   Assert ((dynamic_cast<const dealii::DoFHandler<DH::dimension,DH::space_dimension>*>
           (this->dof_handler) != 0)
@@ -3487,11 +3487,11 @@ DoFCellAccessor<DH,lda>::set_active_fe_index (const unsigned int i)
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <typename number, typename OutputVector>
 inline
 void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
   const Vector<number> &local_source,
   OutputVector         &global_destination) const
 {
@@ -3502,11 +3502,11 @@ DoFCellAccessor<DH,lda>::distribute_local_to_global (
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <typename ForwardIterator, typename OutputVector>
 inline
 void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
   ForwardIterator  local_source_begin,
   ForwardIterator  local_source_end,
   OutputVector    &global_destination) const
@@ -3518,11 +3518,11 @@ DoFCellAccessor<DH,lda>::distribute_local_to_global (
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <typename ForwardIterator, typename OutputVector>
 inline
 void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
   const ConstraintMatrix &constraints,
   ForwardIterator         local_source_begin,
   ForwardIterator         local_source_end,
@@ -3535,11 +3535,11 @@ DoFCellAccessor<DH,lda>::distribute_local_to_global (
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <typename number, typename OutputMatrix>
 inline
 void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
   const FullMatrix<number> &local_source,
   OutputMatrix             &global_destination) const
 {
@@ -3549,11 +3549,11 @@ DoFCellAccessor<DH,lda>::distribute_local_to_global (
 
 
 
-template <class DH, bool lda>
+template <class DH, bool level_dof_access>
 template <typename number, typename OutputMatrix, typename OutputVector>
 inline
 void
-DoFCellAccessor<DH,lda>::distribute_local_to_global (
+DoFCellAccessor<DH,level_dof_access>::distribute_local_to_global (
   const FullMatrix<number> &local_matrix,
   const Vector<number>     &local_vector,
   OutputMatrix             &global_matrix,
index 56194984fef396fbb07b436bc4c9de731b44902c..0c708ab4eab1cd19d25d6c1633fa5663c14e5d8d 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 1999 - 2013 by the deal.II authors
+// Copyright (C) 1999 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -205,7 +205,7 @@ namespace GridGenerator
   template <int dim>
   void
   parallelogram (Triangulation<dim> &tria,
-                 const Point<dim>  corners[dim],
+                 const Point<dim>  (&corners)[dim],
                  const bool          colorize=false);
 
   /**
@@ -576,7 +576,6 @@ namespace GridGenerator
    * @param r The inner radius of the
    * torus.
    */
-
   void torus (Triangulation<2,3> &tria,
               const double        R,
               const double        r);
index 5f43b3af9e00307c8f2a0deee058f57f8fb17110..a439b3da7b1122c5b6367b12575f5009a0d94f52 100644 (file)
@@ -171,15 +171,7 @@ namespace GridTools
   /**
    * Transform the vertices of the given
    * triangulation by applying the
-   * function object provided as first argument to all its vertices. Since
-   * the internal consistency of a
-   * triangulation can only be guaranteed
-   * if the transformation is applied to
-   * the vertices of only one level of
-   * hierarchically refined cells, this
-   * function may only be used if all cells
-   * of the triangulation are on the same
-   * refinement level.
+   * function object provided as first argument to all its vertices.
    *
    * The transformation given as
    * argument is used to transform
@@ -194,6 +186,13 @@ namespace GridTools
    * return value have to be of
    * type <tt>Point<spacedim></tt>.
    *
+   * Note: if you are using a parallel::distributed::Triangulation you will have
+   * hanging nodes in your local Triangulation even if your "global" mesh has
+   * no hanging nodes. This will cause issues with wrong positioning of hanging
+   * nodes in ghost cells. The active cells will be correct, but keep in mind that
+   * computations like KellyErrorEstimator will give wrong answers. A safe bet is
+   * to use this function prior to any refinement in parallel.
+   *
    * This function is used in the
    * "Possibilities for extensions" section
    * of step-38. It is also used in step-49.
@@ -874,6 +873,23 @@ namespace GridTools
   fix_up_distorted_child_cells (const typename Triangulation<dim,spacedim>::DistortedCellList &distorted_cells,
                                 Triangulation<dim,spacedim> &triangulation);
 
+#ifdef _MSC_VER
+  // Microsoft's VC++ has a bug where it doesn't want to recognize that
+  // an implementation (definition) of the extract_boundary_mesh function
+  // matches a declaration. This can apparently only be avoided by
+  // doing some contortion with the return type using the following
+  // intermediate type. This is only used when using MS VC++ and uses
+  // the direct way of doing it otherwise
+  template <template <int,int> class Container, int dim, int spacedim>
+  struct ExtractBoundaryMesh
+  {
+      typedef
+          std::map<typename Container<dim-1,spacedim>::cell_iterator,
+              typename Container<dim,spacedim>::face_iterator>
+          return_type;
+  };
+#endif
+
   /**
    * This function implements a boundary
    * subgrid extraction.  Given a
@@ -961,8 +977,12 @@ namespace GridTools
    * curved boundaries.
    */
   template <template <int,int> class Container, int dim, int spacedim>
+#ifndef _MSC_VER
   std::map<typename Container<dim-1,spacedim>::cell_iterator,
       typename Container<dim,spacedim>::face_iterator>
+#else
+  typename ExtractBoundaryMesh<Container,dim,spacedim>::return_type
+#endif
       extract_boundary_mesh (const Container<dim,spacedim> &volume_mesh,
                              Container<dim-1,spacedim>     &surface_mesh,
                              const std::set<types::boundary_id> &boundary_ids
@@ -1204,13 +1224,6 @@ namespace GridTools
   void transform (const Predicate    &predicate,
                   Triangulation<dim, spacedim> &triangulation)
   {
-    // ensure that all the cells of the
-    // triangulation are on the same level
-    Assert (triangulation.n_levels() ==
-            static_cast<unsigned int>(triangulation.begin_active()->level()+1),
-            ExcMessage ("Not all cells of this triangulation are at the same "
-                        "refinement level, as is required for this function."));
-
     std::vector<bool> treated_vertices (triangulation.n_vertices(),
                                         false);
 
@@ -1232,6 +1245,49 @@ namespace GridTools
             // and mark it as treated
             treated_vertices[cell->vertex_index(v)] = true;
           };
+
+
+    // now fix any vertices on hanging nodes so that we don't create any holes
+    if (dim==2)
+      {
+        typename Triangulation<dim,spacedim>::active_cell_iterator
+        cell = triangulation.begin_active(),
+        endc = triangulation.end();
+        for (; cell!=endc; ++cell)
+          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            if (cell->face(face)->has_children() &&
+                !cell->face(face)->at_boundary())
+              { // this line has children
+                cell->face(face)->child(0)->vertex(1)
+                                       = (cell->face(face)->vertex(0) +
+                                           cell->face(face)->vertex(1)) / 2;
+              }
+      }
+    else if (dim==3)
+      {
+        typename Triangulation<dim,spacedim>::active_cell_iterator
+        cell = triangulation.begin_active(),
+        endc = triangulation.end();
+        for (; cell!=endc; ++cell)
+          for (unsigned int face=0; face<GeometryInfo<dim>::faces_per_cell; ++face)
+            if (cell->face(face)->has_children() &&
+                !cell->face(face)->at_boundary())
+              { // this face has hanging nodes
+                cell->face(face)->child(0)->vertex(1)
+                    = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)) / 2.0;
+                cell->face(face)->child(0)->vertex(2)
+                    = (cell->face(face)->vertex(0) + cell->face(face)->vertex(2)) / 2.0;
+                cell->face(face)->child(1)->vertex(3)
+                    = (cell->face(face)->vertex(1) + cell->face(face)->vertex(3)) / 2.0;
+                cell->face(face)->child(2)->vertex(3)
+                    = (cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 2.0;
+
+                // center of the face
+                cell->face(face)->child(0)->vertex(3)
+                    = (cell->face(face)->vertex(0) + cell->face(face)->vertex(1)
+                        + cell->face(face)->vertex(2) + cell->face(face)->vertex(3)) / 4.0;
+              }
+      }
   }
 
 
index 2313997c040956b002c6b9ba15f36ab648e35719..c3004be3e025ab2a34712f055e818ed8e2e4387a 100644 (file)
@@ -75,6 +75,48 @@ namespace LocalIntegrators
         }
     }
 
+    /**
+     * The weighted mass matrix for scalar or vector values finite elements.
+     * \f[
+     * \int_Z \omega(x) uv\,dx \quad \text{or} \quad \int_Z \omega(x) \mathbf u\cdot \mathbf v\,dx
+     * \f]
+     *
+     * Likewise, this term can be used on faces, where it computes  the integrals
+     * \f[
+     * \int_F \omega(x) uv\,ds \quad \text{or} \quad \int_F \omega(x) \mathbf u\cdot \mathbf v\,ds
+     * \f]
+     *
+     * The size of the vector <tt>weights</tt> must be equal to the
+     * number of quadrature points in the finite element.
+     *
+     * @author Guido Kanschat
+     * @date 2014
+     */
+    template <int dim>
+    void weighted_mass_matrix (
+      FullMatrix<double> &M,
+      const FEValuesBase<dim> &fe,
+      const std::vector<double> weights)
+    {
+      const unsigned int n_dofs = fe.dofs_per_cell;
+      const unsigned int n_components = fe.get_fe().n_components();
+      AssertDimension(M.m(), n_dofs);
+      AssertDimension(M.n(), n_dofs);
+      AssertDimension(weights.size(), fe.n_quadrature_points);
+      
+      for (unsigned int k=0; k<fe.n_quadrature_points; ++k)
+        {
+          const double dx = fe.JxW(k) * weights[k];
+
+          for (unsigned int i=0; i<n_dofs; ++i)
+            for (unsigned int j=0; j<n_dofs; ++j)
+              for (unsigned int d=0; d<n_components; ++d)
+                M(i,j) += dx
+                          * fe.shape_value_component(j,k,d)
+                          * fe.shape_value_component(i,k,d);
+        }
+    }
+
     /**
      * <i>L<sup>2</sup></i>-inner product for scalar functions.
      *
index 3219015fa12a0013c7653d51b1cf82866cbf33fd..75b91077b78f036d4d6f49aa05e1fd204e665a2e 100644 (file)
@@ -1717,7 +1717,7 @@ distribute_local_to_global (const FullMatrix<double>     &local_matrix,
   Vector<double> dummy(0);
   distribute_local_to_global (local_matrix, dummy, local_dof_indices,
                               global_matrix, dummy, false,
-                              internal::bool2type<IsBlockMatrix<MatrixType>::value>());
+                              dealii::internal::bool2type<IsBlockMatrix<MatrixType>::value>());
 }
 
 
index 4be38349f07f487dcd8166cd125e1e7925c609ec..fc5793e53e980655655567e65a9bdaa65964e17e 100644 (file)
@@ -74,30 +74,19 @@ public:
   typedef unsigned int size_type;
 
   /**
-   * Type of matrix entries. In analogy to
-   * the STL container classes.
+   * Type of matrix entries. In analogy to the STL container classes.
    */
   typedef number value_type;
 
 
   /**
-   * Declare a type that has holds
-   * real-valued numbers with the
-   * same precision as the template
-   * argument to this class. If the
-   * template argument of this
-   * class is a real data type,
-   * then real_type equals the
-   * template argument. If the
-   * template argument is a
-   * std::complex type then
-   * real_type equals the type
-   * underlying the complex
-   * numbers.
+   * Declare a type that has holds real-valued numbers with the same precision
+   * as the template argument to this class. If the template argument of this
+   * class is a real data type, then real_type equals the template
+   * argument. If the template argument is a std::complex type then real_type
+   * equals the type underlying the complex numbers.
    *
-   * This typedef is used to
-   * represent the return type of
-   * norms.
+   * This typedef is used to represent the return type of norms.
    */
   typedef typename numbers::NumberTraits<number>::real_type real_type;
 
@@ -111,26 +100,20 @@ public:
   {
   public:
     /**
-     * Constructor. Since we use
-     * accessors only for read
-     * access, a const matrix
-     * pointer is sufficient.
+     * Constructor. Since we use accessors only for read access, a const
+     * matrix pointer is sufficient.
      */
     Accessor (const FullMatrix<number> *matrix,
               const size_type row,
               const size_type col);
 
     /**
-     * Row number of the element
-     * represented by this
-     * object.
+     * Row number of the element represented by this object.
      */
     size_type row() const;
 
     /**
-     * Column number of the
-     * element represented by
-     * this object.
+     * Column number of the element represented by this object.
      */
     size_type column() const;
 
@@ -156,8 +139,7 @@ public:
     unsigned short a_col;
 
     /*
-     * Make enclosing class a
-     * friend.
+     * Make enclosing class a friend.
      */
     friend class const_iterator;
   };
@@ -196,10 +178,7 @@ public:
     const Accessor *operator-> () const;
 
     /**
-     * Comparison. True, if
-     * both iterators point to
-     * the same matrix
-     * position.
+     * Comparison. True, if both iterators point to the same matrix position.
      */
     bool operator == (const const_iterator &) const;
     /**
@@ -208,97 +187,69 @@ public:
     bool operator != (const const_iterator &) const;
 
     /**
-     * Comparison operator. Result is
-     * true if either the first row
-     * number is smaller or if the row
-     * numbers are equal and the first
-     * index is smaller.
+     * Comparison operator. Result is true if either the first row number is
+     * smaller or if the row numbers are equal and the first index is smaller.
      */
     bool operator < (const const_iterator &) const;
 
     /**
-     * Comparison operator. Compares just
-     * the other way around than the
+     * Comparison operator. Compares just the other way around than the
      * operator above.
      */
     bool operator > (const const_iterator &) const;
 
   private:
     /**
-     * Store an object of the
-     * accessor class.
+     * Store an object of the accessor class.
      */
     Accessor accessor;
   };
   /**
-   * @name Constructors and initalization.
-   * See also the base class Table.
+   * @name Constructors and initalization.  See also the base class Table.
    */
 //@{
 
   /**
-   * Constructor. Initialize the
-   * matrix as a square matrix with
-   * dimension <tt>n</tt>.
+   * Constructor. Initialize the matrix as a square matrix with dimension
+   * <tt>n</tt>.
    *
-   * In order to avoid the implicit
-   * conversion of integers and
-   * other types to a matrix, this
-   * constructor is declared
-   * <tt>explicit</tt>.
+   * In order to avoid the implicit conversion of integers and other types to
+   * a matrix, this constructor is declared <tt>explicit</tt>.
    *
-   * By default, no memory is
-   * allocated.
+   * By default, no memory is allocated.
    */
   explicit FullMatrix (const size_type n = 0);
 
   /**
-   * Constructor. Initialize the
-   * matrix as a rectangular
-   * matrix.
+   * Constructor. Initialize the matrix as a rectangular matrix.
    */
   FullMatrix (const size_type rows,
               const size_type cols);
 
   /**
-   * Copy constructor. This
-   * constructor does a deep copy
-   * of the matrix. Therefore, it
-   * poses a possible efficiency
-   * problem, if for example,
-   * function arguments are passed
-   * by value rather than by
-   * reference. Unfortunately, we
-   * can't mark this copy
-   * constructor <tt>explicit</tt>,
-   * since that prevents the use of
-   * this class in containers, such
-   * as <tt>std::vector</tt>. The
-   * responsibility to check
-   * performance of programs must
-   * therefore remain with the
-   * user of this class.
+   * Copy constructor. This constructor does a deep copy of the
+   * matrix. Therefore, it poses a possible efficiency problem, if for
+   * example, function arguments are passed by value rather than by
+   * reference. Unfortunately, we can't mark this copy constructor
+   * <tt>explicit</tt>, since that prevents the use of this class in
+   * containers, such as <tt>std::vector</tt>. The responsibility to check
+   * performance of programs must therefore remain with the user of this
+   * class.
    */
   FullMatrix (const FullMatrix &);
 
   /**
-   * Constructor initializing from
-   * an array of numbers. The array
-   * is arranged line by line. No
-   * range checking is performed.
+   * Constructor initializing from an array of numbers. The array is arranged
+   * line by line. No range checking is performed.
    */
   FullMatrix (const size_type rows,
               const size_type cols,
               const number *entries);
 
   /**
-   * Construct a full matrix that
-   * equals the identity matrix of
-   * the size of the
-   * argument. Using this
-   * constructor, one can easily
-   * create an identity matrix of
-   * size <code>n</code> by saying
+   * Construct a full matrix that equals the identity matrix of the size of
+   * the argument. Using this constructor, one can easily create an identity
+   * matrix of size <code>n</code> by saying
    * @code
    * FullMatrix<double> M(IdentityMatrix(n));
    * @endcode
@@ -329,25 +280,17 @@ public:
   operator = (const FullMatrix<number2> &);
 
   /**
-   * This operator assigns a scalar
-   * to a matrix. To avoid
-   * confusion with the semantics
-   * of this function, zero is the
-   * only value allowed for
-   * <tt>d</tt>, allowing you to
-   * clear a matrix in an intuitive
-   * way.
+   * This operator assigns a scalar to a matrix. To avoid confusion with the
+   * semantics of this function, zero is the only value allowed for
+   * <tt>d</tt>, allowing you to clear a matrix in an intuitive way.
    */
   FullMatrix<number> &
   operator = (const number d);
 
   /**
-   * Copy operator to create a full
-   * matrix that equals the
-   * identity matrix of the size of
-   * the argument. This way, one can easily
-   * create an identity matrix of
-   * size <code>n</code> by saying
+   * Copy operator to create a full matrix that equals the identity matrix of
+   * the size of the argument. This way, one can easily create an identity
+   * matrix of size <code>n</code> by saying
    * @code
    *   M = IdentityMatrix(n);
    * @endcode
@@ -356,10 +299,8 @@ public:
   operator = (const IdentityMatrix &id);
 
   /**
-   * Assignment operator for a
-   * LapackFullMatrix. The calling matrix
-   * must be of the same size as the
-   * LAPACK matrix.
+   * Assignment operator for a LapackFullMatrix. The calling matrix must be of
+   * the same size as the LAPACK matrix.
    */
   template <typename number2>
   FullMatrix<number> &
@@ -367,39 +308,27 @@ public:
 
 
   /**
-   * Assignment from different
-   * matrix classes. This
-   * assignment operator uses
-   * iterators of the class
-   * MATRIX. Therefore, sparse
-   * matrices are possible sources.
+   * Assignment from different matrix classes. This assignment operator uses
+   * iterators of the class MATRIX. Therefore, sparse matrices are possible
+   * sources.
    */
   template <class MATRIX>
   void copy_from (const MATRIX &);
 
   /**
-   * Transposing assignment from
-   * different matrix classes. This
-   * assignment operator uses
-   * iterators of the class
-   * MATRIX. Therefore, sparse
-   * matrices are possible sources.
+   * Transposing assignment from different matrix classes. This assignment
+   * operator uses iterators of the class MATRIX. Therefore, sparse matrices
+   * are possible sources.
    */
   template <class MATRIX>
   void copy_transposed (const MATRIX &);
 
   /**
-   * Fill matrix with elements
-   * extracted from a tensor,
-   * taking rows included between
-   * <tt>r_i</tt> and <tt>r_j</tt>
-   * and columns between
-   * <tt>c_i</tt> and
-   * <tt>c_j</tt>. The resulting
-   * matrix is then inserted in the
-   * destination matrix at position
-   * <tt>(dst_r, dst_c)</tt> Checks
-   * on the indices are made.
+   * Fill matrix with elements extracted from a tensor, taking rows included
+   * between <tt>r_i</tt> and <tt>r_j</tt> and columns between <tt>c_i</tt>
+   * and <tt>c_j</tt>. The resulting matrix is then inserted in the
+   * destination matrix at position <tt>(dst_r, dst_c)</tt> Checks on the
+   * indices are made.
    */
   template <int dim>
   void
@@ -412,17 +341,11 @@ public:
              const size_type dst_c=0);
 
   /**
-   * Insert a submatrix (also
-   * rectangular) into a tensor,
-   * putting its upper left element
-   * at the specified position
-   * <tt>(dst_r, dst_c)</tt> and
-   * the other elements
-   * consequently. Default values
-   * are chosen so that no
-   * parameter needs to be specified
-   * if the size of the tensor and
-   * that of the matrix coincide.
+   * Insert a submatrix (also rectangular) into a tensor, putting its upper
+   * left element at the specified position <tt>(dst_r, dst_c)</tt> and the
+   * other elements consequently. Default values are chosen so that no
+   * parameter needs to be specified if the size of the tensor and that of the
+   * matrix coincide.
    */
   template <int dim>
   void
@@ -472,20 +395,12 @@ public:
   /**
    * Fill rectangular block.
    *
-   * A rectangular block of the
-   * matrix <tt>src</tt> is copied into
-   * <tt>this</tt>. The upper left
-   * corner of the block being
-   * copied is
-   * <tt>(src_offset_i,src_offset_j)</tt>.
-   * The upper left corner of the
-   * copied block is
-   * <tt>(dst_offset_i,dst_offset_j)</tt>.
-   * The size of the rectangular
-   * block being copied is the
-   * maximum size possible,
-   * determined either by the size
-   * of <tt>this</tt> or <tt>src</tt>.
+   * A rectangular block of the matrix <tt>src</tt> is copied into
+   * <tt>this</tt>. The upper left corner of the block being copied is
+   * <tt>(src_offset_i,src_offset_j)</tt>.  The upper left corner of the
+   * copied block is <tt>(dst_offset_i,dst_offset_j)</tt>.  The size of the
+   * rectangular block being copied is the maximum size possible, determined
+   * either by the size of <tt>this</tt> or <tt>src</tt>.
    */
   template <typename number2>
   void fill (const FullMatrix<number2> &src,
@@ -496,28 +411,20 @@ public:
 
 
   /**
-   * Make function of base class
-   * available.
+   * Make function of base class available.
    */
   template <typename number2>
   void fill (const number2 *);
 
   /**
-   * Fill with permutation of
-   * another matrix.
+   * Fill with permutation of another matrix.
    *
-   * The matrix <tt>src</tt> is copied
-   * into the target. The two
-   * permutation <tt>p_r</tt> and
-   * <tt>p_c</tt> operate in a way, such
-   * that <tt>result(i,j) =
-   * src(p_r[i], p_c[j])</tt>.
+   * The matrix <tt>src</tt> is copied into the target. The two permutation
+   * <tt>p_r</tt> and <tt>p_c</tt> operate in a way, such that <tt>result(i,j)
+   * = src(p_r[i], p_c[j])</tt>.
    *
-   * The vectors may also be a
-   * selection from a larger set of
-   * integers, if the matrix
-   * <tt>src</tt> is bigger. It is also
-   * possible to duplicate rows or
+   * The vectors may also be a selection from a larger set of integers, if the
+   * matrix <tt>src</tt> is bigger. It is also possible to duplicate rows or
    * columns by this method.
    */
   template <typename number2>
@@ -549,158 +456,104 @@ public:
    */
 
   /**
-   * Comparison operator. Be
-   * careful with this thing, it
-   * may eat up huge amounts of
-   * computing time! It is most
-   * commonly used for internal
-   * consistency checks of
-   * programs.
+   * Comparison operator. Be careful with this thing, it may eat up huge
+   * amounts of computing time! It is most commonly used for internal
+   * consistency checks of programs.
    */
   bool operator == (const FullMatrix<number> &) const;
 
   /**
-   * Number of rows of this matrix.
-   * To remember: this matrix is an
-   * <i>m x n</i>-matrix.
+   * Number of rows of this matrix.  To remember: this matrix is an <i>m x
+   * n</i>-matrix.
    */
   size_type m () const;
 
   /**
-   * Number of columns of this matrix.
-   * To remember: this matrix is an
-   * <i>m x n</i>-matrix.
+   * Number of columns of this matrix.  To remember: this matrix is an <i>m x
+   * n</i>-matrix.
    */
   size_type n () const;
 
   /**
-   * Return whether the matrix
-   * contains only elements with
-   * value zero. This function is
-   * mainly for internal
-   * consistency checks and should
-   * seldom be used when not in
-   * debug mode since it uses quite
-   * some time.
+   * Return whether the matrix contains only elements with value zero. This
+   * function is mainly for internal consistency checks and should seldom be
+   * used when not in debug mode since it uses quite some time.
    */
   bool all_zero () const;
 
   /**
-   * Return the square of the norm
-   * of the vector <tt>v</tt> induced by
-   * this matrix,
-   * i.e. <i>(v,Mv)</i>. This is
-   * useful, e.g. in the finite
-   * element context, where the
-   * <i>L<sup>2</sup></i> norm of a
-   * function equals the matrix
-   * norm with respect to the mass
-   * matrix of the vector
-   * representing the nodal values
-   * of the finite element
-   * function.
-   *
-   * Obviously, the matrix needs to be
-   * quadratic for this operation, and for
-   * the result to actually be a norm it
-   * also needs to be either real symmetric
-   * or complex hermitian.
-   *
-   * The underlying template types of both
-   * this matrix and the given vector
-   * should either both be real or
-   * complex-valued, but not mixed, for
-   * this function to make sense.
+   * Return the square of the norm of the vector <tt>v</tt> induced by this
+   * matrix, i.e. <i>(v,Mv)</i>. This is useful, e.g. in the finite element
+   * context, where the <i>L<sup>2</sup></i> norm of a function equals the
+   * matrix norm with respect to the mass matrix of the vector representing
+   * the nodal values of the finite element function.
+   *
+   * Obviously, the matrix needs to be quadratic for this operation, and for
+   * the result to actually be a norm it also needs to be either real
+   * symmetric or complex hermitian.
+   *
+   * The underlying template types of both this matrix and the given vector
+   * should either both be real or complex-valued, but not mixed, for this
+   * function to make sense.
    */
   template <typename number2>
   number2 matrix_norm_square (const Vector<number2> &v) const;
 
   /**
-   * Build the matrix scalar
-   * product <tt>u<sup>T</sup> M
-   * v</tt>. This function is
-   * mostly useful when building
-   * the cellwise scalar product of
-   * two functions in the finite
-   * element context.
+   * Build the matrix scalar product <tt>u<sup>T</sup> M v</tt>. This function
+   * is mostly useful when building the cellwise scalar product of two
+   * functions in the finite element context.
    *
-   * The underlying template types of both
-   * this matrix and the given vector
-   * should either both be real or
-   * complex-valued, but not mixed, for
-   * this function to make sense.
+   * The underlying template types of both this matrix and the given vector
+   * should either both be real or complex-valued, but not mixed, for this
+   * function to make sense.
    */
   template <typename number2>
   number2 matrix_scalar_product (const Vector<number2> &u,
                                  const Vector<number2> &v) const;
 
   /**
-   * Return the
-   * <i>l<sub>1</sub></i>-norm of
-   * the matrix, where
-   * $||M||_1 = \max_j \sum_i
-   * |M_{ij}|$ (maximum of
-   * the sums over columns).
+   * Return the <i>l<sub>1</sub></i>-norm of the matrix, where $||M||_1 =
+   * \max_j \sum_i |M_{ij}|$ (maximum of the sums over columns).
    */
   real_type l1_norm () const;
 
   /**
-   * Return the $l_\infty$-norm of
-   * the matrix, where
-   * $||M||_\infty = \max_i \sum_j
-   * |M_{ij}|$ (maximum of the sums
-   * over rows).
+   * Return the $l_\infty$-norm of the matrix, where $||M||_\infty = \max_i
+   * \sum_j |M_{ij}|$ (maximum of the sums over rows).
    */
   real_type linfty_norm () const;
 
   /**
-   * Compute the Frobenius norm of
-   * the matrix.  Return value is
-   * the root of the square sum of
-   * all matrix entries.
+   * Compute the Frobenius norm of the matrix.  Return value is the root of
+   * the square sum of all matrix entries.
    *
-   * @note For the timid among us:
-   * this norm is not the norm
-   * compatible with the
-   * <i>l<sub>2</sub></i>-norm of
-   * the vector space.
+   * @note For the timid among us: this norm is not the norm compatible with
+   * the <i>l<sub>2</sub></i>-norm of the vector space.
    */
   real_type frobenius_norm () const;
 
   /**
-   * Compute the relative norm of
-   * the skew-symmetric part. The
-   * return value is the Frobenius
-   * norm of the skew-symmetric
-   * part of the matrix divided by
+   * Compute the relative norm of the skew-symmetric part. The return value is
+   * the Frobenius norm of the skew-symmetric part of the matrix divided by
    * that of the matrix.
    *
-   * Main purpose of this function
-   * is to check, if a matrix is
-   * symmetric within a certain
-   * accuracy, or not.
+   * Main purpose of this function is to check, if a matrix is symmetric
+   * within a certain accuracy, or not.
    */
   real_type relative_symmetry_norm2 () const;
 
   /**
-   * Computes the determinant of a
-   * matrix.  This is only
-   * implemented for one, two, and
-   * three dimensions, since for
-   * higher dimensions the
-   * numerical work explodes.
-   * Obviously, the matrix needs to
-   * be quadratic for this function.
+   * Computes the determinant of a matrix.  This is only implemented for one,
+   * two, and three dimensions, since for higher dimensions the numerical work
+   * explodes.  Obviously, the matrix needs to be quadratic for this function.
    */
   number determinant () const;
 
   /**
-   * Return the trace of the matrix,
-   * i.e. the sum of the diagonal values
-   * (which happens to also equal the sum
-   * of the eigenvalues of a matrix).
-   * Obviously, the matrix needs to
-   * be quadratic for this function.
+   * Return the trace of the matrix, i.e. the sum of the diagonal values
+   * (which happens to also equal the sum of the eigenvalues of a matrix).
+   * Obviously, the matrix needs to be quadratic for this function.
    */
   number trace () const;
 
@@ -716,45 +569,26 @@ public:
               const unsigned int  precision=2) const;
 
   /**
-   * Print the matrix and allow
-   * formatting of entries.
-   *
-   * The parameters allow for a
-   * flexible setting of the output
-   * format:
-   *
-   * @arg <tt>precision</tt>
-   * denotes the number of trailing
-   * digits.
-   *
-   * @arg <tt>scientific</tt> is
-   * used to determine the number
-   * format, where
-   * <tt>scientific</tt> =
-   * <tt>false</tt> means fixed
-   * point notation.
-   *
-   * @arg <tt>width</tt> denotes
-   * the with of each column. A
-   * zero entry for <tt>width</tt>
-   * makes the function compute a
-   * width, but it may be changed
-   * to a positive value, if output
-   * is crude.
-   *
-   * @arg <tt>zero_string</tt>
-   * specifies a string printed for
-   * zero entries.
-   *
-   * @arg <tt>denominator</tt>
-   * Multiply the whole matrix by
-   * this common denominator to get
-   * nicer numbers.
-   *
-   * @arg <tt>threshold</tt>: all
-   * entries with absolute value
-   * smaller than this are
-   * considered zero.
+   * Print the matrix and allow formatting of entries.
+   *
+   * The parameters allow for a flexible setting of the output format:
+   *
+   * @arg <tt>precision</tt> denotes the number of trailing digits.
+   *
+   * @arg <tt>scientific</tt> is used to determine the number format, where
+   * <tt>scientific</tt> = <tt>false</tt> means fixed point notation.
+   *
+   * @arg <tt>width</tt> denotes the with of each column. A zero entry for
+   * <tt>width</tt> makes the function compute a width, but it may be changed
+   * to a positive value, if output is crude.
+   *
+   * @arg <tt>zero_string</tt> specifies a string printed for zero entries.
+   *
+   * @arg <tt>denominator</tt> Multiply the whole matrix by this common
+   * denominator to get nicer numbers.
+   *
+   * @arg <tt>threshold</tt>: all entries with absolute value smaller than
+   * this are considered zero.
   */
   void print_formatted (std::ostream       &out,
                         const unsigned int  precision=3,
@@ -765,9 +599,8 @@ public:
                         const double        threshold   = 0.) const;
 
   /**
-   * 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;
 
@@ -776,8 +609,7 @@ public:
 //@{
 
   /**
-   * STL-like iterator with the
-   * first entry.
+   * STL-like iterator with the first entry.
    */
   const_iterator begin () const;
 
@@ -787,8 +619,7 @@ public:
   const_iterator end () const;
 
   /**
-   * STL-like iterator with the
-   * first entry of row <tt>r</tt>.
+   * STL-like iterator with the first entry of row <tt>r</tt>.
    */
   const_iterator begin (const size_type r) const;
 
@@ -802,45 +633,32 @@ public:
 //@{
 
   /**
-   * Scale the entire matrix by a
-   * fixed factor.
+   * Scale the entire matrix by a fixed factor.
    */
   FullMatrix &operator *= (const number factor);
 
   /**
-   * Scale the entire matrix by the
-   * inverse of the given factor.
+   * Scale the entire matrix by the inverse of the given factor.
    */
   FullMatrix &operator /= (const number factor);
 
   /**
-   * Simple addition of a scaled
-   * matrix, i.e. <tt>*this +=
-   * a*A</tt>.
+   * Simple addition of a scaled matrix, i.e. <tt>*this += a*A</tt>.
    *
-   * The matrix <tt>A</tt> may be a
-   * full matrix over an arbitrary
-   * underlying scalar type, as
-   * long as its data type is
-   * convertible to the data type
-   * of this matrix.
+   * The matrix <tt>A</tt> may be a full matrix over an arbitrary underlying
+   * scalar type, as long as its data type is convertible to the data type of
+   * this matrix.
    */
   template <typename number2>
   void add (const number               a,
             const FullMatrix<number2> &A);
 
   /**
-   * Multiple addition of scaled
-   * matrices, i.e. <tt>*this +=
-   * a*A + b*B</tt>.
+   * Multiple addition of scaled matrices, i.e. <tt>*this += a*A + b*B</tt>.
    *
-   * The matrices <tt>A</tt> and
-   * <tt>B</tt> may be a full
-   * matrix over an arbitrary
-   * underlying scalar type, as
-   * long as its data type is
-   * convertible to the data type
-   * of this matrix.
+   * The matrices <tt>A</tt> and <tt>B</tt> may be a full matrix over an
+   * arbitrary underlying scalar type, as long as its data type is convertible
+   * to the data type of this matrix.
    */
   template <typename number2>
   void add (const number               a,
@@ -849,17 +667,12 @@ public:
             const FullMatrix<number2> &B);
 
   /**
-   * Multiple addition of scaled
-   * matrices, i.e. <tt>*this +=
-   * a*A + b*B + c*C</tt>.
+   * Multiple addition of scaled matrices, i.e. <tt>*this += a*A + b*B +
+   * c*C</tt>.
    *
-   * The matrices <tt>A</tt>,
-   * <tt>B</tt> and <tt>C</tt> may
-   * be a full matrix over an
-   * arbitrary underlying scalar
-   * type, as long as its data type
-   * is convertible to the data
-   * type of this matrix.
+   * The matrices <tt>A</tt>, <tt>B</tt> and <tt>C</tt> may be a full matrix
+   * over an arbitrary underlying scalar type, as long as its data type is
+   * convertible to the data type of this matrix.
    */
   template <typename number2>
   void add (const number               a,
@@ -872,19 +685,13 @@ public:
   /**
    * Add rectangular block.
    *
-   * A rectangular block of the matrix
-   * <tt>src</tt> is added to
-   * <tt>this</tt>. The upper left corner
-   * of the block being copied is
-   * <tt>(src_offset_i,src_offset_j)</tt>.
-   * The upper left corner of the copied
-   * block is
-   * <tt>(dst_offset_i,dst_offset_j)</tt>.
-   * The size of the rectangular block
-   * being copied is the maximum size
-   * possible, determined either by the
-   * size of <tt>this</tt> or <tt>src</tt>
-   * and the given offsets.
+   * A rectangular block of the matrix <tt>src</tt> is added to
+   * <tt>this</tt>. The upper left corner of the block being copied is
+   * <tt>(src_offset_i,src_offset_j)</tt>.  The upper left corner of the
+   * copied block is <tt>(dst_offset_i,dst_offset_j)</tt>.  The size of the
+   * rectangular block being copied is the maximum size possible, determined
+   * either by the size of <tt>this</tt> or <tt>src</tt> and the given
+   * offsets.
    */
   template <typename number2>
   void add (const FullMatrix<number2> &src,
@@ -895,9 +702,7 @@ public:
             const size_type src_offset_j = 0);
 
   /**
-   * Weighted addition of the
-   * transpose of <tt>B</tt> to
-   * <tt>this</tt>.
+   * Weighted addition of the transpose of <tt>B</tt> to <tt>this</tt>.
    *
    * <i>A += s B<sup>T</sup></i>
    */
@@ -908,24 +713,13 @@ public:
   /**
    * Add transpose of a rectangular block.
    *
-   * A rectangular block of the
-   * matrix <tt>src</tt> is
-   * transposed and addedadded to
-   * <tt>this</tt>. The upper left
-   * corner of the block being
-   * copied is
-   * <tt>(src_offset_i,src_offset_j)</tt>
-   * in the coordinates of the
-   * <b>non</b>-transposed matrix.
-   * The upper left corner of the
-   * copied block is
-   * <tt>(dst_offset_i,dst_offset_j)</tt>.
-   * The size of the rectangular
-   * block being copied is the
-   * maximum size possible,
-   * determined either by the size
-   * of <tt>this</tt> or
-   * <tt>src</tt>.
+   * A rectangular block of the matrix <tt>src</tt> is transposed and
+   * addedadded to <tt>this</tt>. The upper left corner of the block being
+   * copied is <tt>(src_offset_i,src_offset_j)</tt> in the coordinates of the
+   * <b>non</b>-transposed matrix.  The upper left corner of the copied block
+   * is <tt>(dst_offset_i,dst_offset_j)</tt>.  The size of the rectangular
+   * block being copied is the maximum size possible, determined either by the
+   * size of <tt>this</tt> or <tt>src</tt>.
    */
   template <typename number2>
   void Tadd (const FullMatrix<number2> &src,
@@ -936,27 +730,19 @@ public:
              const size_type src_offset_j = 0);
 
   /**
-   * Add a single element at the
-   * given position.
+   * Add a single element at the given position.
    */
   void add (const size_type row,
             const size_type column,
             const number value);
 
   /**
-   * Add an array of values given by
-   * <tt>values</tt> in the given global
-   * matrix row at columns specified by
-   * col_indices in the full matrix. This
-   * function is present for
-   * compatibility with the various
-   * sparse matrices in deal.II. In
-   * particular, the two boolean fields
-   * @p elide_zero_values and @p
-   * col_indices_are_sorted do not impact
-   * the performance of this routine, as
-   * opposed to the sparse matrix case
-   * and are indeed ignored in the
+   * Add an array of values given by <tt>values</tt> in the given global
+   * matrix row at columns specified by col_indices in the full matrix. This
+   * function is present for compatibility with the various sparse matrices in
+   * deal.II. In particular, the two boolean fields @p elide_zero_values and
+   * @p col_indices_are_sorted do not impact the performance of this routine,
+   * as opposed to the sparse matrix case and are indeed ignored in the
    * implementation.
    */
   template <typename number2, typename index_type>
@@ -968,75 +754,62 @@ public:
             const bool          col_indices_are_sorted = false);
 
   /**
-   * <i>A(i,1...n) +=
-   * s*A(j,1...n)</i>.  Simple
-   * addition of rows of this
+   * <i>A(i,1...n) += s*A(j,1...n)</i>.  Simple addition of rows of this
    */
   void add_row (const size_type i,
                 const number    s,
                 const size_type j);
 
   /**
-   * <i>A(i,1...n) += s*A(j,1...n) +
-   * t*A(k,1...n)</i>.  Multiple
-   * addition of rows of this.
+   * <i>A(i,1...n) += s*A(j,1...n) + t*A(k,1...n)</i>.  Multiple addition of
+   * rows of this.
    */
   void add_row (const size_type i,
                 const number s, const size_type j,
                 const number t, const size_type k);
 
   /**
-   * <i>A(1...n,i) += s*A(1...n,j)</i>.
-   *  Simple addition of columns of this.
+   * <i>A(1...n,i) += s*A(1...n,j)</i>.  Simple addition of columns of this.
    */
   void add_col (const size_type i,
                 const number    s,
                 const size_type j);
 
   /**
-   * <i>A(1...n,i) += s*A(1...n,j) +
-   * t*A(1...n,k)</i>.  Multiple
-   * addition of columns of this.
+   * <i>A(1...n,i) += s*A(1...n,j) + t*A(1...n,k)</i>.  Multiple addition of
+   * columns of this.
    */
   void add_col (const size_type i,
                 const number s, const size_type j,
                 const number t, const size_type k);
 
   /**
-   * Swap <i>A(i,1...n) <->
-   * A(j,1...n)</i>.  Swap rows i
-   * and j of this
+   * Swap <i>A(i,1...n) <-> A(j,1...n)</i>.  Swap rows i and j of this
    */
   void swap_row (const size_type i,
                  const size_type j);
 
   /**
-   *  Swap <i>A(1...n,i) <->
-   *  A(1...n,j)</i>.  Swap columns
-   *  i and j of this
+   *  Swap <i>A(1...n,i) <-> A(1...n,j)</i>.  Swap columns i and j of this
    */
   void swap_col (const size_type i,
                  const size_type j);
 
   /**
-   * Add constant to diagonal
-   * elements of this, i.e. add a
-   * multiple of the identity
-   * matrix.
+   * Add constant to diagonal elements of this, i.e. add a multiple of the
+   * identity matrix.
    */
   void diagadd (const number s);
 
   /**
-   * Assignment <tt>*this =
-   * a*A</tt>.
+   * Assignment <tt>*this = a*A</tt>.
    */
   template <typename number2>
   void equ (const number               a,
             const FullMatrix<number2> &A);
 
   /**
-   * Assignment <tt>*this = a*A +
-   * b*B</tt>.
+   * Assignment <tt>*this = a*A + b*B</tt>.
    */
   template <typename number2>
   void equ (const number               a,
@@ -1045,8 +818,7 @@ public:
             const FullMatrix<number2> &B);
 
   /**
-   * Assignment <tt>*this = a*A +
-   * b*B + c*C</tt>.
+   * Assignment <tt>*this = a*A + b*B + c*C</tt>.
    */
   template <typename number2>
   void equ (const number               a,
@@ -1057,90 +829,67 @@ public:
             const FullMatrix<number2> &C);
 
   /**
-   * Symmetrize the matrix by
-   * forming the mean value between
-   * the existing matrix and its
-   * transpose, <i>A =
-   * 1/2(A+A<sup>T</sup>)</i>.
+   * Symmetrize the matrix by forming the mean value between the existing
+   * matrix and its transpose, <i>A = 1/2(A+A<sup>T</sup>)</i>.
    *
-   * Obviously the matrix must be
-   * quadratic for this operation.
+   * Obviously the matrix must be quadratic for this operation.
    */
   void symmetrize ();
 
   /**
-   * A=Inverse(A). A must be a square matrix.
-   * Inversion of
-   * this matrix by Gauss-Jordan
-   * algorithm with partial
-   * pivoting.  This process is
-   * well-behaved for positive
-   * definite matrices, but be
-   * aware of round-off errors in
-   * the indefinite case.
-   *
-   * In case deal.II was configured with
-   * LAPACK, the functions Xgetrf and
-   * Xgetri build an LU factorization and
-   * invert the matrix upon that
-   * factorization, providing best
-   * performance up to matrices with a
-   * few hundreds rows and columns.
-   *
-   * The numerical effort to invert
-   * an <tt>n x n</tt> matrix is of the
-   * order <tt>n**3</tt>.
+   * A=Inverse(A). A must be a square matrix.  Inversion of this matrix by
+   * Gauss-Jordan algorithm with partial pivoting.  This process is
+   * well-behaved for positive definite matrices, but be aware of round-off
+   * errors in the indefinite case.
+   *
+   * In case deal.II was configured with LAPACK, the functions Xgetrf and
+   * Xgetri build an LU factorization and invert the matrix upon that
+   * factorization, providing best performance up to matrices with a few
+   * hundreds rows and columns.
+   *
+   * The numerical effort to invert an <tt>n x n</tt> matrix is of the order
+   * <tt>n**3</tt>.
    */
   void gauss_jordan ();
 
   /**
-   * Assign the inverse of the given matrix
-   * to <tt>*this</tt>. This function is
-   * hardcoded for quadratic matrices of
-   * dimension one to four. However, since
-   * the amount of code needed grows
-   * quickly, the method gauss_jordan() is
-   * invoked implicitly if the dimension is
-   * larger.
+   * Assign the inverse of the given matrix to <tt>*this</tt>. This function
+   * is hardcoded for quadratic matrices of dimension one to four. However,
+   * since the amount of code needed grows quickly, the method gauss_jordan()
+   * is invoked implicitly if the dimension is larger.
    */
   template <typename number2>
   void invert (const FullMatrix<number2> &M);
 
   /**
-   * Assign the Cholesky decomposition
-   * of the given matrix to <tt>*this</tt>.
-   * The given matrix must be symmetric
-   * positive definite.
+   * Assign the Cholesky decomposition of the given matrix to <tt>*this</tt>.
+   * The given matrix must be symmetric positive definite.
    *
-   * ExcMatrixNotPositiveDefinite
-   * will be thrown in the case that the
-   * matrix is not positive definite.
+   * ExcMatrixNotPositiveDefinite will be thrown in the case that the matrix
+   * is not positive definite.
    */
   template <typename number2>
   void cholesky (const FullMatrix<number2> &A);
 
   /**
-   * <tt>*this(i,j)</tt> = $V(i) W(j)$
-   * where $V,W$
-   * are vectors of the same length.
+   * <tt>*this(i,j)</tt> = $V(i) W(j)$ where $V,W$ are vectors of the same
+   * length.
    */
   template <typename number2>
   void outer_product (const Vector<number2> &V,
                       const Vector<number2> &W);
 
   /**
-   * Assign the left_inverse of the given matrix
-   * to <tt>*this</tt>. The calculation being
-   * performed is <i>(A<sup>T</sup>*A)<sup>-1</sup>
+   * Assign the left_inverse of the given matrix to <tt>*this</tt>. The
+   * calculation being performed is <i>(A<sup>T</sup>*A)<sup>-1</sup>
    * *A<sup>T</sup></i>.
    */
   template <typename number2>
   void left_invert (const FullMatrix<number2> &M);
 
   /**
-   * Assign the right_inverse of the given matrix
-   * to <tt>*this</tt>. The calculation being
-   * performed is <i>A<sup>T</sup>*(A*A<sup>T</sup>)
+   * Assign the right_inverse of the given matrix to <tt>*this</tt>. The
+   * calculation being performed is <i>A<sup>T</sup>*(A*A<sup>T</sup>)
    * <sup>-1</sup></i>.
    */
   template <typename number2>
@@ -1153,10 +902,8 @@ public:
   /**
    * Matrix-matrix-multiplication.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>C</tt> or added
-   * to <tt>C</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
    *
    * if (adding)
    *  <i>C += A*B</i>
@@ -1164,17 +911,13 @@ public:
    * if (!adding)
    *  <i>C = A*B</i>
    *
-   * Assumes that <tt>A</tt> and
-   * <tt>B</tt> have compatible sizes and
-   * that <tt>C</tt> already has the
-   * right size.
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
    *
-   * This function uses the BLAS function
-   * Xgemm if the calling matrix has more
-   * than 15 rows and BLAS was detected
-   * during configuration. Using BLAS
-   * usually results in considerable
-   * performance gains.
+   * This function uses the BLAS function Xgemm if the product of the three
+   * matrix dimensions is larger than 300 and BLAS was detected during
+   * configuration. Using BLAS usually results in considerable performance
+   * gains.
    */
   template <typename number2>
   void mmult (FullMatrix<number2>       &C,
@@ -1182,13 +925,10 @@ public:
               const bool                 adding=false) const;
 
   /**
-   * Matrix-matrix-multiplication using
-   * transpose of <tt>this</tt>.
+   * Matrix-matrix-multiplication using transpose of <tt>this</tt>.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>C</tt> or added
-   * to <tt>C</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
    *
    * if (adding)
    *  <i>C += A<sup>T</sup>*B</i>
@@ -1196,17 +936,13 @@ public:
    * if (!adding)
    *  <i>C = A<sup>T</sup>*B</i>
    *
-   * Assumes that <tt>A</tt> and
-   * <tt>B</tt> have compatible
-   * sizes and that <tt>C</tt>
-   * already has the right size.
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
    *
-   * This function uses the BLAS function
-   * Xgemm if the calling matrix has more
-   * than 15 columns and BLAS was
-   * detected during configuration. Using
-   * BLAS usually results in considerable
-   * performance gains.
+   * This function uses the BLAS function Xgemm if the product of the three
+   * matrix dimensions is larger than 300 and BLAS was detected during
+   * configuration. Using BLAS usually results in considerable performance
+   * gains.
    */
   template <typename number2>
   void Tmmult (FullMatrix<number2>       &C,
@@ -1214,13 +950,10 @@ public:
                const bool                 adding=false) const;
 
   /**
-   * Matrix-matrix-multiplication using
-   * transpose of <tt>B</tt>.
+   * Matrix-matrix-multiplication using transpose of <tt>B</tt>.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>C</tt> or added
-   * to <tt>C</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
    *
    * if (adding)
    *  <i>C += A*B<sup>T</sup></i>
@@ -1228,17 +961,13 @@ public:
    * if (!adding)
    *  <i>C = A*B<sup>T</sup></i>
    *
-   * Assumes that <tt>A</tt> and
-   * <tt>B</tt> have compatible sizes and
-   * that <tt>C</tt> already has the
-   * right size.
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
    *
-   * This function uses the BLAS function
-   * Xgemm if the calling matrix has more
-   * than 15 rows and BLAS was detected
-   * during configuration. Using BLAS
-   * usually results in considerable
-   * performance gains.
+   * This function uses the BLAS function Xgemm if the product of the three
+   * matrix dimensions is larger than 300 and BLAS was detected during
+   * configuration. Using BLAS usually results in considerable performance
+   * gains.
    */
   template <typename number2>
   void mTmult (FullMatrix<number2>       &C,
@@ -1246,14 +975,11 @@ public:
                const bool                 adding=false) const;
 
   /**
-   * Matrix-matrix-multiplication using
-   * transpose of <tt>this</tt> and
+   * Matrix-matrix-multiplication using transpose of <tt>this</tt> and
    * <tt>B</tt>.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>C</tt> or added
-   * to <tt>C</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
    *
    * if (adding)
    *  <i>C += A<sup>T</sup>*B<sup>T</sup></i>
@@ -1261,17 +987,13 @@ public:
    * if (!adding)
    *  <i>C = A<sup>T</sup>*B<sup>T</sup></i>
    *
-   * Assumes that <tt>A</tt> and
-   * <tt>B</tt> have compatible
-   * sizes and that <tt>C</tt>
-   * already has the right size.
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
    *
-   * This function uses the BLAS function
-   * Xgemm if the calling matrix has more
-   * than 15 columns and BLAS was
-   * detected during configuration. Using
-   * BLAS usually results in considerable
-   * performance gains.
+   * This function uses the BLAS function Xgemm if the product of the three
+   * matrix dimensions is larger than 300 and BLAS was detected during
+   * configuration. Using BLAS usually results in considerable performance
+   * gains.
    */
   template <typename number2>
   void TmTmult (FullMatrix<number2>       &C,
@@ -1279,24 +1001,14 @@ public:
                 const bool                 adding=false) const;
 
   /**
-   * Add to the current matrix the
-   * triple product <b>B A
-   * D</b>. Optionally, use the
-   * transposes of the matrices
-   * <b>B</b> and <b>D</b>. The
-   * scaling factor scales the
-   * whole product, which is
-   * helpful when adding a multiple
-   * of the triple product to the
-   * matrix.
-   *
-   * This product was written with
-   * the Schur complement
-   * <b>B<sup>T</sup>
-   * A<sup>-1</sup> D</b> in mind.
-   * Note that in this case the
-   * argument for <tt>A</tt> must be
-   * the inverse of the matrix <b>A</b>.
+   * Add to the current matrix the triple product <b>B A D</b>. Optionally,
+   * use the transposes of the matrices <b>B</b> and <b>D</b>. The scaling
+   * factor scales the whole product, which is helpful when adding a multiple
+   * of the triple product to the matrix.
+   *
+   * This product was written with the Schur complement <b>B<sup>T</sup>
+   * A<sup>-1</sup> D</b> in mind.  Note that in this case the argument for
+   * <tt>A</tt> must be the inverse of the matrix <b>A</b>.
    */
   void triple_product(const FullMatrix<number> &A,
                       const FullMatrix<number> &B,
@@ -1308,10 +1020,8 @@ public:
   /**
    * Matrix-vector-multiplication.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>w</tt> or added
-   * to <tt>w</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>w</tt> or added to <tt>w</tt>.
    *
    * if (adding)
    *  <i>w += A*v</i>
@@ -1319,8 +1029,7 @@ public:
    * if (!adding)
    *  <i>w = A*v</i>
    *
-   * Source and destination must
-   * not be the same vector.
+   * Source and destination must not be the same vector.
    */
   template <typename number2>
   void vmult (Vector<number2>       &w,
@@ -1328,24 +1037,19 @@ public:
               const bool             adding=false) const;
 
   /**
-   * Adding Matrix-vector-multiplication.
-   *  <i>w += A*v</i>
+   * Adding Matrix-vector-multiplication.  <i>w += A*v</i>
    *
-   * Source and destination must
-   * not be the same vector.
+   * Source and destination must not be the same vector.
    */
   template <typename number2>
   void vmult_add (Vector<number2>       &w,
                   const Vector<number2> &v) const;
 
   /**
-   * Transpose
-   * matrix-vector-multiplication.
+   * Transpose matrix-vector-multiplication.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>w</tt> or added
-   * to <tt>w</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>w</tt> or added to <tt>w</tt>.
    *
    * if (adding)
    *  <i>w += A<sup>T</sup>*v</i>
@@ -1354,8 +1058,7 @@ public:
    *  <i>w = A<sup>T</sup>*v</i>
    *
    *
-   * Source and destination must
-   * not be the same vector.
+   * Source and destination must not be the same vector.
    */
   template <typename number2>
   void Tvmult (Vector<number2>       &w,
@@ -1363,26 +1066,19 @@ public:
                const bool             adding=false) const;
 
   /**
-   * Adding transpose
-   * matrix-vector-multiplication.
-   *  <i>w += A<sup>T</sup>*v</i>
+   * Adding transpose matrix-vector-multiplication.  <i>w +=
+   * A<sup>T</sup>*v</i>
    *
-   * Source and destination must
-   * not be the same vector.
+   * Source and destination must not be the same vector.
    */
   template <typename number2>
   void Tvmult_add (Vector<number2>       &w,
                    const Vector<number2> &v) const;
 
   /**
-   * Apply the Jacobi
-   * preconditioner, which
-   * multiplies every element of
-   * the <tt>src</tt> vector by the
-   * inverse of the respective
-   * diagonal element and
-   * multiplies the result with the
-   * damping factor <tt>omega</tt>.
+   * Apply the Jacobi preconditioner, which multiplies every element of the
+   * <tt>src</tt> vector by the inverse of the respective diagonal element and
+   * multiplies the result with the damping factor <tt>omega</tt>.
    */
   template <typename somenumber>
   void precondition_Jacobi (Vector<somenumber>       &dst,
@@ -1390,13 +1086,10 @@ public:
                             const number              omega = 1.) const;
 
   /**
-   * <i>dst=b-A*x</i>. Residual calculation,
-   * returns the <i>l<sub>2</sub></i>-norm
-   * |<i>dst</i>|.
+   * <i>dst=b-A*x</i>. Residual calculation, returns the
+   * <i>l<sub>2</sub></i>-norm |<i>dst</i>|.
    *
-   * Source <i>x</i> and destination
-   * <i>dst</i> must not be the same
-   * vector.
+   * Source <i>x</i> and destination <i>dst</i> must not be the same vector.
    */
   template <typename number2, typename number3>
   number residual (Vector<number2>       &dst,
@@ -1404,35 +1097,25 @@ public:
                    const Vector<number3> &b) const;
 
   /**
-   * Forward elimination of lower
-   * triangle.  Inverts the lower
-   * triangle of a rectangular matrix
-   * for a given right hand side.
+   * Forward elimination of lower triangle.  Inverts the lower triangle of a
+   * rectangular matrix for a given right hand side.
    *
-   * If the matrix has more columns
-   * than rows, this function only
-   * operates on the left quadratic
-   * submatrix. If there are more
-   * rows, the upper quadratic part
-   * of the matrix is considered.
+   * If the matrix has more columns than rows, this function only operates on
+   * the left quadratic submatrix. If there are more rows, the upper quadratic
+   * part of the matrix is considered.
    *
-   * @note It is safe to use the
-   * same object for @p dst and @p
-   * src.
+   * @note It is safe to use the same object for @p dst and @p src.
    */
   template <typename number2>
   void forward (Vector<number2>       &dst,
                 const Vector<number2> &src) const;
 
   /**
-   * Backward elimination of upper
-   * triangle.
+   * Backward elimination of upper triangle.
    *
    * See forward()
    *
-   * @note It is safe to use the
-   * same object for @p dst and @p
-   * src.
+   * @note It is safe to use the same object for @p dst and @p src.
    */
   template <typename number2>
   void backward (Vector<number2>       &dst,
index 44c3bb893318045a30697282ddece7be194f62c5..2731918d259ab233e6d6b3a042ddb3c1330740e0 100644 (file)
@@ -575,8 +575,7 @@ void FullMatrix<number>::mmult (FullMatrix<number2>       &dst,
         const number alpha = 1.;
         const number beta = (adding == true) ? 1. : 0.;
 
-        // Use the BLAS function gemm for
-        // calculating the matrix-matrix
+        // Use the BLAS function gemm for calculating the matrix-matrix
         // product.
         gemm(notrans, notrans, &m, &n, &k, &alpha, &src(0,0), &m,
              &this->values[0], &k, &beta, &dst(0,0), &m);
index b6000c48e5038e526d80aaaa9f0f6c9a86cc8632..92e0dd09e8b5227c0364886f232ffb89e458289c 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -60,47 +60,31 @@ public:
   typedef types::global_dof_index size_type;
 
   /**
-   * Constructor. Initialize the
-   * matrix as a square matrix with
-   * dimension <tt>n</tt>.
+   * Constructor. Initialize the matrix as a square matrix with dimension
+   * <tt>n</tt>.
    *
-   * In order to avoid the implicit
-   * conversion of integers and
-   * other types to a matrix, this
-   * constructor is declared
-   * <tt>explicit</tt>.
+   * In order to avoid the implicit conversion of integers and other types to
+   * a matrix, this constructor is declared <tt>explicit</tt>.
    *
-   * By default, no memory is
-   * allocated.
+   * By default, no memory is allocated.
    */
   explicit LAPACKFullMatrix (const size_type n = 0);
 
   /**
-   * Constructor. Initialize the
-   * matrix as a rectangular
-   * matrix.
+   * Constructor. Initialize the matrix as a rectangular matrix.
    */
   LAPACKFullMatrix (const size_type rows,
                     const size_type cols);
 
   /**
-   * Copy constructor. This
-   * constructor does a deep copy
-   * of the matrix. Therefore, it
-   * poses a possible efficiency
-   * problem, if for example,
-   * function arguments are passed
-   * by value rather than by
-   * reference. Unfortunately, we
-   * can't mark this copy
-   * constructor <tt>explicit</tt>,
-   * since that prevents the use of
-   * this class in containers, such
-   * as <tt>std::vector</tt>. The
-   * responsibility to check
-   * performance of programs must
-   * therefore remain with the
-   * user of this class.
+   * Copy constructor. This constructor does a deep copy of the
+   * matrix. Therefore, it poses a possible efficiency problem, if for
+   * example, function arguments are passed by value rather than by
+   * reference. Unfortunately, we can't mark this copy constructor
+   * <tt>explicit</tt>, since that prevents the use of this class in
+   * containers, such as <tt>std::vector</tt>. The responsibility to check
+   * performance of programs must therefore remain with the user of this
+   * class.
    */
   LAPACKFullMatrix (const LAPACKFullMatrix &);
 
@@ -111,35 +95,26 @@ public:
   operator = (const LAPACKFullMatrix<number> &);
 
   /**
-   * Assignment operator for a
-   * regular FullMatrix. Note that
-   * since LAPACK expects matrices
-   * in transposed order, this
-   * transposition is included here.
+   * Assignment operator for a regular FullMatrix. Note that since LAPACK
+   * expects matrices in transposed order, this transposition is included
+   * here.
    */
   template <typename number2>
   LAPACKFullMatrix<number> &
   operator = (const FullMatrix<number2> &);
 
   /**
-   * This operator assigns a scalar
-   * to a matrix. To avoid
-   * confusion with constructors,
-   * zero is the only value allowed
-   * for <tt>d</tt>
+   * This operator assigns a scalar to a matrix. To avoid confusion with
+   * constructors, zero is the only value allowed for <tt>d</tt>
    */
   LAPACKFullMatrix<number> &
   operator = (const double d);
 
   /**
-   * Assignment from different
-   * matrix classes, performing the
-   * usual conversion to the
-   * transposed format expected by LAPACK. This
-   * assignment operator uses
-   * iterators of the class
-   * MATRIX. Therefore, sparse
-   * matrices are possible sources.
+   * Assignment from different matrix classes, performing the usual conversion
+   * to the transposed format expected by LAPACK. This assignment operator
+   * uses iterators of the class MATRIX. Therefore, sparse matrices are
+   * possible sources.
    */
   template <class MATRIX>
   void copy_from (const MATRIX &);
@@ -147,24 +122,15 @@ public:
   /**
    * Fill rectangular block.
    *
-   * A rectangular block of the
-   * matrix <tt>src</tt> is copied into
-   * <tt>this</tt>. The upper left
-   * corner of the block being
-   * copied is
-   * <tt>(src_offset_i,src_offset_j)</tt>.
-   * The upper left corner of the
-   * copied block is
-   * <tt>(dst_offset_i,dst_offset_j)</tt>.
-   * The size of the rectangular
-   * block being copied is the
-   * maximum size possible,
-   * determined either by the size
-   * of <tt>this</tt> or <tt>src</tt>.
-   *
-   * The final two arguments allow
-   * to enter a multiple of the
-   * source or its transpose.
+   * A rectangular block of the matrix <tt>src</tt> is copied into
+   * <tt>this</tt>. The upper left corner of the block being copied is
+   * <tt>(src_offset_i,src_offset_j)</tt>.  The upper left corner of the
+   * copied block is <tt>(dst_offset_i,dst_offset_j)</tt>.  The size of the
+   * rectangular block being copied is the maximum size possible, determined
+   * either by the size of <tt>this</tt> or <tt>src</tt>.
+   *
+   * The final two arguments allow to enter a multiple of the source or its
+   * transpose.
    */
   template<class MATRIX>
   void fill (const MATRIX &src,
@@ -179,33 +145,19 @@ public:
   /**
    * Matrix-vector-multiplication.
    *
-  * Depending on previous
-  * transformations recorded in #state, the
-  * result of this function is one
-  * of
-  *
-  * <ul>
-  * <li> If #state is LAPACKSupport::matrix or
-  * LAPACKSupport::inverse_matrix,
-  * this will be a regular matrix
-  * vector product using LAPACK
-  * gemv().
-  * <li> If #state is
-  * LAPACKSupport::svd or
-  * LAPACKSupport::inverse_svd,
-  * this function first multiplies
-  * with the right transformation
-  * matrix, then with the diagonal
-  * matrix of singular values or
-  * their reciprocal values, and
-  * finally with the left
-  * trandformation matrix.
-  * </ul>
-  *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>w</tt> or added
-   * to <tt>w</tt>.
+   * Depending on previous transformations recorded in #state, the result of
+   * this function is one of
+   * <ul>
+   * <li> If #state is LAPACKSupport::matrix or LAPACKSupport::inverse_matrix,
+   * this will be a regular matrix vector product using LAPACK gemv().
+   * <li> If #state is LAPACKSupport::svd or LAPACKSupport::inverse_svd, this
+   * function first multiplies with the right transformation matrix, then with
+   * the diagonal matrix of singular values or their reciprocal values, and
+   * finally with the left trandformation matrix.
+   * </ul>
+   *
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>w</tt> or added to <tt>w</tt>.
    *
    * if (adding)
    *  <i>w += A*v</i>
@@ -213,36 +165,28 @@ public:
    * if (!adding)
    *  <i>w = A*v</i>
    *
-   * @note Source and destination must
-   * not be the same vector.
+   * @note Source and destination must not be the same vector.
    *
-   * @note This template only
-   * exists for compile-time
-   * compatibility with
-   * FullMatrix. Implementation is
-   * only available for <tt>VECTOR=Vector&lt;number&gt;</tt>
+   * @note This template only exists for compile-time compatibility with
+   * FullMatrix. Implementation is only available for
+   * <tt>VECTOR=Vector&lt;number&gt;</tt>
    */
   template <class VECTOR>
   void vmult(VECTOR &dst, const VECTOR &src, const bool adding = false) const;
+
   /**
-   * Adding Matrix-vector-multiplication.
-   *  <i>w += A*v</i>
+   * Adding Matrix-vector-multiplication.  <i>w += A*v</i>
    *
-  * See the documentation of
-  * vmult() for details on the
-  * implementation.
+   * See the documentation of vmult() for details on the implementation.
    */
   template <class VECTOR>
   void vmult_add (VECTOR &w, const VECTOR &v) const;
 
   /**
-   * Transpose
-   * matrix-vector-multiplication.
+   * Transpose matrix-vector-multiplication.
    *
-   * The optional parameter
-   * <tt>adding</tt> determines, whether the
-   * result is stored in <tt>w</tt> or added
-   * to <tt>w</tt>.
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>w</tt> or added to <tt>w</tt>.
    *
    * if (adding)
    *  <i>w += A<sup>T</sup>*v</i>
@@ -250,22 +194,17 @@ public:
    * if (!adding)
    *  <i>w = A<sup>T</sup>*v</i>
    *
-  * See the documentation of
-  * vmult() for details on the
-  * implementation.
+  * See the documentation of vmult() for details on the implementation.
    */
   template <class VECTOR>
   void Tvmult (VECTOR &w, const VECTOR &v,
                const bool            adding=false) const;
 
   /**
-   * Adding transpose
-   * matrix-vector-multiplication.
-   *  <i>w += A<sup>T</sup>*v</i>
+   * Adding transpose matrix-vector-multiplication.  <i>w +=
+   * A<sup>T</sup>*v</i>
    *
-  * See the documentation of
-  * vmult() for details on the
-  * implementation.
+   * See the documentation of vmult() for details on the implementation.
    */
   template <class VECTOR>
   void Tvmult_add (VECTOR &w, const VECTOR &v) const;
@@ -280,103 +219,197 @@ public:
                const bool            adding=false) const;
   void Tvmult_add (Vector<number>       &w,
                    const Vector<number> &v) const;
+
+
+  /**
+   * Matrix-matrix-multiplication.
+   *
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
+   *
+   * if (adding)
+   *  <i>C += A*B</i>
+   *
+   * if (!adding)
+   *  <i>C = A*B</i>
+   *
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
+   *
+   * This function uses the BLAS function Xgemm.
+   */
+  void mmult (LAPACKFullMatrix<number>       &C,
+              const LAPACKFullMatrix<number> &B,
+              const bool                      adding=false) const;
+
+  /**
+   * Same as before, but stores the result in a FullMatrix, not in a
+   * LAPACKFullMatrix.
+   */
+  void mmult (FullMatrix<number>             &C,
+              const LAPACKFullMatrix<number> &B,
+              const bool                      adding=false) const;
+
+  /**
+   * Matrix-matrix-multiplication using transpose of <tt>this</tt>.
+   *
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
+   *
+   * if (adding)
+   *  <i>C += A<sup>T</sup>*B</i>
+   *
+   * if (!adding)
+   *  <i>C = A<sup>T</sup>*B</i>
+   *
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
+   *
+   * This function uses the BLAS function Xgemm.
+   */
+  void Tmmult (LAPACKFullMatrix<number>       &C,
+               const LAPACKFullMatrix<number> &B,
+               const bool                      adding=false) const;
+
+  /**
+   * Same as before, but stores the result in a FullMatrix, not in a
+   * LAPACKFullMatrix.
+   */
+  void Tmmult (FullMatrix<number>             &C,
+               const LAPACKFullMatrix<number> &B,
+               const bool                      adding=false) const;
+
+  /**
+   * Matrix-matrix-multiplication using transpose of <tt>B</tt>.
+   *
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
+   *
+   * if (adding)
+   *  <i>C += A*B<sup>T</sup></i>
+   *
+   * if (!adding)
+   *  <i>C = A*B<sup>T</sup></i>
+   *
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
+   *
+   * This function uses the BLAS function Xgemm.
+   */
+  void mTmult (LAPACKFullMatrix<number>       &C,
+               const LAPACKFullMatrix<number> &B,
+               const bool                      adding=false) const;
+
   /**
-   * Compute the LU factorization
-   * of the matrix using LAPACK
-   * function Xgetrf.
+   * Same as before, but stores the result in a FullMatrix, not in a
+   * LAPACKFullMatrix.
+   */
+  void mTmult (FullMatrix<number>             &C,
+               const LAPACKFullMatrix<number> &B,
+               const bool                      adding=false) const;
+
+  /**
+   * Matrix-matrix-multiplication using transpose of <tt>this</tt> and
+   * <tt>B</tt>.
+   *
+   * The optional parameter <tt>adding</tt> determines, whether the result is
+   * stored in <tt>C</tt> or added to <tt>C</tt>.
+   *
+   * if (adding)
+   *  <i>C += A<sup>T</sup>*B<sup>T</sup></i>
+   *
+   * if (!adding)
+   *  <i>C = A<sup>T</sup>*B<sup>T</sup></i>
+   *
+   * Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that
+   * <tt>C</tt> already has the right size.
+   *
+   * This function uses the BLAS function Xgemm.
+   */
+  void TmTmult (LAPACKFullMatrix<number>       &C,
+                const LAPACKFullMatrix<number> &B,
+                const bool                      adding=false) const;
+
+  /**
+   * Same as before, but stores the result in a FullMatrix, not in a
+   * LAPACKFullMatrix.
+   */
+  void TmTmult (FullMatrix<number>             &C,
+                const LAPACKFullMatrix<number> &B,
+                const bool                      adding=false) const;
+
+  /**
+   * Compute the LU factorization of the matrix using LAPACK function Xgetrf.
    */
   void compute_lu_factorization ();
 
   /**
-   * Invert the matrix by first computing
-   * an LU factorization with the LAPACK
-   * function Xgetrf and then building
-   * the actual inverse using Xgetri.
+   * Invert the matrix by first computing an LU factorization with the LAPACK
+   * function Xgetrf and then building the actual inverse using Xgetri.
    */
   void invert ();
 
   /**
-   * Solve the linear system with
-   * right hand side given by
-   * applying forward/backward
-   * substitution to the previously
-   * computed LU
-   * factorization. Uses LAPACK
-   * function Xgetrs.
+   * Solve the linear system with right hand side given by applying
+   * forward/backward substitution to the previously computed LU
+   * factorization. Uses LAPACK function Xgetrs.
+   *
+   * The flag transposed indicates whether the solution of the transposed
+   * system is to be performed.
    */
   void apply_lu_factorization (Vector<number> &v,
                                const bool transposed) const;
 
   /**
-   * Compute eigenvalues of the
-   * matrix. After this routine has
-   * been called, eigenvalues can
-   * be retrieved using the
-   * eigenvalue() function. The
-   * matrix itself will be
-   * LAPACKSupport::unusable after
-   * this operation.
-   *
-   * The optional arguments allow
-   * to compute left and right
-   * eigenvectors as well.
-   *
-   * Note that the function does
-   * not return the computed
-   * eigenvalues right away since
-   * that involves copying data
-   * around between the output
-   * arrays of the LAPACK functions
-   * and any return array. This is
-   * often unnecessary since one
-   * may not be interested in all
-   * eigenvalues at once, but for
-   * example only the extreme
-   * ones. In that case, it is
-   * cheaper to just have this
-   * function compute the
-   * eigenvalues and have a
-   * separate function that returns
-   * whatever eigenvalue is
-   * requested.
-   *
-   * @note Calls the LAPACK
-   * function Xgeev.
+   * Solve the linear system with multiple right hand sides (as many as there
+   * are columns in the matrix b) given by applying forward/backward
+   * substitution to the previously computed LU factorization. Uses LAPACK
+   * function Xgetrs.
+   *
+   * The flag transposed indicates whether the solution of the transposed
+   * system is to be performed.
+   */
+  void apply_lu_factorization (LAPACKFullMatrix<number> &B,
+                               const bool transposed) const;
+
+  /**
+   * Compute eigenvalues of the matrix. After this routine has been called,
+   * eigenvalues can be retrieved using the eigenvalue() function. The matrix
+   * itself will be LAPACKSupport::unusable after this operation.
+   *
+   * The optional arguments allow to compute left and right eigenvectors as
+   * well.
+   *
+   * Note that the function does not return the computed eigenvalues right
+   * away since that involves copying data around between the output arrays of
+   * the LAPACK functions and any return array. This is often unnecessary
+   * since one may not be interested in all eigenvalues at once, but for
+   * example only the extreme ones. In that case, it is cheaper to just have
+   * this function compute the eigenvalues and have a separate function that
+   * returns whatever eigenvalue is requested.
+   *
+   * @note Calls the LAPACK function Xgeev.
    */
   void compute_eigenvalues (const bool right_eigenvectors = false,
                             const bool left_eigenvectors = false);
 
   /**
-   * Compute eigenvalues and
-   * eigenvectors of a real symmetric
-   * matrix. Only eigenvalues in the
-   * interval (lower_bound, upper_bound]
-   * are computed with the absolute
-   * tolerance abs_accuracy. An approximate
-   * eigenvalue is accepted as converged
-   * when it is determined to lie in an
-   * interval [a,b] of width less than or
-   * equal to abs_accuracy + eps * max( |a|,|b| ),
-   * where eps is the machine precision.
-   * If abs_accuracy is less than
-   * or equal to zero, then  eps*|t| will
-   * be used in its place, where |t| is the
-   * 1-norm of the tridiagonal matrix obtained
-   * by reducing A to tridiagonal form.
-   * Eigenvalues will be computed most accurately
-   * when abs_accuracy is set to twice the
-   * underflow threshold, not zero.
-   * After this routine has
-   * been called, all eigenvalues in
-   * (lower_bound, upper_bound] will be
-   * stored in eigenvalues and the
-   * corresponding eigenvectors will be stored
-   * in the columns of eigenvectors, whose
-   * dimension is set accordingly.
-   *
-   * @note Calls the LAPACK function
-   * Xsyevx. For this to work, ./configure
-   * has to be told to use LAPACK.
+   * Compute eigenvalues and eigenvectors of a real symmetric matrix. Only
+   * eigenvalues in the interval (lower_bound, upper_bound] are computed with
+   * the absolute tolerance abs_accuracy. An approximate eigenvalue is
+   * accepted as converged when it is determined to lie in an interval [a,b]
+   * of width less than or equal to abs_accuracy + eps * max( |a|,|b| ), where
+   * eps is the machine precision.  If abs_accuracy is less than or equal to
+   * zero, then eps*|t| will be used in its place, where |t| is the 1-norm of
+   * the tridiagonal matrix obtained by reducing A to tridiagonal form.
+   * Eigenvalues will be computed most accurately when abs_accuracy is set to
+   * twice the underflow threshold, not zero.  After this routine has been
+   * called, all eigenvalues in (lower_bound, upper_bound] will be stored in
+   * eigenvalues and the corresponding eigenvectors will be stored in the
+   * columns of eigenvectors, whose dimension is set accordingly.
+   *
+   * @note Calls the LAPACK function Xsyevx. For this to work, ./configure has
+   * to be told to use LAPACK.
    */
   void compute_eigenvalues_symmetric(
     const number lower_bound,
@@ -386,45 +419,25 @@ public:
     FullMatrix<number> &eigenvectors);
 
   /**
-   * Compute generalized eigenvalues
-   * and eigenvectors of
-   * a real generalized symmetric
-   * eigenproblem of the form
-   * itype = 1: $Ax=\lambda B x$
-   * itype = 2: $ABx=\lambda x$
-   * itype = 3: $BAx=\lambda x$,
-   * where A is this matrix.
-   * A and B are assumed to be symmetric,
-   * and B has to be positive definite.
-   * Only eigenvalues in the interval
-   * (lower_bound, upper_bound] are
-   * computed with the absolute tolerance
-   * abs_accuracy.
-   * An approximate eigenvalue is accepted
-   * as converged when it is determined to
-   * lie in an interval [a,b] of width less
-   * than or equal to abs_accuracy + eps * max( |a|,|b| ),
-   * where eps is the machine precision.
-   * If abs_accuracy is less than
-   * or equal to zero, then  eps*|t| will
-   * be used in its place, where |t| is the
-   * 1-norm of the tridiagonal matrix obtained
-   * by reducing A to tridiagonal form.
-   * Eigenvalues will be computed most accurately
-   * when abs_accuracy is set to twice the
-   * underflow threshold, not zero.
-   * After this routine has
-   * been called, all eigenvalues in
-   * (lower_bound, upper_bound] will be
-   * stored in eigenvalues and the
-   * corresponding eigenvectors will be stored
-   * in eigenvectors, whose dimension is set
-   * accordingly.
-   *
-   * @note Calls the LAPACK
-   * function Xsygvx. For this to
-   * work, ./configure has to
-   * be told to use LAPACK.
+   * Compute generalized eigenvalues and eigenvectors of a real generalized
+   * symmetric eigenproblem of the form itype = 1: $Ax=\lambda B x$ itype = 2:
+   * $ABx=\lambda x$ itype = 3: $BAx=\lambda x$, where A is this matrix.  A
+   * and B are assumed to be symmetric, and B has to be positive definite.
+   * Only eigenvalues in the interval (lower_bound, upper_bound] are computed
+   * with the absolute tolerance abs_accuracy.  An approximate eigenvalue is
+   * accepted as converged when it is determined to lie in an interval [a,b]
+   * of width less than or equal to abs_accuracy + eps * max( |a|,|b| ), where
+   * eps is the machine precision.  If abs_accuracy is less than or equal to
+   * zero, then eps*|t| will be used in its place, where |t| is the 1-norm of
+   * the tridiagonal matrix obtained by reducing A to tridiagonal form.
+   * Eigenvalues will be computed most accurately when abs_accuracy is set to
+   * twice the underflow threshold, not zero.  After this routine has been
+   * called, all eigenvalues in (lower_bound, upper_bound] will be stored in
+   * eigenvalues and the corresponding eigenvectors will be stored in
+   * eigenvectors, whose dimension is set accordingly.
+   *
+   * @note Calls the LAPACK function Xsygvx. For this to work, ./configure has
+   * to be told to use LAPACK.
    */
   void compute_generalized_eigenvalues_symmetric(
     LAPACKFullMatrix<number> &B,
@@ -436,40 +449,20 @@ public:
     const int itype = 1);
 
   /**
-   * Same as the other
-   * compute_generalized_eigenvalues_symmetric
-   * function except that all
-   * eigenvalues are computed
-   * and the tolerance is set
-   * automatically.
-   * Note that this function does
-   * not return the computed
-   * eigenvalues right away since
-   * that involves copying data
-   * around between the output
-   * arrays of the LAPACK functions
-   * and any return array. This is
-   * often unnecessary since one
-   * may not be interested in all
-   * eigenvalues at once, but for
-   * example only the extreme
-   * ones. In that case, it is
-   * cheaper to just have this
-   * function compute the
-   * eigenvalues and have a
-   * separate function that returns
-   * whatever eigenvalue is
-   * requested. Eigenvalues can
-   * be retrieved using the
-   * eigenvalue() function.
-   * The number of computed
-   * eigenvectors is equal
-   * to eigenvectors.size()
-   *
-   * @note Calls the LAPACK
-   * function Xsygv. For this to
-   * work, ./configure has to
-   * be told to use LAPACK.
+   * Same as the other compute_generalized_eigenvalues_symmetric function
+   * except that all eigenvalues are computed and the tolerance is set
+   * automatically.  Note that this function does not return the computed
+   * eigenvalues right away since that involves copying data around between
+   * the output arrays of the LAPACK functions and any return array. This is
+   * often unnecessary since one may not be interested in all eigenvalues at
+   * once, but for example only the extreme ones. In that case, it is cheaper
+   * to just have this function compute the eigenvalues and have a separate
+   * function that returns whatever eigenvalue is requested. Eigenvalues can
+   * be retrieved using the eigenvalue() function.  The number of computed
+   * eigenvectors is equal to eigenvectors.size()
+   *
+   * @note Calls the LAPACK function Xsygv. For this to work, ./configure has
+   * to be told to use LAPACK.
    */
   void compute_generalized_eigenvalues_symmetric (
     LAPACKFullMatrix<number> &B,
@@ -477,116 +470,70 @@ public:
     const int itype = 1);
 
   /**
-   * Compute the singular value
-   * decomposition of the
-   * matrix using LAPACK function
-   * Xgesdd.
+   * Compute the singular value decomposition of the matrix using LAPACK
+   * function Xgesdd.
    *
-   * Requires that the #state is
-   * LAPACKSupport::matrix, fills
-   * the data members #wr, #svd_u,
-   * and #svd_vt, and leaves the
-   * object in the #state
+   * Requires that the #state is LAPACKSupport::matrix, fills the data members
+   * #wr, #svd_u, and #svd_vt, and leaves the object in the #state
    * LAPACKSupport::svd.
    */
   void compute_svd();
+
   /**
-   * Compute the inverse of the
-   * matrix by singular value
-   * decomposition.
-   *
-   * Requires that #state is either
-   * LAPACKSupport::matrix or
-   * LAPACKSupport::svd. In the
-   * first case, this function
-   * calls compute_svd(). After
-   * this function, the object will
-   * have the #state
+   * Compute the inverse of the matrix by singular value decomposition.
+   *
+   * Requires that #state is either LAPACKSupport::matrix or
+   * LAPACKSupport::svd. In the first case, this function calls
+   * compute_svd(). After this function, the object will have the #state
    * LAPACKSupport::inverse_svd.
    *
-   * For a singular value
-   * decomposition, the inverse is
-   * simply computed by replacing
-   * all singular values by their
-   * reciprocal values. If the
-   * matrix does not have maximal
-   * rank, singular values 0 are
-   * not touched, thus computing
-   * the minimal norm right inverse
-   * of the matrix.
-   *
-   * The parameter
-   * <tt>threshold</tt> determines,
-   * when a singular value should
-   * be considered zero. It is the
-   * ratio of the smallest to the
-   * largest nonzero singular
-   * value
-   * <i>s</i><sub>max</sub>. Thus,
-   * the inverses of all singular
-   * values less than
-   * <i>s</i><sub>max</sub>/<tt>threshold</tt>
-   * will be set to zero.
+   * For a singular value decomposition, the inverse is simply computed by
+   * replacing all singular values by their reciprocal values. If the matrix
+   * does not have maximal rank, singular values 0 are not touched, thus
+   * computing the minimal norm right inverse of the matrix.
+   *
+   * The parameter <tt>threshold</tt> determines, when a singular value should
+   * be considered zero. It is the ratio of the smallest to the largest
+   * nonzero singular value <i>s</i><sub>max</sub>. Thus, the inverses of all
+   * singular values less than <i>s</i><sub>max</sub>/<tt>threshold</tt> will
+   * be set to zero.
    */
   void compute_inverse_svd (const double threshold = 0.);
 
   /**
-   * Retrieve eigenvalue after
-   * compute_eigenvalues() was
-   * called.
+   * Retrieve eigenvalue after compute_eigenvalues() was called.
    */
   std::complex<number>
   eigenvalue (const size_type i) const;
 
   /**
-   * Retrieve singular values after
-   * compute_svd() or
-   * compute_inverse_svd() was
+   * Retrieve singular values after compute_svd() or compute_inverse_svd() was
    * called.
    */
   number
   singular_value (const size_type i) const;
 
   /**
-   * Print the matrix and allow
-   * formatting of entries.
-   *
-   * The parameters allow for a
-   * flexible setting of the output
-   * format:
-   *
-   * @arg <tt>precision</tt>
-   * denotes the number of trailing
-   * digits.
-   *
-   * @arg <tt>scientific</tt> is
-   * used to determine the number
-   * format, where
-   * <tt>scientific</tt> =
-   * <tt>false</tt> means fixed
-   * point notation.
-   *
-   * @arg <tt>width</tt> denotes
-   * the with of each column. A
-   * zero entry for <tt>width</tt>
-   * makes the function compute a
-   * width, but it may be changed
-   * to a positive value, if output
-   * is crude.
-   *
-   * @arg <tt>zero_string</tt>
-   * specifies a string printed for
-   * zero entries.
-   *
-   * @arg <tt>denominator</tt>
-   * Multiply the whole matrix by
-   * this common denominator to get
-   * nicer numbers.
-   *
-   * @arg <tt>threshold</tt>: all
-   * entries with absolute value
-   * smaller than this are
-   * considered zero.
+   * Print the matrix and allow formatting of entries.
+   *
+   * The parameters allow for a flexible setting of the output format:
+   *
+   * @arg <tt>precision</tt> denotes the number of trailing digits.
+   *
+   * @arg <tt>scientific</tt> is used to determine the number format, where
+   * <tt>scientific</tt> = <tt>false</tt> means fixed point notation.
+   *
+   * @arg <tt>width</tt> denotes the with of each column. A zero entry for
+   * <tt>width</tt> makes the function compute a width, but it may be changed
+   * to a positive value, if output is crude.
+   *
+   * @arg <tt>zero_string</tt> specifies a string printed for zero entries.
+   *
+   * @arg <tt>denominator</tt> Multiply the whole matrix by this common
+   * denominator to get nicer numbers.
+   *
+   * @arg <tt>threshold</tt>: all entries with absolute value smaller than
+   * this are considered zero.
   */
   void print_formatted (std::ostream       &out,
                         const unsigned int  presicion=3,
@@ -598,82 +545,64 @@ public:
 
 private:
   /**
-   * Since LAPACK operations
-   * notoriously change the meaning
-   * of the matrix entries, we
-   * record the current state after
-   * the last operation here.
+   * Since LAPACK operations notoriously change the meaning of the matrix
+   * entries, we record the current state after the last operation here.
    */
   LAPACKSupport::State state;
+
   /**
-   * Additional properties of the
-   * matrix which may help to
-   * select more efficient LAPACK
-   * functions.
+   * Additional properties of the matrix which may help to select more
+   * efficient LAPACK functions.
    */
   LAPACKSupport::Properties properties;
 
   /**
-   * The working array used for
-   * some LAPACK functions.
+   * The working array used for some LAPACK functions.
    */
   mutable std::vector<number> work;
 
   /**
-   * The vector storing the
-   * permutations applied for
-   * pivoting in the
+   * The vector storing the permutations applied for pivoting in the
    * LU-factorization.
    *
-   * Also used as the scratch array
-   * IWORK for LAPACK functions
-   * needing it.
+   * Also used as the scratch array IWORK for LAPACK functions needing it.
    */
   std::vector<int> ipiv;
 
   /**
-   * Workspace for calculating the
-   * inverse matrix from an LU
-   * factorization.
+   * Workspace for calculating the inverse matrix from an LU factorization.
    */
   std::vector<number> inv_work;
 
   /**
-   * Real parts of eigenvalues or
-   * the singular values. Filled by
+   * Real parts of eigenvalues or the singular values. Filled by
    * compute_eigenvalues() or compute_svd().
    */
   std::vector<number> wr;
 
   /**
-   * Imaginary parts of
-   * eigenvalues. Filled by
-   * compute_eigenvalues.
+   * Imaginary parts of eigenvalues. Filled by compute_eigenvalues.
    */
   std::vector<number> wi;
 
   /**
-   * Space where left eigenvectors
-   * can be stored.
+   * Space where left eigenvectors can be stored.
    */
   std::vector<number> vl;
 
   /**
-   * Space where right eigenvectors
-   * can be stored.
+   * Space where right eigenvectors can be stored.
    */
   std::vector<number> vr;
 
   /**
-   * The matrix <i>U</i> in the
-   * singular value decomposition
+   * The matrix <i>U</i> in the singular value decomposition
    * <i>USV<sup>T</sup></i>.
    */
   std_cxx1x::shared_ptr<LAPACKFullMatrix<number> > svd_u;
+
   /**
-   * The matrix
-   * <i>V<sup>T</sup></i> in the
-   * singular value decomposition
+   * The matrix <i>V<sup>T</sup></i> in the singular value decomposition
    * <i>USV<sup>T</sup></i>.
    */
   std_cxx1x::shared_ptr<LAPACKFullMatrix<number> > svd_vt;
index 591f8991803d162a54dc3ba65fca224b264805d4..938b9cf60f6b17f2a144d177862a7e3d309c7f66 100644 (file)
@@ -37,11 +37,13 @@ namespace internal
 {
   template <class MATRIX>
   void
-  reinit(MatrixBlock<MATRIX> &v, const BlockSparsityPattern &p);
+  reinit(MatrixBlock<MATRIX> &v,
+        const BlockSparsityPattern &p);
 
   template <typename number>
   void
-  reinit(MatrixBlock<dealii::SparseMatrix<number> > &, const BlockSparsityPattern &);
+  reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
+        const BlockSparsityPattern &p);
 }
 
 /**
@@ -369,6 +371,7 @@ public:
    * The matrix itself
    */
   MATRIX matrix;
+
 private:
   /**
    * The rwo BlockIndices of the
@@ -389,7 +392,14 @@ private:
   BlockIndices column_indices;
 
   template <class OTHER_MATRIX>
-  friend void internal::reinit(MatrixBlock<OTHER_MATRIX> &, const BlockSparsityPattern &);
+  friend
+  void dealii::internal::reinit(MatrixBlock<OTHER_MATRIX> &,
+                               const BlockSparsityPattern &);
+
+  template <typename number>
+  friend
+  void internal::reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
+                         const BlockSparsityPattern &p);
 };
 
 
@@ -691,7 +701,8 @@ namespace internal
 {
   template <class MATRIX>
   void
-  reinit(MatrixBlock<MATRIX> &v, const BlockSparsityPattern &p)
+  reinit(MatrixBlock<MATRIX> &v,
+        const BlockSparsityPattern &p)
   {
     v.row_indices = p.get_row_indices();
     v.column_indices = p.get_column_indices();
@@ -700,7 +711,8 @@ namespace internal
 
   template <typename number>
   void
-  reinit(MatrixBlock<dealii::SparseMatrix<number> > &v, const BlockSparsityPattern &p)
+  reinit(MatrixBlock<dealii::SparseMatrix<number> > &v,
+        const BlockSparsityPattern &p)
   {
     v.row_indices = p.get_row_indices();
     v.column_indices = p.get_column_indices();
index 425175f5afb45dd6be747322acad7ab3ff86162d..cc564b72b3d07e2fc0c4ca33629f07afdf1bf9fe 100644 (file)
@@ -5100,8 +5100,9 @@ namespace internal
                   fe_eval.template apply_gradients<0,false,false>
                   (fe_eval.gradients_quad[c][0], temp1);
               }
-            fe_eval.template apply_values<1,false,false>
-            (temp1, temp2);
+            if (integrate_val || integrate_grad)
+              fe_eval.template apply_values<1,false,false>
+                (temp1, temp2);
             if (integrate_grad == true)
               {
                 // grad y: can sum to temporary x value in temp2
@@ -5110,8 +5111,9 @@ namespace internal
                 fe_eval.template apply_gradients<1,false,true>
                 (temp1, temp2);
               }
-            fe_eval.template apply_values<2,false,false>
-            (temp2, fe_eval.values_dofs[c]);
+            if (integrate_val || integrate_grad)
+              fe_eval.template apply_values<2,false,false>
+                (temp2, fe_eval.values_dofs[c]);
             if (integrate_grad == true)
               {
                 // grad z: can sum to temporary x and y value in output
@@ -5141,8 +5143,9 @@ namespace internal
                   fe_eval.template apply_gradients<0,false,false>
                   (fe_eval.gradients_quad[c][0], temp1);
               }
-            fe_eval.template apply_values<1,false,false>
-            (temp1, fe_eval.values_dofs[c]);
+            if (integrate_val || integrate_grad)
+              fe_eval.template apply_values<1,false,false>
+                (temp1, fe_eval.values_dofs[c]);
             if (integrate_grad == true)
               {
                 // grad y
index 692cf4de579286a6c819c600e0630b06accb32fd..ee1f8c1961ce6a980d9dfd3a4a12c6224967201d 100644 (file)
@@ -57,6 +57,11 @@ namespace internal
        */
       static const unsigned int n_cell_types = 1U<<n_cell_type_bits;
 
+      /**
+       * An abbreviation for the length of vector lines of the current data type.
+       */
+      static const unsigned int n_vector_elements = VectorizedArray<Number>::n_array_elements;
+
       /**
        * Empty constructor.
        */
@@ -279,7 +284,6 @@ namespace internal
 
       /**
        * Contains all the stuff that depends on the quadrature formula
-
        */
       std::vector<MappingInfoDependent> mapping_data_gen;
 
@@ -320,8 +324,8 @@ namespace internal
                              const std::pair<unsigned int,unsigned int> *cells,
                              const unsigned int  cell,
                              const unsigned int  my_q,
-                             CellType (&cell_t_prev)[VectorizedArray<Number>::n_array_elements],
-                             CellType (&cell_t)[VectorizedArray<Number>::n_array_elements],
+                             CellType (&cell_t_prev)[n_vector_elements],
+                             CellType (&cell_t)[n_vector_elements],
                              FEValues<dim,dim> &fe_values,
                              CellData          &cell_data) const;
     };
index f19e7be6c54a8247217059f1b34ff4f79fc58248..5d093bc971a398ea8a6acbcece26c34effeede5b 100644 (file)
@@ -606,13 +606,11 @@ end_set:
                                                const std::pair<unsigned int,unsigned int> *cells,
                                                const unsigned int  cell,
                                                const unsigned int  my_q,
-                                               CellType (&cell_t_prev)[VectorizedArray<Number>::n_array_elements],
-                                               CellType (&cell_t)[VectorizedArray<Number>::n_array_elements],
+                                               CellType (&cell_t_prev)[n_vector_elements],
+                                               CellType (&cell_t)[n_vector_elements],
                                                FEValues<dim,dim> &fe_val,
                                                CellData          &data) const
     {
-      const unsigned int vectorization_length =
-        VectorizedArray<Number>::n_array_elements;
       const unsigned int n_q_points = fe_val.n_quadrature_points;
       const UpdateFlags update_flags = fe_val.get_update_flags();
 
@@ -620,7 +618,7 @@ end_set:
       // not have that field here)
       const double zero_tolerance_double = data.jac_size *
                                            std::numeric_limits<double>::epsilon() * 1024.;
-      for (unsigned int j=0; j<vectorization_length; ++j)
+      for (unsigned int j=0; j<n_vector_elements; ++j)
         {
           typename dealii::Triangulation<dim>::cell_iterator
           cell_it (&tria, cells[j].first, cells[j].second);
@@ -653,7 +651,7 @@ end_set:
               if (j==0)
                 {
                   Assert (cell>0, ExcInternalError());
-                  cell_t[j] = cell_t_prev[vectorization_length-1];
+                  cell_t[j] = cell_t_prev[n_vector_elements-1];
                 }
               else
                 cell_t[j] = cell_t[j-1];
@@ -791,11 +789,11 @@ end_set:
                         data.general_jac_grad[q][d][e][f][j] = jacobian_grad[d][e][f];
                 }
             }
-        } // end loop over all entries in vectorization (vectorization_length
+        } // end loop over all entries in vectorization (n_vector_elements
       // cells)
 
       // set information for next cell
-      for (unsigned int j=0; j<vectorization_length; ++j)
+      for (unsigned int j=0; j<n_vector_elements; ++j)
         cell_t_prev[j] = cell_t[j];
     }
 
index 6d869a372074514841bc7a96fe536a4e87a74037..5edbbb6a39762c6ec166ab5329a622227dfa9e1a 100644 (file)
@@ -121,7 +121,8 @@ public:
    */
   MGTransferPrebuilt ();
   /**
-   * Constructor with constraint matrices as well as mg_constrained_dofs.
+   * Constructor with constraints. Equivalent to the default
+   * constructor followed by initialize_constraints().
    */
   MGTransferPrebuilt (const ConstraintMatrix &constraints,
                       const MGConstrainedDoFs &mg_constrained_dofs);
@@ -129,6 +130,18 @@ public:
    * Destructor.
    */
   virtual ~MGTransferPrebuilt ();
+
+  /**
+   * Initialize the constraints to be used in build_matrices().
+   */
+  void initialize_constraints (const ConstraintMatrix &constraints,
+                              const MGConstrainedDoFs &mg_constrained_dofs);
+
+  /**
+   * Reset the object to the state it had right after the default constructor.
+   */
+  void clear ();
+    
   /**
    * Actually build the prolongation
    * matrices for each level.
index 961fed7c20382de1a8032cba859ef8c1a4603904..64bb199e4cbfb94b5391703bda2b9de2808e116b 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 1999 - 2013 by the deal.II authors
+// Copyright (C) 1999 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -137,6 +137,13 @@ namespace internal
  * this pair of functions and they return a non-active cell, then an exception
  * will be thrown.
  *
+ * @precondition This class only makes sense if the first template
+ * argument, <code>dim</code> equals the dimension of the
+ * DoFHandler type given as the second template argument, i.e., if
+ * <code>dim == DH::dimension</code>. This redundancy is a historical
+ * relic from the time where the library had only a single DoFHandler
+ * class and this class consequently only a single template argument.
+ *
  * @ingroup output
  * @author Wolfgang Bangerth, 1999
  */
index ada6d1aa91b79d207b8fdf214786944463755cf6..1a6f9427e2c9fb8fa33c749efbd451131080197e 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -108,6 +108,13 @@ namespace internal
  * applications certainly exist, for which the author is not
  * imaginative enough.
  *
+ * @precondition This class only makes sense if the first template
+ * argument, <code>dim</code> equals the dimension of the
+ * DoFHandler type given as the second template argument, i.e., if
+ * <code>dim == DH::dimension</code>. This redundancy is a historical
+ * relic from the time where the library had only a single DoFHandler
+ * class and this class consequently only a single template argument.
+ *
  * @todo Reimplement this whole class using actual FEFaceValues and MeshWorker.
  *
  * @ingroup output
@@ -118,13 +125,25 @@ class DataOutFaces : public DataOut_DoFData<DH,DH::dimension-1,
   DH::dimension>
 {
 public:
+  /**
+   * An abbreviation for the dimension of the DoFHandler object we work
+   * with. Faces are then <code>dimension-1</code> dimensional objects.
+   */
+  static const unsigned int dimension = DH::dimension;
+
+  /**
+   * An abbreviation for the spatial dimension within which the triangulation
+   * and DoFHandler are embedded in.
+   */
+  static const unsigned int space_dimension = DH::space_dimension;
+  
   /**
    * Typedef to the iterator type
    * of the dof handler class under
    * consideration.
    */
-  typedef typename DataOut_DoFData<DH,DH::dimension-1,
-          DH::dimension>::cell_iterator cell_iterator;
+  typedef typename DataOut_DoFData<DH,dimension-1,
+          dimension>::cell_iterator cell_iterator;
 
   /**
    * Constructor determining
@@ -193,7 +212,7 @@ public:
    * replaced by a hp::MappingCollection in
    * case of a hp::DoFHandler.
    */
-  virtual void build_patches (const Mapping<DH::dimension> &mapping,
+  virtual void build_patches (const Mapping<dimension> &mapping,
                               const unsigned int n_subdivisions = 0);
 
   /**
@@ -291,8 +310,8 @@ private:
    * context.
    */
   void build_one_patch (const FaceDescriptor *cell_and_face,
-                        internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension> &data,
-                        DataOutBase::Patch<DH::dimension-1,DH::space_dimension> &patch);
+                        internal::DataOutFaces::ParallelData<dimension, dimension> &data,
+                        DataOutBase::Patch<dimension-1,space_dimension> &patch);
 };
 
 
index f8e8d8aa9110483e19515c2152974c7d6a4edc8c..1f6ea01a9466365bb77af6bfda6d7cc8cdced5e5 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -114,6 +114,13 @@ namespace internal
  * It is in the responsibility of the user to make sure that the
  * radial variable attains only non-negative values.
  *
+ * @precondition This class only makes sense if the first template
+ * argument, <code>dim</code> equals the dimension of the
+ * DoFHandler type given as the second template argument, i.e., if
+ * <code>dim == DH::dimension</code>. This redundancy is a historical
+ * relic from the time where the library had only a single DoFHandler
+ * class and this class consequently only a single template argument.
+ *
  * @ingroup output
  * @author Wolfgang Bangerth, 2000
  */
@@ -121,12 +128,24 @@ template <int dim, class DH=DoFHandler<dim> >
 class DataOutRotation : public DataOut_DoFData<DH,DH::dimension+1>
 {
 public:
+  /**
+   * An abbreviation for the dimension of the DoFHandler object we work
+   * with. Faces are then <code>dimension-1</code> dimensional objects.
+   */
+  static const unsigned int dimension = DH::dimension;
+
+  /**
+   * An abbreviation for the spatial dimension within which the triangulation
+   * and DoFHandler are embedded in.
+   */
+  static const unsigned int space_dimension = DH::space_dimension;
+
   /**
    * Typedef to the iterator type
    * of the dof handler class under
    * consideration.
    */
-  typedef typename DataOut_DoFData<DH,DH::dimension+1>::cell_iterator cell_iterator;
+  typedef typename DataOut_DoFData<DH,dimension+1>::cell_iterator cell_iterator;
 
   /**
    * This is the central function
@@ -212,8 +231,8 @@ private:
    */
   void
   build_one_patch (const cell_iterator *cell,
-                   internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension> &data,
-                   std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> > &patches);
+                   internal::DataOutRotation::ParallelData<dimension, space_dimension> &data,
+                   std::vector<DataOutBase::Patch<dimension+1,space_dimension+1> > &patches);
 };
 
 
index 002ec011373f2737a599a0307b9e0b6594ae8dc1..660365f7b1da625b88d986668ac8fb8300c4cc50 100644 (file)
@@ -39,7 +39,7 @@ namespace hp
 
 
 /**
- * This class computes a cell-wise approximation of the norm of a
+ * This namespace provides functions that compute a cell-wise approximation of the norm of a
  * derivative of a finite element field by taking difference quotients
  * between neighboring cells. This is a rather simple but efficient
  * form to get an error indicator, since it can be computed with
@@ -85,7 +85,7 @@ namespace hp
  * @code
  * --------------------------------------------------------
  * An error occurred in line <749> of file <source/numerics/derivative_approximation.cc> in function
- *     static void DerivativeApproximation::approximate(const Mapping<dim,spacedim>&, const DH<dim,spacedim>&, const InputVector&, unsigned int, const
+ *     void DerivativeApproximation::approximate(const Mapping<dim,spacedim>&, const DH<dim,spacedim>&, const InputVector&, unsigned int, const
  *  std::pair<unsigned int, unsigned int>&, Vector<float>&) [with DerivativeDescription = DerivativeApproximation::Gradient<3>, int
  * dim = 3, DH = DoFHandler, InputVector = Vector<double>]
  * The violated condition was:
@@ -158,7 +158,7 @@ namespace hp
  * The formulae for the computation of approximations to the gradient
  * and to the tensor of second derivatives shown above are very much
  * alike. The basic difference is that in one case the finite
- * difference quotiont is a scalar, while in the other case it is a
+ * difference quotient is a scalar, while in the other case it is a
  * vector. For higher derivatives, this would be a tensor of even
  * higher rank. We then have to form the outer product of this
  * difference quotient with the distance vector $y_{KK'}$, symmetrize
@@ -185,9 +185,8 @@ namespace hp
  * @ingroup numerics
  * @author Wolfgang Bangerth, 2000
  */
-class DerivativeApproximation
+namespace DerivativeApproximation
 {
-public:
   /**
    * This function is used to obtain an approximation of the gradient. Pass it
    * the DoF handler object that describes the finite element field, a nodal
@@ -204,7 +203,7 @@ public:
    * locally relevant unknowns.
    */
   template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-  static void
+  void
   approximate_gradient (const Mapping<dim,spacedim>    &mapping,
                         const DH<dim,spacedim>         &dof,
                         const InputVector     &solution,
@@ -216,7 +215,7 @@ public:
    * <tt>mapping=MappingQ1@<dim@>()</tt>.
    */
   template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-  static void
+  void
   approximate_gradient (const DH<dim,spacedim>         &dof,
                         const InputVector     &solution,
                         Vector<float>         &derivative_norm,
@@ -240,7 +239,7 @@ public:
    * locally relevant unknowns.
    */
   template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-  static void
+  void
   approximate_second_derivative (const Mapping<dim,spacedim>    &mapping,
                                  const DH<dim,spacedim>         &dof,
                                  const InputVector     &solution,
@@ -252,7 +251,7 @@ public:
    * <tt>mapping=MappingQ1@<dim@>()</tt>.
    */
   template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-  static void
+  void
   approximate_second_derivative (const DH<dim,spacedim>         &dof,
                                  const InputVector     &solution,
                                  Vector<float>         &derivative_norm,
@@ -271,9 +270,8 @@ public:
    * In a parallel computation the @p solution vector needs to contain the
    * locally relevant unknowns.
    */
-
   template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
-  static void
+  void
   approximate_derivative_tensor (const Mapping<dim,spacedim>                           &mapping,
                                  const DH<dim,spacedim>                                &dof,
                                  const InputVector                            &solution,
@@ -284,9 +282,8 @@ public:
   /**
    * Same as above, with <tt>mapping=MappingQ1@<dim@>()</tt>.
    */
-
   template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
-  static void
+  void
   approximate_derivative_tensor (const DH<dim,spacedim>                                &dof,
                                  const InputVector                            &solution,
                                  const typename DH<dim,spacedim>::active_cell_iterator &cell,
@@ -297,8 +294,8 @@ public:
    * Return the norm of the derivative.
    */
   template <int dim, int order>
-  static double
-  derivative_norm(const Tensor<order,dim> &derivative);
+  double
+  derivative_norm (const Tensor<order,dim> &derivative);
 
   /**
    * Exception
@@ -311,299 +308,8 @@ public:
    * Exception
    */
   DeclException0 (ExcInsufficientDirections);
+}
 
-private:
-
-  /**
-   * The following class is used to describe the data needed to compute the
-   * finite difference approximation to the gradient on a cell. See the
-   * general documentation of this class for more information on
-   * implementational details.
-   *
-   * @author Wolfgang Bangerth, 2000
-   */
-  template <int dim>
-  class Gradient
-  {
-  public:
-    /**
-     * Declare which data fields have to be updated for the function @p
-     * get_projected_derivative to work.
-     */
-    static const UpdateFlags update_flags;
-
-    /**
-     * Declare the data type which holds the derivative described by this
-     * class.
-     */
-    typedef Tensor<1,dim> Derivative;
-
-    /**
-     * Likewise declare the data type that holds the derivative projected to a
-     * certain directions.
-     */
-    typedef double        ProjectedDerivative;
-
-    /**
-     * Given an FEValues object initialized to a cell, and a solution vector,
-     * extract the desired derivative at the first quadrature point (which is
-     * the only one, as we only evaluate the finite element field at the
-     * center of each cell).
-     */
-    template <class InputVector, int spacedim>
-    static ProjectedDerivative
-    get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
-                              const InputVector    &solution,
-                              const unsigned int    component);
-
-    /**
-     * Return the norm of the derivative object. Here, for the gradient, we
-     * choose the Euclidian norm of the gradient vector.
-     */
-    static double derivative_norm (const Derivative &d);
-
-    /**
-     * If for the present derivative order, symmetrization of the derivative
-     * tensor is necessary, then do so on the argument.
-     *
-     * For the first derivatives, no such thing is necessary, so this function
-     * is a no-op.
-     */
-    static void symmetrize (Derivative &derivative_tensor);
-  };
-
-
-
-  /**
-   * The following class is used to describe the data needed to compute the
-   * finite difference approximation to the second derivatives on a cell. See
-   * the general documentation of this class for more information on
-   * implementational details.
-   *
-   * @author Wolfgang Bangerth, 2000
-   */
-  template <int dim>
-  class SecondDerivative
-  {
-  public:
-    /**
-     * Declare which data fields have to be updated for the function @p
-     * get_projected_derivative to work.
-     */
-    static const UpdateFlags update_flags;
-
-    /**
-     * Declare the data type which holds the derivative described by this
-     * class.
-     */
-    typedef Tensor<2,dim> Derivative;
-
-    /**
-     * Likewise declare the data type that holds the derivative projected to a
-     * certain directions.
-     */
-    typedef Tensor<1,dim> ProjectedDerivative;
-
-    /**
-     * Given an FEValues object initialized to a cell, and a solution vector,
-     * extract the desired derivative at the first quadrature point (which is
-     * the only one, as we only evaluate the finite element field at the
-     * center of each cell).
-     */
-    template <class InputVector, int spacedim>
-    static ProjectedDerivative
-    get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
-                              const InputVector    &solution,
-                              const unsigned int    component);
-
-    /**
-     * Return the norm of the derivative object. Here, for the (symmetric)
-     * tensor of second derivatives, we choose the absolute value of the
-     * largest eigenvalue, which is the matrix norm associated to the $l_2$
-     * norm of vectors. It is also the largest value of the curvature of the
-     * solution.
-     */
-    static double derivative_norm (const Derivative &d);
-
-    /**
-     * If for the present derivative order, symmetrization of the derivative
-     * tensor is necessary, then do so on the argument.
-     *
-     * For the second derivatives, each entry of the tensor is set to the mean
-     * of its value and the value of the transpose element.
-     *
-     * Note that this function actually modifies its argument.
-     */
-    static void symmetrize (Derivative &derivative_tensor);
-  };
-
-  template <int dim>
-  class ThirdDerivative
-  {
-  public:
-    /**
-     * Declare which data fields have to be updated for the function @p
-     * get_projected_derivative to work.
-     */
-    static const UpdateFlags update_flags;
-
-    /**
-     * Declare the data type which
-     * holds the derivative described
-     * by this class.
-     */
-    typedef Tensor<3,dim> Derivative;
-
-    /**
-     * Likewise declare the data type that holds the derivative projected to a
-     * certain directions.
-     */
-    typedef Tensor<2,dim> ProjectedDerivative;
-
-    /**
-     * Given an FEValues object initialized to a cell, and a solution vector,
-     * extract the desired derivative at the first quadrature point (which is
-     * the only one, as we only evaluate the finite element field at the
-     * center of each cell).
-     */
-    template <class InputVector, int spacedim>
-    static ProjectedDerivative
-    get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
-                              const InputVector    &solution,
-                              const unsigned int    component);
-
-    /**
-     * Return the norm of the derivative object. Here, for the (symmetric)
-     * tensor of second derivatives, we choose the absolute value of the
-     * largest eigenvalue, which is the matrix norm associated to the $l_2$
-     * norm of vectors. It is also the largest value of the curvature of the
-     * solution.
-     */
-    static double derivative_norm (const Derivative &d);
-
-    /**
-     * If for the present derivative order, symmetrization of the derivative
-     * tensor is necessary, then do so on the argument.
-     *
-     * For the second derivatives, each entry of the tensor is set to the mean
-     * of its value and the value of the transpose element.
-     *
-     * Note that this function actually modifies its argument.
-     */
-    static void symmetrize (Derivative &derivative_tensor);
-  };
-
-  template <int order, int dim>
-  class DerivativeSelector
-  {
-  public:
-    /**
-     * typedef to select the DerivativeDescription corresponding to the
-     * <tt>order</tt>th derivative. In this general template we set an unvalid
-     * typedef to void, the real typedefs have to be specialized.
-     */
-    typedef void DerivDescr;
-
-  };
-
-  template <int dim>
-  class DerivativeSelector<1,dim>
-  {
-  public:
-
-    typedef Gradient<dim> DerivDescr;
-  };
-
-  template <int dim>
-  class DerivativeSelector<2,dim>
-  {
-  public:
-
-    typedef SecondDerivative<dim> DerivDescr;
-  };
-
-  template <int dim>
-  class DerivativeSelector<3,dim>
-  {
-  public:
-
-    typedef ThirdDerivative<dim> DerivDescr;
-  };
-
-
-
-
-private:
-
-  /**
-   * Convenience typedef denoting the range of indices on which a certain
-   * thread shall operate.
-   */
-  typedef std::pair<unsigned int,unsigned int> IndexInterval;
-
-  /**
-   * Kind of the main function of this class. It is called by the public entry
-   * points to this class with the correct template first argument and then
-   * simply calls the @p approximate function, after setting up several
-   * threads and doing some administration that is independent of the actual
-   * derivative to be computed.
-   *
-   * The @p component argument denotes which component of the solution vector
-   * we are to work on.
-   */
-  template <class DerivativeDescription, int dim,
-            template <int, int> class DH, class InputVector, int spacedim>
-  static void
-  approximate_derivative (const Mapping<dim,spacedim>    &mapping,
-                          const DH<dim,spacedim>         &dof,
-                          const InputVector     &solution,
-                          const unsigned int     component,
-                          Vector<float>         &derivative_norm);
-
-  /**
-   * Compute the derivative approximation on a given cell.  Fill the @p
-   * derivative_norm vector with the norm of the computed derivative tensors
-   * on the cell.
-   */
-  template <class DerivativeDescription, int dim,
-            template <int, int> class DH, class InputVector, int spacedim>
-  static void
-  approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,
-               Vector<float>::iterator> > const &cell,
-               const Mapping<dim,spacedim>    &mapping,
-               const DH<dim,spacedim>         &dof,
-               const InputVector     &solution,
-               const unsigned int     component);
-
-  /**
-   * Compute the derivative approximation on one cell. This computes the full
-   * derivative tensor.
-   */
-  template <class DerivativeDescription, int dim,
-            template <int, int> class DH, class InputVector, int spacedim>
-  static void
-  approximate_cell (const Mapping<dim,spacedim>                            &mapping,
-                    const DH<dim,spacedim>                                 &dof,
-                    const InputVector                             &solution,
-                    const unsigned int                             component,
-                    const typename DH<dim,spacedim>::active_cell_iterator  &cell,
-                    typename DerivativeDescription::Derivative    &derivative);
-};
-
-
-/* -------------- declaration of explicit specializations ------------- */
-
-template <>
-double
-DerivativeApproximation::SecondDerivative<1>::derivative_norm (const Derivative &d);
-
-template <>
-double
-DerivativeApproximation::SecondDerivative<2>::derivative_norm (const Derivative &d);
-
-template <>
-double
-DerivativeApproximation::SecondDerivative<3>::derivative_norm (const Derivative &d);
 
 
 DEAL_II_NAMESPACE_CLOSE
index 3ba2a9f1ffd8c9992511e815858bf9218debc908..abb0ee58f64aeb74ea89a404ada954a342e4e61e 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -1707,8 +1707,13 @@ namespace VectorTools
 
 
 
+    // template for the case dim!=1. Since the function has a template argument
+    // dim_, it is clearly less specialized than the 1d function above and
+    // whenever possible (i.e., if dim==1), the function template above
+    // will be used
     template <class DH,
-              template <int,int> class M_or_MC>
+              template <int,int> class M_or_MC,
+             int dim_>
     static inline
     void
     do_interpolate_boundary_values (const M_or_MC<DH::dimension, DH::space_dimension> &mapping,
@@ -1716,7 +1721,7 @@ namespace VectorTools
                                     const typename FunctionMap<DH::space_dimension>::type &function_map,
                                     std::map<types::global_dof_index,double> &boundary_values,
                                     const ComponentMask       &component_mask,
-                                    const dealii::internal::int2type<DH::dimension>)
+                                    const dealii::internal::int2type<dim_>)
     {
       const unsigned int dim = DH::dimension;
       const unsigned int spacedim=DH::space_dimension;
index 0525ca1b93fe12d9fd96380daa96de61e2ad12b5..e16c106d464ce556cae1e2c413635d5e64e19626 100644 (file)
@@ -21,12 +21,10 @@ MESSAGE(STATUS "Setting up library")
 #
 
 INCLUDE_DIRECTORIES(
-  BEFORE # Ensure deal.II include directories come first
-  #
-  # Reverse order due to BEFORE:
-  #
-  ${CMAKE_SOURCE_DIR}/include/
   ${CMAKE_BINARY_DIR}/include/
+  ${CMAKE_SOURCE_DIR}/include/
+  ${DEAL_II_BUNDLED_INCLUDE_DIRS}
+  ${DEAL_II_INCLUDE_DIRS}
   )
 
 #
@@ -86,8 +84,8 @@ FOREACH(build ${DEAL_II_BUILD_TYPES})
     )
 
   TARGET_LINK_LIBRARIES(${DEAL_II_BASE_NAME}${DEAL_II_${build}_SUFFIX}
-    ${DEAL_II_EXTERNAL_LIBRARIES_${build}}
-    ${DEAL_II_EXTERNAL_LIBRARIES}
+    ${DEAL_II_LIBRARIES_${build}}
+    ${DEAL_II_LIBRARIES}
     )
 
   FILE(MAKE_DIRECTORY
index 23861d2c09f33ae1aae3710fbe7b738a97941652..58a8fbd5dc04862794209bcd68beac997401f23f 100644 (file)
@@ -273,6 +273,155 @@ namespace
 #endif
 }
 
+
+// some declarations of functions and locally used classes
+namespace DataOutBase
+{
+  namespace
+  {
+    /**
+     * Class holding the data of one cell of a patch in two space
+     * dimensions for output. It is the projection of a cell in
+     * three-dimensional space (two coordinates, one height value) to
+     * the direction of sight.
+     */
+    class SvgCell
+    {
+    public:
+
+      // Center of the cell (three-dimensional)
+      Point<3> center;
+
+      /**
+       * Vector of vertices of this cell (three-dimensional)
+       */
+      Point<3> vertices[4];
+
+      /**
+       * Depth into the picture, which is defined as the distance from
+       * an observer at an the origin in direction of the line of sight.
+       */
+      float depth;
+
+      /**
+       * Vector of vertices of this cell (projected, two-dimensional).
+       */
+      Point<2> projected_vertices[4];
+
+      // Center of the cell (projected, two-dimensional)
+      Point<2> projected_center;
+
+      /**
+       * Comparison operator for sorting.
+       */
+      bool operator < (const SvgCell &) const;
+    };
+
+    bool SvgCell::operator < (const SvgCell &e) const
+    {
+      // note the "wrong" order in
+      // which we sort the elements
+      return depth > e.depth;
+    }
+
+
+
+    /**
+     * Class holding the data of one cell of a patch in two space
+     * dimensions for output. It is the projection of a cell in
+     * three-dimensional space (two coordinates, one height value) to
+     * the direction of sight.
+     */
+    class EpsCell2d
+    {
+    public:
+
+      /**
+       * Vector of vertices of this cell.
+       */
+      Point<2> vertices[4];
+
+      /**
+       * Data value from which the actual colors will be computed by the
+       * colorization function stated in the <tt>EpsFlags</tt> class.
+       */
+      float color_value;
+
+      /**
+       * Depth into the picture, which is defined as the distance from
+       * an observer at an the origin in direction of the line of sight.
+       */
+      float depth;
+
+      /**
+       * Comparison operator for sorting.
+       */
+      bool operator < (const EpsCell2d &) const;
+    };
+
+
+    /**
+     * This is a helper function for the write_gmv() function. There,
+     * the data in the patches needs to be copied around as output is
+     * one variable globally at a time, rather than all data on each
+     * vertex at a time. This copying around can be done detached from
+     * the main thread, and is thus moved into this separate function.
+     *
+     * Note that because of the similarity of the formats, this function
+     * is also used by the Vtk and Tecplot output functions.
+     */
+    template <int dim, int spacedim>
+    void
+    write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
+                                    Table<2,double>                         &data_vectors)
+    {
+      // unlike in the main function, we
+      // don't have here the data_names
+      // field, so we initialize it with
+      // the number of data sets in the
+      // first patch. the equivalence of
+      // these two definitions is checked
+      // in the main function.
+
+      // we have to take care, however, whether the
+      // points are appended to the end of the
+      // patch->data table
+      const unsigned int n_data_sets
+        =patches[0].points_are_available ? (patches[0].data.n_rows() - spacedim) : patches[0].data.n_rows();
+
+      Assert (data_vectors.size()[0] == n_data_sets,
+              ExcInternalError());
+
+      // loop over all patches
+      unsigned int next_value = 0;
+      for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+           patch != patches.end(); ++patch)
+        {
+          const unsigned int n_subdivisions = patch->n_subdivisions;
+
+          Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+                  (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+                  ExcDimensionMismatch (patch->points_are_available
+                                        ?
+                                        (n_data_sets + spacedim)
+                                        :
+                                        n_data_sets,
+                                        patch->data.n_rows()));
+          Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
+                  ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+          for (unsigned int i=0; i<patch->data.n_cols(); ++i, ++next_value)
+            for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+              data_vectors[data_set][next_value] = patch->data(data_set,i);
+        }
+
+      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+        Assert (data_vectors[data_set].size() == next_value,
+                ExcInternalError());
+    }
+  }
+}
+
 //----------------------------------------------------------------------//
 // DataOutFilter class member functions
 //----------------------------------------------------------------------//
@@ -391,34 +540,33 @@ void DataOutBase::DataOutFilter::write_data_set(const std::string &name, const u
 
 namespace
 {
-
-  static const char *gmv_cell_type[4] =
+  const char *gmv_cell_type[4] =
   {
     "", "line 2", "quad 4", "hex 8"
   };
 
-  static const char *ucd_cell_type[4] =
+  const char *ucd_cell_type[4] =
   {
     "", "line", "quad", "hex"
   };
 
-  static const char *tecplot_cell_type[4] =
+  const char *tecplot_cell_type[4] =
   {
     "", "lineseg", "quadrilateral", "brick"
   };
 
 #ifdef DEAL_II_HAVE_TECPLOT
-  static unsigned int tecplot_binary_cell_type[4] =
+  const unsigned int tecplot_binary_cell_type[4] =
   {
     0, 0, 1, 3
   };
 #endif
 
-  // NOTE: (UK) The dimension of the array is choosen to 5 to allow the choice
+  // NOTE: The dimension of the array is choosen to 5 to allow the choice
   // DataOutBase<deal_II_dimension,deal_II_dimension+1> in general
   // Wolfgang supposed that we don't need it in general, but however this
   // choice avoids a -Warray-bounds check warning
-  static unsigned int vtk_cell_type[5] =
+  const unsigned int vtk_cell_type[5] =
   {
     0, 3, 9, 12, static_cast<unsigned int>(-1)
   };
@@ -1622,339 +1770,362 @@ namespace
 
 
 //----------------------------------------------------------------------//
-template <int dim, int spacedim>
-const unsigned int DataOutBase::Patch<dim,spacedim>::space_dim;
 
-const unsigned int DataOutBase::Deal_II_IntermediateFlags::format_version;
+namespace DataOutBase
+{
+  template <int dim, int spacedim>
+  const unsigned int Patch<dim,spacedim>::space_dim;
+
+  const unsigned int Deal_II_IntermediateFlags::format_version;
 
 
 
-template <int dim, int spacedim>
-const unsigned int DataOutBase::Patch<dim,spacedim>::no_neighbor;
+  template <int dim, int spacedim>
+  const unsigned int Patch<dim,spacedim>::no_neighbor;
 
 
-template <int dim, int spacedim>
-DataOutBase::Patch<dim,spacedim>::Patch ()
-  :
-  patch_index(no_neighbor),
-  n_subdivisions (1),
-  points_are_available(false)
-  // all the other data has a
-  // constructor of its own, except
-  // for the "neighbors" field, which
-  // we set to invalid values.
-{
-  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
-    neighbors[i] = no_neighbor;
+  template <int dim, int spacedim>
+  Patch<dim,spacedim>::Patch ()
+    :
+    patch_index(no_neighbor),
+    n_subdivisions (1),
+    points_are_available(false)
+    // all the other data has a
+    // constructor of its own, except
+    // for the "neighbors" field, which
+    // we set to invalid values.
+  {
+    for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+      neighbors[i] = no_neighbor;
 
-  Assert (dim<=spacedim, ExcIndexRange(dim,0,spacedim));
-  Assert (spacedim<=3, ExcNotImplemented());
-}
+    Assert (dim<=spacedim, ExcIndexRange(dim,0,spacedim));
+    Assert (spacedim<=3, ExcNotImplemented());
+  }
 
 
 
-template <int dim, int spacedim>
-bool
-DataOutBase::Patch<dim,spacedim>::operator == (const Patch &patch) const
-{
+  template <int dim, int spacedim>
+  bool
+  Patch<dim,spacedim>::operator == (const Patch &patch) const
+  {
 //TODO: make tolerance relative
-  const double epsilon=3e-16;
-  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
-    if (vertices[i].distance(patch.vertices[i]) > epsilon)
-      return false;
+    const double epsilon=3e-16;
+    for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+      if (vertices[i].distance(patch.vertices[i]) > epsilon)
+        return false;
+
+    for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+      if (neighbors[i] != patch.neighbors[i])
+        return false;
 
-  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
-    if (neighbors[i] != patch.neighbors[i])
+    if (patch_index != patch.patch_index)
       return false;
 
-  if (patch_index != patch.patch_index)
-    return false;
+    if (n_subdivisions != patch.n_subdivisions)
+      return false;
 
-  if (n_subdivisions != patch.n_subdivisions)
-    return false;
+    if (points_are_available != patch.points_are_available)
+      return false;
 
-  if (points_are_available != patch.points_are_available)
-    return false;
+    if (data.n_rows() != patch.data.n_rows())
+      return false;
 
-  if (data.n_rows() != patch.data.n_rows())
-    return false;
+    if (data.n_cols() != patch.data.n_cols())
+      return false;
 
-  if (data.n_cols() != patch.data.n_cols())
-    return false;
+    for (unsigned int i=0; i<data.n_rows(); ++i)
+      for (unsigned int j=0; j<data.n_cols(); ++j)
+        if (data[i][j] != patch.data[i][j])
+          return false;
 
-  for (unsigned int i=0; i<data.n_rows(); ++i)
-    for (unsigned int j=0; j<data.n_cols(); ++j)
-      if (data[i][j] != patch.data[i][j])
-        return false;
+    return true;
+  }
 
-  return true;
-}
 
 
+  template <int dim, int spacedim>
+  std::size_t
+  Patch<dim,spacedim>::memory_consumption () const
+  {
+    return (sizeof(vertices) / sizeof(vertices[0]) *
+            MemoryConsumption::memory_consumption(vertices[0])
+            +
+            MemoryConsumption::memory_consumption(n_subdivisions)
+            +
+            MemoryConsumption::memory_consumption(data)
+            +
+            MemoryConsumption::memory_consumption(points_are_available));
+  }
 
-template <int dim, int spacedim>
-std::size_t
-DataOutBase::Patch<dim,spacedim>::memory_consumption () const
-{
-  return (sizeof(vertices) / sizeof(vertices[0]) *
-          MemoryConsumption::memory_consumption(vertices[0])
-          +
-          MemoryConsumption::memory_consumption(n_subdivisions)
-          +
-          MemoryConsumption::memory_consumption(data)
-          +
-          MemoryConsumption::memory_consumption(points_are_available));
-}
 
 
+  UcdFlags::UcdFlags (const bool write_preamble)
+    :
+    write_preamble (write_preamble)
+  {}
 
-DataOutBase::UcdFlags::UcdFlags (const bool write_preamble)
-  :
-  write_preamble (write_preamble)
-{}
 
 
+  PovrayFlags::PovrayFlags (const bool smooth,
+                            const bool bicubic_patch,
+                            const bool external_data)
+    :
+    smooth (smooth),
+    bicubic_patch(bicubic_patch),
+    external_data(external_data)
+  {}
 
-DataOutBase::PovrayFlags::PovrayFlags (const bool smooth,
-                                       const bool bicubic_patch,
-                                       const bool external_data)
-  :
-  smooth (smooth),
-  bicubic_patch(bicubic_patch),
-  external_data(external_data)
-{}
 
+  DataOutFilterFlags::DataOutFilterFlags (const bool filter_duplicate_vertices,
+                                          const bool xdmf_hdf5_output) :
+    filter_duplicate_vertices(filter_duplicate_vertices),
+    xdmf_hdf5_output(xdmf_hdf5_output)
+  {}
 
-DataOutBase::DataOutFilterFlags::DataOutFilterFlags (const bool filter_duplicate_vertices,
-                                                     const bool xdmf_hdf5_output) :
-  filter_duplicate_vertices(filter_duplicate_vertices),
-  xdmf_hdf5_output(xdmf_hdf5_output) {}
 
-void DataOutBase::DataOutFilterFlags::declare_parameters (ParameterHandler &prm)
-{
-  prm.declare_entry ("Filter duplicate vertices", "false",
-                     Patterns::Bool(),
-                     "Whether to remove duplicate vertex values.");
-  prm.declare_entry ("XDMF HDF5 output", "false",
-                     Patterns::Bool(),
-                     "Whether the data will be used in an XDMF/HDF5 combination.");
-}
+  void DataOutFilterFlags::declare_parameters (ParameterHandler &prm)
+  {
+    prm.declare_entry ("Filter duplicate vertices", "false",
+                       Patterns::Bool(),
+                       "Whether to remove duplicate vertex values.");
+    prm.declare_entry ("XDMF HDF5 output", "false",
+                       Patterns::Bool(),
+                       "Whether the data will be used in an XDMF/HDF5 combination.");
+  }
 
 
 
-void DataOutBase::DataOutFilterFlags::parse_parameters (const ParameterHandler &prm)
-{
-  filter_duplicate_vertices = prm.get_bool ("Filter duplicate vertices");
-  xdmf_hdf5_output = prm.get_bool ("XDMF HDF5 output");
-}
+  void DataOutFilterFlags::parse_parameters (const ParameterHandler &prm)
+  {
+    filter_duplicate_vertices = prm.get_bool ("Filter duplicate vertices");
+    xdmf_hdf5_output = prm.get_bool ("XDMF HDF5 output");
+  }
 
 
 
-std::size_t
-DataOutBase::DataOutFilterFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  std::size_t
+  DataOutFilterFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
 
-DataOutBase::DXFlags::DXFlags (const bool write_neighbors,
-                               const bool int_binary,
-                               const bool coordinates_binary,
-                               const bool data_binary)
-  :
-  write_neighbors(write_neighbors),
-  int_binary(int_binary),
-  coordinates_binary(coordinates_binary),
-  data_binary(data_binary),
-  data_double(false)
-{}
+  DXFlags::DXFlags (const bool write_neighbors,
+                    const bool int_binary,
+                    const bool coordinates_binary,
+                    const bool data_binary)
+    :
+    write_neighbors(write_neighbors),
+    int_binary(int_binary),
+    coordinates_binary(coordinates_binary),
+    data_binary(data_binary),
+    data_double(false)
+  {}
 
 
-void DataOutBase::DXFlags::declare_parameters (ParameterHandler &prm)
-{
-  prm.declare_entry ("Write neighbors", "true",
-                     Patterns::Bool(),
-                     "A boolean field indicating whether neighborship "
-                     "information between cells is to be written to the "
-                     "OpenDX output file");
-  prm.declare_entry ("Integer format", "ascii",
-                     Patterns::Selection("ascii|32|64"),
-                     "Output format of integer numbers, which is "
-                     "either a text representation (ascii) or binary integer "
-                     "values of 32 or 64 bits length");
-  prm.declare_entry ("Coordinates format", "ascii",
-                     Patterns::Selection("ascii|32|64"),
-                     "Output format of vertex coordinates, which is "
-                     "either a text representation (ascii) or binary "
-                     "floating point values of 32 or 64 bits length");
-  prm.declare_entry ("Data format", "ascii",
-                     Patterns::Selection("ascii|32|64"),
-                     "Output format of data values, which is "
-                     "either a text representation (ascii) or binary "
-                     "floating point values of 32 or 64 bits length");
-}
+  void DXFlags::declare_parameters (ParameterHandler &prm)
+  {
+    prm.declare_entry ("Write neighbors", "true",
+                       Patterns::Bool(),
+                       "A boolean field indicating whether neighborship "
+                       "information between cells is to be written to the "
+                       "OpenDX output file");
+    prm.declare_entry ("Integer format", "ascii",
+                       Patterns::Selection("ascii|32|64"),
+                       "Output format of integer numbers, which is "
+                       "either a text representation (ascii) or binary integer "
+                       "values of 32 or 64 bits length");
+    prm.declare_entry ("Coordinates format", "ascii",
+                       Patterns::Selection("ascii|32|64"),
+                       "Output format of vertex coordinates, which is "
+                       "either a text representation (ascii) or binary "
+                       "floating point values of 32 or 64 bits length");
+    prm.declare_entry ("Data format", "ascii",
+                       Patterns::Selection("ascii|32|64"),
+                       "Output format of data values, which is "
+                       "either a text representation (ascii) or binary "
+                       "floating point values of 32 or 64 bits length");
+  }
 
 
 
-void DataOutBase::DXFlags::parse_parameters (const ParameterHandler &prm)
-{
-  write_neighbors = prm.get_bool ("Write neighbors");
+  void DXFlags::parse_parameters (const ParameterHandler &prm)
+  {
+    write_neighbors = prm.get_bool ("Write neighbors");
 //TODO:[GK] Read the new  parameters
-}
+  }
 
 
 
-std::size_t
-DataOutBase::DXFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  std::size_t
+  DXFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
 
 
-void DataOutBase::UcdFlags::declare_parameters (ParameterHandler &prm)
-{
-  prm.declare_entry ("Write preamble", "true",
-                     Patterns::Bool(),
-                     "A flag indicating whether a comment should be "
-                     "written to the beginning of the output file "
-                     "indicating date and time of creation as well "
-                     "as the creating program");
-}
+  void UcdFlags::declare_parameters (ParameterHandler &prm)
+  {
+    prm.declare_entry ("Write preamble", "true",
+                       Patterns::Bool(),
+                       "A flag indicating whether a comment should be "
+                       "written to the beginning of the output file "
+                       "indicating date and time of creation as well "
+                       "as the creating program");
+  }
 
 
 
-void DataOutBase::UcdFlags::parse_parameters (const ParameterHandler &prm)
-{
-  write_preamble = prm.get_bool ("Write preamble");
-}
+  void UcdFlags::parse_parameters (const ParameterHandler &prm)
+  {
+    write_preamble = prm.get_bool ("Write preamble");
+  }
 
 
-std::size_t
-DataOutBase::UcdFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  std::size_t
+  UcdFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
 
-DataOutBase::GnuplotFlags::GnuplotFlags ()
-  :
-  dummy (0)
-{}
+  GnuplotFlags::GnuplotFlags ()
+    :
+    dummy (0)
+  {}
 
 
 
-void DataOutBase::GnuplotFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+  void GnuplotFlags::declare_parameters (ParameterHandler &/*prm*/)
+  {}
 
 
 
-void DataOutBase::GnuplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+  void GnuplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+  {}
 
 
 
-size_t
-DataOutBase::GnuplotFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  size_t
+  GnuplotFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
-std::size_t
-DataOutBase::SvgFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  SvgFlags::SvgFlags (const unsigned int height_vector,
+                      const int azimuth_angle,
+                      const int polar_angle,
+                      const unsigned int line_thickness,
+                      const bool margin,
+                      const bool draw_colorbar)
+    :
+    height(4000),
+    width(0),
+    height_vector(height_vector),
+    azimuth_angle(azimuth_angle),
+    polar_angle(polar_angle),
+    line_thickness(line_thickness),
+    margin(margin),
+    draw_colorbar(draw_colorbar)
+  {}
 
 
+  std::size_t
+  SvgFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
+
 
 
-void DataOutBase::PovrayFlags::declare_parameters (ParameterHandler &prm)
-{
-  prm.declare_entry ("Use smooth triangles", "false",
-                     Patterns::Bool(),
-                     "A flag indicating whether POVRAY should use smoothed "
-                     "triangles instead of the usual ones");
-  prm.declare_entry ("Use bicubic patches", "false",
-                     Patterns::Bool(),
-                     "Whether POVRAY should use bicubic patches");
-  prm.declare_entry ("Include external file", "true",
-                     Patterns::Bool (),
-                     "Whether camera and lightling information should "
-                     "be put into an external file \"data.inc\" or into "
-                     "the POVRAY input file");
-}
 
+  void PovrayFlags::declare_parameters (ParameterHandler &prm)
+  {
+    prm.declare_entry ("Use smooth triangles", "false",
+                       Patterns::Bool(),
+                       "A flag indicating whether POVRAY should use smoothed "
+                       "triangles instead of the usual ones");
+    prm.declare_entry ("Use bicubic patches", "false",
+                       Patterns::Bool(),
+                       "Whether POVRAY should use bicubic patches");
+    prm.declare_entry ("Include external file", "true",
+                       Patterns::Bool (),
+                       "Whether camera and lightling information should "
+                       "be put into an external file \"data.inc\" or into "
+                       "the POVRAY input file");
+  }
 
 
-void DataOutBase::PovrayFlags::parse_parameters (const ParameterHandler &prm)
-{
-  smooth        = prm.get_bool ("Use smooth triangles");
-  bicubic_patch = prm.get_bool ("Use bicubic patches");
-  external_data = prm.get_bool ("Include external file");
-}
 
+  void PovrayFlags::parse_parameters (const ParameterHandler &prm)
+  {
+    smooth        = prm.get_bool ("Use smooth triangles");
+    bicubic_patch = prm.get_bool ("Use bicubic patches");
+    external_data = prm.get_bool ("Include external file");
+  }
 
 
-std::size_t
-DataOutBase::PovrayFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
 
+  std::size_t
+  PovrayFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
-DataOutBase::EpsFlags::EpsFlags (const unsigned int  height_vector,
-                                 const unsigned int  color_vector,
-                                 const SizeType      size_type,
-                                 const unsigned int  size,
-                                 const double        line_width,
-                                 const double        azimut_angle,
-                                 const double        turn_angle,
-                                 const double        z_scaling,
-                                 const bool          draw_mesh,
-                                 const bool          draw_cells,
-                                 const bool          shade_cells,
-                                 const ColorFunction color_function)
-  :
-  height_vector(height_vector),
-  color_vector(color_vector),
-  size_type(size_type),
-  size(size),
-  line_width(line_width),
-  azimut_angle(azimut_angle),
-  turn_angle(turn_angle),
-  z_scaling(z_scaling),
-  draw_mesh(draw_mesh),
-  draw_cells(draw_cells),
-  shade_cells(shade_cells),
-  color_function(color_function)
-{}
 
+  EpsFlags::EpsFlags (const unsigned int  height_vector,
+                      const unsigned int  color_vector,
+                      const SizeType      size_type,
+                      const unsigned int  size,
+                      const double        line_width,
+                      const double        azimut_angle,
+                      const double        turn_angle,
+                      const double        z_scaling,
+                      const bool          draw_mesh,
+                      const bool          draw_cells,
+                      const bool          shade_cells,
+                      const ColorFunction color_function)
+    :
+    height_vector(height_vector),
+    color_vector(color_vector),
+    size_type(size_type),
+    size(size),
+    line_width(line_width),
+    azimut_angle(azimut_angle),
+    turn_angle(turn_angle),
+    z_scaling(z_scaling),
+    draw_mesh(draw_mesh),
+    draw_cells(draw_cells),
+    shade_cells(shade_cells),
+    color_function(color_function)
+  {}
 
 
-DataOutBase::EpsFlags::RgbValues
-DataOutBase::EpsFlags::default_color_function (const double x,
-                                               const double xmin,
-                                               const double xmax)
-{
-  RgbValues rgb_values = { 0,0,0 };
+
+  EpsFlags::RgbValues
+  EpsFlags::default_color_function (const double x,
+                                    const double xmin,
+                                    const double xmax)
+  {
+    RgbValues rgb_values = { 0,0,0 };
 
 // A difficult color scale:
 //     xmin          = black  (1)
@@ -1983,4414 +2154,4340 @@ DataOutBase::EpsFlags::default_color_function (const double x,
 //     { 0                                (3) - (4)
 //     { ( 4*x-  xmin-3*xmax)/(xmax-xmin) (4) - (5)
 
-  double sum   =   xmax+  xmin;
-  double sum13 =   xmin+3*xmax;
-  double sum22 = 2*xmin+2*xmax;
-  double sum31 = 3*xmin+  xmax;
-  double dif = xmax-xmin;
-  double rezdif = 1.0/dif;
-
-  int where;
-
-  if (x<(sum31)/4)
-    where = 0;
-  else if (x<(sum22)/4)
-    where = 1;
-  else if (x<(sum13)/4)
-    where = 2;
-  else
-    where = 3;
+    double sum   =   xmax+  xmin;
+    double sum13 =   xmin+3*xmax;
+    double sum22 = 2*xmin+2*xmax;
+    double sum31 = 3*xmin+  xmax;
+    double dif = xmax-xmin;
+    double rezdif = 1.0/dif;
+
+    int where;
+
+    if (x<(sum31)/4)
+      where = 0;
+    else if (x<(sum22)/4)
+      where = 1;
+    else if (x<(sum13)/4)
+      where = 2;
+    else
+      where = 3;
 
-  if (dif!=0)
-    {
-      switch (where)
-        {
-        case 0:
-          rgb_values.red   = 0;
-          rgb_values.green = 0;
-          rgb_values.blue  = (x-xmin)*4.*rezdif;
-          break;
-        case 1:
-          rgb_values.red   = 0;
-          rgb_values.green = (4*x-3*xmin-xmax)*rezdif;
-          rgb_values.blue  = (sum22-4.*x)*rezdif;
-          break;
-        case 2:
-          rgb_values.red   = (4*x-2*sum)*rezdif;
-          rgb_values.green = (xmin+3*xmax-4*x)*rezdif;
-          rgb_values.blue  = 0;
-          break;
-        case 3:
-          rgb_values.red   = 1;
-          rgb_values.green = (4*x-xmin-3*xmax)*rezdif;
-          rgb_values.blue  = (4.*x-sum13)*rezdif;
-        default:
-          break;
-        }
-    }
-  else // White
-    rgb_values.red = rgb_values.green = rgb_values.blue = 1;
+    if (dif!=0)
+      {
+        switch (where)
+          {
+          case 0:
+            rgb_values.red   = 0;
+            rgb_values.green = 0;
+            rgb_values.blue  = (x-xmin)*4.*rezdif;
+            break;
+          case 1:
+            rgb_values.red   = 0;
+            rgb_values.green = (4*x-3*xmin-xmax)*rezdif;
+            rgb_values.blue  = (sum22-4.*x)*rezdif;
+            break;
+          case 2:
+            rgb_values.red   = (4*x-2*sum)*rezdif;
+            rgb_values.green = (xmin+3*xmax-4*x)*rezdif;
+            rgb_values.blue  = 0;
+            break;
+          case 3:
+            rgb_values.red   = 1;
+            rgb_values.green = (4*x-xmin-3*xmax)*rezdif;
+            rgb_values.blue  = (4.*x-sum13)*rezdif;
+          default:
+            break;
+          }
+      }
+    else // White
+      rgb_values.red = rgb_values.green = rgb_values.blue = 1;
 
-  return rgb_values;
-}
+    return rgb_values;
+  }
 
 
 
-DataOutBase::EpsFlags::RgbValues
-DataOutBase::EpsFlags::grey_scale_color_function (const double x,
-                                                  const double xmin,
-                                                  const double xmax)
-{
-  DataOutBase::EpsFlags::RgbValues rgb_values;
-  rgb_values.red = rgb_values.blue = rgb_values.green
-                                     = (x-xmin)/(xmax-xmin);
-  return rgb_values;
-}
+  EpsFlags::RgbValues
+  EpsFlags::grey_scale_color_function (const double x,
+                                       const double xmin,
+                                       const double xmax)
+  {
+    EpsFlags::RgbValues rgb_values;
+    rgb_values.red = rgb_values.blue = rgb_values.green
+                                       = (x-xmin)/(xmax-xmin);
+    return rgb_values;
+  }
 
 
 
-DataOutBase::EpsFlags::RgbValues
-DataOutBase::EpsFlags::reverse_grey_scale_color_function (const double x,
-                                                          const double xmin,
-                                                          const double xmax)
-{
-  DataOutBase::EpsFlags::RgbValues rgb_values;
-  rgb_values.red = rgb_values.blue = rgb_values.green
-                                     = 1-(x-xmin)/(xmax-xmin);
-  return rgb_values;
-}
+  EpsFlags::RgbValues
+  EpsFlags::reverse_grey_scale_color_function (const double x,
+                                               const double xmin,
+                                               const double xmax)
+  {
+    EpsFlags::RgbValues rgb_values;
+    rgb_values.red = rgb_values.blue = rgb_values.green
+                                       = 1-(x-xmin)/(xmax-xmin);
+    return rgb_values;
+  }
 
 
 
-bool DataOutBase::EpsCell2d::operator < (const EpsCell2d &e) const
-{
-  // note the "wrong" order in
-  // which we sort the elements
-  return depth > e.depth;
-}
+  bool EpsCell2d::operator < (const EpsCell2d &e) const
+  {
+    // note the "wrong" order in
+    // which we sort the elements
+    return depth > e.depth;
+  }
 
 
 
-void DataOutBase::EpsFlags::declare_parameters (ParameterHandler &prm)
-{
-  prm.declare_entry ("Index of vector for height", "0",
-                     Patterns::Integer(),
-                     "Number of the input vector that is to be used to "
-                     "generate height information");
-  prm.declare_entry ("Index of vector for color", "0",
-                     Patterns::Integer(),
-                     "Number of the input vector that is to be used to "
-                     "generate color information");
-  prm.declare_entry ("Scale to width or height", "width",
-                     Patterns::Selection ("width|height"),
-                     "Whether width or height should be scaled to match "
-                     "the given size");
-  prm.declare_entry ("Size (width or height) in eps units", "300",
-                     Patterns::Integer(),
-                     "The size (width or height) to which the eps output "
-                     "file is to be scaled");
-  prm.declare_entry ("Line widths in eps units", "0.5",
-                     Patterns::Double(),
-                     "The width in which the postscript renderer is to "
-                     "plot lines");
-  prm.declare_entry ("Azimut angle", "60",
-                     Patterns::Double(0,180),
-                     "Angle of the viewing position against the vertical "
-                     "axis");
-  prm.declare_entry ("Turn angle", "30",
-                     Patterns::Double(0,360),
-                     "Angle of the viewing direction against the y-axis");
-  prm.declare_entry ("Scaling for z-axis", "1",
-                     Patterns::Double (),
-                     "Scaling for the z-direction relative to the scaling "
-                     "used in x- and y-directions");
-  prm.declare_entry ("Draw mesh lines", "true",
-                     Patterns::Bool(),
-                     "Whether the mesh lines, or only the surface should be "
-                     "drawn");
-  prm.declare_entry ("Fill interior of cells", "true",
-                     Patterns::Bool(),
-                     "Whether only the mesh lines, or also the interior of "
-                     "cells should be plotted. If this flag is false, then "
-                     "one can see through the mesh");
-  prm.declare_entry ("Color shading of interior of cells", "true",
-                     Patterns::Bool(),
-                     "Whether the interior of cells shall be shaded");
-  prm.declare_entry ("Color function", "default",
-                     Patterns::Selection ("default|grey scale|reverse grey scale"),
-                     "Name of a color function used to colorize mesh lines "
-                     "and/or cell interiors");
-}
+  void EpsFlags::declare_parameters (ParameterHandler &prm)
+  {
+    prm.declare_entry ("Index of vector for height", "0",
+                       Patterns::Integer(),
+                       "Number of the input vector that is to be used to "
+                       "generate height information");
+    prm.declare_entry ("Index of vector for color", "0",
+                       Patterns::Integer(),
+                       "Number of the input vector that is to be used to "
+                       "generate color information");
+    prm.declare_entry ("Scale to width or height", "width",
+                       Patterns::Selection ("width|height"),
+                       "Whether width or height should be scaled to match "
+                       "the given size");
+    prm.declare_entry ("Size (width or height) in eps units", "300",
+                       Patterns::Integer(),
+                       "The size (width or height) to which the eps output "
+                       "file is to be scaled");
+    prm.declare_entry ("Line widths in eps units", "0.5",
+                       Patterns::Double(),
+                       "The width in which the postscript renderer is to "
+                       "plot lines");
+    prm.declare_entry ("Azimut angle", "60",
+                       Patterns::Double(0,180),
+                       "Angle of the viewing position against the vertical "
+                       "axis");
+    prm.declare_entry ("Turn angle", "30",
+                       Patterns::Double(0,360),
+                       "Angle of the viewing direction against the y-axis");
+    prm.declare_entry ("Scaling for z-axis", "1",
+                       Patterns::Double (),
+                       "Scaling for the z-direction relative to the scaling "
+                       "used in x- and y-directions");
+    prm.declare_entry ("Draw mesh lines", "true",
+                       Patterns::Bool(),
+                       "Whether the mesh lines, or only the surface should be "
+                       "drawn");
+    prm.declare_entry ("Fill interior of cells", "true",
+                       Patterns::Bool(),
+                       "Whether only the mesh lines, or also the interior of "
+                       "cells should be plotted. If this flag is false, then "
+                       "one can see through the mesh");
+    prm.declare_entry ("Color shading of interior of cells", "true",
+                       Patterns::Bool(),
+                       "Whether the interior of cells shall be shaded");
+    prm.declare_entry ("Color function", "default",
+                       Patterns::Selection ("default|grey scale|reverse grey scale"),
+                       "Name of a color function used to colorize mesh lines "
+                       "and/or cell interiors");
+  }
 
 
 
-void DataOutBase::EpsFlags::parse_parameters (const ParameterHandler &prm)
-{
-  height_vector = prm.get_integer ("Index of vector for height");
-  color_vector  = prm.get_integer ("Index of vector for color");
-  if (prm.get ("Scale to width or height") == "width")
-    size_type   = width;
-  else
-    size_type   = height;
-  size          = prm.get_integer ("Size (width or height) in eps units");
-  line_width    = prm.get_double ("Line widths in eps units");
-  azimut_angle  = prm.get_double ("Azimut angle");
-  turn_angle    = prm.get_double ("Turn angle");
-  z_scaling     = prm.get_double ("Scaling for z-axis");
-  draw_mesh     = prm.get_bool ("Draw mesh lines");
-  draw_cells    = prm.get_bool ("Fill interior of cells");
-  shade_cells   = prm.get_bool ("Color shading of interior of cells");
-  if (prm.get("Color function") == "default")
-    color_function = &default_color_function;
-  else if (prm.get("Color function") == "grey scale")
-    color_function = &grey_scale_color_function;
-  else if (prm.get("Color function") == "reverse grey scale")
-    color_function = &reverse_grey_scale_color_function;
-  else
-    // we shouldn't get here, since
-    // the parameter object should
-    // already have checked that the
-    // given value is valid
-    Assert (false, ExcInternalError());
-}
+  void EpsFlags::parse_parameters (const ParameterHandler &prm)
+  {
+    height_vector = prm.get_integer ("Index of vector for height");
+    color_vector  = prm.get_integer ("Index of vector for color");
+    if (prm.get ("Scale to width or height") == "width")
+      size_type   = width;
+    else
+      size_type   = height;
+    size          = prm.get_integer ("Size (width or height) in eps units");
+    line_width    = prm.get_double ("Line widths in eps units");
+    azimut_angle  = prm.get_double ("Azimut angle");
+    turn_angle    = prm.get_double ("Turn angle");
+    z_scaling     = prm.get_double ("Scaling for z-axis");
+    draw_mesh     = prm.get_bool ("Draw mesh lines");
+    draw_cells    = prm.get_bool ("Fill interior of cells");
+    shade_cells   = prm.get_bool ("Color shading of interior of cells");
+    if (prm.get("Color function") == "default")
+      color_function = &default_color_function;
+    else if (prm.get("Color function") == "grey scale")
+      color_function = &grey_scale_color_function;
+    else if (prm.get("Color function") == "reverse grey scale")
+      color_function = &reverse_grey_scale_color_function;
+    else
+      // we shouldn't get here, since
+      // the parameter object should
+      // already have checked that the
+      // given value is valid
+      Assert (false, ExcInternalError());
+  }
 
 
 
-std::size_t
-DataOutBase::EpsFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  std::size_t
+  EpsFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
 
-DataOutBase::GmvFlags::GmvFlags ()
-{}
+  GmvFlags::GmvFlags ()
+  {}
 
 
 
-void DataOutBase::GmvFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+  void GmvFlags::declare_parameters (ParameterHandler &/*prm*/)
+  {}
 
 
 
-void DataOutBase::GmvFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+  void GmvFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+  {}
 
 
-std::size_t
-DataOutBase::GmvFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  std::size_t
+  GmvFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
 
-DataOutBase::TecplotFlags::
-TecplotFlags (const char *tecplot_binary_file_name,
-              const char *zone_name)
-  :
-  tecplot_binary_file_name(tecplot_binary_file_name),
-  zone_name(zone_name)
-{}
+  TecplotFlags::
+  TecplotFlags (const char *tecplot_binary_file_name,
+                const char *zone_name)
+    :
+    tecplot_binary_file_name(tecplot_binary_file_name),
+    zone_name(zone_name)
+  {}
 
 
 
-void DataOutBase::TecplotFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
+  void TecplotFlags::declare_parameters (ParameterHandler &/*prm*/)
+  {}
 
 
 
-void DataOutBase::TecplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
+  void TecplotFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+  {}
 
 
-std::size_t
-DataOutBase::TecplotFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
+  std::size_t
+  TecplotFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
 
 
-DataOutBase::VtkFlags::VtkFlags (const double time,
-                                 const unsigned int cycle,
-                                 const bool print_date_and_time)
-  :
-  time (time),
-  cycle (cycle),
-  print_date_and_time (print_date_and_time)
-{}
+  VtkFlags::VtkFlags (const double time,
+                      const unsigned int cycle,
+                      const bool print_date_and_time)
+    :
+    time (time),
+    cycle (cycle),
+    print_date_and_time (print_date_and_time)
+  {}
 
 
 
-void DataOutBase::VtkFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
-
+  void VtkFlags::declare_parameters (ParameterHandler &/*prm*/)
+  {}
 
 
-void DataOutBase::VtkFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
 
+  void VtkFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+  {}
 
 
-std::size_t
-DataOutBase::VtkFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
 
+  std::size_t
+  VtkFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
-DataOutBase::SvgFlags::SvgFlags (const unsigned int height_vector,
-                                 const int azimuth_angle,
-                                 const int polar_angle,
-                                 const unsigned int line_thickness,
-                                 const bool margin,
-                                 const bool draw_colorbar)
-  :
-  height(4000),
-  width(0),
-  height_vector(height_vector),
-  azimuth_angle(azimuth_angle),
-  polar_angle(polar_angle),
-  line_thickness(line_thickness),
-  margin(margin),
-  draw_colorbar(draw_colorbar)
-{}
 
+  Deal_II_IntermediateFlags::Deal_II_IntermediateFlags ()
+    :
+    dummy (0)
+  {}
 
-DataOutBase::Deal_II_IntermediateFlags::Deal_II_IntermediateFlags ()
-  :
-  dummy (0)
-{}
 
 
+  void Deal_II_IntermediateFlags::declare_parameters (ParameterHandler &/*prm*/)
+  {}
 
-void DataOutBase::Deal_II_IntermediateFlags::declare_parameters (ParameterHandler &/*prm*/)
-{}
 
 
+  void Deal_II_IntermediateFlags::parse_parameters (const ParameterHandler &/*prm*/) const
+  {}
 
-void DataOutBase::Deal_II_IntermediateFlags::parse_parameters (const ParameterHandler &/*prm*/) const
-{}
 
+  std::size_t
+  Deal_II_IntermediateFlags::memory_consumption () const
+  {
+    // only simple data elements, so
+    // use sizeof operator
+    return sizeof (*this);
+  }
 
-std::size_t
-DataOutBase::Deal_II_IntermediateFlags::memory_consumption () const
-{
-  // only simple data elements, so
-  // use sizeof operator
-  return sizeof (*this);
-}
 
 
+  OutputFormat
+  parse_output_format (const std::string &format_name)
+  {
+    if (format_name == "none")
+      return none;
 
-std::size_t
-DataOutBase::memory_consumption ()
-{
-  return 0;
-}
+    if (format_name == "dx")
+      return dx;
 
+    if (format_name == "ucd")
+      return ucd;
 
+    if (format_name == "gnuplot")
+      return gnuplot;
 
+    if (format_name == "povray")
+      return povray;
 
-DataOutBase::OutputFormat
-DataOutBase::
-parse_output_format (const std::string &format_name)
-{
-  if (format_name == "none")
-    return none;
+    if (format_name == "eps")
+      return eps;
 
-  if (format_name == "dx")
-    return dx;
+    if (format_name == "gmv")
+      return gmv;
 
-  if (format_name == "ucd")
-    return ucd;
+    if (format_name == "tecplot")
+      return tecplot;
 
-  if (format_name == "gnuplot")
-    return gnuplot;
+    if (format_name == "tecplot_binary")
+      return tecplot_binary;
 
-  if (format_name == "povray")
-    return povray;
+    if (format_name == "vtk")
+      return vtk;
 
-  if (format_name == "eps")
-    return eps;
+    if (format_name == "vtu")
+      return vtu;
 
-  if (format_name == "gmv")
-    return gmv;
+    if (format_name == "deal.II intermediate")
+      return deal_II_intermediate;
 
-  if (format_name == "tecplot")
-    return tecplot;
+    if (format_name == "hdf5")
+      return hdf5;
 
-  if (format_name == "tecplot_binary")
-    return tecplot_binary;
+    AssertThrow (false,
+                 ExcMessage ("The given file format name is not recognized: <"
+                             + format_name + ">"));
 
-  if (format_name == "vtk")
-    return vtk;
+    // return something invalid
+    return OutputFormat(-1);
+  }
 
-  if (format_name == "vtu")
-    return vtu;
 
-  if (format_name == "deal.II intermediate")
-    return deal_II_intermediate;
 
-  if (format_name == "hdf5")
-    return hdf5;
+  std::string
+  get_output_format_names ()
+  {
+    return "none|dx|ucd|gnuplot|povray|eps|gmv|tecplot|tecplot_binary|vtk|vtu|hdf5|svg|deal.II intermediate";
+  }
 
-  AssertThrow (false,
-               ExcMessage ("The given file format name is not recognized: <"
-                           + format_name + ">"));
 
-  // return something invalid
-  return OutputFormat(-1);
-}
 
+  std::string
+  default_suffix (const OutputFormat output_format)
+  {
+    switch (output_format)
+      {
+      case none:
+        return "";
+      case dx:
+        return ".dx";
+      case ucd:
+        return ".inp";
+      case gnuplot:
+        return ".gnuplot";
+      case povray:
+        return ".pov";
+      case eps:
+        return ".eps";
+      case gmv:
+        return ".gmv";
+      case tecplot:
+        return ".dat";
+      case tecplot_binary:
+        return ".plt";
+      case vtk:
+        return ".vtk";
+      case vtu:
+        return ".vtu";
+      case deal_II_intermediate:
+        return ".d2";
+      case hdf5:
+        return ".h5";
+      case svg:
+        return ".svg";
+      default:
+        Assert (false, ExcNotImplemented());
+        return "";
+      }
+  }
 
 
-std::string
-DataOutBase::get_output_format_names ()
-{
-  return "none|dx|ucd|gnuplot|povray|eps|gmv|tecplot|tecplot_binary|vtk|vtu|hdf5|svg|deal.II intermediate";
-}
+//----------------------------------------------------------------------//
 
+  template <int dim, int spacedim, typename STREAM>
+  void
+  write_nodes (const std::vector<Patch<dim,spacedim> > &patches,
+               STREAM &out)
+  {
+    Assert (dim<=3, ExcNotImplemented());
+    unsigned int count = 0;
+    // We only need this point below,
+    // but it does not harm to declare
+    // it here.
+    Point<spacedim> node;
+
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+         patch=patches.begin();
+         patch!=patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        // Length of loops in all
+        // dimensions. If a dimension
+        // is not used, a loop of
+        // length one will do the job.
+        const unsigned int n1 = (dim>0) ? n : 1;
+        const unsigned int n2 = (dim>1) ? n : 1;
+        const unsigned int n3 = (dim>2) ? n : 1;
+
+        for (unsigned int i3=0; i3<n3; ++i3)
+          for (unsigned int i2=0; i2<n2; ++i2)
+            for (unsigned int i1=0; i1<n1; ++i1)
+              {
+                compute_node(node, &*patch,
+                             i1,
+                             i2,
+                             i3,
+                             n_subdivisions);
+                out.write_point(count++, node);
+              }
+      }
+    out.flush_points ();
+  }
 
+  template <int dim, int spacedim, typename STREAM>
+  void
+  write_cells (const std::vector<Patch<dim,spacedim> > &patches,
+               STREAM &out)
+  {
+    Assert (dim<=3, ExcNotImplemented());
+    unsigned int count = 0;
+    unsigned int first_vertex_of_patch = 0;
+    // Array to hold all the node
+    // numbers of a cell. 8 is
+    // sufficient for 3D
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+         patch=patches.begin();
+         patch!=patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        // Length of loops in all dimensons
+        const unsigned int n1 = (dim>0) ? n_subdivisions : 1;
+        const unsigned int n2 = (dim>1) ? n_subdivisions : 1;
+        const unsigned int n3 = (dim>2) ? n_subdivisions : 1;
+        // Offsets of outer loops
+        unsigned int d1 = 1;
+        unsigned int d2 = n;
+        unsigned int d3 = n*n;
+        for (unsigned int i3=0; i3<n3; ++i3)
+          for (unsigned int i2=0; i2<n2; ++i2)
+            for (unsigned int i1=0; i1<n1; ++i1)
+              {
+                const unsigned int offset = first_vertex_of_patch+i3*d3+i2*d2+i1*d1;
+                // First write line in x direction
+                out.template write_cell<dim>(count++, offset, d1, d2, d3);
+              }
+        // finally update the number
+        // of the first vertex of this patch
+        first_vertex_of_patch += Utilities::fixed_power<dim>(n_subdivisions+1);
+      }
 
-std::string
-DataOutBase::
-default_suffix (const OutputFormat output_format)
-{
-  switch (output_format)
-    {
-    case none:
-      return "";
-    case dx:
-      return ".dx";
-    case ucd:
-      return ".inp";
-    case gnuplot:
-      return ".gnuplot";
-    case povray:
-      return ".pov";
-    case eps:
-      return ".eps";
-    case gmv:
-      return ".gmv";
-    case tecplot:
-      return ".dat";
-    case tecplot_binary:
-      return ".plt";
-    case vtk:
-      return ".vtk";
-    case vtu:
-      return ".vtu";
-    case deal_II_intermediate:
-      return ".d2";
-    case hdf5:
-      return ".h5";
-    case svg:
-      return ".svg";
-    default:
-      Assert (false, ExcNotImplemented());
-      return "";
-    }
-}
+    out.flush_cells ();
+  }
 
 
-//----------------------------------------------------------------------//
+  template <int dim, int spacedim, class STREAM>
+  void
+  write_data (
+    const std::vector<Patch<dim,spacedim> > &patches,
+    unsigned int n_data_sets,
+    const bool double_precision,
+    STREAM &out)
+  {
+    Assert (dim<=3, ExcNotImplemented());
+    unsigned int count = 0;
 
-template <int dim, int spacedim, typename STREAM>
-void
-DataOutBase::write_nodes (const std::vector<Patch<dim,spacedim> > &patches,
-                          STREAM &out)
-{
-  Assert (dim<=3, ExcNotImplemented());
-  unsigned int count = 0;
-  // We only need this point below,
-  // but it does not harm to declare
-  // it here.
-  Point<spacedim> node;
-
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator
-       patch=patches.begin();
-       patch!=patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      // Length of loops in all
-      // dimensions. If a dimension
-      // is not used, a loop of
-      // length one will do the job.
-      const unsigned int n1 = (dim>0) ? n : 1;
-      const unsigned int n2 = (dim>1) ? n : 1;
-      const unsigned int n3 = (dim>2) ? n : 1;
-
-      for (unsigned int i3=0; i3<n3; ++i3)
-        for (unsigned int i2=0; i2<n2; ++i2)
-          for (unsigned int i1=0; i1<n1; ++i1)
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch
+         = patches.begin();
+         patch != patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        // Length of loops in all dimensions
+        Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+                (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+                ExcDimensionMismatch (patch->points_are_available
+                                      ?
+                                      (n_data_sets + spacedim)
+                                      :
+                                      n_data_sets,
+                                      patch->data.n_rows()));
+        Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
+                ExcInvalidDatasetSize (patch->data.n_cols(), n));
+
+        std::vector<float>  floats(n_data_sets);
+        std::vector<double> doubles(n_data_sets);
+
+        // Data is already in
+        // lexicographic ordering
+        for (unsigned int i=0; i<Utilities::fixed_power<dim>(n); ++i, ++count)
+          if (double_precision)
             {
-              compute_node(node, &*patch,
-                           i1,
-                           i2,
-                           i3,
-                           n_subdivisions);
-              out.write_point(count++, node);
+              for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                doubles[data_set] = patch->data(data_set, i);
+              out.write_dataset(count, doubles);
             }
-    }
-  out.flush_points ();
-}
-
-template <int dim, int spacedim, typename STREAM>
-void
-DataOutBase::write_cells (const std::vector<Patch<dim,spacedim> > &patches,
-                          STREAM &out)
-{
-  Assert (dim<=3, ExcNotImplemented());
-  unsigned int count = 0;
-  unsigned int first_vertex_of_patch = 0;
-  // Array to hold all the node
-  // numbers of a cell. 8 is
-  // sufficient for 3D
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator
-       patch=patches.begin();
-       patch!=patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      // Length of loops in all dimensons
-      const unsigned int n1 = (dim>0) ? n_subdivisions : 1;
-      const unsigned int n2 = (dim>1) ? n_subdivisions : 1;
-      const unsigned int n3 = (dim>2) ? n_subdivisions : 1;
-      // Offsets of outer loops
-      unsigned int d1 = 1;
-      unsigned int d2 = n;
-      unsigned int d3 = n*n;
-      for (unsigned int i3=0; i3<n3; ++i3)
-        for (unsigned int i2=0; i2<n2; ++i2)
-          for (unsigned int i1=0; i1<n1; ++i1)
+          else
             {
-              const unsigned int offset = first_vertex_of_patch+i3*d3+i2*d2+i1*d1;
-              // First write line in x direction
-              out.template write_cell<dim>(count++, offset, d1, d2, d3);
+              for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                floats[data_set] = patch->data(data_set, i);
+              out.write_dataset(count, floats);
             }
-      // finally update the number
-      // of the first vertex of this patch
-      first_vertex_of_patch += Utilities::fixed_power<dim>(n_subdivisions+1);
-    }
-
-  out.flush_cells ();
-}
+      }
+  }
 
 
-template <int dim, int spacedim, class STREAM>
-void
-DataOutBase::write_data (
-  const std::vector<Patch<dim,spacedim> > &patches,
-  unsigned int n_data_sets,
-  const bool double_precision,
-  STREAM &out)
-{
-  Assert (dim<=3, ExcNotImplemented());
-  unsigned int count = 0;
 
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch
-       = patches.begin();
-       patch != patches.end(); ++patch)
+  namespace
+  {
+    /**
+     * This function projects a three-dimensional point (Point<3> point)
+     * onto a two-dimensional image plane, specified by the position of
+     * the camera viewing system (Point<3> camera_position), camera
+     * direction (Point<3> camera_position), camera horizontal (Point<3>
+     * camera_horizontal, necessary for the correct alignment of the
+     * later images), and the focus of the camera (float camera_focus).
+     */
+    Point<2> svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus)
     {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      // Length of loops in all dimensions
-      Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
-              (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
-              ExcDimensionMismatch (patch->points_are_available
-                                    ?
-                                    (n_data_sets + spacedim)
-                                    :
-                                    n_data_sets,
-                                    patch->data.n_rows()));
-      Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
-              ExcInvalidDatasetSize (patch->data.n_cols(), n));
-
-      std::vector<float>  floats(n_data_sets);
-      std::vector<double> doubles(n_data_sets);
-
-      // Data is already in
-      // lexicographic ordering
-      for (unsigned int i=0; i<Utilities::fixed_power<dim>(n); ++i, ++count)
-        if (double_precision)
-          {
-            for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-              doubles[data_set] = patch->data(data_set, i);
-            out.write_dataset(count, doubles);
-          }
-        else
-          {
-            for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-              floats[data_set] = patch->data(data_set, i);
-            out.write_dataset(count, floats);
-          }
+      Point<3> camera_vertical;
+      camera_vertical[0] = camera_horizontal[1] * camera_direction[2] - camera_horizontal[2] * camera_direction[1];
+      camera_vertical[1] = camera_horizontal[2] * camera_direction[0] - camera_horizontal[0] * camera_direction[2];
+      camera_vertical[2] = camera_horizontal[0] * camera_direction[1] - camera_horizontal[1] * camera_direction[0];
+
+      float phi;
+      phi  = camera_focus;
+      phi /= (point[0] - camera_position[0]) * camera_direction[0] + (point[1] - camera_position[1]) * camera_direction[1] + (point[2] - camera_position[2]) * camera_direction[2];
+
+      Point<3> projection;
+      projection[0] = camera_position[0] + phi * (point[0] - camera_position[0]);
+      projection[1] = camera_position[1] + phi * (point[1] - camera_position[1]);
+      projection[2] = camera_position[2] + phi * (point[2] - camera_position[2]);
+
+      Point<2> projection_decomposition;
+      projection_decomposition[0]  = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_horizontal[0];
+      projection_decomposition[0] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_horizontal[1];
+      projection_decomposition[0] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_horizontal[2];
+
+      projection_decomposition[1]  = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_vertical[0];
+      projection_decomposition[1] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_vertical[1];
+      projection_decomposition[1] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_vertical[2];
+
+      return projection_decomposition;
     }
-}
-
 
-Point<2> DataOutBase::svg_project_point(Point<3> point, Point<3> camera_position, Point<3> camera_direction, Point<3> camera_horizontal, float camera_focus)
-{
-  Point<3> camera_vertical;
-  camera_vertical[0] = camera_horizontal[1] * camera_direction[2] - camera_horizontal[2] * camera_direction[1];
-  camera_vertical[1] = camera_horizontal[2] * camera_direction[0] - camera_horizontal[0] * camera_direction[2];
-  camera_vertical[2] = camera_horizontal[0] * camera_direction[1] - camera_horizontal[1] * camera_direction[0];
-
-  float phi;
-  phi  = camera_focus;
-  phi /= (point[0] - camera_position[0]) * camera_direction[0] + (point[1] - camera_position[1]) * camera_direction[1] + (point[2] - camera_position[2]) * camera_direction[2];
-
-  Point<3> projection;
-  projection[0] = camera_position[0] + phi * (point[0] - camera_position[0]);
-  projection[1] = camera_position[1] + phi * (point[1] - camera_position[1]);
-  projection[2] = camera_position[2] + phi * (point[2] - camera_position[2]);
-
-  Point<2> projection_decomposition;
-  projection_decomposition[0]  = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_horizontal[0];
-  projection_decomposition[0] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_horizontal[1];
-  projection_decomposition[0] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_horizontal[2];
-
-  projection_decomposition[1]  = (projection[0] - camera_position[0] - camera_focus * camera_direction[0]) * camera_vertical[0];
-  projection_decomposition[1] += (projection[1] - camera_position[1] - camera_focus * camera_direction[1]) * camera_vertical[1];
-  projection_decomposition[1] += (projection[2] - camera_position[2] - camera_focus * camera_direction[2]) * camera_vertical[2];
-
-  return projection_decomposition;
-}
 
-Point<6> DataOutBase::svg_get_gradient_parameters(Point<3> points[])
-{
-  Point<3> v_min, v_max, v_inter;
+    /**
+     * Function to compute the gradient parameters for a triangle with
+     * given values for the vertices.
+     */
+    Point<6> svg_get_gradient_parameters(Point<3> points[])
+    {
+      Point<3> v_min, v_max, v_inter;
 
-  // Use the Bubblesort algorithm to sort the points with respect to the third coordinate
-  int i, j;
+      // Use the Bubblesort algorithm to sort the points with respect to the third coordinate
+      int i, j;
 
-  for (i = 0; i < 2; ++i)
-    {
-      for (j = 0; j < 2-i; ++j)
+      for (i = 0; i < 2; ++i)
         {
-          if (points[j][2] > points[j + 1][2])
+          for (j = 0; j < 2-i; ++j)
             {
-              Point<3> temp = points[j];
-              points[j] = points[j+1];
-              points[j+1] = temp;
+              if (points[j][2] > points[j + 1][2])
+                {
+                  Point<3> temp = points[j];
+                  points[j] = points[j+1];
+                  points[j+1] = temp;
+                }
             }
         }
-    }
 
-  // save the related three-dimensional vectors v_min, v_inter, and v_max
-  v_min = points[0];
-  v_inter = points[1];
-  v_max = points[2];
+      // save the related three-dimensional vectors v_min, v_inter, and v_max
+      v_min = points[0];
+      v_inter = points[1];
+      v_max = points[2];
 
-  Point<2> A[2];
-  Point<2> b, gradient;
+      Point<2> A[2];
+      Point<2> b, gradient;
 
-  // determine the plane offset c
-  A[0][0] = v_max[0] - v_min[0];
-  A[0][1] = v_inter[0] - v_min[0];
-  A[1][0] = v_max[1] - v_min[1];
-  A[1][1] = v_inter[1] - v_min[1];
+      // determine the plane offset c
+      A[0][0] = v_max[0] - v_min[0];
+      A[0][1] = v_inter[0] - v_min[0];
+      A[1][0] = v_max[1] - v_min[1];
+      A[1][1] = v_inter[1] - v_min[1];
 
-  b[0] = - v_min[0];
-  b[1] = - v_min[1];
+      b[0] = - v_min[0];
+      b[1] = - v_min[1];
 
-  double x, sum;
-  bool col_change = false;
+      double x, sum;
+      bool col_change = false;
 
-  if (A[0][0] == 0)
-    {
-      col_change = true;
+      if (A[0][0] == 0)
+        {
+          col_change = true;
 
-      A[0][0] = A[0][1];
-      A[0][1] = 0;
+          A[0][0] = A[0][1];
+          A[0][1] = 0;
 
-      double temp = A[1][0];
-      A[1][0] = A[1][1];
-      A[1][1] = temp;
-    }
+          double temp = A[1][0];
+          A[1][0] = A[1][1];
+          A[1][1] = temp;
+        }
 
-  for (unsigned int k = 0; k < 1; k++)
-    {
-      for (unsigned int i = k+1; i < 2; i++)
+      for (unsigned int k = 0; k < 1; k++)
         {
-          x = A[i][k] / A[k][k];
+          for (unsigned int i = k+1; i < 2; i++)
+            {
+              x = A[i][k] / A[k][k];
 
-          for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
+              for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
 
-          b[i] = b[i] - b[k]*x;
+              b[i] = b[i] - b[k]*x;
 
+            }
         }
-    }
 
-  b[1] = b[1] / A[1][1];
+      b[1] = b[1] / A[1][1];
 
-  for (int i = 0; i >= 0; i--)
-    {
-      sum = b[i];
+      for (int i = 0; i >= 0; i--)
+        {
+          sum = b[i];
 
-      for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
+          for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
 
-      b[i] = sum / A[i][i];
-    }
+          b[i] = sum / A[i][i];
+        }
 
-  if (col_change)
-    {
-      double temp = b[0];
-      b[0] = b[1];
-      b[1] = temp;
-    }
+      if (col_change)
+        {
+          double temp = b[0];
+          b[0] = b[1];
+          b[1] = temp;
+        }
 
-  double c = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) + v_min[2];
+      double c = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) + v_min[2];
 
-  // Determine the first entry of the gradient (phi, cf. documentation)
-  A[0][0] = v_max[0] - v_min[0];
-  A[0][1] = v_inter[0] - v_min[0];
-  A[1][0] = v_max[1] - v_min[1];
-  A[1][1] = v_inter[1] - v_min[1];
+      // Determine the first entry of the gradient (phi, cf. documentation)
+      A[0][0] = v_max[0] - v_min[0];
+      A[0][1] = v_inter[0] - v_min[0];
+      A[1][0] = v_max[1] - v_min[1];
+      A[1][1] = v_inter[1] - v_min[1];
 
-  b[0] = 1.0 - v_min[0];
-  b[1] = - v_min[1];
+      b[0] = 1.0 - v_min[0];
+      b[1] = - v_min[1];
 
-  col_change = false;
+      col_change = false;
 
-  if (A[0][0] == 0)
-    {
-      col_change = true;
+      if (A[0][0] == 0)
+        {
+          col_change = true;
 
-      A[0][0] = A[0][1];
-      A[0][1] = 0;
+          A[0][0] = A[0][1];
+          A[0][1] = 0;
 
-      double temp = A[1][0];
-      A[1][0] = A[1][1];
-      A[1][1] = temp;
-    }
+          double temp = A[1][0];
+          A[1][0] = A[1][1];
+          A[1][1] = temp;
+        }
 
-  for (unsigned int k = 0; k < 1; k++)
-    {
-      for (unsigned int i = k+1; i < 2; i++)
+      for (unsigned int k = 0; k < 1; k++)
         {
-          x = A[i][k] / A[k][k];
+          for (unsigned int i = k+1; i < 2; i++)
+            {
+              x = A[i][k] / A[k][k];
 
-          for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
+              for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
 
-          b[i] = b[i] - b[k] * x;
+              b[i] = b[i] - b[k] * x;
 
+            }
         }
-    }
 
-  b[1]=b[1] / A[1][1];
+      b[1]=b[1] / A[1][1];
 
-  for (int i = 0; i >= 0; i--)
-    {
-      sum = b[i];
+      for (int i = 0; i >= 0; i--)
+        {
+          sum = b[i];
 
-      for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j]*b[j];
+          for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j]*b[j];
 
-      b[i] = sum / A[i][i];
-    }
+          b[i] = sum / A[i][i];
+        }
 
-  if (col_change)
-    {
-      double temp = b[0];
-      b[0] = b[1];
-      b[1] = temp;
-    }
+      if (col_change)
+        {
+          double temp = b[0];
+          b[0] = b[1];
+          b[1] = temp;
+        }
 
-  gradient[0] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
+      gradient[0] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
 
-  // determine the second entry of the gradient
-  A[0][0] = v_max[0] - v_min[0];
-  A[0][1] = v_inter[0] - v_min[0];
-  A[1][0] = v_max[1] - v_min[1];
-  A[1][1] = v_inter[1] - v_min[1];
+      // determine the second entry of the gradient
+      A[0][0] = v_max[0] - v_min[0];
+      A[0][1] = v_inter[0] - v_min[0];
+      A[1][0] = v_max[1] - v_min[1];
+      A[1][1] = v_inter[1] - v_min[1];
 
-  b[0] = - v_min[0];
-  b[1] = 1.0 - v_min[1];
+      b[0] = - v_min[0];
+      b[1] = 1.0 - v_min[1];
 
-  col_change = false;
+      col_change = false;
 
-  if (A[0][0] == 0)
-    {
-      col_change = true;
+      if (A[0][0] == 0)
+        {
+          col_change = true;
 
-      A[0][0] = A[0][1];
-      A[0][1] = 0;
+          A[0][0] = A[0][1];
+          A[0][1] = 0;
 
-      double temp = A[1][0];
-      A[1][0] = A[1][1];
-      A[1][1] = temp;
-    }
+          double temp = A[1][0];
+          A[1][0] = A[1][1];
+          A[1][1] = temp;
+        }
 
-  for (unsigned int k = 0; k < 1; k++)
-    {
-      for (unsigned int i = k+1; i < 2; i++)
+      for (unsigned int k = 0; k < 1; k++)
         {
-          x = A[i][k] / A[k][k];
+          for (unsigned int i = k+1; i < 2; i++)
+            {
+              x = A[i][k] / A[k][k];
 
-          for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
+              for (unsigned int j = k+1; j < 2; j++) A[i][j] = A[i][j] - A[k][j] * x;
 
-          b[i] = b[i] - b[k] * x;
+              b[i] = b[i] - b[k] * x;
+            }
         }
-    }
-
-  b[1] = b[1] / A[1][1];
-
-  for (int i = 0; i >= 0; i--)
-    {
-      sum = b[i];
 
-      for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
+      b[1] = b[1] / A[1][1];
 
-      b[i] = sum / A[i][i];
-    }
+      for (int i = 0; i >= 0; i--)
+        {
+          sum = b[i];
 
-  if (col_change)
-    {
-      double temp = b[0];
-      b[0] = b[1];
-      b[1] = temp;
-    }
+          for (unsigned int j = i+1; j < 2; j++) sum = sum - A[i][j] * b[j];
 
-  gradient[1] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
+          b[i] = sum / A[i][i];
+        }
 
-  // normalize the gradient
-  double gradient_norm = sqrt(pow(gradient[0], 2.0) + pow(gradient[1], 2.0));
-  gradient[0] /= gradient_norm;
-  gradient[1] /= gradient_norm;
+      if (col_change)
+        {
+          double temp = b[0];
+          b[0] = b[1];
+          b[1] = temp;
+        }
 
-  double lambda = - gradient[0] * (v_min[0] - v_max[0]) - gradient[1] * (v_min[1] - v_max[1]);
+      gradient[1] = b[0] * (v_max[2] - v_min[2]) + b[1] * (v_inter[2] - v_min[2]) - c + v_min[2];
 
-  Point<6> gradient_parameters(true);
+      // normalize the gradient
+      double gradient_norm = sqrt(pow(gradient[0], 2.0) + pow(gradient[1], 2.0));
+      gradient[0] /= gradient_norm;
+      gradient[1] /= gradient_norm;
 
-  gradient_parameters[0] = v_min[0];
-  gradient_parameters[1] = v_min[1];
+      double lambda = - gradient[0] * (v_min[0] - v_max[0]) - gradient[1] * (v_min[1] - v_max[1]);
 
-  gradient_parameters[2] = v_min[0] + lambda * gradient[0];
-  gradient_parameters[3] = v_min[1] + lambda * gradient[1];
+      Point<6> gradient_parameters(true);
 
-  gradient_parameters[4] = v_min[2];
-  gradient_parameters[5] = v_max[2];
+      gradient_parameters[0] = v_min[0];
+      gradient_parameters[1] = v_min[1];
 
-  return gradient_parameters;
-}
+      gradient_parameters[2] = v_min[0] + lambda * gradient[0];
+      gradient_parameters[3] = v_min[1] + lambda * gradient[1];
 
+      gradient_parameters[4] = v_min[2];
+      gradient_parameters[5] = v_max[2];
 
-bool DataOutBase::SvgCell::operator < (const SvgCell &e) const
-{
-  // note the "wrong" order in
-  // which we sort the elements
-  return depth > e.depth;
-}
+      return gradient_parameters;
+    }
+  }
 
 
 
-template <int dim, int spacedim>
-void DataOutBase::write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
-                             const std::vector<std::string>          &data_names,
-                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                             const UcdFlags                          &flags,
-                             std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+  template <int dim, int spacedim>
+  void write_ucd (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                  const UcdFlags                          &flags,
+                  std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
 
 #ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
 #else
-  if (patches.size() == 0)
-    return;
+    if (patches.size() == 0)
+      return;
 #endif
 
-  const unsigned int n_data_sets = data_names.size();
+    const unsigned int n_data_sets = data_names.size();
 
-  UcdStream ucd_out(out, flags);
+    UcdStream ucd_out(out, flags);
 
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim> (patches, n_nodes, n_cells);
-  ///////////////////////
-  // preamble
-  if (flags.write_preamble)
-    {
-      std::time_t  time1= std::time (0);
-      std::tm     *time = std::localtime(&time1);
-      out << "# This file was generated by the deal.II library." << '\n'
-          << "# Date =  "
-          << time->tm_year+1900 << "/"
-          << time->tm_mon+1 << "/"
-          << time->tm_mday << '\n'
-          << "# Time =  "
-          << time->tm_hour << ":"
-          << std::setw(2) << time->tm_min << ":"
-          << std::setw(2) << time->tm_sec << '\n'
-          << "#" << '\n'
-          << "# For a description of the UCD format see the AVS Developer's guide."
-          << '\n'
-          << "#" << '\n';
-    }
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim> (patches, n_nodes, n_cells);
+    ///////////////////////
+    // preamble
+    if (flags.write_preamble)
+      {
+        std::time_t  time1= std::time (0);
+        std::tm     *time = std::localtime(&time1);
+        out << "# This file was generated by the deal.II library." << '\n'
+            << "# Date =  "
+            << time->tm_year+1900 << "/"
+            << time->tm_mon+1 << "/"
+            << time->tm_mday << '\n'
+            << "# Time =  "
+            << time->tm_hour << ":"
+            << std::setw(2) << time->tm_min << ":"
+            << std::setw(2) << time->tm_sec << '\n'
+            << "#" << '\n'
+            << "# For a description of the UCD format see the AVS Developer's guide."
+            << '\n'
+            << "#" << '\n';
+      }
 
-  // start with ucd data
-  out << n_nodes << ' '
-      << n_cells << ' '
-      << n_data_sets << ' '
-      << 0 << ' '                  // no cell data at present
-      << 0                         // no model data
-      << '\n';
+    // start with ucd data
+    out << n_nodes << ' '
+        << n_cells << ' '
+        << n_data_sets << ' '
+        << 0 << ' '                  // no cell data at present
+        << 0                         // no model data
+        << '\n';
 
-  write_nodes(patches, ucd_out);
-  out << '\n';
+    write_nodes(patches, ucd_out);
+    out << '\n';
 
-  write_cells(patches, ucd_out);
-  out << '\n';
+    write_cells(patches, ucd_out);
+    out << '\n';
 
-  /////////////////////////////
-  // now write data
-  if (n_data_sets != 0)
-    {
-      out << n_data_sets << "    ";    // number of vectors
-      for (unsigned int i=0; i<n_data_sets; ++i)
-        out << 1 << ' ';               // number of components;
-      // only 1 supported presently
-      out << '\n';
+    /////////////////////////////
+    // now write data
+    if (n_data_sets != 0)
+      {
+        out << n_data_sets << "    ";    // number of vectors
+        for (unsigned int i=0; i<n_data_sets; ++i)
+          out << 1 << ' ';               // number of components;
+        // only 1 supported presently
+        out << '\n';
 
-      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-        out << data_names[data_set]
-            << ",dimensionless"      // no units supported at present
-            << '\n';
+        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+          out << data_names[data_set]
+              << ",dimensionless"      // no units supported at present
+              << '\n';
 
-      write_data(patches, n_data_sets, true, ucd_out);
-    }
-  // make sure everything now gets to
-  // disk
-  out.flush ();
+        write_data(patches, n_data_sets, true, ucd_out);
+      }
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
-  // assert the stream is still ok
-  AssertThrow (out, ExcIO());
-}
+    // assert the stream is still ok
+    AssertThrow (out, ExcIO());
+  }
 
 
-template <int dim, int spacedim>
-void DataOutBase::write_dx (const std::vector<Patch<dim,spacedim> > &patches,
-                            const std::vector<std::string>          &data_names,
-                            const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                            const DXFlags                           &flags,
-                            std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+  template <int dim, int spacedim>
+  void write_dx (const std::vector<Patch<dim,spacedim> > &patches,
+                 const std::vector<std::string>          &data_names,
+                 const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                 const DXFlags                           &flags,
+                 std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
 
 #ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
 #else
-  if (patches.size() == 0)
-    return;
+    if (patches.size() == 0)
+      return;
 #endif
-  // Stream with special features for dx output
-  DXStream dx_out(out, flags);
+    // Stream with special features for dx output
+    DXStream dx_out(out, flags);
 
-  // Variable counting the offset of
-  // binary data.
-  unsigned int offset = 0;
+    // Variable counting the offset of
+    // binary data.
+    unsigned int offset = 0;
 
-  const unsigned int n_data_sets = data_names.size();
-
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-  // start with vertices order is
-  // lexicographical, x varying
-  // fastest
-  out << "object \"vertices\" class array type float rank 1 shape " << spacedim
-      << " items " << n_nodes;
-
-  if (flags.coordinates_binary)
-    {
-      out << " lsb ieee data 0" << '\n';
-      offset += n_nodes * spacedim *  sizeof(float);
-    }
-  else
-    {
-      out << " data follows" << '\n';
-      write_nodes(patches, dx_out);
-    }
+    const unsigned int n_data_sets = data_names.size();
 
-  ///////////////////////////////
-  // first write the coordinates of all vertices
-
-  /////////////////////////////////////////
-  // write cells
-  out << "object \"cells\" class array type int rank 1 shape "
-      << GeometryInfo<dim>::vertices_per_cell
-      << " items " << n_cells;
-
-  if (flags.int_binary)
-    {
-      out << " lsb binary data " << offset << '\n';
-      offset += n_cells * sizeof (int);
-    }
-  else
-    {
-      out << " data follows" << '\n';
-      write_cells(patches, dx_out);
-      out << '\n';
-    }
-
-
-  out << "attribute \"element type\" string \"";
-  if (dim==1) out << "lines";
-  if (dim==2) out << "quads";
-  if (dim==3) out << "cubes";
-  out << "\"" << '\n'
-      << "attribute \"ref\" string \"positions\"" << '\n';
-
-//TODO:[GK] Patches must be of same size!
-  /////////////////////////////
-  // write neighbor information
-  if (flags.write_neighbors)
-    {
-      out << "object \"neighbors\" class array type int rank 1 shape "
-          << GeometryInfo<dim>::faces_per_cell
-          << " items " << n_cells
-          << " data follows";
-
-      for (typename std::vector<Patch<dim,spacedim> >::const_iterator
-           patch=patches.begin();
-           patch!=patches.end(); ++patch)
-        {
-          const unsigned int n = patch->n_subdivisions;
-          const unsigned int n1 = (dim>0) ? n : 1;
-          const unsigned int n2 = (dim>1) ? n : 1;
-          const unsigned int n3 = (dim>2) ? n : 1;
-          unsigned int cells_per_patch = Utilities::fixed_power<dim>(n);
-          unsigned int dx = 1;
-          unsigned int dy = n;
-          unsigned int dz = n*n;
-
-          const unsigned int patch_start = patch->patch_index * cells_per_patch;
-
-          for (unsigned int i3=0; i3<n3; ++i3)
-            for (unsigned int i2=0; i2<n2; ++i2)
-              for (unsigned int i1=0; i1<n1; ++i1)
-                {
-                  const unsigned int nx = i1*dx;
-                  const unsigned int ny = i2*dy;
-                  const unsigned int nz = i3*dz;
-
-                  out << '\n';
-                  // Direction -x
-                  // Last cell in row
-                  // of other patch
-                  if (i1==0)
-                    {
-                      const unsigned int nn = patch->neighbors[0];
-                      out << '\t';
-                      if (nn != patch->no_neighbor)
-                        out << (nn*cells_per_patch+ny+nz+dx*(n-1));
-                      else
-                        out << "-1";
-                    }
-                  else
-                    {
-                      out << '\t'
-                          << patch_start+nx-dx+ny+nz;
-                    }
-                  // Direction +x
-                  // First cell in row
-                  // of other patch
-                  if (i1 == n-1)
-                    {
-                      const unsigned int nn = patch->neighbors[1];
-                      out << '\t';
-                      if (nn != patch->no_neighbor)
-                        out << (nn*cells_per_patch+ny+nz);
-                      else
-                        out << "-1";
-                    }
-                  else
-                    {
-                      out << '\t'
-                          << patch_start+nx+dx+ny+nz;
-                    }
-                  if (dim<2)
-                    continue;
-                  // Direction -y
-                  if (i2==0)
-                    {
-                      const unsigned int nn = patch->neighbors[2];
-                      out << '\t';
-                      if (nn != patch->no_neighbor)
-                        out << (nn*cells_per_patch+nx+nz+dy*(n-1));
-                      else
-                        out << "-1";
-                    }
-                  else
-                    {
-                      out << '\t'
-                          << patch_start+nx+ny-dy+nz;
-                    }
-                  // Direction +y
-                  if (i2 == n-1)
-                    {
-                      const unsigned int nn = patch->neighbors[3];
-                      out << '\t';
-                      if (nn != patch->no_neighbor)
-                        out << (nn*cells_per_patch+nx+nz);
-                      else
-                        out << "-1";
-                    }
-                  else
-                    {
-                      out << '\t'
-                          << patch_start+nx+ny+dy+nz;
-                    }
-                  if (dim<3)
-                    continue;
-
-                  // Direction -z
-                  if (i3==0)
-                    {
-                      const unsigned int nn = patch->neighbors[4];
-                      out << '\t';
-                      if (nn != patch->no_neighbor)
-                        out << (nn*cells_per_patch+nx+ny+dz*(n-1));
-                      else
-                        out << "-1";
-                    }
-                  else
-                    {
-                      out << '\t'
-                          << patch_start+nx+ny+nz-dz;
-                    }
-                  // Direction +z
-                  if (i3 == n-1)
-                    {
-                      const unsigned int nn = patch->neighbors[5];
-                      out << '\t';
-                      if (nn != patch->no_neighbor)
-                        out << (nn*cells_per_patch+nx+ny);
-                      else
-                        out << "-1";
-                    }
-                  else
-                    {
-                      out << '\t'
-                          << patch_start+nx+ny+nz+dz;
-                    }
-                }
-          out << '\n';
-        }
-    }
-  /////////////////////////////
-  // now write data
-  if (n_data_sets != 0)
-    {
-      out << "object \"data\" class array type float rank 1 shape "
-          << n_data_sets
-          << " items " << n_nodes;
-
-      if (flags.data_binary)
-        {
-          out << " lsb ieee data " << offset << '\n';
-          offset += n_data_sets * n_nodes * ((flags.data_double)
-                                             ? sizeof(double)
-                                             : sizeof(float));
-        }
-      else
-        {
-          out << " data follows" << '\n';
-          write_data(patches, n_data_sets, flags.data_double, dx_out);
-        }
-
-      // loop over all patches
-      out << "attribute \"dep\" string \"positions\"" << '\n';
-    }
-  else
-    {
-      out << "object \"data\" class constantarray type float rank 0 items " << n_nodes << " data follows"
-          << '\n' << '0' << '\n';
-    }
-
-  // no model data
-
-  out << "object \"deal data\" class field" << '\n'
-      << "component \"positions\" value \"vertices\"" << '\n'
-      << "component \"connections\" value \"cells\"" << '\n'
-      << "component \"data\" value \"data\"" << '\n';
-
-  if (flags.write_neighbors)
-    out << "component \"neighbors\" value \"neighbors\"" << '\n';
-
-  if (true)
-    {
-      std::time_t  time1= std::time (0);
-      std::tm     *time = std::localtime(&time1);
-      out << "attribute \"created\" string \""
-          << time->tm_year+1900 << "/"
-          << time->tm_mon+1 << "/"
-          << time->tm_mday
-          << ' '
-          << time->tm_hour << ":"
-          << std::setw(2) << time->tm_min << ":"
-          << std::setw(2) << time->tm_sec << '"' << '\n';
-    }
-
-  out << "end" << '\n';
-  // Write all binary data now
-  if (flags.coordinates_binary)
-    write_nodes(patches, dx_out);
-  if (flags.int_binary)
-    write_cells(patches, dx_out);
-  if (flags.data_binary)
-    write_data(patches, n_data_sets, flags.data_double, dx_out);
-
-  // make sure everything now gets to
-  // disk
-  out.flush ();
-
-  // assert the stream is still ok
-  AssertThrow (out, ExcIO());
-}
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+    // start with vertices order is
+    // lexicographical, x varying
+    // fastest
+    out << "object \"vertices\" class array type float rank 1 shape " << spacedim
+        << " items " << n_nodes;
 
+    if (flags.coordinates_binary)
+      {
+        out << " lsb ieee data 0" << '\n';
+        offset += n_nodes * spacedim *  sizeof(float);
+      }
+    else
+      {
+        out << " data follows" << '\n';
+        write_nodes(patches, dx_out);
+      }
 
+    ///////////////////////////////
+    // first write the coordinates of all vertices
 
-template <int dim, int spacedim>
-void DataOutBase::write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
-                                 const std::vector<std::string>          &data_names,
-                                 const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                                 const GnuplotFlags                      &/*flags*/,
-                                 std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+    /////////////////////////////////////////
+    // write cells
+    out << "object \"cells\" class array type int rank 1 shape "
+        << GeometryInfo<dim>::vertices_per_cell
+        << " items " << n_cells;
 
-#ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
-#else
-  if (patches.size() == 0)
-    return;
-#endif
+    if (flags.int_binary)
+      {
+        out << " lsb binary data " << offset << '\n';
+        offset += n_cells * sizeof (int);
+      }
+    else
+      {
+        out << " data follows" << '\n';
+        write_cells(patches, dx_out);
+        out << '\n';
+      }
 
-  const unsigned int n_data_sets = data_names.size();
 
-  // write preamble
-  if (true)
-    {
-      // block this to have local
-      // variables destroyed after
-      // use
-      const std::time_t  time1= std::time (0);
-      const std::tm     *time = std::localtime(&time1);
-      out << "# This file was generated by the deal.II library." << '\n'
-          << "# Date =  "
-          << time->tm_year+1900 << "/"
-          << time->tm_mon+1 << "/"
-          << time->tm_mday << '\n'
-          << "# Time =  "
-          << time->tm_hour << ":"
-          << std::setw(2) << time->tm_min << ":"
-          << std::setw(2) << time->tm_sec << '\n'
-          << "#" << '\n'
-          << "# For a description of the GNUPLOT format see the GNUPLOT manual."
-          << '\n'
-          << "#" << '\n'
-          << "# ";
+    out << "attribute \"element type\" string \"";
+    if (dim==1) out << "lines";
+    if (dim==2) out << "quads";
+    if (dim==3) out << "cubes";
+    out << "\"" << '\n'
+        << "attribute \"ref\" string \"positions\"" << '\n';
 
-      switch (spacedim)
-        {
-        case 1:
-          out << "<x> ";
-          break;
-        case 2:
-          out << "<x> <y> ";
-          break;
-        case 3:
-          out << "<x> <y> <z> ";
-          break;
+//TODO:[GK] Patches must be of same size!
+    /////////////////////////////
+    // write neighbor information
+    if (flags.write_neighbors)
+      {
+        out << "object \"neighbors\" class array type int rank 1 shape "
+            << GeometryInfo<dim>::faces_per_cell
+            << " items " << n_cells
+            << " data follows";
+
+        for (typename std::vector<Patch<dim,spacedim> >::const_iterator
+             patch=patches.begin();
+             patch!=patches.end(); ++patch)
+          {
+            const unsigned int n = patch->n_subdivisions;
+            const unsigned int n1 = (dim>0) ? n : 1;
+            const unsigned int n2 = (dim>1) ? n : 1;
+            const unsigned int n3 = (dim>2) ? n : 1;
+            unsigned int cells_per_patch = Utilities::fixed_power<dim>(n);
+            unsigned int dx = 1;
+            unsigned int dy = n;
+            unsigned int dz = n*n;
+
+            const unsigned int patch_start = patch->patch_index * cells_per_patch;
+
+            for (unsigned int i3=0; i3<n3; ++i3)
+              for (unsigned int i2=0; i2<n2; ++i2)
+                for (unsigned int i1=0; i1<n1; ++i1)
+                  {
+                    const unsigned int nx = i1*dx;
+                    const unsigned int ny = i2*dy;
+                    const unsigned int nz = i3*dz;
+
+                    out << '\n';
+                    // Direction -x
+                    // Last cell in row
+                    // of other patch
+                    if (i1==0)
+                      {
+                        const unsigned int nn = patch->neighbors[0];
+                        out << '\t';
+                        if (nn != patch->no_neighbor)
+                          out << (nn*cells_per_patch+ny+nz+dx*(n-1));
+                        else
+                          out << "-1";
+                      }
+                    else
+                      {
+                        out << '\t'
+                            << patch_start+nx-dx+ny+nz;
+                      }
+                    // Direction +x
+                    // First cell in row
+                    // of other patch
+                    if (i1 == n-1)
+                      {
+                        const unsigned int nn = patch->neighbors[1];
+                        out << '\t';
+                        if (nn != patch->no_neighbor)
+                          out << (nn*cells_per_patch+ny+nz);
+                        else
+                          out << "-1";
+                      }
+                    else
+                      {
+                        out << '\t'
+                            << patch_start+nx+dx+ny+nz;
+                      }
+                    if (dim<2)
+                      continue;
+                    // Direction -y
+                    if (i2==0)
+                      {
+                        const unsigned int nn = patch->neighbors[2];
+                        out << '\t';
+                        if (nn != patch->no_neighbor)
+                          out << (nn*cells_per_patch+nx+nz+dy*(n-1));
+                        else
+                          out << "-1";
+                      }
+                    else
+                      {
+                        out << '\t'
+                            << patch_start+nx+ny-dy+nz;
+                      }
+                    // Direction +y
+                    if (i2 == n-1)
+                      {
+                        const unsigned int nn = patch->neighbors[3];
+                        out << '\t';
+                        if (nn != patch->no_neighbor)
+                          out << (nn*cells_per_patch+nx+nz);
+                        else
+                          out << "-1";
+                      }
+                    else
+                      {
+                        out << '\t'
+                            << patch_start+nx+ny+dy+nz;
+                      }
+                    if (dim<3)
+                      continue;
+
+                    // Direction -z
+                    if (i3==0)
+                      {
+                        const unsigned int nn = patch->neighbors[4];
+                        out << '\t';
+                        if (nn != patch->no_neighbor)
+                          out << (nn*cells_per_patch+nx+ny+dz*(n-1));
+                        else
+                          out << "-1";
+                      }
+                    else
+                      {
+                        out << '\t'
+                            << patch_start+nx+ny+nz-dz;
+                      }
+                    // Direction +z
+                    if (i3 == n-1)
+                      {
+                        const unsigned int nn = patch->neighbors[5];
+                        out << '\t';
+                        if (nn != patch->no_neighbor)
+                          out << (nn*cells_per_patch+nx+ny);
+                        else
+                          out << "-1";
+                      }
+                    else
+                      {
+                        out << '\t'
+                            << patch_start+nx+ny+nz+dz;
+                      }
+                  }
+            out << '\n';
+          }
+      }
+    /////////////////////////////
+    // now write data
+    if (n_data_sets != 0)
+      {
+        out << "object \"data\" class array type float rank 1 shape "
+            << n_data_sets
+            << " items " << n_nodes;
 
-        default:
-          Assert (false, ExcNotImplemented());
-        }
+        if (flags.data_binary)
+          {
+            out << " lsb ieee data " << offset << '\n';
+            offset += n_data_sets * n_nodes * ((flags.data_double)
+                                               ? sizeof(double)
+                                               : sizeof(float));
+          }
+        else
+          {
+            out << " data follows" << '\n';
+            write_data(patches, n_data_sets, flags.data_double, dx_out);
+          }
 
-      for (unsigned int i=0; i<data_names.size(); ++i)
-        out << '<' << data_names[i] << "> ";
-      out << '\n';
-    }
+        // loop over all patches
+        out << "attribute \"dep\" string \"positions\"" << '\n';
+      }
+    else
+      {
+        out << "object \"data\" class constantarray type float rank 0 items " << n_nodes << " data follows"
+            << '\n' << '0' << '\n';
+      }
 
+    // no model data
 
-  // loop over all patches
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-       patch != patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      // Length of loops in all dimensions
-      const unsigned int n1 = (dim>0) ? n : 1;
-      const unsigned int n2 = (dim>1) ? n : 1;
-      const unsigned int n3 = (dim>2) ? n : 1;
-      unsigned int d1 = 1;
-      unsigned int d2 = n;
-      unsigned int d3 = n*n;
-
-      Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
-              (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
-              ExcDimensionMismatch (patch->points_are_available
-                                    ?
-                                    (n_data_sets + spacedim)
-                                    :
-                                    n_data_sets,
-                                    patch->data.n_rows()));
-      Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
-              ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
-      Point<spacedim> this_point;
-      Point<spacedim> node;
-      if (dim<3)
-        {
-          for (unsigned int i2=0; i2<n2; ++i2)
-            {
-              for (unsigned int i1=0; i1<n1; ++i1)
-                {
-                  // compute coordinates for
-                  // this patch point
-                  compute_node(node, &*patch, i1, i2, 0, n_subdivisions);
-                  out << node << ' ';
+    out << "object \"deal data\" class field" << '\n'
+        << "component \"positions\" value \"vertices\"" << '\n'
+        << "component \"connections\" value \"cells\"" << '\n'
+        << "component \"data\" value \"data\"" << '\n';
 
-                  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                    out << patch->data(data_set,i1*d1+i2*d2) << ' ';
-                  out << '\n';
-                }
-              // end of row in patch
-              if (dim>1)
-                out << '\n';
-            }
-          // end of patch
-          if (dim==1)
-            out << '\n';
-          out << '\n';
-        }
-      else if (dim==3)
-        {
-          // for all grid points: draw
-          // lines into all positive
-          // coordinate directions if
-          // there is another grid point
-          // there
-          for (unsigned int i3=0; i3<n3; ++i3)
-            for (unsigned int i2=0; i2<n2; ++i2)
-              for (unsigned int i1=0; i1<n1; ++i1)
-                {
-                  // compute coordinates for
-                  // this patch point
-                  compute_node(this_point, &*patch, i1, i2, i3, n_subdivisions);
-                  // line into positive x-direction
-                  // if possible
-                  if (i1 < n_subdivisions)
-                    {
-                      // write point here
-                      // and its data
-                      out << this_point;
-                      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                        out  << ' '
-                             << patch->data(data_set,i1*d1+i2*d2+i3*d3);
-                      out << '\n';
-
-                      // write point there
-                      // and its data
-                      compute_node(node, &*patch, i1+1, i2, i3, n_subdivisions);
-                      out << node;
-
-                      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                        out  << ' '
-                             << patch->data(data_set,(i1+1)*d1+i2*d2+i3*d3);
-                      out << '\n';
-
-                      // end of line
-                      out << '\n'
-                          << '\n';
-                    }
+    if (flags.write_neighbors)
+      out << "component \"neighbors\" value \"neighbors\"" << '\n';
 
-                  // line into positive y-direction
-                  // if possible
-                  if (i2 < n_subdivisions)
-                    {
-                      // write point here
-                      // and its data
-                      out << this_point;
-                      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                        out  << ' '
-                             << patch->data(data_set, i1*d1+i2*d2+i3*d3);
-                      out << '\n';
-
-                      // write point there
-                      // and its data
-                      compute_node(node, &*patch, i1, i2+1, i3, n_subdivisions);
-                      out << node;
-
-                      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                        out  << ' '
-                             << patch->data(data_set,i1*d1+(i2+1)*d2+i3*d3);
-                      out << '\n';
-
-                      // end of line
-                      out << '\n'
-                          << '\n';
-                    }
+    if (true)
+      {
+        std::time_t  time1= std::time (0);
+        std::tm     *time = std::localtime(&time1);
+        out << "attribute \"created\" string \""
+            << time->tm_year+1900 << "/"
+            << time->tm_mon+1 << "/"
+            << time->tm_mday
+            << ' '
+            << time->tm_hour << ":"
+            << std::setw(2) << time->tm_min << ":"
+            << std::setw(2) << time->tm_sec << '"' << '\n';
+      }
 
-                  // line into positive z-direction
-                  // if possible
-                  if (i3 < n_subdivisions)
-                    {
-                      // write point here
-                      // and its data
-                      out << this_point;
-                      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                        out  << ' '
-                             << patch->data(data_set,i1*d1+i2*d2+i3*d3);
-                      out << '\n';
-
-                      // write point there
-                      // and its data
-                      compute_node(node, &*patch, i1, i2, i3+1, n_subdivisions);
-                      out << node;
-
-                      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                        out  << ' '
-                             << patch->data(data_set,i1*d1+i2*d2+(i3+1)*d3);
-                      out << '\n';
-                      // end of line
-                      out << '\n'
-                          << '\n';
-                    }
+    out << "end" << '\n';
+    // Write all binary data now
+    if (flags.coordinates_binary)
+      write_nodes(patches, dx_out);
+    if (flags.int_binary)
+      write_cells(patches, dx_out);
+    if (flags.data_binary)
+      write_data(patches, n_data_sets, flags.data_double, dx_out);
 
-                }
-        }
-      else
-        Assert (false, ExcNotImplemented());
-    }
-  // make sure everything now gets to
-  // disk
-  out.flush ();
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
-  AssertThrow (out, ExcIO());
-}
+    // assert the stream is still ok
+    AssertThrow (out, ExcIO());
+  }
 
 
 
-template <int dim, int spacedim>
-void DataOutBase::write_povray (const std::vector<Patch<dim,spacedim> > &patches,
-                                const std::vector<std::string>          &data_names,
-                                const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                                const PovrayFlags                       &flags,
-                                std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+  template <int dim, int spacedim>
+  void write_gnuplot (const std::vector<Patch<dim,spacedim> > &patches,
+                      const std::vector<std::string>          &data_names,
+                      const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                      const GnuplotFlags                      &/*flags*/,
+                      std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
 
 #ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
 #else
-  if (patches.size() == 0)
-    return;
+    if (patches.size() == 0)
+      return;
 #endif
-  Assert (dim==2, ExcNotImplemented());        // only for 2-D surfaces on a 2-D plane
-  Assert (spacedim==2, ExcNotImplemented());
-
-  const unsigned int n_data_sets = data_names.size();
-
-  // write preamble
-  if (true)
-    {
-      // block this to have local
-      // variables destroyed after use
-      const std::time_t  time1= std::time (0);
-      const std::tm     *time = std::localtime(&time1);
-      out << "/* This file was generated by the deal.II library." << '\n'
-          << "   Date =  "
-          << time->tm_year+1900 << "/"
-          << time->tm_mon+1 << "/"
-          << time->tm_mday << '\n'
-          << "   Time =  "
-          << time->tm_hour << ":"
-          << std::setw(2) << time->tm_min << ":"
-          << std::setw(2) << time->tm_sec << '\n'
-          << '\n'
-          << "   For a description of the POVRAY format see the POVRAY manual."
-          << '\n'
-          << "*/ " << '\n';
 
-      // include files
-      out << "#include \"colors.inc\" " << '\n'
-          << "#include \"textures.inc\" " << '\n';
+    const unsigned int n_data_sets = data_names.size();
 
+    // write preamble
+    if (true)
+      {
+        // block this to have local
+        // variables destroyed after
+        // use
+        const std::time_t  time1= std::time (0);
+        const std::tm     *time = std::localtime(&time1);
+        out << "# This file was generated by the deal.II library." << '\n'
+            << "# Date =  "
+            << time->tm_year+1900 << "/"
+            << time->tm_mon+1 << "/"
+            << time->tm_mday << '\n'
+            << "# Time =  "
+            << time->tm_hour << ":"
+            << std::setw(2) << time->tm_min << ":"
+            << std::setw(2) << time->tm_sec << '\n'
+            << "#" << '\n'
+            << "# For a description of the GNUPLOT format see the GNUPLOT manual."
+            << '\n'
+            << "#" << '\n'
+            << "# ";
 
-      // use external include file for textures,
-      // camera and light
-      if (flags.external_data)
-        out << "#include \"data.inc\" " << '\n';
-      else                          // all definitions in data file
-        {
-          // camera
-          out << '\n' << '\n'
-              << "camera {"            << '\n'
-              << "  location <1,4,-7>" << '\n'
-              << "  look_at <0,0,0>"   << '\n'
-              << "  angle 30"          << '\n'
-              << "}"                   << '\n';
-
-          // light
-          out << '\n'
-              << "light_source {"      << '\n'
-              << "  <1,4,-7>"      << '\n'
-              << "  color Grey"        << '\n'
-              << "}"                   << '\n';
-          out << '\n'
-              << "light_source {"      << '\n'
-              << "  <0,20,0>"      << '\n'
-              << "  color White"       << '\n'
-              << "}"                   << '\n';
-        }
-    }
-
-  // max. and min. heigth of solution
-  typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-  Assert(patch!=patches.end(), ExcInternalError());
-  double hmin=patch->data(0,0);
-  double hmax=patch->data(0,0);
-
-  for (; patch != patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-
-      Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
-              (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
-              ExcDimensionMismatch (patch->points_are_available
-                                    ?
-                                    (n_data_sets + spacedim)
-                                    :
-                                    n_data_sets,
-                                    patch->data.n_rows()));
-      Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
-              ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
-      for (unsigned int i=0; i<n_subdivisions+1; ++i)
-        for (unsigned int j=0; j<n_subdivisions+1; ++j)
+        switch (spacedim)
           {
-            const int dl = i*(n_subdivisions+1)+j;
-            if (patch->data(0,dl)<hmin)
-              hmin=patch->data(0,dl);
-            if (patch->data(0,dl)>hmax)
-              hmax=patch->data(0,dl);
-          }
-    }
-
-  out << "#declare HMIN=" << hmin << ";" << '\n'
-      << "#declare HMAX=" << hmax << ";" << '\n' << '\n';
-
-  if (!flags.external_data)
-    {
-      // texture with scaled niveau lines
-      // 10 lines in the surface
-      out << "#declare Tex=texture{" << '\n'
-          << "  pigment {" << '\n'
-          << "    gradient y" << '\n'
-          << "    scale y*(HMAX-HMIN)*" << 0.1 << '\n'
-          << "    color_map {" << '\n'
-          << "      [0.00 color Light_Purple] " << '\n'
-          << "      [0.95 color Light_Purple] " << '\n'
-          << "      [1.00 color White]    " << '\n'
-          << "} } }" << '\n' << '\n';
-    }
-
-  if (!flags.bicubic_patch)
-    {
-      // start of mesh header
-      out << '\n'
-          << "mesh {" << '\n';
-    }
+          case 1:
+            out << "<x> ";
+            break;
+          case 2:
+            out << "<x> <y> ";
+            break;
+          case 3:
+            out << "<x> <y> <z> ";
+            break;
 
-  // loop over all patches
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-       patch != patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      const unsigned int d1=1;
-      const unsigned int d2=n;
-
-      Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
-              (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
-              ExcDimensionMismatch (patch->points_are_available
-                                    ?
-                                    (n_data_sets + spacedim)
-                                    :
-                                    n_data_sets,
-                                    patch->data.n_rows()));
-      Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
-              ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
-
-      std::vector<Point<spacedim> > ver(n*n);
-
-      for (unsigned int i2=0; i2<n; ++i2)
-        for (unsigned int i1=0; i1<n; ++i1)
-          {
-            // compute coordinates for
-            // this patch point, storing in ver
-            compute_node(ver[i1*d1+i2*d2], &*patch, i1, i2, 0, n_subdivisions);
+          default:
+            Assert (false, ExcNotImplemented());
           }
 
+        for (unsigned int i=0; i<data_names.size(); ++i)
+          out << '<' << data_names[i] << "> ";
+        out << '\n';
+      }
 
-      if (!flags.bicubic_patch)
-        {
-          // approximate normal
-          // vectors in patch
-          std::vector<Point<3> > nrml;
-          // only if smooth triangles are used
-          if (flags.smooth)
-            {
-              nrml.resize(n*n);
-              // These are
-              // difference
-              // quotients of
-              // the surface
-              // mapping. We
-              // take them
-              // symmetric
-              // inside the
-              // patch and
-              // one-sided at
-              // the edges
-              Point<3> h1,h2;
-              // Now compute normals in every point
-              for (unsigned int i=0; i<n; ++i)
-                for (unsigned int j=0; j<n; ++j)
-                  {
-                    const unsigned int il = (i==0) ? i : (i-1);
-                    const unsigned int ir = (i==n_subdivisions) ? i : (i+1);
-                    const unsigned int jl = (j==0) ? j : (j-1);
-                    const unsigned int jr = (j==n_subdivisions) ? j : (j+1);
-
-                    h1(0)=ver[ir*d1+j*d2](0) - ver[il*d1+j*d2](0);
-                    h1(1)=patch->data(0,ir*d1+j*d2)-
-                          patch->data(0,il*d1+j*d2);
-                    h1(2)=ver[ir*d1+j*d2](1) - ver[il*d1+j*d2](1);
-
-                    h2(0)=ver[i*d1+jr*d2](0) - ver[i*d1+jl*d2](0);
-                    h2(1)=patch->data(0,i*d1+jr*d2)-
-                          patch->data(0,i*d1+jl*d2);
-                    h2(2)=ver[i*d1+jr*d2](1) - ver[i*d1+jl*d2](1);
-
-                    nrml[i*d1+j*d2](0)=h1(1)*h2(2)-h1(2)*h2(1);
-                    nrml[i*d1+j*d2](1)=h1(2)*h2(0)-h1(0)*h2(2);
-                    nrml[i*d1+j*d2](2)=h1(0)*h2(1)-h1(1)*h2(0);
-
-                    // normalize Vector
-                    double norm=std::sqrt(
-                                  std::pow(nrml[i*d1+j*d2](0),2.)+
-                                  std::pow(nrml[i*d1+j*d2](1),2.)+
-                                  std::pow(nrml[i*d1+j*d2](2),2.));
-
-                    if (nrml[i*d1+j*d2](1)<0)
-                      norm*=-1.;
-
-                    for (unsigned int k=0; k<3; ++k)
-                      nrml[i*d1+j*d2](k)/=norm;
-                  }
-            }
 
-          // setting up triangles
-          for (unsigned int i=0; i<n_subdivisions; ++i)
-            for (unsigned int j=0; j<n_subdivisions; ++j)
+    // loop over all patches
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+         patch != patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        // Length of loops in all dimensions
+        const unsigned int n1 = (dim>0) ? n : 1;
+        const unsigned int n2 = (dim>1) ? n : 1;
+        const unsigned int n3 = (dim>2) ? n : 1;
+        unsigned int d1 = 1;
+        unsigned int d2 = n;
+        unsigned int d3 = n*n;
+
+        Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+                (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+                ExcDimensionMismatch (patch->points_are_available
+                                      ?
+                                      (n_data_sets + spacedim)
+                                      :
+                                      n_data_sets,
+                                      patch->data.n_rows()));
+        Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
+                ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+        Point<spacedim> this_point;
+        Point<spacedim> node;
+        if (dim<3)
+          {
+            for (unsigned int i2=0; i2<n2; ++i2)
               {
-                // down/left vertex of triangle
-                const int dl = i*d1+j*d2;
-                if (flags.smooth)
-                  {
-                    // writing smooth_triangles
-
-                    // down/right triangle
-                    out << "smooth_triangle {" << '\n' << "\t<"
-                        << ver[dl](0) << ","
-                        << patch->data(0,dl) << ","
-                        << ver[dl](1) << ">, <"
-                        << nrml[dl](0) << ", "
-                        << nrml[dl](1) << ", "
-                        << nrml[dl](2)
-                        << ">," << '\n';
-                    out << " \t<"
-                        << ver[dl+d1](0) << ","
-                        << patch->data(0,dl+d1)  << ","
-                        << ver[dl+d1](1) << ">, <"
-                        << nrml[dl+d1](0) << ", "
-                        << nrml[dl+d1](1) << ", "
-                        << nrml[dl+d1](2)
-                        << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d1+d2](0) << ","
-                        << patch->data(0,dl+d1+d2)  << ","
-                        << ver[dl+d1+d2](1) << ">, <"
-                        << nrml[dl+d1+d2](0) << ", "
-                        << nrml[dl+d1+d2](1) << ", "
-                        << nrml[dl+d1+d2](2)
-                        << ">}" << '\n';
-
-                    // upper/left triangle
-                    out << "smooth_triangle {" << '\n' << "\t<"
-                        << ver[dl](0) << ","
-                        << patch->data(0,dl) << ","
-                        << ver[dl](1) << ">, <"
-                        << nrml[dl](0) << ", "
-                        << nrml[dl](1) << ", "
-                        << nrml[dl](2)
-                        << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d1+d2](0) << ","
-                        << patch->data(0,dl+d1+d2)  << ","
-                        << ver[dl+d1+d2](1) << ">, <"
-                        << nrml[dl+d1+d2](0) << ", "
-                        << nrml[dl+d1+d2](1) << ", "
-                        << nrml[dl+d1+d2](2)
-                        << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d2](0) << ","
-                        << patch->data(0,dl+d2)  << ","
-                        << ver[dl+d2](1) << ">, <"
-                        << nrml[dl+d2](0) << ", "
-                        << nrml[dl+d2](1) << ", "
-                        << nrml[dl+d2](2)
-                        << ">}" << '\n';
-                  }
-                else
+                for (unsigned int i1=0; i1<n1; ++i1)
                   {
-                    // writing standard triangles
-                    // down/right triangle
-                    out << "triangle {" << '\n' << "\t<"
-                        << ver[dl](0) << ","
-                        << patch->data(0,dl) << ","
-                        << ver[dl](1) << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d1](0) << ","
-                        << patch->data(0,dl+d1)  << ","
-                        << ver[dl+d1](1) << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d1+d2](0) << ","
-                        << patch->data(0,dl+d1+d2)  << ","
-                        << ver[dl+d1+d2](1) << ">}" << '\n';
-
-                    // upper/left triangle
-                    out << "triangle {" << '\n' << "\t<"
-                        << ver[dl](0) << ","
-                        << patch->data(0,dl) << ","
-                        << ver[dl](1) << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d1+d2](0) << ","
-                        << patch->data(0,dl+d1+d2)  << ","
-                        << ver[dl+d1+d2](1) << ">," << '\n';
-                    out << "\t<"
-                        << ver[dl+d2](0) << ","
-                        << patch->data(0,dl+d2)  << ","
-                        << ver[dl+d2](1) << ">}" << '\n';
+                    // compute coordinates for
+                    // this patch point
+                    compute_node(node, &*patch, i1, i2, 0, n_subdivisions);
+                    out << node << ' ';
+
+                    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                      out << patch->data(data_set,i1*d1+i2*d2) << ' ';
+                    out << '\n';
                   }
+                // end of row in patch
+                if (dim>1)
+                  out << '\n';
               }
-        }
-      else
-        {
-          // writing bicubic_patch
-          Assert (n_subdivisions==3, ExcDimensionMismatch(n_subdivisions,3));
-          out << '\n'
-              << "bicubic_patch {" << '\n'
-              << "  type 0" << '\n'
-              << "  flatness 0" << '\n'
-              << "  u_steps 0" << '\n'
-              << "  v_steps 0" << '\n';
-          for (int i=0; i<16; ++i)
-            {
-              out << "\t<" << ver[i](0) << "," << patch->data(0,i) << "," << ver[i](1) << ">";
-              if (i!=15) out << ",";
+            // end of patch
+            if (dim==1)
               out << '\n';
-            }
-          out << "  texture {Tex}" <<  '\n'
-              << "}" << '\n';
-        }
-    }
-
-  if (!flags.bicubic_patch)
-    {
-      // the end of the mesh
-      out << "  texture {Tex}" << '\n'
-          << "}" << '\n'
-          << '\n';
-    }
+            out << '\n';
+          }
+        else if (dim==3)
+          {
+            // for all grid points: draw
+            // lines into all positive
+            // coordinate directions if
+            // there is another grid point
+            // there
+            for (unsigned int i3=0; i3<n3; ++i3)
+              for (unsigned int i2=0; i2<n2; ++i2)
+                for (unsigned int i1=0; i1<n1; ++i1)
+                  {
+                    // compute coordinates for
+                    // this patch point
+                    compute_node(this_point, &*patch, i1, i2, i3, n_subdivisions);
+                    // line into positive x-direction
+                    // if possible
+                    if (i1 < n_subdivisions)
+                      {
+                        // write point here
+                        // and its data
+                        out << this_point;
+                        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                          out  << ' '
+                               << patch->data(data_set,i1*d1+i2*d2+i3*d3);
+                        out << '\n';
+
+                        // write point there
+                        // and its data
+                        compute_node(node, &*patch, i1+1, i2, i3, n_subdivisions);
+                        out << node;
+
+                        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                          out  << ' '
+                               << patch->data(data_set,(i1+1)*d1+i2*d2+i3*d3);
+                        out << '\n';
+
+                        // end of line
+                        out << '\n'
+                            << '\n';
+                      }
+
+                    // line into positive y-direction
+                    // if possible
+                    if (i2 < n_subdivisions)
+                      {
+                        // write point here
+                        // and its data
+                        out << this_point;
+                        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                          out  << ' '
+                               << patch->data(data_set, i1*d1+i2*d2+i3*d3);
+                        out << '\n';
+
+                        // write point there
+                        // and its data
+                        compute_node(node, &*patch, i1, i2+1, i3, n_subdivisions);
+                        out << node;
+
+                        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                          out  << ' '
+                               << patch->data(data_set,i1*d1+(i2+1)*d2+i3*d3);
+                        out << '\n';
+
+                        // end of line
+                        out << '\n'
+                            << '\n';
+                      }
+
+                    // line into positive z-direction
+                    // if possible
+                    if (i3 < n_subdivisions)
+                      {
+                        // write point here
+                        // and its data
+                        out << this_point;
+                        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                          out  << ' '
+                               << patch->data(data_set,i1*d1+i2*d2+i3*d3);
+                        out << '\n';
+
+                        // write point there
+                        // and its data
+                        compute_node(node, &*patch, i1, i2, i3+1, n_subdivisions);
+                        out << node;
+
+                        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                          out  << ' '
+                               << patch->data(data_set,i1*d1+i2*d2+(i3+1)*d3);
+                        out << '\n';
+                        // end of line
+                        out << '\n'
+                            << '\n';
+                      }
 
-  // make sure everything now gets to
-  // disk
-  out.flush ();
+                  }
+          }
+        else
+          Assert (false, ExcNotImplemented());
+      }
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
-  AssertThrow (out, ExcIO());
-}
+    AssertThrow (out, ExcIO());
+  }
 
 
 
-template <int dim, int spacedim>
-void DataOutBase::write_eps (const std::vector<Patch<dim,spacedim> > &patches,
-                             const std::vector<std::string>          &/*data_names*/,
-                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                             const EpsFlags                          &flags,
-                             std::ostream                            &out)
-{
-  Assert (out, ExcIO());
+  template <int dim, int spacedim>
+  void write_povray (const std::vector<Patch<dim,spacedim> > &patches,
+                     const std::vector<std::string>          &data_names,
+                     const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                     const PovrayFlags                       &flags,
+                     std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
 
 #ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
 #else
-  if (patches.size() == 0)
-    return;
+    if (patches.size() == 0)
+      return;
 #endif
+    Assert (dim==2, ExcNotImplemented());        // only for 2-D surfaces on a 2-D plane
+    Assert (spacedim==2, ExcNotImplemented());
 
-  // Do not allow volume rendering
-  AssertThrow (dim==2, ExcNotImplemented());
-
-  const unsigned int old_precision = out.precision();
-
-  // set up an array of cells to be
-  // written later. this array holds the
-  // cells of all the patches as
-  // projected to the plane perpendicular
-  // to the line of sight.
-  //
-  // note that they are kept sorted by
-  // the set, where we chose the value
-  // of the center point of the cell
-  // along the line of sight as value
-  // for sorting
-  std::multiset<EpsCell2d> cells;
-
-  // two variables in which we
-  // will store the minimum and
-  // maximum values of the field
-  // to be used for colorization
-  //
-  // preset them by 0 to calm down the
-  // compiler; they are initialized later
-  double min_color_value=0, max_color_value=0;
-
-  // Array for z-coordinates of points.
-  // The elevation determined by a function if spacedim=2
-  // or the z-cooridate of the grid point if spacedim=3
-  double heights[4] = { 0, 0, 0, 0 };
-
-  // compute the cells for output and
-  // enter them into the set above
-  // note that since dim==2, we
-  // have exactly four vertices per
-  // patch and per cell
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-       patch!=patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      const unsigned int d1 = 1;
-      const unsigned int d2 = n;
-
-      for (unsigned int i2=0; i2<n_subdivisions; ++i2)
-        for (unsigned int i1=0; i1<n_subdivisions; ++i1)
-          {
-            Point<spacedim> points[4];
-            compute_node(points[0], &*patch, i1, i2, 0, n_subdivisions);
-            compute_node(points[1], &*patch, i1+1, i2, 0, n_subdivisions);
-            compute_node(points[2], &*patch, i1, i2+1, 0, n_subdivisions);
-            compute_node(points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
-            switch (spacedim)
-              {
-              case 2:
-                Assert ((flags.height_vector < patch->data.n_rows()) ||
-                        patch->data.n_rows() == 0,
-                        ExcIndexRange (flags.height_vector, 0,
-                                       patch->data.n_rows()));
-                heights[0] = patch->data.n_rows() != 0 ?
-                             patch->data(flags.height_vector,i1*d1 + i2*d2) * flags.z_scaling
-                             : 0;
-                heights[1] = patch->data.n_rows() != 0 ?
-                             patch->data(flags.height_vector,(i1+1)*d1 + i2*d2) * flags.z_scaling
-                             : 0;
-                heights[2] = patch->data.n_rows() != 0 ?
-                             patch->data(flags.height_vector,i1*d1 + (i2+1)*d2) * flags.z_scaling
-                             : 0;
-                heights[3] = patch->data.n_rows() != 0 ?
-                             patch->data(flags.height_vector,(i1+1)*d1 + (i2+1)*d2) * flags.z_scaling
-                             : 0;
-
-                break;
-              case 3:
-                // Copy z-coordinates into the height vector
-                for (unsigned int i=0; i<4; ++i)
-                  heights[i] = points[i](2);
-                break;
-              default:
-                Assert(false, ExcNotImplemented());
-              }
-
-
-            // now compute the projection of
-            // the bilinear cell given by the
-            // four vertices and their heights
-            // and write them to a proper
-            // cell object. note that we only
-            // need the first two components
-            // of the projected position for
-            // output, but we need the value
-            // along the line of sight for
-            // sorting the cells for back-to-
-            // front-output
-            //
-            // this computation was first written
-            // by Stefan Nauber. please no-one
-            // ask me why it works that way (or
-            // may be not), especially not about
-            // the angles and the sign of
-            // the height field, I don't know
-            // it.
-            EpsCell2d eps_cell;
-            const double pi = numbers::PI;
-            const double cx = -std::cos(pi-flags.azimut_angle * 2*pi / 360.),
-                         cz = -std::cos(flags.turn_angle * 2*pi / 360.),
-                         sx = std::sin(pi-flags.azimut_angle * 2*pi / 360.),
-                         sz = std::sin(flags.turn_angle * 2*pi / 360.);
-            for (unsigned int vertex=0; vertex<4; ++vertex)
-              {
-                const double x = points[vertex](0),
-                             y = points[vertex](1),
-                             z = -heights[vertex];
-
-                eps_cell.vertices[vertex](0) = -   cz*x+   sz*y;
-                eps_cell.vertices[vertex](1) = -cx*sz*x-cx*cz*y-sx*z;
-
-                //      ( 1 0    0 )
-                // D1 = ( 0 cx -sx )
-                //      ( 0 sx  cx )
-
-                //      ( cy 0 sy )
-                // Dy = (  0 1  0 )
-                //      (-sy 0 cy )
-
-                //      ( cz -sz 0 )
-                // Dz = ( sz  cz 0 )
-                //      (  0   0 1 )
-
-//       ( cz -sz 0 )( 1 0    0 )(x)   ( cz*x-sz*(cx*y-sx*z)+0*(sx*y+cx*z) )
-// Dxz = ( sz  cz 0 )( 0 cx -sx )(y) = ( sz*x+cz*(cx*y-sx*z)+0*(sx*y+cx*z) )
-//       (  0   0 1 )( 0 sx  cx )(z)   (  0*x+  *(cx*y-sx*z)+1*(sx*y+cx*z) )
-              }
+    const unsigned int n_data_sets = data_names.size();
 
-            // compute coordinates of
-            // center of cell
-            const Point<spacedim> center_point
-              = (points[0] + points[1] + points[2] + points[3]) / 4;
-            const double center_height
-              = -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
+    // write preamble
+    if (true)
+      {
+        // block this to have local
+        // variables destroyed after use
+        const std::time_t  time1= std::time (0);
+        const std::tm     *time = std::localtime(&time1);
+        out << "/* This file was generated by the deal.II library." << '\n'
+            << "   Date =  "
+            << time->tm_year+1900 << "/"
+            << time->tm_mon+1 << "/"
+            << time->tm_mday << '\n'
+            << "   Time =  "
+            << time->tm_hour << ":"
+            << std::setw(2) << time->tm_min << ":"
+            << std::setw(2) << time->tm_sec << '\n'
+            << '\n'
+            << "   For a description of the POVRAY format see the POVRAY manual."
+            << '\n'
+            << "*/ " << '\n';
 
-            // compute the depth into
-            // the picture
-            eps_cell.depth = -sx*sz*center_point(0)
-                             -sx*cz*center_point(1)
-                             +cx*center_height;
+        // include files
+        out << "#include \"colors.inc\" " << '\n'
+            << "#include \"textures.inc\" " << '\n';
 
-            if (flags.draw_cells && flags.shade_cells)
-              {
-                Assert ((flags.color_vector < patch->data.n_rows()) ||
-                        patch->data.n_rows() == 0,
-                        ExcIndexRange (flags.color_vector, 0,
-                                       patch->data.n_rows()));
-                const double color_values[4]
-                  = { patch->data.n_rows() != 0 ?
-                      patch->data(flags.color_vector,i1 *d1 + i2 *d2)       : 1,
-
-                      patch->data.n_rows() != 0 ?
-                      patch->data(flags.color_vector,(i1+1)*d1 + i2 *d2)   : 1,
-
-                      patch->data.n_rows() != 0 ?
-                      patch->data(flags.color_vector,i1 *d1 + (i2+1)*d2)     : 1,
-
-                      patch->data.n_rows() != 0 ?
-                      patch->data(flags.color_vector,(i1+1)*d1 + (i2+1)*d2) : 1
-                    };
-
-                // set color value to average of the value
-                // at the vertices
-                eps_cell.color_value = (color_values[0] +
-                                        color_values[1] +
-                                        color_values[3] +
-                                        color_values[2]) / 4;
-
-                // update bounds of color
-                // field
-                if (patch == patches.begin())
-                  min_color_value = max_color_value = eps_cell.color_value;
-                else
-                  {
-                    min_color_value = (min_color_value < eps_cell.color_value ?
-                                       min_color_value : eps_cell.color_value);
-                    max_color_value = (max_color_value > eps_cell.color_value ?
-                                       max_color_value : eps_cell.color_value);
-                  }
-              }
 
-            // finally add this cell
-            cells.insert (eps_cell);
+        // use external include file for textures,
+        // camera and light
+        if (flags.external_data)
+          out << "#include \"data.inc\" " << '\n';
+        else                          // all definitions in data file
+          {
+            // camera
+            out << '\n' << '\n'
+                << "camera {"            << '\n'
+                << "  location <1,4,-7>" << '\n'
+                << "  look_at <0,0,0>"   << '\n'
+                << "  angle 30"          << '\n'
+                << "}"                   << '\n';
+
+            // light
+            out << '\n'
+                << "light_source {"      << '\n'
+                << "  <1,4,-7>"      << '\n'
+                << "  color Grey"        << '\n'
+                << "}"                   << '\n';
+            out << '\n'
+                << "light_source {"      << '\n'
+                << "  <0,20,0>"      << '\n'
+                << "  color White"       << '\n'
+                << "}"                   << '\n';
           }
-    }
-
-  // find out minimum and maximum x and
-  // y coordinates to compute offsets
-  // and scaling factors
-  double x_min = cells.begin()->vertices[0](0);
-  double x_max = x_min;
-  double y_min = cells.begin()->vertices[0](1);
-  double y_max = y_min;
-
-  for (typename std::multiset<EpsCell2d>::const_iterator
-       cell=cells.begin();
-       cell!=cells.end(); ++cell)
-    for (unsigned int vertex=0; vertex<4; ++vertex)
-      {
-        x_min = std::min (x_min, cell->vertices[vertex](0));
-        x_max = std::max (x_max, cell->vertices[vertex](0));
-        y_min = std::min (y_min, cell->vertices[vertex](1));
-        y_max = std::max (y_max, cell->vertices[vertex](1));
       }
 
-  // scale in x-direction such that
-  // in the output 0 <= x <= 300.
-  // don't scale in y-direction to
-  // preserve the shape of the
-  // triangulation
-  const double scale = (flags.size /
-                        (flags.size_type==EpsFlags::width ?
-                         x_max - x_min :
-                         y_min - y_max));
-
-  const Point<2> offset(x_min, y_min);
+    // max. and min. heigth of solution
+    typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+    Assert(patch!=patches.end(), ExcInternalError());
+    double hmin=patch->data(0,0);
+    double hmax=patch->data(0,0);
 
+    for (; patch != patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+
+        Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+                (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+                ExcDimensionMismatch (patch->points_are_available
+                                      ?
+                                      (n_data_sets + spacedim)
+                                      :
+                                      n_data_sets,
+                                      patch->data.n_rows()));
+        Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
+                ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+        for (unsigned int i=0; i<n_subdivisions+1; ++i)
+          for (unsigned int j=0; j<n_subdivisions+1; ++j)
+            {
+              const int dl = i*(n_subdivisions+1)+j;
+              if (patch->data(0,dl)<hmin)
+                hmin=patch->data(0,dl);
+              if (patch->data(0,dl)>hmax)
+                hmax=patch->data(0,dl);
+            }
+      }
 
-  // now write preamble
-  if (true)
-    {
-      // block this to have local
-      // variables destroyed after
-      // use
-      std::time_t  time1= std::time (0);
-      std::tm     *time = std::localtime(&time1);
-      out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
-          << "%%Title: deal.II Output" << '\n'
-          << "%%Creator: the deal.II library" << '\n'
-          << "%%Creation Date: "
-          << time->tm_year+1900 << "/"
-          << time->tm_mon+1 << "/"
-          << time->tm_mday << " - "
-          << time->tm_hour << ":"
-          << std::setw(2) << time->tm_min << ":"
-          << std::setw(2) << time->tm_sec << '\n'
-          << "%%BoundingBox: "
-          // lower left corner
-          << "0 0 "
-          // upper right corner
-          << static_cast<unsigned int>( (x_max-x_min) * scale + 0.5)
-          << ' '
-          << static_cast<unsigned int>( (y_max-y_min) * scale + 0.5)
-          << '\n';
-
-      // define some abbreviations to keep
-      // the output small:
-      // m=move turtle to
-      // l=define a line
-      // s=set rgb color
-      // sg=set gray value
-      // lx=close the line and plot the line
-      // lf=close the line and fill the interior
-      out << "/m {moveto} bind def"      << '\n'
-          << "/l {lineto} bind def"      << '\n'
-          << "/s {setrgbcolor} bind def" << '\n'
-          << "/sg {setgray} bind def"    << '\n'
-          << "/lx {lineto closepath stroke} bind def" << '\n'
-          << "/lf {lineto closepath fill} bind def"   << '\n';
-
-      out << "%%EndProlog" << '\n'
-          << '\n';
-      // set fine lines
-      out << flags.line_width << " setlinewidth" << '\n';
-      // allow only five digits
-      // for output (instead of the
-      // default six); this should suffice
-      // even for fine grids, but reduces
-      // the file size significantly
-      out << std::setprecision (5);
-    }
+    out << "#declare HMIN=" << hmin << ";" << '\n'
+        << "#declare HMAX=" << hmax << ";" << '\n' << '\n';
 
-  // check if min and max
-  // values for the color are
-  // actually different. If
-  // that is not the case (such
-  // things happen, for
-  // example, in the very first
-  // time step of a time
-  // dependent problem, if the
-  // initial values are zero),
-  // all values are equal, and
-  // then we can draw
-  // everything in an arbitrary
-  // color. Thus, change one of
-  // the two values arbitrarily
-  if (max_color_value == min_color_value)
-    max_color_value = min_color_value+1;
-
-  // now we've got all the information
-  // we need. write the cells.
-  // note: due to the ordering, we
-  // traverse the list of cells
-  // back-to-front
-  for (typename std::multiset<EpsCell2d>::const_iterator
-       cell=cells.begin();
-       cell!=cells.end(); ++cell)
-    {
-      if (flags.draw_cells)
-        {
-          if (flags.shade_cells)
+    if (!flags.external_data)
+      {
+        // texture with scaled niveau lines
+        // 10 lines in the surface
+        out << "#declare Tex=texture{" << '\n'
+            << "  pigment {" << '\n'
+            << "    gradient y" << '\n'
+            << "    scale y*(HMAX-HMIN)*" << 0.1 << '\n'
+            << "    color_map {" << '\n'
+            << "      [0.00 color Light_Purple] " << '\n'
+            << "      [0.95 color Light_Purple] " << '\n'
+            << "      [1.00 color White]    " << '\n'
+            << "} } }" << '\n' << '\n';
+      }
+
+    if (!flags.bicubic_patch)
+      {
+        // start of mesh header
+        out << '\n'
+            << "mesh {" << '\n';
+      }
+
+    // loop over all patches
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+         patch != patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        const unsigned int d1=1;
+        const unsigned int d2=n;
+
+        Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
+                (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
+                ExcDimensionMismatch (patch->points_are_available
+                                      ?
+                                      (n_data_sets + spacedim)
+                                      :
+                                      n_data_sets,
+                                      patch->data.n_rows()));
+        Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n),
+                ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
+
+
+        std::vector<Point<spacedim> > ver(n*n);
+
+        for (unsigned int i2=0; i2<n; ++i2)
+          for (unsigned int i1=0; i1<n; ++i1)
             {
-              const EpsFlags::RgbValues rgb_values
-                = (*flags.color_function) (cell->color_value,
-                                           min_color_value,
-                                           max_color_value);
-
-              // write out color
-              if (rgb_values.is_grey())
-                out << rgb_values.red << " sg ";
-              else
-                out << rgb_values.red   << ' '
-                    << rgb_values.green << ' '
-                    << rgb_values.blue  << " s ";
+              // compute coordinates for
+              // this patch point, storing in ver
+              compute_node(ver[i1*d1+i2*d2], &*patch, i1, i2, 0, n_subdivisions);
             }
-          else
-            out << "1 sg ";
 
-          out << (cell->vertices[0]-offset) * scale << " m "
-              << (cell->vertices[1]-offset) * scale << " l "
-              << (cell->vertices[3]-offset) * scale << " l "
-              << (cell->vertices[2]-offset) * scale << " lf"
-              << '\n';
-        }
 
-      if (flags.draw_mesh)
-        out << "0 sg "      // draw lines in black
-            << (cell->vertices[0]-offset) * scale << " m "
-            << (cell->vertices[1]-offset) * scale << " l "
-            << (cell->vertices[3]-offset) * scale << " l "
-            << (cell->vertices[2]-offset) * scale << " lx"
+        if (!flags.bicubic_patch)
+          {
+            // approximate normal
+            // vectors in patch
+            std::vector<Point<3> > nrml;
+            // only if smooth triangles are used
+            if (flags.smooth)
+              {
+                nrml.resize(n*n);
+                // These are
+                // difference
+                // quotients of
+                // the surface
+                // mapping. We
+                // take them
+                // symmetric
+                // inside the
+                // patch and
+                // one-sided at
+                // the edges
+                Point<3> h1,h2;
+                // Now compute normals in every point
+                for (unsigned int i=0; i<n; ++i)
+                  for (unsigned int j=0; j<n; ++j)
+                    {
+                      const unsigned int il = (i==0) ? i : (i-1);
+                      const unsigned int ir = (i==n_subdivisions) ? i : (i+1);
+                      const unsigned int jl = (j==0) ? j : (j-1);
+                      const unsigned int jr = (j==n_subdivisions) ? j : (j+1);
+
+                      h1(0)=ver[ir*d1+j*d2](0) - ver[il*d1+j*d2](0);
+                      h1(1)=patch->data(0,ir*d1+j*d2)-
+                            patch->data(0,il*d1+j*d2);
+                      h1(2)=ver[ir*d1+j*d2](1) - ver[il*d1+j*d2](1);
+
+                      h2(0)=ver[i*d1+jr*d2](0) - ver[i*d1+jl*d2](0);
+                      h2(1)=patch->data(0,i*d1+jr*d2)-
+                            patch->data(0,i*d1+jl*d2);
+                      h2(2)=ver[i*d1+jr*d2](1) - ver[i*d1+jl*d2](1);
+
+                      nrml[i*d1+j*d2](0)=h1(1)*h2(2)-h1(2)*h2(1);
+                      nrml[i*d1+j*d2](1)=h1(2)*h2(0)-h1(0)*h2(2);
+                      nrml[i*d1+j*d2](2)=h1(0)*h2(1)-h1(1)*h2(0);
+
+                      // normalize Vector
+                      double norm=std::sqrt(
+                                    std::pow(nrml[i*d1+j*d2](0),2.)+
+                                    std::pow(nrml[i*d1+j*d2](1),2.)+
+                                    std::pow(nrml[i*d1+j*d2](2),2.));
+
+                      if (nrml[i*d1+j*d2](1)<0)
+                        norm*=-1.;
+
+                      for (unsigned int k=0; k<3; ++k)
+                        nrml[i*d1+j*d2](k)/=norm;
+                    }
+              }
+
+            // setting up triangles
+            for (unsigned int i=0; i<n_subdivisions; ++i)
+              for (unsigned int j=0; j<n_subdivisions; ++j)
+                {
+                  // down/left vertex of triangle
+                  const int dl = i*d1+j*d2;
+                  if (flags.smooth)
+                    {
+                      // writing smooth_triangles
+
+                      // down/right triangle
+                      out << "smooth_triangle {" << '\n' << "\t<"
+                          << ver[dl](0) << ","
+                          << patch->data(0,dl) << ","
+                          << ver[dl](1) << ">, <"
+                          << nrml[dl](0) << ", "
+                          << nrml[dl](1) << ", "
+                          << nrml[dl](2)
+                          << ">," << '\n';
+                      out << " \t<"
+                          << ver[dl+d1](0) << ","
+                          << patch->data(0,dl+d1)  << ","
+                          << ver[dl+d1](1) << ">, <"
+                          << nrml[dl+d1](0) << ", "
+                          << nrml[dl+d1](1) << ", "
+                          << nrml[dl+d1](2)
+                          << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d1+d2](0) << ","
+                          << patch->data(0,dl+d1+d2)  << ","
+                          << ver[dl+d1+d2](1) << ">, <"
+                          << nrml[dl+d1+d2](0) << ", "
+                          << nrml[dl+d1+d2](1) << ", "
+                          << nrml[dl+d1+d2](2)
+                          << ">}" << '\n';
+
+                      // upper/left triangle
+                      out << "smooth_triangle {" << '\n' << "\t<"
+                          << ver[dl](0) << ","
+                          << patch->data(0,dl) << ","
+                          << ver[dl](1) << ">, <"
+                          << nrml[dl](0) << ", "
+                          << nrml[dl](1) << ", "
+                          << nrml[dl](2)
+                          << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d1+d2](0) << ","
+                          << patch->data(0,dl+d1+d2)  << ","
+                          << ver[dl+d1+d2](1) << ">, <"
+                          << nrml[dl+d1+d2](0) << ", "
+                          << nrml[dl+d1+d2](1) << ", "
+                          << nrml[dl+d1+d2](2)
+                          << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d2](0) << ","
+                          << patch->data(0,dl+d2)  << ","
+                          << ver[dl+d2](1) << ">, <"
+                          << nrml[dl+d2](0) << ", "
+                          << nrml[dl+d2](1) << ", "
+                          << nrml[dl+d2](2)
+                          << ">}" << '\n';
+                    }
+                  else
+                    {
+                      // writing standard triangles
+                      // down/right triangle
+                      out << "triangle {" << '\n' << "\t<"
+                          << ver[dl](0) << ","
+                          << patch->data(0,dl) << ","
+                          << ver[dl](1) << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d1](0) << ","
+                          << patch->data(0,dl+d1)  << ","
+                          << ver[dl+d1](1) << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d1+d2](0) << ","
+                          << patch->data(0,dl+d1+d2)  << ","
+                          << ver[dl+d1+d2](1) << ">}" << '\n';
+
+                      // upper/left triangle
+                      out << "triangle {" << '\n' << "\t<"
+                          << ver[dl](0) << ","
+                          << patch->data(0,dl) << ","
+                          << ver[dl](1) << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d1+d2](0) << ","
+                          << patch->data(0,dl+d1+d2)  << ","
+                          << ver[dl+d1+d2](1) << ">," << '\n';
+                      out << "\t<"
+                          << ver[dl+d2](0) << ","
+                          << patch->data(0,dl+d2)  << ","
+                          << ver[dl+d2](1) << ">}" << '\n';
+                    }
+                }
+          }
+        else
+          {
+            // writing bicubic_patch
+            Assert (n_subdivisions==3, ExcDimensionMismatch(n_subdivisions,3));
+            out << '\n'
+                << "bicubic_patch {" << '\n'
+                << "  type 0" << '\n'
+                << "  flatness 0" << '\n'
+                << "  u_steps 0" << '\n'
+                << "  v_steps 0" << '\n';
+            for (int i=0; i<16; ++i)
+              {
+                out << "\t<" << ver[i](0) << "," << patch->data(0,i) << "," << ver[i](1) << ">";
+                if (i!=15) out << ",";
+                out << '\n';
+              }
+            out << "  texture {Tex}" <<  '\n'
+                << "}" << '\n';
+          }
+      }
+
+    if (!flags.bicubic_patch)
+      {
+        // the end of the mesh
+        out << "  texture {Tex}" << '\n'
+            << "}" << '\n'
             << '\n';
-    }
-  out << "showpage" << '\n';
-  // make sure everything now gets to
-  // disk
-  out << std::setprecision(old_precision);
-  out.flush ();
+      }
 
-  AssertThrow (out, ExcIO());
-}
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
+    AssertThrow (out, ExcIO());
+  }
 
 
-template <int dim, int spacedim>
-void DataOutBase::write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
-                             const std::vector<std::string>          &data_names,
-                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                             const GmvFlags                          &flags,
-                             std::ostream                            &out)
-{
-  Assert(dim<=3, ExcNotImplemented());
-  AssertThrow (out, ExcIO());
+
+  template <int dim, int spacedim>
+  void write_eps (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &/*data_names*/,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                  const EpsFlags                          &flags,
+                  std::ostream                            &out)
+  {
+    Assert (out, ExcIO());
 
 #ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
 #else
-  if (patches.size() == 0)
-    return;
+    if (patches.size() == 0)
+      return;
 #endif
 
-  GmvStream gmv_out(out, flags);
-  const unsigned int n_data_sets = data_names.size();
-  // check against # of data sets in
-  // first patch. checks against all
-  // other patches are made in
-  // write_gmv_reorder_data_vectors
-  Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
-          (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
-          ExcDimensionMismatch (patches[0].points_are_available
-                                ?
-                                (n_data_sets + spacedim)
-                                :
-                                n_data_sets,
-                                patches[0].data.n_rows()));
-
-  ///////////////////////
-  // preamble
-  out << "gmvinput ascii"
-      << '\n'
-      << '\n';
-
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-
-  // in gmv format the vertex
-  // coordinates and the data have an
-  // order that is a bit unpleasant
-  // (first all x coordinates, then
-  // all y coordinate, ...; first all
-  // data of variable 1, then
-  // variable 2, etc), so we have to
-  // copy the data vectors a bit around
-  //
-  // note that we copy vectors when
-  // looping over the patches since we
-  // have to write them one variable
-  // at a time and don't want to use
-  // more than one loop
-  //
-  // this copying of data vectors can
-  // be done while we already output
-  // the vertices, so do this on a
-  // separate task and when wanting
-  // to write out the data, we wait
-  // for that task to finish
-  Table<2,double> data_vectors (n_data_sets, n_nodes);
-  void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
-                   Table<2,double> &)
-    = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
-
-  ///////////////////////////////
-  // first make up a list of used
-  // vertices along with their
-  // coordinates
-  //
-  // note that we have to print
-  // 3 dimensions
-  out << "nodes " << n_nodes << '\n';
-  for (unsigned int d=0; d<spacedim; ++d)
-    {
-      gmv_out.selected_component = d;
-      write_nodes(patches, gmv_out);
-      out << '\n';
-    }
-  gmv_out.selected_component = numbers::invalid_unsigned_int;
-
-  for (unsigned int d=spacedim; d<3; ++d)
-    {
-      for (unsigned int i=0; i<n_nodes; ++i)
-        out << "0 ";
-      out << '\n';
-    }
-
-  /////////////////////////////////
-  // now for the cells. note that
-  // vertices are counted from 1 onwards
-  out << "cells " << n_cells << '\n';
-  write_cells(patches, gmv_out);
+    // Do not allow volume rendering
+    AssertThrow (dim==2, ExcNotImplemented());
+
+    const unsigned int old_precision = out.precision();
+
+    // set up an array of cells to be
+    // written later. this array holds the
+    // cells of all the patches as
+    // projected to the plane perpendicular
+    // to the line of sight.
+    //
+    // note that they are kept sorted by
+    // the set, where we chose the value
+    // of the center point of the cell
+    // along the line of sight as value
+    // for sorting
+    std::multiset<EpsCell2d> cells;
+
+    // two variables in which we
+    // will store the minimum and
+    // maximum values of the field
+    // to be used for colorization
+    //
+    // preset them by 0 to calm down the
+    // compiler; they are initialized later
+    double min_color_value=0, max_color_value=0;
+
+    // Array for z-coordinates of points.
+    // The elevation determined by a function if spacedim=2
+    // or the z-cooridate of the grid point if spacedim=3
+    double heights[4] = { 0, 0, 0, 0 };
+
+    // compute the cells for output and
+    // enter them into the set above
+    // note that since dim==2, we
+    // have exactly four vertices per
+    // patch and per cell
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+         patch!=patches.end(); ++patch)
+      {
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        const unsigned int d1 = 1;
+        const unsigned int d2 = n;
 
-  ///////////////////////////////////////
-  // data output.
-  out << "variable" << '\n';
+        for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+          for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+            {
+              Point<spacedim> points[4];
+              compute_node(points[0], &*patch, i1, i2, 0, n_subdivisions);
+              compute_node(points[1], &*patch, i1+1, i2, 0, n_subdivisions);
+              compute_node(points[2], &*patch, i1, i2+1, 0, n_subdivisions);
+              compute_node(points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
 
-  // now write the data vectors to
-  // @p{out} first make sure that all
-  // data is in place
-  reorder_task.join ();
+              switch (spacedim)
+                {
+                case 2:
+                  Assert ((flags.height_vector < patch->data.n_rows()) ||
+                          patch->data.n_rows() == 0,
+                          ExcIndexRange (flags.height_vector, 0,
+                                         patch->data.n_rows()));
+                  heights[0] = patch->data.n_rows() != 0 ?
+                               patch->data(flags.height_vector,i1*d1 + i2*d2) * flags.z_scaling
+                               : 0;
+                  heights[1] = patch->data.n_rows() != 0 ?
+                               patch->data(flags.height_vector,(i1+1)*d1 + i2*d2) * flags.z_scaling
+                               : 0;
+                  heights[2] = patch->data.n_rows() != 0 ?
+                               patch->data(flags.height_vector,i1*d1 + (i2+1)*d2) * flags.z_scaling
+                               : 0;
+                  heights[3] = patch->data.n_rows() != 0 ?
+                               patch->data(flags.height_vector,(i1+1)*d1 + (i2+1)*d2) * flags.z_scaling
+                               : 0;
+
+                  break;
+                case 3:
+                  // Copy z-coordinates into the height vector
+                  for (unsigned int i=0; i<4; ++i)
+                    heights[i] = points[i](2);
+                  break;
+                default:
+                  Assert(false, ExcNotImplemented());
+                }
 
-  // then write data.
-  // the '1' means: node data (as opposed
-  // to cell data, which we do not
-  // support explicitly here)
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    {
-      out << data_names[data_set] << " 1" << '\n';
-      std::copy (data_vectors[data_set].begin(),
-                 data_vectors[data_set].end(),
-                 std::ostream_iterator<double>(out, " "));
-      out << '\n'
-          << '\n';
-    }
 
+              // now compute the projection of
+              // the bilinear cell given by the
+              // four vertices and their heights
+              // and write them to a proper
+              // cell object. note that we only
+              // need the first two components
+              // of the projected position for
+              // output, but we need the value
+              // along the line of sight for
+              // sorting the cells for back-to-
+              // front-output
+              //
+              // this computation was first written
+              // by Stefan Nauber. please no-one
+              // ask me why it works that way (or
+              // may be not), especially not about
+              // the angles and the sign of
+              // the height field, I don't know
+              // it.
+              EpsCell2d eps_cell;
+              const double pi = numbers::PI;
+              const double cx = -std::cos(pi-flags.azimut_angle * 2*pi / 360.),
+                           cz = -std::cos(flags.turn_angle * 2*pi / 360.),
+                           sx = std::sin(pi-flags.azimut_angle * 2*pi / 360.),
+                           sz = std::sin(flags.turn_angle * 2*pi / 360.);
+              for (unsigned int vertex=0; vertex<4; ++vertex)
+                {
+                  const double x = points[vertex](0),
+                               y = points[vertex](1),
+                               z = -heights[vertex];
 
+                  eps_cell.vertices[vertex](0) = -   cz*x+   sz*y;
+                  eps_cell.vertices[vertex](1) = -cx*sz*x-cx*cz*y-sx*z;
 
-  // end of variable section
-  out << "endvars" << '\n';
+                  //      ( 1 0    0 )
+                  // D1 = ( 0 cx -sx )
+                  //      ( 0 sx  cx )
 
-  // end of output
-  out << "endgmv"
-      << '\n';
+                  //      ( cy 0 sy )
+                  // Dy = (  0 1  0 )
+                  //      (-sy 0 cy )
 
-  // make sure everything now gets to
-  // disk
-  out.flush ();
+                  //      ( cz -sz 0 )
+                  // Dz = ( sz  cz 0 )
+                  //      (  0   0 1 )
 
-  // assert the stream is still ok
-  AssertThrow (out, ExcIO());
-}
+//       ( cz -sz 0 )( 1 0    0 )(x)   ( cz*x-sz*(cx*y-sx*z)+0*(sx*y+cx*z) )
+// Dxz = ( sz  cz 0 )( 0 cx -sx )(y) = ( sz*x+cz*(cx*y-sx*z)+0*(sx*y+cx*z) )
+//       (  0   0 1 )( 0 sx  cx )(z)   (  0*x+  *(cx*y-sx*z)+1*(sx*y+cx*z) )
+                }
 
+              // compute coordinates of
+              // center of cell
+              const Point<spacedim> center_point
+                = (points[0] + points[1] + points[2] + points[3]) / 4;
+              const double center_height
+                = -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
 
+              // compute the depth into
+              // the picture
+              eps_cell.depth = -sx*sz*center_point(0)
+                               -sx*cz*center_point(1)
+                               +cx*center_height;
 
-template <int dim, int spacedim>
-void DataOutBase::write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
-                                 const std::vector<std::string>          &data_names,
-                                 const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
-                                 const TecplotFlags                      &flags,
-                                 std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+              if (flags.draw_cells && flags.shade_cells)
+                {
+                  Assert ((flags.color_vector < patch->data.n_rows()) ||
+                          patch->data.n_rows() == 0,
+                          ExcIndexRange (flags.color_vector, 0,
+                                         patch->data.n_rows()));
+                  const double color_values[4]
+                    = { patch->data.n_rows() != 0 ?
+                        patch->data(flags.color_vector,i1 *d1 + i2 *d2)       : 1,
+
+                        patch->data.n_rows() != 0 ?
+                        patch->data(flags.color_vector,(i1+1)*d1 + i2 *d2)   : 1,
+
+                        patch->data.n_rows() != 0 ?
+                        patch->data(flags.color_vector,i1 *d1 + (i2+1)*d2)     : 1,
+
+                        patch->data.n_rows() != 0 ?
+                        patch->data(flags.color_vector,(i1+1)*d1 + (i2+1)*d2) : 1
+                      };
+
+                  // set color value to average of the value
+                  // at the vertices
+                  eps_cell.color_value = (color_values[0] +
+                                          color_values[1] +
+                                          color_values[3] +
+                                          color_values[2]) / 4;
+
+                  // update bounds of color
+                  // field
+                  if (patch == patches.begin())
+                    min_color_value = max_color_value = eps_cell.color_value;
+                  else
+                    {
+                      min_color_value = (min_color_value < eps_cell.color_value ?
+                                         min_color_value : eps_cell.color_value);
+                      max_color_value = (max_color_value > eps_cell.color_value ?
+                                         max_color_value : eps_cell.color_value);
+                    }
+                }
 
-#ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
-#else
-  if (patches.size() == 0)
-    return;
-#endif
+              // finally add this cell
+              cells.insert (eps_cell);
+            }
+      }
 
-  TecplotStream tecplot_out(out, flags);
+    // find out minimum and maximum x and
+    // y coordinates to compute offsets
+    // and scaling factors
+    double x_min = cells.begin()->vertices[0](0);
+    double x_max = x_min;
+    double y_min = cells.begin()->vertices[0](1);
+    double y_max = y_min;
+
+    for (typename std::multiset<EpsCell2d>::const_iterator
+         cell=cells.begin();
+         cell!=cells.end(); ++cell)
+      for (unsigned int vertex=0; vertex<4; ++vertex)
+        {
+          x_min = std::min (x_min, cell->vertices[vertex](0));
+          x_max = std::max (x_max, cell->vertices[vertex](0));
+          y_min = std::min (y_min, cell->vertices[vertex](1));
+          y_max = std::max (y_max, cell->vertices[vertex](1));
+        }
 
-  const unsigned int n_data_sets = data_names.size();
-  // check against # of data sets in
-  // first patch. checks against all
-  // other patches are made in
-  // write_gmv_reorder_data_vectors
-  Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
-          (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
-          ExcDimensionMismatch (patches[0].points_are_available
-                                ?
-                                (n_data_sets + spacedim)
-                                :
-                                n_data_sets,
-                                patches[0].data.n_rows()));
-
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-
-  ///////////
-  // preamble
-  {
-    std::time_t  time1= std::time (0);
-    std::tm     *time = std::localtime(&time1);
-    out << "# This file was generated by the deal.II library." << '\n'
-        << "# Date =  "
-        << time->tm_year+1900 << "/"
-        << time->tm_mon+1 << "/"
-        << time->tm_mday << '\n'
-        << "# Time =  "
-        << time->tm_hour << ":"
-        << std::setw(2) << time->tm_min << ":"
-        << std::setw(2) << time->tm_sec << '\n'
-        << "#" << '\n'
-        << "# For a description of the Tecplot format see the Tecplot documentation."
-        << '\n'
-        << "#" << '\n';
+    // scale in x-direction such that
+    // in the output 0 <= x <= 300.
+    // don't scale in y-direction to
+    // preserve the shape of the
+    // triangulation
+    const double scale = (flags.size /
+                          (flags.size_type==EpsFlags::width ?
+                           x_max - x_min :
+                           y_min - y_max));
 
+    const Point<2> offset(x_min, y_min);
 
-    out << "Variables=";
 
-    switch (spacedim)
+    // now write preamble
+    if (true)
       {
-      case 1:
-        out << "\"x\"";
-        break;
-      case 2:
-        out << "\"x\", \"y\"";
-        break;
-      case 3:
-        out << "\"x\", \"y\", \"z\"";
-        break;
-      default:
-        Assert (false, ExcNotImplemented());
-      }
+        // block this to have local
+        // variables destroyed after
+        // use
+        std::time_t  time1= std::time (0);
+        std::tm     *time = std::localtime(&time1);
+        out << "%!PS-Adobe-2.0 EPSF-1.2" << '\n'
+            << "%%Title: deal.II Output" << '\n'
+            << "%%Creator: the deal.II library" << '\n'
+            << "%%Creation Date: "
+            << time->tm_year+1900 << "/"
+            << time->tm_mon+1 << "/"
+            << time->tm_mday << " - "
+            << time->tm_hour << ":"
+            << std::setw(2) << time->tm_min << ":"
+            << std::setw(2) << time->tm_sec << '\n'
+            << "%%BoundingBox: "
+            // lower left corner
+            << "0 0 "
+            // upper right corner
+            << static_cast<unsigned int>( (x_max-x_min) * scale + 0.5)
+            << ' '
+            << static_cast<unsigned int>( (y_max-y_min) * scale + 0.5)
+            << '\n';
 
-    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-      out << ", \"" << data_names[data_set] << "\"";
+        // define some abbreviations to keep
+        // the output small:
+        // m=move turtle to
+        // l=define a line
+        // s=set rgb color
+        // sg=set gray value
+        // lx=close the line and plot the line
+        // lf=close the line and fill the interior
+        out << "/m {moveto} bind def"      << '\n'
+            << "/l {lineto} bind def"      << '\n'
+            << "/s {setrgbcolor} bind def" << '\n'
+            << "/sg {setgray} bind def"    << '\n'
+            << "/lx {lineto closepath stroke} bind def" << '\n'
+            << "/lf {lineto closepath fill} bind def"   << '\n';
+
+        out << "%%EndProlog" << '\n'
+            << '\n';
+        // set fine lines
+        out << flags.line_width << " setlinewidth" << '\n';
+        // allow only five digits
+        // for output (instead of the
+        // default six); this should suffice
+        // even for fine grids, but reduces
+        // the file size significantly
+        out << std::setprecision (5);
+      }
 
-    out << '\n';
+    // check if min and max
+    // values for the color are
+    // actually different. If
+    // that is not the case (such
+    // things happen, for
+    // example, in the very first
+    // time step of a time
+    // dependent problem, if the
+    // initial values are zero),
+    // all values are equal, and
+    // then we can draw
+    // everything in an arbitrary
+    // color. Thus, change one of
+    // the two values arbitrarily
+    if (max_color_value == min_color_value)
+      max_color_value = min_color_value+1;
+
+    // now we've got all the information
+    // we need. write the cells.
+    // note: due to the ordering, we
+    // traverse the list of cells
+    // back-to-front
+    for (typename std::multiset<EpsCell2d>::const_iterator
+         cell=cells.begin();
+         cell!=cells.end(); ++cell)
+      {
+        if (flags.draw_cells)
+          {
+            if (flags.shade_cells)
+              {
+                const EpsFlags::RgbValues rgb_values
+                  = (*flags.color_function) (cell->color_value,
+                                             min_color_value,
+                                             max_color_value);
+
+                // write out color
+                if (rgb_values.is_grey())
+                  out << rgb_values.red << " sg ";
+                else
+                  out << rgb_values.red   << ' '
+                      << rgb_values.green << ' '
+                      << rgb_values.blue  << " s ";
+              }
+            else
+              out << "1 sg ";
+
+            out << (cell->vertices[0]-offset) * scale << " m "
+                << (cell->vertices[1]-offset) * scale << " l "
+                << (cell->vertices[3]-offset) * scale << " l "
+                << (cell->vertices[2]-offset) * scale << " lf"
+                << '\n';
+          }
 
-    out << "zone ";
-    if (flags.zone_name)
-      out << "t=\"" << flags.zone_name << "\" ";
+        if (flags.draw_mesh)
+          out << "0 sg "      // draw lines in black
+              << (cell->vertices[0]-offset) * scale << " m "
+              << (cell->vertices[1]-offset) * scale << " l "
+              << (cell->vertices[3]-offset) * scale << " l "
+              << (cell->vertices[2]-offset) * scale << " lx"
+              << '\n';
+      }
+    out << "showpage" << '\n';
+    // make sure everything now gets to
+    // disk
+    out << std::setprecision(old_precision);
+    out.flush ();
 
-    out << "f=feblock, n=" << n_nodes << ", e=" << n_cells
-        << ", et=" << tecplot_cell_type[dim] << '\n';
+    AssertThrow (out, ExcIO());
   }
 
 
-  // in Tecplot FEBLOCK format the vertex
-  // coordinates and the data have an
-  // order that is a bit unpleasant
-  // (first all x coordinates, then
-  // all y coordinate, ...; first all
-  // data of variable 1, then
-  // variable 2, etc), so we have to
-  // copy the data vectors a bit around
-  //
-  // note that we copy vectors when
-  // looping over the patches since we
-  // have to write them one variable
-  // at a time and don't want to use
-  // more than one loop
-  //
-  // this copying of data vectors can
-  // be done while we already output
-  // the vertices, so do this on a
-  // separate task and when wanting
-  // to write out the data, we wait
-  // for that task to finish
-
-  Table<2,double> data_vectors (n_data_sets, n_nodes);
 
-  void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
-                   Table<2,double> &)
-    = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+  template <int dim, int spacedim>
+  void write_gmv (const std::vector<Patch<dim,spacedim> > &patches,
+                  const std::vector<std::string>          &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                  const GmvFlags                          &flags,
+                  std::ostream                            &out)
+  {
+    Assert(dim<=3, ExcNotImplemented());
+    AssertThrow (out, ExcIO());
 
-  ///////////////////////////////
-  // first make up a list of used
-  // vertices along with their
-  // coordinates
+#ifndef DEAL_II_WITH_MPI
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
+#else
+    if (patches.size() == 0)
+      return;
+#endif
 
+    GmvStream gmv_out(out, flags);
+    const unsigned int n_data_sets = data_names.size();
+    // check against # of data sets in
+    // first patch. checks against all
+    // other patches are made in
+    // write_gmv_reorder_data_vectors
+    Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+            (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+            ExcDimensionMismatch (patches[0].points_are_available
+                                  ?
+                                  (n_data_sets + spacedim)
+                                  :
+                                  n_data_sets,
+                                  patches[0].data.n_rows()));
+
+    ///////////////////////
+    // preamble
+    out << "gmvinput ascii"
+        << '\n'
+        << '\n';
 
-  for (unsigned int d=0; d<spacedim; ++d)
-    {
-      tecplot_out.selected_component = d;
-      write_nodes(patches, tecplot_out);
-      out << '\n';
-    }
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+
+    // in gmv format the vertex
+    // coordinates and the data have an
+    // order that is a bit unpleasant
+    // (first all x coordinates, then
+    // all y coordinate, ...; first all
+    // data of variable 1, then
+    // variable 2, etc), so we have to
+    // copy the data vectors a bit around
+    //
+    // note that we copy vectors when
+    // looping over the patches since we
+    // have to write them one variable
+    // at a time and don't want to use
+    // more than one loop
+    //
+    // this copying of data vectors can
+    // be done while we already output
+    // the vertices, so do this on a
+    // separate task and when wanting
+    // to write out the data, we wait
+    // for that task to finish
+    Table<2,double> data_vectors (n_data_sets, n_nodes);
+    void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+                     Table<2,double> &)
+      = &write_gmv_reorder_data_vectors<dim,spacedim>;
+    Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+    ///////////////////////////////
+    // first make up a list of used
+    // vertices along with their
+    // coordinates
+    //
+    // note that we have to print
+    // 3 dimensions
+    out << "nodes " << n_nodes << '\n';
+    for (unsigned int d=0; d<spacedim; ++d)
+      {
+        gmv_out.selected_component = d;
+        write_nodes(patches, gmv_out);
+        out << '\n';
+      }
+    gmv_out.selected_component = numbers::invalid_unsigned_int;
 
+    for (unsigned int d=spacedim; d<3; ++d)
+      {
+        for (unsigned int i=0; i<n_nodes; ++i)
+          out << "0 ";
+        out << '\n';
+      }
 
-  ///////////////////////////////////////
-  // data output.
-  //
-  // now write the data vectors to
-  // @p{out} first make sure that all
-  // data is in place
-  reorder_task.join ();
+    /////////////////////////////////
+    // now for the cells. note that
+    // vertices are counted from 1 onwards
+    out << "cells " << n_cells << '\n';
+    write_cells(patches, gmv_out);
+
+    ///////////////////////////////////////
+    // data output.
+    out << "variable" << '\n';
+
+    // now write the data vectors to
+    // @p{out} first make sure that all
+    // data is in place
+    reorder_task.join ();
+
+    // then write data.
+    // the '1' means: node data (as opposed
+    // to cell data, which we do not
+    // support explicitly here)
+    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+      {
+        out << data_names[data_set] << " 1" << '\n';
+        std::copy (data_vectors[data_set].begin(),
+                   data_vectors[data_set].end(),
+                   std::ostream_iterator<double>(out, " "));
+        out << '\n'
+            << '\n';
+      }
 
-  // then write data.
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    {
-      std::copy (data_vectors[data_set].begin(),
-                 data_vectors[data_set].end(),
-                 std::ostream_iterator<double>(out, "\n"));
-      out << '\n';
-    }
 
-  write_cells(patches, tecplot_out);
 
-  // make sure everything now gets to
-  // disk
-  out.flush ();
+    // end of variable section
+    out << "endvars" << '\n';
 
-  // assert the stream is still ok
-  AssertThrow (out, ExcIO());
-}
+    // end of output
+    out << "endgmv"
+        << '\n';
 
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
+    // assert the stream is still ok
+    AssertThrow (out, ExcIO());
+  }
 
-//---------------------------------------------------------------------------
-// Macros for handling Tecplot API data
 
-#ifdef DEAL_II_HAVE_TECPLOT
 
-namespace
-{
-  class TecplotMacros
+  template <int dim, int spacedim>
+  void write_tecplot (const std::vector<Patch<dim,spacedim> > &patches,
+                      const std::vector<std::string>          &data_names,
+                      const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                      const TecplotFlags                      &flags,
+                      std::ostream                            &out)
   {
-  public:
-    TecplotMacros(const unsigned int n_nodes = 0,
-                  const unsigned int n_vars = 0,
-                  const unsigned int n_cells = 0,
-                  const unsigned int n_vert = 0);
-    ~TecplotMacros();
-    float &nd(const unsigned int i, const unsigned int j);
-    int    &cd(const unsigned int i, const unsigned int j);
-    std::vector<float> nodalData;
-    std::vector<int>   connData;
-  private:
-    unsigned int n_nodes;
-    unsigned int n_vars;
-    unsigned int n_cells;
-    unsigned int n_vert;
-  };
+    AssertThrow (out, ExcIO());
 
+#ifndef DEAL_II_WITH_MPI
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
+#else
+    if (patches.size() == 0)
+      return;
+#endif
 
-  inline
-  TecplotMacros::TecplotMacros(const unsigned int n_nodes,
-                               const unsigned int n_vars,
-                               const unsigned int n_cells,
-                               const unsigned int n_vert)
-    :
-    n_nodes(n_nodes),
-    n_vars(n_vars),
-    n_cells(n_cells),
-    n_vert(n_vert)
-  {
-    nodalData.resize(n_nodes*n_vars);
-    connData.resize(n_cells*n_vert);
-  }
+    TecplotStream tecplot_out(out, flags);
+
+    const unsigned int n_data_sets = data_names.size();
+    // check against # of data sets in
+    // first patch. checks against all
+    // other patches are made in
+    // write_gmv_reorder_data_vectors
+    Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+            (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+            ExcDimensionMismatch (patches[0].points_are_available
+                                  ?
+                                  (n_data_sets + spacedim)
+                                  :
+                                  n_data_sets,
+                                  patches[0].data.n_rows()));
+
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
 
+    ///////////
+    // preamble
+    {
+      std::time_t  time1= std::time (0);
+      std::tm     *time = std::localtime(&time1);
+      out << "# This file was generated by the deal.II library." << '\n'
+          << "# Date =  "
+          << time->tm_year+1900 << "/"
+          << time->tm_mon+1 << "/"
+          << time->tm_mday << '\n'
+          << "# Time =  "
+          << time->tm_hour << ":"
+          << std::setw(2) << time->tm_min << ":"
+          << std::setw(2) << time->tm_sec << '\n'
+          << "#" << '\n'
+          << "# For a description of the Tecplot format see the Tecplot documentation."
+          << '\n'
+          << "#" << '\n';
 
 
-  inline
-  TecplotMacros::~TecplotMacros()
-  {}
+      out << "Variables=";
 
+      switch (spacedim)
+        {
+        case 1:
+          out << "\"x\"";
+          break;
+        case 2:
+          out << "\"x\", \"y\"";
+          break;
+        case 3:
+          out << "\"x\", \"y\", \"z\"";
+          break;
+        default:
+          Assert (false, ExcNotImplemented());
+        }
 
+      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+        out << ", \"" << data_names[data_set] << "\"";
 
-  inline
-  float &TecplotMacros::nd (const unsigned int i,
-                            const unsigned int j)
-  {
-    return nodalData[i*n_nodes+j];
-  }
+      out << '\n';
 
+      out << "zone ";
+      if (flags.zone_name)
+        out << "t=\"" << flags.zone_name << "\" ";
 
+      out << "f=feblock, n=" << n_nodes << ", e=" << n_cells
+          << ", et=" << tecplot_cell_type[dim] << '\n';
+    }
 
-  inline
-  int &TecplotMacros::cd (const unsigned int i,
-                          const unsigned int j)
-  {
-    return connData[i+j*n_vert];
-  }
 
-}
+    // in Tecplot FEBLOCK format the vertex
+    // coordinates and the data have an
+    // order that is a bit unpleasant
+    // (first all x coordinates, then
+    // all y coordinate, ...; first all
+    // data of variable 1, then
+    // variable 2, etc), so we have to
+    // copy the data vectors a bit around
+    //
+    // note that we copy vectors when
+    // looping over the patches since we
+    // have to write them one variable
+    // at a time and don't want to use
+    // more than one loop
+    //
+    // this copying of data vectors can
+    // be done while we already output
+    // the vertices, so do this on a
+    // separate task and when wanting
+    // to write out the data, we wait
+    // for that task to finish
+
+    Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+    void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+                     Table<2,double> &)
+      = &write_gmv_reorder_data_vectors<dim,spacedim>;
+    Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+    ///////////////////////////////
+    // first make up a list of used
+    // vertices along with their
+    // coordinates
+
+
+    for (unsigned int d=0; d<spacedim; ++d)
+      {
+        tecplot_out.selected_component = d;
+        write_nodes(patches, tecplot_out);
+        out << '\n';
+      }
 
 
-#endif
-//---------------------------------------------------------------------------
+    ///////////////////////////////////////
+    // data output.
+    //
+    // now write the data vectors to
+    // @p{out} first make sure that all
+    // data is in place
+    reorder_task.join ();
 
+    // then write data.
+    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+      {
+        std::copy (data_vectors[data_set].begin(),
+                   data_vectors[data_set].end(),
+                   std::ostream_iterator<double>(out, "\n"));
+        out << '\n';
+      }
 
+    write_cells(patches, tecplot_out);
 
-template <int dim, int spacedim>
-void DataOutBase::write_tecplot_binary (const std::vector<Patch<dim,spacedim> > &patches,
-                                        const std::vector<std::string>          &data_names,
-                                        const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                                        const TecplotFlags                      &flags,
-                                        std::ostream                            &out)
-{
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
-#ifndef DEAL_II_HAVE_TECPLOT
+    // assert the stream is still ok
+    AssertThrow (out, ExcIO());
+  }
 
-  // simply call the ASCII output
-  // function if the Tecplot API
-  // isn't present
-  write_tecplot (patches, data_names, vector_data_ranges, flags, out);
-  return;
 
-#else
 
-  // Tecplot binary output only good
-  // for 2D & 3D
-  if (dim == 1)
-    {
-      write_tecplot (patches, data_names, vector_data_ranges, flags, out);
-      return;
-    }
+//---------------------------------------------------------------------------
+// Macros for handling Tecplot API data
 
-  // if the user hasn't specified a
-  // file name we should call the
-  // ASCII function and use the
-  // ostream @p{out} instead of doing
-  // something silly later
-  char *file_name = (char *) flags.tecplot_binary_file_name;
+#ifdef DEAL_II_HAVE_TECPLOT
 
-  if (file_name == NULL)
+  namespace
+  {
+    class TecplotMacros
     {
-      // At least in debug mode we
-      // should tell users why they
-      // don't get tecplot binary
-      // output
-      Assert(false, ExcMessage("Specify the name of the tecplot_binary"
-                               " file through the TecplotFlags interface."));
-      write_tecplot (patches, data_names, vector_data_ranges, flags, out);
-      return;
-    }
-
-
-  AssertThrow (out, ExcIO());
+    public:
+      TecplotMacros(const unsigned int n_nodes = 0,
+                    const unsigned int n_vars = 0,
+                    const unsigned int n_cells = 0,
+                    const unsigned int n_vert = 0);
+      ~TecplotMacros();
+      float &nd(const unsigned int i, const unsigned int j);
+      int    &cd(const unsigned int i, const unsigned int j);
+      std::vector<float> nodalData;
+      std::vector<int>   connData;
+    private:
+      unsigned int n_nodes;
+      unsigned int n_vars;
+      unsigned int n_cells;
+      unsigned int n_vert;
+    };
 
-#ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
-#else
-  if (patches.size() == 0)
-    return;
-#endif
 
-  const unsigned int n_data_sets = data_names.size();
-  // check against # of data sets in
-  // first patch. checks against all
-  // other patches are made in
-  // write_gmv_reorder_data_vectors
-  Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
-          (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
-          ExcDimensionMismatch (patches[0].points_are_available
-                                ?
-                                (n_data_sets + spacedim)
-                                :
-                                n_data_sets,
-                                patches[0].data.n_rows()));
-
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-  // local variables only needed to write Tecplot
-  // binary output files
-  const unsigned int vars_per_node  = (spacedim+n_data_sets),
-                     nodes_per_cell = GeometryInfo<dim>::vertices_per_cell;
-
-  TecplotMacros tm(n_nodes, vars_per_node, n_cells, nodes_per_cell);
-
-  int is_double = 0,
-      tec_debug = 0,
-      cell_type = tecplot_binary_cell_type[dim];
-
-  std::string tec_var_names;
-  switch (spacedim)
+    inline
+    TecplotMacros::TecplotMacros(const unsigned int n_nodes,
+                                 const unsigned int n_vars,
+                                 const unsigned int n_cells,
+                                 const unsigned int n_vert)
+      :
+      n_nodes(n_nodes),
+      n_vars(n_vars),
+      n_cells(n_cells),
+      n_vert(n_vert)
     {
-    case 2:
-      tec_var_names  = "x y";
-      break;
-    case 3:
-      tec_var_names  = "x y z";
-      break;
-    default:
-      Assert(false, ExcNotImplemented());
+      nodalData.resize(n_nodes*n_vars);
+      connData.resize(n_cells*n_vert);
     }
 
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    {
-      tec_var_names += " ";
-      tec_var_names += data_names[data_set];
-    }
-  // in Tecplot FEBLOCK format the vertex
-  // coordinates and the data have an
-  // order that is a bit unpleasant
-  // (first all x coordinates, then
-  // all y coordinate, ...; first all
-  // data of variable 1, then
-  // variable 2, etc), so we have to
-  // copy the data vectors a bit around
-  //
-  // note that we copy vectors when
-  // looping over the patches since we
-  // have to write them one variable
-  // at a time and don't want to use
-  // more than one loop
-  //
-  // this copying of data vectors can
-  // be done while we already output
-  // the vertices, so do this on a
-  // separate task and when wanting
-  // to write out the data, we wait
-  // for that task to finish
-  Table<2,double> data_vectors (n_data_sets, n_nodes);
-
-  void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
-                   Table<2,double> &)
-    = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
-
-  ///////////////////////////////
-  // first make up a list of used
-  // vertices along with their
-  // coordinates
-  for (unsigned int d=1; d<=spacedim; ++d)
-    {
-      unsigned int entry=0;
 
-      for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-           patch!=patches.end(); ++patch)
-        {
-          const unsigned int n_subdivisions = patch->n_subdivisions;
 
-          switch (dim)
-            {
-            case 2:
-            {
-              for (unsigned int j=0; j<n_subdivisions+1; ++j)
-                for (unsigned int i=0; i<n_subdivisions+1; ++i)
-                  {
-                    const double x_frac = i * 1./n_subdivisions,
-                                 y_frac = j * 1./n_subdivisions;
-
-                    tm.nd((d-1),entry) = static_cast<float>(
-                                           (((patch->vertices[1](d-1) * x_frac) +
-                                             (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
-                                            ((patch->vertices[3](d-1) * x_frac) +
-                                             (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)
-                                         );
-                    entry++;
-                  }
-              break;
-            }
+    inline
+    TecplotMacros::~TecplotMacros()
+    {}
 
-            case 3:
-            {
-              for (unsigned int j=0; j<n_subdivisions+1; ++j)
-                for (unsigned int k=0; k<n_subdivisions+1; ++k)
-                  for (unsigned int i=0; i<n_subdivisions+1; ++i)
-                    {
-                      const double x_frac = i * 1./n_subdivisions,
-                                   y_frac = k * 1./n_subdivisions,
-                                   z_frac = j * 1./n_subdivisions;
 
-                      // compute coordinates for
-                      // this patch point
-                      tm.nd((d-1),entry) = static_cast<float>(
-                                             ((((patch->vertices[1](d-1) * x_frac) +
-                                                (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
-                                               ((patch->vertices[3](d-1) * x_frac) +
-                                                (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)   * (1-z_frac) +
-                                              (((patch->vertices[5](d-1) * x_frac) +
-                                                (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
-                                               ((patch->vertices[7](d-1) * x_frac) +
-                                                (patch->vertices[6](d-1) * (1-x_frac))) * y_frac)   * z_frac)
-                                           );
-                      entry++;
-                    }
-              break;
-            }
 
-            default:
-              Assert (false, ExcNotImplemented());
-            }
-        }
+    inline
+    float &TecplotMacros::nd (const unsigned int i,
+                              const unsigned int j)
+    {
+      return nodalData[i*n_nodes+j];
     }
 
 
-  ///////////////////////////////////////
-  // data output.
-  //
-  reorder_task.join ();
 
-  // then write data.
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    for (unsigned int entry=0; entry<data_vectors[data_set].size(); entry++)
-      tm.nd((spacedim+data_set),entry) = static_cast<float>(data_vectors[data_set][entry]);
+    inline
+    int &TecplotMacros::cd (const unsigned int i,
+                            const unsigned int j)
+    {
+      return connData[i+j*n_vert];
+    }
 
+  }
 
 
+#endif
+//---------------------------------------------------------------------------
 
-  /////////////////////////////////
-  // now for the cells. note that
-  // vertices are counted from 1 onwards
-  unsigned int first_vertex_of_patch = 0;
-  unsigned int elem=0;
 
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-       patch!=patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-      const unsigned int n = n_subdivisions+1;
-      const unsigned int d1=1;
-      const unsigned int d2=n;
-      const unsigned int d3=n*n;
-      // write out the cells making
-      // up this patch
-      switch (dim)
-        {
-        case 2:
-        {
-          for (unsigned int i2=0; i2<n_subdivisions; ++i2)
-            for (unsigned int i1=0; i1<n_subdivisions; ++i1)
-              {
-                tm.cd(0,elem) = first_vertex_of_patch+(i1  )*d1+(i2  )*d2+1;
-                tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2  )*d2+1;
-                tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+1;
-                tm.cd(3,elem) = first_vertex_of_patch+(i1  )*d1+(i2+1)*d2+1;
 
-                elem++;
-              }
-          break;
-        }
+  template <int dim, int spacedim>
+  void write_tecplot_binary (const std::vector<Patch<dim,spacedim> > &patches,
+                             const std::vector<std::string>          &data_names,
+                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                             const TecplotFlags                      &flags,
+                             std::ostream                            &out)
+  {
 
-        case 3:
-        {
-          for (unsigned int i3=0; i3<n_subdivisions; ++i3)
-            for (unsigned int i2=0; i2<n_subdivisions; ++i2)
-              for (unsigned int i1=0; i1<n_subdivisions; ++i1)
-                {
-                  // note: vertex indices start with 1!
+#ifndef DEAL_II_HAVE_TECPLOT
 
+    // simply call the ASCII output
+    // function if the Tecplot API
+    // isn't present
+    write_tecplot (patches, data_names, vector_data_ranges, flags, out);
+    return;
 
-                  tm.cd(0,elem) = first_vertex_of_patch+(i1  )*d1+(i2  )*d2+(i3  )*d3+1;
-                  tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2  )*d2+(i3  )*d3+1;
-                  tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3  )*d3+1;
-                  tm.cd(3,elem) = first_vertex_of_patch+(i1  )*d1+(i2+1)*d2+(i3  )*d3+1;
-                  tm.cd(4,elem) = first_vertex_of_patch+(i1  )*d1+(i2  )*d2+(i3+1)*d3+1;
-                  tm.cd(5,elem) = first_vertex_of_patch+(i1+1)*d1+(i2  )*d2+(i3+1)*d3+1;
-                  tm.cd(6,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3+1)*d3+1;
-                  tm.cd(7,elem) = first_vertex_of_patch+(i1  )*d1+(i2+1)*d2+(i3+1)*d3+1;
+#else
 
-                  elem++;
-                }
-          break;
-        }
+    // Tecplot binary output only good
+    // for 2D & 3D
+    if (dim == 1)
+      {
+        write_tecplot (patches, data_names, vector_data_ranges, flags, out);
+        return;
+      }
 
-        default:
-          Assert (false, ExcNotImplemented());
-        }
+    // if the user hasn't specified a
+    // file name we should call the
+    // ASCII function and use the
+    // ostream @p{out} instead of doing
+    // something silly later
+    char *file_name = (char *) flags.tecplot_binary_file_name;
 
+    if (file_name == NULL)
+      {
+        // At least in debug mode we
+        // should tell users why they
+        // don't get tecplot binary
+        // output
+        Assert(false, ExcMessage("Specify the name of the tecplot_binary"
+                                 " file through the TecplotFlags interface."));
+        write_tecplot (patches, data_names, vector_data_ranges, flags, out);
+        return;
+      }
 
-      // finally update the number
-      // of the first vertex of this patch
-      first_vertex_of_patch += Utilities::fixed_power<dim>(n);
-    }
 
+    AssertThrow (out, ExcIO());
 
-  {
-    int ierr      = 0,
-        num_nodes = static_cast<int>(n_nodes),
-        num_cells = static_cast<int>(n_cells);
+#ifndef DEAL_II_WITH_MPI
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
+#else
+    if (patches.size() == 0)
+      return;
+#endif
 
-    char dot[2] = {'.', 0};
-    // Unfortunately, TECINI takes a
-    // char *, but c_str() gives a
-    // const char *.  As we don't do
-    // anything else with
-    // tec_var_names following
-    // const_cast is ok
-    char *var_names=const_cast<char *> (tec_var_names.c_str());
-    ierr = TECINI (NULL,
-                   var_names,
-                   file_name,
-                   dot,
-                   &tec_debug,
-                   &is_double);
+    const unsigned int n_data_sets = data_names.size();
+    // check against # of data sets in
+    // first patch. checks against all
+    // other patches are made in
+    // write_gmv_reorder_data_vectors
+    Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+            (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+            ExcDimensionMismatch (patches[0].points_are_available
+                                  ?
+                                  (n_data_sets + spacedim)
+                                  :
+                                  n_data_sets,
+                                  patches[0].data.n_rows()));
+
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+    // local variables only needed to write Tecplot
+    // binary output files
+    const unsigned int vars_per_node  = (spacedim+n_data_sets),
+                       nodes_per_cell = GeometryInfo<dim>::vertices_per_cell;
 
-    Assert (ierr == 0, ExcErrorOpeningTecplotFile(file_name));
+    TecplotMacros tm(n_nodes, vars_per_node, n_cells, nodes_per_cell);
 
-    char FEBLOCK[] = {'F','E','B','L','O','C','K',0};
-    ierr = TECZNE (NULL,
-                   &num_nodes,
-                   &num_cells,
-                   &cell_type,
-                   FEBLOCK,
-                   NULL);
+    int is_double = 0,
+        tec_debug = 0,
+        cell_type = tecplot_binary_cell_type[dim];
 
-    Assert (ierr == 0, ExcTecplotAPIError());
+    std::string tec_var_names;
+    switch (spacedim)
+      {
+      case 2:
+        tec_var_names  = "x y";
+        break;
+      case 3:
+        tec_var_names  = "x y z";
+        break;
+      default:
+        Assert(false, ExcNotImplemented());
+      }
 
-    int total = (vars_per_node*num_nodes);
+    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+      {
+        tec_var_names += " ";
+        tec_var_names += data_names[data_set];
+      }
+    // in Tecplot FEBLOCK format the vertex
+    // coordinates and the data have an
+    // order that is a bit unpleasant
+    // (first all x coordinates, then
+    // all y coordinate, ...; first all
+    // data of variable 1, then
+    // variable 2, etc), so we have to
+    // copy the data vectors a bit around
+    //
+    // note that we copy vectors when
+    // looping over the patches since we
+    // have to write them one variable
+    // at a time and don't want to use
+    // more than one loop
+    //
+    // this copying of data vectors can
+    // be done while we already output
+    // the vertices, so do this on a
+    // separate task and when wanting
+    // to write out the data, we wait
+    // for that task to finish
+    Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+    void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+                     Table<2,double> &)
+      = &write_gmv_reorder_data_vectors<dim,spacedim>;
+    Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+    ///////////////////////////////
+    // first make up a list of used
+    // vertices along with their
+    // coordinates
+    for (unsigned int d=1; d<=spacedim; ++d)
+      {
+        unsigned int entry=0;
 
-    ierr = TECDAT (&total,
-                   &tm.nodalData[0],
-                   &is_double);
+        for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+             patch!=patches.end(); ++patch)
+          {
+            const unsigned int n_subdivisions = patch->n_subdivisions;
 
-    Assert (ierr == 0, ExcTecplotAPIError());
+            switch (dim)
+              {
+              case 2:
+              {
+                for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                  for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                    {
+                      const double x_frac = i * 1./n_subdivisions,
+                                   y_frac = j * 1./n_subdivisions;
 
-    ierr = TECNOD (&tm.connData[0]);
+                      tm.nd((d-1),entry) = static_cast<float>(
+                                             (((patch->vertices[1](d-1) * x_frac) +
+                                               (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+                                              ((patch->vertices[3](d-1) * x_frac) +
+                                               (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)
+                                           );
+                      entry++;
+                    }
+                break;
+              }
 
-    Assert (ierr == 0, ExcTecplotAPIError());
+              case 3:
+              {
+                for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                  for (unsigned int k=0; k<n_subdivisions+1; ++k)
+                    for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                      {
+                        const double x_frac = i * 1./n_subdivisions,
+                                     y_frac = k * 1./n_subdivisions,
+                                     z_frac = j * 1./n_subdivisions;
+
+                        // compute coordinates for
+                        // this patch point
+                        tm.nd((d-1),entry) = static_cast<float>(
+                                               ((((patch->vertices[1](d-1) * x_frac) +
+                                                  (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+                                                 ((patch->vertices[3](d-1) * x_frac) +
+                                                  (patch->vertices[2](d-1) * (1-x_frac))) * y_frac)   * (1-z_frac) +
+                                                (((patch->vertices[5](d-1) * x_frac) +
+                                                  (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
+                                                 ((patch->vertices[7](d-1) * x_frac) +
+                                                  (patch->vertices[6](d-1) * (1-x_frac))) * y_frac)   * z_frac)
+                                             );
+                        entry++;
+                      }
+                break;
+              }
 
-    ierr = TECEND ();
+              default:
+                Assert (false, ExcNotImplemented());
+              }
+          }
+      }
 
-    Assert (ierr == 0, ExcTecplotAPIError());
-  }
-#endif
-}
 
+    ///////////////////////////////////////
+    // data output.
+    //
+    reorder_task.join ();
 
+    // then write data.
+    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+      for (unsigned int entry=0; entry<data_vectors[data_set].size(); entry++)
+        tm.nd((spacedim+data_set),entry) = static_cast<float>(data_vectors[data_set][entry]);
 
-template <int dim, int spacedim>
-void
-DataOutBase::write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
-                        const std::vector<std::string>          &data_names,
-                        const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                        const VtkFlags                          &flags,
-                        std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
 
-#ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
-#else
-  if (patches.size() == 0)
-    return;
-#endif
 
-  VtkStream vtk_out(out, flags);
 
-  const unsigned int n_data_sets = data_names.size();
-  // check against # of data sets in
-  // first patch. checks against all
-  // other patches are made in
-  // write_gmv_reorder_data_vectors
-  Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
-          (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
-          ExcDimensionMismatch (patches[0].points_are_available
-                                ?
-                                (n_data_sets + spacedim)
-                                :
-                                n_data_sets,
-                                patches[0].data.n_rows()));
-
-  ///////////////////////
-  // preamble
-  {
-    std::time_t  time1= std::time (0);
-    std::tm     *time = std::localtime(&time1);
-    out << "# vtk DataFile Version 3.0"
-        << '\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
-    out << "DATASET UNSTRUCTURED_GRID\n"
-        << '\n';
-  }
+    /////////////////////////////////
+    // now for the cells. note that
+    // vertices are counted from 1 onwards
+    unsigned int first_vertex_of_patch = 0;
+    unsigned int elem=0;
 
-  // if desired, output time and cycle of the simulation, following
-  // the instructions at
-  // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
-  {
-    const unsigned int
-    n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
-                  +
-                  (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
-    if (n_metadata > 0)
-      out << "FIELD FieldData " << n_metadata << "\n";
-
-    if (flags.cycle != std::numeric_limits<unsigned int>::min())
-      {
-        out << "CYCLE 1 1 int\n"
-            << flags.cycle << "\n";
-      }
-    if (flags.time != std::numeric_limits<double>::min())
+    for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
+         patch!=patches.end(); ++patch)
       {
-        out << "TIME 1 1 double\n"
-            << flags.time << "\n";
-      }
-  }
-
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-  // in gmv format the vertex
-  // coordinates and the data have an
-  // order that is a bit unpleasant
-  // (first all x coordinates, then
-  // all y coordinate, ...; first all
-  // data of variable 1, then
-  // variable 2, etc), so we have to
-  // copy the data vectors a bit around
-  //
-  // note that we copy vectors when
-  // looping over the patches since we
-  // have to write them one variable
-  // at a time and don't want to use
-  // more than one loop
-  //
-  // this copying of data vectors can
-  // be done while we already output
-  // the vertices, so do this on a
-  // separate task and when wanting
-  // to write out the data, we wait
-  // for that task to finish
-  Table<2,double> data_vectors (n_data_sets, n_nodes);
-
-  void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
-                   Table<2,double> &)
-    = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
-
-  ///////////////////////////////
-  // first make up a list of used
-  // vertices along with their
-  // coordinates
-  //
-  // note that we have to print
-  // d=1..3 dimensions
-  out << "POINTS " << n_nodes << " double" << '\n';
-  write_nodes(patches, vtk_out);
-  out << '\n';
-  /////////////////////////////////
-  // now for the cells
-  out << "CELLS " << n_cells << ' '
-      << n_cells*(GeometryInfo<dim>::vertices_per_cell+1)
-      << '\n';
-  write_cells(patches, vtk_out);
-  out << '\n';
-  // next output the types of the
-  // cells. since all cells are
-  // the same, this is simple
-  out << "CELL_TYPES " << n_cells << '\n';
-  for (unsigned int i=0; i<n_cells; ++i)
-    out << ' ' << vtk_cell_type[dim];
-  out << '\n';
-  ///////////////////////////////////////
-  // data output.
-
-  // now write the data vectors to
-  // @p{out} first make sure that all
-  // data is in place
-  reorder_task.join ();
+        const unsigned int n_subdivisions = patch->n_subdivisions;
+        const unsigned int n = n_subdivisions+1;
+        const unsigned int d1=1;
+        const unsigned int d2=n;
+        const unsigned int d3=n*n;
+        // write out the cells making
+        // up this patch
+        switch (dim)
+          {
+          case 2:
+          {
+            for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+              for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+                {
+                  tm.cd(0,elem) = first_vertex_of_patch+(i1  )*d1+(i2  )*d2+1;
+                  tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2  )*d2+1;
+                  tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+1;
+                  tm.cd(3,elem) = first_vertex_of_patch+(i1  )*d1+(i2+1)*d2+1;
 
-  // then write data.  the
-  // 'POINT_DATA' means: node data
-  // (as opposed to cell data, which
-  // we do not support explicitly
-  // here). all following data sets
-  // are point data
-  out << "POINT_DATA " << n_nodes
-      << '\n';
+                  elem++;
+                }
+            break;
+          }
 
-  // when writing, first write out
-  // all vector data, then handle the
-  // scalar data sets that have been
-  // left over
-  std::vector<bool> data_set_written (n_data_sets, false);
-  for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
-    {
-      AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
-                   std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
-                   ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
-                                  std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
-      AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
-                   ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
-                                  0, n_data_sets));
-      AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
-                   - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
-                   ExcMessage ("Can't declare a vector with more than 3 components "
-                               "in VTK"));
+          case 3:
+          {
+            for (unsigned int i3=0; i3<n_subdivisions; ++i3)
+              for (unsigned int i2=0; i2<n_subdivisions; ++i2)
+                for (unsigned int i1=0; i1<n_subdivisions; ++i1)
+                  {
+                    // note: vertex indices start with 1!
 
-      // mark these components as already written:
-      for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
-           i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
-           ++i)
-        data_set_written[i] = true;
 
-      // write the
-      // header. concatenate all the
-      // component names with double
-      // underscores unless a vector
-      // name has been specified
-      out << "VECTORS ";
+                    tm.cd(0,elem) = first_vertex_of_patch+(i1  )*d1+(i2  )*d2+(i3  )*d3+1;
+                    tm.cd(1,elem) = first_vertex_of_patch+(i1+1)*d1+(i2  )*d2+(i3  )*d3+1;
+                    tm.cd(2,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3  )*d3+1;
+                    tm.cd(3,elem) = first_vertex_of_patch+(i1  )*d1+(i2+1)*d2+(i3  )*d3+1;
+                    tm.cd(4,elem) = first_vertex_of_patch+(i1  )*d1+(i2  )*d2+(i3+1)*d3+1;
+                    tm.cd(5,elem) = first_vertex_of_patch+(i1+1)*d1+(i2  )*d2+(i3+1)*d3+1;
+                    tm.cd(6,elem) = first_vertex_of_patch+(i1+1)*d1+(i2+1)*d2+(i3+1)*d3+1;
+                    tm.cd(7,elem) = first_vertex_of_patch+(i1  )*d1+(i2+1)*d2+(i3+1)*d3+1;
 
-      if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
-        out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
-      else
-        {
-          for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
-               i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
-               ++i)
-            out << data_names[i] << "__";
-          out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
-        }
+                    elem++;
+                  }
+            break;
+          }
 
-      out << " double"
-          << '\n';
+          default:
+            Assert (false, ExcNotImplemented());
+          }
 
-      // now write data. pad all
-      // vectors to have three
-      // components
-      for (unsigned int n=0; n<n_nodes; ++n)
-        {
-          switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
-                  std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
-            {
-            case 0:
-              out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << " 0 0"
-                  << '\n';
-              break;
-
-            case 1:
-              out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << " 0"
-                  << '\n';
-              break;
-            case 2:
-              out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n)
-                  << '\n';
-              break;
-
-            default:
-              // VTK doesn't
-              // support
-              // anything else
-              // than vectors
-              // with 1, 2, or
-              // 3 components
-              Assert (false, ExcInternalError());
-            }
-        }
-    }
 
-  // now do the left over scalar data sets
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    if (data_set_written[data_set] == false)
-      {
-        out << "SCALARS "
-            << data_names[data_set]
-            << " double 1"
-            << '\n'
-            << "LOOKUP_TABLE default"
-            << '\n';
-        std::copy (data_vectors[data_set].begin(),
-                   data_vectors[data_set].end(),
-                   std::ostream_iterator<double>(out, " "));
-        out << '\n';
+        // finally update the number
+        // of the first vertex of this patch
+        first_vertex_of_patch += Utilities::fixed_power<dim>(n);
       }
 
-  // make sure everything now gets to
-  // disk
-  out.flush ();
 
-  // assert the stream is still ok
-  AssertThrow (out, ExcIO());
-}
+    {
+      int ierr      = 0,
+          num_nodes = static_cast<int>(n_nodes),
+          num_cells = static_cast<int>(n_cells);
 
+      char dot[2] = {'.', 0};
+      // Unfortunately, TECINI takes a
+      // char *, but c_str() gives a
+      // const char *.  As we don't do
+      // anything else with
+      // tec_var_names following
+      // const_cast is ok
+      char *var_names=const_cast<char *> (tec_var_names.c_str());
+      ierr = TECINI (NULL,
+                     var_names,
+                     file_name,
+                     dot,
+                     &tec_debug,
+                     &is_double);
 
-void DataOutBase::write_vtu_header (std::ostream &out,
-                                    const VtkFlags &flags)
-{
-  AssertThrow (out, ExcIO());
-  std::time_t  time1= std::time (0);
-  std::tm     *time = std::localtime(&time1);
-  out << "<?xml version=\"1.0\" ?> \n";
-  out << "<!-- \n";
-  out << "# vtk DataFile Version 3.0"
-      << '\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\"";
-#endif
-#ifdef DEAL_II_WORDS_BIGENDIAN
-  out << " byte_order=\"BigEndian\"";
-#else
-  out << " byte_order=\"LittleEndian\"";
-#endif
-  out << ">";
-  out << '\n';
-  out << "<UnstructuredGrid>";
-  out << '\n';
-}
+      Assert (ierr == 0, ExcErrorOpeningTecplotFile(file_name));
 
+      char FEBLOCK[] = {'F','E','B','L','O','C','K',0};
+      ierr = TECZNE (NULL,
+                     &num_nodes,
+                     &num_cells,
+                     &cell_type,
+                     FEBLOCK,
+                     NULL);
 
+      Assert (ierr == 0, ExcTecplotAPIError());
 
-void DataOutBase::write_vtu_footer (std::ostream &out)
-{
-  AssertThrow (out, ExcIO());
-  out << " </UnstructuredGrid>\n";
-  out << "</VTKFile>\n";
-}
+      int total = (vars_per_node*num_nodes);
 
+      ierr = TECDAT (&total,
+                     &tm.nodalData[0],
+                     &is_double);
 
+      Assert (ierr == 0, ExcTecplotAPIError());
 
-template <int dim, int spacedim>
-void
-DataOutBase::write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
-                        const std::vector<std::string>          &data_names,
-                        const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                        const VtkFlags                          &flags,
-                        std::ostream                            &out)
-{
-  write_vtu_header(out, flags);
-  write_vtu_main (patches, data_names, vector_data_ranges, flags, out);
-  write_vtu_footer(out);
+      ierr = TECNOD (&tm.connData[0]);
 
-  out << std::flush;
-}
+      Assert (ierr == 0, ExcTecplotAPIError());
 
+      ierr = TECEND ();
+
+      Assert (ierr == 0, ExcTecplotAPIError());
+    }
+#endif
+  }
 
-template <int dim, int spacedim>
-void DataOutBase::write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
-                                  const std::vector<std::string>          &data_names,
-                                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                                  const VtkFlags                          &flags,
-                                  std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+
+
+  template <int dim, int spacedim>
+  void
+  write_vtk (const std::vector<Patch<dim,spacedim> > &patches,
+             const std::vector<std::string>          &data_names,
+             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+             const VtkFlags                          &flags,
+             std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
 
 #ifndef DEAL_II_WITH_MPI
-  // verify that there are indeed
-  // patches to be written out. most
-  // of the times, people just forget
-  // to call build_patches when there
-  // are no patches, so a warning is
-  // in order. that said, the
-  // assertion is disabled if we
-  // support MPI since then it can
-  // happen that on the coarsest
-  // mesh, a processor simply has no
-  // cells it actually owns, and in
-  // that case it is legit if there
-  // are no patches
-  Assert (patches.size() > 0, ExcNoPatches());
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
 #else
-  if (patches.size() == 0)
-    {
-      // we still need to output a valid vtu file, because other CPUs
-      // might output data. This is the minimal file that is accepted by paraview and visit.
-      // if we remove the field definitions, visit is complaining.
-      out << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\" >\n"
-          << "<Cells>\n"
-          << "<DataArray type=\"UInt8\" Name=\"types\"></DataArray>\n"
-          << "</Cells>\n"
-          << "  <PointData Scalars=\"scalars\">\n";
-      std::vector<bool> data_set_written (data_names.size(), false);
-      for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
-        {
-          // mark these components as already
-          // written:
-          for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
-               i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
-               ++i)
-            data_set_written[i] = true;
-
-          // write the
-          // header. concatenate all the
-          // component names with double
-          // underscores unless a vector
-          // name has been specified
-          out << "    <DataArray type=\"Float64\" Name=\"";
+    if (patches.size() == 0)
+      return;
+#endif
 
-          if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
-            out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
-          else
-            {
-              for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
-                   i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
-                   ++i)
-                out << data_names[i] << "__";
-              out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
-            }
+    VtkStream vtk_out(out, flags);
+
+    const unsigned int n_data_sets = data_names.size();
+    // check against # of data sets in
+    // first patch. checks against all
+    // other patches are made in
+    // write_gmv_reorder_data_vectors
+    Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+            (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+            ExcDimensionMismatch (patches[0].points_are_available
+                                  ?
+                                  (n_data_sets + spacedim)
+                                  :
+                                  n_data_sets,
+                                  patches[0].data.n_rows()));
+
+    ///////////////////////
+    // preamble
+    {
+      std::time_t  time1= std::time (0);
+      std::tm     *time = std::localtime(&time1);
+      out << "# vtk DataFile Version 3.0"
+          << '\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
+      out << "DATASET UNSTRUCTURED_GRID\n"
+          << '\n';
+    }
 
-          out << "\" NumberOfComponents=\"3\"></DataArray>\n";
+    // if desired, output time and cycle of the simulation, following
+    // the instructions at
+    // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
+    {
+      const unsigned int
+      n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
+                    +
+                    (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
+      if (n_metadata > 0)
+        out << "FIELD FieldData " << n_metadata << "\n";
+
+      if (flags.cycle != std::numeric_limits<unsigned int>::min())
+        {
+          out << "CYCLE 1 1 int\n"
+              << flags.cycle << "\n";
         }
+      if (flags.time != std::numeric_limits<double>::min())
+        {
+          out << "TIME 1 1 double\n"
+              << flags.time << "\n";
+        }
+    }
+
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+    // in gmv format the vertex
+    // coordinates and the data have an
+    // order that is a bit unpleasant
+    // (first all x coordinates, then
+    // all y coordinate, ...; first all
+    // data of variable 1, then
+    // variable 2, etc), so we have to
+    // copy the data vectors a bit around
+    //
+    // note that we copy vectors when
+    // looping over the patches since we
+    // have to write them one variable
+    // at a time and don't want to use
+    // more than one loop
+    //
+    // this copying of data vectors can
+    // be done while we already output
+    // the vertices, so do this on a
+    // separate task and when wanting
+    // to write out the data, we wait
+    // for that task to finish
+    Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+    void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+                     Table<2,double> &)
+      = &write_gmv_reorder_data_vectors<dim,spacedim>;
+    Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches, data_vectors);
+
+    ///////////////////////////////
+    // first make up a list of used
+    // vertices along with their
+    // coordinates
+    //
+    // note that we have to print
+    // d=1..3 dimensions
+    out << "POINTS " << n_nodes << " double" << '\n';
+    write_nodes(patches, vtk_out);
+    out << '\n';
+    /////////////////////////////////
+    // now for the cells
+    out << "CELLS " << n_cells << ' '
+        << n_cells*(GeometryInfo<dim>::vertices_per_cell+1)
+        << '\n';
+    write_cells(patches, vtk_out);
+    out << '\n';
+    // next output the types of the
+    // cells. since all cells are
+    // the same, this is simple
+    out << "CELL_TYPES " << n_cells << '\n';
+    for (unsigned int i=0; i<n_cells; ++i)
+      out << ' ' << vtk_cell_type[dim];
+    out << '\n';
+    ///////////////////////////////////////
+    // data output.
+
+    // now write the data vectors to
+    // @p{out} first make sure that all
+    // data is in place
+    reorder_task.join ();
+
+    // then write data.  the
+    // 'POINT_DATA' means: node data
+    // (as opposed to cell data, which
+    // we do not support explicitly
+    // here). all following data sets
+    // are point data
+    out << "POINT_DATA " << n_nodes
+        << '\n';
 
-      for (unsigned int data_set=0; data_set<data_names.size(); ++data_set)
-        if (data_set_written[data_set] == false)
+    // when writing, first write out
+    // all vector data, then handle the
+    // scalar data sets that have been
+    // left over
+    std::vector<bool> data_set_written (n_data_sets, false);
+    for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
+      {
+        AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
+                     std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+                     ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+                                    std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+        AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
+                     ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+                                    0, n_data_sets));
+        AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
+                     - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+                     ExcMessage ("Can't declare a vector with more than 3 components "
+                                 "in VTK"));
+
+        // mark these components as already written:
+        for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+             i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+             ++i)
+          data_set_written[i] = true;
+
+        // write the
+        // header. concatenate all the
+        // component names with double
+        // underscores unless a vector
+        // name has been specified
+        out << "VECTORS ";
+
+        if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
+          out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+        else
           {
-            out << "    <DataArray type=\"Float64\" Name=\""
-                << data_names[data_set]
-                << "\"></DataArray>\n";
+            for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+                 i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+                 ++i)
+              out << data_names[i] << "__";
+            out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
           }
 
-      out << "  </PointData>\n";
-      out << "</Piece>\n";
+        out << " double"
+            << '\n';
 
-      out << std::flush;
+        // now write data. pad all
+        // vectors to have three
+        // components
+        for (unsigned int n=0; n<n_nodes; ++n)
+          {
+            switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
+                    std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
+              {
+              case 0:
+                out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n) << " 0 0"
+                    << '\n';
+                break;
 
-      return;
-    }
-#endif
+              case 1:
+                out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << " 0"
+                    << '\n';
+                break;
+              case 2:
+                out << data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n) << ' '<< data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n)
+                    << '\n';
+                break;
 
-  // first up: metadata
-  //
-  // if desired, output time and cycle of the simulation, following
-  // the instructions at
-  // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
-  {
-    const unsigned int
-    n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
-                  +
-                  (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
-    if (n_metadata > 0)
-      out << "<FieldData>\n";
-
-    if (flags.cycle != std::numeric_limits<unsigned int>::min())
-      {
-        out << "<DataArray type=\"Float32\" Name=\"CYCLE\" NumberOfTuples=\"1\" format=\"ascii\">"
-            << flags.cycle
-            << "</DataArray>\n";
-      }
-    if (flags.time != std::numeric_limits<double>::min())
-      {
-        out << "<DataArray type=\"Float32\" Name=\"TIME\" NumberOfTuples=\"1\" format=\"ascii\">"
-            << flags.time
-            << "</DataArray>\n";
+              default:
+                // VTK doesn't
+                // support
+                // anything else
+                // than vectors
+                // with 1, 2, or
+                // 3 components
+                Assert (false, ExcInternalError());
+              }
+          }
       }
 
-    if (n_metadata > 0)
-      out << "</FieldData>\n";
-  }
-
+    // now do the left over scalar data sets
+    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+      if (data_set_written[data_set] == false)
+        {
+          out << "SCALARS "
+              << data_names[data_set]
+              << " double 1"
+              << '\n'
+              << "LOOKUP_TABLE default"
+              << '\n';
+          std::copy (data_vectors[data_set].begin(),
+                     data_vectors[data_set].end(),
+                     std::ostream_iterator<double>(out, " "));
+          out << '\n';
+        }
 
-  VtuStream vtu_out(out, flags);
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
-  const unsigned int n_data_sets = data_names.size();
-  // check against # of data sets in
-  // first patch. checks against all
-  // other patches are made in
-  // write_gmv_reorder_data_vectors
-  Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
-          (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
-          ExcDimensionMismatch (patches[0].points_are_available
-                                ?
-                                (n_data_sets + spacedim)
-                                :
-                                n_data_sets,
-                                patches[0].data.n_rows()));
+    // assert the stream is still ok
+    AssertThrow (out, ExcIO());
+  }
 
 
+  void write_vtu_header (std::ostream &out,
+                         const VtkFlags &flags)
+  {
+    AssertThrow (out, ExcIO());
+    std::time_t  time1= std::time (0);
+    std::tm     *time = std::localtime(&time1);
+    out << "<?xml version=\"1.0\" ?> \n";
+    out << "<!-- \n";
+    out << "# vtk DataFile Version 3.0"
+        << '\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
-  const char *ascii_or_binary = "binary";
+    out << " compressor=\"vtkZLibDataCompressor\"";
+#endif
+#ifdef DEAL_II_WORDS_BIGENDIAN
+    out << " byte_order=\"BigEndian\"";
 #else
-  const char *ascii_or_binary = "ascii";
+    out << " byte_order=\"LittleEndian\"";
 #endif
+    out << ">";
+    out << '\n';
+    out << "<UnstructuredGrid>";
+    out << '\n';
+  }
 
 
-  // first count the number of cells
-  // and cells for later use
-  unsigned int n_nodes;
-  unsigned int n_cells;
-  compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
-  // in gmv format the vertex
-  // coordinates and the data have an
-  // order that is a bit unpleasant
-  // (first all x coordinates, then
-  // all y coordinate, ...; first all
-  // data of variable 1, then
-  // variable 2, etc), so we have to
-  // copy the data vectors a bit around
-  //
-  // note that we copy vectors when
-  // looping over the patches since we
-  // have to write them one variable
-  // at a time and don't want to use
-  // more than one loop
-  //
-  // this copying of data vectors can
-  // be done while we already output
-  // the vertices, so do this on a
-  // separate task and when wanting
-  // to write out the data, we wait
-  // for that task to finish
-  Table<2,double> data_vectors (n_data_sets, n_nodes);
-
-  void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
-                   Table<2,double> &)
-    = &DataOutBase::template write_gmv_reorder_data_vectors<dim,spacedim>;
-  Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches,
-                                                    data_vectors);
-
-  ///////////////////////////////
-  // first make up a list of used
-  // vertices along with their
-  // coordinates
-  //
-  // note that according to the standard, we
-  // have to print d=1..3 dimensions, even if
-  // we are in reality in 2d, for example
-  out << "<Piece NumberOfPoints=\"" << n_nodes
-      <<"\" NumberOfCells=\"" << n_cells << "\" >\n";
-  out << "  <Points>\n";
-  out << "    <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\""
-      << ascii_or_binary << "\">\n";
-  write_nodes(patches, vtu_out);
-  out << "    </DataArray>\n";
-  out << "  </Points>\n\n";
-  /////////////////////////////////
-  // now for the cells
-  out << "  <Cells>\n";
-  out << "    <DataArray type=\"Int32\" Name=\"connectivity\" format=\""
-      << ascii_or_binary << "\">\n";
-  write_cells(patches, vtu_out);
-  out << "    </DataArray>\n";
-
-  // XML VTU format uses offsets; this is
-  // different than the VTK format, which
-  // puts the number of nodes per cell in
-  // front of the connectivity list.
-  out << "    <DataArray type=\"Int32\" Name=\"offsets\" format=\""
-      << ascii_or_binary << "\">\n";
-
-  std::vector<int32_t> offsets (n_cells);
-  for (unsigned int i=0; i<n_cells; ++i)
-    offsets[i] = (i+1)*GeometryInfo<dim>::vertices_per_cell;
-  vtu_out << offsets;
-  out << "\n";
-  out << "    </DataArray>\n";
-
-  // next output the types of the
-  // cells. since all cells are
-  // the same, this is simple
-  out << "    <DataArray type=\"UInt8\" Name=\"types\" format=\""
-      << ascii_or_binary << "\">\n";
 
+  void write_vtu_footer (std::ostream &out)
   {
-    // uint8_t might be a typedef to unsigned
-    // char which is then not printed as
-    // ascii integers
-#ifdef DEAL_II_WITH_ZLIB
-    std::vector<uint8_t> cell_types (n_cells,
-                                     static_cast<uint8_t>(vtk_cell_type[dim]));
-#else
-    std::vector<unsigned int> cell_types (n_cells,
-                                          vtk_cell_type[dim]);
-#endif
-    // this should compress well :-)
-    vtu_out << cell_types;
+    AssertThrow (out, ExcIO());
+    out << " </UnstructuredGrid>\n";
+    out << "</VTKFile>\n";
   }
-  out << "\n";
-  out << "    </DataArray>\n";
-  out << "  </Cells>\n";
 
 
-  ///////////////////////////////////////
-  // data output.
 
-  // now write the data vectors to
-  // @p{out} first make sure that all
-  // data is in place
-  reorder_task.join ();
+  template <int dim, int spacedim>
+  void
+  write_vtu (const std::vector<Patch<dim,spacedim> > &patches,
+             const std::vector<std::string>          &data_names,
+             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+             const VtkFlags                          &flags,
+             std::ostream                            &out)
+  {
+    write_vtu_header(out, flags);
+    write_vtu_main (patches, data_names, vector_data_ranges, flags, out);
+    write_vtu_footer(out);
 
-  // then write data.  the
-  // 'POINT_DATA' means: node data
-  // (as opposed to cell data, which
-  // we do not support explicitly
-  // here). all following data sets
-  // are point data
-  out << "  <PointData Scalars=\"scalars\">\n";
+    out << std::flush;
+  }
 
-  // when writing, first write out
-  // all vector data, then handle the
-  // scalar data sets that have been
-  // left over
-  std::vector<bool> data_set_written (n_data_sets, false);
-  for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
-    {
-      AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
-                   std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
-                   ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
-                                  std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
-      AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
-                   ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
-                                  0, n_data_sets));
-      AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
-                   - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
-                   ExcMessage ("Can't declare a vector with more than 3 components "
-                               "in VTK"));
 
-      // mark these components as already
-      // written:
-      for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
-           i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
-           ++i)
-        data_set_written[i] = true;
+  template <int dim, int spacedim>
+  void write_vtu_main (const std::vector<Patch<dim,spacedim> > &patches,
+                       const std::vector<std::string>          &data_names,
+                       const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                       const VtkFlags                          &flags,
+                       std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
 
-      // write the
-      // header. concatenate all the
-      // component names with double
-      // underscores unless a vector
-      // name has been specified
-      out << "    <DataArray type=\"Float64\" Name=\"";
+#ifndef DEAL_II_WITH_MPI
+    // verify that there are indeed
+    // patches to be written out. most
+    // of the times, people just forget
+    // to call build_patches when there
+    // are no patches, so a warning is
+    // in order. that said, the
+    // assertion is disabled if we
+    // support MPI since then it can
+    // happen that on the coarsest
+    // mesh, a processor simply has no
+    // cells it actually owns, and in
+    // that case it is legit if there
+    // are no patches
+    Assert (patches.size() > 0, ExcNoPatches());
+#else
+    if (patches.size() == 0)
+      {
+        // we still need to output a valid vtu file, because other CPUs
+        // might output data. This is the minimal file that is accepted by paraview and visit.
+        // if we remove the field definitions, visit is complaining.
+        out << "<Piece NumberOfPoints=\"0\" NumberOfCells=\"0\" >\n"
+            << "<Cells>\n"
+            << "<DataArray type=\"UInt8\" Name=\"types\"></DataArray>\n"
+            << "</Cells>\n"
+            << "  <PointData Scalars=\"scalars\">\n";
+        std::vector<bool> data_set_written (data_names.size(), false);
+        for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
+          {
+            // mark these components as already
+            // written:
+            for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+                 i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+                 ++i)
+              data_set_written[i] = true;
+
+            // write the
+            // header. concatenate all the
+            // component names with double
+            // underscores unless a vector
+            // name has been specified
+            out << "    <DataArray type=\"Float64\" Name=\"";
+
+            if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
+              out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+            else
+              {
+                for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+                     i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+                     ++i)
+                  out << data_names[i] << "__";
+                out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+              }
 
-      if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
-        out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
-      else
+            out << "\" NumberOfComponents=\"3\"></DataArray>\n";
+          }
+
+        for (unsigned int data_set=0; data_set<data_names.size(); ++data_set)
+          if (data_set_written[data_set] == false)
+            {
+              out << "    <DataArray type=\"Float64\" Name=\""
+                  << data_names[data_set]
+                  << "\"></DataArray>\n";
+            }
+
+        out << "  </PointData>\n";
+        out << "</Piece>\n";
+
+        out << std::flush;
+
+        return;
+      }
+#endif
+
+    // first up: metadata
+    //
+    // if desired, output time and cycle of the simulation, following
+    // the instructions at
+    // http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
+    {
+      const unsigned int
+      n_metadata = ((flags.cycle != std::numeric_limits<unsigned int>::min() ? 1 : 0)
+                    +
+                    (flags.time != std::numeric_limits<double>::min() ? 1 : 0));
+      if (n_metadata > 0)
+        out << "<FieldData>\n";
+
+      if (flags.cycle != std::numeric_limits<unsigned int>::min())
         {
-          for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
-               i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
-               ++i)
-            out << data_names[i] << "__";
-          out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+          out << "<DataArray type=\"Float32\" Name=\"CYCLE\" NumberOfTuples=\"1\" format=\"ascii\">"
+              << flags.cycle
+              << "</DataArray>\n";
         }
+      if (flags.time != std::numeric_limits<double>::min())
+        {
+          out << "<DataArray type=\"Float32\" Name=\"TIME\" NumberOfTuples=\"1\" format=\"ascii\">"
+              << flags.time
+              << "</DataArray>\n";
+        }
+
+      if (n_metadata > 0)
+        out << "</FieldData>\n";
+    }
+
+
+    VtuStream vtu_out(out, flags);
+
+    const unsigned int n_data_sets = data_names.size();
+    // check against # of data sets in
+    // first patch. checks against all
+    // other patches are made in
+    // write_gmv_reorder_data_vectors
+    Assert ((patches[0].data.n_rows() == n_data_sets && !patches[0].points_are_available) ||
+            (patches[0].data.n_rows() == n_data_sets+spacedim && patches[0].points_are_available),
+            ExcDimensionMismatch (patches[0].points_are_available
+                                  ?
+                                  (n_data_sets + spacedim)
+                                  :
+                                  n_data_sets,
+                                  patches[0].data.n_rows()));
+
+
+#ifdef DEAL_II_WITH_ZLIB
+    const char *ascii_or_binary = "binary";
+#else
+    const char *ascii_or_binary = "ascii";
+#endif
 
-      out << "\" NumberOfComponents=\"3\" format=\""
-          << ascii_or_binary << "\">\n";
 
-      // now write data. pad all
-      // vectors to have three
-      // components
-      std::vector<double> data;
-      data.reserve (n_nodes*dim);
+    // first count the number of cells
+    // and cells for later use
+    unsigned int n_nodes;
+    unsigned int n_cells;
+    compute_sizes<dim,spacedim>(patches, n_nodes, n_cells);
+    // in gmv format the vertex
+    // coordinates and the data have an
+    // order that is a bit unpleasant
+    // (first all x coordinates, then
+    // all y coordinate, ...; first all
+    // data of variable 1, then
+    // variable 2, etc), so we have to
+    // copy the data vectors a bit around
+    //
+    // note that we copy vectors when
+    // looping over the patches since we
+    // have to write them one variable
+    // at a time and don't want to use
+    // more than one loop
+    //
+    // this copying of data vectors can
+    // be done while we already output
+    // the vertices, so do this on a
+    // separate task and when wanting
+    // to write out the data, we wait
+    // for that task to finish
+    Table<2,double> data_vectors (n_data_sets, n_nodes);
+
+    void (*fun_ptr) (const std::vector<Patch<dim,spacedim> > &,
+                     Table<2,double> &)
+      = &write_gmv_reorder_data_vectors<dim,spacedim>;
+    Threads::Task<> reorder_task = Threads::new_task (fun_ptr, patches,
+                                                      data_vectors);
+
+    ///////////////////////////////
+    // first make up a list of used
+    // vertices along with their
+    // coordinates
+    //
+    // note that according to the standard, we
+    // have to print d=1..3 dimensions, even if
+    // we are in reality in 2d, for example
+    out << "<Piece NumberOfPoints=\"" << n_nodes
+        <<"\" NumberOfCells=\"" << n_cells << "\" >\n";
+    out << "  <Points>\n";
+    out << "    <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\""
+        << ascii_or_binary << "\">\n";
+    write_nodes(patches, vtu_out);
+    out << "    </DataArray>\n";
+    out << "  </Points>\n\n";
+    /////////////////////////////////
+    // now for the cells
+    out << "  <Cells>\n";
+    out << "    <DataArray type=\"Int32\" Name=\"connectivity\" format=\""
+        << ascii_or_binary << "\">\n";
+    write_cells(patches, vtu_out);
+    out << "    </DataArray>\n";
+
+    // XML VTU format uses offsets; this is
+    // different than the VTK format, which
+    // puts the number of nodes per cell in
+    // front of the connectivity list.
+    out << "    <DataArray type=\"Int32\" Name=\"offsets\" format=\""
+        << ascii_or_binary << "\">\n";
+
+    std::vector<int32_t> offsets (n_cells);
+    for (unsigned int i=0; i<n_cells; ++i)
+      offsets[i] = (i+1)*GeometryInfo<dim>::vertices_per_cell;
+    vtu_out << offsets;
+    out << "\n";
+    out << "    </DataArray>\n";
+
+    // next output the types of the
+    // cells. since all cells are
+    // the same, this is simple
+    out << "    <DataArray type=\"UInt8\" Name=\"types\" format=\""
+        << ascii_or_binary << "\">\n";
 
-      for (unsigned int n=0; n<n_nodes; ++n)
-        {
-          switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
-                  std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
-            {
-            case 0:
-              data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
-              data.push_back (0);
-              data.push_back (0);
-              break;
-
-            case 1:
-              data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n));
-              data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
-              data.push_back (0);
-              break;
-            case 2:
-              data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n));
-              data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
-              data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n));
-              break;
-
-            default:
-              // VTK doesn't
-              // support
-              // anything else
-              // than vectors
-              // with 1, 2, or
-              // 3 components
-              Assert (false, ExcInternalError());
-            }
-        }
-      vtu_out << data;
-      out << "    </DataArray>\n";
+    {
+      // uint8_t might be a typedef to unsigned
+      // char which is then not printed as
+      // ascii integers
+#ifdef DEAL_II_WITH_ZLIB
+      std::vector<uint8_t> cell_types (n_cells,
+                                       static_cast<uint8_t>(vtk_cell_type[dim]));
+#else
+      std::vector<unsigned int> cell_types (n_cells,
+                                            vtk_cell_type[dim]);
+#endif
+      // this should compress well :-)
+      vtu_out << cell_types;
     }
-
-  // now do the left over scalar data sets
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    if (data_set_written[data_set] == false)
+    out << "\n";
+    out << "    </DataArray>\n";
+    out << "  </Cells>\n";
+
+
+    ///////////////////////////////////////
+    // data output.
+
+    // now write the data vectors to
+    // @p{out} first make sure that all
+    // data is in place
+    reorder_task.join ();
+
+    // then write data.  the
+    // 'POINT_DATA' means: node data
+    // (as opposed to cell data, which
+    // we do not support explicitly
+    // here). all following data sets
+    // are point data
+    out << "  <PointData Scalars=\"scalars\">\n";
+
+    // when writing, first write out
+    // all vector data, then handle the
+    // scalar data sets that have been
+    // left over
+    std::vector<bool> data_set_written (n_data_sets, false);
+    for (unsigned int n_th_vector=0; n_th_vector<vector_data_ranges.size(); ++n_th_vector)
       {
-        out << "    <DataArray type=\"Float64\" Name=\""
-            << data_names[data_set]
-            << "\" format=\""
+        AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) >=
+                     std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),
+                     ExcLowerRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+                                    std_cxx1x::get<0>(vector_data_ranges[n_th_vector])));
+        AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) < n_data_sets,
+                     ExcIndexRange (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]),
+                                    0, n_data_sets));
+        AssertThrow (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) + 1
+                     - std_cxx1x::get<0>(vector_data_ranges[n_th_vector]) <= 3,
+                     ExcMessage ("Can't declare a vector with more than 3 components "
+                                 "in VTK"));
+
+        // mark these components as already
+        // written:
+        for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+             i<=std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+             ++i)
+          data_set_written[i] = true;
+
+        // write the
+        // header. concatenate all the
+        // component names with double
+        // underscores unless a vector
+        // name has been specified
+        out << "    <DataArray type=\"Float64\" Name=\"";
+
+        if (std_cxx1x::get<2>(vector_data_ranges[n_th_vector]) != "")
+          out << std_cxx1x::get<2>(vector_data_ranges[n_th_vector]);
+        else
+          {
+            for (unsigned int i=std_cxx1x::get<0>(vector_data_ranges[n_th_vector]);
+                 i<std_cxx1x::get<1>(vector_data_ranges[n_th_vector]);
+                 ++i)
+              out << data_names[i] << "__";
+            out << data_names[std_cxx1x::get<1>(vector_data_ranges[n_th_vector])];
+          }
+
+        out << "\" NumberOfComponents=\"3\" format=\""
             << ascii_or_binary << "\">\n";
 
-        std::vector<double> data (data_vectors[data_set].begin(),
-                                  data_vectors[data_set].end());
+        // now write data. pad all
+        // vectors to have three
+        // components
+        std::vector<double> data;
+        data.reserve (n_nodes*dim);
+
+        for (unsigned int n=0; n<n_nodes; ++n)
+          {
+            switch (std_cxx1x::get<1>(vector_data_ranges[n_th_vector]) -
+                    std_cxx1x::get<0>(vector_data_ranges[n_th_vector]))
+              {
+              case 0:
+                data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]), n));
+                data.push_back (0);
+                data.push_back (0);
+                break;
+
+              case 1:
+                data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n));
+                data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
+                data.push_back (0);
+                break;
+              case 2:
+                data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector]),   n));
+                data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+1, n));
+                data.push_back (data_vectors(std_cxx1x::get<0>(vector_data_ranges[n_th_vector])+2, n));
+                break;
+
+              default:
+                // VTK doesn't
+                // support
+                // anything else
+                // than vectors
+                // with 1, 2, or
+                // 3 components
+                Assert (false, ExcInternalError());
+              }
+          }
         vtu_out << data;
         out << "    </DataArray>\n";
       }
 
-  out << "  </PointData>\n";
+    // now do the left over scalar data sets
+    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+      if (data_set_written[data_set] == false)
+        {
+          out << "    <DataArray type=\"Float64\" Name=\""
+              << data_names[data_set]
+              << "\" format=\""
+              << ascii_or_binary << "\">\n";
+
+          std::vector<double> data (data_vectors[data_set].begin(),
+                                    data_vectors[data_set].end());
+          vtu_out << data;
+          out << "    </DataArray>\n";
+        }
+
+    out << "  </PointData>\n";
 
-  // Finish up writing a valid XML file
-  out << " </Piece>\n";
+    // Finish up writing a valid XML file
+    out << " </Piece>\n";
 
-  // make sure everything now gets to
-  // disk
-  out.flush ();
+    // make sure everything now gets to
+    // disk
+    out.flush ();
 
-  // assert the stream is still ok
-  AssertThrow (out, ExcIO());
-}
+    // assert the stream is still ok
+    AssertThrow (out, ExcIO());
+  }
 
-template <>
-void DataOutBase::write_svg<1,1> (const std::vector<Patch<1,1> > &patches,
-                                  const std::vector<std::string> &data_names,
-                                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                                  const SvgFlags &flags,
-                                  std::ostream &out)
-{
-  AssertThrow (false, ExcNotImplemented());
-}
 
+  template <int dim, int spacedim>
+  void write_svg (const std::vector<Patch<dim,spacedim> > &,
+                  const std::vector<std::string> &,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &,
+                  const SvgFlags &,
+                  std::ostream &)
+  {
+    Assert (false, ExcNotImplemented());
+  }
 
-template <int dim, int spacedim>
-void DataOutBase::write_svg (const std::vector<Patch<dim,spacedim> > &patches,
-                             const std::vector<std::string> &data_names,
-                             const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                             const SvgFlags &flags,
-                             std::ostream &out)
-{
-  // do not allow volume rendering
-  AssertThrow (dim==2, ExcNotImplemented());
+  template <int spacedim>
+  void write_svg (const std::vector<Patch<2,spacedim> > &patches,
+                  const std::vector<std::string> &data_names,
+                  const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                  const SvgFlags &flags,
+                  std::ostream &out)
+  {
+    const int dim = 2;
+    const unsigned int height = flags.height;
+    unsigned int width = flags.width;
+
+    // margin around the plotted area
+    unsigned int margin_in_percent = 0;
+    if (flags.margin) margin_in_percent = 5;
 
-  const unsigned int height = flags.height;
-  unsigned int width = flags.width;
 
-  // margin around the plotted area
-  unsigned int margin_in_percent = 0;
-  if (flags.margin) margin_in_percent = 5;
+    // determine the bounding box in the model space
+    double x_dimension, y_dimension, z_dimension;
 
+    typename std::vector<Patch<dim,spacedim> >::const_iterator patch = patches.begin();
 
-  // determine the bounding box in the model space
-  double x_dimension, y_dimension, z_dimension;
+    unsigned int n_subdivisions = patch->n_subdivisions;
+    unsigned int n = n_subdivisions + 1;
+    const unsigned int d1 = 1;
+    const unsigned int d2 = n;
 
-  typename std::vector<Patch<dim,spacedim> >::const_iterator patch = patches.begin();
+    Point<spacedim> projected_point;
+    Point<spacedim> projected_points[4];
 
-  unsigned int n_subdivisions = patch->n_subdivisions;
-  unsigned int n = n_subdivisions + 1;
-  const unsigned int d1 = 1;
-  const unsigned int d2 = n;
+    Point<2> projection_decomposition;
+    Point<2> projection_decompositions[4];
 
-  Point<spacedim> projected_point;
-  Point<spacedim> projected_points[4];
+    compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
 
-  Point<2> projection_decomposition;
-  Point<2> projection_decompositions[4];
+    Assert ((flags.height_vector < patch->data.n_rows()) ||
+            patch->data.n_rows() == 0,
+            ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
 
-  compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
+    double x_min = projected_point[0];
+    double x_max = x_min;
+    double y_min = projected_point[1];
+    double y_max = y_min;
+    double z_min = patch->data.n_rows() != 0 ? patch->data(flags.height_vector,0) : 0;
+    double z_max = z_min;
 
-  Assert ((flags.height_vector < patch->data.n_rows()) ||
-          patch->data.n_rows() == 0,
-          ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+    // iterate over the patches
+    for (; patch != patches.end(); ++patch)
+      {
+        n_subdivisions = patch->n_subdivisions;
+        n = n_subdivisions + 1;
 
-  double x_min = projected_point[0];
-  double x_max = x_min;
-  double y_min = projected_point[1];
-  double y_max = y_min;
-  double z_min = patch->data.n_rows() != 0 ? patch->data(flags.height_vector,0) : 0;
-  double z_max = z_min;
+        for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
+          {
+            for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
+              {
+                compute_node(projected_points[0], &*patch, i1, i2, 0, n_subdivisions);
+                compute_node(projected_points[1], &*patch, i1+1, i2, 0, n_subdivisions);
+                compute_node(projected_points[2], &*patch, i1, i2+1, 0, n_subdivisions);
+                compute_node(projected_points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
+
+                x_min = std::min(x_min, (double)projected_points[0][0]);
+                x_min = std::min(x_min, (double)projected_points[1][0]);
+                x_min = std::min(x_min, (double)projected_points[2][0]);
+                x_min = std::min(x_min, (double)projected_points[3][0]);
+
+                x_max = std::max(x_max, (double)projected_points[0][0]);
+                x_max = std::max(x_max, (double)projected_points[1][0]);
+                x_max = std::max(x_max, (double)projected_points[2][0]);
+                x_max = std::max(x_max, (double)projected_points[3][0]);
+
+                y_min = std::min(y_min, (double)projected_points[0][1]);
+                y_min = std::min(y_min, (double)projected_points[1][1]);
+                y_min = std::min(y_min, (double)projected_points[2][1]);
+                y_min = std::min(y_min, (double)projected_points[3][1]);
+
+                y_max = std::max(y_max, (double)projected_points[0][1]);
+                y_max = std::max(y_max, (double)projected_points[1][1]);
+                y_max = std::max(y_max, (double)projected_points[2][1]);
+                y_max = std::max(y_max, (double)projected_points[3][1]);
 
-  // iterate over the patches
-  for (; patch != patches.end(); ++patch)
-    {
-      n_subdivisions = patch->n_subdivisions;
-      n = n_subdivisions + 1;
+                Assert ((flags.height_vector < patch->data.n_rows()) ||
+                        patch->data.n_rows() == 0,
+                        ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
 
-      for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
-        {
-          for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
-            {
-              compute_node(projected_points[0], &*patch, i1, i2, 0, n_subdivisions);
-              compute_node(projected_points[1], &*patch, i1+1, i2, 0, n_subdivisions);
-              compute_node(projected_points[2], &*patch, i1, i2+1, 0, n_subdivisions);
-              compute_node(projected_points[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
-              x_min = std::min(x_min, (double)projected_points[0][0]);
-              x_min = std::min(x_min, (double)projected_points[1][0]);
-              x_min = std::min(x_min, (double)projected_points[2][0]);
-              x_min = std::min(x_min, (double)projected_points[3][0]);
-
-              x_max = std::max(x_max, (double)projected_points[0][0]);
-              x_max = std::max(x_max, (double)projected_points[1][0]);
-              x_max = std::max(x_max, (double)projected_points[2][0]);
-              x_max = std::max(x_max, (double)projected_points[3][0]);
-
-              y_min = std::min(y_min, (double)projected_points[0][1]);
-              y_min = std::min(y_min, (double)projected_points[1][1]);
-              y_min = std::min(y_min, (double)projected_points[2][1]);
-              y_min = std::min(y_min, (double)projected_points[3][1]);
-
-              y_max = std::max(y_max, (double)projected_points[0][1]);
-              y_max = std::max(y_max, (double)projected_points[1][1]);
-              y_max = std::max(y_max, (double)projected_points[2][1]);
-              y_max = std::max(y_max, (double)projected_points[3][1]);
-
-              Assert ((flags.height_vector < patch->data.n_rows()) ||
-                      patch->data.n_rows() == 0,
-                      ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
-
-              z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
-              z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
-              z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
-              z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
-
-              z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
-              z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
-              z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
-              z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
-            }
-        }
-    }
+                z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
+                z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
+                z_min = std::min(z_min, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
+                z_min = std::min(z_min, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
+
+                z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + i2*d2));
+                z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + i2*d2));
+                z_max = std::max(z_max, (double)patch->data(flags.height_vector, i1*d1 + (i2+1)*d2));
+                z_max = std::max(z_max, (double)patch->data(flags.height_vector, (i1+1)*d1 + (i2+1)*d2));
+              }
+          }
+      }
 
-  x_dimension = x_max - x_min;
-  y_dimension = y_max - y_min;
-  z_dimension = z_max - z_min;
+    x_dimension = x_max - x_min;
+    y_dimension = y_max - y_min;
+    z_dimension = z_max - z_min;
 
 
 // set initial camera position
-  Point<3> camera_position(true);
-  Point<3> camera_direction(true);
-  Point<3> camera_horizontal(true);
-  float camera_focus = 0;
+    Point<3> camera_position(true);
+    Point<3> camera_direction(true);
+    Point<3> camera_horizontal(true);
+    float camera_focus = 0;
 
-  // translate camera from the origin to the initial position
-  camera_position[0] = 0.;
-  camera_position[1] = 0.;
-  camera_position[2] = z_min + 2. * z_dimension;
+    // translate camera from the origin to the initial position
+    camera_position[0] = 0.;
+    camera_position[1] = 0.;
+    camera_position[2] = z_min + 2. * z_dimension;
 
-  camera_direction[0] = 0.;
-  camera_direction[1] = 0.;
-  camera_direction[2] = - 1.;
+    camera_direction[0] = 0.;
+    camera_direction[1] = 0.;
+    camera_direction[2] = - 1.;
 
-  camera_horizontal[0] = 1.;
-  camera_horizontal[1] = 0.;
-  camera_horizontal[2] = 0.;
+    camera_horizontal[0] = 1.;
+    camera_horizontal[1] = 0.;
+    camera_horizontal[2] = 0.;
 
-  camera_focus = .5 * z_dimension;
+    camera_focus = .5 * z_dimension;
 
-  Point<3> camera_position_temp;
-  Point<3> camera_direction_temp;
-  Point<3> camera_horizontal_temp;
+    Point<3> camera_position_temp;
+    Point<3> camera_direction_temp;
+    Point<3> camera_horizontal_temp;
 
-  const float angle_factor = 3.14159265 / 180.;
+    const float angle_factor = 3.14159265 / 180.;
 
-  // (I) rotate the camera to the chosen polar angle
-  camera_position_temp[1] = cos(angle_factor * flags.polar_angle) * camera_position[1] - sin(angle_factor * flags.polar_angle) * camera_position[2];
-  camera_position_temp[2] = sin(angle_factor * flags.polar_angle) * camera_position[1] + cos(angle_factor * flags.polar_angle) * camera_position[2];
+    // (I) rotate the camera to the chosen polar angle
+    camera_position_temp[1] = cos(angle_factor * flags.polar_angle) * camera_position[1] - sin(angle_factor * flags.polar_angle) * camera_position[2];
+    camera_position_temp[2] = sin(angle_factor * flags.polar_angle) * camera_position[1] + cos(angle_factor * flags.polar_angle) * camera_position[2];
 
-  camera_direction_temp[1] = cos(angle_factor * flags.polar_angle) * camera_direction[1] - sin(angle_factor * flags.polar_angle) * camera_direction[2];
-  camera_direction_temp[2] = sin(angle_factor * flags.polar_angle) * camera_direction[1] + cos(angle_factor * flags.polar_angle) * camera_direction[2];
+    camera_direction_temp[1] = cos(angle_factor * flags.polar_angle) * camera_direction[1] - sin(angle_factor * flags.polar_angle) * camera_direction[2];
+    camera_direction_temp[2] = sin(angle_factor * flags.polar_angle) * camera_direction[1] + cos(angle_factor * flags.polar_angle) * camera_direction[2];
 
-  camera_horizontal_temp[1] = cos(angle_factor * flags.polar_angle) * camera_horizontal[1] - sin(angle_factor * flags.polar_angle) * camera_horizontal[2];
-  camera_horizontal_temp[2] = sin(angle_factor * flags.polar_angle) * camera_horizontal[1] + cos(angle_factor * flags.polar_angle) * camera_horizontal[2];
+    camera_horizontal_temp[1] = cos(angle_factor * flags.polar_angle) * camera_horizontal[1] - sin(angle_factor * flags.polar_angle) * camera_horizontal[2];
+    camera_horizontal_temp[2] = sin(angle_factor * flags.polar_angle) * camera_horizontal[1] + cos(angle_factor * flags.polar_angle) * camera_horizontal[2];
 
-  camera_position[1] = camera_position_temp[1];
-  camera_position[2] = camera_position_temp[2];
+    camera_position[1] = camera_position_temp[1];
+    camera_position[2] = camera_position_temp[2];
 
-  camera_direction[1] = camera_direction_temp[1];
-  camera_direction[2] = camera_direction_temp[2];
+    camera_direction[1] = camera_direction_temp[1];
+    camera_direction[2] = camera_direction_temp[2];
 
-  camera_horizontal[1] = camera_horizontal_temp[1];
-  camera_horizontal[2] = camera_horizontal_temp[2];
+    camera_horizontal[1] = camera_horizontal_temp[1];
+    camera_horizontal[2] = camera_horizontal_temp[2];
 
-  // (II) rotate the camera to the chosen azimuth angle
-  camera_position_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_position[0] - sin(angle_factor * flags.azimuth_angle) * camera_position[1];
-  camera_position_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_position[0] + cos(angle_factor * flags.azimuth_angle) * camera_position[1];
+    // (II) rotate the camera to the chosen azimuth angle
+    camera_position_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_position[0] - sin(angle_factor * flags.azimuth_angle) * camera_position[1];
+    camera_position_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_position[0] + cos(angle_factor * flags.azimuth_angle) * camera_position[1];
 
-  camera_direction_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_direction[0] - sin(angle_factor * flags.azimuth_angle) * camera_direction[1];
-  camera_direction_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_direction[0] + cos(angle_factor * flags.azimuth_angle) * camera_direction[1];
+    camera_direction_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_direction[0] - sin(angle_factor * flags.azimuth_angle) * camera_direction[1];
+    camera_direction_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_direction[0] + cos(angle_factor * flags.azimuth_angle) * camera_direction[1];
 
-  camera_horizontal_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_horizontal[0] - sin(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
-  camera_horizontal_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_horizontal[0] + cos(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
+    camera_horizontal_temp[0] = cos(angle_factor * flags.azimuth_angle) * camera_horizontal[0] - sin(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
+    camera_horizontal_temp[1] = sin(angle_factor * flags.azimuth_angle) * camera_horizontal[0] + cos(angle_factor * flags.azimuth_angle) * camera_horizontal[1];
 
-  camera_position[0] = camera_position_temp[0];
-  camera_position[1] = camera_position_temp[1];
+    camera_position[0] = camera_position_temp[0];
+    camera_position[1] = camera_position_temp[1];
 
-  camera_direction[0] = camera_direction_temp[0];
-  camera_direction[1] = camera_direction_temp[1];
+    camera_direction[0] = camera_direction_temp[0];
+    camera_direction[1] = camera_direction_temp[1];
 
-  camera_horizontal[0] = camera_horizontal_temp[0];
-  camera_horizontal[1] = camera_horizontal_temp[1];
+    camera_horizontal[0] = camera_horizontal_temp[0];
+    camera_horizontal[1] = camera_horizontal_temp[1];
 
-  // (III) translate the camera
-  camera_position[0] = x_min + .5 * x_dimension;
-  camera_position[1] = y_min + .5 * y_dimension;
+    // (III) translate the camera
+    camera_position[0] = x_min + .5 * x_dimension;
+    camera_position[1] = y_min + .5 * y_dimension;
 
-  camera_position[0] += (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * sin(angle_factor * flags.azimuth_angle);
-  camera_position[1] -= (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * cos(angle_factor * flags.azimuth_angle);
+    camera_position[0] += (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * sin(angle_factor * flags.azimuth_angle);
+    camera_position[1] -= (z_min + 2. * z_dimension) * sin(angle_factor * flags.polar_angle) * cos(angle_factor * flags.azimuth_angle);
 
 
 // determine the bounding box on the projection plane
-  double x_min_perspective, y_min_perspective;
-  double x_max_perspective, y_max_perspective;
-  double x_dimension_perspective, y_dimension_perspective;
-
-  patch = patches.begin();
+    double x_min_perspective, y_min_perspective;
+    double x_max_perspective, y_max_perspective;
+    double x_dimension_perspective, y_dimension_perspective;
 
-  n_subdivisions = patch->n_subdivisions;
-  n = n_subdivisions + 1;
+    patch = patches.begin();
 
-  Point<3> point(true);
+    n_subdivisions = patch->n_subdivisions;
+    n = n_subdivisions + 1;
 
-  compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
+    Point<3> point(true);
 
-  Assert ((flags.height_vector < patch->data.n_rows()) ||
-          patch->data.n_rows() == 0,
-          ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+    compute_node(projected_point, &*patch, 0, 0, 0, n_subdivisions);
 
-  point[0] = projected_point[0];
-  point[1] = projected_point[1];
-  point[2] = patch->data.n_rows() != 0 ? patch->data(flags.height_vector, 0) : 0;
+    Assert ((flags.height_vector < patch->data.n_rows()) ||
+            patch->data.n_rows() == 0,
+            ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
 
-  projection_decomposition = svg_project_point(point, camera_position, camera_direction, camera_horizontal, camera_focus);
+    point[0] = projected_point[0];
+    point[1] = projected_point[1];
+    point[2] = patch->data.n_rows() != 0 ? patch->data(flags.height_vector, 0) : 0;
 
-  x_min_perspective = projection_decomposition[0];
-  x_max_perspective = projection_decomposition[0];
-  y_min_perspective = projection_decomposition[1];
-  y_max_perspective = projection_decomposition[1];
+    projection_decomposition = svg_project_point(point, camera_position, camera_direction, camera_horizontal, camera_focus);
 
-  // iterate over the patches
-  for (; patch != patches.end(); ++patch)
-    {
-      n_subdivisions = patch->n_subdivisions;
-      n = n_subdivisions + 1;
+    x_min_perspective = projection_decomposition[0];
+    x_max_perspective = projection_decomposition[0];
+    y_min_perspective = projection_decomposition[1];
+    y_max_perspective = projection_decomposition[1];
 
-      for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
-        {
-          for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
-            {
-              Point<spacedim> projected_vertices[4];
-              Point<3> vertices[4];
-
-              compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
-              compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
-              compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
-              compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
-
-              Assert ((flags.height_vector < patch->data.n_rows()) ||
-                      patch->data.n_rows() == 0,
-                      ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
-
-              vertices[0][0] = projected_vertices[0][0];
-              vertices[0][1] = projected_vertices[0][1];
-              vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
-
-              vertices[1][0] = projected_vertices[1][0];
-              vertices[1][1] = projected_vertices[1][1];
-              vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
-
-              vertices[2][0] = projected_vertices[2][0];
-              vertices[2][1] = projected_vertices[2][1];
-              vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
-
-              vertices[3][0] = projected_vertices[3][0];
-              vertices[3][1] = projected_vertices[3][1];
-              vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
-
-              projection_decompositions[0] = svg_project_point(vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
-              projection_decompositions[1] = svg_project_point(vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
-              projection_decompositions[2] = svg_project_point(vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
-              projection_decompositions[3] = svg_project_point(vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
-
-              x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[0][0]);
-              x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[1][0]);
-              x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[2][0]);
-              x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[3][0]);
-
-              x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[0][0]);
-              x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[1][0]);
-              x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[2][0]);
-              x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[3][0]);
-
-              y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[0][1]);
-              y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[1][1]);
-              y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[2][1]);
-              y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[3][1]);
-
-              y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[0][1]);
-              y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[1][1]);
-              y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[2][1]);
-              y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[3][1]);
-            }
-        }
-    }
+    // iterate over the patches
+    for (; patch != patches.end(); ++patch)
+      {
+        n_subdivisions = patch->n_subdivisions;
+        n = n_subdivisions + 1;
 
-  x_dimension_perspective = x_max_perspective - x_min_perspective;
-  y_dimension_perspective = y_max_perspective - y_min_perspective;
+        for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
+          {
+            for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
+              {
+                Point<spacedim> projected_vertices[4];
+                Point<3> vertices[4];
 
-  std::multiset<SvgCell> cells;
+                compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
+                compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
+                compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
+                compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
 
-  // iterate over the patches
-  for (patch = patches.begin(); patch != patches.end(); ++patch)
-    {
-      n_subdivisions = patch->n_subdivisions;
-      n = n_subdivisions + 1;
+                Assert ((flags.height_vector < patch->data.n_rows()) ||
+                        patch->data.n_rows() == 0,
+                        ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+
+                vertices[0][0] = projected_vertices[0][0];
+                vertices[0][1] = projected_vertices[0][1];
+                vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
+
+                vertices[1][0] = projected_vertices[1][0];
+                vertices[1][1] = projected_vertices[1][1];
+                vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
+
+                vertices[2][0] = projected_vertices[2][0];
+                vertices[2][1] = projected_vertices[2][1];
+                vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
+
+                vertices[3][0] = projected_vertices[3][0];
+                vertices[3][1] = projected_vertices[3][1];
+                vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
+
+                projection_decompositions[0] = svg_project_point(vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
+                projection_decompositions[1] = svg_project_point(vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
+                projection_decompositions[2] = svg_project_point(vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
+                projection_decompositions[3] = svg_project_point(vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
+
+                x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[0][0]);
+                x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[1][0]);
+                x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[2][0]);
+                x_min_perspective = std::min(x_min_perspective, (double)projection_decompositions[3][0]);
+
+                x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[0][0]);
+                x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[1][0]);
+                x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[2][0]);
+                x_max_perspective = std::max(x_max_perspective, (double)projection_decompositions[3][0]);
+
+                y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[0][1]);
+                y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[1][1]);
+                y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[2][1]);
+                y_min_perspective = std::min(y_min_perspective, (double)projection_decompositions[3][1]);
+
+                y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[0][1]);
+                y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[1][1]);
+                y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[2][1]);
+                y_max_perspective = std::max(y_max_perspective, (double)projection_decompositions[3][1]);
+              }
+          }
+      }
 
-      for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
-        {
-          for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
-            {
-              Point<spacedim> projected_vertices[4];
-              SvgCell cell;
+    x_dimension_perspective = x_max_perspective - x_min_perspective;
+    y_dimension_perspective = y_max_perspective - y_min_perspective;
 
-              compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
-              compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
-              compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
-              compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
+    std::multiset<SvgCell> cells;
 
-              Assert ((flags.height_vector < patch->data.n_rows()) ||
-                      patch->data.n_rows() == 0,
-                      ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
+    // iterate over the patches
+    for (patch = patches.begin(); patch != patches.end(); ++patch)
+      {
+        n_subdivisions = patch->n_subdivisions;
+        n = n_subdivisions + 1;
 
-              cell.vertices[0][0] = projected_vertices[0][0];
-              cell.vertices[0][1] = projected_vertices[0][1];
-              cell.vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
+        for (unsigned int i2 = 0; i2 < n_subdivisions; ++i2)
+          {
+            for (unsigned int i1 = 0; i1 < n_subdivisions; ++i1)
+              {
+                Point<spacedim> projected_vertices[4];
+                SvgCell cell;
 
-              cell.vertices[1][0] = projected_vertices[1][0];
-              cell.vertices[1][1] = projected_vertices[1][1];
-              cell.vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
+                compute_node(projected_vertices[0], &*patch, i1, i2, 0, n_subdivisions);
+                compute_node(projected_vertices[1], &*patch, i1+1, i2, 0, n_subdivisions);
+                compute_node(projected_vertices[2], &*patch, i1, i2+1, 0, n_subdivisions);
+                compute_node(projected_vertices[3], &*patch, i1+1, i2+1, 0, n_subdivisions);
 
-              cell.vertices[2][0] = projected_vertices[2][0];
-              cell.vertices[2][1] = projected_vertices[2][1];
-              cell.vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
+                Assert ((flags.height_vector < patch->data.n_rows()) ||
+                        patch->data.n_rows() == 0,
+                        ExcIndexRange (flags.height_vector, 0, patch->data.n_rows()));
 
-              cell.vertices[3][0] = projected_vertices[3][0];
-              cell.vertices[3][1] = projected_vertices[3][1];
-              cell.vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
+                cell.vertices[0][0] = projected_vertices[0][0];
+                cell.vertices[0][1] = projected_vertices[0][1];
+                cell.vertices[0][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + i2*d2) : 0;
 
-              cell.projected_vertices[0] = svg_project_point(cell.vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
-              cell.projected_vertices[1] = svg_project_point(cell.vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
-              cell.projected_vertices[2] = svg_project_point(cell.vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
-              cell.projected_vertices[3] = svg_project_point(cell.vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
+                cell.vertices[1][0] = projected_vertices[1][0];
+                cell.vertices[1][1] = projected_vertices[1][1];
+                cell.vertices[1][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + i2*d2) : 0;
 
-              cell.center = .25 * (cell.vertices[0] + cell.vertices[1] + cell.vertices[2] + cell.vertices[3]);
-              cell.projected_center = svg_project_point(cell.center, camera_position, camera_direction, camera_horizontal, camera_focus);
+                cell.vertices[2][0] = projected_vertices[2][0];
+                cell.vertices[2][1] = projected_vertices[2][1];
+                cell.vertices[2][2] = patch->data.n_rows() != 0 ? patch->data(0,i1*d1 + (i2+1)*d2) : 0;
 
-              cell.depth = cell.center.distance(camera_position);
+                cell.vertices[3][0] = projected_vertices[3][0];
+                cell.vertices[3][1] = projected_vertices[3][1];
+                cell.vertices[3][2] = patch->data.n_rows() != 0 ? patch->data(0,(i1+1)*d1 + (i2+1)*d2) : 0;
 
-              cells.insert(cell);
-            }
-        }
-    }
+                cell.projected_vertices[0] = svg_project_point(cell.vertices[0], camera_position, camera_direction, camera_horizontal, camera_focus);
+                cell.projected_vertices[1] = svg_project_point(cell.vertices[1], camera_position, camera_direction, camera_horizontal, camera_focus);
+                cell.projected_vertices[2] = svg_project_point(cell.vertices[2], camera_position, camera_direction, camera_horizontal, camera_focus);
+                cell.projected_vertices[3] = svg_project_point(cell.vertices[3], camera_position, camera_direction, camera_horizontal, camera_focus);
 
+                cell.center = .25 * (cell.vertices[0] + cell.vertices[1] + cell.vertices[2] + cell.vertices[3]);
+                cell.projected_center = svg_project_point(cell.center, camera_position, camera_direction, camera_horizontal, camera_focus);
 
-// write the svg file
-  if (width==0)
-    width = static_cast<unsigned int>(.5 + height * (x_dimension_perspective / y_dimension_perspective));
-  unsigned int additional_width = 0;
+                cell.depth = cell.center.distance(camera_position);
 
-  if (flags.draw_colorbar) additional_width = static_cast<unsigned int>(.5 + height * .3); // additional width for colorbar
+                cells.insert(cell);
+              }
+          }
+      }
 
-  // basic svg header and background rectangle
-  out << "<svg width=\"" << width + additional_width << "\" height=\"" << height << "\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">" << '\n'
-      << " <rect width=\"" << width + additional_width << "\" height=\"" << height << "\" style=\"fill:white\"/>" << '\n' << '\n';
 
-  unsigned int triangle_counter = 0;
+    // write the svg file
+    if (width==0)
+      width = static_cast<unsigned int>(.5 + height * (x_dimension_perspective / y_dimension_perspective));
+    unsigned int additional_width = 0;
 
-  // write the cells in the correct order
-  for (typename std::multiset<SvgCell>::const_iterator cell = cells.begin(); cell != cells.end(); ++cell)
-    {
-      Point<3> points3d_triangle[3];
+    if (flags.draw_colorbar) additional_width = static_cast<unsigned int>(.5 + height * .3); // additional width for colorbar
 
-      for (unsigned int triangle_index = 0; triangle_index < 4; triangle_index++)
-        {
-          switch (triangle_index)
-            {
-            case 0:
-              points3d_triangle[0] = cell->vertices[0], points3d_triangle[1] = cell->vertices[1], points3d_triangle[2] = cell->center;
-              break;
-            case 1:
-              points3d_triangle[0] = cell->vertices[1], points3d_triangle[1] = cell->vertices[3], points3d_triangle[2] = cell->center;
-              break;
-            case 2:
-              points3d_triangle[0] = cell->vertices[3], points3d_triangle[1] = cell->vertices[2], points3d_triangle[2] = cell->center;
-              break;
-            case 3:
-              points3d_triangle[0] = cell->vertices[2], points3d_triangle[1] = cell->vertices[0], points3d_triangle[2] = cell->center;
-              break;
-            default:
-              break;
-            }
+    // basic svg header and background rectangle
+    out << "<svg width=\"" << width + additional_width << "\" height=\"" << height << "\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">" << '\n'
+        << " <rect width=\"" << width + additional_width << "\" height=\"" << height << "\" style=\"fill:white\"/>" << '\n' << '\n';
 
-          Point<6> gradient_param = svg_get_gradient_parameters(points3d_triangle);
+    unsigned int triangle_counter = 0;
 
-          double start_h = .667 - ((gradient_param[4] - z_min) / z_dimension) * .667;
-          double stop_h = .667 - ((gradient_param[5] - z_min) / z_dimension) * .667;
+    // write the cells in the correct order
+    for (typename std::multiset<SvgCell>::const_iterator cell = cells.begin(); cell != cells.end(); ++cell)
+      {
+        Point<3> points3d_triangle[3];
 
-          unsigned int start_r = 0;
-          unsigned int start_g = 0;
-          unsigned int start_b = 0;
+        for (unsigned int triangle_index = 0; triangle_index < 4; triangle_index++)
+          {
+            switch (triangle_index)
+              {
+              case 0:
+                points3d_triangle[0] = cell->vertices[0], points3d_triangle[1] = cell->vertices[1], points3d_triangle[2] = cell->center;
+                break;
+              case 1:
+                points3d_triangle[0] = cell->vertices[1], points3d_triangle[1] = cell->vertices[3], points3d_triangle[2] = cell->center;
+                break;
+              case 2:
+                points3d_triangle[0] = cell->vertices[3], points3d_triangle[1] = cell->vertices[2], points3d_triangle[2] = cell->center;
+                break;
+              case 3:
+                points3d_triangle[0] = cell->vertices[2], points3d_triangle[1] = cell->vertices[0], points3d_triangle[2] = cell->center;
+                break;
+              default:
+                break;
+              }
 
-          unsigned int stop_r = 0;
-          unsigned int stop_g = 0;
-          unsigned int stop_b = 0;
+            Point<6> gradient_param = svg_get_gradient_parameters(points3d_triangle);
 
-          unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
-          unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
+            double start_h = .667 - ((gradient_param[4] - z_min) / z_dimension) * .667;
+            double stop_h = .667 - ((gradient_param[5] - z_min) / z_dimension) * .667;
 
-          double start_f = start_h * 6. - start_i;
-          double start_q = 1. - start_f;
+            unsigned int start_r = 0;
+            unsigned int start_g = 0;
+            unsigned int start_b = 0;
 
-          double stop_f = stop_h * 6. - stop_i;
-          double stop_q = 1. - stop_f;
+            unsigned int stop_r = 0;
+            unsigned int stop_g = 0;
+            unsigned int stop_b = 0;
 
-          switch (start_i % 6)
-            {
-            case 0:
-              start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
-              break;
-            case 1:
-              start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
-              break;
-            case 2:
-              start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
-              break;
-            case 3:
-              start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
-              break;
-            case 4:
-              start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
-              break;
-            case 5:
-              start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
-              break;
-            default:
-              break;
-            }
+            unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
+            unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
 
-          switch (stop_i % 6)
-            {
-            case 0:
-              stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
-              break;
-            case 1:
-              stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
-              break;
-            case 2:
-              stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
-              break;
-            case 3:
-              stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
-              break;
-            case 4:
-              stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
-              break;
-            case 5:
-              stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
-              break;
-            default:
-              break;
-            }
+            double start_f = start_h * 6. - start_i;
+            double start_q = 1. - start_f;
 
-          Point<3> gradient_start_point_3d, gradient_stop_point_3d;
-
-          gradient_start_point_3d[0] = gradient_param[0];
-          gradient_start_point_3d[1] = gradient_param[1];
-          gradient_start_point_3d[2] = gradient_param[4];
-
-          gradient_stop_point_3d[0] = gradient_param[2];
-          gradient_stop_point_3d[1] = gradient_param[3];
-          gradient_stop_point_3d[2] = gradient_param[5];
-
-          Point<2> gradient_start_point = svg_project_point(gradient_start_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
-          Point<2> gradient_stop_point = svg_project_point(gradient_stop_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
-
-          // define linear gradient
-          out << "  <linearGradient id=\"" << triangle_counter << "\" gradientUnits=\"userSpaceOnUse\" "
-              << "x1=\""
-              << static_cast<unsigned int>(.5 + ((gradient_start_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
-              << "\" "
-              << "y1=\""
-              << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_start_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
-              << "\" "
-              << "x2=\""
-              << static_cast<unsigned int>(.5 + ((gradient_stop_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
-              << "\" "
-              << "y2=\""
-              << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_stop_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
-              << "\""
-              << ">" << '\n'
-              << "   <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
-              << "   <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
-              << "  </linearGradient>" << '\n';
-
-          // draw current triangle
-          double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
-          double x3 = cell->projected_center[0];
-          double y3 = cell->projected_center[1];
-
-          switch (triangle_index)
-            {
-            case 0:
-              x1 = cell->projected_vertices[0][0], y1 = cell->projected_vertices[0][1], x2 = cell->projected_vertices[1][0], y2 = cell->projected_vertices[1][1];
-              break;
-            case 1:
-              x1 = cell->projected_vertices[1][0], y1 = cell->projected_vertices[1][1], x2 = cell->projected_vertices[3][0], y2 = cell->projected_vertices[3][1];
-              break;
-            case 2:
-              x1 = cell->projected_vertices[3][0], y1 = cell->projected_vertices[3][1], x2 = cell->projected_vertices[2][0], y2 = cell->projected_vertices[2][1];
-              break;
-            case 3:
-              x1 = cell->projected_vertices[2][0], y1 = cell->projected_vertices[2][1], x2 = cell->projected_vertices[0][0], y2 = cell->projected_vertices[0][1];
-              break;
-            default:
-              break;
-            }
+            double stop_f = stop_h * 6. - stop_i;
+            double stop_q = 1. - stop_f;
 
-          out << "  <path d=\"M "
-              << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
-              << ' '
-              << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
-              << " L "
-              << static_cast<unsigned int>(.5 + ((x2 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
-              << ' '
-              << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y2 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
-              << " L "
-              << static_cast<unsigned int>(.5 + ((x3 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
-              << ' '
-              << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y3 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
-              << " L "
-              << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
-              << ' '
-              << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
-              << "\" style=\"stroke:black; fill:url(#" << triangle_counter << "); stroke-width:" << flags.line_thickness << "\"/>" << '\n';
-
-          triangle_counter++;
-        }
-    }
+            switch (start_i % 6)
+              {
+              case 0:
+                start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
+                break;
+              case 1:
+                start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
+                break;
+              case 2:
+                start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
+                break;
+              case 3:
+                start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
+                break;
+              case 4:
+                start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
+                break;
+              case 5:
+                start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
+                break;
+              default:
+                break;
+              }
 
+            switch (stop_i % 6)
+              {
+              case 0:
+                stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
+                break;
+              case 1:
+                stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
+                break;
+              case 2:
+                stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
+                break;
+              case 3:
+                stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
+                break;
+              case 4:
+                stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
+                break;
+              case 5:
+                stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
+                break;
+              default:
+                break;
+              }
 
-// draw the colorbar
-  if (flags.draw_colorbar)
-    {
-      out << '\n' << " <!-- colorbar -->" << '\n';
+            Point<3> gradient_start_point_3d, gradient_stop_point_3d;
+
+            gradient_start_point_3d[0] = gradient_param[0];
+            gradient_start_point_3d[1] = gradient_param[1];
+            gradient_start_point_3d[2] = gradient_param[4];
+
+            gradient_stop_point_3d[0] = gradient_param[2];
+            gradient_stop_point_3d[1] = gradient_param[3];
+            gradient_stop_point_3d[2] = gradient_param[5];
+
+            Point<2> gradient_start_point = svg_project_point(gradient_start_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
+            Point<2> gradient_stop_point = svg_project_point(gradient_stop_point_3d, camera_position, camera_direction, camera_horizontal, camera_focus);
+
+            // define linear gradient
+            out << "  <linearGradient id=\"" << triangle_counter << "\" gradientUnits=\"userSpaceOnUse\" "
+                << "x1=\""
+                << static_cast<unsigned int>(.5 + ((gradient_start_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+                << "\" "
+                << "y1=\""
+                << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_start_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+                << "\" "
+                << "x2=\""
+                << static_cast<unsigned int>(.5 + ((gradient_stop_point[0] - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+                << "\" "
+                << "y2=\""
+                << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((gradient_stop_point[1] - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+                << "\""
+                << ">" << '\n'
+                << "   <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
+                << "   <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
+                << "  </linearGradient>" << '\n';
+
+            // draw current triangle
+            double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+            double x3 = cell->projected_center[0];
+            double y3 = cell->projected_center[1];
+
+            switch (triangle_index)
+              {
+              case 0:
+                x1 = cell->projected_vertices[0][0], y1 = cell->projected_vertices[0][1], x2 = cell->projected_vertices[1][0], y2 = cell->projected_vertices[1][1];
+                break;
+              case 1:
+                x1 = cell->projected_vertices[1][0], y1 = cell->projected_vertices[1][1], x2 = cell->projected_vertices[3][0], y2 = cell->projected_vertices[3][1];
+                break;
+              case 2:
+                x1 = cell->projected_vertices[3][0], y1 = cell->projected_vertices[3][1], x2 = cell->projected_vertices[2][0], y2 = cell->projected_vertices[2][1];
+                break;
+              case 3:
+                x1 = cell->projected_vertices[2][0], y1 = cell->projected_vertices[2][1], x2 = cell->projected_vertices[0][0], y2 = cell->projected_vertices[0][1];
+                break;
+              default:
+                break;
+              }
 
-      unsigned int element_height = static_cast<unsigned int>(((height/100.) * (71. - 2.*margin_in_percent)) / 4);
-      unsigned int element_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
+            out << "  <path d=\"M "
+                << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+                << ' '
+                << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+                << " L "
+                << static_cast<unsigned int>(.5 + ((x2 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+                << ' '
+                << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y2 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+                << " L "
+                << static_cast<unsigned int>(.5 + ((x3 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+                << ' '
+                << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y3 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+                << " L "
+                << static_cast<unsigned int>(.5 + ((x1 - x_min_perspective) / x_dimension_perspective) * (width - (width/100.) * 2. * margin_in_percent) + ((width/100.) * margin_in_percent))
+                << ' '
+                << static_cast<unsigned int>(.5 + height - (height/100.) * margin_in_percent - ((y1 - y_min_perspective) / y_dimension_perspective) * (height - (height/100.) * 2. * margin_in_percent))
+                << "\" style=\"stroke:black; fill:url(#" << triangle_counter << "); stroke-width:" << flags.line_thickness << "\"/>" << '\n';
+
+            triangle_counter++;
+          }
+      }
 
-      additional_width = 0;
-      if (!flags.margin) additional_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
 
-      for (unsigned int index = 0; index < 4; index++)
-        {
-          double start_h = .667 - ((index+1) / 4.) * .667;
-          double stop_h = .667 - (index / 4.) * .667;
+// draw the colorbar
+    if (flags.draw_colorbar)
+      {
+        out << '\n' << " <!-- colorbar -->" << '\n';
 
-          unsigned int start_r = 0;
-          unsigned int start_g = 0;
-          unsigned int start_b = 0;
+        unsigned int element_height = static_cast<unsigned int>(((height/100.) * (71. - 2.*margin_in_percent)) / 4);
+        unsigned int element_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
 
-          unsigned int stop_r = 0;
-          unsigned int stop_g = 0;
-          unsigned int stop_b = 0;
+        additional_width = 0;
+        if (!flags.margin) additional_width = static_cast<unsigned int>(.5 + (height/100.) * 2.5);
 
-          unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
-          unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
+        for (unsigned int index = 0; index < 4; index++)
+          {
+            double start_h = .667 - ((index+1) / 4.) * .667;
+            double stop_h = .667 - (index / 4.) * .667;
 
-          double start_f = start_h * 6. - start_i;
-          double start_q = 1. - start_f;
+            unsigned int start_r = 0;
+            unsigned int start_g = 0;
+            unsigned int start_b = 0;
 
-          double stop_f = stop_h * 6. - stop_i;
-          double stop_q = 1. - stop_f;
+            unsigned int stop_r = 0;
+            unsigned int stop_g = 0;
+            unsigned int stop_b = 0;
 
-          switch (start_i % 6)
-            {
-            case 0:
-              start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
-              break;
-            case 1:
-              start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
-              break;
-            case 2:
-              start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
-              break;
-            case 3:
-              start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
-              break;
-            case 4:
-              start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
-              break;
-            case 5:
-              start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
-              break;
-            default:
-              break;
-            }
+            unsigned int start_i = static_cast<unsigned int>(start_h * 6.);
+            unsigned int stop_i = static_cast<unsigned int>(stop_h * 6.);
 
-          switch (stop_i % 6)
-            {
-            case 0:
-              stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
-              break;
-            case 1:
-              stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
-              break;
-            case 2:
-              stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
-              break;
-            case 3:
-              stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
-              break;
-            case 4:
-              stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
-              break;
-            case 5:
-              stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
-              break;
-            default:
-              break;
-            }
+            double start_f = start_h * 6. - start_i;
+            double start_q = 1. - start_f;
 
-          // define gradient
-          out << "  <linearGradient id=\"colorbar_" << index << "\" gradientUnits=\"userSpaceOnUse\" "
-              << "x1=\"" << width + additional_width << "\" "
-              << "y1=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height << "\" "
-              << "x2=\"" << width + additional_width << "\" "
-              << "y2=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (4-index) * element_height << "\""
-              << ">" << '\n'
-              << "   <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
-              << "   <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
-              << "  </linearGradient>" << '\n';
-
-          // draw box corresponding to the gradient above
-          out << "  <rect"
-              << " x=\"" << width + additional_width
-              << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height
-              << "\" width=\"" << element_width
-              << "\" height=\"" << element_height
-              << "\" style=\"stroke:black; stroke-width:2; fill:url(#colorbar_" << index << ")\"/>" << '\n';
-        }
+            double stop_f = stop_h * 6. - stop_i;
+            double stop_q = 1. - stop_f;
 
-      for (unsigned int index = 0; index < 5; index++)
-        {
-          out << "  <text x=\"" << width + additional_width + static_cast<unsigned int>(1.5 * element_width)
-              << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29) + (4.-index) * element_height + 30.) << "\""
-              << " style=\"text-anchor:start; font-size:80; font-family:Helvetica";
+            switch (start_i % 6)
+              {
+              case 0:
+                start_r = 255, start_g = static_cast<unsigned int>(.5 + 255. * start_f);
+                break;
+              case 1:
+                start_r = static_cast<unsigned int>(.5 + 255. * start_q), start_g = 255;
+                break;
+              case 2:
+                start_g = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_f);
+                break;
+              case 3:
+                start_g = static_cast<unsigned int>(.5 + 255. * start_q), start_b = 255;
+                break;
+              case 4:
+                start_r = static_cast<unsigned int>(.5 + 255. * start_f), start_b = 255;
+                break;
+              case 5:
+                start_r = 255, start_b = static_cast<unsigned int>(.5 + 255. * start_q);
+                break;
+              default:
+                break;
+              }
 
-          if (index == 0 || index == 4) out << "; font-weight:bold";
+            switch (stop_i % 6)
+              {
+              case 0:
+                stop_r = 255, stop_g = static_cast<unsigned int>(.5 + 255. * stop_f);
+                break;
+              case 1:
+                stop_r = static_cast<unsigned int>(.5 + 255. * stop_q), stop_g = 255;
+                break;
+              case 2:
+                stop_g = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_f);
+                break;
+              case 3:
+                stop_g = static_cast<unsigned int>(.5 + 255. * stop_q), stop_b = 255;
+                break;
+              case 4:
+                stop_r = static_cast<unsigned int>(.5 + 255. * stop_f), stop_b = 255;
+                break;
+              case 5:
+                stop_r = 255, stop_b = static_cast<unsigned int>(.5 + 255. * stop_q);
+                break;
+              default:
+                break;
+              }
 
-          out << "\">" << (float)(((int)((z_min + index * (z_dimension / 4.))*10000))/10000.);
+            // define gradient
+            out << "  <linearGradient id=\"colorbar_" << index << "\" gradientUnits=\"userSpaceOnUse\" "
+                << "x1=\"" << width + additional_width << "\" "
+                << "y1=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height << "\" "
+                << "x2=\"" << width + additional_width << "\" "
+                << "y2=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (4-index) * element_height << "\""
+                << ">" << '\n'
+                << "   <stop offset=\"0\" style=\"stop-color:rgb(" << start_r << "," << start_g << "," << start_b << ")\"/>" << '\n'
+                << "   <stop offset=\"1\" style=\"stop-color:rgb(" << stop_r << "," << stop_g << "," << stop_b << ")\"/>" << '\n'
+                << "  </linearGradient>" << '\n';
+
+            // draw box corresponding to the gradient above
+            out << "  <rect"
+                << " x=\"" << width + additional_width
+                << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29)) + (3-index) * element_height
+                << "\" width=\"" << element_width
+                << "\" height=\"" << element_height
+                << "\" style=\"stroke:black; stroke-width:2; fill:url(#colorbar_" << index << ")\"/>" << '\n';
+          }
 
-          if (index == 4) out << " max";
-          if (index == 0) out << " min";
+        for (unsigned int index = 0; index < 5; index++)
+          {
+            out << "  <text x=\"" << width + additional_width + static_cast<unsigned int>(1.5 * element_width)
+                << "\" y=\"" << static_cast<unsigned int>(.5 + (height/100.) * (margin_in_percent + 29) + (4.-index) * element_height + 30.) << "\""
+                << " style=\"text-anchor:start; font-size:80; font-family:Helvetica";
 
-          out << "</text>" << '\n';
-        }
-    }
+            if (index == 0 || index == 4) out << "; font-weight:bold";
 
-  // finalize the svg file
-  out << '\n' << "</svg>";
-  out.flush();
+            out << "\">" << (float)(((int)((z_min + index * (z_dimension / 4.))*10000))/10000.);
 
-}
+            if (index == 4) out << " max";
+            if (index == 0) out << " min";
 
+            out << "</text>" << '\n';
+          }
+      }
 
+    // finalize the svg file
+    out << '\n' << "</svg>";
+    out.flush();
 
-template <int dim, int spacedim>
-void
-DataOutBase::
-write_deal_II_intermediate (const std::vector<Patch<dim,spacedim> > &patches,
-                            const std::vector<std::string>          &data_names,
-                            const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                            const Deal_II_IntermediateFlags         &/*flags*/,
-                            std::ostream                            &out)
-{
-  AssertThrow (out, ExcIO());
+  }
 
-  // first write tokens indicating the
-  // template parameters. we need this in
-  // here because we may want to read in data
-  // again even if we don't know in advance
-  // the template parameters, see step-19
-  out << dim << ' ' << spacedim << '\n';
-
-  // then write a header
-  out << "[deal.II intermediate format graphics data]" << '\n'
-      << "[written by " << DEAL_II_PACKAGE_NAME << " " << DEAL_II_PACKAGE_VERSION << "]" << '\n'
-      << "[Version: " << Deal_II_IntermediateFlags::format_version << "]" << '\n';
-
-  out << data_names.size() << '\n';
-  for (unsigned int i=0; i<data_names.size(); ++i)
-    out << data_names[i] << '\n';
-
-  out << patches.size() << '\n';
-  for (unsigned int i=0; i<patches.size(); ++i)
-    out << patches[i] << '\n';
-
-  out << vector_data_ranges.size() << '\n';
-  for (unsigned int i=0; i<vector_data_ranges.size(); ++i)
-    out << std_cxx1x::get<0>(vector_data_ranges[i]) << ' '
-        << std_cxx1x::get<1>(vector_data_ranges[i]) << '\n'
-        << std_cxx1x::get<2>(vector_data_ranges[i]) << '\n';
-
-  out << '\n';
-  // make sure everything now gets to
-  // disk
-  out.flush ();
-}
 
 
+  template <int dim, int spacedim>
+  void
+  write_deal_II_intermediate (const std::vector<Patch<dim,spacedim> > &patches,
+                              const std::vector<std::string>          &data_names,
+                              const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
+                              const Deal_II_IntermediateFlags         &/*flags*/,
+                              std::ostream                            &out)
+  {
+    AssertThrow (out, ExcIO());
+
+    // first write tokens indicating the
+    // template parameters. we need this in
+    // here because we may want to read in data
+    // again even if we don't know in advance
+    // the template parameters, see step-19
+    out << dim << ' ' << spacedim << '\n';
+
+    // then write a header
+    out << "[deal.II intermediate format graphics data]" << '\n'
+        << "[written by " << DEAL_II_PACKAGE_NAME << " " << DEAL_II_PACKAGE_VERSION << "]" << '\n'
+        << "[Version: " << Deal_II_IntermediateFlags::format_version << "]" << '\n';
+
+    out << data_names.size() << '\n';
+    for (unsigned int i=0; i<data_names.size(); ++i)
+      out << data_names[i] << '\n';
+
+    out << patches.size() << '\n';
+    for (unsigned int i=0; i<patches.size(); ++i)
+      out << patches[i] << '\n';
+
+    out << vector_data_ranges.size() << '\n';
+    for (unsigned int i=0; i<vector_data_ranges.size(); ++i)
+      out << std_cxx1x::get<0>(vector_data_ranges[i]) << ' '
+          << std_cxx1x::get<1>(vector_data_ranges[i]) << '\n'
+          << std_cxx1x::get<2>(vector_data_ranges[i]) << '\n';
 
-std::pair<unsigned int, unsigned int>
-DataOutBase::
-determine_intermediate_format_dimensions (std::istream &input)
-{
-  Assert (input, ExcIO());
+    out << '\n';
+    // make sure everything now gets to
+    // disk
+    out.flush ();
+  }
 
-  unsigned int dim, spacedim;
-  input >> dim >> spacedim;
 
-  return std::make_pair (dim, spacedim);
-}
 
+  std::pair<unsigned int, unsigned int>
+  determine_intermediate_format_dimensions (std::istream &input)
+  {
+    Assert (input, ExcIO());
 
+    unsigned int dim, spacedim;
+    input >> dim >> spacedim;
 
-template <int dim, int spacedim>
-void
-DataOutBase::write_gmv_reorder_data_vectors (const std::vector<Patch<dim,spacedim> > &patches,
-                                             Table<2,double>                         &data_vectors)
-{
-  // unlike in the main function, we
-  // don't have here the data_names
-  // field, so we initialize it with
-  // the number of data sets in the
-  // first patch. the equivalence of
-  // these two definitions is checked
-  // in the main function.
-
-  // we have to take care, however, whether the
-  // points are appended to the end of the
-  // patch->data table
-  const unsigned int n_data_sets
-    =patches[0].points_are_available ? (patches[0].data.n_rows() - spacedim) : patches[0].data.n_rows();
-
-  Assert (data_vectors.size()[0] == n_data_sets,
-          ExcInternalError());
-
-  // loop over all patches
-  unsigned int next_value = 0;
-  for (typename std::vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
-       patch != patches.end(); ++patch)
-    {
-      const unsigned int n_subdivisions = patch->n_subdivisions;
-
-      Assert ((patch->data.n_rows() == n_data_sets && !patch->points_are_available) ||
-              (patch->data.n_rows() == n_data_sets+spacedim && patch->points_are_available),
-              ExcDimensionMismatch (patch->points_are_available
-                                    ?
-                                    (n_data_sets + spacedim)
-                                    :
-                                    n_data_sets,
-                                    patch->data.n_rows()));
-      Assert (patch->data.n_cols() == Utilities::fixed_power<dim>(n_subdivisions+1),
-              ExcInvalidDatasetSize (patch->data.n_cols(), n_subdivisions+1));
-
-      for (unsigned int i=0; i<patch->data.n_cols(); ++i, ++next_value)
-        for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-          data_vectors[data_set][next_value] = patch->data(data_set,i);
-    }
+    return std::make_pair (dim, spacedim);
+  }
+} // namespace DataOutBase
 
-  for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-    Assert (data_vectors[data_set].size() == next_value,
-            ExcInternalError());
-}
 
 
 
@@ -6780,16 +6877,25 @@ create_xdmf_entry (const std::string &h5_filename, const double cur_time, MPI_Co
   return create_xdmf_entry(data_filter, h5_filename, cur_time, comm);
 }
 
+
+
 template <int dim, int spacedim>
 XDMFEntry DataOutInterface<dim,spacedim>::
-create_xdmf_entry (const DataOutFilter &data_filter, const std::string &h5_filename, const double cur_time, MPI_Comm comm) const
+create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
+                   const std::string &h5_filename, const double cur_time, MPI_Comm comm) const
 {
   return create_xdmf_entry(data_filter, h5_filename, h5_filename, cur_time, comm);
 }
 
+
+
 template <int dim, int spacedim>
 XDMFEntry DataOutInterface<dim,spacedim>::
-create_xdmf_entry (const DataOutFilter &data_filter, const std::string &h5_mesh_filename, const std::string &h5_solution_filename, const double cur_time, MPI_Comm comm) const
+create_xdmf_entry (const DataOutBase::DataOutFilter &data_filter,
+                   const std::string &h5_mesh_filename,
+                   const std::string &h5_solution_filename,
+                   const double cur_time,
+                   MPI_Comm comm) const
 {
   unsigned int    local_node_cell_count[2], global_node_cell_count[2];
   int             myrank;
@@ -6936,7 +7042,7 @@ std::string XDMFEntry::get_xdmf_content(const unsigned int indent_level) const
  */
 template <int dim, int spacedim>
 void DataOutInterface<dim,spacedim>::
-write_filtered_data (DataOutFilter &filtered_data) const
+write_filtered_data (DataOutBase::DataOutFilter &filtered_data) const
 {
   DataOutBase::write_filtered_data(get_patches(), get_dataset_names(),
                                    get_vector_data_ranges(),
@@ -6947,7 +7053,7 @@ template <int dim, int spacedim>
 void DataOutBase::write_filtered_data (const std::vector<Patch<dim,spacedim> > &patches,
                                        const std::vector<std::string>          &data_names,
                                        const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
-                                       DataOutFilter &filtered_data)
+                                       DataOutBase::DataOutFilter &filtered_data)
 {
   const unsigned int n_data_sets = data_names.size();
   unsigned int    n_node, n_cell;
@@ -7050,21 +7156,23 @@ write_hdf5_parallel (const std::string &filename, MPI_Comm comm) const
 
 template <int dim, int spacedim>
 void DataOutInterface<dim,spacedim>::
-write_hdf5_parallel (const DataOutFilter &data_filter, const std::string &filename, MPI_Comm comm) const
+write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+                     const std::string &filename, MPI_Comm comm) const
 {
   DataOutBase::write_hdf5_parallel(get_patches(), data_filter, filename, comm);
 }
 
 template <int dim, int spacedim>
 void DataOutInterface<dim,spacedim>::
-write_hdf5_parallel (const DataOutFilter &data_filter, const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const
+write_hdf5_parallel (const DataOutBase::DataOutFilter &data_filter,
+                     const bool write_mesh_file, const std::string &mesh_filename, const std::string &solution_filename, MPI_Comm comm) const
 {
   DataOutBase::write_hdf5_parallel(get_patches(), data_filter, write_mesh_file, mesh_filename, solution_filename, comm);
 }
 
 template <int dim, int spacedim>
 void DataOutBase::write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
-                                       const DataOutFilter &data_filter,
+                                       const DataOutBase::DataOutFilter &data_filter,
                                        const std::string &filename,
                                        MPI_Comm comm)
 {
@@ -7073,7 +7181,7 @@ void DataOutBase::write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &
 
 template <int dim, int spacedim>
 void DataOutBase::write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &patches,
-                                       const DataOutFilter &data_filter,
+                                       const DataOutBase::DataOutFilter &data_filter,
                                        const bool write_mesh_file,
                                        const std::string &mesh_filename,
                                        const std::string &solution_filename,
@@ -7356,62 +7464,62 @@ void DataOutBase::write_hdf5_parallel (const std::vector<Patch<dim,spacedim> > &
 template <int dim, int spacedim>
 void
 DataOutInterface<dim,spacedim>::write (std::ostream &out,
-                                       const OutputFormat output_format_) const
+                                       const DataOutBase::OutputFormat output_format_) const
 {
-  OutputFormat output_format = output_format_;
-  if (output_format == default_format)
+  DataOutBase::OutputFormat output_format = output_format_;
+  if (output_format == DataOutBase::default_format)
     output_format = default_fmt;
 
   switch (output_format)
     {
-    case none:
+    case DataOutBase::none:
       break;
 
-    case dx:
+    case DataOutBase::dx:
       write_dx (out);
       break;
 
-    case ucd:
+    case DataOutBase::ucd:
       write_ucd (out);
       break;
 
-    case gnuplot:
+    case DataOutBase::gnuplot:
       write_gnuplot (out);
       break;
 
-    case povray:
+    case DataOutBase::povray:
       write_povray (out);
       break;
 
-    case eps:
+    case DataOutBase::eps:
       write_eps (out);
       break;
 
-    case gmv:
+    case DataOutBase::gmv:
       write_gmv (out);
       break;
 
-    case tecplot:
+    case DataOutBase::tecplot:
       write_tecplot (out);
       break;
 
-    case tecplot_binary:
+    case DataOutBase::tecplot_binary:
       write_tecplot_binary (out);
       break;
 
-    case vtk:
+    case DataOutBase::vtk:
       write_vtk (out);
       break;
 
-    case vtu:
+    case DataOutBase::vtu:
       write_vtu (out);
       break;
 
-    case svg:
+    case DataOutBase::svg:
       write_svg (out);
       break;
 
-    case deal_II_intermediate:
+    case DataOutBase::deal_II_intermediate:
       write_deal_II_intermediate (out);
       break;
 
@@ -7424,9 +7532,9 @@ DataOutInterface<dim,spacedim>::write (std::ostream &out,
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_default_format(const OutputFormat fmt)
+DataOutInterface<dim,spacedim>::set_default_format(const DataOutBase::OutputFormat fmt)
 {
-  Assert (fmt != default_format, ExcNotImplemented());
+  Assert (fmt != DataOutBase::default_format, ExcNotImplemented());
   default_fmt = fmt;
 }
 
@@ -7434,7 +7542,7 @@ DataOutInterface<dim,spacedim>::set_default_format(const OutputFormat fmt)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const DXFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::DXFlags &flags)
 {
   dx_flags = flags;
 }
@@ -7443,7 +7551,7 @@ DataOutInterface<dim,spacedim>::set_flags (const DXFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const UcdFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::UcdFlags &flags)
 {
   ucd_flags = flags;
 }
@@ -7452,7 +7560,7 @@ DataOutInterface<dim,spacedim>::set_flags (const UcdFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const GnuplotFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::GnuplotFlags &flags)
 {
   gnuplot_flags = flags;
 }
@@ -7461,7 +7569,7 @@ DataOutInterface<dim,spacedim>::set_flags (const GnuplotFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const PovrayFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::PovrayFlags &flags)
 {
   povray_flags = flags;
 }
@@ -7470,7 +7578,7 @@ DataOutInterface<dim,spacedim>::set_flags (const PovrayFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const EpsFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::EpsFlags &flags)
 {
   eps_flags = flags;
 }
@@ -7479,7 +7587,7 @@ DataOutInterface<dim,spacedim>::set_flags (const EpsFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const GmvFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::GmvFlags &flags)
 {
   gmv_flags = flags;
 }
@@ -7488,7 +7596,7 @@ DataOutInterface<dim,spacedim>::set_flags (const GmvFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const TecplotFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::TecplotFlags &flags)
 {
   tecplot_flags = flags;
 }
@@ -7497,7 +7605,7 @@ DataOutInterface<dim,spacedim>::set_flags (const TecplotFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const VtkFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::VtkFlags &flags)
 {
   vtk_flags = flags;
 }
@@ -7506,7 +7614,7 @@ DataOutInterface<dim,spacedim>::set_flags (const VtkFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const SvgFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::SvgFlags &flags)
 {
   svg_flags = flags;
 }
@@ -7515,7 +7623,7 @@ DataOutInterface<dim,spacedim>::set_flags (const SvgFlags &flags)
 
 template <int dim, int spacedim>
 void
-DataOutInterface<dim,spacedim>::set_flags (const Deal_II_IntermediateFlags &flags)
+DataOutInterface<dim,spacedim>::set_flags (const DataOutBase::Deal_II_IntermediateFlags &flags)
 {
   deal_II_intermediate_flags = flags;
 }
@@ -7525,9 +7633,9 @@ DataOutInterface<dim,spacedim>::set_flags (const Deal_II_IntermediateFlags &flag
 template <int dim, int spacedim>
 std::string
 DataOutInterface<dim,spacedim>::
-default_suffix (const OutputFormat output_format) const
+default_suffix (const DataOutBase::OutputFormat output_format) const
 {
-  if (output_format == default_format)
+  if (output_format == DataOutBase::default_format)
     return DataOutBase::default_suffix (default_fmt);
   else
     return DataOutBase::default_suffix (output_format);
@@ -7540,46 +7648,46 @@ void
 DataOutInterface<dim,spacedim>::declare_parameters (ParameterHandler &prm)
 {
   prm.declare_entry ("Output format", "gnuplot",
-                     Patterns::Selection (get_output_format_names ()),
+                     Patterns::Selection (DataOutBase::get_output_format_names ()),
                      "A name for the output format to be used");
   prm.declare_entry("Subdivisions", "1", Patterns::Integer(),
                     "Number of subdivisions of each mesh cell");
 
   prm.enter_subsection ("DX output parameters");
-  DXFlags::declare_parameters (prm);
+  DataOutBase::DXFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("UCD output parameters");
-  UcdFlags::declare_parameters (prm);
+  DataOutBase::UcdFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("Gnuplot output parameters");
-  GnuplotFlags::declare_parameters (prm);
+  DataOutBase::GnuplotFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("Povray output parameters");
-  PovrayFlags::declare_parameters (prm);
+  DataOutBase::PovrayFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("Eps output parameters");
-  EpsFlags::declare_parameters (prm);
+  DataOutBase::EpsFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("Gmv output parameters");
-  GmvFlags::declare_parameters (prm);
+  DataOutBase::GmvFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("Tecplot output parameters");
-  TecplotFlags::declare_parameters (prm);
+  DataOutBase::TecplotFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
   prm.enter_subsection ("Vtk output parameters");
-  VtkFlags::declare_parameters (prm);
+  DataOutBase::VtkFlags::declare_parameters (prm);
   prm.leave_subsection ();
 
 
   prm.enter_subsection ("deal.II intermediate output parameters");
-  Deal_II_IntermediateFlags::declare_parameters (prm);
+  DataOutBase::Deal_II_IntermediateFlags::declare_parameters (prm);
   prm.leave_subsection ();
 }
 
@@ -7590,7 +7698,7 @@ void
 DataOutInterface<dim,spacedim>::parse_parameters (ParameterHandler &prm)
 {
   const std::string &output_name = prm.get ("Output format");
-  default_fmt = parse_output_format (output_name);
+  default_fmt = DataOutBase::parse_output_format (output_name);
   default_subdivisions = prm.get_integer ("Subdivisions");
 
   prm.enter_subsection ("DX output parameters");
@@ -7695,7 +7803,7 @@ DataOutReader<dim,spacedim>::read (std::istream &in)
   {
     std::pair<unsigned int, unsigned int>
     dimension_info
-      = this->determine_intermediate_format_dimensions (in);
+      = DataOutBase::determine_intermediate_format_dimensions (in);
     AssertThrow ((dimension_info.first  == dim) &&
                  (dimension_info.second == spacedim),
                  ExcIncompatibleDimensions (dimension_info.first, dim,
@@ -7872,99 +7980,99 @@ DataOutReader<dim,spacedim>::get_vector_data_ranges () const
 
 
 
-
-template <int dim, int spacedim>
-std::ostream &
-operator << (std::ostream                           &out,
-             const DataOutBase::Patch<dim,spacedim> &patch)
+namespace DataOutBase
 {
-  // write a header line
-  out << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]"
-      << '\n';
-
-  // then write all the data that is
-  // in this patch
-  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
-    out << patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]] << ' ';
-  out << '\n';
-
-  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
-    out << patch.neighbors[i] << ' ';
-  out << '\n';
+  template <int dim, int spacedim>
+  std::ostream &
+  operator << (std::ostream                           &out,
+               const Patch<dim,spacedim> &patch)
+  {
+    // write a header line
+    out << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]"
+        << '\n';
 
-  out << patch.patch_index << ' ' << patch.n_subdivisions
-      << '\n';
+    // then write all the data that is
+    // in this patch
+    for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+      out << patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]] << ' ';
+    out << '\n';
 
-  out << patch.points_are_available<<'\n';
+    for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+      out << patch.neighbors[i] << ' ';
+    out << '\n';
 
-  out << patch.data.n_rows() << ' ' << patch.data.n_cols() << '\n';
-  for (unsigned int i=0; i<patch.data.n_rows(); ++i)
-    for (unsigned int j=0; j<patch.data.n_cols(); ++j)
-      out << patch.data[i][j] << ' ';
-  out << '\n';
-  out << '\n';
+    out << patch.patch_index << ' ' << patch.n_subdivisions
+        << '\n';
 
-  return out;
-}
+    out << patch.points_are_available<<'\n';
 
+    out << patch.data.n_rows() << ' ' << patch.data.n_cols() << '\n';
+    for (unsigned int i=0; i<patch.data.n_rows(); ++i)
+      for (unsigned int j=0; j<patch.data.n_cols(); ++j)
+        out << patch.data[i][j] << ' ';
+    out << '\n';
+    out << '\n';
 
+    return out;
+  }
 
-template <int dim, int spacedim>
-std::istream &
-operator >> (std::istream                     &in,
-             DataOutBase::Patch<dim,spacedim> &patch)
-{
-  Assert (in, ExcIO());
 
-  // read a header line and compare
-  // it to what we usually
-  // write. skip all lines that
-  // contain only blanks at the start
+  template <int dim, int spacedim>
+  std::istream &
+  operator >> (std::istream                     &in,
+               Patch<dim,spacedim> &patch)
   {
-    std::string header;
-    do
-      {
-        getline (in, header);
-        while ((header.size() != 0) &&
-               (header[header.size()-1] == ' '))
-          header.erase(header.size()-1);
-      }
-    while ((header == "") && in);
+    Assert (in, ExcIO());
 
-    std::ostringstream s;
-    s << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]";
+    // read a header line and compare
+    // it to what we usually
+    // write. skip all lines that
+    // contain only blanks at the start
+    {
+      std::string header;
+      do
+        {
+          getline (in, header);
+          while ((header.size() != 0) &&
+                 (header[header.size()-1] == ' '))
+            header.erase(header.size()-1);
+        }
+      while ((header == "") && in);
 
-    Assert (header == s.str(), ExcUnexpectedInput(s.str(),header));
-  }
+      std::ostringstream s;
+      s << "[deal.II intermediate Patch<" << dim << ',' << spacedim << ">]";
+
+      Assert (header == s.str(), ExcUnexpectedInput(s.str(),header));
+    }
 
 
-  // then read all the data that is
-  // in this patch
-  for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
-    in >> patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]];
+    // then read all the data that is
+    // in this patch
+    for (unsigned int i=0; i<GeometryInfo<dim>::vertices_per_cell; ++i)
+      in >> patch.vertices[GeometryInfo<dim>::ucd_to_deal[i]];
 
-  for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
-    in >> patch.neighbors[i];
+    for (unsigned int i=0; i<GeometryInfo<dim>::faces_per_cell; ++i)
+      in >> patch.neighbors[i];
 
-  in >> patch.patch_index >> patch.n_subdivisions;
+    in >> patch.patch_index >> patch.n_subdivisions;
 
-  in >> patch.points_are_available;
+    in >> patch.points_are_available;
 
-  unsigned int n_rows, n_cols;
-  in >> n_rows >> n_cols;
-  patch.data.reinit (n_rows, n_cols);
-  for (unsigned int i=0; i<patch.data.n_rows(); ++i)
-    for (unsigned int j=0; j<patch.data.n_cols(); ++j)
-      in >> patch.data[i][j];
+    unsigned int n_rows, n_cols;
+    in >> n_rows >> n_cols;
+    patch.data.reinit (n_rows, n_cols);
+    for (unsigned int i=0; i<patch.data.n_rows(); ++i)
+      for (unsigned int j=0; j<patch.data.n_cols(); ++j)
+        in >> patch.data[i][j];
 
-  Assert (in, ExcIO());
+    Assert (in, ExcIO());
 
-  return in;
+    return in;
+  }
 }
 
 
 
-
 // explicit instantiations
 #include "data_out_base.inst"
 
index 28547f6d1718791f737a21ec165fae3efde191b6..dc4ea5982367ae6987d62f6d2c7aa9094e09af01 100644 (file)
@@ -20,21 +20,24 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 #if deal_II_dimension <= deal_II_space_dimension
   template class DataOutInterface<deal_II_dimension, deal_II_space_dimension>;
   template class DataOutReader<deal_II_dimension, deal_II_space_dimension>;
-  template struct DataOutBase::Patch<deal_II_dimension, deal_II_space_dimension>;
+  
+  namespace DataOutBase
+  \{
+  template struct Patch<deal_II_dimension, deal_II_space_dimension>;
 
   template
   std::ostream &
   operator << (std::ostream                           &out,
-               const DataOutBase::Patch<deal_II_dimension, deal_II_space_dimension> &patch);
+               const Patch<deal_II_dimension, deal_II_space_dimension> &patch);
 
   template
   std::istream &
   operator >> (std::istream                     &in,
-               DataOutBase::Patch<deal_II_dimension, deal_II_space_dimension> &patch);
+               Patch<deal_II_dimension, deal_II_space_dimension> &patch);
 
   template
   void
-  DataOutBase::write_vtk (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_vtk (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const VtkFlags                          &flags,
@@ -42,7 +45,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_vtu (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_vtu (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const VtkFlags                          &flags,
@@ -50,7 +53,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_ucd (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_ucd (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const UcdFlags                          &flags,
@@ -58,7 +61,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_dx (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_dx (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const DXFlags                          &flags,
@@ -66,7 +69,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_gnuplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_gnuplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const GnuplotFlags                          &flags,
@@ -74,7 +77,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_povray (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_povray (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const PovrayFlags                          &flags,
@@ -82,7 +85,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_eps (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_eps (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const EpsFlags                          &flags,
@@ -90,7 +93,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_gmv (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_gmv (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const GmvFlags                          &flags,
@@ -98,7 +101,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_tecplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_tecplot (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const TecplotFlags                          &flags,
@@ -106,7 +109,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 
   template
   void
-  DataOutBase::write_tecplot_binary (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_tecplot_binary (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const TecplotFlags                          &flags,
@@ -115,7 +118,7 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 #if deal_II_space_dimension >1
   template
   void
-  DataOutBase::write_svg (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_svg (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const SvgFlags                          &flags,
@@ -123,10 +126,11 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
 #endif
   template
   void
-  DataOutBase::write_deal_II_intermediate (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
+  write_deal_II_intermediate (const std::vector<Patch<deal_II_dimension,deal_II_space_dimension> > &patches,
                         const std::vector<std::string>          &data_names,
                         const std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > &vector_data_ranges,
                         const Deal_II_IntermediateFlags                          &flags,
                         std::ostream                            &out);
+  \}
 #endif
 }
index 97a7c89b66d5905d71f945a972880f9fd4dc8614..df1d36039366e5b262076b97e66acba2cc608eb4 100644 (file)
@@ -19,6 +19,8 @@
 #include <deal.II/base/utilities.h>
 #include <deal.II/base/exceptions.h>
 #include <deal.II/lac/vector_memory.h>
+#include <deal.II/lac/parallel_vector.h>
+#include <deal.II/lac/parallel_block_vector.h>
 #include <deal.II/base/multithread_info.h>
 
 #include <cstddef>
@@ -401,8 +403,18 @@ namespace Utilities
       // to errors
 
 #ifdef DEAL_II_WITH_MPI
-      // Start with Trilinos (need to do this before finalizing PETSc because it finalizes MPI.
-      // Delete vectors from the pools:
+      // Start with the deal.II MPI vectors (need to do this before finalizing
+      // PETSc because it finalizes MPI).  Delete vectors from the pools:
+      GrowingVectorMemory<parallel::distributed::Vector<double> >
+      ::release_unused_memory ();
+      GrowingVectorMemory<parallel::distributed::BlockVector<double> >
+      ::release_unused_memory ();
+      GrowingVectorMemory<parallel::distributed::Vector<float> >
+      ::release_unused_memory ();
+      GrowingVectorMemory<parallel::distributed::BlockVector<float> >
+      ::release_unused_memory ();
+
+      // Next with Trilinos:
 #  if defined(DEAL_II_WITH_TRILINOS)
       GrowingVectorMemory<TrilinosWrappers::MPI::Vector>
       ::release_unused_memory ();
index 049b8de1e7ca151bccc21e268f2f97671cea0a82..7752b9d81eb2e346ef242cfb19c6a67b96492414 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <cmath>
 #include <limits>
+#include <algorithm>
+
 
 DEAL_II_NAMESPACE_OPEN
 
@@ -128,7 +130,7 @@ QGauss<1>::QGauss (const unsigned int n)
   const long double tolerance
     = (runtime_one + long_double_eps != runtime_one
        ?
-       fmax (double_eps / 100, long_double_eps * 5)
+       std::max (double_eps / 100, long_double_eps * 5)
        :
        double_eps * 5
       );
@@ -215,7 +217,7 @@ compute_quadrature_points(const unsigned int q,
   const long double tolerance
     = (runtime_one + long_double_eps != runtime_one
        ?
-       fmax (double_eps / 100, long_double_eps * 5)
+       std::max (double_eps / 100, long_double_eps * 5)
        :
        double_eps * 5
       );
index aaf9fe0a0a746d355bc9e6670484848e0bc5a565..163f03d2b7f0350ad49cb53e16aead969bea3dd3 100644 (file)
@@ -800,24 +800,22 @@ namespace FEValuesViews
                   const dealii::Tensor<1, spacedim> *shape_gradient_ptr =
                     &shape_gradients[snc][0];
 
-                  switch (shape_function_data[shape_function].single_nonzero_component_index)
-                    {
-                    case 0:
-                    {
-                      for (unsigned int q_point = 0;
-                           q_point < n_quadrature_points; ++q_point)
-                        curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
-
-                      break;
-                    }
-
-                    default:
-                      for (unsigned int q_point = 0;
-                           q_point < n_quadrature_points; ++q_point)
-                        curls[q_point][0] += value * (*shape_gradient_ptr)[0];
-                    }
+                  Assert (shape_function_data[shape_function].single_nonzero_component >= 0,
+                          ExcInternalError());
+                  // we're in 2d, so the formula for the curl is simple:
+                  if (shape_function_data[shape_function].single_nonzero_component_index == 0)
+                    for (unsigned int q_point = 0;
+                        q_point < n_quadrature_points; ++q_point)
+                      curls[q_point][0] -= value * (*shape_gradient_ptr++)[1];
+                  else
+                    for (unsigned int q_point = 0;
+                        q_point < n_quadrature_points; ++q_point)
+                      curls[q_point][0] += value * (*shape_gradient_ptr++)[0];
                 }
               else
+                // we have multiple non-zero components in the shape functions. not
+                // all of them must necessarily be within the 2-component window
+                // this FEValuesViews::Vector object considers, however.
                 {
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
                     {
@@ -887,17 +885,26 @@ namespace FEValuesViews
                       break;
                     }
 
-                    default:
+                    case 2:
+                    {
                       for (unsigned int q_point = 0;
                            q_point < n_quadrature_points; ++q_point)
                         {
                           curls[q_point][0] += value * (*shape_gradient_ptr)[1];
                           curls[q_point][1] -= value * (*shape_gradient_ptr++)[0];
                         }
+                      break;
+                    }
+
+                    default:
+                      Assert (false, ExcInternalError());
                     }
                 }
 
               else
+                // we have multiple non-zero components in the shape functions. not
+                // all of them must necessarily be within the 3-component window
+                // this FEValuesViews::Vector object considers, however.
                 {
                   if (shape_function_data[shape_function].is_nonzero_shape_function_component[0])
                     {
index e9777188b85d4036c655a54271a58db3acbebffc..e56250111f531e6049ed54170bdae6213b75705a 100644 (file)
@@ -634,7 +634,7 @@ namespace GridGenerator
   template<>
   void
   parallelogram (Triangulation<3>  &tria,
-                 const Point<3> corners[3],
+                 const Point<3> (&corners)[3],
                  const bool         colorize)
   {
     Assert (false, ExcNotImplemented());
@@ -643,7 +643,7 @@ namespace GridGenerator
   template<>
   void
   parallelogram (Triangulation<1>  &tria,
-                 const Point<1> corners[1],
+                 const Point<1> (&corners)[1],
                  const bool         colorize)
   {
     Assert (false, ExcNotImplemented());
@@ -653,7 +653,7 @@ namespace GridGenerator
   template<>
   void
   parallelogram (Triangulation<2>  &tria,
-                 const Point<2> corners[2],
+                 const Point<2> (&corners)[2],
                  const bool         colorize)
   {
     std::vector<Point<2> > vertices (GeometryInfo<2>::vertices_per_cell);
index b385bb51b25420a8ee588ebeafdf05e090a35920..c03cf1acc740e04eb8d03003cf432796d2d02a34 100644 (file)
@@ -2085,8 +2085,12 @@ next_cell:
 
 
   template <template <int,int> class Container, int dim, int spacedim>
+#ifndef _MSC_VER
   std::map<typename Container<dim-1,spacedim>::cell_iterator,
       typename Container<dim,spacedim>::face_iterator>
+#else
+  typename ExtractBoundaryMesh<Container,dim,spacedim>::return_type
+#endif
       extract_boundary_mesh (const Container<dim,spacedim> &volume_mesh,
                              Container<dim-1,spacedim>     &surface_mesh,
                              const std::set<types::boundary_id> &boundary_ids)
index 8089c7dad665c1d58a7a25d95370bfa0869164cf..a85fc66fb5269201f0e40c0eb55400f3ae2d4eec 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2001 - 2013 by the deal.II authors
+// Copyright (C) 2001 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -116,12 +116,12 @@ for (deal_II_dimension : DIMENSIONS ; deal_II_space_dimension : SPACE_DIMENSIONS
 
 for (deal_II_space_dimension : SPACE_DIMENSIONS)
 {
-  
+
     parallel::distributed::Triangulation<deal_II_space_dimension>::active_cell_iterator
     find_active_cell_around_point (const parallel::distributed::Triangulation<deal_II_space_dimension> &,
                                   const Point<deal_II_space_dimension> &p);
 
-  
+
     std::pair<parallel::distributed::Triangulation<deal_II_space_dimension>::active_cell_iterator, Point<deal_II_space_dimension> >
     find_active_cell_around_point (const Mapping<deal_II_space_dimension> &,
                                   const parallel::distributed::Triangulation<deal_II_space_dimension> &,
@@ -265,8 +265,12 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension :  SPACE_DIMENSIONS
     namespace GridTools \{
 
       template
-       std::map<  Container<deal_II_dimension-1,deal_II_space_dimension>::cell_iterator,
+#ifndef _MSC_VER
+      std::map<  Container<deal_II_dimension-1,deal_II_space_dimension>::cell_iterator,
                   Container<deal_II_dimension,deal_II_space_dimension>::face_iterator>
+#else
+      ExtractBoundaryMesh<Container,deal_II_dimension,deal_II_space_dimension>::return_type
+#endif
       extract_boundary_mesh (const Container<deal_II_dimension, deal_II_space_dimension> &mesh,
                             Container<deal_II_dimension-1,deal_II_space_dimension>  &boundary_mesh,
                             const std::set<types::boundary_id> &boundary_ids);
index b083369760b1b9d3e2107597c36a03b2b6f57124..2f271224d7dd89320fa48683269137af903eccd7 100644 (file)
@@ -2417,45 +2417,26 @@ namespace hp
 
 
 
-  template <>
-  void
-  DoFHandler<1>::
-  compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
-  {}
-
-  template <>
-  void
-  DoFHandler<1,2>::
-  compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
-  {}
-
-  template <>
-  void
-  DoFHandler<1,3>::
-  compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
-  {}
-
-  template <>
+  template <int dim, int spacedim>
   void
-  DoFHandler<2>::
+  DoFHandler<dim,spacedim>::
   compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
-  {}
-
+  {
+    // this function should only be called for dim<3 where there are
+    // no quad dof identies. for dim>=3, the specialization below should
+    // take care of it
+    Assert (dim < 3, ExcInternalError());
+  }
 
 
   template <>
   void
-  DoFHandler<2,3>::
-  compute_quad_dof_identities (std::vector<types::global_dof_index> &) const
-  {}
-
-
-
-  template<int dim, int spacedim>
-  void
-  DoFHandler<dim,spacedim>::
+  DoFHandler<3,3>::
   compute_quad_dof_identities (std::vector<types::global_dof_index> &new_dof_indices) const
   {
+    const int dim = 3;
+    const int spacedim = 3;
+
     // we will mark quads that we
     // have already treated, so first
     // save and clear the user flags
@@ -2643,7 +2624,7 @@ namespace hp
 
       for (; cell != endc; ++cell)
         next_free_dof
-          = dealii::internal::hp::DoFHandler::Implementation::template distribute_dofs_on_cell<spacedim> (cell,
+          = dealii::internal::hp::DoFHandler::Implementation::distribute_dofs_on_cell<spacedim> (cell,
             next_free_dof);
 
       number_cache.n_global_dofs = next_free_dof;
index 215f9c07e19ca7e531b36d53a09d1f5690a52797..2731f40777238d061361bc8d31863cc22338def8 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -37,6 +37,7 @@ LAPACKFullMatrix<number>::LAPACKFullMatrix(const size_type n)
 {}
 
 
+
 template <typename number>
 LAPACKFullMatrix<number>::LAPACKFullMatrix(
   const size_type m,
@@ -47,6 +48,7 @@ LAPACKFullMatrix<number>::LAPACKFullMatrix(
 {}
 
 
+
 template <typename number>
 LAPACKFullMatrix<number>::LAPACKFullMatrix(const LAPACKFullMatrix &M)
   :
@@ -55,6 +57,7 @@ LAPACKFullMatrix<number>::LAPACKFullMatrix(const LAPACKFullMatrix &M)
 {}
 
 
+
 template <typename number>
 LAPACKFullMatrix<number> &
 LAPACKFullMatrix<number>::operator = (const LAPACKFullMatrix<number> &M)
@@ -65,12 +68,13 @@ LAPACKFullMatrix<number>::operator = (const LAPACKFullMatrix<number> &M)
 }
 
 
+
 template <typename number>
 template <typename number2>
 LAPACKFullMatrix<number> &
 LAPACKFullMatrix<number>::operator = (const FullMatrix<number2> &M)
 {
-  Assert (this->n_rows() == M.m(), ExcDimensionMismatch(this->n_rows(), M.m()));
+  Assert (this->n_rows() == M.n_rows(), ExcDimensionMismatch(this->n_rows(), M.n_rows()));
   Assert (this->n_cols() == M.n(), ExcDimensionMismatch(this->n_cols(), M.n()));
   for (size_type i=0; i<this->n_rows(); ++i)
     for (size_type j=0; j<this->n_cols(); ++j)
@@ -81,6 +85,7 @@ LAPACKFullMatrix<number>::operator = (const FullMatrix<number2> &M)
 }
 
 
+
 template <typename number>
 LAPACKFullMatrix<number> &
 LAPACKFullMatrix<number>::operator = (const double d)
@@ -95,6 +100,7 @@ LAPACKFullMatrix<number>::operator = (const double d)
 }
 
 
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::vmult (
@@ -153,6 +159,7 @@ LAPACKFullMatrix<number>::vmult (
 }
 
 
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::Tvmult (
@@ -213,6 +220,203 @@ LAPACKFullMatrix<number>::Tvmult (
 }
 
 
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mmult(LAPACKFullMatrix<number>       &C,
+                                const LAPACKFullMatrix<number> &B,
+                                const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert(C.state == matrix, ExcState(state));
+  Assert (this->n_cols() == B.n_rows(), ExcDimensionMismatch(this->n_cols(), B.n_rows()));
+  Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+  Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+  const int mm = this->n_rows();
+  const int nn = B.n_cols();
+  const int kk = this->n_cols();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  gemm("N", "N", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.values[0],
+       &kk, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mmult(FullMatrix<number>             &C,
+                                const LAPACKFullMatrix<number> &B,
+                                const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert (this->n_cols() == B.n_rows(), ExcDimensionMismatch(this->n_cols(), B.n_rows()));
+  Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+  Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+  const int mm = this->n_rows();
+  const int nn = B.n_cols();
+  const int kk = this->n_cols();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  // since FullMatrix stores the matrix in transposed order compared to this
+  // matrix, compute B^T * A^T = (A * B)^T
+  gemm("T", "T", &nn, &mm, &kk, &alpha, &B.values[0], &kk, &this->values[0],
+       &mm, &beta, &C(0,0), &nn);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::Tmmult(LAPACKFullMatrix<number>       &C,
+                                 const LAPACKFullMatrix<number> &B,
+                                 const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert(C.state == matrix, ExcState(state));
+  Assert (this->n_rows() == B.n_rows(), ExcDimensionMismatch(this->n_rows(), B.n_rows()));
+  Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+  Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+  const int mm = this->n_cols();
+  const int nn = B.n_cols();
+  const int kk = B.n_rows();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  gemm("T", "N", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.values[0],
+       &kk, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::Tmmult(FullMatrix<number>             &C,
+                                 const LAPACKFullMatrix<number> &B,
+                                 const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert (this->n_rows() == B.n_rows(), ExcDimensionMismatch(this->n_rows(), B.n_rows()));
+  Assert (C.n_cols() == B.n_cols(), ExcDimensionMismatch(C.n_cols(), B.n_cols()));
+  Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+  const int mm = this->n_cols();
+  const int nn = B.n_cols();
+  const int kk = B.n_rows();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  // since FullMatrix stores the matrix in transposed order compared to this
+  // matrix, compute B^T * A = (A^T * B)^T
+  gemm("T", "N", &nn, &mm, &kk, &alpha, &B.values[0], &kk, &this->values[0],
+       &kk, &beta, &C(0,0), &nn);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mTmult(LAPACKFullMatrix<number>       &C,
+                                 const LAPACKFullMatrix<number> &B,
+                                 const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert(C.state == matrix, ExcState(state));
+  Assert (this->n_cols() == B.n_cols(), ExcDimensionMismatch(this->n_cols(), B.n_cols()));
+  Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+  Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+  const int mm = this->n_rows();
+  const int nn = B.n_rows();
+  const int kk = B.n_cols();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  gemm("N", "T", &mm, &nn, &kk, &alpha, &this->values[0], &mm, &B.values[0],
+       &nn, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::mTmult(FullMatrix<number>             &C,
+                                 const LAPACKFullMatrix<number> &B,
+                                 const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert (this->n_cols() == B.n_cols(), ExcDimensionMismatch(this->n_cols(), B.n_cols()));
+  Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+  Assert (C.n_rows() == this->n_rows(), ExcDimensionMismatch(this->n_rows(), C.n_rows()));
+  const int mm = this->n_rows();
+  const int nn = B.n_rows();
+  const int kk = B.n_cols();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  // since FullMatrix stores the matrix in transposed order compared to this
+  // matrix, compute B * A^T = (A * B^T)^T
+  gemm("N", "T", &nn, &mm, &kk, &alpha, &B.values[0], &nn, &this->values[0],
+       &mm, &beta, &C(0,0), &nn);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::TmTmult(LAPACKFullMatrix<number>       &C,
+                                  const LAPACKFullMatrix<number> &B,
+                                  const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert(C.state == matrix, ExcState(state));
+  Assert (this->n_rows() == B.n_cols(), ExcDimensionMismatch(this->n_rows(), B.n_cols()));
+  Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+  Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+  const int mm = this->n_cols();
+  const int nn = B.n_rows();
+  const int kk = B.n_cols();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  gemm("T", "T", &mm, &nn, &kk, &alpha, &this->values[0], &kk, &B.values[0],
+       &nn, &beta, &C.values[0], &mm);
+}
+
+
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::TmTmult(FullMatrix<number>             &C,
+                                  const LAPACKFullMatrix<number> &B,
+                                  const bool                      adding) const
+{
+  Assert(state == matrix, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert (this->n_rows() == B.n_cols(), ExcDimensionMismatch(this->n_rows(), B.n_cols()));
+  Assert (C.n_cols() == B.n_rows(), ExcDimensionMismatch(C.n_cols(), B.n_rows()));
+  Assert (C.n_rows() == this->n_cols(), ExcDimensionMismatch(this->n_cols(), C.n_rows()));
+  const int mm = this->n_cols();
+  const int nn = B.n_rows();
+  const int kk = B.n_cols();
+  const number alpha = 1.;
+  const number beta = (adding ? 1. : 0.);
+
+  // since FullMatrix stores the matrix in transposed order compared to this
+  // matrix, compute B * A = (A^T * B^T)^T
+  gemm("N", "N", &nn, &mm, &kk, &alpha, &B.values[0], &nn, &this->values[0],
+       &kk, &beta, &C(0,0), &nn);
+}
+
+
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::compute_lu_factorization()
@@ -232,6 +436,7 @@ LAPACKFullMatrix<number>::compute_lu_factorization()
 }
 
 
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::compute_svd()
@@ -252,12 +457,10 @@ LAPACKFullMatrix<number>::compute_svd()
   number *mvt = const_cast<number *> (&svd_vt->values[0]);
   int info = 0;
 
-  // see comment on this #if
-  // below. Another reason to love Petsc
+  // see comment on this #if below. Another reason to love Petsc
 #ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
 
-  // First determine optimal
-  // workspace size
+  // First determine optimal workspace size
   work.resize(1);
   int lwork = -1;
   gesdd(&LAPACKSupport::A, &mm, &nn, values, &mm,
@@ -284,6 +487,7 @@ LAPACKFullMatrix<number>::compute_svd()
 }
 
 
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::compute_inverse_svd(const double threshold)
@@ -305,6 +509,7 @@ LAPACKFullMatrix<number>::compute_inverse_svd(const double threshold)
 }
 
 
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::invert()
@@ -337,6 +542,7 @@ LAPACKFullMatrix<number>::invert()
 }
 
 
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::apply_lu_factorization(Vector<number> &v,
@@ -358,6 +564,29 @@ LAPACKFullMatrix<number>::apply_lu_factorization(Vector<number> &v,
 }
 
 
+
+template <typename number>
+void
+LAPACKFullMatrix<number>::apply_lu_factorization(LAPACKFullMatrix<number> &B,
+                                                 const bool transposed) const
+{
+  Assert(state == lu, ExcState(state));
+  Assert(B.state == matrix, ExcState(state));
+  Assert(this->n_rows() == this->n_cols(), LACExceptions::ExcNotQuadratic());
+
+  const char *trans = transposed ? &T : &N;
+  const int nn = this->n_cols();
+  const int kk = B.n_cols();
+  const number *values = &this->values[0];
+  int info = 0;
+
+  getrs(trans, &nn, &kk, values, &nn, &ipiv[0], &B.values[0], &nn, &info);
+
+  AssertThrow(info == 0, ExcInternalError());
+}
+
+
+
 template <typename number>
 void
 LAPACKFullMatrix<number>::compute_eigenvalues(
@@ -380,23 +609,20 @@ LAPACKFullMatrix<number>::compute_eigenvalues(
 
   // Optimal workspace query:
 
-  // The LAPACK routine DGEEV requires
-  // a sufficient large workspace variable,
+  // The LAPACK routine DGEEV requires a sufficient large workspace variable,
   // minimum requirement is
   //    work.size>=4*nn.
-  // However, to improve performance, a
-  // somewhat larger workspace may be needed.
+  // However, to improve performance, a somewhat larger workspace may be
+  // needed.
 
-  // SOME implementations of the LAPACK routine
-  // provide a workspace query call,
+  // SOME implementations of the LAPACK routine provide a workspace query
+  // call,
   //   info:=0, lwork:=-1
-  // which returns an optimal value for the
-  // size of the workspace array
-  // (the PETSc 2.3.0 implementation does NOT
-  // provide this functionality!).
+  // which returns an optimal value for the size of the workspace array (the
+  // PETSc 2.3.0 implementation does NOT provide this functionality!).
 
-  // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
-  // disable the workspace query.
+  // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to disable the workspace
+  // query.
 #ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
   lwork = -1;
   work.resize(1);
@@ -405,14 +631,10 @@ LAPACKFullMatrix<number>::compute_eigenvalues(
        &wr[0], &wi[0],
        &vl[0], &nn, &vr[0], &nn,
        &work[0], &lwork, &info);
-  // geev returns info=0 on
-  // success. Since we only queried
-  // the optimal size for work,
-  // everything else would not be
-  // acceptable.
+  // geev returns info=0 on success. Since we only queried the optimal size
+  // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according
-  // to suggestion.
+  // Allocate working array according to suggestion.
   lwork = (int) (work[0]+.1);
 #else
   lwork = 4*nn;                    // no query mode
@@ -425,9 +647,7 @@ LAPACKFullMatrix<number>::compute_eigenvalues(
        &wr[0], &wi[0],
        &vl[0], &nn, &vr[0], &nn,
        &work[0], &lwork, &info);
-  // Negative return value implies a
-  // wrong argument. This should be
-  // internal.
+  // Negative return value implies a wrong argument. This should be internal.
 
   Assert (info >=0, ExcInternalError());
 //TODO:[GK] What if the QR method fails?
@@ -470,20 +690,17 @@ LAPACKFullMatrix<number>::compute_eigenvalues_symmetric(
 
   // Optimal workspace query:
 
-  // The LAPACK routine ?SYEVX requires
-  // a sufficient large workspace variable,
+  // The LAPACK routine ?SYEVX requires a sufficient large workspace variable,
   // minimum requirement is
   //    work.size>=3*nn-1.
-  // However, to improve performance, a
-  // somewhat larger workspace may be needed.
+  // However, to improve performance, a somewhat larger workspace may be
+  // needed.
 
-  // SOME implementations of the LAPACK routine
-  // provide a workspace query call,
+  // SOME implementations of the LAPACK routine provide a workspace query
+  // call,
   //   info:=0, lwork:=-1
-  // which returns an optimal value for the
-  // size of the workspace array
-  // (the PETSc 2.3.0 implementation does NOT
-  // provide this functionality!).
+  // which returns an optimal value for the size of the workspace array (the
+  // PETSc 2.3.0 implementation does NOT provide this functionality!).
 
   // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
   // disable the workspace query.
@@ -498,14 +715,10 @@ LAPACKFullMatrix<number>::compute_eigenvalues_symmetric(
          &n_eigenpairs, &wr[0], values_eigenvectors,
          &nn, &work[0], &lwork, &iwork[0],
          &ifail[0], &info);
-  // syevx returns info=0 on
-  // success. Since we only queried
-  // the optimal size for work,
-  // everything else would not be
-  // acceptable.
+  // syevx returns info=0 on success. Since we only queried the optimal size
+  // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according
-  // to suggestion.
+  // Allocate working array according to suggestion.
   lwork = (int) (work[0]+.1);
 #else
   lwork = 8*nn > 1 ? 8*nn : 1; // no query mode
@@ -522,9 +735,7 @@ LAPACKFullMatrix<number>::compute_eigenvalues_symmetric(
          &nn, &work[0], &lwork, &iwork[0],
          &ifail[0], &info);
 
-  // Negative return value implies a
-  // wrong argument. This should be
-  // internal.
+  // Negative return value implies a wrong argument. This should be internal.
   Assert (info >=0, ExcInternalError());
   if (info != 0)
     std::cerr << "LAPACK error in syevx" << std::endl;
@@ -583,23 +794,20 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric(
 
   // Optimal workspace query:
 
-  // The LAPACK routine ?SYGVX requires
-  // a sufficient large workspace variable,
+  // The LAPACK routine ?SYGVX requires a sufficient large workspace variable,
   // minimum requirement is
   //    work.size>=3*nn-1.
-  // However, to improve performance, a
-  // somewhat larger workspace may be needed.
+  // However, to improve performance, a somewhat larger workspace may be
+  // needed.
 
-  // SOME implementations of the LAPACK routine
-  // provide a workspace query call,
+  // SOME implementations of the LAPACK routine provide a workspace query
+  // call,
   //   info:=0, lwork:=-1
-  // which returns an optimal value for the
-  // size of the workspace array
-  // (the PETSc 2.3.0 implementation does NOT
-  // provide this functionality!).
+  // which returns an optimal value for the size of the workspace array (the
+  // PETSc 2.3.0 implementation does NOT provide this functionality!).
 
-  // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
-  // disable the workspace query.
+  // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to disable the workspace
+  // query.
 #ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
   lwork = -1;
   work.resize(1);
@@ -609,14 +817,10 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric(
          dummy, dummy, &abs_accuracy, &n_eigenpairs,
          &wr[0], values_eigenvectors, &nn, &work[0],
          &lwork, &iwork[0], &ifail[0], &info);
-  // sygvx returns info=0 on
-  // success. Since we only queried
-  // the optimal size for work,
-  // everything else would not be
-  // acceptable.
+  // sygvx returns info=0 on success. Since we only queried the optimal size
+  // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according
-  // to suggestion.
+  // Allocate working array according to suggestion.
   lwork = (int) (work[0]+.1);
 #else
   lwork = 8*nn > 1 ? 8*nn : 1; // no query mode
@@ -624,17 +828,14 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric(
   // resize workspace arrays
   work.resize(static_cast<size_type> (lwork));
 
-  // Finally compute the generalized
-  // eigenvalues.
+  // Finally compute the generalized eigenvalues.
   sygvx (&itype, jobz, range, uplo, &nn, values_A, &nn,
          values_B, &nn, &lower_bound, &upper_bound,
          dummy, dummy, &abs_accuracy, &n_eigenpairs,
          &wr[0], values_eigenvectors, &nn, &work[0],
          &lwork, &iwork[0], &ifail[0], &info);
 
-  // Negative return value implies a
-  // wrong argument. This should be
-  // internal.
+  // Negative return value implies a wrong argument. This should be internal.
   Assert (info >=0, ExcInternalError());
   if (info != 0)
     std::cerr << "LAPACK error in sygvx" << std::endl;
@@ -686,23 +887,20 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric (
 
   // Optimal workspace query:
 
-  // The LAPACK routine DSYGV requires
-  // a sufficient large workspace variable,
+  // The LAPACK routine DSYGV requires a sufficient large workspace variable,
   // minimum requirement is
   //    work.size>=3*nn-1.
-  // However, to improve performance, a
-  // somewhat larger workspace may be needed.
+  // However, to improve performance, a somewhat larger workspace may be
+  // needed.
 
-  // SOME implementations of the LAPACK routine
-  // provide a workspace query call,
+  // SOME implementations of the LAPACK routine provide a workspace query
+  // call,
   //   info:=0, lwork:=-1
-  // which returns an optimal value for the
-  // size of the workspace array
-  // (the PETSc 2.3.0 implementation does NOT
-  // provide this functionality!).
+  // which returns an optimal value for the size of the workspace array (the
+  // PETSc 2.3.0 implementation does NOT provide this functionality!).
 
-  // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to
-  // disable the workspace query.
+  // define the DEAL_II_LIBLAPACK_NOQUERYMODE flag to disable the workspace
+  // query.
 #ifndef DEAL_II_LIBLAPACK_NOQUERYMODE
   lwork = -1;
   work.resize(1);
@@ -710,14 +908,10 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric (
   sygv (&itype, jobz, uplo, &nn, values_A, &nn,
         values_B, &nn,
         &wr[0], &work[0], &lwork, &info);
-  // sygv returns info=0 on
-  // success. Since we only queried
-  // the optimal size for work,
-  // everything else would not be
-  // acceptable.
+  // sygv returns info=0 on success. Since we only queried the optimal size
+  // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according
-  // to suggestion.
+  // Allocate working array according to suggestion.
   lwork = (int) (work[0]+.1);
 #else
   lwork = 3*nn-1 > 1 ? 3*nn-1 : 1; // no query mode
@@ -725,14 +919,11 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric (
   // resize workspace array
   work.resize((size_type) lwork);
 
-  // Finally compute the generalized
-  // eigenvalues.
+  // Finally compute the generalized eigenvalues.
   sygv (&itype, jobz, uplo, &nn, values_A, &nn,
         values_B, &nn,
         &wr[0], &work[0], &lwork, &info);
-  // Negative return value implies a
-  // wrong argument. This should be
-  // internal.
+  // Negative return value implies a wrong argument. This should be internal.
 
   Assert (info >=0, ExcInternalError());
   if (info != 0)
index 8a35af920a89b0ba449064d5b7a3760ce1a91350..bb2271ffda97f256386fd1f5c3b1709bc8b0d861 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2004 - 2013 by the deal.II authors
+// Copyright (C) 2004 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -27,12 +27,8 @@ namespace PETScWrappers
 
   FullMatrix::FullMatrix ()
   {
-    const int m=0, n=0;
-    const int ierr
-      = MatCreateSeqDense (PETSC_COMM_SELF, m, n, PETSC_NULL,
-                          &matrix);
-
-    AssertThrow (ierr == 0, ExcPETScError(ierr));
+    // empty constructor generate an empty matrix
+    do_reinit (0, 0);
   }
 
   FullMatrix::FullMatrix (const size_type m,
@@ -71,7 +67,6 @@ namespace PETScWrappers
   }
 
 
-
   const MPI_Comm &
   FullMatrix::get_mpi_communicator () const
   {
index 00d449ad91b5329a918efa2f723004fd1efa60b6..f19388ce34a73862a154cbc6bd3602c0c111f37b 100644 (file)
@@ -56,11 +56,37 @@ MGTransferPrebuilt<VECTOR>::MGTransferPrebuilt (const ConstraintMatrix &c, const
   mg_constrained_dofs(&mg_c)
 {}
 
+
 template <class VECTOR>
 MGTransferPrebuilt<VECTOR>::~MGTransferPrebuilt ()
 {}
 
 
+template <class VECTOR>
+void MGTransferPrebuilt<VECTOR>::initialize_constraints (
+  const ConstraintMatrix &c, const MGConstrainedDoFs &mg_c)
+{
+  constraints = &c;
+  mg_constrained_dofs = &mg_c;
+}
+
+
+template <class VECTOR>
+void MGTransferPrebuilt<VECTOR>::clear ()
+{
+  sizes.resize(0);
+  prolongation_matrices.resize(0);
+  prolongation_sparsities.resize(0);
+  copy_indices.resize(0);
+  copy_indices_to_me.resize(0);
+  copy_indices_from_me.resize(0);
+  component_to_block_map.resize(0);
+  interface_dofs.resize(0);
+  constraints = 0;
+  mg_constrained_dofs = 0;
+}
+
+
 template <class VECTOR>
 void MGTransferPrebuilt<VECTOR>::prolongate (
   const unsigned int to_level,
index 9f265672288e1eeb2531775620c070066f84be99..a14c34428f21b8434bf1eb21b8a4ea8db7d96b89 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -77,7 +77,10 @@ template <int dim, class DH>
 DataOutFaces<dim,DH>::DataOutFaces(const bool so)
   :
   surface_only(so)
-{}
+{
+  Assert (dim == DH::dimension,
+         ExcNotImplemented());
+}
 
 
 
@@ -85,8 +88,8 @@ template <int dim, class DH>
 void
 DataOutFaces<dim,DH>::
 build_one_patch (const FaceDescriptor *cell_and_face,
-                 internal::DataOutFaces::ParallelData<DH::dimension, DH::dimension> &data,
-                 DataOutBase::Patch<DH::dimension-1,DH::space_dimension>  &patch)
+                 internal::DataOutFaces::ParallelData<dimension, dimension> &data,
+                 DataOutBase::Patch<dimension-1,space_dimension>  &patch)
 {
   Assert (cell_and_face->first->is_locally_owned(),
           ExcNotImplemented());
@@ -95,10 +98,10 @@ build_one_patch (const FaceDescriptor *cell_and_face,
   // 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)
+  for (unsigned int vertex=0; vertex<GeometryInfo<dimension-1>::vertices_per_cell; ++vertex)
     patch.vertices[vertex] = data.mapping_collection[0].transform_unit_to_real_cell
                              (cell_and_face->first,
-                              GeometryInfo<DH::dimension>::unit_cell_vertex
+                              GeometryInfo<dimension>::unit_cell_vertex
                               (GeometryInfo<dim>::face_to_cell_vertices
                                (cell_and_face->second,
                                 vertex,
@@ -110,25 +113,25 @@ build_one_patch (const FaceDescriptor *cell_and_face,
     {
       data.reinit_all_fe_values(this->dof_data, cell_and_face->first,
                                 cell_and_face->second);
-      const FEValuesBase<DH::dimension> &fe_patch_values
+      const FEValuesBase<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();
+      Assert(patch.space_dim==dimension, ExcInternalError());
+      const std::vector<Point<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
-      patch.data.reinit(data.n_datasets+DH::dimension,
+      patch.data.reinit(data.n_datasets+dimension,
                         patch.data.size(1));
       // 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)
+      for (unsigned int i=0; i<dimension; ++i)
         for (unsigned int q=0; q<n_q_points; ++q)
-          patch.data(patch.data.size(0)-DH::dimension+i,q)=q_points[q][i];
+          patch.data(patch.data.size(0)-dimension+i,q)=q_points[q][i];
 
       // counter for data records
       unsigned int offset=0;
@@ -136,7 +139,7 @@ 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
+          const FEValuesBase<dimension> &fe_patch_values
             = data.get_present_fe_values (dataset);
           const unsigned int n_components
             = fe_patch_values.get_fe().n_components();
@@ -246,7 +249,7 @@ build_one_patch (const FaceDescriptor *cell_and_face,
           Assert (cell_and_face->first->active(), ExcCellNotActiveForCellData());
           const unsigned int cell_number
             = std::distance (this->triangulation->begin_active(),
-                             typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator(cell_and_face->first));
+                             typename Triangulation<dimension,space_dimension>::active_cell_iterator(cell_and_face->first));
 
           const double value
             = this->cell_data[dataset]->get_cell_data_value (cell_number);
@@ -262,17 +265,17 @@ build_one_patch (const FaceDescriptor *cell_and_face,
 template <int dim, class DH>
 void DataOutFaces<dim,DH>::build_patches (const unsigned int n_subdivisions_)
 {
-  build_patches (StaticMappingQ1<DH::dimension>::mapping, n_subdivisions_);
+  build_patches (StaticMappingQ1<dimension>::mapping, n_subdivisions_);
 }
 
 
 
 template <int dim, class DH>
-void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
+void DataOutFaces<dim,DH>::build_patches (const Mapping<dimension> &mapping,
                                           const unsigned int n_subdivisions_)
 {
   // Check consistency of redundant template parameter
-  Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
+  Assert (dim==dimension, ExcDimensionMismatch(dim, dimension));
 
   const unsigned int n_subdivisions = (n_subdivisions_ != 0)
                                       ? n_subdivisions_
@@ -281,7 +284,7 @@ void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
   Assert (n_subdivisions >= 1,
           ExcInvalidNumberOfSubdivisions(n_subdivisions));
 
-  typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
+  typedef DataOut_DoFData<DH,dimension+1> BaseClass;
   Assert (this->triangulation != 0,
           typename BaseClass::ExcNoTriangulationSelected());
 
@@ -316,17 +319,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::space_dimension>
+  internal::DataOutFaces::ParallelData<dimension, space_dimension>
   thread_data (n_datasets,
                n_subdivisions,
                n_postprocessor_outputs,
                mapping,
                this->get_finite_elements(),
                update_flags);
-  DataOutBase::Patch<DH::dimension-1,DH::space_dimension> sample_patch;
+  DataOutBase::Patch<dimension-1,space_dimension> sample_patch;
   sample_patch.n_subdivisions = n_subdivisions;
   sample_patch.data.reinit (n_datasets,
-                            Utilities::fixed_power<DH::dimension-1>(n_subdivisions+1));
+                            Utilities::fixed_power<dimension-1>(n_subdivisions+1));
 
   // now build the patches in parallel
   WorkStream::run (&all_faces[0],
@@ -334,7 +337,7 @@ void DataOutFaces<dim,DH>::build_patches (const Mapping<DH::dimension> &mapping,
                    std_cxx1x::bind(&DataOutFaces<dim,DH>::build_one_patch,
                                    this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
                    std_cxx1x::bind(&internal::DataOutFaces::
-                                   append_patch_to_list<dim,DH::space_dimension>,
+                                   append_patch_to_list<dim,space_dimension>,
                                    std_cxx1x::_1, std_cxx1x::ref(this->patches)),
                    thread_data,
                    sample_patch);
@@ -348,9 +351,9 @@ DataOutFaces<dim,DH>::first_face ()
 {
   // simply find first active cell
   // with a face on the boundary
-  typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator cell = this->triangulation->begin_active();
+  typename Triangulation<dimension,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)
+    for (unsigned int f=0; f<GeometryInfo<dimension>::faces_per_cell; ++f)
       if (!surface_only || cell->face(f)->at_boundary())
         return FaceDescriptor(cell, f);
 
@@ -370,7 +373,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
-  for (unsigned int f=face.second+1; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+  for (unsigned int f=face.second+1; f<GeometryInfo<dimension>::faces_per_cell; ++f)
     if (!surface_only || face.first->face(f)->at_boundary())
       // yup, that is so, so return it
       {
@@ -382,7 +385,7 @@ DataOutFaces<dim,DH>::next_face (const FaceDescriptor &old_face)
 
   // 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;
+  typename Triangulation<dimension,space_dimension>::active_cell_iterator active_cell = face.first;
 
   // increase face pointer by one
   ++active_cell;
@@ -391,7 +394,7 @@ DataOutFaces<dim,DH>::next_face (const FaceDescriptor &old_face)
   while (active_cell != this->triangulation->end())
     {
       // check all the faces of this active cell
-      for (unsigned int f=0; f<GeometryInfo<DH::dimension>::faces_per_cell; ++f)
+      for (unsigned int f=0; f<GeometryInfo<dimension>::faces_per_cell; ++f)
         if (!surface_only || active_cell->face(f)->at_boundary())
           {
             face.first  = active_cell;
index 82464c5557ec3ebbfe77f7cecfbc2f6cd52c9df5..e53a3f351346b6f5baa31a641324deba5c763e45 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2000 - 2013 by the deal.II authors
+// Copyright (C) 2000 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -95,8 +95,8 @@ template <int dim, class DH>
 void
 DataOutRotation<dim,DH>::
 build_one_patch (const cell_iterator *cell,
-                 internal::DataOutRotation::ParallelData<DH::dimension, DH::space_dimension> &data,
-                 std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> > &patches)
+                 internal::DataOutRotation::ParallelData<dimension, space_dimension> &data,
+                 std::vector<DataOutBase::Patch<dimension+1,space_dimension+1> > &patches)
 {
   if (dim == 3)
     {
@@ -118,12 +118,12 @@ build_one_patch (const cell_iterator *cell,
   // 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);
+  std::vector<Point<dimension+1> > angle_directions (n_patches_per_circle+1);
   for (unsigned int i=0; i<=n_patches_per_circle; ++i)
     {
-      angle_directions[i][DH::dimension-1] = std::cos(2*numbers::PI *
+      angle_directions[i][dimension-1] = std::cos(2*numbers::PI *
                                                       i/n_patches_per_circle);
-      angle_directions[i][DH::dimension] = std::sin(2*numbers::PI *
+      angle_directions[i][dimension] = std::sin(2*numbers::PI *
                                                     i/n_patches_per_circle);
     }
 
@@ -132,7 +132,7 @@ build_one_patch (const cell_iterator *cell,
       // 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)
+      switch (dimension)
         {
         case 1:
         {
@@ -152,10 +152,10 @@ build_one_patch (const cell_iterator *cell,
         case 2:
         {
           for (unsigned int vertex=0;
-               vertex<GeometryInfo<DH::dimension>::vertices_per_cell;
+               vertex<GeometryInfo<dimension>::vertices_per_cell;
                ++vertex)
             {
-              const Point<DH::dimension> v = (*cell)->vertex(vertex);
+              const Point<dimension> v = (*cell)->vertex(vertex);
 
               // make sure that the radial variable does attain negative
               // values
@@ -165,9 +165,9 @@ build_one_patch (const cell_iterator *cell,
               patches[angle].vertices[vertex] = v(0) * angle_directions[angle];
               patches[angle].vertices[vertex][0] = v(1);
 
-              patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell]
+              patches[angle].vertices[vertex+GeometryInfo<dimension>::vertices_per_cell]
                 = v(0) * angle_directions[angle+1];
-              patches[angle].vertices[vertex+GeometryInfo<DH::dimension>::vertices_per_cell][0]
+              patches[angle].vertices[vertex+GeometryInfo<dimension>::vertices_per_cell][0]
                 = v(1);
             };
 
@@ -187,7 +187,7 @@ build_one_patch (const cell_iterator *cell,
           // first fill dof_data
           for (unsigned int dataset=0; dataset<this->dof_data.size(); ++dataset)
             {
-              const FEValuesBase<DH::dimension> &fe_patch_values
+              const FEValuesBase<dimension> &fe_patch_values
                 = data.get_present_fe_values(dataset);
               const unsigned int n_components
                 = fe_patch_values.get_fe().n_components();
@@ -217,7 +217,7 @@ build_one_patch (const cell_iterator *cell,
                       if (update_flags & update_quadrature_points)
                         data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
 
-                      std::vector<Point<DH::space_dimension> > dummy_normals;
+                      std::vector<Point<space_dimension> > dummy_normals;
                       postprocessor->
                       compute_derived_quantities_scalar(data.patch_values,
                                                         data.patch_gradients,
@@ -245,7 +245,7 @@ build_one_patch (const cell_iterator *cell,
                       if (update_flags & update_quadrature_points)
                         data.patch_evaluation_points = fe_patch_values.get_quadrature_points();
 
-                      std::vector<Point<DH::space_dimension> > dummy_normals;
+                      std::vector<Point<space_dimension> > dummy_normals;
                       postprocessor->
                       compute_derived_quantities_vector(data.patch_values_system,
                                                         data.patch_gradients_system,
@@ -259,7 +259,7 @@ build_one_patch (const cell_iterator *cell,
                        component<this->dof_data[dataset]->n_output_variables;
                        ++component)
                     {
-                      switch (DH::dimension)
+                      switch (dimension)
                         {
                         case 1:
                           for (unsigned int x=0; x<n_points; ++x)
@@ -290,7 +290,7 @@ build_one_patch (const cell_iterator *cell,
                   this->dof_data[dataset]->get_function_values (fe_patch_values,
                                                                 data.patch_values);
 
-                  switch (DH::dimension)
+                  switch (dimension)
                     {
                     case 1:
                       for (unsigned int x=0; x<n_points; ++x)
@@ -325,7 +325,7 @@ build_one_patch (const cell_iterator *cell,
                   for (unsigned int component=0; component<n_components;
                        ++component)
                     {
-                      switch (DH::dimension)
+                      switch (dimension)
                         {
                         case 1:
                           for (unsigned int x=0; x<n_points; ++x)
@@ -364,10 +364,10 @@ build_one_patch (const cell_iterator *cell,
                       ExcMessage("Cell must be active for cell data"));
               const unsigned int cell_number
                 = std::distance (this->triangulation->begin_active(),
-                                 typename Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator(*cell));
+                                 typename Triangulation<dimension,space_dimension>::active_cell_iterator(*cell));
               const double value
                 = this->cell_data[dataset]->get_cell_data_value (cell_number);
-              switch (DH::dimension)
+              switch (dimension)
                 {
                 case 1:
                   for (unsigned int x=0; x<n_points; ++x)
@@ -405,8 +405,8 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
 {
   // Check consistency of redundant
   // template parameter
-  Assert (dim==DH::dimension, ExcDimensionMismatch(dim, DH::dimension));
-  typedef DataOut_DoFData<DH,DH::dimension+1> BaseClass;
+  Assert (dim==dimension, ExcDimensionMismatch(dim, dimension));
+  typedef DataOut_DoFData<DH,dimension+1> BaseClass;
   Assert (this->triangulation != 0,
           typename BaseClass::ExcNoTriangulationSelected());
 
@@ -455,19 +455,19 @@ 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>
+  const MappingQ1<dimension, space_dimension> mapping;
+  internal::DataOutRotation::ParallelData<dimension, space_dimension>
   thread_data (n_datasets,
                n_subdivisions, n_patches_per_circle,
                n_postprocessor_outputs, mapping, this->get_finite_elements(),
                update_flags);
-  std::vector<DataOutBase::Patch<DH::dimension+1,DH::space_dimension+1> >
+  std::vector<DataOutBase::Patch<dimension+1,space_dimension+1> >
   new_patches (n_patches_per_circle);
   for (unsigned int i=0; i<new_patches.size(); ++i)
     {
       new_patches[i].n_subdivisions = n_subdivisions;
       new_patches[i].data.reinit (n_datasets,
-                                  Utilities::fixed_power<DH::dimension+1>(n_subdivisions+1));
+                                  Utilities::fixed_power<dimension+1>(n_subdivisions+1));
     }
 
   // now build the patches in parallel
@@ -476,7 +476,7 @@ void DataOutRotation<dim,DH>::build_patches (const unsigned int n_patches_per_ci
                    std_cxx1x::bind(&DataOutRotation<dim,DH>::build_one_patch,
                                    this, std_cxx1x::_1, std_cxx1x::_2, std_cxx1x::_3),
                    std_cxx1x::bind(&internal::DataOutRotation
-                                   ::append_patch_to_list<dim,DH::space_dimension>,
+                                   ::append_patch_to_list<dim,space_dimension>,
                                    std_cxx1x::_1, std_cxx1x::ref(this->patches)),
                    thread_data,
                    new_patches);
@@ -499,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 Triangulation<DH::dimension,DH::space_dimension>::active_cell_iterator active_cell = cell;
+  typename Triangulation<dimension,space_dimension>::active_cell_iterator active_cell = cell;
   ++active_cell;
   return active_cell;
 }
index 85edde6ed05a42c32396411031296caa647cca9b..75a4578557aa114bd6d1a36dd4cf96d24d3c4d16 100644 (file)
@@ -45,832 +45,1083 @@ DEAL_II_NAMESPACE_OPEN
 
 
 
-template <typename T>
-static inline T sqr (const T t)
+namespace
 {
-  return t*t;
+  template <typename T>
+  inline T sqr (const T t)
+  {
+    return t*t;
+  }
 }
 
+// --------------- First the classes and functions that describe individual
+// --------------- derivatives
 
+namespace DerivativeApproximation
+{
+  namespace internal
+  {
+    /**
+     * The following class is used to describe the data needed to compute the
+     * finite difference approximation to the gradient on a cell. See the
+     * general documentation of this class for more information on
+     * implementational details.
+     *
+     * @author Wolfgang Bangerth, 2000
+     */
+    template <int dim>
+    class Gradient
+    {
+      public:
+        /**
+         * Declare which data fields have to be updated for the function @p
+         * get_projected_derivative to work.
+         */
+        static const UpdateFlags update_flags;
+
+        /**
+         * Declare the data type which holds the derivative described by this
+         * class.
+         */
+        typedef Tensor<1,dim> Derivative;
+
+        /**
+         * Likewise declare the data type that holds the derivative projected to a
+         * certain directions.
+         */
+        typedef double        ProjectedDerivative;
+
+        /**
+         * Given an FEValues object initialized to a cell, and a solution vector,
+         * extract the desired derivative at the first quadrature point (which is
+         * the only one, as we only evaluate the finite element field at the
+         * center of each cell).
+         */
+        template <class InputVector, int spacedim>
+        static ProjectedDerivative
+        get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
+                                  const InputVector    &solution,
+                                  const unsigned int    component);
+
+        /**
+         * Return the norm of the derivative object. Here, for the gradient, we
+         * choose the Euclidian norm of the gradient vector.
+         */
+        static double derivative_norm (const Derivative &d);
+
+        /**
+         * If for the present derivative order, symmetrization of the derivative
+         * tensor is necessary, then do so on the argument.
+         *
+         * For the first derivatives, no such thing is necessary, so this function
+         * is a no-op.
+         */
+        static void symmetrize (Derivative &derivative_tensor);
+    };
 
-// static variables
-template <int dim>
-const UpdateFlags DerivativeApproximation::Gradient<dim>::update_flags = update_values;
-
-template <int dim>
-const UpdateFlags DerivativeApproximation::SecondDerivative<dim>::update_flags = update_gradients;
+    // static variables
+    template <int dim>
+    const UpdateFlags Gradient<dim>::update_flags = update_values;
 
-template <int dim>
-const UpdateFlags DerivativeApproximation::ThirdDerivative<dim>::update_flags = update_hessians;
 
+    template <int dim>
+    template <class InputVector, int spacedim>
+    inline
+    typename Gradient<dim>::ProjectedDerivative
+    Gradient<dim>::
+    get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
+        const InputVector    &solution,
+        const unsigned int    component)
+        {
+        if (fe_values.get_fe().n_components() == 1)
+          {
+            std::vector<ProjectedDerivative> values (1);
+            fe_values.get_function_values (solution, values);
+            return values[0];
+          }
+        else
+          {
+            std::vector<Vector<double> > values
+            (1, Vector<double>(fe_values.get_fe().n_components()));
+            fe_values.get_function_values (solution, values);
+            return values[0](component);
+          }
+        }
 
 
-// Dummy structures and dummy function used for WorkStream
-namespace internal
-{
-  namespace Assembler
-  {
-    struct Scratch
-    {
-      Scratch() {}
-    };
 
-    struct CopyData
+    template <int dim>
+    inline
+    double
+    Gradient<dim>::derivative_norm (const Derivative &d)
     {
-      CopyData() {}
-    };
-  }
-}
+      double s = 0;
+      for (unsigned int i=0; i<dim; ++i)
+        s += d[i]*d[i];
+      return std::sqrt(s);
+    }
 
 
 
-template <int dim>
-template <class InputVector, int spacedim>
-inline
-typename DerivativeApproximation::Gradient<dim>::ProjectedDerivative
-DerivativeApproximation::Gradient<dim>::
-get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
-                          const InputVector    &solution,
-                          const unsigned int    component)
-{
-  if (fe_values.get_fe().n_components() == 1)
+    template <int dim>
+    inline
+    void
+    Gradient<dim>::symmetrize (Derivative &)
     {
-      std::vector<ProjectedDerivative> values (1);
-      fe_values.get_function_values (solution, values);
-      return values[0];
+      // nothing to do here
     }
-  else
+
+
+
+    /**
+     * The following class is used to describe the data needed to compute the
+     * finite difference approximation to the second derivatives on a cell. See
+     * the general documentation of this class for more information on
+     * implementational details.
+     *
+     * @author Wolfgang Bangerth, 2000
+     */
+    template <int dim>
+    class SecondDerivative
     {
-      std::vector<Vector<double> > values
-      (1, Vector<double>(fe_values.get_fe().n_components()));
-      fe_values.get_function_values (solution, values);
-      return values[0](component);
-    }
-}
+      public:
+        /**
+         * Declare which data fields have to be updated for the function @p
+         * get_projected_derivative to work.
+         */
+        static const UpdateFlags update_flags;
+
+        /**
+         * Declare the data type which holds the derivative described by this
+         * class.
+         */
+        typedef Tensor<2,dim> Derivative;
+
+        /**
+         * Likewise declare the data type that holds the derivative projected to a
+         * certain directions.
+         */
+        typedef Tensor<1,dim> ProjectedDerivative;
+
+        /**
+         * Given an FEValues object initialized to a cell, and a solution vector,
+         * extract the desired derivative at the first quadrature point (which is
+         * the only one, as we only evaluate the finite element field at the
+         * center of each cell).
+         */
+        template <class InputVector, int spacedim>
+        static ProjectedDerivative
+        get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
+                                  const InputVector    &solution,
+                                  const unsigned int    component);
+
+        /**
+         * Return the norm of the derivative object. Here, for the (symmetric)
+         * tensor of second derivatives, we choose the absolute value of the
+         * largest eigenvalue, which is the matrix norm associated to the $l_2$
+         * norm of vectors. It is also the largest value of the curvature of the
+         * solution.
+         */
+        static double derivative_norm (const Derivative &d);
+
+        /**
+         * If for the present derivative order, symmetrization of the derivative
+         * tensor is necessary, then do so on the argument.
+         *
+         * For the second derivatives, each entry of the tensor is set to the mean
+         * of its value and the value of the transpose element.
+         *
+         * Note that this function actually modifies its argument.
+         */
+        static void symmetrize (Derivative &derivative_tensor);
+    };
 
+    template <int dim>
+    const UpdateFlags SecondDerivative<dim>::update_flags = update_gradients;
 
 
-template <int dim>
-inline
-double
-DerivativeApproximation::Gradient<dim>::derivative_norm (const Derivative &d)
-{
-  double s = 0;
-  for (unsigned int i=0; i<dim; ++i)
-    s += d[i]*d[i];
-  return std::sqrt(s);
-}
+    template <int dim>
+    template <class InputVector, int spacedim>
+    inline
+    typename SecondDerivative<dim>::ProjectedDerivative
+    SecondDerivative<dim>::
+    get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
+        const InputVector    &solution,
+        const unsigned int    component)
+        {
+        if (fe_values.get_fe().n_components() == 1)
+          {
+            std::vector<ProjectedDerivative> values (1);
+            fe_values.get_function_gradients (solution, values);
+            return values[0];
+          }
+        else
+          {
+            std::vector<std::vector<ProjectedDerivative> > values
+            (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+            fe_values.get_function_gradients (solution, values);
+            return values[0][component];
+          };
+        }
 
 
 
-template <int dim>
-inline
-void
-DerivativeApproximation::Gradient<dim>::symmetrize (Derivative &)
-{
-  // nothing to do here
-}
+    template <>
+    inline
+    double
+    SecondDerivative<1>::
+    derivative_norm (const Derivative &d)
+    {
+      return std::fabs (d[0][0]);
+    }
 
 
 
-template <int dim>
-template <class InputVector, int spacedim>
-inline
-typename DerivativeApproximation::SecondDerivative<dim>::ProjectedDerivative
-DerivativeApproximation::SecondDerivative<dim>::
-get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
-                          const InputVector    &solution,
-                          const unsigned int    component)
-{
-  if (fe_values.get_fe().n_components() == 1)
+    template <>
+    inline
+    double
+    SecondDerivative<2>::
+    derivative_norm (const Derivative &d)
     {
-      std::vector<ProjectedDerivative> values (1);
-      fe_values.get_function_gradients (solution, values);
-      return values[0];
+      // note that d should be a
+      // symmetric 2x2 tensor, so the
+      // eigenvalues are:
+      //
+      // 1/2(a+b\pm\sqrt((a-b)^2+4c^2))
+      //
+      // if the d_11=a, d_22=b,
+      // d_12=d_21=c
+      const double radicand = dealii::sqr(d[0][0] - d[1][1]) +
+          4*dealii::sqr(d[0][1]);
+      const double eigenvalues[2]
+                               = { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
+                                   0.5*(d[0][0] + d[1][1] - std::sqrt(radicand))
+      };
+
+      return std::max (std::fabs (eigenvalues[0]),
+                       std::fabs (eigenvalues[1]));
     }
-  else
+
+
+
+    template <>
+    inline
+    double
+    SecondDerivative<3>::
+    derivative_norm (const Derivative &d)
     {
-      std::vector<std::vector<ProjectedDerivative> > values
-      (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
-      fe_values.get_function_gradients (solution, values);
-      return values[0][component];
-    };
-}
+      /*
+      compute the three eigenvalues of the tensor @p{d} and take the
+      largest. one could use the following maple script to generate C
+      code:
+
+      with(linalg);
+      readlib(C);
+      A:=matrix(3,3,[[a00,a01,a02],[a01,a11,a12],[a02,a12,a22]]);
+      E:=eigenvals(A);
+      EE:=vector(3,[E[1],E[2],E[3]]);
+      C(EE);
+
+      Unfortunately, with both optimized and non-optimized output, at some
+      places the code `sqrt(-1.0)' is emitted, and I don't know what
+      Maple intends to do with it. This happens both with Maple4 and
+      Maple5.
+
+      Fortunately, Roger Young provided the following Fortran code, which
+      is transcribed below to C. The code uses an algorithm that uses the
+      invariants of a symmetric matrix. (The translated algorithm is
+      augmented by a test for R>0, since R==0 indicates that all three
+      eigenvalues are equal.)
+
+
+          PROGRAM MAIN
+
+    C FIND EIGENVALUES OF REAL SYMMETRIC MATRIX
+    C (ROGER YOUNG, 2001)
+
+          IMPLICIT NONE
+
+          REAL*8 A11, A12, A13, A22, A23, A33
+          REAL*8 I1, J2, J3, AM
+          REAL*8 S11, S12, S13, S22, S23, S33
+          REAL*8 SS12, SS23, SS13
+          REAL*8 R,R3, XX,YY, THETA
+          REAL*8 A1,A2,A3
+          REAL*8 PI
+          PARAMETER (PI=3.141592653587932384D0)
+          REAL*8 A,B,C, TOL
+          PARAMETER (TOL=1.D-14)
+
+    C DEFINE A TEST MATRIX
+
+          A11 = -1.D0
+          A12 = 5.D0
+          A13 = 3.D0
+          A22 = -2.D0
+          A23 = 0.5D0
+          A33 = 4.D0
+
+
+          I1 = A11 + A22 + A33
+          AM = I1/3.D0
+
+          S11 = A11 - AM
+          S22 = A22 - AM
+          S33 = A33 - AM
+          S12 = A12
+          S13 = A13
+          S23 = A23
+
+          SS12 = S12*S12
+          SS23 = S23*S23
+          SS13 = S13*S13
+
+          J2 = S11*S11 + S22*S22 + S33*S33
+          J2 = J2 + 2.D0*(SS12 + SS23 + SS13)
+          J2 = J2/2.D0
+
+          J3 = S11**3 + S22**3 + S33**3
+          J3 = J3 + 3.D0*S11*(SS12 + SS13)
+          J3 = J3 + 3.D0*S22*(SS12 + SS23)
+          J3 = J3 + 3.D0*S33*(SS13 + SS23)
+          J3 = J3 + 6.D0*S12*S23*S13
+          J3 = J3/3.D0
+
+          R = SQRT(4.D0*J2/3.D0)
+          R3 = R*R*R
+          XX = 4.D0*J3/R3
+
+          YY = 1.D0 - DABS(XX)
+          IF(YY.LE.0.D0)THEN
+             IF(YY.GT.(-TOL))THEN
+                WRITE(6,*)'Equal roots: XX= ',XX
+                A = -(XX/DABS(XX))*SQRT(J2/3.D0)
+                B = AM + A
+                C = AM - 2.D0*A
+                WRITE(6,*)B,' (twice) ',C
+                STOP
+             ELSE
+                WRITE(6,*)'Error: XX= ',XX
+                STOP
+             ENDIF
+          ENDIF
+
+          THETA = (ACOS(XX))/3.D0
+
+          A1 = AM + R*COS(THETA)
+          A2 = AM + R*COS(THETA + 2.D0*PI/3.D0)
+          A3 = AM + R*COS(THETA + 4.D0*PI/3.D0)
+
+          WRITE(6,*)A1,A2,A3
+
+          STOP
+          END
+
+       */
+
+      const double am = trace(d) / 3.;
+
+      // s := d - trace(d) I
+      Tensor<2,3> s = d;
+      for (unsigned int i=0; i<3; ++i)
+        s[i][i] -= am;
+
+      const double ss01 = s[0][1] * s[0][1],
+          ss12 = s[1][2] * s[1][2],
+          ss02 = s[0][2] * s[0][2];
+
+      const double J2 = (s[0][0]*s[0][0] + s[1][1]*s[1][1] + s[2][2]*s[2][2]
+                                                                          + 2 * (ss01 + ss02 + ss12))  / 2.;
+      const double J3 = (std::pow(s[0][0],3) + std::pow(s[1][1],3) + std::pow(s[2][2],3)
+      + 3. * s[0][0] * (ss01 + ss02)
+      + 3. * s[1][1] * (ss01 + ss12)
+      + 3. * s[2][2] * (ss02 + ss12)
+      + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
+
+      const double R  = std::sqrt (4. * J2 / 3.);
+
+      double EE[3] = { 0, 0, 0 };
+      // the eigenvalues are away from
+      // @p{am} in the order of R. thus,
+      // if R<<AM, then we have the
+      // degenerate case with three
+      // identical eigenvalues. check
+      // this first
+      if (R <= 1e-14*std::fabs(am))
+        EE[0] = EE[1] = EE[2] = am;
+      else
+        {
+          // at least two eigenvalues are
+          // distinct
+          const double R3 = R*R*R;
+          const double XX = 4. * J3 / R3;
+          const double YY = 1. - std::fabs(XX);
+
+          Assert (YY > -1e-14, ExcInternalError());
+
+          if (YY < 0)
+            {
+              // two roots are equal
+              const double a = (XX>0 ? -1. : 1.) * R / 2;
+              EE[0] = EE[1] = am + a;
+              EE[2] = am - 2.*a;
+            }
+          else
+            {
+              const double theta = std::acos(XX) / 3.;
+              EE[0] = am + R*std::cos(theta);
+              EE[1] = am + R*std::cos(theta + 2./3.*numbers::PI);
+              EE[2] = am + R*std::cos(theta + 4./3.*numbers::PI);
+            };
+        };
 
+      return std::max (std::fabs (EE[0]),
+                       std::max (std::fabs (EE[1]),
+                                 std::fabs (EE[2])));
+    }
 
 
-template <>
-inline
-double
-DerivativeApproximation::SecondDerivative<1>::
-derivative_norm (const Derivative &d)
-{
-  return std::fabs (d[0][0]);
-}
 
+    template <int dim>
+    inline
+    double
+    SecondDerivative<dim>::
+    derivative_norm (const Derivative &)
+    {
+      // computing the spectral norm is
+      // not so simple in general. it is
+      // feasible for dim==3 as shown
+      // above, since then there are
+      // still closed form expressions of
+      // the roots of the characteristic
+      // polynomial, and they can easily
+      // be computed using
+      // maple. however, for higher
+      // dimensions, some other method
+      // needs to be employed. maybe some
+      // steps of the power method would
+      // suffice?
+      Assert (false, ExcNotImplemented());
+      return 0;
+    }
 
 
-template <>
-inline
-double
-DerivativeApproximation::SecondDerivative<2>::
-derivative_norm (const Derivative &d)
-{
-  // note that d should be a
-  // symmetric 2x2 tensor, so the
-  // eigenvalues are:
-  //
-  // 1/2(a+b\pm\sqrt((a-b)^2+4c^2))
-  //
-  // if the d_11=a, d_22=b,
-  // d_12=d_21=c
-  const double radicand = dealii::sqr(d[0][0] - d[1][1]) +
-                          4*dealii::sqr(d[0][1]);
-  const double eigenvalues[2]
-    = { 0.5*(d[0][0] + d[1][1] + std::sqrt(radicand)),
-        0.5*(d[0][0] + d[1][1] - std::sqrt(radicand))
-      };
 
-  return std::max (std::fabs (eigenvalues[0]),
-                   std::fabs (eigenvalues[1]));
-}
+    template <int dim>
+    inline
+    void
+    SecondDerivative<dim>::symmetrize (Derivative &d)
+    {
+      // symmetrize non-diagonal entries
+      for (unsigned int i=0; i<dim; ++i)
+        for (unsigned int j=i+1; j<dim; ++j)
+          {
+            const double s = (d[i][j] + d[j][i]) / 2;
+            d[i][j] = d[j][i] = s;
+          };
+    }
 
 
 
-template <>
-inline
-double
-DerivativeApproximation::SecondDerivative<3>::
-derivative_norm (const Derivative &d)
-{
-  /*
-    compute the three eigenvalues of the tensor @p{d} and take the
-    largest. one could use the following maple script to generate C
-    code:
-
-    with(linalg);
-    readlib(C);
-    A:=matrix(3,3,[[a00,a01,a02],[a01,a11,a12],[a02,a12,a22]]);
-    E:=eigenvals(A);
-    EE:=vector(3,[E[1],E[2],E[3]]);
-    C(EE);
-
-    Unfortunately, with both optimized and non-optimized output, at some
-    places the code `sqrt(-1.0)' is emitted, and I don't know what
-    Maple intends to do with it. This happens both with Maple4 and
-    Maple5.
-
-    Fortunately, Roger Young provided the following Fortran code, which
-    is transcribed below to C. The code uses an algorithm that uses the
-    invariants of a symmetric matrix. (The translated algorithm is
-    augmented by a test for R>0, since R==0 indicates that all three
-    eigenvalues are equal.)
-
-
-        PROGRAM MAIN
-
-  C FIND EIGENVALUES OF REAL SYMMETRIC MATRIX
-  C (ROGER YOUNG, 2001)
-
-        IMPLICIT NONE
-
-        REAL*8 A11, A12, A13, A22, A23, A33
-        REAL*8 I1, J2, J3, AM
-        REAL*8 S11, S12, S13, S22, S23, S33
-        REAL*8 SS12, SS23, SS13
-        REAL*8 R,R3, XX,YY, THETA
-        REAL*8 A1,A2,A3
-        REAL*8 PI
-        PARAMETER (PI=3.141592653587932384D0)
-        REAL*8 A,B,C, TOL
-        PARAMETER (TOL=1.D-14)
-
-  C DEFINE A TEST MATRIX
-
-        A11 = -1.D0
-        A12 = 5.D0
-        A13 = 3.D0
-        A22 = -2.D0
-        A23 = 0.5D0
-        A33 = 4.D0
-
-
-        I1 = A11 + A22 + A33
-        AM = I1/3.D0
-
-        S11 = A11 - AM
-        S22 = A22 - AM
-        S33 = A33 - AM
-        S12 = A12
-        S13 = A13
-        S23 = A23
-
-        SS12 = S12*S12
-        SS23 = S23*S23
-        SS13 = S13*S13
-
-        J2 = S11*S11 + S22*S22 + S33*S33
-        J2 = J2 + 2.D0*(SS12 + SS23 + SS13)
-        J2 = J2/2.D0
-
-        J3 = S11**3 + S22**3 + S33**3
-        J3 = J3 + 3.D0*S11*(SS12 + SS13)
-        J3 = J3 + 3.D0*S22*(SS12 + SS23)
-        J3 = J3 + 3.D0*S33*(SS13 + SS23)
-        J3 = J3 + 6.D0*S12*S23*S13
-        J3 = J3/3.D0
-
-        R = SQRT(4.D0*J2/3.D0)
-        R3 = R*R*R
-        XX = 4.D0*J3/R3
-
-        YY = 1.D0 - DABS(XX)
-        IF(YY.LE.0.D0)THEN
-           IF(YY.GT.(-TOL))THEN
-              WRITE(6,*)'Equal roots: XX= ',XX
-              A = -(XX/DABS(XX))*SQRT(J2/3.D0)
-              B = AM + A
-              C = AM - 2.D0*A
-              WRITE(6,*)B,' (twice) ',C
-              STOP
-           ELSE
-              WRITE(6,*)'Error: XX= ',XX
-              STOP
-           ENDIF
-        ENDIF
-
-        THETA = (ACOS(XX))/3.D0
-
-        A1 = AM + R*COS(THETA)
-        A2 = AM + R*COS(THETA + 2.D0*PI/3.D0)
-        A3 = AM + R*COS(THETA + 4.D0*PI/3.D0)
-
-        WRITE(6,*)A1,A2,A3
-
-        STOP
-        END
-
-  */
-
-  const double am = trace(d) / 3.;
-
-  // s := d - trace(d) I
-  Tensor<2,3> s = d;
-  for (unsigned int i=0; i<3; ++i)
-    s[i][i] -= am;
-
-  const double ss01 = s[0][1] * s[0][1],
-               ss12 = s[1][2] * s[1][2],
-               ss02 = s[0][2] * s[0][2];
-
-  const double J2 = (s[0][0]*s[0][0] + s[1][1]*s[1][1] + s[2][2]*s[2][2]
-                     + 2 * (ss01 + ss02 + ss12))  / 2.;
-  const double J3 = (std::pow(s[0][0],3) + std::pow(s[1][1],3) + std::pow(s[2][2],3)
-                     + 3. * s[0][0] * (ss01 + ss02)
-                     + 3. * s[1][1] * (ss01 + ss12)
-                     + 3. * s[2][2] * (ss02 + ss12)
-                     + 6. * s[0][1] * s[0][2] * s[1][2]) / 3.;
-
-  const double R  = std::sqrt (4. * J2 / 3.);
-
-  double EE[3] = { 0, 0, 0 };
-  // the eigenvalues are away from
-  // @p{am} in the order of R. thus,
-  // if R<<AM, then we have the
-  // degenerate case with three
-  // identical eigenvalues. check
-  // this first
-  if (R <= 1e-14*std::fabs(am))
-    EE[0] = EE[1] = EE[2] = am;
-  else
+    template <int dim>
+    class ThirdDerivative
     {
-      // at least two eigenvalues are
-      // distinct
-      const double R3 = R*R*R;
-      const double XX = 4. * J3 / R3;
-      const double YY = 1. - std::fabs(XX);
+      public:
+        /**
+         * Declare which data fields have to be updated for the function @p
+         * get_projected_derivative to work.
+         */
+        static const UpdateFlags update_flags;
+
+        /**
+         * Declare the data type which
+         * holds the derivative described
+         * by this class.
+         */
+        typedef Tensor<3,dim> Derivative;
+
+        /**
+         * Likewise declare the data type that holds the derivative projected to a
+         * certain directions.
+         */
+        typedef Tensor<2,dim> ProjectedDerivative;
+
+        /**
+         * Given an FEValues object initialized to a cell, and a solution vector,
+         * extract the desired derivative at the first quadrature point (which is
+         * the only one, as we only evaluate the finite element field at the
+         * center of each cell).
+         */
+        template <class InputVector, int spacedim>
+        static ProjectedDerivative
+        get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
+                                  const InputVector    &solution,
+                                  const unsigned int    component);
+
+        /**
+         * Return the norm of the derivative object. Here, for the (symmetric)
+         * tensor of second derivatives, we choose the absolute value of the
+         * largest eigenvalue, which is the matrix norm associated to the $l_2$
+         * norm of vectors. It is also the largest value of the curvature of the
+         * solution.
+         */
+        static double derivative_norm (const Derivative &d);
+
+        /**
+         * If for the present derivative order, symmetrization of the derivative
+         * tensor is necessary, then do so on the argument.
+         *
+         * For the second derivatives, each entry of the tensor is set to the mean
+         * of its value and the value of the transpose element.
+         *
+         * Note that this function actually modifies its argument.
+         */
+        static void symmetrize (Derivative &derivative_tensor);
+    };
 
-      Assert (YY > -1e-14, ExcInternalError());
+    template <int dim>
+    const UpdateFlags ThirdDerivative<dim>::update_flags = update_hessians;
 
-      if (YY < 0)
+
+    template <int dim>
+    template <class InputVector, int spacedim>
+    inline
+    typename ThirdDerivative<dim>::ProjectedDerivative
+    ThirdDerivative<dim>::
+    get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
+        const InputVector    &solution,
+        const unsigned int    component)
         {
-          // two roots are equal
-          const double a = (XX>0 ? -1. : 1.) * R / 2;
-          EE[0] = EE[1] = am + a;
-          EE[2] = am - 2.*a;
+        if (fe_values.get_fe().n_components() == 1)
+          {
+            std::vector<ProjectedDerivative> values (1);
+            fe_values.get_function_hessians (solution, values);
+            return values[0];
+          }
+        else
+          {
+            std::vector<std::vector<ProjectedDerivative> > values
+            (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
+            fe_values.get_function_hessians (solution, values);
+            return values[0][component];
+          };
         }
-      else
-        {
-          const double theta = std::acos(XX) / 3.;
-          EE[0] = am + R*std::cos(theta);
-          EE[1] = am + R*std::cos(theta + 2./3.*numbers::PI);
-          EE[2] = am + R*std::cos(theta + 4./3.*numbers::PI);
-        };
-    };
-
-  return std::max (std::fabs (EE[0]),
-                   std::max (std::fabs (EE[1]),
-                             std::fabs (EE[2])));
-}
 
 
 
-template <int dim>
-inline
-double
-DerivativeApproximation::SecondDerivative<dim>::
-derivative_norm (const Derivative &)
-{
-  // computing the spectral norm is
-  // not so simple in general. it is
-  // feasible for dim==3 as shown
-  // above, since then there are
-  // still closed form expressions of
-  // the roots of the characteristic
-  // polynomial, and they can easily
-  // be computed using
-  // maple. however, for higher
-  // dimensions, some other method
-  // needs to be employed. maybe some
-  // steps of the power method would
-  // suffice?
-  Assert (false, ExcNotImplemented());
-  return 0;
-}
+    template <>
+    inline
+    double
+    ThirdDerivative<1>::
+    derivative_norm (const Derivative &d)
+    {
+      return std::fabs (d[0][0][0]);
+    }
 
 
 
-template <int dim>
-inline
-void
-DerivativeApproximation::SecondDerivative<dim>::symmetrize (Derivative &d)
-{
-  // symmetrize non-diagonal entries
-  for (unsigned int i=0; i<dim; ++i)
-    for (unsigned int j=i+1; j<dim; ++j)
-      {
-        const double s = (d[i][j] + d[j][i]) / 2;
-        d[i][j] = d[j][i] = s;
-      };
-}
+    template <int dim>
+    inline
+    double
+    ThirdDerivative<dim>::
+    derivative_norm (const Derivative &d)
+    {
+      // return the Frobenius-norm. this is a
+      // member function of Tensor<rank_,dim>
+      return d.norm();
+    }
 
 
-template <int dim>
-template <class InputVector, int spacedim>
-inline
-typename DerivativeApproximation::ThirdDerivative<dim>::ProjectedDerivative
-DerivativeApproximation::ThirdDerivative<dim>::
-get_projected_derivative (const FEValues<dim,spacedim>  &fe_values,
-                          const InputVector    &solution,
-                          const unsigned int    component)
-{
-  if (fe_values.get_fe().n_components() == 1)
+    template <int dim>
+    inline
+    void
+    ThirdDerivative<dim>::symmetrize (Derivative &d)
     {
-      std::vector<ProjectedDerivative> values (1);
-      fe_values.get_function_hessians (solution, values);
-      return values[0];
+      // symmetrize non-diagonal entries
+
+      // first do it in the case, that i,j,k are
+      // pairwise different (which can onlky happen
+      // in dim >= 3)
+      for (unsigned int i=0; i<dim; ++i)
+        for (unsigned int j=i+1; j<dim; ++j)
+          for (unsigned int k=j+1; k<dim; ++k)
+            {
+              const double s = (d[i][j][k] +
+                  d[i][k][j] +
+                  d[j][i][k] +
+                  d[j][k][i] +
+                  d[k][i][j] +
+                  d[k][j][i]) / 6;
+              d[i][j][k]
+                      = d[i][k][j]
+                                = d[j][i][k]
+                                          = d[j][k][i]
+                                                    = d[k][i][j]
+                                                              = d[k][j][i]
+                                                                        = s;
+            }
+      // now do the case, where two indices are
+      // equal
+      for (unsigned int i=0; i<dim; ++i)
+        for (unsigned int j=i+1; j<dim; ++j)
+          {
+            // case 1: index i (lower one) is
+            // double
+            const double s = (d[i][i][j] +
+                d[i][j][i] +
+                d[j][i][i] ) / 3;
+            d[i][i][j]
+                    = d[i][j][i]
+                              = d[j][i][i]
+                                        = s;
+
+            // case 2: index j (higher one) is
+            // double
+            const double t = (d[i][j][j] +
+                d[j][i][j] +
+                d[j][j][i] ) / 3;
+            d[i][j][j]
+                    = d[j][i][j]
+                              = d[j][j][i]
+                                        = t;
+          }
     }
-  else
+
+
+    template <int order, int dim>
+    class DerivativeSelector
     {
-      std::vector<std::vector<ProjectedDerivative> > values
-      (1, std::vector<ProjectedDerivative>(fe_values.get_fe().n_components()));
-      fe_values.get_function_hessians (solution, values);
-      return values[0][component];
+      public:
+        /**
+         * typedef to select the DerivativeDescription corresponding to the
+         * <tt>order</tt>th derivative. In this general template we set an unvalid
+         * typedef to void, the real typedefs have to be specialized.
+         */
+        typedef void DerivDescr;
+
     };
-}
 
+    template <int dim>
+    class DerivativeSelector<1,dim>
+    {
+      public:
 
+        typedef Gradient<dim> DerivDescr;
+    };
 
-template <>
-inline
-double
-DerivativeApproximation::ThirdDerivative<1>::
-derivative_norm (const Derivative &d)
-{
-  return std::fabs (d[0][0][0]);
-}
+    template <int dim>
+    class DerivativeSelector<2,dim>
+    {
+      public:
 
+        typedef SecondDerivative<dim> DerivDescr;
+    };
 
+    template <int dim>
+    class DerivativeSelector<3,dim>
+    {
+      public:
 
-template <int dim>
-inline
-double
-DerivativeApproximation::ThirdDerivative<dim>::
-derivative_norm (const Derivative &d)
-{
-  // return the Frobenius-norm. this is a
-  // member function of Tensor<rank_,dim>
-  return d.norm();
+        typedef ThirdDerivative<dim> DerivDescr;
+    };
+  }
 }
 
-
-template <int dim>
-inline
-void
-DerivativeApproximation::ThirdDerivative<dim>::symmetrize (Derivative &d)
+// Dummy structures and dummy function used for WorkStream
+namespace DerivativeApproximation
 {
-  // symmetrize non-diagonal entries
-
-  // first do it in the case, that i,j,k are
-  // pairwise different (which can onlky happen
-  // in dim >= 3)
-  for (unsigned int i=0; i<dim; ++i)
-    for (unsigned int j=i+1; j<dim; ++j)
-      for (unsigned int k=j+1; k<dim; ++k)
-        {
-          const double s = (d[i][j][k] +
-                            d[i][k][j] +
-                            d[j][i][k] +
-                            d[j][k][i] +
-                            d[k][i][j] +
-                            d[k][j][i]) / 6;
-          d[i][j][k]
-            = d[i][k][j]
-              = d[j][i][k]
-                = d[j][k][i]
-                  = d[k][i][j]
-                    = d[k][j][i]
-                      = s;
-        };
-  // now do the case, where two indices are
-  // equal
-  for (unsigned int i=0; i<dim; ++i)
-    for (unsigned int j=i+1; j<dim; ++j)
+  namespace internal
+  {
+    namespace Assembler
+    {
+      struct Scratch
       {
-        // case 1: index i (lower one) is
-        // double
-        const double s = (d[i][i][j] +
-                          d[i][j][i] +
-                          d[j][i][i] ) / 3;
-        d[i][i][j]
-          = d[i][j][i]
-            = d[j][i][i]
-              = s;
-
-        // case 2: index j (higher one) is
-        // double
-        const double t = (d[i][j][j] +
-                          d[j][i][j] +
-                          d[j][j][i] ) / 3;
-        d[i][j][j]
-          = d[j][i][j]
-            = d[j][j][i]
-              = t;
+          Scratch() {}
       };
 
+      struct CopyData
+      {
+          CopyData() {}
+      };
+    }
+  }
 }
 
+// ------------------------------- now for the functions that do the
+// ------------------------------- actual work
 
-
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_gradient (const Mapping<dim,spacedim>    &mapping,
-                      const DH<dim,spacedim>         &dof_handler,
-                      const InputVector     &solution,
-                      Vector<float>         &derivative_norm,
-                      const unsigned int     component)
+namespace DerivativeApproximation
 {
-  approximate_derivative<Gradient<dim>,dim> (mapping,
-                                             dof_handler,
-                                             solution,
-                                             component,
-                                             derivative_norm);
-}
+  namespace internal
+  {
+    /**
+     * Compute the derivative approximation on one cell. This computes the full
+     * derivative tensor.
+     */
+    template <class DerivativeDescription, int dim,
+    template <int, int> class DH, class InputVector, int spacedim>
+    void
+    approximate_cell (const Mapping<dim,spacedim>                   &mapping,
+                      const DH<dim,spacedim>                        &dof_handler,
+                      const InputVector                             &solution,
+                      const unsigned int                             component,
+                      const typename DH<dim,spacedim>::active_cell_iterator  &cell,
+                      typename DerivativeDescription::Derivative    &derivative)
+    {
+        QMidpoint<dim> midpoint_rule;
+
+        // create collection objects from
+        // single quadratures, mappings,
+        // and finite elements. if we have
+        // an hp DoFHandler,
+        // dof_handler.get_fe() returns a
+        // collection of which we do a
+        // shallow copy instead
+        const hp::QCollection<dim>       q_collection (midpoint_rule);
+        const hp::FECollection<dim>      fe_collection(dof_handler.get_fe());
+        const hp::MappingCollection<dim> mapping_collection (mapping);
+
+        hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
+            q_collection,
+            DerivativeDescription::update_flags |
+            update_quadrature_points);
+
+        // matrix Y=sum_i y_i y_i^T
+            Tensor<2,dim> Y;
+
+
+        // vector to hold iterators to all
+            // active neighbors of a cell
+            // reserve the maximal number of
+            // active neighbors
+            std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
+            active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
+                GeometryInfo<dim>::max_children_per_face);
+
+            // vector
+            // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
+            // or related type for higher
+            // derivatives
+            typename DerivativeDescription::Derivative projected_derivative;
+
+            // reinit fe values object...
+            x_fe_midpoint_value.reinit (cell);
+            const FEValues<dim> &fe_midpoint_value
+            = x_fe_midpoint_value.get_present_fe_values();
+
+            // ...and get the value of the
+            // projected derivative...
+            const typename DerivativeDescription::ProjectedDerivative
+            this_midpoint_value
+            = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
+                                                               solution,
+                                                               component);
+            // ...and the place where it lives
+            const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
+
+            // loop over all neighbors and
+            // accumulate the difference
+            // quotients from them. note
+            // that things get a bit more
+            // complicated if the neighbor
+            // is more refined than the
+            // present one
+            //
+            // to make processing simpler,
+            // first collect all neighbor
+            // cells in a vector, and then
+            // collect the data from them
+            GridTools::get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
+
+            // now loop over all active
+            // neighbors and collect the
+            // data we need
+            typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
+            neighbor_ptr = active_neighbors.begin();
+            for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
+              {
+                const typename DH<dim,spacedim>::active_cell_iterator
+                neighbor = *neighbor_ptr;
+
+                // reinit fe values object...
+                x_fe_midpoint_value.reinit (neighbor);
+                const FEValues<dim> &fe_midpoint_value
+                = x_fe_midpoint_value.get_present_fe_values();
+
+                // ...and get the value of the
+                // solution...
+                const typename DerivativeDescription::ProjectedDerivative
+                neighbor_midpoint_value
+                = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
+                                                                   solution, component);
+
+                // ...and the place where it lives
+                const Point<dim>
+                neighbor_center = fe_midpoint_value.quadrature_point(0);
+
+
+                // vector for the
+                // normalized
+                // direction between
+                // the centers of two
+                // cells
+                Point<dim>   y        = neighbor_center - this_center;
+                const double distance = std::sqrt(y.square());
+                // normalize y
+                y /= distance;
+                // *** note that unlike in
+                // the docs, y denotes the
+                // normalized vector
+                // connecting the centers
+                // of the two cells, rather
+                // than the normal
+                // difference! ***
+
+                // add up the
+                // contribution of
+                // this cell to Y
+                for (unsigned int i=0; i<dim; ++i)
+                  for (unsigned int j=0; j<dim; ++j)
+                    Y[i][j] += y[i] * y[j];
+
+                // then update the sum
+                // of difference
+                // quotients
+                typename DerivativeDescription::ProjectedDerivative
+                projected_finite_difference
+                = (neighbor_midpoint_value -
+                    this_midpoint_value);
+                projected_finite_difference /= distance;
+
+                typename DerivativeDescription::Derivative projected_derivative_update;
+                outer_product (projected_derivative_update,
+                               y,
+                               projected_finite_difference);
+                projected_derivative += projected_derivative_update;
+              };
+
+            // can we determine an
+            // approximation of the
+            // gradient for the present
+            // cell? if so, then we need to
+            // have passed over vectors y_i
+            // which span the whole space,
+            // otherwise we would not have
+            // all components of the
+            // gradient
+            AssertThrow (determinant(Y) != 0,
+                         ExcInsufficientDirections());
+
+            // compute Y^-1 g
+            const Tensor<2,dim> Y_inverse = invert(Y);
+
+            contract (derivative, Y_inverse, projected_derivative);
+
+            // finally symmetrize the derivative
+            DerivativeDescription::symmetrize (derivative);
+    }
 
 
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_gradient (const DH<dim,spacedim>         &dof_handler,
-                      const InputVector     &solution,
-                      Vector<float>         &derivative_norm,
-                      const unsigned int     component)
-{
-  approximate_derivative<Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
-                                             dof_handler,
-                                             solution,
-                                             component,
-                                             derivative_norm);
-}
 
+    /**
+     * Compute the derivative approximation on a given cell.  Fill the @p
+     * derivative_norm vector with the norm of the computed derivative tensors
+     * on the cell.
+     */
+    template <class DerivativeDescription, int dim,
+    template <int, int> class DH, class InputVector, int spacedim>
+    void
+    approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator> > const &cell,
+                                          const Mapping<dim,spacedim>                  &mapping,
+                                          const DH<dim,spacedim>                       &dof_handler,
+                                          const InputVector                            &solution,
+                                          const unsigned int                            component)
+    {
+        // if the cell is not locally owned, then there is nothing to do
+        if (std_cxx1x::get<0>(cell.iterators)->is_locally_owned() == false)
+          *std_cxx1x::get<1>(cell.iterators) = 0;
+        else
+          {
+            typename DerivativeDescription::Derivative derivative;
+            // call the function doing the actual
+            // work on this cell
+            approximate_cell<DerivativeDescription,dim,DH,InputVector>
+            (mapping,dof_handler,solution,component,std_cxx1x::get<0>(cell.iterators),derivative);
+            // evaluate the norm and fill the vector
+            //*derivative_norm_on_this_cell
+            *std_cxx1x::get<1>(cell.iterators) = DerivativeDescription::derivative_norm (derivative);
+          }
+    }
 
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_second_derivative (const Mapping<dim,spacedim>    &mapping,
-                               const DH<dim,spacedim>         &dof_handler,
-                               const InputVector     &solution,
-                               Vector<float>         &derivative_norm,
-                               const unsigned int     component)
-{
-  approximate_derivative<SecondDerivative<dim>,dim> (mapping,
-                                                     dof_handler,
-                                                     solution,
-                                                     component,
-                                                     derivative_norm);
-}
 
+    /**
+     * Kind of the main function of this class. It is called by the public entry
+     * points to this class with the correct template first argument and then
+     * simply calls the @p approximate function, after setting up several
+     * threads and doing some administration that is independent of the actual
+     * derivative to be computed.
+     *
+     * The @p component argument denotes which component of the solution vector
+     * we are to work on.
+     */
+    template <class DerivativeDescription, int dim,
+    template <int, int> class DH, class InputVector, int spacedim>
+    void
+    approximate_derivative (const Mapping<dim,spacedim>    &mapping,
+                            const DH<dim,spacedim>         &dof_handler,
+                            const InputVector     &solution,
+                            const unsigned int     component,
+                            Vector<float>         &derivative_norm)
+    {
+        Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
+            ExcInvalidVectorLength (derivative_norm.size(),
+                dof_handler.get_tria().n_active_cells()));
+        Assert (component < dof_handler.get_fe().n_components(),
+                ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
+
+        typedef std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator>
+        Iterators;
+        SynchronousIterators<Iterators> begin(Iterators(dof_handler.begin_active(),
+            derivative_norm.begin())),
+                end(Iterators(dof_handler.end(),
+                    derivative_norm.end()));
+
+        // There is no need for a copier because there is no conflict between threads
+        // to write in derivative_norm. Scratch and CopyData are also useless.
+        WorkStream::run(begin,
+                        end,
+                        static_cast<std_cxx1x::function<void (SynchronousIterators<Iterators> const &,
+                            Assembler::Scratch const &, Assembler::CopyData &)> >
+        (std_cxx1x::bind(&approximate<DerivativeDescription,dim,DH,InputVector,spacedim>,
+                         std_cxx1x::_1,
+                         std_cxx1x::cref(mapping),
+                         std_cxx1x::cref(dof_handler),
+                         std_cxx1x::cref(solution),component)),
+                         std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
+                         internal::Assembler::Scratch (),internal::Assembler::CopyData ());
+    }
 
-template <int dim, template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_second_derivative (const DH<dim,spacedim>         &dof_handler,
-                               const InputVector     &solution,
-                               Vector<float>         &derivative_norm,
-                               const unsigned int     component)
-{
-  approximate_derivative<SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
-                                                     dof_handler,
-                                                     solution,
-                                                     component,
-                                                     derivative_norm);
-}
+  } // namespace internal
 
+} // namespace DerivativeApproximation
 
-template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
-void
-DerivativeApproximation::
-approximate_derivative_tensor (const Mapping<dim,spacedim>                           &mapping,
-                               const DH<dim,spacedim>                                &dof,
-                               const InputVector                            &solution,
-                               const typename DH<dim,spacedim>::active_cell_iterator &cell,
-                               Tensor<order,dim>                            &derivative,
-                               const unsigned int                            component)
+
+// ------------------------ finally for the public interface of this namespace
+
+namespace DerivativeApproximation
 {
-  approximate_cell<typename DerivativeSelector<order,dim>::DerivDescr,dim,DH,InputVector>
-  (mapping,
-   dof,
-   solution,
-   component,
-   cell,
-   derivative);
-}
+  template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+  void
+  approximate_gradient (const Mapping<dim,spacedim>    &mapping,
+                        const DH<dim,spacedim>         &dof_handler,
+                        const InputVector     &solution,
+                        Vector<float>         &derivative_norm,
+                        const unsigned int     component)
+  {
+      internal::approximate_derivative<internal::Gradient<dim>,dim> (mapping,
+          dof_handler,
+          solution,
+          component,
+          derivative_norm);
+  }
 
 
+  template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+  void
+  approximate_gradient (const DH<dim,spacedim>         &dof_handler,
+                        const InputVector     &solution,
+                        Vector<float>         &derivative_norm,
+                        const unsigned int     component)
+  {
+      internal::approximate_derivative<internal::Gradient<dim>,dim> (StaticMappingQ1<dim>::mapping,
+          dof_handler,
+          solution,
+          component,
+          derivative_norm);
+  }
 
-template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
-void
-DerivativeApproximation::
-approximate_derivative_tensor (const DH<dim,spacedim>                                &dof,
-                               const InputVector                            &solution,
-                               const typename DH<dim,spacedim>::active_cell_iterator &cell,
-                               Tensor<order,dim>                            &derivative,
-                               const unsigned int                            component)
-{
-  // just call the respective function with Q1
-  // mapping
-  approximate_derivative_tensor (StaticMappingQ1<dim>::mapping,
-                                 dof,
-                                 solution,
-                                 cell,
-                                 derivative,
-                                 component);
-}
 
+  template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+  void
+  approximate_second_derivative (const Mapping<dim,spacedim>    &mapping,
+                                 const DH<dim,spacedim>         &dof_handler,
+                                 const InputVector     &solution,
+                                 Vector<float>         &derivative_norm,
+                                 const unsigned int     component)
+  {
+      internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (mapping,
+          dof_handler,
+          solution,
+          component,
+          derivative_norm);
+  }
 
 
-template <class DerivativeDescription, int dim,
-          template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_derivative (const Mapping<dim,spacedim>    &mapping,
-                        const DH<dim,spacedim>         &dof_handler,
-                        const InputVector     &solution,
-                        const unsigned int     component,
-                        Vector<float>         &derivative_norm)
-{
-  Assert (derivative_norm.size() == dof_handler.get_tria().n_active_cells(),
-          ExcInvalidVectorLength (derivative_norm.size(),
-                                  dof_handler.get_tria().n_active_cells()));
-  Assert (component < dof_handler.get_fe().n_components(),
-          ExcIndexRange (component, 0, dof_handler.get_fe().n_components()));
-
-  typedef std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator>
-  Iterators;
-  SynchronousIterators<Iterators> begin(Iterators(dof_handler.begin_active(),
-                                                  derivative_norm.begin())),
-                                  end(Iterators(dof_handler.end(),
-                                                derivative_norm.end()));
-
-  // There is no need for a copier because there is no conflict between threads
-  // to write in derivative_norm. Scratch and CopyData are also useless.
-  WorkStream::run(begin,
-                  end,
-                  static_cast<std_cxx1x::function<void (SynchronousIterators<Iterators> const &,
-                                                        internal::Assembler::Scratch const &,internal::Assembler::CopyData &)> >
-                  (std_cxx1x::bind(&DerivativeApproximation::template approximate<DerivativeDescription,dim,DH,
-                                   InputVector,spacedim>,
-                                   std_cxx1x::_1,
-                                   std_cxx1x::cref(mapping),
-                                   std_cxx1x::cref(dof_handler),
-                                   std_cxx1x::cref(solution),component)),
-                  std_cxx1x::function<void (internal::Assembler::CopyData const &)> (),
-                  internal::Assembler::Scratch (),internal::Assembler::CopyData ());
-}
+  template <int dim, template <int, int> class DH, class InputVector, int spacedim>
+  void
+  approximate_second_derivative (const DH<dim,spacedim>         &dof_handler,
+                                 const InputVector     &solution,
+                                 Vector<float>         &derivative_norm,
+                                 const unsigned int     component)
+  {
+      internal::approximate_derivative<internal::SecondDerivative<dim>,dim> (StaticMappingQ1<dim>::mapping,
+          dof_handler,
+          solution,
+          component,
+          derivative_norm);
+  }
 
 
+  template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
+  void
+  approximate_derivative_tensor (const Mapping<dim,spacedim>                           &mapping,
+                                 const DH<dim,spacedim>                                &dof,
+                                 const InputVector                            &solution,
+                                 const typename DH<dim,spacedim>::active_cell_iterator &cell,
+                                 Tensor<order,dim>                            &derivative,
+                                 const unsigned int                            component)
+  {
+      internal::approximate_cell<typename internal::DerivativeSelector<order,dim>::DerivDescr,dim,DH,InputVector>
+      (mapping,
+          dof,
+          solution,
+          component,
+          cell,
+          derivative);
+  }
 
-template <class DerivativeDescription, int dim,
-          template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::approximate (SynchronousIterators<std_cxx1x::tuple<typename DH<dim,spacedim>::active_cell_iterator,Vector<float>::iterator> > const &cell,
-                                      const Mapping<dim,spacedim>                  &mapping,
-                                      const DH<dim,spacedim>                       &dof_handler,
-                                      const InputVector                            &solution,
-                                      const unsigned int                            component)
-{
-  // if the cell is not locally owned, then there is nothing to do
-  if (std_cxx1x::get<0>(cell.iterators)->is_locally_owned() == false)
-    *std_cxx1x::get<1>(cell.iterators) = 0;
-  else
-    {
-      typename DerivativeDescription::Derivative derivative;
-      // call the function doing the actual
-      // work on this cell
-      DerivativeApproximation::template approximate_cell<DerivativeDescription,dim,DH,InputVector>
-      (mapping,dof_handler,solution,component,std_cxx1x::get<0>(cell.iterators),derivative);
-      // evaluate the norm and fill the vector
-      //*derivative_norm_on_this_cell
-      *std_cxx1x::get<1>(cell.iterators) = DerivativeDescription::derivative_norm (derivative);
-    }
-}
 
 
+  template <int dim, template <int, int> class DH, class InputVector, int order, int spacedim>
+  void
+  approximate_derivative_tensor (const DH<dim,spacedim>                                &dof,
+                                 const InputVector                            &solution,
+                                 const typename DH<dim,spacedim>::active_cell_iterator &cell,
+                                 Tensor<order,dim>                            &derivative,
+                                 const unsigned int                            component)
+  {
+      // just call the respective function with Q1 mapping
+      approximate_derivative_tensor<dim,DH,InputVector,order,spacedim>
+      (StaticMappingQ1<dim>::mapping,
+          dof,
+          solution,
+          cell,
+          derivative,
+          component);
+  }
 
-template <class DerivativeDescription, int dim,
-          template <int, int> class DH, class InputVector, int spacedim>
-void
-DerivativeApproximation::
-approximate_cell (const Mapping<dim,spacedim>                   &mapping,
-                  const DH<dim,spacedim>                        &dof_handler,
-                  const InputVector                             &solution,
-                  const unsigned int                             component,
-                  const typename DH<dim,spacedim>::active_cell_iterator  &cell,
-                  typename DerivativeDescription::Derivative    &derivative)
-{
-  QMidpoint<dim> midpoint_rule;
-
-  // create collection objects from
-  // single quadratures, mappings,
-  // and finite elements. if we have
-  // an hp DoFHandler,
-  // dof_handler.get_fe() returns a
-  // collection of which we do a
-  // shallow copy instead
-  const hp::QCollection<dim>       q_collection (midpoint_rule);
-  const hp::FECollection<dim>      fe_collection(dof_handler.get_fe());
-  const hp::MappingCollection<dim> mapping_collection (mapping);
-
-  hp::FEValues<dim> x_fe_midpoint_value (mapping_collection, fe_collection,
-                                         q_collection,
-                                         DerivativeDescription::update_flags |
-                                         update_quadrature_points);
-
-  // matrix Y=sum_i y_i y_i^T
-  Tensor<2,dim> Y;
-
-
-  // vector to hold iterators to all
-  // active neighbors of a cell
-  // reserve the maximal number of
-  // active neighbors
-  std::vector<typename DH<dim,spacedim>::active_cell_iterator> active_neighbors;
-  active_neighbors.reserve (GeometryInfo<dim>::faces_per_cell *
-                            GeometryInfo<dim>::max_children_per_face);
-
-  // vector
-  // g=sum_i y_i (f(x+y_i)-f(x))/|y_i|
-  // or related type for higher
-  // derivatives
-  typename DerivativeDescription::Derivative projected_derivative;
-
-  // reinit fe values object...
-  x_fe_midpoint_value.reinit (cell);
-  const FEValues<dim> &fe_midpoint_value
-    = x_fe_midpoint_value.get_present_fe_values();
-
-  // ...and get the value of the
-  // projected derivative...
-  const typename DerivativeDescription::ProjectedDerivative
-  this_midpoint_value
-    = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
-                                                       solution,
-                                                       component);
-  // ...and the place where it lives
-  const Point<dim> this_center = fe_midpoint_value.quadrature_point(0);
-
-  // loop over all neighbors and
-  // accumulate the difference
-  // quotients from them. note
-  // that things get a bit more
-  // complicated if the neighbor
-  // is more refined than the
-  // present one
-  //
-  // to make processing simpler,
-  // first collect all neighbor
-  // cells in a vector, and then
-  // collect the data from them
-  GridTools::get_active_neighbors<DH<dim,spacedim> >(cell, active_neighbors);
-
-  // now loop over all active
-  // neighbors and collect the
-  // data we need
-  typename std::vector<typename DH<dim,spacedim>::active_cell_iterator>::const_iterator
-  neighbor_ptr = active_neighbors.begin();
-  for (; neighbor_ptr!=active_neighbors.end(); ++neighbor_ptr)
-    {
-      const typename DH<dim,spacedim>::active_cell_iterator
-      neighbor = *neighbor_ptr;
-
-      // reinit fe values object...
-      x_fe_midpoint_value.reinit (neighbor);
-      const FEValues<dim> &fe_midpoint_value
-        = x_fe_midpoint_value.get_present_fe_values();
-
-      // ...and get the value of the
-      // solution...
-      const typename DerivativeDescription::ProjectedDerivative
-      neighbor_midpoint_value
-        = DerivativeDescription::get_projected_derivative (fe_midpoint_value,
-                                                           solution, component);
-
-      // ...and the place where it lives
-      const Point<dim>
-      neighbor_center = fe_midpoint_value.quadrature_point(0);
-
-
-      // vector for the
-      // normalized
-      // direction between
-      // the centers of two
-      // cells
-      Point<dim>   y        = neighbor_center - this_center;
-      const double distance = std::sqrt(y.square());
-      // normalize y
-      y /= distance;
-      // *** note that unlike in
-      // the docs, y denotes the
-      // normalized vector
-      // connecting the centers
-      // of the two cells, rather
-      // than the normal
-      // difference! ***
-
-      // add up the
-      // contribution of
-      // this cell to Y
-      for (unsigned int i=0; i<dim; ++i)
-        for (unsigned int j=0; j<dim; ++j)
-          Y[i][j] += y[i] * y[j];
-
-      // then update the sum
-      // of difference
-      // quotients
-      typename DerivativeDescription::ProjectedDerivative
-      projected_finite_difference
-        = (neighbor_midpoint_value -
-           this_midpoint_value);
-      projected_finite_difference /= distance;
-
-      typename DerivativeDescription::Derivative projected_derivative_update;
-      outer_product (projected_derivative_update,
-                     y,
-                     projected_finite_difference);
-      projected_derivative += projected_derivative_update;
-    };
 
-  // can we determine an
-  // approximation of the
-  // gradient for the present
-  // cell? if so, then we need to
-  // have passed over vectors y_i
-  // which span the whole space,
-  // otherwise we would not have
-  // all components of the
-  // gradient
-  AssertThrow (determinant(Y) != 0,
-               ExcInsufficientDirections());
-
-  // compute Y^-1 g
-  const Tensor<2,dim> Y_inverse = invert(Y);
-
-  contract (derivative, Y_inverse, projected_derivative);
-
-  // finally symmetrize the derivative
-  DerivativeDescription::symmetrize (derivative);
-}
 
 
-template <int dim, int order>
-double
-DerivativeApproximation::
-derivative_norm(const Tensor<order,dim> &derivative)
-{
-  return DerivativeSelector<order,dim>::DerivDescr::derivative_norm(derivative);
-}
 
+  template <int dim, int order>
+  double
+  derivative_norm (const Tensor<order,dim> &derivative)
+  {
+    return internal::DerivativeSelector<order,dim>::DerivDescr::derivative_norm(derivative);
+  }
+
+}
 
 
 // --------------------------- explicit instantiations ---------------------
index 6e7ed876abc893734a94beb851560be8a0cf9484..430c8a095f0e7ebdbf738369e7ecc61763218725 100644 (file)
 
 for (deal_II_dimension : DIMENSIONS ; VEC : SERIAL_VECTORS ; DH : DOFHANDLER_TEMPLATES)
 {
+  namespace DerivativeApproximation
+  \{
 template
 void
-DerivativeApproximation::
 approximate_gradient<deal_II_dimension>
 (const Mapping<deal_II_dimension> &mapping,
  const DH<deal_II_dimension> &dof_handler,
@@ -29,7 +30,6 @@ approximate_gradient<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_gradient<deal_II_dimension>
 (const DH<deal_II_dimension> &dof_handler,
  const VEC             &solution,
@@ -38,7 +38,6 @@ approximate_gradient<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_second_derivative<deal_II_dimension>
 (const Mapping<deal_II_dimension> &mapping,
  const DH<deal_II_dimension> &dof_handler,
@@ -48,7 +47,6 @@ approximate_second_derivative<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_second_derivative<deal_II_dimension>
 (const DH<deal_II_dimension> &dof_handler,
  const VEC             &solution,
@@ -57,7 +55,6 @@ approximate_second_derivative<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_derivative_tensor<deal_II_dimension>
 (const Mapping<deal_II_dimension> &    mapping,
  const DH<deal_II_dimension> &dof_handler,
@@ -68,7 +65,6 @@ approximate_derivative_tensor<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_derivative_tensor<deal_II_dimension>
 (const Mapping<deal_II_dimension> &    mapping,
  const DH<deal_II_dimension> &dof_handler,
@@ -79,7 +75,6 @@ approximate_derivative_tensor<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_derivative_tensor<deal_II_dimension>
 (const Mapping<deal_II_dimension> &    mapping,
  const DH<deal_II_dimension> &dof_handler,
@@ -90,7 +85,6 @@ approximate_derivative_tensor<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_derivative_tensor<deal_II_dimension>
 (const DH<deal_II_dimension> &dof_handler,
  const VEC &solution,
@@ -100,7 +94,6 @@ approximate_derivative_tensor<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_derivative_tensor<deal_II_dimension>
 (const DH<deal_II_dimension> &dof_handler,
  const VEC &solution,
@@ -110,7 +103,6 @@ approximate_derivative_tensor<deal_II_dimension>
 
 template
 void
-DerivativeApproximation::
 approximate_derivative_tensor<deal_II_dimension>
 (const DH<deal_II_dimension> &dof_handler,
  const VEC &solution,
@@ -118,40 +110,24 @@ approximate_derivative_tensor<deal_II_dimension>
  Tensor<3,deal_II_dimension> &derivative,
  const unsigned int     component);
 
+  \}
 }
 
 
 for (deal_II_dimension : DIMENSIONS)
 {
+  namespace DerivativeApproximation
+  \{
 template
 double
-DerivativeApproximation::
 derivative_norm(const Tensor<1,deal_II_dimension> &derivative);
 
 template
 double
-DerivativeApproximation::
 derivative_norm(const Tensor<2,deal_II_dimension> &derivative);
 
 template
 double
-DerivativeApproximation::
 derivative_norm(const Tensor<3,deal_II_dimension> &derivative);
-
-
-// static variables
-//
-// on AIX, the linker is unhappy about some missing symbols. they
-// should really be there, but explicitly instantiating them will also
-// not hurt
-template
-const UpdateFlags
-DerivativeApproximation::Gradient<deal_II_dimension>::update_flags;
-
-template
-const UpdateFlags
-DerivativeApproximation::SecondDerivative<deal_II_dimension>::update_flags;
-template
-const UpdateFlags
-DerivativeApproximation::ThirdDerivative<deal_II_dimension>::update_flags;
+  \}
 }
index 83e89a9afae087c7ef56f21b782b4d2bd9a7ef81..19fbf0c5427f9f5813358ba0e906a2038164eab3 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 1998 - 2013 by the deal.II authors
+// Copyright (C) 1998 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -186,8 +186,8 @@ namespace internal
        */
       template <class FE>
       ParallelData (const FE                                           &fe,
-                    const dealii::hp::QCollection<DH::dimension-1>               &face_quadratures,
-                    const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
+                    const dealii::hp::QCollection<dim-1>               &face_quadratures,
+                    const dealii::hp::MappingCollection<dim,spacedim> &mapping,
                     const bool         need_quadrature_points,
                     const unsigned int n_solution_vectors,
                     const types::subdomain_id subdomain_id,
@@ -209,8 +209,8 @@ namespace internal
     template <class FE>
     ParallelData<DH>::
     ParallelData (const FE                                           &fe,
-                  const dealii::hp::QCollection<DH::dimension-1>     &face_quadratures,
-                  const dealii::hp::MappingCollection<DH::dimension, DH::space_dimension> &mapping,
+                  const dealii::hp::QCollection<dim-1>     &face_quadratures,
+                  const dealii::hp::MappingCollection<dim, spacedim> &mapping,
                   const bool     need_quadrature_points,
                   const unsigned int n_solution_vectors,
                   const types::subdomain_id subdomain_id,
index e8d639f4814729f3d69c5dd0cbab10f6cd4714bb..a21bcc72008894d1e5bea033257fb2286997a85b 100644 (file)
 #
 ENABLE_TESTING()
 
+INCLUDE_DIRECTORIES(
+  ${CMAKE_BINARY_DIR}/include/
+  ${CMAKE_SOURCE_DIR}/include/
+  ${DEAL_II_BUNDLED_INCLUDE_DIRS}
+  ${DEAL_II_INCLUDE_DIRS}
+  )
+
 # Use the first available build type (this prefers debug mode if available):
 LIST(GET DEAL_II_BUILD_TYPES 0 _mybuild)
 MESSAGE(STATUS "Setting up quick_tests in ${_mybuild} mode")
@@ -36,7 +43,7 @@ MACRO(make_quicktest test_basename build_name mpi_run)
   IF("${mpi_run}" STREQUAL "")
     SET(_command ./${_target})
   ELSE()
-    SET(_command mpirun -n ${mpi_run} ./${_target})
+    SET(_command ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${mpi_run} ${MPIEXEC_PREFLAGS} ./${_target})
   ENDIF()
   ADD_CUSTOM_TARGET(${_target}.run
     DEPENDS ${_target}
@@ -75,7 +82,9 @@ FOREACH(_build ${DEAL_II_BUILD_TYPES})
 ENDFOREACH()
 
 # Test whether thread affinity is well behaved
+IF (DEAL_II_WITH_THREADS)
 make_quicktest("affinity" ${_mybuild} "")
+ENDIF()
 
 # Test if MPI is configured correctly
 IF (DEAL_II_WITH_MPI)
index e9d01a4ea05d1f71f0869b619d28313ce1b42cf8..ab0fca1bca0b0203ff7506ace84dfc102f4ff27e 100644 (file)
 // ---------------------------------------------------------------------
 
 #include <deal.II/grid/tria.h>
+#include <deal.II/base/multithread_info.h>
 #include <stdio.h>
+
+#if defined(__linux__)
 #include <sched.h>
+#include <sys/sysinfo.h>
+#endif
 
-int main ()
+bool getaffinity(unsigned int &bits_set,unsigned int &mask)
 {
-  // we need this, otherwise gcc will not link against deal.II
-  dealii::Triangulation<2> test;
-
+  bits_set = 0;
+  mask = 0x00;
+  
+#if defined(__linux__)
   cpu_set_t my_set;
   CPU_ZERO(&my_set);
 
@@ -32,17 +38,45 @@ int main ()
   if (ret!=0)
     {
       printf("sched_getaffinity() failed, return value: %d\n", ret);
-      return -1;
+      return false;
     }
-
-  unsigned int bits_set = 0;//not supported on old kernels: CPU_COUNT(&my_set);
   for (int i=0;i<CPU_SETSIZE;++i)
     bits_set += CPU_ISSET(i,&my_set);
 
-  if (bits_set==1)
+  mask = *(int*)(&my_set);
+#else
+  // sadly we don't have an implementation
+  // for mac/windows
+#endif
+  return true;
+}
+
+
+int main ()
+{
+  // we need this, otherwise gcc will not link against deal.II
+  dealii::Triangulation<2> test;
+
+  unsigned int bits_set, mask;
+  if (!getaffinity(bits_set, mask))
+    return 1;
+
+  unsigned int nprocs = dealii::multithread_info.n_cpus;
+  unsigned int tbbprocs = dealii::multithread_info.n_threads();
+  printf("aff_ncpus=%d, mask=%08X, nprocs=%d, tbb_threads=%d\n",
+        bits_set, mask, nprocs, tbbprocs );
+
+  if (bits_set !=0  && bits_set!=nprocs)
+    {
+      printf("Warning: sched_getaffinity() returns that we can only use %d out of %d CPUs.\n",bits_set, nprocs);
+      return 2;
+    }
+  if (nprocs != tbbprocs)
     {
-      printf("Warning: sched_getaffinity() returns that we can only use one CPU.\n");
-      return 1;
+      printf("Warning: for some reason TBB only wants to use %d out of %d CPUs.\n",
+            tbbprocs, nprocs);
+      return 3;
     }
-  printf("ncpus=%d, mask=%08X\n", bits_set, *(unsigned int*)(&my_set));
+  
+  return 0;
 }
index 0e8110caf9433f0db790d9acfecdc73487f173a6..31da6440d783019bc0edbc4d419f7497f3dc06db 100644 (file)
@@ -51,9 +51,7 @@ void assemble(const std::vector<int>::iterator &it,
              scratch_data &scratch,
              copy_data &data)
 {
-  std::cout << "hello!" << std::endl;
-
-  data.value +=(*it)*(*it);
+  data.value = (*it);
 }
 
 void copy(int & value, const copy_data &data)
@@ -62,11 +60,11 @@ void copy(int & value, const copy_data &data)
 }
 
 void test2()
-{ 
-  std::vector<int> v(3);
-  v[0] = 3;
-  v[1] = 5;
-  v[2] = 1;
+{
+  const int maxi = 10000;
+  std::vector<int> v(maxi);
+  for (unsigned int i=0;i<v.size();++i)
+    v[i] = i+1;
   int result = 0;
   WorkStream::run(v.begin(),
                  v.end(),
@@ -77,7 +75,7 @@ void test2()
                  scratch_data(), copy_data());
   std::cout << "result: " << result << std::endl;
 
-  if (result != (3*3+5*5+1*1))
+  if (result != maxi*(maxi+1)/2)
     exit(2);
 }
 
diff --git a/tests/base/function_parser_03.cc b/tests/base/function_parser_03.cc
new file mode 100644 (file)
index 0000000..7e8250f
--- /dev/null
@@ -0,0 +1,59 @@
+// ---------------------------------------------------------------------
+// $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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// functionparser: check if you can change the expression in an existing object
+
+#include "../tests.h"
+#include <fstream>
+#include <iomanip>
+#include <map>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/point.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/base/function_parser.h>
+
+
+int main ()
+{
+  initlog();
+
+  // Define some constants that will be used by the function parser
+  std::map<std::string, double> constants;
+  constants["pi"] = numbers::PI;
+
+  // Define the variables that will be used inside the expressions
+  std::string variables = "s,t";
+
+  FunctionParser<2> fp;
+  fp.initialize("s,t", "s*t+1", constants);
+
+  double value = fp.value(Point<2>(2.0,2.5));
+  Assert(abs(1.0+2.0*2.5 - value) < 1e-10, ExcMessage("wrong value"));
+  
+  std::vector<std::string> expressions;
+  expressions.push_back("sin(2*mypi*x)+y");
+  constants["mypi"] = numbers::PI;
+  fp.initialize("x,y", expressions, constants);
+  double value1 = fp.value(Point<2>(1.0,2.5), 0);
+  Assert(abs(2.5 - value1) < 1e-10, ExcMessage("wrong value"));
+  
+}
+
+
+
+
diff --git a/tests/base/function_parser_03.with_functionparser=true.output b/tests/base/function_parser_03.with_functionparser=true.output
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/tests/base/function_parser_04.cc b/tests/base/function_parser_04.cc
new file mode 100644 (file)
index 0000000..461522a
--- /dev/null
@@ -0,0 +1,100 @@
+// ---------------------------------------------------------------------
+// $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.
+//
+// ---------------------------------------------------------------------
+
+
+
+// functionparser: TBB
+
+#include "../tests.h"
+#include <fstream>
+#include <iomanip>
+#include <map>
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/point.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/base/function_parser.h>
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/work_stream.h>
+
+
+FunctionParser<2> fp;
+
+struct scratch_data
+{
+};
+
+struct copy_data
+{
+    int value;
+    copy_data():
+                   value(0)
+      {}
+    
+};
+
+
+void assemble(const std::vector<int>::iterator &it,
+              scratch_data &scratch,
+              copy_data &data)
+{
+  double s = *it;
+  double value = fp.value(Point<2>(s, 2.5));
+  Assert(abs(1.0+s*2.5 - value) < 1e-10, ExcMessage("wrong value"));
+  std::cout << data.value  << std::endl;
+  
+  data.value = (abs(1.0+s*2.5 - value) < 1e-10)?1:0;
+}
+
+void copy(int & value, const copy_data &data)
+{
+  value += data.value;
+}
+
+
+void test2()
+{
+  std::map<std::string, double> constants;
+  constants["c"]=1.0;
+  fp.initialize("s,t", "s*t+c", constants);
+
+  std::vector<int> v(10000);
+  for (unsigned int i=0;i<v.size();++i)
+    v[i] = i;
+
+  int result = 0;
+  WorkStream::run(v.begin(),
+                  v.end(),
+                  &assemble,
+                  std_cxx1x::bind(&copy,
+                                  std_cxx1x::ref(result),
+                                  std_cxx1x::_1),
+                  scratch_data(), copy_data());
+  std::cout << "result: " << result << std::endl;
+
+  Assert(result == v.size(), ExcMessage("uhuh!"));
+}
+
+
+int main ()
+{
+  initlog();
+
+  test2();
+}
+
+
+
+
diff --git a/tests/base/function_parser_04.with_functionparser=true.with_threads=true.output b/tests/base/function_parser_04.with_functionparser=true.with_threads=true.output
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
index f5107c14d6396bd845ba61e97377cd8f499d3016..3524d65d39336956fe1a0012dcfb60e30071ddcc 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2007 - 2013 by the deal.II authors
+// Copyright (C) 2007 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -182,15 +182,14 @@ check_function(const Functions::FlowFunction<dim> &f,
     {
       names[i] = std::string("comp");
     }
-
-  DataOutBase dout;
+  
   DataOutBase::DXFlags dxflags;
   DataOutBase::GnuplotFlags gflags;
   std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > vectors;
   if (dim==2)
-    dout.write_gnuplot(patches, names, vectors, gflags, out);
+    DataOutBase::write_gnuplot(patches, names, vectors, gflags, out);
   else
-    dout.write_dx(patches, names, vectors, dxflags, out);
+    DataOutBase::write_dx(patches, names, vectors, dxflags, out);
 }
 
 
index 6e15ff79cc07bf591ab895dd30d1b696288143a2..13b6ead1a23233db2053da4ff77e253df07fff46 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2007 - 2013 by the deal.II authors
+// Copyright (C) 2007 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -223,14 +223,13 @@ check_function_derivative(const Functions::FlowFunction<dim> &f,
       names[i] = std::string("comp");
     }
 
-  DataOutBase dout;
   DataOutBase::DXFlags dxflags;
   DataOutBase::GnuplotFlags gflags;
   std::vector<std_cxx1x::tuple<unsigned int, unsigned int, std::string> > vectors;
   if (dim==2)
-    dout.write_gnuplot(patches, names, vectors, gflags, out);
+    DataOutBase::write_gnuplot(patches, names, vectors, gflags, out);
   else
-    dout.write_dx(patches, names, vectors, dxflags, out);
+    DataOutBase::write_dx(patches, names, vectors, dxflags, out);
 }
 
 
diff --git a/tests/base/thread_local_storage_05.cc b/tests/base/thread_local_storage_05.cc
new file mode 100644 (file)
index 0000000..5ff0c4a
--- /dev/null
@@ -0,0 +1,109 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2008 - 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// test ThreadLocalStorage::clear
+
+#include "../tests.h"
+#include <iomanip>
+#include <fstream>
+#include <unistd.h>
+
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/thread_local_storage.h>
+
+
+struct X
+{
+  X ()
+  :
+  i(1)
+  {};
+
+  int i;
+};
+
+Threads::ThreadLocalStorage<X> tls_data;
+
+
+void execute (Threads::Mutex &m)
+{
+  // check correct default initialization
+  bool exists;
+  int i = tls_data.get(exists).i;
+  Assert (i == 1, ExcInternalError());
+  Assert (exists == false, ExcInternalError());
+
+  // set value
+  tls_data.get(exists).i = 2;
+
+  // try again. should have existed this time around
+  i = tls_data.get(exists).i;
+  Assert (i == 2, ExcInternalError());
+  Assert (exists == true, ExcInternalError());
+
+  // wait for the barrier to clear
+  m.acquire ();
+  m.release ();
+
+  // at this point, the tls object should have been cleared and should
+  // be back at its original value
+  i = tls_data.get(exists).i;
+  Assert (i == 1, ExcInternalError());
+  Assert (exists == false, ExcInternalError());
+}
+
+
+void test ()
+{
+  const unsigned int N = 10;
+  Threads::Mutex m[N];
+
+  // start N threads with mutices locked
+  Threads::ThreadGroup<> tg;
+  for (unsigned int i=0; i<N; ++i)
+    {
+      m[i].acquire ();
+      tg += Threads::new_thread (execute, m[i]);
+    }
+
+  // let threads work through their first part
+  sleep (3);
+
+  // then reset the thread local object and release the mutices so the
+  // threads can actually run to an end
+  tls_data.clear ();
+  for (unsigned int i=0; i<N; ++i)
+    m[i].release ();
+
+  // now make sure the threads all finish
+  tg.join_all ();
+
+  deallog << "OK" << std::endl;
+}
+
+
+
+
+int main()
+{
+  std::ofstream logfile("output");
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test ();
+}
diff --git a/tests/base/thread_local_storage_05.with_threads=on.output b/tests/base/thread_local_storage_05.with_threads=on.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/base/thread_local_storage_06.cc b/tests/base/thread_local_storage_06.cc
new file mode 100644 (file)
index 0000000..484fc07
--- /dev/null
@@ -0,0 +1,120 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2008 - 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// test ThreadLocalStorage::clear but using a sample object to
+// initialize the thread local storage
+
+#include "../tests.h"
+#include <iomanip>
+#include <fstream>
+#include <unistd.h>
+
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/thread_local_storage.h>
+
+
+struct X
+{
+  X ()
+  :
+  i(1)
+  {};
+
+  int i;
+};
+
+X initializer ()
+{
+  X x;
+  x.i = 42;
+  return x;
+}
+
+X fourty_two = initializer();
+
+
+Threads::ThreadLocalStorage<X> tls_data(fourty_two);
+
+
+void execute (Threads::Mutex &m)
+{
+  // check correct default initialization
+  bool exists;
+  int i = tls_data.get(exists).i;
+  Assert (i == 42, ExcInternalError());
+  Assert (exists == false, ExcInternalError());
+
+  // set value
+  tls_data.get(exists).i = 2;
+
+  // try again. should have existed this time around
+  i = tls_data.get(exists).i;
+  Assert (i == 2, ExcInternalError());
+  Assert (exists == true, ExcInternalError());
+
+  // wait for the barrier to clear
+  m.acquire ();
+  m.release ();
+
+  // at this point, the tls object should have been cleared and should
+  // be back at its original value
+  i = tls_data.get(exists).i;
+  Assert (i == 42, ExcInternalError());
+  Assert (exists == false, ExcInternalError());
+}
+
+
+void test ()
+{
+  const unsigned int N = 10;
+  Threads::Mutex m[N];
+
+  // start N threads with mutices locked
+  Threads::ThreadGroup<> tg;
+  for (unsigned int i=0; i<N; ++i)
+    {
+      m[i].acquire ();
+      tg += Threads::new_thread (execute, m[i]);
+    }
+
+  // let threads work through their first part
+  sleep (3);
+
+  // then reset the thread local object and release the mutices so the
+  // threads can actually run to an end
+  tls_data.clear ();
+  for (unsigned int i=0; i<N; ++i)
+    m[i].release ();
+
+  // now make sure the threads all finish
+  tg.join_all ();
+
+  deallog << "OK" << std::endl;
+}
+
+
+
+
+int main()
+{
+  std::ofstream logfile("output");
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test ();
+}
diff --git a/tests/base/thread_local_storage_06.with_threads=on.output b/tests/base/thread_local_storage_06.with_threads=on.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
index a5ab8a882cb407f652fb517245ab888458a7b818..35f88bac8a5b335adcb096860f95354e4623079f 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -163,20 +163,20 @@ namespace Evaluation
   {
   public:
     SolutionOutput (const std::string                         &output_name_base,
-                    const typename DataOut<dim>::OutputFormat  output_format);
+                    const DataOutBase::OutputFormat  output_format);
 
     virtual void operator () (const DoFHandler<dim> &dof_handler,
                               const Vector<double>  &solution) const;
   private:
     const std::string                         output_name_base;
-    const typename DataOut<dim>::OutputFormat output_format;
+    const DataOutBase::OutputFormat output_format;
   };
 
 
   template <int dim>
   SolutionOutput<dim>::
   SolutionOutput (const std::string                         &output_name_base,
-                  const typename DataOut<dim>::OutputFormat  output_format)
+                  const DataOutBase::OutputFormat  output_format)
     :
     output_name_base (output_name_base),
     output_format (output_format)
@@ -783,7 +783,7 @@ void solve_problem (const std::string &solver_name)
 
   Evaluation::SolutionOutput<dim>
   postprocessor2 (std::string("solution-")+solver_name,
-                  DataOut<dim>::gnuplot);
+                  DataOutBase::gnuplot);
 
   std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
   postprocessor_list.push_back (&postprocessor1);
index 558b70fa7ecb7501e6d147587274f1c83e0f3aae..83d847fb815f6b74d7a3f750e38a645548a67f08 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -660,7 +660,7 @@ namespace LaplaceSolver
              << this->refinement_cycle
              << ".gnuplot"
              << std::ends;
-    data_out.write (deallog.get_file_stream(), DataOut<dim>::gnuplot);
+    data_out.write (deallog.get_file_stream(), DataOutBase::gnuplot);
   }
 
 
@@ -1635,7 +1635,7 @@ namespace LaplaceSolver
              << this->refinement_cycle
              << ".gnuplot"
              << std::ends;
-    data_out.write (deallog.get_file_stream(), DataOut<dim>::gnuplot);
+    data_out.write (deallog.get_file_stream(), DataOutBase::gnuplot);
   }
 
 
index 74b1736bcdaf3f66f1106f2247fadbb4a53e184f..284011d5405f9c10c875329df24d2bf46aa10587 100644 (file)
@@ -124,7 +124,7 @@ void test_hyper_cube()
   Triangulation<dim> tr;
   GridGenerator::hyper_cube(tr);
 
-  FE_Nedelec<dim> fe(3);
+  FESystem<dim> fe(FE_Q<dim>(2), dim);
   test(tr, fe);
 }
 
index 9341da79437d2d4f559f0cfda2e31f4803b8d2a3..c3c1e10f0bf840396274d416df2eb906b677a623 100644 (file)
@@ -1,27 +1,10 @@
 
-DEAL::FE=FESystem<2>[FE_Q<2>(1)^2]
-DEAL::  curls[q]= -2.00
-DEAL::  grads[q]= 2.00 4.00 2.00 4.00
-DEAL::  curls[q]= -2.00
-DEAL::  grads[q]= 2.00 4.00 2.00 4.00
-DEAL::  curls[q]= -2.00
-DEAL::  grads[q]= 2.00 4.00 2.00 4.00
-DEAL::  curls[q]= -2.00
-DEAL::  grads[q]= 2.00 4.00 2.00 4.00
-DEAL::FE=FESystem<3>[FE_Q<3>(1)^3]
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
-DEAL::  curls[q]= -6.00 9.00 -3.00
-DEAL::  grads[q]= 3.00 6.00 12.0 3.00 6.00 12.0 3.00 6.00 12.0
+DEAL::FE=FESystem<2>[FE_Q<2>(2)^2]
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 8.33e-16
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 -1.11e-16
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 -6.66e-16
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 2.22e-16
diff --git a/tests/deal.II/fe_values_view_29.cc b/tests/deal.II/fe_values_view_29.cc
new file mode 100644 (file)
index 0000000..e5f27a4
--- /dev/null
@@ -0,0 +1,146 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2007 - 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+// like _28 but also test a non-primitive element.
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/base/function.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/lac/vector.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria_boundary_lib.h>
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/fe/fe_nedelec.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/data_out.h>
+
+#include <fstream>
+
+
+class F : public Function<2>
+{
+public:
+  F() : Function<2>(2) {}
+
+  virtual void vector_value (const Point<2> &p,
+                            Vector<double> &v) const
+    {
+      // make the function equal to (0,x^2)
+      v[0] = 0;
+      v[1] = p[0]*p[0];
+    }
+};
+
+
+
+Tensor<1,1> curl (const Tensor<2,2> &grads)
+{
+  return Point<1>(grads[1][0] - grads[0][1]);
+}
+
+
+Tensor<1,3> curl (const Tensor<2,3> &grads)
+{
+  return Point<3>(grads[2][1] - grads[1][2],
+                 grads[0][2] - grads[2][0],
+                 grads[1][0] - grads[0][1]);
+}
+
+
+
+template<int dim>
+void test (const Triangulation<dim> &tr,
+           const FiniteElement<dim> &fe,
+          const unsigned int degree)
+{
+  deallog << "FE=" << fe.get_name()
+          << std::endl;
+
+  DoFHandler<dim> dof(tr);
+  dof.distribute_dofs(fe);
+
+  Vector<double> fe_function(dof.n_dofs());
+  // set the elements of the vector in such a way that the function
+  // equals the vector function (0,x^2)
+  ConstraintMatrix cm;
+  cm.close ();
+  VectorTools::project (dof, cm, QGauss<2>(2+degree), F(), fe_function);
+  
+  const QGauss<dim> quadrature(2);
+  FEValues<dim> fe_values (fe, quadrature,
+                           update_values | update_gradients | update_q_points);
+  fe_values.reinit (dof.begin_active());
+
+  // let the FEValues object compute the
+  // divergences at quadrature points
+  std::vector<typename dealii::internal::CurlType<dim>::type> curls (quadrature.size());
+  std::vector<Tensor<2,dim> > grads (quadrature.size());
+  FEValuesExtractors::Vector extractor(0);
+  fe_values[extractor].get_function_curls (fe_function, curls);
+  fe_values[extractor].get_function_gradients (fe_function, grads);
+
+  // now compare
+  for (unsigned int q=0; q<quadrature.size(); ++q)
+    {
+      deallog << "  curls[q]= " << curls[q] << std::endl
+             << "  grads[q]= " << grads[q] << std::endl;
+      Assert ((curl(grads[q]) - curls[q]).norm()
+             <= 1e-10,
+             ExcInternalError());
+
+      // we know the function F=(0,x^2) and we chose an element with
+      // high enough degree to exactly represent this function, so the
+      // curl of this function should be
+      //   curl F = d_x F_y - d_y F_x = 2x
+      // verify that this is true
+      Assert (std::fabs(curls[q][0] - 2*fe_values.quadrature_point(q)[0])
+             <= 1e-10,
+             ExcInternalError());
+    }
+}
+
+
+
+template<int dim>
+void test_hyper_cube()
+{
+  Triangulation<dim> tr;
+  GridGenerator::hyper_cube(tr);
+
+  for (unsigned int degree=2; degree<5; ++degree)
+    {
+      FE_Nedelec<dim> fe(degree);
+      test(tr, fe, degree);
+    }
+}
+
+
+int main()
+{
+  std::ofstream logfile ("output");
+  deallog << std::setprecision (3);
+
+  deallog.attach(logfile);
+  deallog.depth_console (0);
+  deallog.threshold_double(1.e-7);
+
+  test_hyper_cube<2>();
+}
diff --git a/tests/deal.II/fe_values_view_29.output b/tests/deal.II/fe_values_view_29.output
new file mode 100644 (file)
index 0000000..7903818
--- /dev/null
@@ -0,0 +1,28 @@
+
+DEAL::FE=FE_Nedelec<2>(2)
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 -1.98e-16
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 4.45e-16
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 -2.00e-16
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 -3.38e-16
+DEAL::FE=FE_Nedelec<2>(3)
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 5.69e-17
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 1.29e-15
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 2.40e-15
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 6.52e-16
+DEAL::FE=FE_Nedelec<2>(4)
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 -1.06e-15
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 2.32e-15
+DEAL::  curls[q]= 0.423
+DEAL::  grads[q]= 0.00 0.00 0.423 1.64e-15
+DEAL::  curls[q]= 1.58
+DEAL::  grads[q]= 0.00 0.00 1.58 -2.01e-15
diff --git a/tests/deal.II/grid_tools_transform_01.cc b/tests/deal.II/grid_tools_transform_01.cc
new file mode 100644 (file)
index 0000000..34c9ebb
--- /dev/null
@@ -0,0 +1,88 @@
+// ---------------------------------------------------------------------
+// $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.
+//
+// ---------------------------------------------------------------------
+
+
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/grid_out.h>
+
+#include <fstream>
+#include <iomanip>
+
+template<int dim>
+Point<dim> trans_func(Point<dim> & p);
+
+template<>
+Point<2> trans_func(Point<2> & p)
+{
+  Point<2> r(p(0)+p(1)*p(1),p(1));
+  return r;
+}
+template<>
+Point<3> trans_func(Point<3> & p)
+{
+  Point<3> r(p(0)+p(1)*p(1),p(1),p(2));
+  return r;
+}
+
+
+
+template <int dim>
+void test ()
+{
+  deallog << "dim = " << dim << std::endl;
+  
+  Triangulation<dim> tria;
+  GridGenerator::hyper_cube(tria);
+  tria.refine_global(1);
+  tria.begin_active()->set_refine_flag();
+  tria.execute_coarsening_and_refinement();
+  
+
+  deallog << "Unchanged grid:" << std::endl;
+  GridOut().write_gnuplot (tria, deallog.get_file_stream());
+
+  {
+    std::ofstream f("grid1");
+    GridOut().write_gnuplot (tria, f);
+  }
+
+  GridTools::transform(trans_func<dim>, tria);
+  
+  deallog << "transformed grid:" << std::endl;
+  GridOut().write_gnuplot (tria, deallog.get_file_stream());
+  {
+    std::ofstream f("grid2");
+    GridOut().write_gnuplot (tria, f);
+  }
+}
+
+
+int main ()
+{
+  initlog();
+  deallog.depth_console(0);
+
+  test<2> ();
+  test<3> ();
+
+  return 0;
+}
+
diff --git a/tests/deal.II/grid_tools_transform_01.output b/tests/deal.II/grid_tools_transform_01.output
new file mode 100644 (file)
index 0000000..9adb1e3
--- /dev/null
@@ -0,0 +1,825 @@
+
+DEAL::dim = 2
+DEAL::Unchanged grid:
+0.500000 0.00000 1 0
+1.00000 0.00000 1 0
+1.00000 0.500000 1 0
+0.500000 0.500000 1 0
+0.500000 0.00000 1 0
+
+
+0.00000 0.500000 1 0
+0.500000 0.500000 1 0
+0.500000 1.00000 1 0
+0.00000 1.00000 1 0
+0.00000 0.500000 1 0
+
+
+0.500000 0.500000 1 0
+1.00000 0.500000 1 0
+1.00000 1.00000 1 0
+0.500000 1.00000 1 0
+0.500000 0.500000 1 0
+
+
+0.00000 0.00000 2 0
+0.250000 0.00000 2 0
+0.250000 0.250000 2 0
+0.00000 0.250000 2 0
+0.00000 0.00000 2 0
+
+
+0.250000 0.00000 2 0
+0.500000 0.00000 2 0
+0.500000 0.250000 2 0
+0.250000 0.250000 2 0
+0.250000 0.00000 2 0
+
+
+0.00000 0.250000 2 0
+0.250000 0.250000 2 0
+0.250000 0.500000 2 0
+0.00000 0.500000 2 0
+0.00000 0.250000 2 0
+
+
+0.250000 0.250000 2 0
+0.500000 0.250000 2 0
+0.500000 0.500000 2 0
+0.250000 0.500000 2 0
+0.250000 0.250000 2 0
+
+
+DEAL::transformed grid:
+0.500000 0.00000 1 0
+1.00000 0.00000 1 0
+1.25000 0.500000 1 0
+0.750000 0.500000 1 0
+0.500000 0.00000 1 0
+
+
+0.250000 0.500000 1 0
+0.750000 0.500000 1 0
+1.50000 1.00000 1 0
+1.00000 1.00000 1 0
+0.250000 0.500000 1 0
+
+
+0.750000 0.500000 1 0
+1.25000 0.500000 1 0
+2.00000 1.00000 1 0
+1.50000 1.00000 1 0
+0.750000 0.500000 1 0
+
+
+0.00000 0.00000 2 0
+0.250000 0.00000 2 0
+0.312500 0.250000 2 0
+0.0625000 0.250000 2 0
+0.00000 0.00000 2 0
+
+
+0.250000 0.00000 2 0
+0.500000 0.00000 2 0
+0.625000 0.250000 2 0
+0.312500 0.250000 2 0
+0.250000 0.00000 2 0
+
+
+0.0625000 0.250000 2 0
+0.312500 0.250000 2 0
+0.500000 0.500000 2 0
+0.250000 0.500000 2 0
+0.0625000 0.250000 2 0
+
+
+0.312500 0.250000 2 0
+0.625000 0.250000 2 0
+0.750000 0.500000 2 0
+0.500000 0.500000 2 0
+0.312500 0.250000 2 0
+
+
+DEAL::dim = 3
+DEAL::Unchanged grid:
+0.500000 0.00000 0.00000 1 0
+1.00000 0.00000 0.00000 1 0
+1.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 0.00000 1 0
+
+0.500000 0.500000 0.00000 1 0
+1.00000 0.500000 0.00000 1 0
+1.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 0.00000 1 0
+
+0.500000 0.00000 0.00000 1 0
+0.500000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.00000 1 0
+1.00000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.00000 0.500000 0.00000 1 0
+0.500000 0.500000 0.00000 1 0
+0.500000 0.500000 0.500000 1 0
+0.00000 0.500000 0.500000 1 0
+0.00000 0.500000 0.00000 1 0
+
+0.00000 1.00000 0.00000 1 0
+0.500000 1.00000 0.00000 1 0
+0.500000 1.00000 0.500000 1 0
+0.00000 1.00000 0.500000 1 0
+0.00000 1.00000 0.00000 1 0
+
+0.00000 0.500000 0.00000 1 0
+0.00000 1.00000 0.00000 1 0
+
+0.500000 0.500000 0.00000 1 0
+0.500000 1.00000 0.00000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.00000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.00000 1 0
+1.00000 0.500000 0.00000 1 0
+1.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 0.00000 1 0
+
+0.500000 1.00000 0.00000 1 0
+1.00000 1.00000 0.00000 1 0
+1.00000 1.00000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+0.500000 1.00000 0.00000 1 0
+
+0.500000 0.500000 0.00000 1 0
+0.500000 1.00000 0.00000 1 0
+
+1.00000 0.500000 0.00000 1 0
+1.00000 1.00000 0.00000 1 0
+
+1.00000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 1.00000 1 0
+0.00000 0.00000 1.00000 1 0
+0.00000 0.00000 0.500000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 1.00000 1 0
+0.00000 0.500000 1.00000 1 0
+0.00000 0.500000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.00000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+
+0.00000 0.00000 1.00000 1 0
+0.00000 0.500000 1.00000 1 0
+
+0.500000 0.00000 0.500000 1 0
+1.00000 0.00000 0.500000 1 0
+1.00000 0.00000 1.00000 1 0
+0.500000 0.00000 1.00000 1 0
+0.500000 0.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+1.00000 0.500000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+
+1.00000 0.00000 1.00000 1 0
+1.00000 0.500000 1.00000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.500000 0.500000 0.500000 1 0
+0.500000 0.500000 1.00000 1 0
+0.00000 0.500000 1.00000 1 0
+0.00000 0.500000 0.500000 1 0
+
+0.00000 1.00000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+0.500000 1.00000 1.00000 1 0
+0.00000 1.00000 1.00000 1 0
+0.00000 1.00000 0.500000 1 0
+
+0.00000 0.500000 0.500000 1 0
+0.00000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.500000 0.500000 1.00000 1 0
+0.500000 1.00000 1.00000 1 0
+
+0.00000 0.500000 1.00000 1 0
+0.00000 1.00000 1.00000 1 0
+
+0.500000 0.500000 0.500000 1 0
+1.00000 0.500000 0.500000 1 0
+1.00000 0.500000 1.00000 1 0
+0.500000 0.500000 1.00000 1 0
+0.500000 0.500000 0.500000 1 0
+
+0.500000 1.00000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+1.00000 1.00000 1.00000 1 0
+0.500000 1.00000 1.00000 1 0
+0.500000 1.00000 0.500000 1 0
+
+0.500000 0.500000 0.500000 1 0
+0.500000 1.00000 0.500000 1 0
+
+1.00000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+1.00000 0.500000 1.00000 1 0
+1.00000 1.00000 1.00000 1 0
+
+0.500000 0.500000 1.00000 1 0
+0.500000 1.00000 1.00000 1 0
+
+0.00000 0.00000 0.00000 2 0
+0.250000 0.00000 0.00000 2 0
+0.250000 0.00000 0.250000 2 0
+0.00000 0.00000 0.250000 2 0
+0.00000 0.00000 0.00000 2 0
+
+0.00000 0.250000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+0.250000 0.250000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+0.00000 0.250000 0.00000 2 0
+
+0.00000 0.00000 0.00000 2 0
+0.00000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.500000 0.00000 0.00000 2 0
+0.500000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.00000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.500000 0.250000 0.00000 2 0
+0.500000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.00000 2 0
+0.500000 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.00000 0.250000 0.00000 2 0
+0.250000 0.250000 0.00000 2 0
+0.250000 0.250000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+0.00000 0.250000 0.00000 2 0
+
+0.00000 0.500000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+0.250000 0.500000 0.250000 2 0
+0.00000 0.500000 0.250000 2 0
+0.00000 0.500000 0.00000 2 0
+
+0.00000 0.250000 0.00000 2 0
+0.00000 0.500000 0.00000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.00000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.500000 0.250000 0.00000 2 0
+0.500000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.00000 2 0
+
+0.250000 0.500000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+0.500000 0.500000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.250000 0.250000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.500000 0.250000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.500000 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.500000 2 0
+0.00000 0.00000 0.500000 2 0
+0.00000 0.00000 0.250000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.500000 2 0
+0.00000 0.250000 0.500000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+
+0.00000 0.00000 0.500000 2 0
+0.00000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.500000 0.00000 0.250000 2 0
+0.500000 0.00000 0.500000 2 0
+0.250000 0.00000 0.500000 2 0
+0.250000 0.00000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+0.500000 0.250000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.500000 2 0
+0.500000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.250000 0.250000 0.250000 2 0
+0.250000 0.250000 0.500000 2 0
+0.00000 0.250000 0.500000 2 0
+0.00000 0.250000 0.250000 2 0
+
+0.00000 0.500000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+0.250000 0.500000 0.500000 2 0
+0.00000 0.500000 0.500000 2 0
+0.00000 0.500000 0.250000 2 0
+
+0.00000 0.250000 0.250000 2 0
+0.00000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+
+0.00000 0.250000 0.500000 2 0
+0.00000 0.500000 0.500000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.500000 0.250000 0.250000 2 0
+0.500000 0.250000 0.500000 2 0
+0.250000 0.250000 0.500000 2 0
+0.250000 0.250000 0.250000 2 0
+
+0.250000 0.500000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+0.500000 0.500000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.250000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.500000 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.500000 0.250000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+
+0.250000 0.250000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+
+DEAL::transformed grid:
+0.500000 0.00000 0.00000 1 0
+1.00000 0.00000 0.00000 1 0
+1.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 0.00000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.25000 0.500000 0.00000 1 0
+1.25000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 0.00000 1 0
+
+0.500000 0.00000 0.00000 1 0
+0.750000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.00000 1 0
+1.25000 0.500000 0.00000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+
+0.250000 0.500000 0.00000 1 0
+0.750000 0.500000 0.00000 1 0
+0.750000 0.500000 0.500000 1 0
+0.250000 0.500000 0.500000 1 0
+0.250000 0.500000 0.00000 1 0
+
+1.00000 1.00000 0.00000 1 0
+1.50000 1.00000 0.00000 1 0
+1.50000 1.00000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+1.00000 1.00000 0.00000 1 0
+
+0.250000 0.500000 0.00000 1 0
+1.00000 1.00000 0.00000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.50000 1.00000 0.00000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.250000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.25000 0.500000 0.00000 1 0
+1.25000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 0.00000 1 0
+
+1.50000 1.00000 0.00000 1 0
+2.00000 1.00000 0.00000 1 0
+2.00000 1.00000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+1.50000 1.00000 0.00000 1 0
+
+0.750000 0.500000 0.00000 1 0
+1.50000 1.00000 0.00000 1 0
+
+1.25000 0.500000 0.00000 1 0
+2.00000 1.00000 0.00000 1 0
+
+1.25000 0.500000 0.500000 1 0
+2.00000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.500000 0.00000 0.500000 1 0
+0.500000 0.00000 1.00000 1 0
+0.00000 0.00000 1.00000 1 0
+0.00000 0.00000 0.500000 1 0
+
+0.250000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 1.00000 1 0
+0.250000 0.500000 1.00000 1 0
+0.250000 0.500000 0.500000 1 0
+
+0.00000 0.00000 0.500000 1 0
+0.250000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+
+0.00000 0.00000 1.00000 1 0
+0.250000 0.500000 1.00000 1 0
+
+0.500000 0.00000 0.500000 1 0
+1.00000 0.00000 0.500000 1 0
+1.00000 0.00000 1.00000 1 0
+0.500000 0.00000 1.00000 1 0
+0.500000 0.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+1.25000 0.500000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+0.750000 0.500000 0.500000 1 0
+
+0.500000 0.00000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+
+1.00000 0.00000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+
+1.00000 0.00000 1.00000 1 0
+1.25000 0.500000 1.00000 1 0
+
+0.500000 0.00000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+
+0.250000 0.500000 0.500000 1 0
+0.750000 0.500000 0.500000 1 0
+0.750000 0.500000 1.00000 1 0
+0.250000 0.500000 1.00000 1 0
+0.250000 0.500000 0.500000 1 0
+
+1.00000 1.00000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+1.50000 1.00000 1.00000 1 0
+1.00000 1.00000 1.00000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.250000 0.500000 0.500000 1 0
+1.00000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.750000 0.500000 1.00000 1 0
+1.50000 1.00000 1.00000 1 0
+
+0.250000 0.500000 1.00000 1 0
+1.00000 1.00000 1.00000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.25000 0.500000 0.500000 1 0
+1.25000 0.500000 1.00000 1 0
+0.750000 0.500000 1.00000 1 0
+0.750000 0.500000 0.500000 1 0
+
+1.50000 1.00000 0.500000 1 0
+2.00000 1.00000 0.500000 1 0
+2.00000 1.00000 1.00000 1 0
+1.50000 1.00000 1.00000 1 0
+1.50000 1.00000 0.500000 1 0
+
+0.750000 0.500000 0.500000 1 0
+1.50000 1.00000 0.500000 1 0
+
+1.25000 0.500000 0.500000 1 0
+2.00000 1.00000 0.500000 1 0
+
+1.25000 0.500000 1.00000 1 0
+2.00000 1.00000 1.00000 1 0
+
+0.750000 0.500000 1.00000 1 0
+1.50000 1.00000 1.00000 1 0
+
+0.00000 0.00000 0.00000 2 0
+0.250000 0.00000 0.00000 2 0
+0.250000 0.00000 0.250000 2 0
+0.00000 0.00000 0.250000 2 0
+0.00000 0.00000 0.00000 2 0
+
+0.0625000 0.250000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+0.312500 0.250000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+0.0625000 0.250000 0.00000 2 0
+
+0.00000 0.00000 0.00000 2 0
+0.0625000 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.500000 0.00000 0.00000 2 0
+0.500000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.00000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.625000 0.250000 0.00000 2 0
+0.625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.250000 0.00000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.00000 2 0
+0.625000 0.250000 0.00000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.0625000 0.250000 0.00000 2 0
+0.312500 0.250000 0.00000 2 0
+0.312500 0.250000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+0.0625000 0.250000 0.00000 2 0
+
+0.250000 0.500000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+0.500000 0.500000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.0625000 0.250000 0.00000 2 0
+0.250000 0.500000 0.00000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.625000 0.250000 0.00000 2 0
+0.625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.312500 0.250000 0.00000 2 0
+
+0.500000 0.500000 0.00000 2 0
+0.750000 0.500000 0.00000 2 0
+0.750000 0.500000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.312500 0.250000 0.00000 2 0
+0.500000 0.500000 0.00000 2 0
+
+0.625000 0.250000 0.00000 2 0
+0.750000 0.500000 0.00000 2 0
+
+0.625000 0.250000 0.250000 2 0
+0.750000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.250000 0.00000 0.250000 2 0
+0.250000 0.00000 0.500000 2 0
+0.00000 0.00000 0.500000 2 0
+0.00000 0.00000 0.250000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.375000 0.250000 0.500000 2 0
+0.125000 0.250000 0.500000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.00000 0.00000 0.250000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+
+0.00000 0.00000 0.500000 2 0
+0.125000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.500000 0.00000 0.250000 2 0
+0.500000 0.00000 0.500000 2 0
+0.250000 0.00000 0.500000 2 0
+0.250000 0.00000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+0.625000 0.250000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.250000 0.00000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+
+0.500000 0.00000 0.500000 2 0
+0.625000 0.250000 0.500000 2 0
+
+0.250000 0.00000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.312500 0.250000 0.250000 2 0
+0.375000 0.250000 0.500000 2 0
+0.125000 0.250000 0.500000 2 0
+0.0625000 0.250000 0.250000 2 0
+
+0.250000 0.500000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+0.500000 0.500000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.0625000 0.250000 0.250000 2 0
+0.250000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.375000 0.250000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+
+0.125000 0.250000 0.500000 2 0
+0.250000 0.500000 0.500000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.625000 0.250000 0.250000 2 0
+0.625000 0.250000 0.500000 2 0
+0.375000 0.250000 0.500000 2 0
+0.312500 0.250000 0.250000 2 0
+
+0.500000 0.500000 0.250000 2 0
+0.750000 0.500000 0.250000 2 0
+0.750000 0.500000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.312500 0.250000 0.250000 2 0
+0.500000 0.500000 0.250000 2 0
+
+0.625000 0.250000 0.250000 2 0
+0.750000 0.500000 0.250000 2 0
+
+0.625000 0.250000 0.500000 2 0
+0.750000 0.500000 0.500000 2 0
+
+0.375000 0.250000 0.500000 2 0
+0.500000 0.500000 0.500000 2 0
+
index 0773ff956b9697b66e8c2e85be96476f7eba1ff2..b9838a1531ae121c62bf9263b46b0b1ba7a1109c 100644 (file)
@@ -1,7 +1,7 @@
 // ---------------------------------------------------------------------
 // $Id$
 //
-// Copyright (C) 2005 - 2013 by the deal.II authors
+// Copyright (C) 2005 - 2014 by the deal.II authors
 //
 // This file is part of the deal.II library.
 //
@@ -163,20 +163,20 @@ namespace Evaluation
   {
   public:
     SolutionOutput (const std::string                         &output_name_base,
-                    const typename DataOut<dim>::OutputFormat  output_format);
+                    const DataOutBase::OutputFormat  output_format);
 
     virtual void operator () (const hp::DoFHandler<dim> &dof_handler,
                               const Vector<double>  &solution) const;
   private:
     const std::string                         output_name_base;
-    const typename DataOut<dim>::OutputFormat output_format;
+    const DataOutBase::OutputFormat output_format;
   };
 
 
   template <int dim>
   SolutionOutput<dim>::
   SolutionOutput (const std::string                         &output_name_base,
-                  const typename DataOut<dim>::OutputFormat  output_format)
+                  const DataOutBase::OutputFormat  output_format)
     :
     output_name_base (output_name_base),
     output_format (output_format)
@@ -783,7 +783,7 @@ void solve_problem (const std::string &solver_name)
 
   Evaluation::SolutionOutput<dim>
   postprocessor2 (std::string("solution-")+solver_name,
-                  DataOut<dim>::gnuplot);
+                  DataOutBase::gnuplot);
 
   std::list<Evaluation::EvaluationBase<dim> *> postprocessor_list;
   postprocessor_list.push_back (&postprocessor1);
diff --git a/tests/lapack/full_matrix_08.cc b/tests/lapack/full_matrix_08.cc
new file mode 100644 (file)
index 0000000..8d2a514
--- /dev/null
@@ -0,0 +1,68 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::mmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+  const unsigned int m=2;
+  const unsigned int n=3;
+  const unsigned int k=4;
+  FullMatrix<double> A(m, k), B(k, n), C(m, n), OC(m,n);
+  LAPACKFullMatrix<double> AL(m, k), BL(k, n), CL(m, n);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<k; ++j)
+      A(i,j) = AL(i,j) = (double)rand()/RAND_MAX;
+  for (unsigned int i=0; i<k; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+  A.mmult(C, B);
+  AL.mmult(CL, BL);
+  AL.mmult(OC, BL);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      {
+        Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+        Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+      }
+
+  deallog << "OK" << std::endl;
+}
+
+int main()
+{
+  const std::string logname = "output";
+  std::ofstream logfile(logname.c_str());
+  logfile.precision(3);
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test();
+}
diff --git a/tests/lapack/full_matrix_08.output b/tests/lapack/full_matrix_08.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/lapack/full_matrix_09.cc b/tests/lapack/full_matrix_09.cc
new file mode 100644 (file)
index 0000000..b5de9db
--- /dev/null
@@ -0,0 +1,68 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::Tmmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+  const unsigned int m=2;
+  const unsigned int n=3;
+  const unsigned int k=4;
+  FullMatrix<double> A(k, m), B(k, n), C(m, n), OC(m,n);
+  LAPACKFullMatrix<double> AL(k,m), BL(k, n), CL(m, n);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<k; ++j)
+      A(j,i) = AL(j,i) = (double)rand()/RAND_MAX;
+  for (unsigned int i=0; i<k; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+  A.Tmmult(C, B);
+  AL.Tmmult(CL, BL);
+  AL.Tmmult(OC, BL);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      {
+        Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+        Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+      }
+
+  deallog << "OK" << std::endl;
+}
+
+int main()
+{
+  const std::string logname = "output";
+  std::ofstream logfile(logname.c_str());
+  logfile.precision(3);
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test();
+}
diff --git a/tests/lapack/full_matrix_09.output b/tests/lapack/full_matrix_09.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/lapack/full_matrix_10.cc b/tests/lapack/full_matrix_10.cc
new file mode 100644 (file)
index 0000000..de83b13
--- /dev/null
@@ -0,0 +1,68 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::mTmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+  const unsigned int m=2;
+  const unsigned int n=3;
+  const unsigned int k=4;
+  FullMatrix<double> A(m, k), B(n, k), C(m, n), OC(m,n);
+  LAPACKFullMatrix<double> AL(m, k), BL(n, k), CL(m, n);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<k; ++j)
+      A(i,j) = AL(i,j) = (double)rand()/RAND_MAX;
+  for (unsigned int i=0; i<n; ++i)
+    for (unsigned int j=0; j<k; ++j)
+      B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+  A.mTmult(C, B);
+  AL.mTmult(CL, BL);
+  AL.mTmult(OC, BL);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      {
+        Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+        Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+      }
+
+  deallog << "OK" << std::endl;
+}
+
+int main()
+{
+  const std::string logname = "output";
+  std::ofstream logfile(logname.c_str());
+  logfile.precision(3);
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test();
+}
diff --git a/tests/lapack/full_matrix_10.output b/tests/lapack/full_matrix_10.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/lapack/full_matrix_11.cc b/tests/lapack/full_matrix_11.cc
new file mode 100644 (file)
index 0000000..03d991e
--- /dev/null
@@ -0,0 +1,68 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::TmTmult
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+  const unsigned int m=2;
+  const unsigned int n=3;
+  const unsigned int k=4;
+  FullMatrix<double> A(k, m), B(n, k), C(m, n), OC(m,n);
+  LAPACKFullMatrix<double> AL(k, m), BL(n, k), CL(m, n);
+  for (unsigned int i=0; i<k; ++i)
+    for (unsigned int j=0; j<m; ++j)
+      A(i,j) = AL(i,j) = (double)rand()/RAND_MAX;
+  for (unsigned int i=0; i<n; ++i)
+    for (unsigned int j=0; j<k; ++j)
+      B(i,j) = BL(i,j) = (double)rand()/RAND_MAX;
+
+  A.TmTmult(C, B);
+  AL.TmTmult(CL, BL);
+  AL.TmTmult(OC, BL);
+  for (unsigned int i=0; i<m; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      {
+        Assert(std::abs(C(i,j)-CL(i,j)) < 1e-13, ExcInternalError());
+        Assert(std::abs(C(i,j)-OC(i,j)) < 1e-13, ExcInternalError());
+      }
+
+  deallog << "OK" << std::endl;
+}
+
+int main()
+{
+  const std::string logname = "output";
+  std::ofstream logfile(logname.c_str());
+  logfile.precision(3);
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test();
+}
diff --git a/tests/lapack/full_matrix_11.output b/tests/lapack/full_matrix_11.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/lapack/full_matrix_12.cc b/tests/lapack/full_matrix_12.cc
new file mode 100644 (file)
index 0000000..a976490
--- /dev/null
@@ -0,0 +1,71 @@
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// Tests LAPACKFullMatrix::apply_lu_factorization in two different variants
+
+#include "../tests.h"
+#include <deal.II/base/logstream.h>
+#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <fstream>
+#include <iostream>
+
+
+
+void test()
+{
+  const unsigned int n=11;
+  LAPACKFullMatrix<double> A(n,n);
+  for (unsigned int i=0; i<n; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      A(i,j) = (double)rand()/RAND_MAX;
+  A.compute_lu_factorization();
+  LAPACKFullMatrix<double> rhs_orig(n, 3);
+  for (unsigned int i=0; i<3; ++i)
+    for (unsigned int j=0; j<n; ++j)
+      rhs_orig(j,i) = 2.32 * rand() / RAND_MAX - 0.9923;
+
+  for (unsigned int transpose=0; transpose < 2; ++transpose)
+    {
+      LAPACKFullMatrix<double> rhs(rhs_orig);
+      A.apply_lu_factorization(rhs, transpose);
+      for (unsigned int i=0; i<3; ++i)
+        {
+          Vector<double> check(n);
+          for (unsigned int j=0; j<n; ++j)
+            check(j) = rhs_orig(j, i);
+          A.apply_lu_factorization(check, transpose);
+          for (unsigned int j=0; j<n; ++j)
+            Assert(std::abs(check(j) - rhs(j,i)) < 1e-13, ExcInternalError());
+        }
+    }
+
+  deallog << "OK" << std::endl;
+}
+
+int main()
+{
+  const std::string logname = "output";
+  std::ofstream logfile(logname.c_str());
+  logfile.precision(3);
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  test();
+}
diff --git a/tests/lapack/full_matrix_12.output b/tests/lapack/full_matrix_12.output
new file mode 100644 (file)
index 0000000..0fd8fc1
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEAL::OK
diff --git a/tests/petsc/full_matrix_00.cc b/tests/petsc/full_matrix_00.cc
new file mode 100644 (file)
index 0000000..cbdde4b
--- /dev/null
@@ -0,0 +1,122 @@
+// ---------------------------------------------------------------------
+// $Id: full_matrix_01.cc 31602 2013-11-09 15:38:36Z young $
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+// check initialiser (aka do_reinit). .
+//
+// PETScWrappers::FullMatrix::reinit ()
+
+#include "../tests.h"
+#include <deal.II/lac/petsc_full_matrix.h>
+#include <fstream>
+#include <iostream>
+
+// Simply take an already intialised full matrix, fill in some of the
+// elements, reinitialise it to a different size and fill in some
+// elements again. To be sure this generates the correct results the
+// test is verbose (and uses tiny matrices).
+void test (PETScWrappers::FullMatrix &m)
+{
+  // asign some matrix elements
+  for (unsigned int i=0; i<m.m(); ++i)
+    for (unsigned int j=0; j<m.n(); ++j)
+      m.set (i, j, i+2*j);
+
+  m.compress (VectorOperation::add);
+
+  // things we know
+  Assert (m.m() == 3, ExcInternalError());
+  Assert (m.n() == 3, ExcInternalError());
+  
+  // Generate some output
+  deallog << "initial matrix: " << std::endl;
+  for (unsigned int i=0; i<m.m(); ++i)
+    {
+      for (unsigned int j=0; j<m.n(); ++j)
+       deallog << m(i,j) << " ";
+      deallog << std::endl;
+    }
+  deallog << std::endl;
+
+  // test reinit, this time a different size matrix
+  m.reinit (5, 5);
+
+  // set some entries
+  for (unsigned int i=0; i<m.m(); ++i)
+    for (unsigned int j=0; j<m.n(); ++j)
+      m.set (i, j, j+2*i);
+  m.compress (VectorOperation::add);
+  
+  // things we know
+  Assert (m.m() == 5, ExcInternalError());
+  Assert (m.n() == 5, ExcInternalError());
+
+  // Generate some output
+  deallog << "after reinit: " << std::endl;
+  for (unsigned int i=0; i<m.m(); ++i)
+    {
+      for (unsigned int j=0; j<m.n(); ++j)
+       deallog << m(i,j) << " ";
+      deallog << std::endl;
+    }
+  deallog << std::endl;
+  
+  // done
+  deallog << "OK" << std::endl;
+}
+
+int main (int argc,char **argv)
+{
+  std::ofstream logfile("output");
+  deallog.attach(logfile);
+  deallog.depth_console(0);
+  deallog.threshold_double(1.e-10);
+
+  try
+    {
+      Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+      {
+       // Standard intialiser...
+        PETScWrappers::FullMatrix m (3,3);
+        test (m);
+      }
+
+    }
+  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;
+    };
+}
diff --git a/tests/petsc/full_matrix_00.output b/tests/petsc/full_matrix_00.output
new file mode 100644 (file)
index 0000000..c7aa78d
--- /dev/null
@@ -0,0 +1,14 @@
+
+DEAL::initial matrix: 
+DEAL::0 2.00000 4.00000 
+DEAL::1.00000 3.00000 5.00000 
+DEAL::2.00000 4.00000 6.00000 
+DEAL::
+DEAL::after reinit: 
+DEAL::0 1.00000 2.00000 3.00000 4.00000 
+DEAL::2.00000 3.00000 4.00000 5.00000 6.00000 
+DEAL::4.00000 5.00000 6.00000 7.00000 8.00000 
+DEAL::6.00000 7.00000 8.00000 9.00000 10.0000 
+DEAL::8.00000 9.00000 10.0000 11.0000 12.0000 
+DEAL::
+DEAL::OK

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.